test: resume interrupted CLAW-603 Test proof

This commit is contained in:
Patrick Erichsen
2026-07-30 23:22:31 -07:00
parent 6a6bb71382
commit d83032cbff
5 changed files with 998 additions and 29 deletions
+25 -16
View File
@@ -1,8 +1,14 @@
name: CLAW-603 Permanent Test Claim and Native Proof
name: CLAW-603 One-Time Permanent Test Claim Recovery
# Branch-only operator proof. This file is never merged; main retains the hourly production sync.
# Branch-only continuation of interrupted proof run 30608116457. This file is never merged;
# main retains the hourly production sync.
on:
workflow_dispatch:
inputs:
confirm_recovery:
description: Type resume-30608116457 to continue the exact interrupted Test proof
required: true
type: string
concurrency:
group: claw-603-permanent-test-proof
@@ -16,14 +22,15 @@ jobs:
if: >-
github.ref == 'refs/heads/pe/claw-603-final-proof' &&
github.actor == 'Patrick-Erichsen' &&
github.triggering_actor == 'Patrick-Erichsen'
github.triggering_actor == 'Patrick-Erichsen' &&
inputs.confirm_recovery == 'resume-30608116457'
runs-on: ubuntu-latest
timeout-minutes: 60
environment:
name: Test
env:
CONVEX_DEPLOY_KEY: ${{ secrets.CONVEX_DEPLOY_KEY }}
DEPLOY_SHA: c1f6ba2f07b5fc084a31286a54e23e7bce404780
DEPLOY_SHA: 73eb44cd70ff6c2759e5cf4748a84c7a8949a37f
EXPECTED_CATALOG_SCAN_ATTEMPTS: 9
EXPECTED_NATIVE_SCAN_JOBS: 16
EXPECTED_NATIVE_SCAN_UPDATED_AT_SUM: 28554932587800
@@ -200,6 +207,17 @@ jobs:
.scanAdmissionEnabled == false
' proof/claw-603/claim-control-enabled.json >/dev/null
CLAWHUB_CLAIM_PROOF_OUTPUT="proof/claw-603/claim-lifecycle.json" \
bun scripts/skills-sh-catalog/claw-603-claim-recovery.ts \
> proof/claw-603/claim-lifecycle-stdout.json
jq -e '
.ok == true and
.target.productionWrites == 0 and
.paidScans == 0 and
.scansPlanned == 0 and
.scansAdmitted == 0
' proof/claw-603/claim-lifecycle.json >/dev/null
post_mirror \
'{"operation":"verify-activate","reason":"CLAW-603 permanent Test claim precondition"}' \
proof/claw-603/claim-activation.json
@@ -210,16 +228,6 @@ jobs:
.trendingSnapshot.status == "ready"
' proof/claw-603/claim-activation.json >/dev/null
bun scripts/skills-sh-catalog/claw-603-claim-proof.ts \
> proof/claw-603/claim-lifecycle-stdout.json
jq -e '
.ok == true and
.target.productionWrites == 0 and
.paidScans == 0 and
.scansPlanned == 0 and
.scansAdmitted == 0
' proof/claw-603/claim-lifecycle.json >/dev/null
native_skill_id="$(
jq -r '
.restoration.restoredSource.skills[] |
@@ -353,14 +361,15 @@ jobs:
always() &&
github.ref == 'refs/heads/pe/claw-603-final-proof' &&
github.actor == 'Patrick-Erichsen' &&
github.triggering_actor == 'Patrick-Erichsen'
github.triggering_actor == 'Patrick-Erichsen' &&
inputs.confirm_recovery == 'resume-30608116457'
runs-on: ubuntu-latest
timeout-minutes: 15
environment:
name: Test
env:
CONVEX_DEPLOY_KEY: ${{ secrets.CONVEX_DEPLOY_KEY }}
DEPLOY_SHA: c1f6ba2f07b5fc084a31286a54e23e7bce404780
DEPLOY_SHA: 73eb44cd70ff6c2759e5cf4748a84c7a8949a37f
EXPECTED_CATALOG_SCAN_ATTEMPTS: 9
EXPECTED_NATIVE_SCAN_JOBS: 16
EXPECTED_NATIVE_SCAN_UPDATED_AT_SUM: 28554932587800
@@ -0,0 +1,223 @@
import { describe, expect, it } from "vitest";
import {
assertControlledMirrorRecoveryMetadata,
assertControlledProofBookmark,
buildControlledCandidateContent,
classifyClaimRecoveryState,
} from "./claw-603-claim-proof-helpers";
describe("CLAW-603 claim proof candidate content", () => {
it("binds cached markdown to the exact controlled candidate after validating the pinned file hash", () => {
const content = "# HTML\n";
const result = buildControlledCandidateContent({
mirror: {
digest: {
externalId: "patrick-erichsen/skills/html",
slug: "html",
displayName: "HTML",
githubPath: "skills/html",
},
detail: {
path: "skills/html/SKILL.md",
content,
},
},
expectedExternalId: "patrick-erichsen/skills/html",
expectedPath: "skills/html",
expectedFileHash: "50361c318c6720f33fe0e061bd4bc97e0fcc7d135b676701a9a2ef626e830339",
candidateCommit: "a".repeat(40),
candidateContentHash: "b".repeat(64),
});
expect(result).toEqual({
slug: "html",
displayName: "HTML",
path: "skills/html",
skillMarkdownPath: "skills/html/SKILL.md",
skillMarkdown: content,
contentHash: "b".repeat(64),
});
});
it("rejects markdown that is not the exact pinned controlled source", () => {
expect(() =>
buildControlledCandidateContent({
mirror: {
digest: {
externalId: "patrick-erichsen/skills/html",
slug: "html",
displayName: "HTML",
githubPath: "skills/html",
},
detail: {
path: "skills/html/SKILL.md",
content: "# changed\n",
},
},
expectedExternalId: "patrick-erichsen/skills/html",
expectedPath: "skills/html",
expectedFileHash: "50361c318c6720f33fe0e061bd4bc97e0fcc7d135b676701a9a2ef626e830339",
candidateCommit: "a".repeat(40),
candidateContentHash: "b".repeat(64),
}),
).toThrow("controlled candidate markdown hash mismatch");
});
it("requires every replayed mirror field to match the captured recovery fixture", () => {
const mirror = {
digest: {
externalId: "patrick-erichsen/skills/html",
sourceType: "github",
upstreamSourceType: "controlled-github",
owner: "patrick-erichsen",
repo: "skills",
slug: "html",
displayName: "HTML",
sourceUrl: "https://www.skills.sh/patrick-erichsen/skills/html",
canonicalRepoUrl: "https://github.com/patrick-erichsen/skills",
githubPath: "skills/html",
upstreamInstalls: 123,
upstreamScanners: { socket: { status: "unavailable" } },
inferredCategories: ["other"],
inferredTopics: [],
inferredCategoryConfidence: "low",
inferredTopicConfidence: "low",
inferredClassifierVersion: "taxonomy-v1",
inferredTopicClassifierVersion: "topic-v1",
inferredInputHash: "input",
inferredTopicInputHash: "topic-input",
inferredAt: 1234,
},
detail: {
contentKind: "skill-md",
path: "skills/html/SKILL.md",
content: "# HTML\n",
contentBytes: 7,
sourceBytes: 7,
sourceFileCount: 1,
truncated: false,
},
};
const expected = {
digest: { ...mirror.digest },
detail: {
contentKind: "skill-md",
path: "skills/html/SKILL.md",
contentSha256: "50361c318c6720f33fe0e061bd4bc97e0fcc7d135b676701a9a2ef626e830339",
contentBytes: 7,
sourceBytes: 7,
sourceFileCount: 1,
truncated: false,
},
};
expect(() => assertControlledMirrorRecoveryMetadata({ mirror, expected })).not.toThrow();
expect(() =>
assertControlledMirrorRecoveryMetadata({
mirror: {
...mirror,
digest: { ...mirror.digest, upstreamInstalls: 124 },
},
expected,
}),
).toThrow("controlled mirror recovery metadata mismatch");
});
it("accepts only the exact Bookmark created by the interrupted proof", () => {
const expected = {
id: "stars:proof",
skillId: "skills:html",
userId: "users:owner",
createdAt: 1234,
hourlyStatsRecordedAt: 1234,
};
expect(() =>
assertControlledProofBookmark({
star: {
_id: "stars:proof",
skillId: "skills:html",
userId: "users:owner",
createdAt: 1234,
hourlyStatsRecordedAt: 1234,
},
expected,
currentSkillStars: 1,
baselineSkillStars: 0,
}),
).not.toThrow();
expect(() =>
assertControlledProofBookmark({
star: {
_id: "stars:someone-else",
skillId: "skills:html",
userId: "users:owner",
createdAt: 1234,
hourlyStatsRecordedAt: 1234,
},
expected,
currentSkillStars: 1,
baselineSkillStars: 0,
}),
).toThrow("controlled proof Bookmark does not match the interrupted proof");
});
it.each([
{
expected: "candidate-pending",
mirrorCommit: "b",
nativeCommit: "b",
pendingCandidate: true,
proofBookmark: true,
},
{
expected: "native-restored",
mirrorCommit: "b",
nativeCommit: "a",
pendingCandidate: false,
proofBookmark: true,
},
{
expected: "mirror-restored-candidate-pending",
mirrorCommit: "a",
nativeCommit: "b",
pendingCandidate: true,
proofBookmark: true,
},
{
expected: "mirror-restored",
mirrorCommit: "a",
nativeCommit: "a",
pendingCandidate: false,
proofBookmark: true,
},
{
expected: "complete",
mirrorCommit: "a",
nativeCommit: "a",
pendingCandidate: false,
proofBookmark: false,
},
])("recognizes the retry-safe recovery phase $expected", (fixture) => {
expect(
classifyClaimRecoveryState({
...fixture,
restoredCommit: "a",
contaminatingCommit: "b",
}),
).toBe(fixture.expected);
});
it("rejects recovery state outside the exact monotonic path", () => {
expect(() =>
classifyClaimRecoveryState({
mirrorCommit: "b",
nativeCommit: "a",
pendingCandidate: true,
proofBookmark: true,
restoredCommit: "a",
contaminatingCommit: "b",
}),
).toThrow("controlled claim recovery state is not resumable");
});
});
@@ -0,0 +1,234 @@
import { createHash } from "node:crypto";
type ControlledMirrorState = {
digest?: {
externalId?: string;
sourceType?: string;
upstreamSourceType?: string;
owner?: string;
repo?: string;
slug?: string;
displayName?: string;
sourceUrl?: string;
canonicalRepoUrl?: string;
githubPath?: string;
upstreamInstalls?: number;
upstreamScanners?: unknown;
inferredCategories?: unknown;
inferredTopics?: unknown;
inferredCategoryConfidence?: string;
inferredTopicConfidence?: string;
inferredClassifierVersion?: string;
inferredTopicClassifierVersion?: string;
inferredInputHash?: string;
inferredTopicInputHash?: string;
inferredAt?: number;
summary?: string;
};
detail?: {
contentKind?: string;
path?: string;
content?: string;
contentBytes?: number;
sourceBytes?: number;
sourceFileCount?: number;
truncated?: boolean;
};
};
type ControlledMirrorRecoveryMetadata = {
digest: {
externalId: unknown;
sourceType: unknown;
upstreamSourceType: unknown;
owner: unknown;
repo: unknown;
slug: unknown;
displayName: unknown;
sourceUrl: unknown;
canonicalRepoUrl: unknown;
githubPath: unknown;
upstreamInstalls: unknown;
upstreamScanners: unknown;
inferredCategories: unknown;
inferredTopics: unknown;
inferredCategoryConfidence: unknown;
inferredTopicConfidence: unknown;
inferredClassifierVersion: unknown;
inferredTopicClassifierVersion: unknown;
inferredInputHash: unknown;
inferredTopicInputHash: unknown;
inferredAt: unknown;
};
detail: {
contentKind: unknown;
path: unknown;
contentSha256: string;
contentBytes: unknown;
sourceBytes: unknown;
sourceFileCount: unknown;
truncated: unknown;
};
};
export function assertControlledMirrorRecoveryMetadata(args: {
mirror: ControlledMirrorState;
expected: ControlledMirrorRecoveryMetadata;
}) {
const { digest, detail } = args.mirror;
if (!digest || !detail || typeof detail.content !== "string") {
throw new Error("controlled mirror recovery metadata is incomplete");
}
const actual: ControlledMirrorRecoveryMetadata = {
digest: {
externalId: digest.externalId,
sourceType: digest.sourceType,
upstreamSourceType: digest.upstreamSourceType,
owner: digest.owner,
repo: digest.repo,
slug: digest.slug,
displayName: digest.displayName,
sourceUrl: digest.sourceUrl,
canonicalRepoUrl: digest.canonicalRepoUrl,
githubPath: digest.githubPath,
upstreamInstalls: digest.upstreamInstalls,
upstreamScanners: digest.upstreamScanners,
inferredCategories: digest.inferredCategories,
inferredTopics: digest.inferredTopics,
inferredCategoryConfidence: digest.inferredCategoryConfidence,
inferredTopicConfidence: digest.inferredTopicConfidence,
inferredClassifierVersion: digest.inferredClassifierVersion,
inferredTopicClassifierVersion: digest.inferredTopicClassifierVersion,
inferredInputHash: digest.inferredInputHash,
inferredTopicInputHash: digest.inferredTopicInputHash,
inferredAt: digest.inferredAt,
},
detail: {
contentKind: detail.contentKind,
path: detail.path,
contentSha256: createHash("sha256").update(detail.content).digest("hex"),
contentBytes: detail.contentBytes,
sourceBytes: detail.sourceBytes,
sourceFileCount: detail.sourceFileCount,
truncated: detail.truncated,
},
};
if (JSON.stringify(actual) !== JSON.stringify(args.expected)) {
throw new Error("controlled mirror recovery metadata mismatch");
}
}
export function assertControlledProofBookmark(args: {
star: {
_id?: string;
skillId?: string;
userId?: string;
createdAt?: number;
hourlyStatsRecordedAt?: number;
} | null;
expected: {
id: string;
skillId: string;
userId: string;
createdAt: number;
hourlyStatsRecordedAt: number;
};
currentSkillStars: number;
baselineSkillStars: number;
}) {
const { star, expected } = args;
if (
!star ||
star._id !== expected.id ||
star.skillId !== expected.skillId ||
star.userId !== expected.userId ||
star.createdAt !== expected.createdAt ||
star.hourlyStatsRecordedAt !== expected.hourlyStatsRecordedAt ||
args.currentSkillStars !== args.baselineSkillStars + 1
) {
throw new Error("controlled proof Bookmark does not match the interrupted proof");
}
}
export function classifyClaimRecoveryState(args: {
mirrorCommit: string;
nativeCommit: string;
pendingCandidate: boolean;
proofBookmark: boolean;
restoredCommit: string;
contaminatingCommit: string;
}) {
if (
args.mirrorCommit === args.contaminatingCommit &&
args.nativeCommit === args.contaminatingCommit &&
args.pendingCandidate &&
args.proofBookmark
) {
return "candidate-pending" as const;
}
if (
args.mirrorCommit === args.contaminatingCommit &&
args.nativeCommit === args.restoredCommit &&
!args.pendingCandidate &&
args.proofBookmark
) {
return "native-restored" as const;
}
if (
args.mirrorCommit === args.restoredCommit &&
args.nativeCommit === args.contaminatingCommit &&
args.pendingCandidate &&
args.proofBookmark
) {
return "mirror-restored-candidate-pending" as const;
}
if (
args.mirrorCommit === args.restoredCommit &&
args.nativeCommit === args.restoredCommit &&
!args.pendingCandidate
) {
return args.proofBookmark ? ("mirror-restored" as const) : ("complete" as const);
}
throw new Error("controlled claim recovery state is not resumable");
}
export function buildControlledCandidateContent(args: {
mirror: ControlledMirrorState;
expectedExternalId: string;
expectedPath: string;
expectedFileHash: string;
candidateCommit: string;
candidateContentHash: string;
}) {
const { digest, detail } = args.mirror;
if (
digest?.externalId !== args.expectedExternalId ||
digest.githubPath !== args.expectedPath ||
detail?.path !== `${args.expectedPath}/SKILL.md` ||
typeof detail.content !== "string"
) {
throw new Error("controlled candidate source does not match the exact fixture");
}
if (!/^[0-9a-f]{40}$/.test(args.candidateCommit)) {
throw new Error("controlled candidate commit is invalid");
}
if (!/^[0-9a-f]{64}$/.test(args.candidateContentHash)) {
throw new Error("controlled candidate content hash is invalid");
}
const fileHash = createHash("sha256").update(detail.content).digest("hex");
if (fileHash !== args.expectedFileHash) {
throw new Error("controlled candidate markdown hash mismatch");
}
if (!digest.slug || !digest.displayName) {
throw new Error("controlled candidate display metadata is incomplete");
}
return {
slug: digest.slug,
displayName: digest.displayName,
...(digest.summary ? { summary: digest.summary } : {}),
path: args.expectedPath,
skillMarkdownPath: detail.path,
skillMarkdown: detail.content,
contentHash: args.candidateContentHash,
};
}
@@ -2,20 +2,25 @@
/* oxlint-disable typescript/no-explicit-any -- Test-only proof decodes live Convex JSON. */
import { execFile } from "node:child_process";
import { createHash } from "node:crypto";
import { appendFile, writeFile } from "node:fs/promises";
import { resolve } from "node:path";
import { promisify } from "node:util";
import { buildControlledCandidateContent } from "./claw-603-claim-proof-helpers";
const EXTERNAL_ID = "patrick-erichsen/skills/html";
const REPO = "patrick-erichsen/skills";
const PATH = "skills/html";
const COMMIT_A = "050daba89f6b6636470add5cb300aac46a412cf8";
const HASH_A = "a47adb2c1ac33c088f664b5187971b63d2b958a7b9f01516d26005ca941a108f";
const FILE_HASH_A = "42d2e89358ea927441dfede45c3b0cf89a21603bc7c32246f098d24a9cbea1ff";
const COMMIT_B = "1111111111111111111111111111111111111111";
const HASH_B = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
const COMMIT_C = "2222222222222222222222222222222222222222";
const HASH_C = "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc";
const PUBLIC_SITE = "https://academic-chihuahua-392.convex.site";
const execFileAsync = promisify(execFile);
function requireEnv(name: string) {
const value = process.env[name]?.trim();
@@ -28,20 +33,13 @@ function assert(value: unknown, message: string): asserts value {
}
async function runCommand(command: string[]) {
const child = Bun.spawn(command, {
const [executable, ...args] = command;
assert(executable, "command executable is required");
const { stdout } = await execFileAsync(executable, args, {
cwd: process.cwd(),
env: process.env,
stdout: "pipe",
stderr: "pipe",
maxBuffer: 100 * 1024 * 1024,
});
const [stdout, stderr, exitCode] = await Promise.all([
new Response(child.stdout).text(),
new Response(child.stderr).text(),
child.exited,
]);
if (exitCode !== 0) {
throw new Error(`${command.join(" ")} failed: ${stderr.trim() || stdout.trim()}`);
}
return stdout.trim();
}
@@ -66,7 +64,7 @@ async function fetchCapture(url: string, init?: RequestInit) {
const startedAt = performance.now();
const response = await fetch(url, init);
const text = await response.text();
let body: unknown = text;
let body: any = text;
try {
body = JSON.parse(text);
} catch {}
@@ -270,6 +268,29 @@ async function applyNativeSnapshot(
});
}
async function cacheControlledPendingCandidateContent(
source: Record<string, any>,
mirror: Record<string, any>,
commit: string,
contentHash: string,
) {
const html = source.skills.find((skill: Record<string, any>) => skill.githubPath === PATH);
assert(html?.githubPendingCandidateId, "controlled native candidate is not pending");
const discovered = buildControlledCandidateContent({
mirror,
expectedExternalId: EXTERNAL_ID,
expectedPath: PATH,
expectedFileHash: FILE_HASH_A,
candidateCommit: commit,
candidateContentHash: contentHash,
});
return await runConvex("githubSkillSync:upsertGitHubSkillCandidateContentInternal", {
candidateId: html.githubPendingCandidateId,
discovered,
commit,
});
}
function mirrorRow(
state: Record<string, any>,
commit: string,
@@ -456,6 +477,14 @@ const correctedObservation = await observeCorrectedMirror(
const sourceAfterFailure = await sourceState();
const correctedClaim = await applyClaimedSnapshot(sourceAfterFailure, COMMIT_B, HASH_B);
await writeCheckpoint("corrected-claim-pending", { correctedClaim });
const correctedPendingSource = await sourceState();
const correctedContent = await cacheControlledPendingCandidateContent(
correctedPendingSource,
mirrorBefore,
COMMIT_B,
HASH_B,
);
await writeCheckpoint("corrected-claim-content-cached", { correctedContent });
const retryMirror = await readMirror();
assert(retryMirror.digest?.claimStatus === "pending", "corrected claim did not become pending");
assert(retryMirror.digest?.claimAttempt === 2, "corrected claim attempt was not two");
@@ -500,6 +529,14 @@ assert(
const nativeFollowup = await applyNativeSnapshot(nativePromoted, COMMIT_C, HASH_C);
await writeCheckpoint("native-followup-pending", { nativeFollowup });
const nativeFollowupPendingSource = await sourceState();
const nativeFollowupContent = await cacheControlledPendingCandidateContent(
nativeFollowupPendingSource,
promotedMirror,
COMMIT_C,
HASH_C,
);
await writeCheckpoint("native-followup-content-cached", { nativeFollowupContent });
const followupFailure = await runConvex("skillsShClaims:applyTestVerdictInternal", {
externalId: EXTERNAL_ID,
phase: "native-followup",
@@ -532,6 +569,14 @@ const restorationPass = await runConvex("skillsShClaims:applyTestVerdictInternal
confirm: "pass-skills-sh-test-native-followup",
});
await writeCheckpoint("native-restoration-passed", { restorationPass });
const restorationPendingSource = await sourceState();
const restorationContent = await cacheControlledPendingCandidateContent(
restorationPendingSource,
promotedMirror,
COMMIT_A,
HASH_A,
);
await writeCheckpoint("native-restoration-content-cached", { restorationContent });
const restoredSource = await sourceState();
const restoredHtml = restoredSource.skills.find(
(skill: Record<string, any>) => skill.githubPath === PATH,
@@ -635,7 +680,13 @@ const proof = {
aliasAfterFollowupFailure,
installAfterFollowupFailure,
},
restoration: { restoration, restorationPass, restoredSource, restoredObservation },
restoration: {
restoration,
restorationPass,
restorationContent,
restoredSource,
restoredObservation,
},
final: {
finalMirror,
finalAlias,
@@ -0,0 +1,452 @@
#!/usr/bin/env bun
/* oxlint-disable typescript/no-explicit-any -- Test-only recovery decodes live Convex JSON. */
import { execFile } from "node:child_process";
import { writeFile } from "node:fs/promises";
import { resolve } from "node:path";
import { promisify } from "node:util";
import {
assertControlledMirrorRecoveryMetadata,
assertControlledProofBookmark,
buildControlledCandidateContent,
classifyClaimRecoveryState,
} from "./claw-603-claim-proof-helpers";
const EXTERNAL_ID = "patrick-erichsen/skills/html";
const REPO = "patrick-erichsen/skills";
const PATH = "skills/html";
const COMMIT_A = "050daba89f6b6636470add5cb300aac46a412cf8";
const HASH_A = "a47adb2c1ac33c088f664b5187971b63d2b958a7b9f01516d26005ca941a108f";
const FILE_HASH_A = "42d2e89358ea927441dfede45c3b0cf89a21603bc7c32246f098d24a9cbea1ff";
const COMMIT_B = "1111111111111111111111111111111111111111";
const HASH_B = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
const PREVIOUS_PROOF_RUN = 30608116457;
const PUBLIC_SITE = "https://academic-chihuahua-392.convex.site";
const RECOVERY_SNAPSHOT_ID = "claw-603-claim-recovery:30608116457";
const PROOF_BOOKMARK = {
id: "w17aeppjxks4v38af24a897fd98bkvfp",
skillId: "kd712b24dhkftgq5pt88gctehx8b6g9v",
userId: "kn746c8fb39xg3pachtrd40fgd8akgxr",
createdAt: 1785477444440,
hourlyStatsRecordedAt: 1785477444440,
};
const EXPECTED_MIRROR_RECOVERY_METADATA = {
digest: {
externalId: EXTERNAL_ID,
sourceType: "github",
upstreamSourceType: "controlled-github",
owner: "patrick-erichsen",
repo: "skills",
slug: "html",
displayName: "HTML Artifact Chooser",
sourceUrl: "https://www.skills.sh/patrick-erichsen/skills/html",
canonicalRepoUrl: "https://github.com/patrick-erichsen/skills",
githubPath: PATH,
upstreamInstalls: 123,
upstreamScanners: {
genAgentTrustHub: { status: "unavailable" },
snyk: { status: "unavailable" },
socket: { status: "unavailable" },
},
inferredCategories: ["other"],
inferredTopics: [],
inferredCategoryConfidence: "low",
inferredTopicConfidence: "low",
inferredClassifierVersion: "taxonomy-prototype-v9",
inferredTopicClassifierVersion: "topic-prototype-v1",
inferredInputHash: "5cd78db114746ff695441cc98f9560f0ac09876ccfaecff572ddfe07039f7045",
inferredTopicInputHash: "0f0d55bfc10574035d704c182e7054da83f1240d30185e8486cf928e58475ec7",
inferredAt: 1784788731652,
},
detail: {
contentKind: "skill-md",
path: "skills/html/SKILL.md",
contentSha256: FILE_HASH_A,
contentBytes: 5688,
sourceBytes: 5688,
sourceFileCount: 1,
truncated: false,
},
};
const execFileAsync = promisify(execFile);
function requireEnv(name: string) {
const value = process.env[name]?.trim();
if (!value) throw new Error(`${name} is required`);
return value;
}
function assert(value: unknown, message: string): asserts value {
if (!value) throw new Error(message);
}
async function runCommand(command: string[]) {
const [executable, ...args] = command;
assert(executable, "command executable is required");
const { stdout } = await execFileAsync(executable, args, {
cwd: process.cwd(),
env: process.env,
maxBuffer: 100 * 1024 * 1024,
});
return stdout.trim();
}
async function runConvex(functionName: string, args: Record<string, unknown>) {
const output = await runCommand([
"bunx",
"convex",
"run",
"--no-push",
functionName,
JSON.stringify(args),
]);
return JSON.parse(output) as Record<string, any>;
}
async function runInline(query: string) {
const output = await runCommand(["bunx", "convex", "run", "--no-push", "--inline-query", query]);
return JSON.parse(output) as Record<string, any>;
}
const operatorToken = requireEnv("CLAWHUB_TEST_OPERATOR_TOKEN");
const mirrorGateUrl = requireEnv("CLAWHUB_TEST_MIRROR_GATE_URL");
const outputPath = resolve(
process.env.CLAWHUB_CLAIM_PROOF_OUTPUT?.trim() || "claw-603-claim-recovery.json",
);
async function postMirror(body: Record<string, unknown>) {
const response = await fetch(mirrorGateUrl, {
method: "POST",
headers: {
Accept: "application/json",
Authorization: `Bearer ${operatorToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
const text = await response.text();
assert(response.status === 200, `mirror ${String(body.operation)} returned ${response.status}`);
return JSON.parse(text) as Record<string, any>;
}
async function sourceState() {
return await runInline(`
const source = await ctx.db.query("githubSkillSources")
.withIndex("by_repo", q => q.eq("repo", "${REPO}"))
.unique();
if (!source) return null;
const skills = await ctx.db.query("skills")
.withIndex("by_github_source", q => q.eq("githubSourceId", source._id))
.collect();
const candidates = [];
for (const skill of skills) {
if (skill.githubPendingCandidateId) {
candidates.push(await ctx.db.get(skill.githubPendingCandidateId));
}
}
return {source, skills, candidates};
`);
}
async function queueState() {
return await runInline(`
const requests = await ctx.db.query("skillScanRequests").take(1001);
const jobs = await ctx.db.query("securityScanJobs").take(1001);
return {
requestIds: requests.map(row => row._id).sort(),
jobIds: jobs.map(row => row._id).sort(),
// Candidate promotion and mirror processing do not write scan jobs; this detects any
// out-of-contract mutation even when the bounded queue identities stay unchanged.
jobUpdatedAtSum: jobs.reduce((sum, row) => sum + row.updatedAt, 0),
requestsTruncated: requests.length > 1000,
jobsTruncated: jobs.length > 1000,
};
`);
}
async function proofBookmarkState() {
return await runInline(`
const star = await ctx.db.query("stars")
.withIndex("by_skill_user", q => q
.eq("skillId", "${PROOF_BOOKMARK.skillId}")
.eq("userId", "${PROOF_BOOKMARK.userId}"))
.unique();
const skill = await ctx.db.get("${PROOF_BOOKMARK.skillId}");
return {star, skill};
`);
}
function mirrorRow(state: Record<string, any>) {
const { digest, detail } = state;
assert(digest && detail, "controlled mirror row and detail are required");
// skillsShMirror.rowValidator has no summary field; searchable summary text is derived from
// the exact detail content below rather than copied as independent mirror metadata.
assert(digest.summary === undefined, "controlled mirror has unsupported summary metadata");
return {
externalId: digest.externalId,
sourceType: digest.sourceType,
upstreamSourceType: digest.upstreamSourceType,
owner: digest.owner,
repo: digest.repo,
slug: digest.slug,
displayName: digest.displayName,
sourceUrl: digest.sourceUrl,
canonicalRepoUrl: digest.canonicalRepoUrl,
githubPath: digest.githubPath,
githubCommit: COMMIT_A,
sourceContentHash: HASH_A,
upstreamInstalls: digest.upstreamInstalls,
upstreamScanners: digest.upstreamScanners,
inferredCategories: digest.inferredCategories,
inferredTopics: digest.inferredTopics,
inferredCategoryConfidence: digest.inferredCategoryConfidence,
inferredTopicConfidence: digest.inferredTopicConfidence,
inferredClassifierVersion: digest.inferredClassifierVersion,
inferredTopicClassifierVersion: digest.inferredTopicClassifierVersion,
inferredInputHash: digest.inferredInputHash,
inferredTopicInputHash: digest.inferredTopicInputHash,
inferredAt: digest.inferredAt,
detail: {
contentKind: detail.contentKind,
path: detail.path,
content: detail.content,
contentBytes: detail.contentBytes,
sourceBytes: detail.sourceBytes,
sourceFileCount: detail.sourceFileCount,
truncated: detail.truncated,
},
};
}
async function restoreMirror(state: Record<string, any>) {
const run = await runConvex("skillsShMirror:startRunInternal", {
actor: "CLAW-603 permanent Test claim recovery",
reason: "restore exact controlled mirror after completed claim proof",
snapshotId: RECOVERY_SNAPSHOT_ID,
sourceTotal: 1,
sourcePageSize: 1,
sourceMeasuredAt: new Date().toISOString(),
sourceRequests: 0,
sourceDurationMs: 0,
});
const leaseToken = `claw-603-claim-recovery-${Date.now()}`;
await runConvex("skillsShMirror:claimBatchLeaseInternal", {
runId: run.runId,
page: 0,
offset: 0,
leaseToken,
});
const processed = await runConvex("skillsShMirror:processBatchInternal", {
runId: run.runId,
page: 0,
offset: 0,
leaseToken,
pageLength: 1,
hasMore: false,
sourceTotal: 1,
sourceRequests: 0,
sourceBytes: 0,
rows: [mirrorRow(state)],
});
const canceled = await runConvex("skillsShMirror:cancelRunInternal", {
runId: run.runId,
actor: "CLAW-603 permanent Test claim recovery",
reason: "exact controlled row recovery complete",
confirm: "cancel-skills-sh-mirror-test-run",
});
return { run, processed, canceled };
}
const startedAt = new Date().toISOString();
const statusBefore = await postMirror({ operation: "status" });
const activeRuns = statusBefore.runs.filter((run: Record<string, any>) =>
["running", "paused", "reconciling"].includes(run.status),
);
assert(activeRuns.length === 0, "skills.sh mirror recovery requires no active run");
const [mirrorBefore, sourceBefore, bookmarkBefore, queuesBefore, isolationBefore] =
await Promise.all([
postMirror({ operation: "read", externalId: EXTERNAL_ID }),
sourceState(),
proofBookmarkState(),
queueState(),
runConvex("skillsShMirror:getIsolationInternal", {}),
]);
assert(
!queuesBefore.requestsTruncated && !queuesBefore.jobsTruncated,
"scan queues were truncated",
);
assert(mirrorBefore.digest?.claimStatus === "promoted", "controlled claim is not promoted");
assert(
mirrorBefore.digest?.publicVisible === false,
"controlled claimed row is unexpectedly public",
);
assert(sourceBefore?.source?.repo === REPO, "controlled native source is missing");
const htmlBefore = sourceBefore.skills.find(
(skill: Record<string, any>) => skill.githubPath === PATH,
);
assert(htmlBefore, "controlled native source is missing the HTML skill");
const proofBookmarkPresent = bookmarkBefore.star !== null;
const recoveryPhase = classifyClaimRecoveryState({
mirrorCommit: mirrorBefore.digest.githubCommit,
nativeCommit: htmlBefore.githubCurrentCommit,
pendingCandidate: Boolean(htmlBefore.githubPendingCandidateId),
proofBookmark: proofBookmarkPresent,
restoredCommit: COMMIT_A,
contaminatingCommit: COMMIT_B,
});
assert(
mirrorBefore.digest.sourceContentHash ===
(mirrorBefore.digest.githubCommit === COMMIT_A ? HASH_A : HASH_B),
"controlled mirror residue hash mismatch",
);
assert(
htmlBefore.githubCurrentContentHash ===
(htmlBefore.githubCurrentCommit === COMMIT_A ? HASH_A : HASH_B),
"controlled native residue hash mismatch",
);
const pending = sourceBefore.candidates.find(
(candidate: Record<string, any>) => candidate?._id === htmlBefore.githubPendingCandidateId,
);
assertControlledMirrorRecoveryMetadata({
mirror: mirrorBefore,
expected: EXPECTED_MIRROR_RECOVERY_METADATA,
});
if (proofBookmarkPresent) {
assertControlledProofBookmark({
star: bookmarkBefore.star,
expected: PROOF_BOOKMARK,
currentSkillStars: bookmarkBefore.skill?.statsStars,
baselineSkillStars: 0,
});
} else {
assert(bookmarkBefore.skill?.statsStars === 0, "controlled Bookmark count is not restored");
}
let discovered: ReturnType<typeof buildControlledCandidateContent> | null = null;
if (htmlBefore.githubCurrentCommit === COMMIT_B) {
assert(pending?.githubCommit === COMMIT_A, "restoration candidate commit mismatch");
assert(pending?.githubContentHash === HASH_A, "restoration candidate hash mismatch");
assert(pending?.scanStatus === "clean", "restoration candidate verdict is not clean");
assert(pending?.lifecycleStatus === "pending", "restoration candidate is not pending");
discovered = buildControlledCandidateContent({
mirror: mirrorBefore,
expectedExternalId: EXTERNAL_ID,
expectedPath: PATH,
expectedFileHash: FILE_HASH_A,
candidateCommit: COMMIT_A,
candidateContentHash: HASH_A,
});
if (pending.skillMarkdown !== undefined) {
assert(
pending.skillMarkdownPath === discovered.skillMarkdownPath &&
pending.skillMarkdown === discovered.skillMarkdown,
"cached restoration candidate content mismatch",
);
}
}
const mirrorRecovery =
mirrorBefore.digest.githubCommit === COMMIT_B
? await restoreMirror(mirrorBefore)
: { skipped: true, reason: "mirror already restored" };
let contentRecovery: Record<string, any> = {
skipped: true,
reason: "native candidate already restored",
};
if (discovered) {
contentRecovery = await runConvex("githubSkillSync:upsertGitHubSkillCandidateContentInternal", {
candidateId: pending._id,
discovered,
commit: COMMIT_A,
});
assert(contentRecovery.promoted === true, "cached restoration candidate did not promote");
}
const restoredSource = await sourceState();
const restoredHtml = restoredSource.skills.find(
(skill: Record<string, any>) => skill.githubPath === PATH,
);
assert(restoredHtml?.githubCurrentCommit === COMMIT_A, "native source commit was not restored");
assert(restoredHtml?.githubCurrentContentHash === HASH_A, "native source hash was not restored");
assert(!restoredHtml?.githubPendingCandidateId, "native source still has a pending candidate");
const starRestoration = proofBookmarkPresent
? await runConvex("stars:removeStarInternal", {
userId: PROOF_BOOKMARK.userId,
skillId: PROOF_BOOKMARK.skillId,
})
: { skipped: true, reason: "proof Bookmark already restored" };
if (proofBookmarkPresent) {
assert(starRestoration.unstarred === true, "exact proof Bookmark was not removed");
}
const [
mirrorAfter,
sourceAfter,
bookmarkAfter,
queuesAfter,
isolationAfter,
alias,
installResponse,
] = await Promise.all([
postMirror({ operation: "read", externalId: EXTERNAL_ID }),
sourceState(),
proofBookmarkState(),
queueState(),
runConvex("skillsShMirror:getIsolationInternal", {}),
runConvex("skillsShMirrorPublic:getByRoute", {
owner: "patrick-erichsen",
repo: "skills",
slug: "html",
}),
fetch(`${PUBLIC_SITE}/api/v1/skills-sh/${EXTERNAL_ID}/install`).then(async (response) => ({
status: response.status,
body: (await response.json()) as Record<string, any>,
})),
]);
const htmlAfter = sourceAfter.skills.find(
(skill: Record<string, any>) => skill.githubPath === PATH,
);
assert(mirrorAfter.digest?.claimStatus === "promoted", "restored mirror claim changed");
assert(mirrorAfter.digest?.githubCommit === COMMIT_A, "restored mirror commit mismatch");
assert(mirrorAfter.digest?.sourceContentHash === HASH_A, "restored mirror hash mismatch");
assert(mirrorAfter.digest?.publicVisible === false, "restored claimed mirror became public");
assert(htmlAfter?.githubCurrentCommit === COMMIT_A, "final native commit mismatch");
assert(htmlAfter?.githubCurrentContentHash === HASH_A, "final native hash mismatch");
assert(bookmarkAfter.star === null, "controlled proof Bookmark still exists");
assert(bookmarkAfter.skill?.statsStars === 0, "controlled Bookmark count was not restored");
assert(alias.kind === "redirect", "restored compatibility route is not a redirect");
assert(installResponse.status === 200, "restored compatibility install failed");
assert(installResponse.body?.github?.commit === COMMIT_A, "restored install commit mismatch");
assert(installResponse.body?.github?.contentHash === HASH_A, "restored install hash mismatch");
assert(JSON.stringify(queuesAfter) === JSON.stringify(queuesBefore), "scan queues changed");
assert(
JSON.stringify(isolationAfter) === JSON.stringify(isolationBefore),
"scan isolation changed",
);
const proof = {
ok: true,
startedAt,
completedAt: new Date().toISOString(),
target: { environment: "permanent Test", productionWrites: 0 },
resumedFromProofRun: PREVIOUS_PROOF_RUN,
recoveryPhase,
recoveryBoundary: "exact pending commit-A candidate content cache and normal promotion",
restoration: {
contentRecovery,
restoredSource,
mirrorRecovery,
restoredObservation: mirrorAfter,
},
bookmarkBefore,
final: { mirrorAfter, sourceAfter, bookmarkAfter, alias, installResponse, starRestoration },
isolationBefore,
isolationAfter,
queuesBefore,
queuesAfter,
scansPlanned: 0,
scansAdmitted: 0,
paidScans: 0,
};
await writeFile(outputPath, `${JSON.stringify(proof, null, 2)}\n`, "utf8");
process.stdout.write(`${JSON.stringify(proof)}\n`);