fix: preserve canonical skills.sh supplement hashes (#3308)

This commit is contained in:
Patrick Erichsen
2026-07-30 04:49:52 -07:00
committed by GitHub
parent 23af0934e4
commit 5a1d9c9472
3 changed files with 15 additions and 7 deletions
+1 -1
View File
@@ -521,7 +521,7 @@ jobs:
.digest.repo == "clawdis" and
.digest.githubPath == ".agents/skills/discrawl" and
.digest.githubCommit == "690ed564419291ca6e832dc69b53061300075b62" and
.digest.sourceContentHash == "889dc43180b210dbca12f8291e007feb231250ecfdba90c4d3938a18125efb6d" and
.digest.sourceContentHash == "4d3c90262b309ee9ee0ef2f83397fc2a68e8c7d098a8a960fdcbf8908f077f10" and
.digest.active == true and
.digest.publicVisible == false and
.digest.installable == false
+5 -3
View File
@@ -157,8 +157,9 @@ describe("skills.sh Vercel source boundary", () => {
});
});
it("builds a hidden controlled observation only from exact immutable content", () => {
it("keeps the canonical folder hash while verifying exact controlled detail content", () => {
const fullContent = "# Controlled\n\nThis content is longer than the retained prefix.";
const detailContentHash = createHash("sha256").update(fullContent).digest("hex");
const supplement = {
externalId: "owner/repo/controlled",
owner: "owner",
@@ -169,7 +170,8 @@ describe("skills.sh Vercel source boundary", () => {
githubPath: "skills/controlled",
detailPath: "skills/controlled/SKILL.md",
githubCommit: "0123456789abcdef0123456789abcdef01234567",
sourceContentHash: createHash("sha256").update(fullContent).digest("hex"),
sourceContentHash: "a".repeat(64),
detailContentHash,
};
expect(
@@ -203,7 +205,7 @@ describe("skills.sh Vercel source boundary", () => {
});
expect(() =>
buildSkillsShMirrorControlledObservation(
{ ...supplement, sourceContentHash: "0".repeat(64) },
{ ...supplement, detailContentHash: "0".repeat(64) },
fullContent,
Buffer.byteLength(fullContent),
16,
+9 -3
View File
@@ -40,6 +40,7 @@ const SKILLS_SH_MIRROR_CONTROLLED_SUPPLEMENTS = [
detailPath: "skills/html/SKILL.md",
githubCommit: "050daba89f6b6636470add5cb300aac46a412cf8",
sourceContentHash: "a47adb2c1ac33c088f664b5187971b63d2b958a7b9f01516d26005ca941a108f",
detailContentHash: "42d2e89358ea927441dfede45c3b0cf89a21603bc7c32246f098d24a9cbea1ff",
},
{
externalId: "steipete/clawdis/discrawl",
@@ -51,7 +52,8 @@ const SKILLS_SH_MIRROR_CONTROLLED_SUPPLEMENTS = [
githubPath: ".agents/skills/discrawl",
detailPath: ".agents/skills/discrawl/SKILL.md",
githubCommit: "690ed564419291ca6e832dc69b53061300075b62",
sourceContentHash: "889dc43180b210dbca12f8291e007feb231250ecfdba90c4d3938a18125efb6d",
sourceContentHash: "4d3c90262b309ee9ee0ef2f83397fc2a68e8c7d098a8a960fdcbf8908f077f10",
detailContentHash: "889dc43180b210dbca12f8291e007feb231250ecfdba90c4d3938a18125efb6d",
},
] as const;
@@ -66,6 +68,7 @@ type SkillsShMirrorControlledSupplement = {
detailPath: string;
githubCommit: string;
sourceContentHash: string;
detailContentHash: string;
};
export const SKILLS_SH_MIRROR_CONTROLLED_SUPPLEMENT_COUNT =
@@ -2389,10 +2392,13 @@ export function buildSkillsShMirrorControlledObservation(
) {
assertIntegerInRange("sourceBytes", sourceBytes, 0, MAX_CONTROLLED_DETAIL_BYTES);
assertIntegerInRange("maxDetailBytes", maxDetailBytes, 1, 64 * 1024);
const sourceContentHash = sha256Hex(fullContent);
if (sourceContentHash !== supplement.sourceContentHash) {
const detailContentHash = sha256Hex(fullContent);
if (detailContentHash !== supplement.detailContentHash) {
throw new Error(`controlled skills.sh mirror source hash changed: ${supplement.externalId}`);
}
// Mirror and claim identity use the canonical whole-folder hash. The raw
// detail response is verified separately because it contains only SKILL.md.
const sourceContentHash = supplement.sourceContentHash;
const content = truncateUtf8(fullContent, maxDetailBytes);
const unavailable = { status: "unavailable" as const };
return {