fix: harden CI evidence and removal contracts

This commit is contained in:
DongHyeonka
2026-08-02 14:48:04 +09:00
parent 1bb2cc4a20
commit f49d147b01
20 changed files with 1175 additions and 767 deletions
+9 -3
View File
@@ -28,6 +28,7 @@ export type GenerateCiWorkflowOptions = Readonly<{
root: string;
contract?: CiGateContract;
check: boolean;
contractMode?: "canonical" | "removal-fixture";
}>;
export type GenerateCiWorkflowResult = Readonly<{
@@ -176,7 +177,7 @@ function renderStep(
" - name: Frozen install",
" run: |",
" corepack enable",
" corepack pnpm install --frozen-lockfile",
" corepack pnpm install --frozen-lockfile --ignore-scripts",
];
case "browser-install":
return [
@@ -335,7 +336,9 @@ export function createCiWorkflowGenerator(
const createNonce = dependencies.createNonce ?? randomUUID;
return async function generate(options: GenerateCiWorkflowOptions): Promise<GenerateCiWorkflowResult> {
const root = path.resolve(options.root);
const contract = options.contract ?? (await loadCiGateContract(root));
const contract = options.contract ?? (await loadCiGateContract(root, {
mode: options.contractMode ?? "canonical",
}));
const target = path.resolve(root, contract.providerAdapter);
if (path.relative(root, target).startsWith("..") || path.relative(root, target) === "") {
throw new TypeError(`workflow target escapes repository root: ${contract.providerAdapter}`);
@@ -449,8 +452,11 @@ function hasErrorCode(error: unknown, code: string): boolean {
const isCli = process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
if (isCli) {
const check = process.argv.includes("--check");
const contractMode = process.argv.includes("--reduced-removal-fixture")
? "removal-fixture" as const
: "canonical" as const;
try {
const result = await generateCiWorkflow({ root: process.cwd(), check });
const result = await generateCiWorkflow({ root: process.cwd(), check, contractMode });
if (!result.matches) {
process.stderr.write(
`CI workflow drift: ${result.target} differs at byte ${result.firstDifferenceByte ?? 0}, line ${result.firstDifferenceLine ?? 1}\n`,