{"version":3,"file":"workspace-verification.d.ts","sourceRoot":"","sources":["../../../src/core/reliability/workspace-verification.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D,MAAM,WAAW,4BAA4B;IAC5C,yDAAyD;IACzD,GAAG,EAAE,MAAM,CAAC;IACZ,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kDAAkD;IAClD,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB;AAID,wBAAgB,mCAAmC,CAAC,OAAO,EAAE,4BAA4B,GAAG,oBAAoB,CAgE/G","sourcesContent":["/**\n * Workspace Verification Executor — real filesystem/process verification for\n * live sessions.\n *\n * Deterministic verification in a real Jensen session needs a provider that can\n * actually run commands, inspect files, search the repository, and read git\n * scope. This adapter implements the VerificationExecutor contract against the\n * session's working directory using the shared `execCommand` helper and\n * node:fs. It is used by the Reliability Kernel's automatic final verification;\n * it never trusts model output.\n */\n\nimport { access, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { execCommand } from \"../exec.js\";\nimport type { VerificationExecutor } from \"./verifier.js\";\n\nexport interface WorkspaceVerificationOptions {\n\t/** Working directory for relative paths and commands. */\n\tcwd: string;\n\t/** Maximum wall-clock time for a single command (default 120s). */\n\tcommandTimeoutMs?: number;\n\t/** Abort signal honoured by spawned processes. */\n\tsignal?: AbortSignal;\n}\n\nconst DEFAULT_COMMAND_TIMEOUT_MS = 120_000;\n\nexport function createWorkspaceVerificationExecutor(options: WorkspaceVerificationOptions): VerificationExecutor {\n\tconst cwd = options.cwd;\n\tconst timeout = options.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;\n\n\tconst resolvePath = (p: string, cwdOverride?: string): string => {\n\t\tconst base = cwdOverride ?? cwd;\n\t\tif (p.startsWith(\"/\") || /^[A-Za-z]:/.test(p)) return p;\n\t\treturn join(base, p);\n\t};\n\n\treturn {\n\t\tasync runCommand(command, cwdOverride) {\n\t\t\tconst result = await execCommand(\"sh\", [\"-c\", command], cwdOverride ?? cwd, {\n\t\t\t\ttimeout,\n\t\t\t\tsignal: options.signal,\n\t\t\t});\n\t\t\t// A timed-out/killed process is reported as a non-zero exit code so a\n\t\t\t// timed-out verification can never be mistaken for success.\n\t\t\treturn {\n\t\t\t\texitCode: result.killed ? 124 : result.code,\n\t\t\t\tstdout: result.stdout,\n\t\t\t\tstderr: result.stderr,\n\t\t\t};\n\t\t},\n\n\t\tasync fileExists(p, cwdOverride) {\n\t\t\ttry {\n\t\t\t\tawait access(resolvePath(p, cwdOverride));\n\t\t\t\treturn true;\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\n\t\tasync readFile(p, cwdOverride) {\n\t\t\ttry {\n\t\t\t\treturn await readFile(resolvePath(p, cwdOverride), \"utf8\");\n\t\t\t} catch {\n\t\t\t\treturn \"\";\n\t\t\t}\n\t\t},\n\n\t\tasync searchMatches(pattern, cwdOverride) {\n\t\t\tconst result = await execCommand(\"grep\", [\"-rl\", \"--\", pattern, \".\"], cwdOverride ?? cwd, {\n\t\t\t\ttimeout: 30_000,\n\t\t\t\tsignal: options.signal,\n\t\t\t});\n\t\t\treturn result.stdout\n\t\t\t\t.split(\"\\n\")\n\t\t\t\t.map((line) => line.trim())\n\t\t\t\t.filter((line) => line.length > 0);\n\t\t},\n\n\t\tasync gitChangedPaths(cwdOverride) {\n\t\t\tconst result = await execCommand(\"git\", [\"diff\", \"--name-only\"], cwdOverride ?? cwd, {\n\t\t\t\ttimeout: 30_000,\n\t\t\t\tsignal: options.signal,\n\t\t\t});\n\t\t\treturn result.stdout\n\t\t\t\t.split(\"\\n\")\n\t\t\t\t.map((line) => line.trim())\n\t\t\t\t.filter((line) => line.length > 0);\n\t\t},\n\t};\n}\n"]}