import { existsSync, readFileSync } from "node:fs"; import { join } from "node:path"; import type { ActiveRun } from "./types.ts"; import { runRoot } from "./paths.ts"; import { hasEvidenceEntry } from "./evidence.ts"; export const SDK_SIGNATURE_EVIDENCE = "evidence/sdk-signature.md"; export function requiresSdkSignatureEvidence(run: ActiveRun): boolean { if (run.mode !== "normal") return false; const language = run.profile?.language; return language === "java" || language === "csharp"; } export function hasValidSdkSignatureEvidence(cwd: string, run: ActiveRun): boolean { if (!requiresSdkSignatureEvidence(run)) return true; const path = join(runRoot(cwd, run), SDK_SIGNATURE_EVIDENCE); if (!existsSync(path)) return false; if (!hasEvidenceEntry(cwd, run, SDK_SIGNATURE_EVIDENCE)) return false; const content = readFileSync(path, "utf8"); return /(退出码|Exit)\s*[::]\s*0/i.test(content) && /(来源|Sources?)\s*[::]/i.test(content); } /** * @deprecated SDK signature write blocking is now handled by V2 SourceWritePolicy * via GateRunner. Other SDK utility functions remain active. * @see src/harness/gates/policies/source-write-policy.ts */ export function sdkSignatureProductionWriteBlockReason(_cwd: string, _run: ActiveRun | undefined, _path: string | undefined): string | undefined { return undefined; } function normalizeRelativePath(path: string): string { return path.replace(/\\/g, "/").replace(/^\.\//, "").replace(/^\/+/, ""); }