{"version":3,"file":"check-profiles.d.ts","sourceRoot":"","sources":["../../src/evolve/check-profiles.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;AAE5E;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC9B,aAAa,EAAE,CAAC,CAAC;IACjB,OAAO,EAAE,eAAe,CAAC;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,4BAA4B,EAAE,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,WAAW,CAAC,sBAAsB,CAAC,CAAC,CAM9G,CAAC;AAEF,eAAO,MAAM,+BAA+B,EAAE,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,WAAW,CAAC,sBAAsB,CAAC,CAAC,CAEjH,CAAC;AAEF,wBAAgB,kBAAkB,CACjC,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,WAAW,CAAC,sBAAsB,CAAC,CAAC,CAAC,EACnF,IAAI,EAAE,sBAAsB,GAC1B,GAAG,CAAC,eAAe,CAAC,CAMtB;AAMD,wBAAsB,mBAAmB,CACxC,KAAK,EAAE,QAAQ,EACf,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,IAAI,CAAC,cAAc,EAAE,eAAe,GAAG,YAAY,CAAC,GAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GACrF,OAAO,CAAC,cAAc,CAAC,CAYzB;AAED,wBAAsB,mBAAmB,CACxC,KAAK,EAAE,QAAQ,EACf,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,WAAW,CAAC,eAAe,EAAE,cAAc,CAAC,CAAC,CAkBvD","sourcesContent":["import { mkdir, readdir, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { EvoPaths } from \"../paths.ts\";\nimport { atomicWriteJson } from \"../storage.ts\";\nimport type { EvoCheckProfile } from \"../types.ts\";\nimport { evolutionRunDirectory } from \"./run.ts\";\n\nexport type EvolutionCandidateKind = \"none\" | \"data\" | \"component\" | \"code\";\n\n/**\n * A receipt is the one and only representation of \"this check actually executed\".\n * It is written exclusively by the code that performed the execution; the release\n * gate reads receipts and nothing else. Declarations never count as execution.\n */\nexport interface ProfileReceipt {\n\tschemaVersion: 1;\n\tprofile: EvoCheckProfile;\n\tpassed: boolean;\n\texecutedAt: string;\n\t/** Human-readable one-liner about what ran (command, scenario, scope). */\n\tsummary: string;\n\t/** Digest or path of the produced artifact, when one exists. */\n\tartifact?: string;\n}\n\n/**\n * Capability table: which profiles can actually execute before release, per\n * candidate kind. A plan can only require what the system can execute — the\n * declarable set is derived from this table, never maintained separately.\n *\n * session-comparison and compaction-replay are absent: the former only runs\n * during the post-release trial retrospective, the latter has no executor yet.\n * Neither can therefore be a pre-release requirement.\n */\nexport const OFFLINE_PROFILE_CAPABILITIES: Partial<Record<EvoCheckProfile, ReadonlySet<EvolutionCandidateKind>>> = {\n\t// \"none\" plans freeze an experiment that is never built; they may describe the\n\t// checks a future candidate would need without blocking on execution.\n\t\"bundle-compile\": new Set([\"none\", \"data\", \"component\", \"code\"]),\n\t\"repo-check\": new Set([\"code\"]),\n\t\"related-tests\": new Set([\"code\", \"component\"]),\n};\n\nexport const HISTORICAL_PROFILE_CAPABILITIES: Partial<Record<EvoCheckProfile, ReadonlySet<EvolutionCandidateKind>>> = {\n\t\"paired-replay\": new Set([\"none\", \"data\", \"component\", \"code\"]),\n};\n\nexport function declarableProfiles(\n\tcapabilities: Partial<Record<EvoCheckProfile, ReadonlySet<EvolutionCandidateKind>>>,\n\tkind: EvolutionCandidateKind,\n): Set<EvoCheckProfile> {\n\tconst declarable = new Set<EvoCheckProfile>();\n\tfor (const [profile, kinds] of Object.entries(capabilities)) {\n\t\tif (kinds?.has(kind)) declarable.add(profile as EvoCheckProfile);\n\t}\n\treturn declarable;\n}\n\nfunction receiptsDirectory(paths: EvoPaths, runId: string): string {\n\treturn join(evolutionRunDirectory(paths, runId), \"receipts\");\n}\n\nexport async function writeProfileReceipt(\n\tpaths: EvoPaths,\n\trunId: string,\n\treceipt: Omit<ProfileReceipt, \"schemaVersion\" | \"executedAt\"> & { executedAt?: string },\n): Promise<ProfileReceipt> {\n\tconst complete: ProfileReceipt = {\n\t\tschemaVersion: 1,\n\t\texecutedAt: receipt.executedAt ?? new Date().toISOString(),\n\t\tprofile: receipt.profile,\n\t\tpassed: receipt.passed,\n\t\tsummary: receipt.summary,\n\t\t...(receipt.artifact ? { artifact: receipt.artifact } : {}),\n\t};\n\tawait mkdir(receiptsDirectory(paths, runId), { recursive: true });\n\tawait atomicWriteJson(join(receiptsDirectory(paths, runId), `${complete.profile}.json`), complete);\n\treturn complete;\n}\n\nexport async function readProfileReceipts(\n\tpaths: EvoPaths,\n\trunId: string,\n): Promise<ReadonlyMap<EvoCheckProfile, ProfileReceipt>> {\n\tconst receipts = new Map<EvoCheckProfile, ProfileReceipt>();\n\tlet entries: string[];\n\ttry {\n\t\tentries = await readdir(receiptsDirectory(paths, runId));\n\t} catch (error) {\n\t\tif ((error as { code?: string }).code === \"ENOENT\") return receipts;\n\t\tthrow error;\n\t}\n\tfor (const entry of entries) {\n\t\tif (!entry.endsWith(\".json\")) continue;\n\t\tconst value = JSON.parse(await readFile(join(receiptsDirectory(paths, runId), entry), \"utf8\")) as ProfileReceipt;\n\t\tif (value.schemaVersion !== 1 || typeof value.profile !== \"string\" || typeof value.passed !== \"boolean\") {\n\t\t\tthrow new Error(`Profile receipt ${entry} is invalid`);\n\t\t}\n\t\treceipts.set(value.profile, value);\n\t}\n\treturn receipts;\n}\n"]}