diff --git a/CHANGELOG.md b/CHANGELOG.md index dcc1ba1..2e0bd56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,28 @@ ## Unreleased +### Telemetry, Token-Conservation Analytics & Operational Reporting — vNext.10.2 Phase 9 + +- Added a versioned Job/Mission execution telemetry report derived from + durable WorkUnit, routing, attempt, research, cooldown, verification, + closure, and autonomy facts. Reports keep unknown usage as `null`, expose + coverage, deduplicate replayed attempt IDs, redact diagnostics, and remain + observational rather than granting authority or completion. +- Added formal Secondary success/repair/fallback funnels, + `StrongBuilderAvoidanceRatio` with Strong evaluator separation, Strong + direct/fallback attribution, research avoidance/reuse and lifecycle + breakdowns, cooldown productivity/avoidable-idle diagnostics, restart and + candidate reuse accounting, completed-work redo detection, and a compact + Phase 10-compatible qualification summary. +- Added `specbridge report job ` with JSON and verbose formats plus the + read-only MCP `job_report` tool. CLI reports persist under + `.specbridge/reports/` by default; MCP derives the same contract without + writing runtime state. +- Added deterministic mixed-compute, Strong-only replay, research, cooldown, + restart/deduplication, token coverage, intervention, reliability, old-Job, + corruption, CLI, and MCP qualification coverage, and regenerated the public + contracts, tool reference, and Claude/Codex plugin bundles. + ### Subscription Cooldown Continuation & Compute Survival — vNext.10.2 Phase 8 - Added durable, resource-scoped Strong subscription cooldown state at the diff --git a/contracts/cli-commands.json b/contracts/cli-commands.json index 3fe381d..ddf6825 100644 --- a/contracts/cli-commands.json +++ b/contracts/cli-commands.json @@ -761,6 +761,21 @@ } } }, + "report": { + "options": [ + "--help" + ], + "subcommands": { + "job": { + "options": [ + "--help", + "--json", + "--no-persist", + "--verbose" + ] + } + } + }, "research": { "options": [ "--help" diff --git a/contracts/mcp-contract.json b/contracts/mcp-contract.json index 1bfd6ad..1f08dd9 100644 --- a/contracts/mcp-contract.json +++ b/contracts/mcp-contract.json @@ -27,6 +27,7 @@ "job_cancel", "job_list", "job_read", + "job_report", "mission_answer", "mission_assess", "mission_begin", diff --git a/docs/README.md b/docs/README.md index a5cfe13..a669e48 100644 --- a/docs/README.md +++ b/docs/README.md @@ -129,6 +129,9 @@ the intent in the evening, run one command, read the report in the morning. self-repair that cannot weaken its own constraints. - [Autonomy telemetry](autonomy/telemetry.md) — the honest report, where an unknown is `null` and never zero. +- [Execution telemetry and token conservation](autonomy/execution-telemetry.md) + — versioned Phase 9 Job/WorkUnit routing, research, cooldown, reliability, + verification, and closure analytics without new authority. - [Zero-touch certification](autonomy/certification.md) — the sixteen-fault matrix, and the three defects it found. - [Operator setup](autonomy/operator-setup.md) — the evening checklist. @@ -243,7 +246,7 @@ the intent in the evening, run one command, read the report in the morning. ## MCP & frontend plugins - [MCP server](mcp-server.md) — the local stdio server. -- [MCP tool reference](mcp/tool-reference.md) — all 77 tools (generated). +- [MCP tool reference](mcp/tool-reference.md) — all 78 tools (generated). - [MCP tools](mcp-tools.md) · [resources](mcp-resources.md) · [prompts](mcp-prompts.md) · [CLI/MCP parity](cli-mcp-parity.md). - [Claude Code integration](claude-code-integration.md) — both directions. diff --git a/docs/autonomy/execution-telemetry.md b/docs/autonomy/execution-telemetry.md new file mode 100644 index 0000000..c8d75ee --- /dev/null +++ b/docs/autonomy/execution-telemetry.md @@ -0,0 +1,93 @@ +# Execution telemetry and token-conservation reports + +Phase 9 turns durable Job, WorkUnit, routing, research, cooldown, +verification, closure, and autonomy records into one versioned operational +report. The report is observational: it cannot approve work, change routing, +grant authority, or make a Job complete. + +## Read a report + +```bash +specbridge report job +specbridge report job --verbose +specbridge report job --json +``` + +The human view is concise by default. `--verbose` adds bounded WorkUnit +accounting and the cooldown timeline. The JSON view carries +`schemaVersion: "1.0.0"` and, unless `--no-persist` is used, is saved at +`.specbridge/reports/job--telemetry.json`. + +MCP clients can call the read-only `job_report` tool. It derives the same +report without persisting a file. + +## Formal metric definitions + +A ratio is represented as `{ numerator, denominator, value }`. `value` is +`null` when the denominator is zero or the underlying durable facts do not +exist. Unknown measurements are never reported as zero. + +| Metric | Numerator | Denominator | Exclusions and unknown semantics | +| --- | --- | --- | --- | +| `StrongBuilderAvoidanceRatio` | Eligible, completed implementation WorkUnits with no `STRONG` or `STRONG_FALLBACK` builder attempt | Eligible, completed implementation WorkUnits | Excludes `STRONG_REQUIRED`, cancelled, authority-pending, research-pending, context-pending, and incomplete work. A Strong evaluator is not a Strong Builder. `null` when no eligible implementation WorkUnit completed. | +| `SecondaryInitialSuccessRate` | WorkUnits whose initial `SECONDARY` attempt passed without repair | WorkUnits with an initial `SECONDARY` attempt | `null` when Secondary was never initially attempted. Replayed attempt IDs are counted once. | +| `SecondaryRepairRecoveryRate` | WorkUnits whose `SECONDARY_REPAIR` path passed | WorkUnits that received a `SECONDARY_REPAIR` attempt | `null` when repair was never attempted. | +| `SecondaryToStrongFallbackRate` | Secondary-attempted WorkUnits that later used `STRONG_FALLBACK` | WorkUnits with any Secondary implementation attempt | `null` when Secondary was never attempted. | +| `ResearchAvoidanceRatio` | Research-gate considerations resolved without a new QUICK or DEEP provider call | Research-gate considerations | `null` where gate aggregates are unavailable. The report labels existing aggregate gate telemetry as `WORKSPACE`; it does not pretend it is Job-scoped. Job-scoped provider records remain Job-scoped. | +| `ResearchReuseRate` | Reused prior research reports | Reused reports plus new provider calls | `null` when neither reuse nor a new call occurred. | +| `UsefulWorkDuringSubscriptionCooldown` | Distinct WorkUnits durably recorded as completed during a Strong subscription cooldown | Not a ratio | Includes productive Secondary and research progress while Strong-required work waits. Duplicate WorkUnit IDs within the same objective are counted once. | +| `ZeroTouchAfterSeal` | `true` only when `humanInterventionsAfterSeal` is zero | Not a ratio | Correct authority escalation is reported separately. A missing seal boundary is diagnosed by the underlying autonomy telemetry; it is never inferred from a successful outcome. | +| `CompletedWorkRedoCount` | Implementation attempts that began after the same WorkUnit had already been durably integrated | Not a ratio | Resource waits and replayed copies of the same durable attempt ID are excluded. Candidate reuse and restart recovery are reported separately. | + +## Work accounting + +Every current WorkUnit belongs to exactly one reporting category: +`completed`, `failed`, `cancelled`, `waiting`, `not-ready`, +`human-authority-pending`, `research-pending`, or `context-pending`. This is +reporting classification only and does not alter the WorkUnit state machine. + +The same accounting is rolled up per Objective and for the whole Job; +`missionId` links the Job report to its sealed Mission when that durable +binding exists. Secondary eligibility reports both the eligible total and an +explicit ineligible total, with Strong-required, research, authority, +context, and not-ready reasons kept separate. + +Implementation builder calls and evaluator calls are separate populations. +`STRONG` and `STRONG_FALLBACK` count as Strong Builder calls; +non-local `EVALUATOR` ledger entries count only as Strong evaluator calls. + +## Token and research coverage + +Provider-reported input and output tokens are summed only when present. +`knownTokens` is the sum of observed components; `completeTokens` is `null` +unless every attempt reported both components. Coverage states how many +attempts reported any, input, and output usage. Research cost and duration +follow the same rule: absence is `null`, not free or instantaneous. + +Research reports expose `JOB`, `WORKSPACE`, or `NONE` scope. Lifecycle +breakdowns cover conversation, spec draft, intake decision, and runtime +investigation. Workspace-scoped legacy aggregates are explicitly labeled so +cross-Job evidence cannot be mistaken for a Job-only total. + +## Provenance, safety, and compatibility + +The report records Job and objective graph revisions, event and execution +ledger watermarks, seal references, the current non-secret strategy summary, +and whether the current runtime policy differs from the sealed binding. +Diagnostic text is bounded and redacted. Prompts, transcripts, raw provider +payloads, environment secrets, and credentials are never report fields. + +Older Jobs remain reportable. Missing Phase 7/8, research, seal, or closure +records produce empty or `null` sections plus diagnostics rather than +invented facts. Inputs and output arrays are bounded, and duplicate durable +attempt IDs are deterministically deduplicated. + +## Comparing routing strategies + +Efficiency claims require comparable verification and closure outcomes. +The JSON report can carry an explicitly identified observed or qualification +baseline; it reports whether outcomes match before presenting Strong Builder +call reduction. `correctnessEqual` remains false when trusted verification or +closure evidence is unavailable, even when both missing values match. This is +evidence for qualification and operations, not a learned-routing or +production-readiness claim. diff --git a/docs/autonomy/telemetry.md b/docs/autonomy/telemetry.md index 4d0c9fc..b6b2c30 100644 --- a/docs/autonomy/telemetry.md +++ b/docs/autonomy/telemetry.md @@ -89,6 +89,11 @@ first process restart — and process restarts are the normal case here. specbridge autonomy report ``` +For the Phase 9 Job/WorkUnit routing, research, cooldown, token-conservation, +verification, and closure report, see +[Execution telemetry and token conservation](execution-telemetry.md) and run +`specbridge report job `. + ``` Autonomy ✓ humanInterventionsAfterSeal: 0 diff --git a/docs/mcp/tool-reference.md b/docs/mcp/tool-reference.md index 55a665c..91c65e5 100644 --- a/docs/mcp/tool-reference.md +++ b/docs/mcp/tool-reference.md @@ -7,7 +7,7 @@ Generated from the authoritative registries of the `specbridge` MCP server (version 1.1.0). Tool names, resource URI templates, and prompt names are stable contracts — see docs/stability/public-contracts.md. -## Tools (77) +## Tools (78) | Tool | Access | Summary | | --- | --- | --- | @@ -22,6 +22,7 @@ names are stable contracts — see docs/stability/public-contracts.md. | `job_cancel` | write | Cancel a job (final, idempotent, evidence preserved) | | `job_list` | read-only | List long-running orchestration jobs | | `job_read` | read-only | One job in depth: graph, attempts, questions, checkpoint | +| `job_report` | read-only | Durable Job operational and token-conservation report | | `mission_answer` | write | Record the user’s answer to one discovery question | | `mission_assess` | write | Record a governed structured discovery assessment | | `mission_begin` | write | Begin Mission Discovery from a product direction | diff --git a/integrations/claude-code-plugin/specbridge/dist/checksums.json b/integrations/claude-code-plugin/specbridge/dist/checksums.json index 1f7aa92..854fefa 100644 --- a/integrations/claude-code-plugin/specbridge/dist/checksums.json +++ b/integrations/claude-code-plugin/specbridge/dist/checksums.json @@ -7,12 +7,12 @@ "bytes": 155994 }, "cli.cjs": { - "sha256": "9b6d58aef80578e88c81a1c48606cb13ac0d02d41d9acccc7e3cc67348c1c698", - "bytes": 5739368 + "sha256": "91d51d28006410e893ba0f19b1989e0e170a4c2820bf3fd2770a84686777fe2c", + "bytes": 5814917 }, "mcp-server.cjs": { - "sha256": "f096d9dff325c106c15334e6c67baef15771789e5aa2ddd06858894987ae9b4c", - "bytes": 3669226 + "sha256": "0cf0895d3af59c3de92fbf899965f2c093145e1f5aa3bf23846ec59e9a5568d6", + "bytes": 3758229 } } } diff --git a/integrations/claude-code-plugin/specbridge/dist/cli.cjs b/integrations/claude-code-plugin/specbridge/dist/cli.cjs index b8dc769..def6b81 100644 --- a/integrations/claude-code-plugin/specbridge/dist/cli.cjs +++ b/integrations/claude-code-plugin/specbridge/dist/cli.cjs @@ -3597,8 +3597,8 @@ var require_Node = __commonJS({ }; const res = toJS.toJS(this, "", ctx); if (typeof onAnchor === "function") - for (const { count: count3, res: res2 } of ctx.anchors.values()) - onAnchor(res2, count3); + for (const { count: count4, res: res2 } of ctx.anchors.values()) + onAnchor(res2, count4); return typeof reviver === "function" ? applyReviver.applyReviver(reviver, { "": res }, "", res) : res; } }; @@ -3704,13 +3704,13 @@ var require_Alias = __commonJS({ const anchor = anchors2 && source && anchors2.get(source); return anchor ? anchor.count * anchor.aliasCount : 0; } else if (identity3.isCollection(node)) { - let count3 = 0; + let count4 = 0; for (const item of node.items) { const c3 = getAliasCount(doc, item, anchors2); - if (c3 > count3) - count3 = c3; + if (c3 > count4) + count4 = c3; } - return count3; + return count4; } else if (identity3.isPair(node)) { const kc = getAliasCount(doc, node.key, anchors2); const vc = getAliasCount(doc, node.value, anchors2); @@ -6663,8 +6663,8 @@ var require_Document = __commonJS({ }; const res = toJS.toJS(this.contents, jsonArg ?? "", ctx); if (typeof onAnchor === "function") - for (const { count: count3, res: res2 } of ctx.anchors.values()) - onAnchor(res2, count3); + for (const { count: count4, res: res2 } of ctx.anchors.values()) + onAnchor(res2, count4); return typeof reviver === "function" ? applyReviver.applyReviver(reviver, { "": res }, "", res) : res; } /** @@ -6741,12 +6741,12 @@ var require_errors = __commonJS({ lineStr = prev + lineStr; } if (/[^ ]/.test(lineStr)) { - let count3 = 1; + let count4 = 1; const end = error2.linePos[1]; if (end?.line === line && end.col > col) { - count3 = Math.max(1, Math.min(end.col - col, 80 - ci)); + count4 = Math.max(1, Math.min(end.col - col, 80 - ci)); } - const pointer = " ".repeat(ci) + "^".repeat(count3); + const pointer = " ".repeat(ci) + "^".repeat(count4); error2.message += `: ${lineStr} @@ -6765,7 +6765,7 @@ ${pointer} var require_resolve_props = __commonJS({ "../../node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/dist/compose/resolve-props.js"(exports2) { "use strict"; - function resolveProps(tokens, { flow, indicator, next, offset, onError, parentIndent, startOnNewline }) { + function resolveProps(tokens2, { flow, indicator, next, offset, onError, parentIndent, startOnNewline }) { let spaceBefore = false; let atNewline = startOnNewline; let hasSpace = startOnNewline; @@ -6780,7 +6780,7 @@ var require_resolve_props = __commonJS({ let comma = null; let found = null; let start = null; - for (const token of tokens) { + for (const token of tokens2) { if (reqSpace) { if (token.type !== "space" && token.type !== "newline" && token.type !== "comma") onError(token.offset, "MISSING_CHAR", "Tags and anchors must be separated from the next token by white space"); @@ -6871,7 +6871,7 @@ var require_resolve_props = __commonJS({ hasSpace = false; } } - const last = tokens[tokens.length - 1]; + const last = tokens2[tokens2.length - 1]; const end = last ? last.offset + last.source.length : offset; if (reqSpace && next && next.type !== "space" && next.type !== "newline" && next.type !== "comma" && (next.type !== "scalar" || next.source !== "")) { onError(next.offset, "MISSING_CHAR", "Tags and anchors must be separated from the next token by white space"); @@ -8210,8 +8210,8 @@ ${cb}` : comment; * @param forceDoc - If the stream contains no document, still emit a final document including any comments and directives that would be applied to a subsequent document. * @param endOffset - Should be set if `forceDoc` is also set, to set the document range end and to indicate errors correctly. */ - *compose(tokens, forceDoc = false, endOffset = -1) { - for (const token of tokens) + *compose(tokens2, forceDoc = false, endOffset = -1) { + for (const token of tokens2) yield* this.next(token); yield* this.end(forceDoc, endOffset); } @@ -11246,7 +11246,7 @@ var require_scan = __commonJS({ const length = input.length - 1; const scanToEnd = opts.parts === true || opts.scanToEnd === true; const slashes = []; - const tokens = []; + const tokens2 = []; const parts = []; let str = input; let index = -1; @@ -11330,7 +11330,7 @@ var require_scan = __commonJS({ } if (code2 === CHAR_FORWARD_SLASH) { slashes.push(index); - tokens.push(token); + tokens2.push(token); token = { value: "", depth: 0, isGlob: false }; if (finished7 === true) continue; if (prev === CHAR_DOT && index === start + 1) { @@ -11483,9 +11483,9 @@ var require_scan = __commonJS({ if (opts.tokens === true) { state.maxDepth = 0; if (!isPathSeparator(code2)) { - tokens.push(token); + tokens2.push(token); } - state.tokens = tokens; + state.tokens = tokens2; } if (opts.parts === true || opts.tokens === true) { let prevIndex; @@ -11495,13 +11495,13 @@ var require_scan = __commonJS({ const value = input.slice(n2, i2); if (opts.tokens) { if (idx === 0 && start !== 0) { - tokens[idx].isPrefix = true; - tokens[idx].value = prefix; + tokens2[idx].isPrefix = true; + tokens2[idx].value = prefix; } else { - tokens[idx].value = value; + tokens2[idx].value = value; } - depth(tokens[idx]); - state.maxDepth += tokens[idx].depth; + depth(tokens2[idx]); + state.maxDepth += tokens2[idx].depth; } if (idx !== 0 || value !== "") { parts.push(value); @@ -11512,9 +11512,9 @@ var require_scan = __commonJS({ const value = input.slice(prevIndex + 1); parts.push(value); if (opts.tokens) { - tokens[tokens.length - 1].value = value; - depth(tokens[tokens.length - 1]); - state.maxDepth += tokens[tokens.length - 1].depth; + tokens2[tokens2.length - 1].value = value; + depth(tokens2[tokens2.length - 1]); + state.maxDepth += tokens2[tokens2.length - 1].depth; } } state.slashes = slashes; @@ -11791,7 +11791,7 @@ var require_parse2 = __commonJS({ throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); } const bos = { type: "bos", value: "", output: opts.prepend || "" }; - const tokens = [bos]; + const tokens2 = [bos]; const capture = opts.capture ? "" : "?:"; const PLATFORM_CHARS = constants5.globChars(opts.windows); const EXTGLOB_CHARS = constants5.extglobChars(PLATFORM_CHARS); @@ -11836,7 +11836,7 @@ var require_parse2 = __commonJS({ parens: 0, quotes: 0, globstar: false, - tokens + tokens: tokens2 }; input = utils.removePrefix(input, state); len = input.length; @@ -11858,20 +11858,20 @@ var require_parse2 = __commonJS({ consume(token.value); }; const negate = () => { - let count3 = 1; + let count4 = 1; while (peek() === "!" && (peek(2) !== "(" || peek(3) === "?")) { advance(); state.start++; - count3++; + count4++; } - if (count3 % 2 === 0) { + if (count4 % 2 === 0) { return false; } state.negated = true; state.start++; return true; }; - const increment2 = (type) => { + const increment3 = (type) => { state[type]++; stack.push(type); }; @@ -11901,7 +11901,7 @@ var require_parse2 = __commonJS({ return; } tok.prev = prev; - tokens.push(tok); + tokens2.push(tok); prev = tok; }; const extglobOpen = (type, value2) => { @@ -11910,9 +11910,9 @@ var require_parse2 = __commonJS({ token.parens = state.parens; token.output = state.output; token.startIndex = state.index; - token.tokensIndex = tokens.length; + token.tokensIndex = tokens2.length; const output = (opts.capture ? "(" : "") + token.open; - increment2("parens"); + increment3("parens"); push2({ type, value: value2, output: state.output ? "" : ONE_CHAR }); push2({ type: "paren", extglob: true, value: advance(), output }); extglobs.push(token); @@ -11923,14 +11923,14 @@ var require_parse2 = __commonJS({ const analysis = analyzeRepeatedExtglob(body, opts); if ((token.type === "plus" || token.type === "star") && analysis.risky) { const safeOutput = analysis.safeOutput ? (token.output ? "" : ONE_CHAR) + (opts.capture ? `(${analysis.safeOutput})` : analysis.safeOutput) : void 0; - const open = tokens[token.tokensIndex]; + const open = tokens2[token.tokensIndex]; open.type = "text"; open.value = literal2; open.output = safeOutput || utils.escapeRegex(literal2); - for (let i2 = token.tokensIndex + 1; i2 < tokens.length; i2++) { - tokens[i2].value = ""; - tokens[i2].output = ""; - delete tokens[i2].suffix; + for (let i2 = token.tokensIndex + 1; i2 < tokens2.length; i2++) { + tokens2[i2].value = ""; + tokens2[i2].output = ""; + delete tokens2[i2].suffix; } state.output = token.output + open.output; state.backtrack = true; @@ -12053,7 +12053,7 @@ var require_parse2 = __commonJS({ prev.value = pre + posix; state.backtrack = true; advance(); - if (!bos.output && tokens.indexOf(prev) === 1) { + if (!bos.output && tokens2.indexOf(prev) === 1) { bos.output = ONE_CHAR; } continue; @@ -12088,7 +12088,7 @@ var require_parse2 = __commonJS({ continue; } if (value === "(") { - increment2("parens"); + increment3("parens"); push2({ type: "paren", value }); continue; } @@ -12112,7 +12112,7 @@ var require_parse2 = __commonJS({ } value = `\\${value}`; } else { - increment2("brackets"); + increment3("brackets"); } push2({ type: "bracket", value }); continue; @@ -12151,7 +12151,7 @@ var require_parse2 = __commonJS({ continue; } if (value === "{" && opts.nobrace !== true) { - increment2("braces"); + increment3("braces"); const open = { type: "brace", value, @@ -12171,10 +12171,10 @@ var require_parse2 = __commonJS({ } let output = ")"; if (brace.dots === true) { - const arr = tokens.slice(); + const arr = tokens2.slice(); const range = []; for (let i2 = arr.length - 1; i2 >= 0; i2--) { - tokens.pop(); + tokens2.pop(); if (arr[i2].type === "brace") { break; } @@ -12222,7 +12222,7 @@ var require_parse2 = __commonJS({ state.start = state.index + 1; state.consumed = ""; state.output = ""; - tokens.pop(); + tokens2.pop(); prev = bos; continue; } @@ -14602,9 +14602,9 @@ var require_keyword = __commonJS({ if (Array.isArray(def.keyword) ? !def.keyword.includes(keyword) : def.keyword !== keyword) { throw new Error("ajv implementation error"); } - const deps3 = def.dependencies; - if (deps3 === null || deps3 === void 0 ? void 0 : deps3.some((kwd) => !Object.prototype.hasOwnProperty.call(schema, kwd))) { - throw new Error(`parent schema must have dependencies of ${keyword}: ${deps3.join(",")}`); + const deps4 = def.dependencies; + if (deps4 === null || deps4 === void 0 ? void 0 : deps4.some((kwd) => !Object.prototype.hasOwnProperty.call(schema, kwd))) { + throw new Error(`parent schema must have dependencies of ${keyword}: ${deps4.join(",")}`); } if (def.validateSchema) { const valid = def.validateSchema(schema[keyword]); @@ -14884,20 +14884,20 @@ var require_resolve = __commonJS({ return false; } function countKeys(schema) { - let count3 = 0; + let count4 = 0; for (const key in schema) { if (key === "$ref") return Infinity; - count3++; + count4++; if (SIMPLE_INLINED.has(key)) continue; if (typeof schema[key] == "object") { - (0, util_1.eachItem)(schema[key], (sch) => count3 += countKeys(sch)); + (0, util_1.eachItem)(schema[key], (sch) => count4 += countKeys(sch)); } - if (count3 === Infinity) + if (count4 === Infinity) return Infinity; } - return count3; + return count4; } function getFullPath(resolver, id = "", normalize3) { if (normalize3 !== false) @@ -18069,8 +18069,8 @@ var require_contains = __commonJS({ cxt.result(valid, () => cxt.reset()); function validateItemsWithCount() { const schValid = gen.name("_valid"); - const count3 = gen.let("count", 0); - validateItems(schValid, () => gen.if(schValid, () => checkLimits(count3))); + const count4 = gen.let("count", 0); + validateItems(schValid, () => gen.if(schValid, () => checkLimits(count4))); } function validateItems(_valid, block) { gen.forRange("i", 0, len, (i2) => { @@ -18083,16 +18083,16 @@ var require_contains = __commonJS({ block(); }); } - function checkLimits(count3) { - gen.code((0, codegen_1._)`${count3}++`); + function checkLimits(count4) { + gen.code((0, codegen_1._)`${count4}++`); if (max === void 0) { - gen.if((0, codegen_1._)`${count3} >= ${min}`, () => gen.assign(valid, true).break()); + gen.if((0, codegen_1._)`${count4} >= ${min}`, () => gen.assign(valid, true).break()); } else { - gen.if((0, codegen_1._)`${count3} > ${max}`, () => gen.assign(valid, false).break()); + gen.if((0, codegen_1._)`${count4} > ${max}`, () => gen.assign(valid, false).break()); if (min === 1) gen.assign(valid, true); else - gen.if((0, codegen_1._)`${count3} >= ${min}`, () => gen.assign(valid, true)); + gen.if((0, codegen_1._)`${count4} >= ${min}`, () => gen.assign(valid, true)); } } } @@ -18111,14 +18111,14 @@ var require_dependencies = __commonJS({ var util_1 = require_util(); var code_1 = require_code2(); exports2.error = { - message: ({ params: { property, depsCount, deps: deps3 } }) => { + message: ({ params: { property, depsCount, deps: deps4 } }) => { const property_ies = depsCount === 1 ? "property" : "properties"; - return (0, codegen_1.str)`must have ${property_ies} ${deps3} when property ${property} is present`; + return (0, codegen_1.str)`must have ${property_ies} ${deps4} when property ${property} is present`; }, - params: ({ params: { property, depsCount, deps: deps3, missingProperty } }) => (0, codegen_1._)`{property: ${property}, + params: ({ params: { property, depsCount, deps: deps4, missingProperty } }) => (0, codegen_1._)`{property: ${property}, missingProperty: ${missingProperty}, depsCount: ${depsCount}, - deps: ${deps3}}` + deps: ${deps4}}` // TODO change to reference }; var def = { @@ -18138,8 +18138,8 @@ var require_dependencies = __commonJS({ for (const key in schema) { if (key === "__proto__") continue; - const deps3 = Array.isArray(schema[key]) ? propertyDeps : schemaDeps; - deps3[key] = schema[key]; + const deps4 = Array.isArray(schema[key]) ? propertyDeps : schemaDeps; + deps4[key] = schema[key]; } return [propertyDeps, schemaDeps]; } @@ -18149,23 +18149,23 @@ var require_dependencies = __commonJS({ return; const missing = gen.let("missing"); for (const prop in propertyDeps) { - const deps3 = propertyDeps[prop]; - if (deps3.length === 0) + const deps4 = propertyDeps[prop]; + if (deps4.length === 0) continue; const hasProperty = (0, code_1.propertyInData)(gen, data, prop, it.opts.ownProperties); cxt.setParams({ property: prop, - depsCount: deps3.length, - deps: deps3.join(", ") + depsCount: deps4.length, + deps: deps4.join(", ") }); if (it.allErrors) { gen.if(hasProperty, () => { - for (const depProp of deps3) { + for (const depProp of deps4) { (0, code_1.checkReportMissingProp)(cxt, depProp); } }); } else { - gen.if((0, codegen_1._)`${hasProperty} && (${(0, code_1.checkMissingProp)(cxt, deps3, missing)})`); + gen.if((0, codegen_1._)`${hasProperty} && (${(0, code_1.checkMissingProp)(cxt, deps4, missing)})`); (0, code_1.reportMissingProp)(cxt, missing); gen.else(); } @@ -30480,28 +30480,28 @@ var getJoinLength = (uint8Arrays) => { // ../../node_modules/.pnpm/execa@9.6.1/node_modules/execa/lib/methods/template.js var isTemplateString = (templates) => Array.isArray(templates) && Array.isArray(templates.raw); var parseTemplates = (templates, expressions) => { - let tokens = []; + let tokens2 = []; for (const [index, template2] of templates.entries()) { - tokens = parseTemplate({ + tokens2 = parseTemplate({ templates, expressions, - tokens, + tokens: tokens2, index, template: template2 }); } - if (tokens.length === 0) { + if (tokens2.length === 0) { throw new TypeError("Template script must not be empty"); } - const [file, ...commandArguments] = tokens; + const [file, ...commandArguments] = tokens2; return [file, commandArguments, {}]; }; -var parseTemplate = ({ templates, expressions, tokens, index, template: template2 }) => { +var parseTemplate = ({ templates, expressions, tokens: tokens2, index, template: template2 }) => { if (template2 === void 0) { throw new TypeError(`Invalid backslash sequence: ${templates.raw[index]}`); } const { nextTokens, leadingWhitespaces, trailingWhitespaces } = splitByWhitespaces(template2, templates.raw[index]); - const newTokens = concatTokens(tokens, nextTokens, leadingWhitespaces); + const newTokens = concatTokens(tokens2, nextTokens, leadingWhitespaces); if (index === expressions.length) { return newTokens; } @@ -30543,9 +30543,9 @@ var splitByWhitespaces = (template2, rawTemplate) => { }; var DELIMITERS = /* @__PURE__ */ new Set([" ", " ", "\r", "\n"]); var ESCAPE_LENGTH = { x: 3, u: 5 }; -var concatTokens = (tokens, nextTokens, isSeparated) => isSeparated || tokens.length === 0 || nextTokens.length === 0 ? [...tokens, ...nextTokens] : [ - ...tokens.slice(0, -1), - `${tokens.at(-1)}${nextTokens[0]}`, +var concatTokens = (tokens2, nextTokens, isSeparated) => isSeparated || tokens2.length === 0 || nextTokens.length === 0 ? [...tokens2, ...nextTokens] : [ + ...tokens2.slice(0, -1), + `${tokens2.at(-1)}${nextTokens[0]}`, ...nextTokens.slice(1) ]; var parseExpression = (expression) => { @@ -33463,7 +33463,7 @@ function parseMilliseconds(milliseconds) { // ../../node_modules/.pnpm/pretty-ms@9.3.0/node_modules/pretty-ms/index.js var isZero = (value) => value === 0 || value === 0n; -var pluralize = (word, count3) => count3 === 1 || count3 === 1n ? word : `${word}s`; +var pluralize = (word, count4) => count4 === 1 || count4 === 1n ? word : `${word}s`; var SECOND_ROUNDING_EPSILON = 1e-7; var ONE_DAY_IN_MILLISECONDS = 24n * 60n * 60n * 1000n; function prettyMilliseconds(milliseconds, options) { @@ -35467,10 +35467,10 @@ var errorStream = (stream, error2) => { }; var noop2 = () => { }; -var updateMaxListeners = (passThroughStream, increment2) => { +var updateMaxListeners = (passThroughStream, increment3) => { const maxListeners = passThroughStream.getMaxListeners(); if (maxListeners !== 0 && maxListeners !== Number.POSITIVE_INFINITY) { - passThroughStream.setMaxListeners(maxListeners + increment2); + passThroughStream.setMaxListeners(maxListeners + increment3); } }; var PASSTHROUGH_LISTENERS_COUNT = 2; @@ -35694,12 +35694,12 @@ var SignalExit = class extends SignalExitBase { for (const sig of signals) { this.#sigListeners[sig] = () => { const listeners = this.#process.listeners(sig); - let { count: count3 } = this.#emitter; + let { count: count4 } = this.#emitter; const p = process11; if (typeof p.__signal_exit_emitter__ === "object" && typeof p.__signal_exit_emitter__.count === "number") { - count3 += p.__signal_exit_emitter__.count; + count4 += p.__signal_exit_emitter__.count; } - if (listeners.length === count3) { + if (listeners.length === count4) { this.unload(); const ret = this.#emitter.emit("exit", null, sig); const s = sig === "SIGHUP" ? this.#hupSig : sig; @@ -37121,16 +37121,16 @@ var parseCommandString = (command) => { if (trimmedCommand === "") { return []; } - const tokens = []; + const tokens2 = []; for (const token of trimmedCommand.split(SPACES_REGEXP)) { - const previousToken = tokens.at(-1); + const previousToken = tokens2.at(-1); if (previousToken && previousToken.endsWith("\\")) { - tokens[tokens.length - 1] = `${previousToken.slice(0, -1)} ${token}`; + tokens2[tokens2.length - 1] = `${previousToken.slice(0, -1)} ${token}`; } else { - tokens.push(token); + tokens2.push(token); } } - return tokens; + return tokens2; }; var SPACES_REGEXP = / +/g; @@ -41639,7 +41639,7 @@ async function safeHttpRequest(request) { } async function performSafeHttpRequest(request, signal) { const started = Date.now(); - const duration3 = () => Math.max(0, Date.now() - started); + const duration4 = () => Math.max(0, Date.now() - started); const externalAborted = () => request.signal?.aborted === true; const maxRedirects = request.maxRedirects ?? 0; const initialUrl = new URL(request.url); @@ -41666,14 +41666,14 @@ async function performSafeHttpRequest(request, signal) { }); } catch (cause) { if (externalAborted()) { - return { ok: false, kind: "cancelled", detail: "the request was cancelled", durationMs: duration3() }; + return { ok: false, kind: "cancelled", detail: "the request was cancelled", durationMs: duration4() }; } if (cause instanceof Error && (cause.name === "TimeoutError" || cause.name === "AbortError")) { return { ok: false, kind: "timeout", detail: `the request did not complete within ${request.timeoutMs} ms`, - durationMs: duration3() + durationMs: duration4() }; } const message2 = cause instanceof Error ? cause.message : String(cause); @@ -41681,7 +41681,7 @@ async function performSafeHttpRequest(request, signal) { ok: false, kind: "unreachable", detail: `the endpoint could not be reached (${message2.slice(0, 300)})`, - durationMs: duration3() + durationMs: duration4() }; } if (response.status < 300 || response.status >= 400) break; @@ -41691,7 +41691,7 @@ async function performSafeHttpRequest(request, signal) { kind: "redirect-rejected", status: response.status, detail: maxRedirects === 0 ? `the endpoint answered with a redirect (${response.status}); redirects are never followed` : `the endpoint exceeded the bounded redirect limit of ${maxRedirects}`, - durationMs: duration3() + durationMs: duration4() }; } const location = response.headers.get("location"); @@ -41701,7 +41701,7 @@ async function performSafeHttpRequest(request, signal) { kind: "redirect-rejected", status: response.status, detail: `the endpoint answered with a redirect (${response.status}) without a target`, - durationMs: duration3() + durationMs: duration4() }; } const decision = checkRedirectTarget(currentUrl, location); @@ -41711,7 +41711,7 @@ async function performSafeHttpRequest(request, signal) { kind: "redirect-rejected", status: response.status, detail: decision.detail ?? "the redirect was rejected", - durationMs: duration3() + durationMs: duration4() }; } redirectCount += 1; @@ -41728,21 +41728,21 @@ async function performSafeHttpRequest(request, signal) { body = await readBounded(response, request.maxResponseBytes); } catch (cause) { if (externalAborted()) { - return { ok: false, kind: "cancelled", detail: "the request was cancelled", durationMs: duration3() }; + return { ok: false, kind: "cancelled", detail: "the request was cancelled", durationMs: duration4() }; } if (cause instanceof Error && (cause.name === "TimeoutError" || cause.name === "AbortError")) { return { ok: false, kind: "timeout", detail: `the response body did not complete within ${request.timeoutMs} ms`, - durationMs: duration3() + durationMs: duration4() }; } return { ok: false, kind: "unreachable", detail: `the response body could not be read (${cause instanceof Error ? cause.message.slice(0, 300) : "unknown error"})`, - durationMs: duration3() + durationMs: duration4() }; } if (body === "too-large") { @@ -41751,7 +41751,7 @@ async function performSafeHttpRequest(request, signal) { kind: "response-too-large", status: response.status, detail: `the response exceeded the configured limit of ${request.maxResponseBytes} bytes and was aborted`, - durationMs: duration3() + durationMs: duration4() }; } if (!response.ok) { @@ -41760,7 +41760,7 @@ async function performSafeHttpRequest(request, signal) { kind: "http-error", status: response.status, detail: `the endpoint answered HTTP ${response.status}`, - durationMs: duration3(), + durationMs: duration4(), bodyExcerpt: body.text.slice(0, 500) }; } @@ -41772,7 +41772,7 @@ async function performSafeHttpRequest(request, signal) { kind: "invalid-content-type", status: response.status, detail: `expected application/json but the endpoint answered "${contentType.slice(0, 100) || "(none)"}"`, - durationMs: duration3() + durationMs: duration4() }; } } @@ -41785,7 +41785,7 @@ async function performSafeHttpRequest(request, signal) { // archives). UTF-8 decoding is lossy for binary content, so callers that // need exact bytes opt in here. ...request.binaryBody === true ? { bodyBase64: body.buffer.toString("base64") } : {}, - durationMs: duration3(), + durationMs: duration4(), ...redirects !== void 0 ? { redirects } : {} }; } @@ -46049,9 +46049,9 @@ function hashFileIfRegular(absolutePath) { } function parsePorcelainStatus(raw) { const entries = []; - const tokens = raw.split("\0"); - for (let i2 = 0; i2 < tokens.length; i2 += 1) { - const token = tokens[i2]; + const tokens2 = raw.split("\0"); + for (let i2 = 0; i2 < tokens2.length; i2 += 1) { + const token = tokens2[i2]; if (token === void 0 || token.length === 0) continue; const status = token.slice(0, 2); const filePath = token.slice(3); @@ -46523,10 +46523,10 @@ function evaluateEvidence(input) { if (!input.taskStillExists) { violations.push("the selected task no longer exists in tasks.md with its recorded text"); } - const outcomeStatus = statusForFailedOutcome(input.runnerOutcome); - if (outcomeStatus !== void 0) { + const outcomeStatus2 = statusForFailedOutcome(input.runnerOutcome); + if (outcomeStatus2 !== void 0) { reasons.push(`the runner outcome was "${input.runnerOutcome}"`); - return { status: outcomeStatus, violations, warnings, reasons }; + return { status: outcomeStatus2, violations, warnings, reasons }; } const agentChanges = agentChangedFiles(input.comparison).filter( (file) => !input.comparison.ambiguousPaths.includes(file.path) @@ -47728,11 +47728,11 @@ function validateReferencedFiles(workspace, referenced) { } return { accepted, rejected }; } -async function authoringArgvPreview(deps3, plan, prompt, toolPolicy, timeoutMs) { - const profileConfig = deps3.registry.getProfile(plan.profile).config; +async function authoringArgvPreview(deps4, plan, prompt, toolPolicy, timeoutMs) { + const profileConfig = deps4.registry.getProfile(plan.profile).config; const execution = { - workspaceRoot: deps3.workspace.rootDir, - runDir: import_path24.default.join(deps3.workspace.sidecarDir, "runs", ""), + workspaceRoot: deps4.workspace.rootDir, + runDir: import_path24.default.join(deps4.workspace.sidecarDir, "runs", ""), timeoutMs }; if (profileConfig.runner === "claude-code") { @@ -47771,20 +47771,20 @@ function includedDocumentPaths(specName, steering, documents) { ...documents.map((section) => `.kiro/specs/${specName}/${section.stage}.md`) ]; } -async function runAuthoringAttempts(deps3, request, runId, primary, input, timeoutMs, clock) { +async function runAuthoringAttempts(deps4, request, runId, primary, input, timeoutMs, clock) { const operation = request.intent === "refine" ? "stage-refinement" : "stage-generation"; const attempts = []; - const backoff = deps3.backoff ?? ((ms) => (0, import_promises12.setTimeout)(ms)); + const backoff = deps4.backoff ?? ((ms) => (0, import_promises12.setTimeout)(ms)); const candidates = [primary.profile, ...primary.fallbackChain]; let lastFailure; let parentAttemptId; - const initialTree = candidates.length > 1 ? await captureGitSnapshot(deps3.workspace.rootDir) : void 0; + const initialTree = candidates.length > 1 ? await captureGitSnapshot(deps4.workspace.rootDir) : void 0; const treeFingerprint = (snapshot2) => JSON.stringify(snapshot2.entries.map((entry2) => [entry2.path, entry2.contentHash])); for (let index = 0; index < candidates.length; index += 1) { const profileName = candidates[index]; const isFallback = index > 0; if (isFallback && initialTree !== void 0 && initialTree.gitAvailable) { - const treeNow = await captureGitSnapshot(deps3.workspace.rootDir); + const treeNow = await captureGitSnapshot(deps4.workspace.rootDir); if (treeFingerprint(treeNow) !== treeFingerprint(initialTree)) { attempts.push({ profile: profileName, @@ -47792,7 +47792,7 @@ async function runAuthoringAttempts(deps3, request, runId, primary, input, timeo outcome: "not-attempted", reason: "the repository changed since the run started; fallback never runs after repository modification" }); - appendRunEvent(deps3.workspace, runId, { + appendRunEvent(deps4.workspace, runId, { at: clock().toISOString(), type: "fallback-stopped", profile: profileName, @@ -47801,7 +47801,7 @@ async function runAuthoringAttempts(deps3, request, runId, primary, input, timeo break; } } - const selection = isFallback ? selectRunner(deps3.registry, deps3.config, { operation, explicitProfile: profileName }) : { ok: true, plan: primary }; + const selection = isFallback ? selectRunner(deps4.registry, deps4.config, { operation, explicitProfile: profileName }) : { ok: true, plan: primary }; if (!selection.ok) { attempts.push({ profile: profileName, @@ -47809,7 +47809,7 @@ async function runAuthoringAttempts(deps3, request, runId, primary, input, timeo outcome: "not-attempted", reason: selection.failure.error.message }); - appendRunEvent(deps3.workspace, runId, { + appendRunEvent(deps4.workspace, runId, { at: clock().toISOString(), type: "fallback-skipped", profile: profileName, @@ -47818,15 +47818,15 @@ async function runAuthoringAttempts(deps3, request, runId, primary, input, timeo continue; } const plan = selection.plan; - const runner = deps3.registry.get(plan.profile); - const profileConfig = deps3.registry.getProfile(plan.profile).config; + const runner = deps4.registry.get(plan.profile); + const profileConfig = deps4.registry.getProfile(plan.profile).config; const profileTimeout = request.timeoutMs ?? (profileConfig.runner !== "mock" ? profileConfig.timeoutMs : timeoutMs); let transportRetries = 0; let correctionRetries = 0; let correction; for (; ; ) { const attemptKind = correction !== void 0 ? "correction-retry" : transportRetries > 0 ? "transport-retry" : isFallback ? "fallback" : "initial"; - const attempt = createAttempt(deps3.workspace, { + const attempt = createAttempt(deps4.workspace, { runId, profile: plan.profile, runner: plan.runner, @@ -47840,7 +47840,7 @@ async function runAuthoringAttempts(deps3, request, runId, primary, input, timeo capabilitySnapshot: plan.declaredCapabilities, createdAt: clock().toISOString() }); - appendRunEvent(deps3.workspace, runId, { + appendRunEvent(deps4.workspace, runId, { at: clock().toISOString(), type: "attempt-start", attemptId: attempt.attemptId, @@ -47850,16 +47850,16 @@ async function runAuthoringAttempts(deps3, request, runId, primary, input, timeo const result = await runner.generateStage( { ...input, ...correction !== void 0 ? { correction } : {} }, { - workspaceRoot: deps3.workspace.rootDir, - runDir: runDir(deps3.workspace, runId), + workspaceRoot: deps4.workspace.rootDir, + runDir: runDir(deps4.workspace, runId), timeoutMs: profileTimeout, - ...deps3.signal !== void 0 ? { signal: deps3.signal } : {}, + ...deps4.signal !== void 0 ? { signal: deps4.signal } : {}, ...request.model !== void 0 ? { model: request.model } : {}, ...request.maxTurns !== void 0 ? { maxTurns: request.maxTurns } : {}, ...request.maxBudgetUsd !== void 0 ? { maxBudgetUsd: request.maxBudgetUsd } : {} } ); - finalizeAttempt(deps3.workspace, attempt, { + finalizeAttempt(deps4.workspace, attempt, { finishedAt: clock().toISOString(), outcome: result.outcome, durationMs: result.durationMs, @@ -47876,7 +47876,7 @@ async function runAuthoringAttempts(deps3, request, runId, primary, input, timeo }); if (result.invalidStructuredOutput !== void 0) { writeAttemptArtifact( - deps3.workspace, + deps4.workspace, runId, attempt.attemptId, "invalid-candidate.txt", @@ -47920,7 +47920,7 @@ async function runAuthoringAttempts(deps3, request, runId, primary, input, timeo } const decision = fallbackEligible(operation, result.outcome, result.error); if (!decision.eligible) { - appendRunEvent(deps3.workspace, runId, { + appendRunEvent(deps4.workspace, runId, { at: clock().toISOString(), type: "fallback-stopped", profile: plan.profile, @@ -47934,9 +47934,9 @@ async function runAuthoringAttempts(deps3, request, runId, primary, input, timeo const last = lastFailure; return { kind: "failure", result: last.result, plan: last.plan, attempts }; } -async function authorStage(deps3, request) { - const clock = deps3.clock ?? systemClock; - const { workspace, config: config2 } = deps3; +async function authorStage(deps4, request) { + const clock = deps4.clock ?? systemClock; + const { workspace, config: config2 } = deps4; const folder = requireSpec(workspace, request.specName); const spec = analyzeSpec(workspace, folder); const specName = folder.name; @@ -47985,7 +47985,7 @@ async function authorStage(deps3, request) { } } const operation = request.intent === "refine" ? "stage-refinement" : "stage-generation"; - const selection = selectRunner(deps3.registry, config2, { + const selection = selectRunner(deps4.registry, config2, { operation, ...request.runnerName !== void 0 ? { explicitProfile: request.runnerName } : {} }); @@ -47997,8 +47997,8 @@ async function authorStage(deps3, request) { }; } const plan = selection.plan; - const runner = deps3.registry.get(plan.profile); - const profileConfig = deps3.registry.getProfile(plan.profile).config; + const runner = deps4.registry.get(plan.profile); + const profileConfig = deps4.registry.getProfile(plan.profile).config; const steering = steeringSections(workspace); const contextStages = contextStagesFor(gate.shape, request.stage); const documents = specDocumentSections(spec, evaluation, contextStages); @@ -48031,7 +48031,7 @@ async function authorStage(deps3, request) { const timeoutMs = request.timeoutMs ?? (profileConfig.runner !== "mock" ? profileConfig.timeoutMs : 18e5); const targetFile = stageDocumentPath(workspace, specName, request.stage); if (request.dryRun === true) { - const argvPreview = plan.category === "agent-cli" ? await authoringArgvPreview(deps3, plan, prompt, toolPolicy, timeoutMs) : void 0; + const argvPreview = plan.category === "agent-cli" ? await authoringArgvPreview(deps4, plan, prompt, toolPolicy, timeoutMs) : void 0; return { kind: "dry-run", exitCode: EXIT_CODES.ok, @@ -48069,7 +48069,7 @@ async function authorStage(deps3, request) { }; } } - const runId = (deps3.idFactory ?? import_crypto6.randomUUID)(); + const runId = (deps4.idFactory ?? import_crypto6.randomUUID)(); const createdAt = clock().toISOString(); createRun(workspace, { schemaVersion: RUN_RECORD_SCHEMA_VERSION, @@ -48111,7 +48111,7 @@ async function authorStage(deps3, request) { ); appendRunEvent(workspace, runId, { at: createdAt, type: "runner-start", runner: plan.profile }); const loop = await runAuthoringAttempts( - deps3, + deps4, request, runId, plan, @@ -48280,18 +48280,18 @@ function policyRelevantDirtyPaths(before, evaluation) { return true; }).map((entry2) => entry2.path); } -async function preflightTaskRun(deps3, request) { - const { workspace, config: config2 } = deps3; +async function preflightTaskRun(deps4, request) { + const { workspace, config: config2 } = deps4; const allowDirty = request.allowDirty === true; const verificationCommands = config2.verification.commands; const warnings = []; const operation = request.operation ?? "task-execution"; - const runnerSelection = selectRunner(deps3.registry, config2, { + const runnerSelection = selectRunner(deps4.registry, config2, { operation, ...request.runnerName !== void 0 ? { explicitProfile: request.runnerName } : {} }); const runnerName = runnerSelection.ok ? runnerSelection.plan.profile : runnerSelection.failure.profile ?? request.runnerName ?? config2.defaultRunner; - const profileConfig = deps3.registry.has(runnerName) ? deps3.registry.getProfile(runnerName).config : void 0; + const profileConfig = deps4.registry.has(runnerName) ? deps4.registry.getProfile(runnerName).config : void 0; const timeoutMs = request.timeoutMs ?? profileTimeoutMs(profileConfig); const folder = requireSpec(workspace, request.specName); const spec = analyzeSpec(workspace, folder); @@ -48403,7 +48403,7 @@ async function preflightTaskRun(deps3, request) { `${predecessors.length} earlier task(s) are still open (next would be ${predecessors[0]?.id}); running ${task.id} out of order.` ); } - const runner = deps3.registry.get(runnerName); + const runner = deps4.registry.get(runnerName); base.runner = runner; const detection = await runner.detect({ workspaceRoot: workspace.rootDir, @@ -48420,7 +48420,7 @@ async function preflightTaskRun(deps3, request) { }); } const before = await captureGitSnapshot(workspace.rootDir, { - ...deps3.clock !== void 0 ? { clock: deps3.clock } : {} + ...deps4.clock !== void 0 ? { clock: deps4.clock } : {} }); base.before = before; if (!before.gitAvailable) { @@ -48522,12 +48522,12 @@ function completeTaskCheckbox(workspace, specName, expected, clock) { ...newHash !== void 0 ? { newHash } : {} }; } -async function taskArgvPreview(deps3, preflight, prompt, runIdPreview) { +async function taskArgvPreview(deps4, preflight, prompt, runIdPreview) { const profileConfig = preflight.profileConfig; if (profileConfig === void 0) return void 0; const execution = { - workspaceRoot: deps3.workspace.rootDir, - runDir: import_path26.default.join(deps3.workspace.sidecarDir, "runs", runIdPreview), + workspaceRoot: deps4.workspace.rootDir, + runDir: import_path26.default.join(deps4.workspace.sidecarDir, "runs", runIdPreview), timeoutMs: preflight.timeoutMs }; if (profileConfig.runner === "claude-code") { @@ -48587,8 +48587,8 @@ function exitCodeForEvidence(status, outcome) { function boundaryNoteFor(preflight) { return preflight.runner?.executionBoundaryNote?.("implementation") ?? "Repository access is bounded by the configured runner safety boundary. Permission bypasses are never used."; } -function buildPrompt(deps3, preflight, extraObservations = []) { - const { workspace } = deps3; +function buildPrompt(deps4, preflight, extraObservations = []) { + const { workspace } = deps4; const spec = preflight.spec; const state = preflight.state; const evaluation = preflight.evaluation; @@ -48614,9 +48614,9 @@ function buildPrompt(deps3, preflight, extraObservations = []) { }; return buildTaskExecutionPrompt(input); } -async function runApprovedTask(deps3, request) { - const clock = deps3.clock ?? systemClock; - const preflight = await preflightTaskRun(deps3, { +async function runApprovedTask(deps4, request) { + const clock = deps4.clock ?? systemClock; + const preflight = await preflightTaskRun(deps4, { specName: request.specName, selector: { ...request.taskId !== void 0 ? { taskId: request.taskId } : {}, @@ -48642,11 +48642,11 @@ async function runApprovedTask(deps3, request) { }; } const task = preflight.task; - const prompt = buildPrompt(deps3, preflight, request.extraObservations ?? []); + const prompt = buildPrompt(deps4, preflight, request.extraObservations ?? []); const profileConfig = preflight.profileConfig; if (request.dryRun === true) { - const runIdPreview = (deps3.idFactory ?? import_crypto7.randomUUID)(); - const argvPreview = await taskArgvPreview(deps3, preflight, prompt, runIdPreview); + const runIdPreview = (deps4.idFactory ?? import_crypto7.randomUUID)(); + const argvPreview = await taskArgvPreview(deps4, preflight, prompt, runIdPreview); const artifactBase = `.specbridge/runs/${runIdPreview}`; return { kind: "dry-run", @@ -48691,11 +48691,11 @@ async function runApprovedTask(deps3, request) { } }; } - const runId = (deps3.idFactory ?? import_crypto7.randomUUID)(); - const sessionId = (deps3.idFactory ?? import_crypto7.randomUUID)(); - const parent = latestRunForTask(deps3.workspace, preflight.spec.folder.name, task.id); + const runId = (deps4.idFactory ?? import_crypto7.randomUUID)(); + const sessionId = (deps4.idFactory ?? import_crypto7.randomUUID)(); + const parent = latestRunForTask(deps4.workspace, preflight.spec.folder.name, task.id); const createdAt = clock().toISOString(); - createRun(deps3.workspace, { + createRun(deps4.workspace, { schemaVersion: RUN_RECORD_SCHEMA_VERSION, runId, kind: "task-execution", @@ -48709,9 +48709,9 @@ async function runApprovedTask(deps3, request) { promptVersion: PROMPT_CONTRACT_VERSION, warnings: preflight.warnings }); - writeRunArtifact(deps3.workspace, runId, "prompt.md", prompt); + writeRunArtifact(deps4.workspace, runId, "prompt.md", prompt); writeRunArtifact( - deps3.workspace, + deps4.workspace, runId, "runner-request.json", `${JSON.stringify( @@ -48730,12 +48730,12 @@ async function runApprovedTask(deps3, request) { )} ` ); - appendRunEvent(deps3.workspace, runId, { at: createdAt, type: "runner-start", task: task.id }); - deps3.onProgress?.(`Executing task ${task.id} with ${preflight.runnerName}\u2026`); + appendRunEvent(deps4.workspace, runId, { at: createdAt, type: "runner-start", task: task.id }); + deps4.onProgress?.(`Executing task ${task.id} with ${preflight.runnerName}\u2026`); const runner = preflight.runner; if (runner === void 0) throw new Error("preflight.ok implies runner"); const selectionPlan = preflight.selectionPlan; - const attempt = selectionPlan !== void 0 ? createAttempt(deps3.workspace, { + const attempt = selectionPlan !== void 0 ? createAttempt(deps4.workspace, { runId, profile: selectionPlan.profile, runner: selectionPlan.runner, @@ -48758,17 +48758,17 @@ async function runApprovedTask(deps3, request) { sessionId }, { - workspaceRoot: deps3.workspace.rootDir, - runDir: runDir(deps3.workspace, runId), + workspaceRoot: deps4.workspace.rootDir, + runDir: runDir(deps4.workspace, runId), timeoutMs: preflight.timeoutMs, - ...deps3.signal !== void 0 ? { signal: deps3.signal } : {}, + ...deps4.signal !== void 0 ? { signal: deps4.signal } : {}, ...request.model !== void 0 ? { model: request.model } : {}, ...request.maxTurns !== void 0 ? { maxTurns: request.maxTurns } : {}, ...request.maxBudgetUsd !== void 0 ? { maxBudgetUsd: request.maxBudgetUsd } : {} } ); if (attempt !== void 0 && selectionPlan !== void 0) { - finalizeAttempt(deps3.workspace, attempt, { + finalizeAttempt(deps4.workspace, attempt, { finishedAt: clock().toISOString(), outcome: result.outcome, durationMs: result.durationMs, @@ -48784,7 +48784,7 @@ async function runApprovedTask(deps3, request) { ) }); } - const report = await finalizeTaskRun(deps3, { + const report = await finalizeTaskRun(deps4, { runId, ...parent !== void 0 ? { parentRunId: parent.runId } : {}, specName: preflight.spec.folder.name, @@ -48798,9 +48798,9 @@ async function runApprovedTask(deps3, request) { }); return { kind: "executed", exitCode: report.exitCode, report }; } -async function finalizeTaskRun(deps3, context) { - const clock = deps3.clock ?? systemClock; - const { workspace, config: config2 } = deps3; +async function finalizeTaskRun(deps4, context) { + const clock = deps4.clock ?? systemClock; + const { workspace, config: config2 } = deps4; const { runId, task, result } = context; writeRunArtifact(workspace, runId, "raw-stdout.log", result.rawStdout); writeRunArtifact(workspace, runId, "raw-stderr.log", result.rawStderr); @@ -48871,12 +48871,12 @@ async function finalizeTaskRun(deps3, context) { if (context.noVerify) { verification = skippedVerification(config2.verification.commands); } else if (result.outcome === "completed" && agentChanges.length > 0) { - deps3.onProgress?.("Running trusted verification commands\u2026"); + deps4.onProgress?.("Running trusted verification commands\u2026"); verification = await runVerificationCommands( workspace.rootDir, config2.verification.commands, { - ...deps3.signal !== void 0 ? { signal: deps3.signal } : {}, + ...deps4.signal !== void 0 ? { signal: deps4.signal } : {}, onCommandFinished: (commandResult, stdout, stderr) => { writeRunArtifact( workspace, @@ -49085,12 +49085,12 @@ function taskLineIntact(workspace, specName, task) { return false; } } -async function runAllOpenTasks(deps3, request) { +async function runAllOpenTasks(deps4, request) { const attempted = []; - const stopOnUnverified = deps3.config.execution.stopOnUnverifiedTask; + const stopOnUnverified = deps4.config.execution.stopOnUnverifiedTask; for (; ; ) { const allowDirty = request.allowDirty === true || attempted.length > 0; - const outcome = await runApprovedTask(deps3, { ...request, allowDirty, next: true }); + const outcome = await runApprovedTask(deps4, { ...request, allowDirty, next: true }); if (outcome.kind === "nothing-to-do") { return { attempted, exitCode: attempted.length === 0 ? EXIT_CODES.ok : summaryExit(attempted) }; } @@ -49150,9 +49150,9 @@ function diverges(current, recordedAfter) { } return differences; } -async function resumeRun(deps3, request) { - const clock = deps3.clock ?? systemClock; - const { workspace } = deps3; +async function resumeRun(deps4, request) { + const clock = deps4.clock ?? systemClock; + const { workspace } = deps4; const original = readRunRecord(workspace, request.runId); if (original === void 0) { return refuse( @@ -49190,7 +49190,7 @@ async function resumeRun(deps3, request) { [`specbridge spec run ${original.specName} --task ${original.taskId}`] ); } - const preflight = await preflightTaskRun(deps3, { + const preflight = await preflightTaskRun(deps4, { specName: original.specName, selector: { taskId: original.taskId }, runnerName: original.runner, @@ -49306,7 +49306,7 @@ async function resumeRun(deps3, request) { } }; } - const runId = (deps3.idFactory ?? import_crypto8.randomUUID)(); + const runId = (deps4.idFactory ?? import_crypto8.randomUUID)(); const createdAt = clock().toISOString(); createRun(workspace, { schemaVersion: RUN_RECORD_SCHEMA_VERSION, @@ -49329,7 +49329,7 @@ async function resumeRun(deps3, request) { originalRunId: original.runId, sessionId: original.sessionId }); - deps3.onProgress?.(`Resuming task ${task.id} (session ${original.sessionId})\u2026`); + deps4.onProgress?.(`Resuming task ${task.id} (session ${original.sessionId})\u2026`); const result = await runner.resumeTask( { specName: original.specName, @@ -49343,10 +49343,10 @@ async function resumeRun(deps3, request) { workspaceRoot: workspace.rootDir, runDir: runDir(workspace, runId), timeoutMs: preflight.timeoutMs, - ...deps3.signal !== void 0 ? { signal: deps3.signal } : {} + ...deps4.signal !== void 0 ? { signal: deps4.signal } : {} } ); - const report = await finalizeTaskRun(deps3, { + const report = await finalizeTaskRun(deps4, { runId, parentRunId: original.runId, specName: original.specName, @@ -49529,11 +49529,11 @@ var INTERACTIVE_AGENT_INSTRUCTIONS = [ function blocked(code2, message2, remediation = [], details) { return { kind: "blocked", code: code2, message: message2, remediation, ...details !== void 0 ? { details } : {} }; } -function buildInteractiveContext(deps3, specName, task) { - const folder = requireSpec(deps3.workspace, specName); - const spec = analyzeSpec(deps3.workspace, folder); +function buildInteractiveContext(deps4, specName, task) { + const folder = requireSpec(deps4.workspace, specName); + const spec = analyzeSpec(deps4.workspace, folder); const state = spec.state; - const evaluation = state !== void 0 ? evaluateWorkflow(deps3.workspace, state) : void 0; + const evaluation = state !== void 0 ? evaluateWorkflow(deps4.workspace, state) : void 0; const documentStage = state?.specType === "bugfix" ? "bugfix" : "requirements"; const lines = []; lines.push(`# Interactive task context: ${specName} \u2014 task ${task.id}`); @@ -49543,7 +49543,7 @@ function buildInteractiveContext(deps3, specName, task) { lines.push(`Requirement references: ${task.requirementRefs.join(", ")}`); } lines.push(""); - for (const steering of steeringSections(deps3.workspace)) { + for (const steering of steeringSections(deps4.workspace)) { lines.push(`## Steering: ${steering.name}`); lines.push(""); lines.push(steering.body.trimEnd()); @@ -49564,9 +49564,9 @@ function buildInteractiveContext(deps3, specName, task) { return `${lines.join("\n").replace(/\n+$/, "")} `; } -async function beginInteractiveTask(deps3, request) { - const clock = deps3.clock ?? systemClock; - const { workspace, config: config2 } = deps3; +async function beginInteractiveTask(deps4, request) { + const clock = deps4.clock ?? systemClock; + const { workspace, config: config2 } = deps4; const allowDirty = request.allowDirty === true; const runVerificationOnComplete = request.runVerificationOnComplete !== false; const warnings = []; @@ -49619,7 +49619,7 @@ async function beginInteractiveTask(deps3, request) { `${predecessors.length} earlier task(s) are still open (next would be ${predecessors[0]?.id}); running ${task.id} out of order.` ); } - const runId = (deps3.idFactory ?? import_crypto9.randomUUID)(); + const runId = (deps4.idFactory ?? import_crypto9.randomUUID)(); const acquisition = acquireInteractiveLock(workspace, { runId, specName, @@ -49679,7 +49679,7 @@ async function beginInteractiveTask(deps3, request) { resumeSupported: false, warnings, lifecycleStatus: "AWAITING_AGENT_CHANGES", - host: deps3.host ?? "mcp" + host: deps4.host ?? "mcp" }); const fingerprint = taskFingerprint({ id: task.id, @@ -49709,7 +49709,7 @@ async function beginInteractiveTask(deps3, request) { `${JSON.stringify(buildEvidenceSpecContext(workspace, specName, spec.state, task), null, 2)} ` ); - const contextMarkdown = buildInteractiveContext(deps3, specName, task); + const contextMarkdown = buildInteractiveContext(deps4, specName, task); writeRunArtifact(workspace, runId, "context.md", contextMarkdown); appendRunEvent(workspace, runId, { at: createdAt, @@ -49811,9 +49811,9 @@ function readFinalReport(workspace, runId) { const artifact = readRunArtifactJson(workspace, runId, "report.json"); return artifact?.report; } -async function completeInteractiveTask(deps3, request) { - const clock = deps3.clock ?? systemClock; - const { workspace } = deps3; +async function completeInteractiveTask(deps4, request) { + const clock = deps4.clock ?? systemClock; + const { workspace } = deps4; const loaded = loadInteractiveRun(workspace, request.runId); if (!loaded.ok) return loaded.failure; const { record: record5, state } = loaded; @@ -49911,9 +49911,9 @@ async function completeInteractiveTask(deps3, request) { const finalReport = await finalizeTaskRun( { workspace, - config: deps3.config, - ...deps3.clock !== void 0 ? { clock: deps3.clock } : {}, - ...deps3.signal !== void 0 ? { signal: deps3.signal } : {} + config: deps4.config, + ...deps4.clock !== void 0 ? { clock: deps4.clock } : {}, + ...deps4.signal !== void 0 ? { signal: deps4.signal } : {} }, { runId: request.runId, @@ -49943,9 +49943,9 @@ async function completeInteractiveTask(deps3, request) { finalizedNow: true }; } -async function abortInteractiveTask(deps3, request) { - const clock = deps3.clock ?? systemClock; - const { workspace } = deps3; +async function abortInteractiveTask(deps4, request) { + const clock = deps4.clock ?? systemClock; + const { workspace } = deps4; const reason3 = request.reason.trim(); if (reason3.length === 0) { return blocked("run-state-invalid", "task_abort requires a non-empty reason.", []); @@ -50203,7 +50203,7 @@ var resumeConformanceGroup = { check2("resume", "resume.refusals", "unsafe resumes are refused", "skipped", fixture.error) ]; } - const deps3 = { workspace: fixture.workspace, config: fixture.config, registry: fixture.registry }; + const deps4 = { workspace: fixture.workspace, config: fixture.config, registry: fixture.registry }; createRun(fixture.workspace, { schemaVersion: RUN_RECORD_SCHEMA_VERSION, runId: "conf-resume-verified", @@ -50218,7 +50218,7 @@ var resumeConformanceGroup = { outcome: "completed", warnings: [] }); - const verifiedResume = await resumeRun(deps3, { runId: "conf-resume-verified" }); + const verifiedResume = await resumeRun(deps4, { runId: "conf-resume-verified" }); results.push( check2( "resume", @@ -50241,7 +50241,7 @@ var resumeConformanceGroup = { outcome: "failed", warnings: [] }); - const sessionlessResume = await resumeRun(deps3, { runId: "conf-resume-no-session" }); + const sessionlessResume = await resumeRun(deps4, { runId: "conf-resume-no-session" }); results.push( check2( "resume", @@ -50285,7 +50285,7 @@ var resumeConformanceGroup = { "git-after.json", fakeSnapshot([{ path: "src/from-previous-session.txt", status: " M", contentHash: "deadbeef" }]) ); - const divergedResume = await resumeRun(deps3, { runId: "conf-resume-diverged" }); + const divergedResume = await resumeRun(deps4, { runId: "conf-resume-diverged" }); results.push( check2( "resume", @@ -50649,11 +50649,11 @@ function computeContextUsage(config2, estimatedTokens) { }; } function assessContextHealth(config2, estimatedTokens) { - const ratio3 = estimatedTokens / usableInputTokens(config2); - if (ratio3 >= config2.hardStopThreshold) return "OVERFLOW"; - if (ratio3 >= config2.emergencyCompactionThreshold) return "FORCE_COMPACT"; - if (ratio3 >= config2.proactiveCompactionThreshold) return "PROACTIVE_COMPACT"; - if (ratio3 >= config2.prepareThreshold) return "PREPARE"; + const ratio4 = estimatedTokens / usableInputTokens(config2); + if (ratio4 >= config2.hardStopThreshold) return "OVERFLOW"; + if (ratio4 >= config2.emergencyCompactionThreshold) return "FORCE_COMPACT"; + if (ratio4 >= config2.proactiveCompactionThreshold) return "PROACTIVE_COMPACT"; + if (ratio4 >= config2.prepareThreshold) return "PREPARE"; return "HEALTHY"; } var ContextBudgetError = class extends Error { @@ -51890,17 +51890,17 @@ function extractSymbolReferences(text15) { } function extractTokens(text15) { const bounded22 = text15.slice(0, RETRIEVAL_QUERY_LIMITS.maxScannedTextChars); - const tokens = /* @__PURE__ */ new Set(); + const tokens2 = /* @__PURE__ */ new Set(); for (const raw of bounded22.split(/[^A-Za-z0-9]+/)) { if (raw.length < 3 || raw.length > 40) continue; for (const part of raw.split(/(?<=[a-z0-9])(?=[A-Z])/)) { const token = part.toLowerCase(); if (token.length < 3 || STOP_TOKENS.has(token)) continue; - tokens.add(token); - if (tokens.size >= RETRIEVAL_QUERY_LIMITS.maxTokens) return [...tokens]; + tokens2.add(token); + if (tokens2.size >= RETRIEVAL_QUERY_LIMITS.maxTokens) return [...tokens2]; } } - return [...tokens]; + return [...tokens2]; } function bounded(values) { return [...new Set((values ?? []).map(normalizePath).filter((value) => value !== ""))].slice( @@ -51923,7 +51923,7 @@ function buildRetrievalQuery(input) { ...extractSymbolReferences(actionText) ]) ].slice(0, RETRIEVAL_QUERY_LIMITS.maxSymbols); - const tokens = [ + const tokens2 = [ .../* @__PURE__ */ new Set([ ...extractTokens(objective), ...extractTokens(actionText), @@ -51954,7 +51954,7 @@ function buildRetrievalQuery(input) { checkpointChangedPaths: bounded(input.checkpointChangedPaths), priorRelevantPaths: bounded(input.priorRelevantPaths), symbols, - tokens, + tokens: tokens2, failureFingerprint: input.failureFingerprint, expansionLevel: input.expansionLevel ?? "TOP_WORKING_SET" }; @@ -53278,8 +53278,8 @@ function selectWorkingSet(input) { lines: lineHints.get(candidate.path) ?? [], options: input.sectionOptions }); - const tokens = estimateTokens(section.content) + estimateTokens(candidate.path) + 8; - if (!candidate.mandatory && tokens > input.allocation.maxSingleItemTokens) { + const tokens2 = estimateTokens(section.content) + estimateTokens(candidate.path) + 8; + if (!candidate.mandatory && tokens2 > input.allocation.maxSingleItemTokens) { if (pointers.length < maxPointers) { pointers.push({ path: candidate.path, @@ -53294,11 +53294,11 @@ function selectWorkingSet(input) { path: candidate.path, reason: "TOO_LARGE", score: candidate.score, - detail: truncate(`${tokens} tokens exceeds the ${input.allocation.maxSingleItemTokens}-token per-item ceiling`) + detail: truncate(`${tokens2} tokens exceeds the ${input.allocation.maxSingleItemTokens}-token per-item ceiling`) }); continue; } - if (!candidate.mandatory && spent + tokens > input.allocation.workingSetBudget) { + if (!candidate.mandatory && spent + tokens2 > input.allocation.workingSetBudget) { if (pointers.length < maxPointers) { pointers.push({ path: candidate.path, @@ -53326,7 +53326,7 @@ function selectWorkingSet(input) { ...section.startLine !== void 0 ? { startLine: section.startLine } : {}, ...section.endLine !== void 0 ? { endLine: section.endLine } : {}, ...section.symbol !== void 0 ? { symbol: truncate(section.symbol) } : {}, - estimatedTokens: tokens, + estimatedTokens: tokens2, ...candidate.signals[0]?.detail !== void 0 ? { detail: truncate(candidate.signals[0].detail) } : {} }); items.push({ @@ -53353,7 +53353,7 @@ function selectWorkingSet(input) { sourceHashes: [] } }); - spent += tokens; + spent += tokens2; } return { selected, pointers, excluded, items, refreshedPaths, workingSetTokens: spent }; } @@ -53599,7 +53599,7 @@ function buildContextMetrics(input) { function census(values) { const counts = /* @__PURE__ */ new Map(); for (const value of values) counts.set(value, (counts.get(value) ?? 0) + 1); - return [...counts.entries()].map(([key, count3]) => ({ key, count: count3 })).sort((left, right) => right.count !== left.count ? right.count - left.count : left.key < right.key ? -1 : 1); + return [...counts.entries()].map(([key, count4]) => ({ key, count: count4 })).sort((left, right) => right.count !== left.count ? right.count - left.count : left.key < right.key ? -1 : 1); } function explainContextSelection(input) { const { plan } = input; @@ -55069,12 +55069,12 @@ function readMissionEvents(workspace, missionId, options = {}) { const window = parsed.slice(Math.max(0, parsed.length - offset - limit), parsed.length - offset); return { events: window, total: parsed.length, truncated: parsed.length > window.length }; } -function now(deps3) { - return (deps3.clock ?? systemClock)(); +function now(deps4) { + return (deps4.clock ?? systemClock)(); } -function record2(deps3, mission, type, payload = {}) { - appendMissionEvent(deps3.workspace, mission.missionId, { - at: now(deps3).toISOString(), +function record2(deps4, mission, type, payload = {}) { + appendMissionEvent(deps4.workspace, mission.missionId, { + at: now(deps4).toISOString(), type, ...payload }); @@ -55083,15 +55083,15 @@ function record2(deps3, mission, type, payload = {}) { counters: { ...mission.counters, events: mission.counters.events + 1 } }; } -function transition(deps3, mission, to) { +function transition(deps4, mission, to) { assertMissionTransition(mission.status, to); - const moved = { ...mission, status: to, updatedAt: now(deps3).toISOString() }; - return record2(deps3, moved, "status_changed", { from: mission.status, to }); + const moved = { ...mission, status: to, updatedAt: now(deps4).toISOString() }; + return record2(deps4, moved, "status_changed", { from: mission.status, to }); } -function persist(deps3, mission) { - return writeMissionState(deps3.workspace, { +function persist(deps4, mission) { + return writeMissionState(deps4.workspace, { ...mission, - updatedAt: now(deps3).toISOString() + updatedAt: now(deps4).toISOString() }); } function assertNotFinal(mission) { @@ -55118,7 +55118,7 @@ function assertDiscoveryOpen(mission, what) { function pad(value, width) { return String(value).padStart(width, "0"); } -function beginMission(deps3, request) { +function beginMission(deps4, request) { const name = request.name.trim(); const goal = request.goal.trim(); if (name.length === 0 || goal.length === 0) { @@ -55126,32 +55126,32 @@ function beginMission(deps3, request) { remediation: ["Describe the product direction in one or two sentences."] }); } - const createdAt = now(deps3).toISOString(); + const createdAt = now(deps4).toISOString(); const mission = missionStateSchema.parse({ schemaVersion: MISSION_STATE_SCHEMA_VERSION, - missionId: `m-${(deps3.idFactory ?? import_crypto15.randomUUID)()}`, + missionId: `m-${(deps4.idFactory ?? import_crypto15.randomUUID)()}`, name: name.slice(0, MISSION_LIMITS.maxNameChars), status: "IDEA", goal: goal.slice(0, MISSION_LIMITS.maxTextChars), createdAt, updatedAt: createdAt, - host: deps3.host ?? "cli" + host: deps4.host ?? "cli" }); - initializeMissionRecord(deps3.workspace, mission); - writeConstitution(deps3.workspace, mission.missionId, { + initializeMissionRecord(deps4.workspace, mission); + writeConstitution(deps4.workspace, mission.missionId, { schemaVersion: MISSION_CONSTITUTION_SCHEMA_VERSION, missionId: mission.missionId, version: 0, updatedAt: createdAt, rules: [] }); - const recorded = record2(deps3, mission, "mission_created", { name: mission.name }); - const persisted = persist(deps3, recorded); - refreshCoverage(deps3, persisted); + const recorded = record2(deps4, mission, "mission_created", { name: mission.name }); + const persisted = persist(deps4, recorded); + refreshCoverage(deps4, persisted); return persisted; } -function recordTurn(deps3, missionId, request) { - let mission = requireMissionState(deps3.workspace, missionId); +function recordTurn(deps4, missionId, request) { + let mission = requireMissionState(deps4.workspace, missionId); assertNotFinal(mission); if (mission.counters.turns >= MISSION_LIMITS.maxTurns) { throw new MissionError("SBM006", `The mission reached its ${MISSION_LIMITS.maxTurns}-turn bound.`); @@ -55160,34 +55160,34 @@ function recordTurn(deps3, missionId, request) { if (text24.length === 0) { throw new MissionError("SBM005", "A turn needs visible text."); } - if (request.inReplyTo !== void 0 && findTurn(deps3.workspace, missionId, request.inReplyTo) === void 0) { + if (request.inReplyTo !== void 0 && findTurn(deps4.workspace, missionId, request.inReplyTo) === void 0) { throw new MissionError("SBM005", `Turn "${request.inReplyTo}" does not exist; inReplyTo must reference a recorded turn.`); } const sequence = mission.sequences.turn + 1; const turn = { turnId: `t-${sequence}`, - at: now(deps3).toISOString(), + at: now(deps4).toISOString(), speaker: request.speaker, kind: request.kind, text: text24.slice(0, MISSION_LIMITS.maxTurnTextChars), refs: (request.refs ?? []).slice(0, MISSION_LIMITS.maxRefsPerRecord), ...request.inReplyTo !== void 0 ? { inReplyTo: request.inReplyTo } : {} }; - appendTurn(deps3.workspace, missionId, turn); + appendTurn(deps4.workspace, missionId, turn); mission = { ...mission, sequences: { ...mission.sequences, turn: sequence }, counters: { ...mission.counters, turns: mission.counters.turns + 1 } }; - mission = record2(deps3, mission, "turn_recorded", { + mission = record2(deps4, mission, "turn_recorded", { turnId: turn.turnId, speaker: turn.speaker, kind: turn.kind }); if (mission.status === "IDEA") { - mission = transition(deps3, mission, "DISCOVERING"); + mission = transition(deps4, mission, "DISCOVERING"); } - return { mission: persist(deps3, mission), turn }; + return { mission: persist(deps4, mission), turn }; } function validateSafeRegex(patterns, what) { const validated = []; @@ -55201,14 +55201,14 @@ function validateSafeRegex(patterns, what) { } return validated; } -function requireUserTurn(deps3, missionId, turnId, what) { +function requireUserTurn(deps4, missionId, turnId, what) { if (turnId === void 0) { throw new MissionError( "SBM007", `${what} claims user provenance but references no conversation turn. A user-provenance decision must point at the visible turn that confirms it.` ); } - const turn = findTurn(deps3.workspace, missionId, turnId); + const turn = findTurn(deps4.workspace, missionId, turnId); if (turn === void 0) { throw new MissionError("SBM007", `${what} references turn "${turnId}", which does not exist.`); } @@ -55232,10 +55232,10 @@ function requireDecisions(activeDecisions, decisionIds, what) { } } } -function recordAssessment(deps3, missionId, input) { - let mission = requireMissionState(deps3.workspace, missionId); +function recordAssessment(deps4, missionId, input) { + let mission = requireMissionState(deps4.workspace, missionId); assertDiscoveryOpen(mission, "a discovery assessment"); - const at = now(deps3).toISOString(); + const at = now(deps4).toISOString(); const factIds = []; const questionIds = []; const decisionIds = []; @@ -55247,18 +55247,18 @@ function recordAssessment(deps3, missionId, input) { if (mission.counters.facts >= MISSION_LIMITS.maxFacts) { throw new MissionError("SBM006", `The mission reached its ${MISSION_LIMITS.maxFacts}-fact bound.`); } - if (fact.sourceTurnId !== void 0 && findTurn(deps3.workspace, missionId, fact.sourceTurnId) === void 0) { + if (fact.sourceTurnId !== void 0 && findTurn(deps4.workspace, missionId, fact.sourceTurnId) === void 0) { throw new MissionError("SBM005", `Fact references turn "${fact.sourceTurnId}", which does not exist.`); } if (fact.supersedesFactId !== void 0) { - const existing = readFacts(deps3.workspace, missionId).find( + const existing = readFacts(deps4.workspace, missionId).find( (candidate) => candidate.factId === fact.supersedesFactId ); if (existing === void 0) { throw new MissionError("SBM009", `Fact "${fact.supersedesFactId}" cannot be superseded: it does not exist.`); } - appendFact(deps3.workspace, missionId, { ...existing, status: "superseded" }); - mission = record2(deps3, mission, "fact_superseded", { factId: existing.factId }); + appendFact(deps4.workspace, missionId, { ...existing, status: "superseded" }); + mission = record2(deps4, mission, "fact_superseded", { factId: existing.factId }); } const sequence = mission.sequences.fact + 1; const recordFact = { @@ -55271,14 +55271,14 @@ function recordAssessment(deps3, missionId, input) { ...fact.supersedesFactId !== void 0 ? { supersedes: fact.supersedesFactId } : {}, recordedAt: at }; - appendFact(deps3.workspace, missionId, recordFact); + appendFact(deps4.workspace, missionId, recordFact); factIds.push(recordFact.factId); mission = { ...mission, sequences: { ...mission.sequences, fact: sequence }, counters: { ...mission.counters, facts: mission.counters.facts + 1 } }; - mission = record2(deps3, mission, "fact_recorded", { + mission = record2(deps4, mission, "fact_recorded", { factId: recordFact.factId, provenance: recordFact.provenance }); @@ -55308,7 +55308,7 @@ function recordAssessment(deps3, missionId, input) { ...question.sourceTurnId !== void 0 ? { sourceTurnId: question.sourceTurnId } : {}, askedAt: at }; - appendQuestion(deps3.workspace, missionId, recordQuestion); + appendQuestion(deps4.workspace, missionId, recordQuestion); questionIds.push(recordQuestion.questionId); if (assessment.raisedFrom !== void 0) { materialityRaised.push({ @@ -55326,19 +55326,19 @@ function recordAssessment(deps3, missionId, input) { openQuestions: mission.counters.openQuestions + 1 } }; - mission = record2(deps3, mission, "question_opened", { + mission = record2(deps4, mission, "question_opened", { questionId: recordQuestion.questionId, materiality: recordQuestion.materiality }); } for (const decision of input.decisions ?? []) { - mission = recordDecisionInternal(deps3, missionId, mission, decision, at, decisionIds); + mission = recordDecisionInternal(deps4, missionId, mission, decision, at, decisionIds); } if ((input.constitutionRules ?? []).length > 0) { - const activeDecisions = readDecisions(deps3.workspace, missionId).filter( + const activeDecisions = readDecisions(deps4.workspace, missionId).filter( (decision) => decision.status === "active" ); - let constitution = readConstitution(deps3.workspace, missionId) ?? { + let constitution = readConstitution(deps4.workspace, missionId) ?? { schemaVersion: MISSION_CONSTITUTION_SCHEMA_VERSION, missionId, version: 0, @@ -55363,7 +55363,7 @@ function recordAssessment(deps3, missionId, input) { rules = rules.map( (candidate) => candidate.ruleId === rule.supersedesRuleId ? { ...candidate, status: "superseded" } : candidate ); - mission = record2(deps3, mission, "constitution_rule_superseded", { ruleId: rule.supersedesRuleId }); + mission = record2(deps4, mission, "constitution_rule_superseded", { ruleId: rule.supersedesRuleId }); } const sequence = mission.sequences.constitutionRule + 1; const ruleId = `CON-${pad(sequence, 3)}`; @@ -55395,12 +55395,12 @@ function recordAssessment(deps3, missionId, input) { sequences: { ...mission.sequences, constitutionRule: sequence }, counters: { ...mission.counters, constitutionRules: mission.counters.constitutionRules + 1 } }; - mission = record2(deps3, mission, "constitution_rule_recorded", { ruleId }); + mission = record2(deps4, mission, "constitution_rule_recorded", { ruleId }); } - writeConstitution(deps3.workspace, missionId, constitution); + writeConstitution(deps4.workspace, missionId, constitution); } if ((input.adrs ?? []).length > 0) { - const activeDecisions = readDecisions(deps3.workspace, missionId).filter( + const activeDecisions = readDecisions(deps4.workspace, missionId).filter( (decision) => decision.status === "active" ); for (const adr of input.adrs ?? []) { @@ -55435,18 +55435,18 @@ function recordAssessment(deps3, missionId, input) { ...adr.supersedesAdrId !== void 0 ? { supersedes: adr.supersedesAdrId } : {}, recordedAt: at }); - storeAdr(deps3.workspace, missionId, document); + storeAdr(deps4.workspace, missionId, document); adrIds.push(adrId); mission = { ...mission, sequences: { ...mission.sequences, adr: sequence }, counters: { ...mission.counters, adrs: mission.counters.adrs + 1 } }; - mission = record2(deps3, mission, "adr_recorded", { adrId }); + mission = record2(deps4, mission, "adr_recorded", { adrId }); } } if ((input.contracts ?? []).length > 0) { - const activeDecisions = readDecisions(deps3.workspace, missionId).filter( + const activeDecisions = readDecisions(deps4.workspace, missionId).filter( (decision) => decision.status === "active" ); for (const contract of input.contracts ?? []) { @@ -55484,14 +55484,14 @@ function recordAssessment(deps3, missionId, input) { turnIds: (contract.turnIds ?? []).slice(0, MISSION_LIMITS.maxRefsPerRecord), recordedAt: at }); - storeContractRevision(deps3.workspace, missionId, document); + storeContractRevision(deps4.workspace, missionId, document); contractIds.push(contractId); mission = { ...mission, sequences: { ...mission.sequences, contract: sequence }, counters: { ...mission.counters, contracts: mission.counters.contracts + 1 } }; - mission = record2(deps3, mission, "contract_recorded", { contractId, revision: 1 }); + mission = record2(deps4, mission, "contract_recorded", { contractId, revision: 1 }); } } const updates = input.missionUpdates; @@ -55514,12 +55514,12 @@ function recordAssessment(deps3, missionId, input) { }; } if (mission.status === "IDEA") { - mission = transition(deps3, mission, "DISCOVERING"); + mission = transition(deps4, mission, "DISCOVERING"); } - const coverage = refreshCoverage(deps3, mission); - mission = reconcileStatusWithCoverage(deps3, mission, coverage); + const coverage = refreshCoverage(deps4, mission); + mission = reconcileStatusWithCoverage(deps4, mission, coverage); return { - mission: persist(deps3, mission), + mission: persist(deps4, mission), coverage, factIds, questionIds, @@ -55530,7 +55530,7 @@ function recordAssessment(deps3, missionId, input) { materialityRaised }; } -function recordDecisionInternal(deps3, missionId, mission, input, at, outIds) { +function recordDecisionInternal(deps4, missionId, mission, input, at, outIds) { if (mission.counters.decisions >= MISSION_LIMITS.maxDecisions) { throw new MissionError("SBM006", `The mission reached its ${MISSION_LIMITS.maxDecisions}-decision bound.`); } @@ -55542,11 +55542,11 @@ function recordDecisionInternal(deps3, missionId, mission, input, at, outIds) { ); } if (input.provenance === "known-from-user") { - requireUserTurn(deps3, missionId, input.sourceTurnId, "A decision"); - } else if (input.sourceTurnId !== void 0 && findTurn(deps3.workspace, missionId, input.sourceTurnId) === void 0) { + requireUserTurn(deps4, missionId, input.sourceTurnId, "A decision"); + } else if (input.sourceTurnId !== void 0 && findTurn(deps4.workspace, missionId, input.sourceTurnId) === void 0) { throw new MissionError("SBM005", `Decision references turn "${input.sourceTurnId}", which does not exist.`); } - const questions = readQuestions(deps3.workspace, missionId); + const questions = readQuestions(deps4.workspace, missionId); let answeredQuestion; if (input.questionId !== void 0) { answeredQuestion = questions.find((question) => question.questionId === input.questionId); @@ -55555,14 +55555,14 @@ function recordDecisionInternal(deps3, missionId, mission, input, at, outIds) { } } if (input.supersedesDecisionId !== void 0) { - const previous = readDecisions(deps3.workspace, missionId).find( + const previous = readDecisions(deps4.workspace, missionId).find( (candidate) => candidate.decisionId === input.supersedesDecisionId ); if (previous === void 0) { throw new MissionError("SBM009", `Decision "${input.supersedesDecisionId}" cannot be superseded: it does not exist.`); } - appendDecision(deps3.workspace, missionId, { ...previous, status: "superseded" }); - mission = record2(deps3, mission, "decision_superseded", { decisionId: previous.decisionId }); + appendDecision(deps4.workspace, missionId, { ...previous, status: "superseded" }); + mission = record2(deps4, mission, "decision_superseded", { decisionId: previous.decisionId }); } const sequence = mission.sequences.decision + 1; const decision = { @@ -55581,20 +55581,20 @@ function recordDecisionInternal(deps3, missionId, mission, input, at, outIds) { resultingArtifactIds: [], decidedAt: at }; - appendDecision(deps3.workspace, missionId, decision); + appendDecision(deps4.workspace, missionId, decision); outIds.push(decision.decisionId); mission = { ...mission, sequences: { ...mission.sequences, decision: sequence }, counters: { ...mission.counters, decisions: mission.counters.decisions + 1 } }; - mission = record2(deps3, mission, "decision_recorded", { + mission = record2(deps4, mission, "decision_recorded", { decisionId: decision.decisionId, provenance: decision.provenance, ...decision.questionId !== void 0 ? { questionId: decision.questionId } : {} }); if (answeredQuestion !== void 0 && answeredQuestion.status === "open") { - appendQuestion(deps3.workspace, missionId, { + appendQuestion(deps4.workspace, missionId, { ...answeredQuestion, status: "answered", resolvedByDecisionId: decision.decisionId @@ -55603,17 +55603,17 @@ function recordDecisionInternal(deps3, missionId, mission, input, at, outIds) { ...mission, counters: { ...mission.counters, openQuestions: Math.max(0, mission.counters.openQuestions - 1) } }; - mission = record2(deps3, mission, "question_answered", { + mission = record2(deps4, mission, "question_answered", { questionId: answeredQuestion.questionId, decisionId: decision.decisionId }); } return mission; } -function answerQuestion(deps3, missionId, request) { - const mission = requireMissionState(deps3.workspace, missionId); +function answerQuestion(deps4, missionId, request) { + const mission = requireMissionState(deps4.workspace, missionId); assertDiscoveryOpen(mission, "an answer"); - const question = readQuestions(deps3.workspace, missionId).find( + const question = readQuestions(deps4.workspace, missionId).find( (candidate) => candidate.questionId === request.questionId ); if (question === void 0) { @@ -55626,13 +55626,13 @@ function answerQuestion(deps3, missionId, request) { if (answer.length === 0) { throw new MissionError("SBM005", "An answer needs text."); } - const { turn } = recordTurn(deps3, missionId, { + const { turn } = recordTurn(deps4, missionId, { speaker: "user", kind: "statement", text: answer, refs: [question.questionId] }); - const assessment = recordAssessment(deps3, missionId, { + const assessment = recordAssessment(deps4, missionId, { decisions: [ { decision: answer, @@ -55645,7 +55645,7 @@ function answerQuestion(deps3, missionId, request) { ] }); const decisionId = assessment.decisionIds[0]; - const decision = readDecisions(deps3.workspace, missionId).find( + const decision = readDecisions(deps4.workspace, missionId).find( (candidate) => candidate.decisionId === decisionId ); if (decision === void 0) { @@ -55653,34 +55653,34 @@ function answerQuestion(deps3, missionId, request) { } return { mission: assessment.mission, decision, coverage: assessment.coverage }; } -function refreshCoverage(deps3, mission) { +function refreshCoverage(deps4, mission) { const coverage = computeCoverage({ missionId: mission.missionId, - facts: readFacts(deps3.workspace, mission.missionId), - questions: readQuestions(deps3.workspace, mission.missionId), - decisions: readDecisions(deps3.workspace, mission.missionId), - now: now(deps3) + facts: readFacts(deps4.workspace, mission.missionId), + questions: readQuestions(deps4.workspace, mission.missionId), + decisions: readDecisions(deps4.workspace, mission.missionId), + now: now(deps4) }); - writeCoverage(deps3.workspace, mission.missionId, coverage); + writeCoverage(deps4.workspace, mission.missionId, coverage); return coverage; } -function reconcileStatusWithCoverage(deps3, mission, coverage) { +function reconcileStatusWithCoverage(deps4, mission, coverage) { const blocking = coverage.blockingQuestionIds.length > 0; if (mission.status === "DISCOVERING" && blocking) { - return transition(deps3, mission, "NEEDS_DECISION"); + return transition(deps4, mission, "NEEDS_DECISION"); } if (mission.status === "NEEDS_DECISION" && !blocking) { - return transition(deps3, mission, "DISCOVERING"); + return transition(deps4, mission, "DISCOVERING"); } if (mission.status === "CONTRACT_READY" && !coverage.contractReady) { - return transition(deps3, mission, blocking ? "NEEDS_DECISION" : "DISCOVERING"); + return transition(deps4, mission, blocking ? "NEEDS_DECISION" : "DISCOVERING"); } return mission; } -function markContractReady(deps3, missionId) { - let mission = requireMissionState(deps3.workspace, missionId); +function markContractReady(deps4, missionId) { + let mission = requireMissionState(deps4.workspace, missionId); assertNotFinal(mission); - const coverage = refreshCoverage(deps3, mission); + const coverage = refreshCoverage(deps4, mission); if (!coverage.contractReady) { throw new MissionError( "SBM008", @@ -55698,36 +55698,36 @@ function markContractReady(deps3, missionId) { ); } if (mission.status !== "CONTRACT_READY") { - mission = transition(deps3, mission, "CONTRACT_READY"); - mission = persist(deps3, mission); + mission = transition(deps4, mission, "CONTRACT_READY"); + mission = persist(deps4, mission); } return { mission, coverage }; } -function reopenDiscovery(deps3, missionId, reason3) { - let mission = requireMissionState(deps3.workspace, missionId); +function reopenDiscovery(deps4, missionId, reason3) { + let mission = requireMissionState(deps4.workspace, missionId); assertNotFinal(mission); if (DISCOVERY_STATUSES.includes(mission.status) && mission.status !== "CONTRACT_READY") { return mission; } - mission = transition(deps3, mission, "DISCOVERING"); - mission = record2(deps3, mission, "status_changed", { reason: reason3.slice(0, 500), reopened: true }); - return persist(deps3, mission); + mission = transition(deps4, mission, "DISCOVERING"); + mission = record2(deps4, mission, "status_changed", { reason: reason3.slice(0, 500), reopened: true }); + return persist(deps4, mission); } -function abandonMission(deps3, missionId, reason3) { - let mission = requireMissionState(deps3.workspace, missionId); +function abandonMission(deps4, missionId, reason3) { + let mission = requireMissionState(deps4.workspace, missionId); if (isFinalMissionStatus(mission.status)) return mission; - const at = now(deps3).toISOString(); - mission = transition(deps3, mission, "ABANDONED"); - mission = record2(deps3, mission, "mission_abandoned", { reason: reason3.slice(0, 500) }); - return persist(deps3, { ...mission, abandonedAt: at, abandonReason: reason3.slice(0, MISSION_LIMITS.maxTextChars) }); + const at = now(deps4).toISOString(); + mission = transition(deps4, mission, "ABANDONED"); + mission = record2(deps4, mission, "mission_abandoned", { reason: reason3.slice(0, 500) }); + return persist(deps4, { ...mission, abandonedAt: at, abandonReason: reason3.slice(0, MISSION_LIMITS.maxTextChars) }); } -function createContractChangeRequest(deps3, missionId, request) { - let mission = requireMissionState(deps3.workspace, missionId); +function createContractChangeRequest(deps4, missionId, request) { + let mission = requireMissionState(deps4.workspace, missionId); assertNotFinal(mission); if (mission.counters.ccrs >= MISSION_LIMITS.maxCcrs) { throw new MissionError("SBM006", `The mission reached its ${MISSION_LIMITS.maxCcrs}-change-request bound.`); } - const contract = readContract(deps3.workspace, missionId, request.contractId); + const contract = readContract(deps4.workspace, missionId, request.contractId); if (contract === void 0) { throw new MissionError("SBM009", `Contract "${request.contractId}" does not exist in this mission's registry.`); } @@ -55737,7 +55737,7 @@ function createContractChangeRequest(deps3, missionId, request) { }); const material = contract.classification === "public" || contract.compatibilityPolicy === "frozen" || contract.compatibilityPolicy === "additive-only" || screen.level === "blocking"; const sequence = mission.sequences.ccr + 1; - const at = now(deps3).toISOString(); + const at = now(deps4).toISOString(); const ccr = contractChangeRequestSchema.parse({ schemaVersion: MISSION_CCR_SCHEMA_VERSION, ccrId: `CCR-${pad(sequence, 3)}`, @@ -55752,31 +55752,31 @@ function createContractChangeRequest(deps3, missionId, request) { ...request.originJobId !== void 0 ? { originJobId: request.originJobId } : {}, createdAt: at }); - writeCcr(deps3.workspace, missionId, ccr); + writeCcr(deps4.workspace, missionId, ccr); mission = { ...mission, sequences: { ...mission.sequences, ccr: sequence }, counters: { ...mission.counters, ccrs: mission.counters.ccrs + 1 } }; - mission = record2(deps3, mission, "ccr_created", { + mission = record2(deps4, mission, "ccr_created", { ccrId: ccr.ccrId, contractId: ccr.contractId, status: ccr.status, raisedBy: ccr.raisedBy }); - return { mission: persist(deps3, mission), ccr, material }; + return { mission: persist(deps4, mission), ccr, material }; } -function decideContractChangeRequest(deps3, missionId, request) { - let mission = requireMissionState(deps3.workspace, missionId); +function decideContractChangeRequest(deps4, missionId, request) { + let mission = requireMissionState(deps4.workspace, missionId); assertNotFinal(mission); - const existing = readCcr(deps3.workspace, missionId, request.ccrId); + const existing = readCcr(deps4.workspace, missionId, request.ccrId); if (existing === void 0) { throw new MissionError("SBM009", `Change request "${request.ccrId}" does not exist.`); } if (existing.status !== "PROPOSED" && existing.status !== "NEEDS_HUMAN") { throw new MissionError("SBM013", `Change request ${existing.ccrId} is already ${existing.status}.`); } - const at = now(deps3).toISOString(); + const at = now(deps4).toISOString(); if (request.decision === "rejected") { const rejected = { ...existing, @@ -55784,17 +55784,17 @@ function decideContractChangeRequest(deps3, missionId, request) { decidedAt: at, ...request.note !== void 0 ? { decisionNote: request.note.slice(0, MISSION_LIMITS.maxTextChars) } : {} }; - writeCcr(deps3.workspace, missionId, rejected); - mission = record2(deps3, mission, "ccr_decided", { ccrId: existing.ccrId, decision: "rejected" }); - return { mission: persist(deps3, mission), ccr: rejected }; + writeCcr(deps4.workspace, missionId, rejected); + mission = record2(deps4, mission, "ccr_decided", { ccrId: existing.ccrId, decision: "rejected" }); + return { mission: persist(deps4, mission), ccr: rejected }; } - const current = readContract(deps3.workspace, missionId, existing.contractId); + const current = readContract(deps4.workspace, missionId, existing.contractId); if (current === void 0) { throw new MissionError("SBM009", `Contract "${existing.contractId}" vanished from the registry.`); } const decisionIds = []; mission = recordDecisionInternal( - deps3, + deps4, missionId, mission, { @@ -55843,7 +55843,7 @@ function decideContractChangeRequest(deps3, missionId, request) { status: "active" }); } - storeContractRevision(deps3.workspace, missionId, nextRevision); + storeContractRevision(deps4.workspace, missionId, nextRevision); const approved = { ...existing, status: "APPROVED", @@ -55851,27 +55851,27 @@ function decideContractChangeRequest(deps3, missionId, request) { ...request.note !== void 0 ? { decisionNote: request.note.slice(0, MISSION_LIMITS.maxTextChars) } : {}, resultingRevision: nextRevisionNumber }; - writeCcr(deps3.workspace, missionId, approved); - mission = record2(deps3, mission, "ccr_decided", { ccrId: existing.ccrId, decision: "approved" }); - mission = record2(deps3, mission, "contract_revised", { + writeCcr(deps4.workspace, missionId, approved); + mission = record2(deps4, mission, "ccr_decided", { ccrId: existing.ccrId, decision: "approved" }); + mission = record2(deps4, mission, "contract_revised", { contractId: current.contractId, revision: nextRevisionNumber, ccrId: existing.ccrId }); - mission = record2(deps3, mission, "ccr_applied", { + mission = record2(deps4, mission, "ccr_applied", { ccrId: existing.ccrId, contractId: current.contractId, revision: nextRevisionNumber }); - return { mission: persist(deps3, mission), ccr: approved, contract: nextRevision }; + return { mission: persist(deps4, mission), ccr: approved, contract: nextRevision }; } -function describeMission(deps3, missionId) { - const mission = requireMissionState(deps3.workspace, missionId); - const coverage = refreshCoverage(deps3, mission); - const questions = readQuestions(deps3.workspace, missionId); +function describeMission(deps4, missionId) { + const mission = requireMissionState(deps4.workspace, missionId); + const coverage = refreshCoverage(deps4, mission); + const questions = readQuestions(deps4.workspace, missionId); const openQuestions = questions.filter((question) => question.status === "open"); - const constitution = readConstitution(deps3.workspace, missionId); - const openCcrs = readCcrs(deps3.workspace, missionId).filter( + const constitution = readConstitution(deps4.workspace, missionId); + const openCcrs = readCcrs(deps4.workspace, missionId).filter( (ccr) => ccr.status === "PROPOSED" || ccr.status === "NEEDS_HUMAN" ); return { @@ -55879,12 +55879,12 @@ function describeMission(deps3, missionId) { coverage, openQuestions, blockingQuestions: openQuestions.filter((question) => question.materiality === "blocking"), - activeDecisionCount: readDecisions(deps3.workspace, missionId).filter( + activeDecisionCount: readDecisions(deps4.workspace, missionId).filter( (decision) => decision.status === "active" ).length, constitutionVersion: constitution?.version ?? 0, activeConstitutionRules: constitution?.rules.filter((rule) => rule.status === "active").length ?? 0, - contractCount: readContractRegistry(deps3.workspace, missionId).length, + contractCount: readContractRegistry(deps4.workspace, missionId).length, adrCount: mission.counters.adrs, openCcrs }; @@ -55958,9 +55958,9 @@ function assignSuccessCriteria(successCriteria, contracts) { const criterionTokens = tokenize(statement); let best = contracts.length - 1; let bestScore = 0; - contractTokens.forEach((tokens, contractIndex) => { + contractTokens.forEach((tokens2, contractIndex) => { let score = 0; - for (const token of criterionTokens) if (tokens.has(token)) score += 1; + for (const token of criterionTokens) if (tokens2.has(token)) score += 1; if (score > bestScore) { bestScore = score; best = contractIndex; @@ -56199,8 +56199,8 @@ function validateCompiledDocuments(documents) { } return problems; } -function synthesizeMissionSpec(deps3, missionId, request = {}) { - let mission = requireMissionState(deps3.workspace, missionId); +function synthesizeMissionSpec(deps4, missionId, request = {}) { + let mission = requireMissionState(deps4.workspace, missionId); if (mission.status !== "CONTRACT_READY") { throw new MissionError( "SBM014", @@ -56212,7 +56212,7 @@ function synthesizeMissionSpec(deps3, missionId, request = {}) { } ); } - const coverage = refreshCoverage(deps3, mission); + const coverage = refreshCoverage(deps4, mission); if (!coverage.contractReady) { throw new MissionError("SBM008", `The coverage gate no longer holds: ${coverage.reasons.join(" ")}`); } @@ -56221,10 +56221,10 @@ function synthesizeMissionSpec(deps3, missionId, request = {}) { if (!nameCheck.valid) { throw new MissionError("SBM005", `"${specName}" is not a valid spec name: ${nameCheck.problems.join("; ")}`); } - const contracts = readContractRegistry(deps3.workspace, missionId); - const constitution = readConstitution(deps3.workspace, missionId); - const adrs = readAdrs(deps3.workspace, missionId); - const decisions = readDecisions(deps3.workspace, missionId); + const contracts = readContractRegistry(deps4.workspace, missionId); + const constitution = readConstitution(deps4.workspace, missionId); + const adrs = readAdrs(deps4.workspace, missionId); + const decisions = readDecisions(deps4.workspace, missionId); const compiled = compileMissionDocuments({ mission, contracts, @@ -56236,20 +56236,20 @@ function synthesizeMissionSpec(deps3, missionId, request = {}) { if (problems.length > 0) { throw new MissionError("SBM011", `The compiled spec candidates are invalid: ${problems.join("; ")}.`); } - const at = (deps3.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); + const at = (deps4.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); mission = { ...mission, updatedAt: at }; assertMissionTransition(mission.status, "SPEC_SYNTHESIS"); mission = { ...mission, status: "SPEC_SYNTHESIS" }; - appendMissionEvent(deps3.workspace, missionId, { at, type: "synthesis_started", specName }); - mission = writeMissionState(deps3.workspace, { + appendMissionEvent(deps4.workspace, missionId, { at, type: "synthesis_started", specName }); + mission = writeMissionState(deps4.workspace, { ...mission, counters: { ...mission.counters, events: mission.counters.events + 1 } }); - writeSpecCandidate(deps3.workspace, missionId, "requirements.md", compiled.requirements); - writeSpecCandidate(deps3.workspace, missionId, "design.md", compiled.design); - writeSpecCandidate(deps3.workspace, missionId, "tasks.md", compiled.tasks); + writeSpecCandidate(deps4.workspace, missionId, "requirements.md", compiled.requirements); + writeSpecCandidate(deps4.workspace, missionId, "design.md", compiled.design); + writeSpecCandidate(deps4.workspace, missionId, "tasks.md", compiled.tasks); writeSpecCandidate( - deps3.workspace, + deps4.workspace, missionId, "provenance.json", `${JSON.stringify( @@ -56271,7 +56271,7 @@ function synthesizeMissionSpec(deps3, missionId, request = {}) { ); try { const plan = planSpecCreationFromFiles( - deps3.workspace, + deps4.workspace, { name: specName, specType: "feature", @@ -56285,19 +56285,19 @@ function synthesizeMissionSpec(deps3, missionId, request = {}) { { fileName: "tasks.md", stage: "tasks", content: compiled.tasks } ] }, - deps3.clock ?? (() => /* @__PURE__ */ new Date()) + deps4.clock ?? (() => /* @__PURE__ */ new Date()) ); - executeSpecCreation(deps3.workspace, plan); + executeSpecCreation(deps4.workspace, plan); } catch (cause) { - const failedAt = (deps3.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); - appendMissionEvent(deps3.workspace, missionId, { + const failedAt = (deps4.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); + appendMissionEvent(deps4.workspace, missionId, { at: failedAt, type: "status_changed", from: "SPEC_SYNTHESIS", to: "CONTRACT_READY", reason: "synthesis failed" }); - writeMissionState(deps3.workspace, { + writeMissionState(deps4.workspace, { ...mission, status: "CONTRACT_READY", updatedAt: failedAt, @@ -56310,19 +56310,19 @@ function synthesizeMissionSpec(deps3, missionId, request = {}) { ); } assertMissionTransition("SPEC_SYNTHESIS", "SPEC_REVIEW"); - appendMissionEvent(deps3.workspace, missionId, { + appendMissionEvent(deps4.workspace, missionId, { at, type: "synthesis_completed", specName, objectives: compiled.objectiveCount }); - appendMissionEvent(deps3.workspace, missionId, { + appendMissionEvent(deps4.workspace, missionId, { at, type: "status_changed", from: "SPEC_SYNTHESIS", to: "SPEC_REVIEW" }); - mission = writeMissionState(deps3.workspace, { + mission = writeMissionState(deps4.workspace, { ...mission, status: "SPEC_REVIEW", specName, @@ -56342,33 +56342,33 @@ function synthesizeMissionSpec(deps3, missionId, request = {}) { warnings: [] }; } -function observeSpecApproval(deps3, missionId) { - let mission = requireMissionState(deps3.workspace, missionId); +function observeSpecApproval(deps4, missionId) { + let mission = requireMissionState(deps4.workspace, missionId); if (mission.status !== "SPEC_REVIEW" || mission.specName === void 0) return mission; let approved = false; try { - const spec = analyzeSpec(deps3.workspace, requireSpec(deps3.workspace, mission.specName)); + const spec = analyzeSpec(deps4.workspace, requireSpec(deps4.workspace, mission.specName)); if (spec.state !== void 0) { - approved = evaluateWorkflow(deps3.workspace, spec.state).effectiveStatus === "READY_FOR_IMPLEMENTATION"; + approved = evaluateWorkflow(deps4.workspace, spec.state).effectiveStatus === "READY_FOR_IMPLEMENTATION"; } } catch { return mission; } if (!approved) return mission; - const at = (deps3.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); + const at = (deps4.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); assertMissionTransition("SPEC_REVIEW", "APPROVED"); - appendMissionEvent(deps3.workspace, missionId, { + appendMissionEvent(deps4.workspace, missionId, { at, type: "spec_approval_observed", specName: mission.specName }); - appendMissionEvent(deps3.workspace, missionId, { + appendMissionEvent(deps4.workspace, missionId, { at, type: "status_changed", from: "SPEC_REVIEW", to: "APPROVED" }); - mission = writeMissionState(deps3.workspace, { + mission = writeMissionState(deps4.workspace, { ...mission, status: "APPROVED", approvedAt: at, @@ -58178,14 +58178,14 @@ function orchestrationStorageBytes(workspace, orchestrationId) { walk(dir); return total; } -function policyOf(deps3) { - return deps3.config.orchestration; +function policyOf(deps4) { + return deps4.config.orchestration; } -function now2(deps3) { - return (deps3.clock ?? systemClock)(); +function now2(deps4) { + return (deps4.clock ?? systemClock)(); } -function newId(deps3) { - return (deps3.idFactory ?? import_crypto18.randomUUID)(); +function newId(deps4) { + return (deps4.idFactory ?? import_crypto18.randomUUID)(); } function assertEnabled(policy) { if (policy.enabled) return; @@ -58199,9 +58199,9 @@ function assertEnabled(policy) { } ); } -function record3(deps3, state, type, payload = {}) { - const policy = policyOf(deps3); - const stored = countOrchestrationEvents(deps3.workspace, state.orchestrationId); +function record3(deps4, state, type, payload = {}) { + const policy = policyOf(deps4); + const stored = countOrchestrationEvents(deps4.workspace, state.orchestrationId); if (stored >= state.budgets.maxEvents) { throw new OrchestrationError( "SBO020", @@ -58215,25 +58215,25 @@ function record3(deps3, state, type, payload = {}) { ); } appendOrchestrationEvent( - deps3.workspace, + deps4.workspace, state.orchestrationId, - { at: now2(deps3).toISOString(), type, ...payload }, + { at: now2(deps4).toISOString(), type, ...payload }, { maxEventBytes: policy.history.maxEventBytes } ); return { ...state, counters: { ...state.counters, events: stored + 1 } }; } -function transition2(deps3, state, to) { +function transition2(deps4, state, to) { assertTransition(state.phase, to); - return { ...state, phase: to, updatedAt: now2(deps3).toISOString() }; + return { ...state, phase: to, updatedAt: now2(deps4).toISOString() }; } -function persist2(deps3, state) { - return writeOrchestrationState(deps3.workspace, { +function persist2(deps4, state) { + return writeOrchestrationState(deps4.workspace, { ...state, - updatedAt: now2(deps3).toISOString() + updatedAt: now2(deps4).toISOString() }); } -function beginOrchestration(deps3, request) { - const policy = policyOf(deps3); +function beginOrchestration(deps4, request) { + const policy = policyOf(deps4); assertEnabled(policy); const goal = request.goal.trim(); if (goal.length === 0) { @@ -58241,17 +58241,17 @@ function beginOrchestration(deps3, request) { remediation: ["Describe what the user asked for, in one or two sentences."] }); } - const createdAt = now2(deps3).toISOString(); + const createdAt = now2(deps4).toISOString(); const state = { schemaVersion: ORCHESTRATION_STATE_SCHEMA_VERSION, - orchestrationId: newId(deps3), + orchestrationId: newId(deps4), specName: request.specName, ...request.taskId !== void 0 ? { taskId: request.taskId } : {}, phase: "CREATED", goal: goal.slice(0, 4e3), createdAt, updatedAt: createdAt, - host: deps3.host ?? "mcp", + host: deps4.host ?? "mcp", planningMode: policy.planning.mode, policyFingerprint: orchestrationPolicyFingerprint(policy), budgets: { @@ -58279,18 +58279,18 @@ function beginOrchestration(deps3, request) { planStaleReasons: [], interactiveRunIds: [] }; - createOrchestrationRun(deps3.workspace, state); - const recorded = record3(deps3, state, "orchestration_started", { + createOrchestrationRun(deps4.workspace, state); + const recorded = record3(deps4, state, "orchestration_started", { specName: state.specName, ...state.taskId !== void 0 ? { taskId: state.taskId } : {}, planningMode: state.planningMode }); - return persist2(deps3, recorded); + return persist2(deps4, recorded); } -function assessIntent(deps3, orchestrationId, submission) { - const policy = policyOf(deps3); +function assessIntent(deps4, orchestrationId, submission) { + const policy = policyOf(deps4); assertEnabled(policy); - let state = requireOrchestrationState(deps3.workspace, orchestrationId); + let state = requireOrchestrationState(deps4.workspace, orchestrationId); if (isFinalPhase(state.phase)) { throw new OrchestrationError( "SBO005", @@ -58300,18 +58300,18 @@ function assessIntent(deps3, orchestrationId, submission) { } const validation = validateIntent( { - workspace: deps3.workspace, + workspace: deps4.workspace, specName: state.specName, taskId: state.taskId, policy, orchestrationId }, submission, - { assessedAt: now2(deps3).toISOString() } + { assessedAt: now2(deps4).toISOString() } ); const target = validation.assessment.outcome === "READY" ? "READY_TO_PLAN" : validation.assessment.outcome === "NEEDS_CLARIFICATION" ? "NEEDS_CLARIFICATION" : validation.assessment.outcome === "REJECTED" ? "REJECTED" : "BLOCKED"; state = { ...state, intent: validation.assessment }; - state = transition2(deps3, state, target); + state = transition2(deps4, state, target); if (target === "BLOCKED" && validation.blockers[0] !== void 0) { const first = validation.blockers[0]; state = { @@ -58321,25 +58321,25 @@ function assessIntent(deps3, orchestrationId, submission) { code: first.code, message: first.message, remediation: first.remediation, - at: now2(deps3).toISOString() + at: now2(deps4).toISOString() } }; } if (target === "REJECTED") { state = { ...state, - finalizedAt: now2(deps3).toISOString(), + finalizedAt: now2(deps4).toISOString(), finalOutcome: "REJECTED" }; } - state = record3(deps3, state, "intent_assessed", { + state = record3(deps4, state, "intent_assessed", { outcome: validation.assessment.outcome, overridden: validation.overridden, ...validation.assessment.overriddenFrom !== void 0 ? { submittedOutcome: validation.assessment.overriddenFrom } : {}, blockers: validation.blockers.map((blocker) => blocker.code) }); return { - state: persist2(deps3, state), + state: persist2(deps4, state), overridden: validation.overridden, blockers: validation.blockers.map((blocker) => ({ code: blocker.code, @@ -58348,14 +58348,14 @@ function assessIntent(deps3, orchestrationId, submission) { })) }; } -function requestClarification(deps3, orchestrationId, candidates) { - const policy = policyOf(deps3); +function requestClarification(deps4, orchestrationId, candidates) { + const policy = policyOf(deps4); assertEnabled(policy); - let state = requireOrchestrationState(deps3.workspace, orchestrationId); + let state = requireOrchestrationState(deps4.workspace, orchestrationId); assertActionAllowed(state.phase, "REQUEST_CLARIFICATION"); const round2 = buildClarificationRound(state, candidates, policy, { - askedAt: now2(deps3).toISOString(), - idFactory: () => newId(deps3) + askedAt: now2(deps4).toISOString(), + idFactory: () => newId(deps4) }); state = { ...state, @@ -58363,18 +58363,18 @@ function requestClarification(deps3, orchestrationId, candidates) { counters: { ...state.counters, clarificationRounds: round2.round } }; if (state.phase !== "NEEDS_CLARIFICATION") { - state = transition2(deps3, state, "NEEDS_CLARIFICATION"); + state = transition2(deps4, state, "NEEDS_CLARIFICATION"); } - state = record3(deps3, state, "clarification_requested", { + state = record3(deps4, state, "clarification_requested", { round: round2.round, questionIds: round2.questions.map((question) => question.id) }); - return persist2(deps3, state); + return persist2(deps4, state); } -function resolveClarification(deps3, orchestrationId, candidates) { - const policy = policyOf(deps3); +function resolveClarification(deps4, orchestrationId, candidates) { + const policy = policyOf(deps4); assertEnabled(policy); - let state = requireOrchestrationState(deps3.workspace, orchestrationId); + let state = requireOrchestrationState(deps4.workspace, orchestrationId); if (isFinalPhase(state.phase)) { throw new OrchestrationError( "SBO005", @@ -58382,8 +58382,8 @@ function resolveClarification(deps3, orchestrationId, candidates) { ); } const decisions = buildClarificationDecisions(state, candidates, policy, { - decidedAt: now2(deps3).toISOString(), - idFactory: () => newId(deps3) + decidedAt: now2(deps4).toISOString(), + idFactory: () => newId(deps4) }); const answeredIds = new Set(decisions.map((decision) => decision.questionId)); state = { @@ -58392,19 +58392,19 @@ function resolveClarification(deps3, orchestrationId, candidates) { openQuestions: state.openQuestions.filter((question) => !answeredIds.has(question.id)) }; if (state.openQuestions.length === 0 && state.phase === "NEEDS_CLARIFICATION") { - state = transition2(deps3, state, "READY_TO_PLAN"); + state = transition2(deps4, state, "READY_TO_PLAN"); } - state = record3(deps3, state, "clarification_resolved", { + state = record3(deps4, state, "clarification_resolved", { decisionIds: decisions.map((decision) => decision.id), remainingQuestions: state.openQuestions.length }); const requiresSpecChange = decisions.filter((decision) => /\b(spec|requirement|design|acceptance criteri)\b/i.test(decision.impact ?? "")).map((decision) => decision.id); - return { state: persist2(deps3, state), requiresSpecChange }; + return { state: persist2(deps4, state), requiresSpecChange }; } -async function submitPlan(deps3, orchestrationId, candidate) { - const policy = policyOf(deps3); +async function submitPlan(deps4, orchestrationId, candidate) { + const policy = policyOf(deps4); assertEnabled(policy); - let state = requireOrchestrationState(deps3.workspace, orchestrationId); + let state = requireOrchestrationState(deps4.workspace, orchestrationId); if (isFinalPhase(state.phase)) { throw new OrchestrationError( "SBO005", @@ -58445,26 +58445,26 @@ async function submitPlan(deps3, orchestrationId, candidate) { } ); } - const snapshot2 = await captureGitSnapshot(deps3.workspace.rootDir, { clock: () => now2(deps3) }); - const binding = capturePlanBinding(deps3.workspace, { + const snapshot2 = await captureGitSnapshot(deps4.workspace.rootDir, { clock: () => now2(deps4) }); + const binding = capturePlanBinding(deps4.workspace, { specName: state.specName, taskId: candidate.taskId, policy, gitHead: snapshot2.head }); const revision = state.planRevision + 1; - const previous = replacing ? readPlanRevision(deps3.workspace, orchestrationId, state.planRevision) : void 0; + const previous = replacing ? readPlanRevision(deps4.workspace, orchestrationId, state.planRevision) : void 0; const plan = buildExecutionPlan({ candidate, specName: state.specName, binding, revision, - planId: newId(deps3), - createdAt: now2(deps3).toISOString(), + planId: newId(deps4), + createdAt: now2(deps4).toISOString(), policy, ...previous !== void 0 ? { supersedes: previous.planId } : {} }); - const stored = storePlanRevision(deps3.workspace, orchestrationId, plan); + const stored = storePlanRevision(deps4.workspace, orchestrationId, plan); const materiality = previous !== void 0 ? assessPlanChange(previous, plan) : void 0; const reviewRequired = policy.planning.mode === "review" && (state.planReview?.decision !== "approved" || materiality?.materiality === "material"); state = { @@ -58483,7 +58483,7 @@ async function submitPlan(deps3, orchestrationId, candidate) { } }; if (reviewRequired) delete state.planReview; - state = record3(deps3, state, "plan_created", { + state = record3(deps4, state, "plan_created", { revision, planId: plan.planId, planHash: stored.hash, @@ -58492,24 +58492,24 @@ async function submitPlan(deps3, orchestrationId, candidate) { ...materiality !== void 0 ? { materialChanges: materiality.materialChanges } : {} }); if (replacing) { - state = record3(deps3, state, "replan_started", { + state = record3(deps4, state, "replan_started", { revision, ...candidate.replanReason !== void 0 ? { reason: candidate.replanReason } : {} }); } - state = transition2(deps3, state, reviewRequired ? "AWAITING_PLAN_REVIEW" : "READY_TO_EXECUTE"); + state = transition2(deps4, state, reviewRequired ? "AWAITING_PLAN_REVIEW" : "READY_TO_EXECUTE"); return { - state: persist2(deps3, state), + state: persist2(deps4, state), plan, planHash: stored.hash, reviewRequired, ...materiality !== void 0 ? { materiality } : {} }; } -function reviewPlan(deps3, orchestrationId, request) { - const policy = policyOf(deps3); +function reviewPlan(deps4, orchestrationId, request) { + const policy = policyOf(deps4); assertEnabled(policy); - let state = requireOrchestrationState(deps3.workspace, orchestrationId); + let state = requireOrchestrationState(deps4.workspace, orchestrationId); if (state.phase !== "AWAITING_PLAN_REVIEW") { throw new OrchestrationError( "SBO004", @@ -58529,7 +58529,7 @@ function reviewPlan(deps3, orchestrationId, request) { } ); } - const reviewedAt = now2(deps3).toISOString(); + const reviewedAt = now2(deps4).toISOString(); state = { ...state, planReview: { @@ -58541,21 +58541,21 @@ function reviewPlan(deps3, orchestrationId, request) { ...request.note !== void 0 ? { note: request.note } : {} } }; - state = record3(deps3, state, "plan_reviewed", { + state = record3(deps4, state, "plan_reviewed", { decision: request.decision, revision: state.planRevision, planHash: request.planHash }); - state = transition2(deps3, state, request.decision === "approved" ? "READY_TO_EXECUTE" : "READY_TO_PLAN"); - return persist2(deps3, state); + state = transition2(deps4, state, request.decision === "approved" ? "READY_TO_EXECUTE" : "READY_TO_PLAN"); + return persist2(deps4, state); } -async function checkPlanFreshness(deps3, orchestrationId) { - const policy = policyOf(deps3); - const state = requireOrchestrationState(deps3.workspace, orchestrationId); +async function checkPlanFreshness(deps4, orchestrationId) { + const policy = policyOf(deps4); + const state = requireOrchestrationState(deps4.workspace, orchestrationId); if (state.planRevision === 0) { return { fresh: false, reasons: ["no-plan"], explanations: ["No plan exists yet."], planRevision: 0 }; } - const plan = readPlanRevision(deps3.workspace, orchestrationId, state.planRevision); + const plan = readPlanRevision(deps4.workspace, orchestrationId, state.planRevision); if (plan === void 0) { return { fresh: false, @@ -58564,8 +58564,8 @@ async function checkPlanFreshness(deps3, orchestrationId) { planRevision: state.planRevision }; } - const snapshot2 = await captureGitSnapshot(deps3.workspace.rootDir, { clock: () => now2(deps3) }); - const current = capturePlanBinding(deps3.workspace, { + const snapshot2 = await captureGitSnapshot(deps4.workspace.rootDir, { clock: () => now2(deps4) }); + const current = capturePlanBinding(deps4.workspace, { specName: state.specName, taskId: plan.binding.taskId, policy, @@ -58574,16 +58574,16 @@ async function checkPlanFreshness(deps3, orchestrationId) { const freshness = evaluatePlanFreshness(plan, current); return { ...freshness, planRevision: state.planRevision }; } -async function refreshPlanBinding(deps3, orchestrationId) { - const policy = policyOf(deps3); - let state = requireOrchestrationState(deps3.workspace, orchestrationId); +async function refreshPlanBinding(deps4, orchestrationId) { + const policy = policyOf(deps4); + let state = requireOrchestrationState(deps4.workspace, orchestrationId); if (state.planRevision === 0) { return { state, freshness: { fresh: false, reasons: ["no-plan"], explanations: ["No plan exists yet."], planRevision: 0 } }; } - const plan = readPlanRevision(deps3.workspace, orchestrationId, state.planRevision); + const plan = readPlanRevision(deps4.workspace, orchestrationId, state.planRevision); if (plan === void 0) { throw new OrchestrationError( "SBO010", @@ -58591,8 +58591,8 @@ async function refreshPlanBinding(deps3, orchestrationId) { { remediation: ["Submit a fresh plan; the previous revisions are preserved on disk."] } ); } - const snapshot2 = await captureGitSnapshot(deps3.workspace.rootDir, { clock: () => now2(deps3) }); - const current = capturePlanBinding(deps3.workspace, { + const snapshot2 = await captureGitSnapshot(deps4.workspace.rootDir, { clock: () => now2(deps4) }); + const current = capturePlanBinding(deps4.workspace, { specName: state.specName, taskId: plan.binding.taskId, policy, @@ -58601,16 +58601,16 @@ async function refreshPlanBinding(deps3, orchestrationId) { const freshness = evaluatePlanFreshness(plan, current); if (!freshness.fresh) { state = { ...state, planStaleReasons: freshness.reasons }; - state = record3(deps3, state, "plan_invalidated", { + state = record3(deps4, state, "plan_invalidated", { revision: state.planRevision, reasons: freshness.reasons }); if (state.phase !== "REPLANNING" && !isFinalPhase(state.phase)) { - state = transition2(deps3, state, "REPLANNING"); + state = transition2(deps4, state, "REPLANNING"); } - state = persist2(deps3, state); + state = persist2(deps4, state); } else if (state.planStaleReasons.length > 0) { - state = persist2(deps3, { ...state, planStaleReasons: [] }); + state = persist2(deps4, { ...state, planStaleReasons: [] }); } return { state, @@ -58622,10 +58622,10 @@ async function refreshPlanBinding(deps3, orchestrationId) { } }; } -function recordAction(deps3, orchestrationId, request) { - const policy = policyOf(deps3); +function recordAction(deps4, orchestrationId, request) { + const policy = policyOf(deps4); assertEnabled(policy); - let state = requireOrchestrationState(deps3.workspace, orchestrationId); + let state = requireOrchestrationState(deps4.workspace, orchestrationId); if (isFinalPhase(state.phase)) { throw new OrchestrationError( "SBO005", @@ -58680,7 +58680,7 @@ function recordAction(deps3, orchestrationId, request) { consecutiveNoProgress: state.counters.consecutiveNoProgress, maxNoProgressCycles: state.budgets.maxNoProgressCycles }); - const elapsedMs = Math.max(0, now2(deps3).getTime() - Date.parse(state.createdAt)); + const elapsedMs = Math.max(0, now2(deps4).getTime() - Date.parse(state.createdAt)); const decision = decideNextStep( { failure: classified2, @@ -58704,13 +58704,13 @@ function recordAction(deps3, orchestrationId, request) { ...decision.directive === "REPAIR" ? { repairCycles: state.counters.repairCycles + 1 } : {} } }; - state = record3(deps3, state, "action_recorded", { + state = record3(deps4, state, "action_recorded", { action: request.action, target: request.target.slice(0, 200), ...request.planStepId !== void 0 ? { planStepId: request.planStepId } : {}, result: request.result }); - state = record3(deps3, state, "observation_recorded", { + state = record3(deps4, state, "observation_recorded", { result: request.result, progressed: progress.progressed, consecutiveNoProgress: progress.consecutiveNoProgress, @@ -58720,42 +58720,42 @@ function recordAction(deps3, orchestrationId, request) { directive: decision.directive }); if (classified2?.category === "VERIFICATION_FAILURE") { - state = record3(deps3, state, "verification_failed", { + state = record3(deps4, state, "verification_failed", { source: request.failure?.source ?? "unknown", fingerprint: classified2.fingerprint }); } - state = applyDirective(deps3, state, decision, classified2); + state = applyDirective(deps4, state, decision, classified2); return { - state: persist2(deps3, state), + state: persist2(deps4, state), decision, progress, ...classified2 !== void 0 ? { classifiedFailure: classified2 } : {} }; } -async function recordActionChecked(deps3, orchestrationId, request) { +async function recordActionChecked(deps4, orchestrationId, request) { const needsFreshPlan = request.action === "EDIT" || request.action === "VERIFY" || request.action === "COMPLETE"; if (needsFreshPlan) { - const state = requireOrchestrationState(deps3.workspace, orchestrationId); + const state = requireOrchestrationState(deps4.workspace, orchestrationId); if (state.planRevision > 0 && !isFinalPhase(state.phase)) { - await refreshPlanBinding(deps3, orchestrationId); + await refreshPlanBinding(deps4, orchestrationId); } } - return recordAction(deps3, orchestrationId, request); + return recordAction(deps4, orchestrationId, request); } -function applyDirective(deps3, input, decision, failure3) { +function applyDirective(deps4, input, decision, failure3) { let state = input; - const at = now2(deps3).toISOString(); + const at = now2(deps4).toISOString(); switch (decision.directive) { case "CONTINUE": case "RETRY": case "VERIFY": - if (state.phase === "READY_TO_EXECUTE") state = transition2(deps3, state, "EXECUTING"); + if (state.phase === "READY_TO_EXECUTE") state = transition2(deps4, state, "EXECUTING"); return state; case "REPAIR": { if (state.phase !== "REPAIRING") { - state = transition2(deps3, state, "REPAIRING"); - state = record3(deps3, state, "repair_started", { + state = transition2(deps4, state, "REPAIRING"); + state = record3(deps4, state, "repair_started", { cycle: state.counters.repairCycles, ...failure3 !== void 0 ? { fingerprint: failure3.fingerprint } : {} }); @@ -58767,17 +58767,17 @@ function applyDirective(deps3, input, decision, failure3) { } case "REPLAN": if (state.planRevision > 0 && state.phase !== "REPLANNING") { - state = transition2(deps3, state, "REPLANNING"); + state = transition2(deps4, state, "REPLANNING"); } return state; case "CLARIFY": if (state.phase !== "NEEDS_CLARIFICATION") { - state = transition2(deps3, state, "NEEDS_CLARIFICATION"); + state = transition2(deps4, state, "NEEDS_CLARIFICATION"); } return state; case "BLOCK": { - state = transition2(deps3, state, "BLOCKED"); - state = record3(deps3, state, "execution_blocked", { + state = transition2(deps4, state, "BLOCKED"); + state = record3(deps4, state, "execution_blocked", { ...failure3 !== void 0 ? { category: failure3.category } : {}, reason: decision.reason }); @@ -58793,8 +58793,8 @@ function applyDirective(deps3, input, decision, failure3) { }; } case "STOP_BUDGET_EXHAUSTED": { - state = transition2(deps3, state, "BLOCKED"); - state = record3(deps3, state, "budget_exhausted", { + state = transition2(deps4, state, "BLOCKED"); + state = record3(deps4, state, "budget_exhausted", { budget: decision.exhaustedBudget ?? "unknown", reason: decision.reason }); @@ -58810,18 +58810,18 @@ function applyDirective(deps3, input, decision, failure3) { }; } case "STOP_FINAL": { - state = transition2(deps3, state, "CANCELLED"); - state = record3(deps3, state, "execution_cancelled", { reason: decision.reason }); + state = transition2(deps4, state, "CANCELLED"); + state = record3(deps4, state, "execution_cancelled", { reason: decision.reason }); return { ...state, finalizedAt: at, finalOutcome: "CANCELLED" }; } } } -function finalizeOrchestration(deps3, orchestrationId, request) { - let state = requireOrchestrationState(deps3.workspace, orchestrationId); +function finalizeOrchestration(deps4, orchestrationId, request) { + let state = requireOrchestrationState(deps4.workspace, orchestrationId); if (isFinalPhase(state.phase)) { return state; } - const at = now2(deps3).toISOString(); + const at = now2(deps4).toISOString(); if (request.outcome === "completed") { const accepted = request.evidenceStatus === "verified" || request.evidenceStatus === "manually-accepted"; if (!accepted) { @@ -58837,29 +58837,29 @@ function finalizeOrchestration(deps3, orchestrationId, request) { } ); } - state = transition2(deps3, state, "COMPLETED"); - state = record3(deps3, state, "execution_completed", { + state = transition2(deps4, state, "COMPLETED"); + state = record3(deps4, state, "execution_completed", { evidenceStatus: request.evidenceStatus, ...request.interactiveRunId !== void 0 ? { runId: request.interactiveRunId } : {} }); - return persist2(deps3, { ...state, finalizedAt: at, finalOutcome: "COMPLETED" }); + return persist2(deps4, { ...state, finalizedAt: at, finalOutcome: "COMPLETED" }); } if (request.outcome === "cancelled") { - state = transition2(deps3, state, "CANCELLED"); - state = record3(deps3, state, "execution_cancelled", { reason: request.reason }); - return persist2(deps3, { ...state, finalizedAt: at, finalOutcome: "CANCELLED" }); + state = transition2(deps4, state, "CANCELLED"); + state = record3(deps4, state, "execution_cancelled", { reason: request.reason }); + return persist2(deps4, { ...state, finalizedAt: at, finalOutcome: "CANCELLED" }); } - state = transition2(deps3, state, "ABORTED"); - state = record3(deps3, state, "execution_aborted", { reason: request.reason }); - return persist2(deps3, { ...state, finalizedAt: at, finalOutcome: "ABORTED" }); + state = transition2(deps4, state, "ABORTED"); + state = record3(deps4, state, "execution_aborted", { reason: request.reason }); + return persist2(deps4, { ...state, finalizedAt: at, finalOutcome: "ABORTED" }); } -function createCheckpoint(deps3, orchestrationId, input) { - let state = requireOrchestrationState(deps3.workspace, orchestrationId); - const plan = state.planRevision > 0 ? readPlanRevision(deps3.workspace, orchestrationId, state.planRevision) : void 0; +function createCheckpoint(deps4, orchestrationId, input) { + let state = requireOrchestrationState(deps4.workspace, orchestrationId); + const plan = state.planRevision > 0 ? readPlanRevision(deps4.workspace, orchestrationId, state.planRevision) : void 0; const checkpoint = orchestrationCheckpointSchema.parse({ schemaVersion: ORCHESTRATION_CHECKPOINT_SCHEMA_VERSION, orchestrationId, - createdAt: now2(deps3).toISOString(), + createdAt: now2(deps4).toISOString(), specName: state.specName, ...state.taskId !== void 0 ? { taskId: state.taskId } : {}, phase: state.phase, @@ -58873,9 +58873,9 @@ function createCheckpoint(deps3, orchestrationId, input) { ...state.blocker !== void 0 ? { blocker: state.blocker } : {}, nextAction: input.nextAction }); - writeOrchestrationCheckpoint(deps3.workspace, orchestrationId, checkpoint); - state = record3(deps3, state, "checkpoint_created", { phase: state.phase }); - persist2(deps3, state); + writeOrchestrationCheckpoint(deps4.workspace, orchestrationId, checkpoint); + state = record3(deps4, state, "checkpoint_created", { phase: state.phase }); + persist2(deps4, state); return checkpoint; } function budgetUsage(state) { @@ -59051,10 +59051,10 @@ function describeOrchestration(workspace, state, options = {}) { totalEvents: page.total }; } -async function resumeOrchestration(deps3, orchestrationId) { - const state = requireOrchestrationState(deps3.workspace, orchestrationId); +async function resumeOrchestration(deps4, orchestrationId) { + const state = requireOrchestrationState(deps4.workspace, orchestrationId); const warnings = []; - const checkpoint = readOrchestrationCheckpoint(deps3.workspace, orchestrationId); + const checkpoint = readOrchestrationCheckpoint(deps4.workspace, orchestrationId); if (isFinalPhase(state.phase)) { const explanation2 = explainOrchestration(state); return { @@ -59072,21 +59072,21 @@ async function resumeOrchestration(deps3, orchestrationId) { ] }; } - const currentFingerprint = orchestrationPolicyFingerprint(deps3.config.orchestration); + const currentFingerprint = orchestrationPolicyFingerprint(deps4.config.orchestration); const policyChanged = currentFingerprint !== state.policyFingerprint; if (policyChanged) { warnings.push( "The orchestration policy changed since this run began. The run continues under the budgets recorded at its start; start a new run to adopt the new policy." ); } - const snapshot2 = await captureGitSnapshot(deps3.workspace.rootDir, { - clock: () => (deps3.clock ?? (() => /* @__PURE__ */ new Date()))() + const snapshot2 = await captureGitSnapshot(deps4.workspace.rootDir, { + clock: () => (deps4.clock ?? (() => /* @__PURE__ */ new Date()))() }); let planStale = false; let planStaleReasons = []; let planStaleExplanations = []; if (state.planRevision > 0) { - const freshness = await checkPlanFreshness(deps3, orchestrationId); + const freshness = await checkPlanFreshness(deps4, orchestrationId); planStale = !freshness.fresh; planStaleReasons = freshness.reasons; planStaleExplanations = freshness.explanations; @@ -59098,8 +59098,8 @@ async function resumeOrchestration(deps3, orchestrationId) { } let activeInteractiveRun; if (state.activeInteractiveRunId !== void 0) { - const record32 = readRunRecord(deps3.workspace, state.activeInteractiveRunId); - const lock = readInteractiveLock(deps3.workspace); + const record32 = readRunRecord(deps4.workspace, state.activeInteractiveRunId); + const lock = readInteractiveLock(deps4.workspace); const lockHeld = lock.state === "held" && lock.lock.runId === state.activeInteractiveRunId; activeInteractiveRun = { runId: state.activeInteractiveRunId, @@ -62513,7 +62513,7 @@ function failureResult(category, message2, source, escalated) { }; } async function dispatchLocalExecution(input) { - const deps3 = { + const deps4 = { workspace: input.workspace, config: input.config, ...input.clock !== void 0 ? { clock: input.clock } : {}, @@ -62521,7 +62521,7 @@ async function dispatchLocalExecution(input) { ...input.signal !== void 0 ? { signal: input.signal } : {}, host: "local-executor" }; - const begin = await beginInteractiveTask(deps3, { + const begin = await beginInteractiveTask(deps4, { specName: input.specName, taskId: input.node.parentTaskId, allowDirty: input.allowDirty, @@ -62538,7 +62538,7 @@ async function dispatchLocalExecution(input) { input.onProgress?.(`local executor: run ${begin.runId} started for task ${begin.task.id}`); const abort = async (reason3) => { try { - await abortInteractiveTask(deps3, { runId: begin.runId, reason: reason3.slice(0, 500) }); + await abortInteractiveTask(deps4, { runId: begin.runId, reason: reason3.slice(0, 500) }); } catch { } }; @@ -62649,7 +62649,7 @@ Your previous response was invalid (${lastProblem.slice(0, 300)}). Return ONLY v ); } input.onProgress?.(`local executor: applied ${written.length} file(s); verifying`); - const completion = await completeInteractiveTask(deps3, { + const completion = await completeInteractiveTask(deps4, { runId: begin.runId, summary: `[local-executor] ${output.summary}`.slice(0, 2e3), reportedChangedFiles: written @@ -65085,6 +65085,11 @@ function readAggregationReport(workspace, jobId, nodeId, name) { (raw) => raw !== null && typeof raw === "object" ? raw : void 0 ); } +function listObjectiveNodes(workspace, jobId) { + const dir = import_path36.default.join(jobDir(workspace, jobId), "objectives"); + if (!(0, import_fs34.existsSync)(dir)) return []; + return (0, import_fs34.readdirSync)(dir, { withFileTypes: true }).filter((entry2) => entry2.isDirectory() && ID_PATTERN3.test(entry2.name)).map((entry2) => entry2.name).sort(); +} var EVALUATION_STATUSES = ["PASS", "FAIL", "INCONCLUSIVE"]; var EVALUATION_CHECK_LEVELS = [ "EXECUTION_INTEGRITY", @@ -66154,16 +66159,16 @@ function readLatestTaskCheckpoint(workspace, jobId, nodeId) { } return void 0; } -function now22(deps3) { - return (deps3.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); +function now22(deps4) { + return (deps4.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); } -function newId2(deps3) { - return (deps3.idFactory ?? import_crypto20.randomUUID)(); +function newId2(deps4) { + return (deps4.idFactory ?? import_crypto20.randomUUID)(); } -function beginTaskAttempt(deps3, input) { - const attemptNumber = nextAttemptNumber2(deps3.workspace, input.jobId, input.nodeId); +function beginTaskAttempt(deps4, input) { + const attemptNumber = nextAttemptNumber2(deps4.workspace, input.jobId, input.nodeId); if (input.resumedFromAttemptId !== void 0) { - const previous = readTaskAttempt(deps3.workspace, input.jobId, input.resumedFromAttemptId); + const previous = readTaskAttempt(deps4.workspace, input.jobId, input.resumedFromAttemptId); if (previous === void 0) { throw new OrchestrationError( "SBO049", @@ -66181,7 +66186,7 @@ function beginTaskAttempt(deps3, input) { schemaVersion: TASK_ATTEMPT_SCHEMA_VERSION, // The generated id is used in full: truncating it could alias two ids // from a deterministic factory, and append-only storage refuses aliases. - attemptId: `ta-${String(attemptNumber).padStart(4, "0")}-${newId2(deps3)}`.slice(0, 64), + attemptId: `ta-${String(attemptNumber).padStart(4, "0")}-${newId2(deps4)}`.slice(0, 64), jobId: input.jobId, nodeId: input.nodeId, taskId: input.taskId, @@ -66191,7 +66196,7 @@ function beginTaskAttempt(deps3, input) { model: input.model ?? null, status: "RUNNING", attemptNumber, - startedAt: now22(deps3), + startedAt: now22(deps4), checkpointIds: [], ...input.runId !== void 0 ? { runId: input.runId } : {}, ...input.providerSessionId !== void 0 ? { providerSessionId: input.providerSessionId } : {}, @@ -66239,10 +66244,10 @@ function beginTaskAttempt(deps3, input) { reconciledCostUsd: null } }; - return writeNewTaskAttempt(deps3.workspace, attempt); + return writeNewTaskAttempt(deps4.workspace, attempt); } -function requireOpenAttempt(deps3, jobId, attemptId) { - const attempt = readTaskAttempt(deps3.workspace, jobId, attemptId); +function requireOpenAttempt(deps4, jobId, attemptId) { + const attempt = readTaskAttempt(deps4.workspace, jobId, attemptId); if (attempt === void 0) { throw new OrchestrationError("SBO049", `Attempt ${attemptId} of job ${jobId} was not found.`); } @@ -66255,9 +66260,9 @@ function requireOpenAttempt(deps3, jobId, attemptId) { } return attempt; } -function completeTaskAttempt(deps3, input) { - const attempt = requireOpenAttempt(deps3, input.jobId, input.attemptId); - const completedAt = now22(deps3); +function completeTaskAttempt(deps4, input) { + const attempt = requireOpenAttempt(deps4, input.jobId, input.attemptId); + const completedAt = now22(deps4); const derivedDuration = Math.max(0, Date.parse(completedAt) - Date.parse(attempt.startedAt)); const finalized = { ...attempt, @@ -66272,24 +66277,24 @@ function completeTaskAttempt(deps3, input) { ...input.metrics ?? {} } }; - return updateTaskAttempt(deps3.workspace, finalized); + return updateTaskAttempt(deps4.workspace, finalized); } -function reconcileInterruptedAttempts(deps3, jobId, reason3 = "process-restart") { - const running = listTaskAttempts(deps3.workspace, jobId, { status: "RUNNING" }); +function reconcileInterruptedAttempts(deps4, jobId, reason3 = "process-restart") { + const running = listTaskAttempts(deps4.workspace, jobId, { status: "RUNNING" }); const reconciled = []; for (const attempt of running) { const interrupted = { ...attempt, status: "INTERRUPTED", - completedAt: now22(deps3), + completedAt: now22(deps4), interruptedReason: reason3 }; - reconciled.push(updateTaskAttempt(deps3.workspace, interrupted)); + reconciled.push(updateTaskAttempt(deps4.workspace, interrupted)); } return reconciled; } -function createTaskCheckpoint(deps3, input) { - const attempt = readTaskAttempt(deps3.workspace, input.jobId, input.attemptId); +function createTaskCheckpoint(deps4, input) { + const attempt = readTaskAttempt(deps4.workspace, input.jobId, input.attemptId); if (attempt === void 0) { throw new OrchestrationError( "SBO050", @@ -66302,8 +66307,8 @@ function createTaskCheckpoint(deps3, input) { `Attempt ${input.attemptId} belongs to node ${attempt.nodeId}, not ${input.nodeId}.` ); } - const previous = readLatestTaskCheckpoint(deps3.workspace, input.jobId, input.nodeId); - const seqs = listTaskCheckpointSeqs(deps3.workspace, input.jobId, input.nodeId); + const previous = readLatestTaskCheckpoint(deps4.workspace, input.jobId, input.nodeId); + const seqs = listTaskCheckpointSeqs(deps4.workspace, input.jobId, input.nodeId); const seq = (seqs[seqs.length - 1] ?? 0) + 1; const mergeTexts = (older, newer) => { const merged = [...older]; @@ -66347,14 +66352,14 @@ function createTaskCheckpoint(deps3, input) { nextActions: input.nextActions, relevantArtifacts: input.relevantArtifacts ?? [], relevantContextReferences: input.relevantContextReferences ?? [], - createdAt: now22(deps3) + createdAt: now22(deps4) }); - const stored = writeTaskCheckpoint(deps3.workspace, checkpoint).checkpoint; + const stored = writeTaskCheckpoint(deps4.workspace, checkpoint).checkpoint; const linked = { ...attempt, checkpointIds: [...attempt.checkpointIds, stored.checkpointId].slice(-50) }; - updateTaskAttempt(deps3.workspace, linked); + updateTaskAttempt(deps4.workspace, linked); return stored; } function readExecutionLedger(workspace, jobId, options = {}) { @@ -66474,8 +66479,8 @@ function summarizeExecutionLedger(entries) { if (!entry2.success) { reliability.failedAttempts += 1; reliability.failedAttemptMs = add2(reliability.failedAttemptMs, entry2.metrics.durationMs); - const tokens = entry2.metrics.inputTokens === null && entry2.metrics.outputTokens === null ? null : (entry2.metrics.inputTokens ?? 0) + (entry2.metrics.outputTokens ?? 0); - reliability.failedAttemptTokens = add2(reliability.failedAttemptTokens, tokens); + const tokens2 = entry2.metrics.inputTokens === null && entry2.metrics.outputTokens === null ? null : (entry2.metrics.inputTokens ?? 0) + (entry2.metrics.outputTokens ?? 0); + reliability.failedAttemptTokens = add2(reliability.failedAttemptTokens, tokens2); reliability.failedAttemptCostUsd = add2( reliability.failedAttemptCostUsd, entry2.metrics.reconciledCostUsd ?? entry2.metrics.costUsd @@ -68582,15 +68587,15 @@ ${bullets(checkpoint.nextActions)}` compacted: true }; } -function reconstructTaskContext(deps3, input) { - const job = requireJobState(deps3.workspace, input.jobId); +function reconstructTaskContext(deps4, input) { + const job = requireJobState(deps4.workspace, input.jobId); if (job.graphRevision < 1) { throw new OrchestrationError( "SBO051", `Job ${input.jobId} has no runtime graph yet; there is no task context to reconstruct.` ); } - const graph = requireGraphRevision(deps3.workspace, input.jobId, job.graphRevision); + const graph = requireGraphRevision(deps4.workspace, input.jobId, job.graphRevision); const node = graph.nodes.find((candidate) => candidate.nodeId === input.nodeId); if (node === void 0) { throw new OrchestrationError( @@ -68598,10 +68603,10 @@ function reconstructTaskContext(deps3, input) { `Node ${input.nodeId} does not exist in graph revision ${job.graphRevision} of job ${input.jobId}.` ); } - const checkpoint = readLatestTaskCheckpoint(deps3.workspace, input.jobId, input.nodeId); - const attempts = listTaskAttempts(deps3.workspace, input.jobId, { nodeId: input.nodeId }); - const createdAt = (deps3.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); - const budget = input.budget ?? contextBudgetFromPolicy(deps3.config.orchestration.jobs.context); + const checkpoint = readLatestTaskCheckpoint(deps4.workspace, input.jobId, input.nodeId); + const attempts = listTaskAttempts(deps4.workspace, input.jobId, { nodeId: input.nodeId }); + const createdAt = (deps4.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); + const budget = input.budget ?? contextBudgetFromPolicy(deps4.config.orchestration.jobs.context); const items = [ ...pinnedItems(job, node, checkpoint, createdAt), ...durableItems(checkpoint, createdAt), @@ -68644,28 +68649,28 @@ function reconstructTaskContext(deps3, input) { throw cause; } } -function nowIso(deps3) { - return (deps3.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); +function nowIso(deps4) { + return (deps4.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); } -function latestFailureText(deps3, jobId, nodeId, node) { +function latestFailureText(deps4, jobId, nodeId, node) { const parts = []; if (node.latestFailure !== void 0) { parts.push(`${node.latestFailure.category}: ${node.latestFailure.message}`); } - const assessment = listFailureAssessments(deps3.workspace, jobId, { nodeId }).at(-1); + const assessment = listFailureAssessments(deps4.workspace, jobId, { nodeId }).at(-1); if (assessment !== void 0) { parts.push(assessment.likelyCause); parts.push(...assessment.evidenceRefs); } return parts.join("\n"); } -function recoveryText(deps3, jobId, nodeId) { - const decision = listRecoveryDecisions(deps3.workspace, jobId, { nodeId }).at(-1); +function recoveryText(deps4, jobId, nodeId) { + const decision = listRecoveryDecisions(deps4.workspace, jobId, { nodeId }).at(-1); if (decision === void 0) return ""; return [decision.action, decision.reason, ...decision.remediation].join("\n"); } -function priorRelevantPaths(deps3, jobId, nodeId) { - const plans = listContextSelectionPlans(deps3.workspace, jobId, { nodeId }).slice(-3); +function priorRelevantPaths(deps4, jobId, nodeId) { + const plans = listContextSelectionPlans(deps4.workspace, jobId, { nodeId }).slice(-3); const paths = /* @__PURE__ */ new Set(); for (const plan of plans) { for (const entry2 of plan.selectedWorkingItems) paths.add(entry2.path); @@ -68673,15 +68678,15 @@ function priorRelevantPaths(deps3, jobId, nodeId) { } return [...paths]; } -async function buildTaskContextPackage(deps3, input) { - const job = requireJobState(deps3.workspace, input.jobId); +async function buildTaskContextPackage(deps4, input) { + const job = requireJobState(deps4.workspace, input.jobId); if (job.graphRevision < 1) { throw new OrchestrationError( "SBO051", `Job ${input.jobId} has no runtime graph yet; there is no task context to build.` ); } - const graph = requireGraphRevision(deps3.workspace, input.jobId, job.graphRevision); + const graph = requireGraphRevision(deps4.workspace, input.jobId, job.graphRevision); const node = graph.nodes.find((candidate) => candidate.nodeId === input.nodeId); if (node === void 0) { throw new OrchestrationError( @@ -68689,15 +68694,15 @@ async function buildTaskContextPackage(deps3, input) { `Node ${input.nodeId} does not exist in graph revision ${job.graphRevision} of job ${input.jobId}.` ); } - const contextPolicy = deps3.config.orchestration.jobs.context; + const contextPolicy = deps4.config.orchestration.jobs.context; const policy = contextPolicy.efficiency; const strategy = policy.strategy; - const createdAt = nowIso(deps3); + const createdAt = nowIso(deps4); const budget = input.budget ?? contextBudgetFromPolicy(contextPolicy); - const checkpoint = readLatestTaskCheckpoint(deps3.workspace, input.jobId, input.nodeId); - const attempts = listTaskAttempts(deps3.workspace, input.jobId, { nodeId: input.nodeId }); - const snapshot2 = input.gitSnapshot ?? await captureGitSnapshot(deps3.workspace.rootDir, { - clock: () => (deps3.clock ?? (() => /* @__PURE__ */ new Date()))() + const checkpoint = readLatestTaskCheckpoint(deps4.workspace, input.jobId, input.nodeId); + const attempts = listTaskAttempts(deps4.workspace, input.jobId, { nodeId: input.nodeId }); + const snapshot2 = input.gitSnapshot ?? await captureGitSnapshot(deps4.workspace.rootDir, { + clock: () => (deps4.clock ?? (() => /* @__PURE__ */ new Date()))() }); const nextActions = checkpoint?.nextActions ?? [`Start task ${node.parentTaskId}: ${node.title}`]; const currentActionText = input.currentAction ?? bullets(nextActions); @@ -68720,7 +68725,7 @@ async function buildTaskContextPackage(deps3, input) { freshness: "EPHEMERAL" } ]; - const stored = readContextExpansionState(deps3.workspace, input.jobId, input.nodeId) ?? initialExpansionState({ taskId: node.parentTaskId, nodeId: input.nodeId, now: createdAt }); + const stored = readContextExpansionState(deps4.workspace, input.jobId, input.nodeId) ?? initialExpansionState({ taskId: node.parentTaskId, nodeId: input.nodeId, now: createdAt }); const expansion = input.attemptId !== void 0 ? beginAttemptExpansion(stored, createdAt) : stored; if (strategy === "LEGACY") { const result2 = await buildEfficientContext({ @@ -68741,7 +68746,7 @@ async function buildTaskContextPackage(deps3, input) { checkpointId: checkpoint?.checkpointId, checkpointSummaryItem: checkpoint !== void 0 ? checkpointSummaryItem(checkpoint, createdAt) : void 0 }).catch(rethrowBudget); - return persistAndReturn(deps3, input, { + return persistAndReturn(deps4, input, { job, node, checkpoint, @@ -68753,8 +68758,8 @@ async function buildTaskContextPackage(deps3, input) { }); } const indexed = ensureRepositoryIndex({ - workspace: deps3.workspace, - config: deps3.config, + workspace: deps4.workspace, + config: deps4.config, now: createdAt, gitSnapshot: snapshot2, ...input.rebuildIndex === true ? { rebuild: true } : {} @@ -68768,12 +68773,12 @@ async function buildTaskContextPackage(deps3, input) { objective: checkpoint?.objective ?? node.title, acceptanceCriteria: checkpoint?.pinned.acceptanceCriteria ?? [], currentAction: currentActionText, - failureText: latestFailureText(deps3, input.jobId, input.nodeId, node), - recoveryText: recoveryText(deps3, input.jobId, input.nodeId), - failureFingerprint: readTaskReliabilityState(deps3.workspace, input.jobId, input.nodeId)?.observations.at(-1)?.failureFingerprint ?? void 0, + failureText: latestFailureText(deps4, input.jobId, input.nodeId, node), + recoveryText: recoveryText(deps4, input.jobId, input.nodeId), + failureFingerprint: readTaskReliabilityState(deps4.workspace, input.jobId, input.nodeId)?.observations.at(-1)?.failureFingerprint ?? void 0, changedPaths: snapshot2.entries.map((entry2) => entry2.path.replace(/\\/g, "/")), checkpointChangedPaths: (checkpoint?.changedFiles ?? []).map((file) => file.path), - priorRelevantPaths: priorRelevantPaths(deps3, input.jobId, input.nodeId), + priorRelevantPaths: priorRelevantPaths(deps4, input.jobId, input.nodeId), expansionLevel: expansion.level }); const allocationPolicy = contextAllocationPolicySchema.parse({ @@ -68805,7 +68810,7 @@ async function buildTaskContextPackage(deps3, input) { executionMode: input.executionMode ?? null, runner: input.runner ?? null, index: indexed.index, - rootDir: deps3.workspace.rootDir, + rootDir: deps4.workspace.rootDir, query, rankOptions: { maxCandidates: policy.maxCandidates }, sectionOptions: { @@ -68827,7 +68832,7 @@ async function buildTaskContextPackage(deps3, input) { checkpointSummaryItem: checkpoint !== void 0 ? checkpointSummaryItem(checkpoint, createdAt) : void 0, contextExpansionsSoFar: expansion.expansionsThisTask }).catch(rethrowBudget); - return persistAndReturn(deps3, input, { + return persistAndReturn(deps4, input, { job, node, checkpoint, @@ -68854,13 +68859,13 @@ function rethrowBudget(cause) { } throw cause; } -function persistAndReturn(deps3, input, data) { +function persistAndReturn(deps4, input, data) { const { result } = data; if (input.persist !== false && data.strategy !== "LEGACY") { - writeContextSelectionPlan(deps3.workspace, result.plan); + writeContextSelectionPlan(deps4.workspace, result.plan); if (input.attemptId !== void 0) { - writeContextMetrics(deps3.workspace, input.jobId, input.attemptId, result.metrics); - writeContextExpansionState(deps3.workspace, input.jobId, input.nodeId, { + writeContextMetrics(deps4.workspace, input.jobId, input.attemptId, result.metrics); + writeContextExpansionState(deps4.workspace, input.jobId, input.nodeId, { ...data.expansion, lastWorkingSetTokens: result.metrics.workingSetTokens, baselineWorkingSetTokens: data.expansion.baselineWorkingSetTokens ?? result.metrics.workingSetTokens @@ -70049,22 +70054,22 @@ function evaluateRuntimeResearchTrigger(input) { } return { eligible: false, depth: "QUICK", reason: "no evidence-backed external knowledge trigger is present", repeatedCount: matching.length, materiallyDistinctStrategies: strategies }; } -function now3(deps3) { - return (deps3.clock ?? (() => /* @__PURE__ */ new Date()))(); +function now3(deps4) { + return (deps4.clock ?? (() => /* @__PURE__ */ new Date()))(); } -function newId3(deps3, prefix) { - const raw = (deps3.idFactory ?? (() => `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`))(); +function newId3(deps4, prefix) { + const raw = (deps4.idFactory ?? (() => `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`))(); return `${prefix}-${raw}`.replace(/[^A-Za-z0-9._-]/g, "-").slice(0, 64); } -function emit(deps3, type, payload) { - deps3.recordEvent?.(type, payload); +function emit(deps4, type, payload) { + deps4.recordEvent?.(type, payload); } -function recordEvaluation(deps3, result) { - const stored = writeEvaluationResult(deps3.workspace, result, { - maxRecords: deps3.policy.maxRecordsPerJob +function recordEvaluation(deps4, result) { + const stored = writeEvaluationResult(deps4.workspace, result, { + maxRecords: deps4.policy.maxRecordsPerJob }); emit( - deps3, + deps4, stored.status === "PASS" ? "evaluation_passed" : stored.status === "FAIL" ? "evaluation_failed" : "evaluation_inconclusive", { nodeId: stored.nodeId, @@ -70079,7 +70084,7 @@ function recordEvaluation(deps3, result) { } ); if (stored.semanticReviewRan) { - emit(deps3, "semantic_review_completed", { + emit(deps4, "semantic_review_completed", { nodeId: stored.nodeId, taskId: stored.taskId, attemptId: stored.attemptId, @@ -70089,10 +70094,10 @@ function recordEvaluation(deps3, result) { } return stored; } -function governFailedAttempt(deps3, input) { - const at = now3(deps3).toISOString(); +function governFailedAttempt(deps4, input) { + const at = now3(deps4).toISOString(); const previous = requireTaskReliabilityState( - deps3.workspace, + deps4.workspace, input.jobId, input.nodeId, input.taskId, @@ -70101,11 +70106,11 @@ function governFailedAttempt(deps3, input) { const runawaySignals = detectRunaway( input.activity, { - maxToolCallsPerAttempt: deps3.policy.maxToolCallsPerAttempt, - maxCommandRunsPerAttempt: deps3.policy.maxCommandRunsPerAttempt, - maxAttemptWallTimeMs: deps3.policy.maxAttemptWallTimeMs, - maxContextUsageRatio: deps3.policy.maxContextUsageRatio, - maxTestLoopsPerAttempt: deps3.policy.maxTestLoopsPerAttempt + maxToolCallsPerAttempt: deps4.policy.maxToolCallsPerAttempt, + maxCommandRunsPerAttempt: deps4.policy.maxCommandRunsPerAttempt, + maxAttemptWallTimeMs: deps4.policy.maxAttemptWallTimeMs, + maxContextUsageRatio: deps4.policy.maxContextUsageRatio, + maxTestLoopsPerAttempt: deps4.policy.maxTestLoopsPerAttempt }, previous.observations ); @@ -70132,17 +70137,17 @@ function governFailedAttempt(deps3, input) { const healthAssessment = assessHealth({ window, thresholds: { - sameFailureThreshold: deps3.policy.sameFailureThreshold, + sameFailureThreshold: deps4.policy.sameFailureThreshold, // The same-diff bound is the EXISTING no-progress budget, read from // its owner rather than duplicated under a reliability-specific name. sameDiffThreshold: input.budgets.maxNoProgressCycles, - oscillationThreshold: deps3.policy.oscillationThreshold + oscillationThreshold: deps4.policy.oscillationThreshold }, runawaySignals, passed: false }); if (healthAssessment.health === "RUNAWAY") { - emit(deps3, "execution_runaway", { + emit(deps4, "execution_runaway", { nodeId: input.nodeId, taskId: input.taskId, attemptId: input.attemptId, @@ -70151,7 +70156,7 @@ function governFailedAttempt(deps3, input) { detail: healthAssessment.reasons[0]?.slice(0, 300) ?? "the attempt exceeded its bounds" }); } else if (healthAssessment.health === "OSCILLATING") { - emit(deps3, "execution_oscillating", { + emit(deps4, "execution_oscillating", { nodeId: input.nodeId, taskId: input.taskId, attemptId: input.attemptId, @@ -70159,7 +70164,7 @@ function governFailedAttempt(deps3, input) { failureFingerprint: input.classified.fingerprint }); } else if (healthAssessment.health === "STALLED") { - emit(deps3, "execution_stalled", { + emit(deps4, "execution_stalled", { nodeId: input.nodeId, taskId: input.taskId, attemptId: input.attemptId, @@ -70181,10 +70186,10 @@ function governFailedAttempt(deps3, input) { ...input.contextInsufficiencySignals !== void 0 ? { contextInsufficiencySignals: input.contextInsufficiencySignals } : {} }); const assessment = writeFailureAssessment( - deps3.workspace, + deps4.workspace, failureAssessmentSchema.parse({ schemaVersion: FAILURE_ASSESSMENT_SCHEMA_VERSION, - assessmentId: newId3(deps3, "fa"), + assessmentId: newId3(deps4, "fa"), jobId: input.jobId, nodeId: input.nodeId, taskId: input.taskId, @@ -70205,9 +70210,9 @@ function governFailedAttempt(deps3, input) { evidenceRefs: [...input.evidenceRefs ?? []].slice(0, 40), createdAt: at }), - { maxRecords: deps3.policy.maxRecordsPerJob } + { maxRecords: deps4.policy.maxRecordsPerJob } ); - emit(deps3, "failure_assessed", { + emit(deps4, "failure_assessed", { nodeId: input.nodeId, taskId: input.taskId, attemptId: input.attemptId, @@ -70234,7 +70239,7 @@ function governFailedAttempt(deps3, input) { ...input.evaluation !== void 0 ? { evaluation: input.evaluation } : {}, health: healthAssessment.health, budget, - policy: deps3.policy, + policy: deps4.policy, lane: input.lane ?? null, executionMode: input.executionMode ?? null, planRevision: input.planRevision, @@ -70260,7 +70265,7 @@ function governFailedAttempt(deps3, input) { observations: window }); if (researchEligibility.eligible) { - emit(deps3, "runtime_research_eligible", { + emit(deps4, "runtime_research_eligible", { nodeId: input.nodeId, taskId: input.taskId, attemptId: input.attemptId, @@ -70273,10 +70278,10 @@ function governFailedAttempt(deps3, input) { }); } const decision = writeRecoveryDecision( - deps3.workspace, + deps4.workspace, recoveryDecisionSchema.parse({ schemaVersion: RECOVERY_DECISION_SCHEMA_VERSION, - decisionId: newId3(deps3, "rd"), + decisionId: newId3(deps4, "rd"), jobId: input.jobId, nodeId: input.nodeId, taskId: input.taskId, @@ -70298,10 +70303,10 @@ function governFailedAttempt(deps3, input) { applied: false, createdAt: at }), - { maxRecords: deps3.policy.maxRecordsPerJob } + { maxRecords: deps4.policy.maxRecordsPerJob } ); - emitDecisionEvents(deps3, input, decision, plan); - const state = writeTaskReliabilityState(deps3.workspace, { + emitDecisionEvents(deps4, input, decision, plan); + const state = writeTaskReliabilityState(deps4.workspace, { ...previous, health: healthAssessment.health, observations: window, @@ -70326,10 +70331,10 @@ function governFailedAttempt(deps3, input) { ...researchEligibility.eligible ? { researchEligibility } : {} }; } -function recordSuccessfulAttempt(deps3, input) { - const at = now3(deps3).toISOString(); +function recordSuccessfulAttempt(deps4, input) { + const at = now3(deps4).toISOString(); const previous = requireTaskReliabilityState( - deps3.workspace, + deps4.workspace, input.jobId, input.nodeId, input.taskId, @@ -70356,7 +70361,7 @@ function recordSuccessfulAttempt(deps3, input) { updatedAt: at }; delete next.pendingDecisionId; - return writeTaskReliabilityState(deps3.workspace, next); + return writeTaskReliabilityState(deps4.workspace, next); } function verificationBroken(evaluation) { if (evaluation === void 0) return false; @@ -70377,7 +70382,7 @@ function rememberStrategy(previous, plan, observation2) { const next = [...previous.exhaustedStrategies, key]; return next.length > RELIABILITY_LIMITS.maxListItems ? next.slice(next.length - RELIABILITY_LIMITS.maxListItems) : next; } -function emitDecisionEvents(deps3, input, decision, plan) { +function emitDecisionEvents(deps4, input, decision, plan) { const base = { nodeId: input.nodeId, taskId: input.taskId, @@ -70388,7 +70393,7 @@ function emitDecisionEvents(deps3, input, decision, plan) { health: decision.health, strategyChange: decision.strategyChange }; - emit(deps3, "recovery_decided", { + emit(deps4, "recovery_decided", { ...base, reason: decision.reason.slice(0, 300), remainingAttempts: decision.budgetSnapshot.attemptsMax - decision.budgetSnapshot.attemptsUsed, @@ -70397,10 +70402,10 @@ function emitDecisionEvents(deps3, input, decision, plan) { }); switch (plan.action) { case "RESTART_FRESH_CONTEXT": - emit(deps3, "fresh_context_selected", base); + emit(deps4, "fresh_context_selected", base); break; case "RETRY_DIFFERENT_LOCAL_MODE": - emit(deps3, "local_mode_recovery_selected", { + emit(deps4, "local_mode_recovery_selected", { ...base, fromMode: input.executionMode ?? "unknown", toMode: plan.nextStrategy.executionMode ?? "unknown" @@ -70408,7 +70413,7 @@ function emitDecisionEvents(deps3, input, decision, plan) { break; case "ESCALATE_INTELLIGENCE": case "ESCALATE_LANE": - emit(deps3, "lane_escalation_requested", { + emit(deps4, "lane_escalation_requested", { ...base, requestedKind: plan.requestedCapability?.kind ?? "STRONG", // Said explicitly in the timeline because it is the invariant most @@ -70417,23 +70422,23 @@ function emitDecisionEvents(deps3, input, decision, plan) { }); break; case "WAIT_FOR_RESOURCE": - emit(deps3, "resource_wait_selected", { + emit(deps4, "resource_wait_selected", { ...base, waitMs: plan.waitMs ?? null }); break; case "FAIL_TASK": - emit(deps3, "recovery_budget_exhausted", { + emit(deps4, "recovery_budget_exhausted", { ...base, budgetSnapshot: decision.budgetSnapshot }); - emit(deps3, "task_blocked_after_recovery", { + emit(deps4, "task_blocked_after_recovery", { ...base, remediation: decision.remediation.slice(0, 5) }); break; case "BLOCK": - emit(deps3, "task_blocked_after_recovery", { + emit(deps4, "task_blocked_after_recovery", { ...base, remediation: decision.remediation.slice(0, 5) }); @@ -70442,17 +70447,17 @@ function emitDecisionEvents(deps3, input, decision, plan) { break; } } -function policyOf2(deps3) { - return deps3.config.orchestration.jobs; +function policyOf2(deps4) { + return deps4.config.orchestration.jobs; } -function now4(deps3) { - return (deps3.clock ?? systemClock)(); +function now4(deps4) { + return (deps4.clock ?? systemClock)(); } -function newId4(deps3) { - return (deps3.idFactory ?? import_crypto19.randomUUID)(); +function newId4(deps4) { + return (deps4.idFactory ?? import_crypto19.randomUUID)(); } -function assertJobsEnabled(deps3) { - if (policyOf2(deps3).enabled) return; +function assertJobsEnabled(deps4) { + if (policyOf2(deps4).enabled) return; throw new OrchestrationError( "SBO025", "Job orchestration is disabled by `orchestration.jobs.enabled` in .specbridge/config.json.", @@ -70468,8 +70473,8 @@ function planTextOf(plan) { ).filter((description) => description.length > 0); return [goal, ...descriptions].join("\n").slice(0, 4e3); } -function record22(deps3, job, type, payload = {}) { - const stored = countJobEvents(deps3.workspace, job.jobId); +function record22(deps4, job, type, payload = {}) { + const stored = countJobEvents(deps4.workspace, job.jobId); if (stored >= job.budgets.maxEvents) { throw new OrchestrationError( "SBO020", @@ -70481,16 +70486,16 @@ function record22(deps3, job, type, payload = {}) { ); } appendJobEvent( - deps3.workspace, + deps4.workspace, job.jobId, - { at: now4(deps3).toISOString(), type, ...payload }, - { maxEventBytes: deps3.config.orchestration.history.maxEventBytes } + { at: now4(deps4).toISOString(), type, ...payload }, + { maxEventBytes: deps4.config.orchestration.history.maxEventBytes } ); return { ...job, counters: { ...job.counters, events: stored + 1 } }; } -function transition22(deps3, job, to) { +function transition22(deps4, job, to) { assertJobTransition(job.status, to); - const at = now4(deps3).toISOString(); + const at = now4(deps4).toISOString(); const wasWaiting = requiresHumanAttention(job.status); const willWait = requiresHumanAttention(to); if (!wasWaiting && willWait) { @@ -70498,7 +70503,7 @@ function transition22(deps3, job, to) { } if (wasWaiting && !willWait) { const since = job.humanWaitSince === void 0 ? void 0 : Date.parse(job.humanWaitSince); - const banked = since === void 0 || Number.isNaN(since) ? 0 : Math.max(0, now4(deps3).getTime() - since); + const banked = since === void 0 || Number.isNaN(since) ? 0 : Math.max(0, now4(deps4).getTime() - since); const { humanWaitSince: _stopped, ...rest } = job; return { ...rest, @@ -70512,19 +70517,19 @@ function transition22(deps3, job, to) { } return { ...job, status: to, updatedAt: at }; } -function persist22(deps3, job) { - return writeJobState(deps3.workspace, { ...job, updatedAt: now4(deps3).toISOString() }); +function persist22(deps4, job) { + return writeJobState(deps4.workspace, { ...job, updatedAt: now4(deps4).toISOString() }); } -function persistGraph(deps3, job, graph) { - const existing = readGraphRevision(deps3.workspace, job.jobId, graph.revision); +function persistGraph(deps4, job, graph) { + const existing = readGraphRevision(deps4.workspace, job.jobId, graph.revision); if (existing === void 0) { - return storeGraphRevision(deps3.workspace, job.jobId, graph).graph; + return storeGraphRevision(deps4.workspace, job.jobId, graph).graph; } const validated = jobGraphSchema.parse(graph); const file = assertInsideWorkspace( - deps3.workspace.rootDir, + deps4.workspace.rootDir, import_path35.default.join( - jobDir(deps3.workspace, job.jobId), + jobDir(deps4.workspace, job.jobId), "graphs", `${String(validated.revision).padStart(4, "0")}.json` ) @@ -70534,26 +70539,26 @@ function persistGraph(deps3, job, graph) { `); return validated; } -function createJob(deps3, request) { - assertJobsEnabled(deps3); - const policy = policyOf2(deps3); +function createJob(deps4, request) { + assertJobsEnabled(deps4); + const policy = policyOf2(deps4); const goal = request.goal.trim(); if (goal.length === 0) { throw new OrchestrationError("SBO006", "A job needs a stated goal.", { remediation: ["Describe what should be accomplished, in one or two sentences."] }); } - const createdAt = now4(deps3).toISOString(); + const createdAt = now4(deps4).toISOString(); const job = { schemaVersion: JOB_STATE_SCHEMA_VERSION, - jobId: `job-${newId4(deps3)}`, + jobId: `job-${newId4(deps4)}`, specName: request.specName, status: "CREATED", goal: goal.slice(0, 4e3), createdAt, updatedAt: createdAt, - host: deps3.host ?? "cli", - policyFingerprint: jobPolicyFingerprint(deps3.config.orchestration), + host: deps4.host ?? "cli", + policyFingerprint: jobPolicyFingerprint(deps4.config.orchestration), budgets: { maxAgentRuns: policy.budgets.maxAgentRuns, maxTaskAttempts: policy.budgets.maxTaskAttempts, @@ -70586,24 +70591,24 @@ function createJob(deps3, request) { decisions: [], escalations: [] }; - initializeJobRecord(deps3.workspace, job); - const recorded = record22(deps3, job, "job_created", { specName: job.specName }); - return persist22(deps3, recorded); + initializeJobRecord(deps4.workspace, job); + const recorded = record22(deps4, job, "job_created", { specName: job.specName }); + return persist22(deps4, recorded); } -async function buildJobGraph(deps3, jobId) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); +async function buildJobGraph(deps4, jobId) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); if (job.status !== "CREATED") { throw new OrchestrationError("SBO027", `The graph is built exactly once, from CREATED (job is ${job.status}).`); } - const snapshot2 = await captureGitSnapshot(deps3.workspace.rootDir, { clock: () => now4(deps3) }); - const built = buildInitialGraph(deps3.workspace, { + const snapshot2 = await captureGitSnapshot(deps4.workspace.rootDir, { clock: () => now4(deps4) }); + const built = buildInitialGraph(deps4.workspace, { jobId, specName: job.specName, - createdAt: now4(deps3).toISOString(), + createdAt: now4(deps4).toISOString(), gitHead: snapshot2.head }); - const policy = policyOf2(deps3); + const policy = policyOf2(deps4); const graph = { ...built.graph, nodes: built.graph.nodes.map((node) => { @@ -70617,16 +70622,16 @@ async function buildJobGraph(deps3, jobId) { }; }) }; - storeGraphRevision(deps3.workspace, jobId, graph); + storeGraphRevision(deps4.workspace, jobId, graph); job = { ...job, graphRevision: graph.revision, currentNodeId: graph.nodes[0]?.nodeId }; - job = transition22(deps3, job, "PLANNING"); - job = record22(deps3, job, "graph_created", { + job = transition22(deps4, job, "PLANNING"); + job = record22(deps4, job, "graph_created", { revision: graph.revision, nodes: graph.nodes.length, ...built.skippedCompleted.length > 0 ? { skippedCompleted: built.skippedCompleted.length } : {} }); - job = transition22(deps3, job, "READY"); - return { job: persist22(deps3, job), graph }; + job = transition22(deps4, job, "READY"); + return { job: persist22(deps4, job), graph }; } function complexityInputFor(node) { return { @@ -70638,18 +70643,18 @@ function complexityInputFor(node) { previousReplanCount: node.replans }; } -function activeGraph(deps3, job) { +function activeGraph(deps4, job) { if (job.graphRevision === 0) return void 0; - return requireGraphRevision(deps3.workspace, job.jobId, job.graphRevision); + return requireGraphRevision(deps4.workspace, job.jobId, job.graphRevision); } -function appendAttempt(deps3, job, graph, context, outcome, extras = {}) { +function appendAttempt(deps4, job, graph, context, outcome, extras = {}) { const node = requireNode(graph, context.nodeId); const attempt = { attempt: node.attempts.length + 1, role: context.role, workerId: context.workerId, startedAt: context.startedAt, - finishedAt: now4(deps3).toISOString(), + finishedAt: now4(deps4).toISOString(), outcome, ...context.agentResultRef !== void 0 ? { agentResultRef: context.agentResultRef } : {}, ...context.runId !== void 0 ? { runId: context.runId } : {}, @@ -70671,8 +70676,8 @@ function appendAttempt(deps3, job, graph, context, outcome, extras = {}) { }; return { job: nextJob, graph: nextGraph }; } -function recordEscalation(deps3, job, input) { - const at = now4(deps3).toISOString(); +function recordEscalation(deps4, job, input) { + const at = now4(deps4).toISOString(); const entry2 = { at, ...input.nodeId !== void 0 ? { nodeId: input.nodeId } : {}, @@ -70685,32 +70690,32 @@ function recordEscalation(deps3, job, input) { escalations: [...job.escalations, entry2].slice(-100), counters: { ...job.counters, escalations: job.counters.escalations + 1 } }; - next = record22(deps3, next, "worker_escalated", { + next = record22(deps4, next, "worker_escalated", { ...input.nodeId !== void 0 ? { nodeId: input.nodeId } : {}, role: input.role, reason: input.reason }); return next; } -function beginPlanning(deps3, jobId, nodeId) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); +function beginPlanning(deps4, jobId, nodeId) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); if (job.status === "PLANNING") return job; - job = transition22(deps3, job, "PLANNING"); + job = transition22(deps4, job, "PLANNING"); job = { ...job, currentNodeId: nodeId }; - job = record22(deps3, job, "planning_started", { nodeId }); - return persist22(deps3, job); -} -function recordRoleFailure(deps3, jobId, input) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); - let graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); - ({ job, graph } = appendAttempt(deps3, job, graph, input.context, input.outcome, { + job = record22(deps4, job, "planning_started", { nodeId }); + return persist22(deps4, job); +} +function recordRoleFailure(deps4, jobId, input) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); + let graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); + ({ job, graph } = appendAttempt(deps4, job, graph, input.context, input.outcome, { ...input.failureCategory !== void 0 ? { failureCategory: input.failureCategory } : {}, ...input.escalation !== void 0 ? { escalationReason: input.escalation.reason } : {} })); if (input.escalation !== void 0) { - job = recordEscalation(deps3, job, { + job = recordEscalation(deps4, job, { nodeId: input.context.nodeId, role: input.context.role, reason: input.escalation.reason, @@ -70718,38 +70723,38 @@ function recordRoleFailure(deps3, jobId, input) { }); } if (job.status === "PLANNING") { - job = transition22(deps3, job, "READY"); + job = transition22(deps4, job, "READY"); } - persistGraph(deps3, job, graph); - return persist22(deps3, job); + persistGraph(deps4, job, graph); + return persist22(deps4, job); } -function recordClassification(deps3, jobId, result) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); - let graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); +function recordClassification(deps4, jobId, result) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); + let graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); const node = requireNode(graph, result.context.nodeId); const deterministic = node.complexity ?? "LOW"; const effective = mergeComplexity(deterministic, result.proposedClass); - ({ job, graph } = appendAttempt(deps3, job, graph, result.context, "succeeded")); + ({ job, graph } = appendAttempt(deps4, job, graph, result.context, "succeeded")); graph = withNode(graph, { ...requireNode(graph, node.nodeId), complexity: effective, complexitySignals: effective !== deterministic ? [...node.complexitySignals, `classifier-raised(${deterministic}->${effective})`] : node.complexitySignals }); - job = record22(deps3, job, "classification_completed", { + job = record22(deps4, job, "classification_completed", { nodeId: node.nodeId, deterministic, proposed: result.proposedClass, effective }); - persistGraph(deps3, job, graph); - return { job: persist22(deps3, job), effectiveClass: effective }; + persistGraph(deps4, job, graph); + return { job: persist22(deps4, job), effectiveClass: effective }; } -async function recordPlan(deps3, jobId, result, options = {}) { - assertJobsEnabled(deps3); - const policy = policyOf2(deps3); - let job = requireJobState(deps3.workspace, jobId); - let graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); +async function recordPlan(deps4, jobId, result, options = {}) { + assertJobsEnabled(deps4); + const policy = policyOf2(deps4); + let job = requireJobState(deps4.workspace, jobId); + let graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); const node = requireNode(graph, result.context.nodeId); if (options.replan === true) { if (node.replans >= job.budgets.maxReplansPerTask) { @@ -70767,11 +70772,11 @@ async function recordPlan(deps3, jobId, result, options = {}) { ); } } - const gitHead = options.gitHead ?? (await captureGitSnapshot(deps3.workspace.rootDir, { clock: () => now4(deps3) })).head; - const binding = capturePlanBinding(deps3.workspace, { + const gitHead = options.gitHead ?? (await captureGitSnapshot(deps4.workspace.rootDir, { clock: () => now4(deps4) })).head; + const binding = capturePlanBinding(deps4.workspace, { specName: job.specName, taskId: node.parentTaskId, - policy: deps3.config.orchestration, + policy: deps4.config.orchestration, gitHead }); const revision = node.planRevision + 1; @@ -70781,15 +70786,15 @@ async function recordPlan(deps3, jobId, result, options = {}) { binding, revision, planId: `${node.nodeId}-p${revision}`, - createdAt: now4(deps3).toISOString(), - policy: deps3.config.orchestration + createdAt: now4(deps4).toISOString(), + policy: deps4.config.orchestration }); - storeNodePlan(deps3.workspace, jobId, node.nodeId, revision, plan); - ({ job, graph } = appendAttempt(deps3, job, graph, result.context, "succeeded")); + storeNodePlan(deps4.workspace, jobId, node.nodeId, revision, plan); + ({ job, graph } = appendAttempt(deps4, job, graph, result.context, "succeeded")); const criticApplies = policy.routing.critic !== "disabled" && result.producedByTier === "LOCAL_SMALL"; const complexity = requireNode(graph, node.nodeId).complexity ?? "LOW"; const policyRequiresReview = policy.planReview === "always" || policy.planReview === "high-risk" && complexity === "HIGH"; - const review = resolvePlanReviewRequirement(deps3.authorityResolver, { + const review = resolvePlanReviewRequirement(deps4.authorityResolver, { jobId, nodeId: node.nodeId, policyRequiresReview, @@ -70817,9 +70822,9 @@ ${result.candidate.steps.map((step2) => step2.description).join("\n")}` graph = withNode(graph, withoutVerdict); if (options.replan === true) { job = { ...job, counters: { ...job.counters, jobReplans: job.counters.jobReplans + 1 } }; - job = record22(deps3, job, "replan_started", { nodeId: node.nodeId, revision }); + job = record22(deps4, job, "replan_started", { nodeId: node.nodeId, revision }); } - job = record22(deps3, job, "plan_created", { + job = record22(deps4, job, "plan_created", { nodeId: node.nodeId, revision, producedByTier: result.producedByTier, @@ -70827,21 +70832,21 @@ ${result.candidate.steps.map((step2) => step2.description).join("\n")}` humanReview }); if (job.status === "PLANNING" || job.status === "REPLANNING") { - job = transition22(deps3, job, "READY"); + job = transition22(deps4, job, "READY"); } - persistGraph(deps3, job, graph); - return { job: persist22(deps3, job), plan }; + persistGraph(deps4, job, graph); + return { job: persist22(deps4, job), plan }; } -function recordCriticVerdict(deps3, jobId, result) { - assertJobsEnabled(deps3); - const policy = policyOf2(deps3); - let job = requireJobState(deps3.workspace, jobId); - let graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); +function recordCriticVerdict(deps4, jobId, result) { + assertJobsEnabled(deps4); + const policy = policyOf2(deps4); + let job = requireJobState(deps4.workspace, jobId); + let graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); const node = requireNode(graph, result.context.nodeId); - ({ job, graph } = appendAttempt(deps3, job, graph, result.context, "succeeded")); - const activePlan = readNodePlan(deps3.workspace, jobId, node.nodeId, node.planRevision); + ({ job, graph } = appendAttempt(deps4, job, graph, result.context, "succeeded")); + const activePlan = readNodePlan(deps4.workspace, jobId, node.nodeId, node.planRevision); const policyRequiresReview = policy.planReview === "always" || policy.planReview === "high-risk" && (node.complexity ?? "LOW") === "HIGH"; - const humanReview = resolvePlanReviewRequirement(deps3.authorityResolver, { + const humanReview = resolvePlanReviewRequirement(deps4.authorityResolver, { jobId, nodeId: node.nodeId, policyRequiresReview, @@ -70856,66 +70861,66 @@ function recordCriticVerdict(deps3, jobId, result) { planApproved: accepted && !humanReview, humanReviewRequired: accepted ? humanReview : false }); - job = record22(deps3, job, "critic_completed", { + job = record22(deps4, job, "critic_completed", { nodeId: node.nodeId, planRevision: node.planRevision, verdict: result.verdict, reasons: result.reasons.slice(0, 10).map((reason3) => reason3.slice(0, 200)) }); if (result.verdict === "REVISE" || result.verdict === "ESCALATE") { - job = transition22(deps3, job, "PLANNING"); + job = transition22(deps4, job, "PLANNING"); } - persistGraph(deps3, job, graph); + persistGraph(deps4, job, graph); return { - job: persist22(deps3, job), + job: persist22(deps4, job), verdict: result.verdict, humanReviewRequired: accepted ? humanReview : false }; } -function noteEscalation(deps3, jobId, input) { - let job = requireJobState(deps3.workspace, jobId); +function noteEscalation(deps4, jobId, input) { + let job = requireJobState(deps4.workspace, jobId); const already = job.escalations.some( (entry2) => entry2.nodeId === input.nodeId && entry2.reason === input.reason ); if (already) return job; - job = recordEscalation(deps3, job, input); - return persist22(deps3, job); + job = recordEscalation(deps4, job, input); + return persist22(deps4, job); } -function completeJobIfDone(deps3, jobId) { - let job = requireJobState(deps3.workspace, jobId); +function completeJobIfDone(deps4, jobId) { + let job = requireJobState(deps4.workspace, jobId); if (isFinalJobStatus(job.status)) return job; - const graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); + const graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); if (!allNodesComplete(graph)) { throw new OrchestrationError("SBO027", "The job cannot complete: unfinished nodes remain."); } - const closure = assessCompletion(deps3.completionGate, jobId); + const closure = assessCompletion(deps4.completionGate, jobId); if (closure !== void 0 && !closure.mayComplete) { if (job.status === "QUALIFYING") { return job; } - job = transition22(deps3, job, "QUALIFYING"); - job = record22(deps3, job, "closure_audit_completed", { + job = transition22(deps4, job, "QUALIFYING"); + job = record22(deps4, job, "closure_audit_completed", { directive: "CONTRACT_CLOSURE_AUDIT", unclosed: closure.unclosed, reason: closure.reason.slice(0, 500) }); - return persist22(deps3, { ...job, closurePhase: "CONTRACT_CLOSURE_AUDIT" }); + return persist22(deps4, { ...job, closurePhase: "CONTRACT_CLOSURE_AUDIT" }); } - const at = now4(deps3).toISOString(); - job = transition22(deps3, job, "COMPLETED"); - job = record22(deps3, job, "job_completed", { + const at = now4(deps4).toISOString(); + job = transition22(deps4, job, "COMPLETED"); + job = record22(deps4, job, "job_completed", { reconciled: true, ...closure !== void 0 ? { closure: closure.reason.slice(0, 300) } : {} }); - return persist22(deps3, { ...job, finalizedAt: at, finalOutcome: "COMPLETED" }); + return persist22(deps4, { ...job, finalizedAt: at, finalOutcome: "COMPLETED" }); } -function recordJobEvent(deps3, jobId, type, payload = {}) { - let job = requireJobState(deps3.workspace, jobId); - job = record22(deps3, job, type, payload); - return persist22(deps3, job); +function recordJobEvent(deps4, jobId, type, payload = {}) { + let job = requireJobState(deps4.workspace, jobId); + job = record22(deps4, job, type, payload); + return persist22(deps4, job); } -function applyJobTransition(deps3, jobId, input) { - let job = requireJobState(deps3.workspace, jobId); +function applyJobTransition(deps4, jobId, input) { + let job = requireJobState(deps4.workspace, jobId); if (isFinalJobStatus(job.status)) { throw new OrchestrationError( "SBO026", @@ -70923,14 +70928,14 @@ function applyJobTransition(deps3, jobId, input) { { details: { from: job.status, to: input.to } } ); } - if (job.status !== input.to) job = transition22(deps3, job, input.to); - job = record22(deps3, job, input.event, input.payload ?? {}); - return persist22(deps3, { ...job, ...input.patch ?? {} }); + if (job.status !== input.to) job = transition22(deps4, job, input.to); + job = record22(deps4, job, input.event, input.payload ?? {}); + return persist22(deps4, { ...job, ...input.patch ?? {} }); } -function reviewNodePlan(deps3, jobId, input) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); - let graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); +function reviewNodePlan(deps4, jobId, input) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); + let graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); const node = requireNode(graph, input.nodeId); if (!node.humanReviewRequired) { throw new OrchestrationError("SBO012", `Node ${input.nodeId} has no pending human plan review.`); @@ -70940,7 +70945,7 @@ function reviewNodePlan(deps3, jobId, input) { planApproved: input.decision === "approved", humanReviewRequired: input.decision === "approved" ? false : true }); - job = record22(deps3, job, "plan_reviewed", { + job = record22(deps4, job, "plan_reviewed", { nodeId: node.nodeId, planRevision: node.planRevision, decision: input.decision, @@ -70948,22 +70953,22 @@ function reviewNodePlan(deps3, jobId, input) { }); if (input.decision === "rejected") { graph = withNode(graph, { ...requireNode(graph, node.nodeId), humanReviewRequired: false }); - if (job.status === "READY") job = transition22(deps3, job, "PLANNING"); + if (job.status === "READY") job = transition22(deps4, job, "PLANNING"); } - persistGraph(deps3, job, graph); - return persist22(deps3, job); + persistGraph(deps4, job, graph); + return persist22(deps4, job); } -function beginExecutorDispatch(deps3, jobId, input) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); - let graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); +function beginExecutorDispatch(deps4, jobId, input) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); + let graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); const node = requireNode(graph, input.nodeId); graph = transitionNode(graph, node.nodeId, input.mode === "repair" ? "REPAIRING" : "RUNNING"); - job = transition22(deps3, job, input.mode === "repair" ? "REPAIRING" : "RUNNING"); - const priorAttempts = listTaskAttempts(deps3.workspace, jobId, { nodeId: node.nodeId }); + job = transition22(deps4, job, input.mode === "repair" ? "REPAIRING" : "RUNNING"); + const priorAttempts = listTaskAttempts(deps4.workspace, jobId, { nodeId: node.nodeId }); const lineageParent = [...priorAttempts].reverse().find((prior) => isFinalAttemptStatus(prior.status)); const attempt = beginTaskAttempt( - { workspace: deps3.workspace, clock: deps3.clock, idFactory: deps3.idFactory }, + { workspace: deps4.workspace, clock: deps4.clock, idFactory: deps4.idFactory }, { jobId, nodeId: node.nodeId, @@ -71001,13 +71006,13 @@ function beginExecutorDispatch(deps3, jobId, input) { } ); job = { ...job, currentNodeId: node.nodeId, currentAttemptId: attempt.attemptId }; - job = record22(deps3, job, input.mode === "repair" ? "repair_started" : "execution_started", { + job = record22(deps4, job, input.mode === "repair" ? "repair_started" : "execution_started", { nodeId: node.nodeId, taskId: node.parentTaskId, workerId: input.workerId, ...input.mode === "repair" ? { cycle: node.repairCycles + 1 } : {} }); - job = record22(deps3, job, "attempt_started", { + job = record22(deps4, job, "attempt_started", { nodeId: node.nodeId, taskId: node.parentTaskId, attemptId: attempt.attemptId, @@ -71015,13 +71020,13 @@ function beginExecutorDispatch(deps3, jobId, input) { provider: attempt.provider, ...attempt.resumedFromAttemptId !== void 0 ? { resumedFromAttemptId: attempt.resumedFromAttemptId } : {} }); - persistGraph(deps3, job, graph); - return persist22(deps3, job); + persistGraph(deps4, job, graph); + return persist22(deps4, job); } -function yieldExecutorForResourceWait(deps3, jobId, input) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); - let graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); +function yieldExecutorForResourceWait(deps4, jobId, input) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); + let graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); const node = requireNode(graph, input.nodeId); if (node.status !== "RUNNING" && node.status !== "REPAIRING") { throw new OrchestrationError( @@ -71030,10 +71035,10 @@ function yieldExecutorForResourceWait(deps3, jobId, input) { ); } if (job.currentAttemptId !== void 0) { - const attempt = readTaskAttempt(deps3.workspace, jobId, job.currentAttemptId); + const attempt = readTaskAttempt(deps4.workspace, jobId, job.currentAttemptId); if (attempt !== void 0 && !isFinalAttemptStatus(attempt.status)) { completeTaskAttempt( - { workspace: deps3.workspace, clock: deps3.clock, idFactory: deps3.idFactory }, + { workspace: deps4.workspace, clock: deps4.clock, idFactory: deps4.idFactory }, { jobId, attemptId: attempt.attemptId, @@ -71042,7 +71047,7 @@ function yieldExecutorForResourceWait(deps3, jobId, input) { } ); } - job = record22(deps3, job, "attempt_completed", { + job = record22(deps4, job, "attempt_completed", { nodeId: node.nodeId, taskId: node.parentTaskId, attemptId: job.currentAttemptId, @@ -71052,16 +71057,16 @@ function yieldExecutorForResourceWait(deps3, jobId, input) { }); } graph = transitionNode(graph, node.nodeId, "READY"); - job = transition22(deps3, job, "READY"); + job = transition22(deps4, job, "READY"); job = { ...job, currentAttemptId: void 0, currentNodeId: node.nodeId }; - persistGraph(deps3, job, graph); - return persist22(deps3, job); + persistGraph(deps4, job, graph); + return persist22(deps4, job); } -function buildAttemptEvaluation(deps3, job, node, outcome, attemptId, lane, at) { +function buildAttemptEvaluation(deps4, job, node, outcome, attemptId, lane, at) { const input = outcome.reliability; const status = outcome.evidenceStatus; const verified = status === "verified" || status === "manually-accepted"; @@ -71112,7 +71117,7 @@ function buildAttemptEvaluation(deps3, job, node, outcome, attemptId, lane, at) }; const criteria = input?.acceptanceCriteria !== void 0 && input.criteriaEvidence !== void 0 ? evaluateAcceptanceCriteria(input.acceptanceCriteria, input.criteriaEvidence) : { checks: [], failedCriteria: [], uncheckedCriteria: [] }; return evaluateAttempt({ - evaluationId: `ev-${newId4(deps3)}`.slice(0, 64), + evaluationId: `ev-${newId4(deps4)}`.slice(0, 64), jobId: job.jobId, nodeId: node.nodeId, taskId: node.parentTaskId, @@ -71156,37 +71161,37 @@ function attemptActivity(outcome, startedAt, at) { function numeric(value) { return typeof value === "number" && Number.isFinite(value) ? value : null; } -function reliabilityDepsFor(deps3, jobId) { +function reliabilityDepsFor(deps4, jobId) { return { - workspace: deps3.workspace, - policy: policyOf2(deps3).reliability, - ...deps3.clock !== void 0 ? { clock: deps3.clock } : {}, - ...deps3.idFactory !== void 0 ? { idFactory: deps3.idFactory } : {}, + workspace: deps4.workspace, + policy: policyOf2(deps4).reliability, + ...deps4.clock !== void 0 ? { clock: deps4.clock } : {}, + ...deps4.idFactory !== void 0 ? { idFactory: deps4.idFactory } : {}, recordEvent: (type, payload) => { try { - recordJobEvent(deps3, jobId, type, payload); + recordJobEvent(deps4, jobId, type, payload); } catch { } } }; } -function pendingRecoveryDecision(deps3, jobId, nodeId) { - if (!policyOf2(deps3).reliability.enabled) return void 0; - const state = readTaskReliabilityState(deps3.workspace, jobId, nodeId); +function pendingRecoveryDecision(deps4, jobId, nodeId) { + if (!policyOf2(deps4).reliability.enabled) return void 0; + const state = readTaskReliabilityState(deps4.workspace, jobId, nodeId); const decisionId = state?.pendingDecisionId; if (decisionId === void 0) return void 0; - const decision = readRecoveryDecision(deps3.workspace, jobId, decisionId); + const decision = readRecoveryDecision(deps4.workspace, jobId, decisionId); return decision !== void 0 && !decision.applied ? decision : void 0; } -function applyRecoveryDecision(deps3, input) { +function applyRecoveryDecision(deps4, input) { const { decision, node, at } = input; let job = input.job; const graph = input.graph; - const retryDelayMs = policyOf2(deps3).retryDelayMs; + const retryDelayMs = policyOf2(deps4).retryDelayMs; const finish5 = (next, nextAction) => { - persistGraph(deps3, next, graph); + persistGraph(deps4, next, graph); return { - job: persist22(deps3, next), + job: persist22(deps4, next), nextAction, classified: input.classified, evaluation: input.evaluation, @@ -71199,13 +71204,13 @@ function applyRecoveryDecision(deps3, input) { baseBackoffMs: Math.max(retryDelayMs, 1), maxBackoffMs: Math.max(retryDelayMs * 16, retryDelayMs) }); - job = transition22(deps3, job, "WAITING_RETRY"); + job = transition22(deps4, job, "WAITING_RETRY"); job = { ...job, - retryAt: new Date(now4(deps3).getTime() + backoffMs).toISOString(), + retryAt: new Date(now4(deps4).getTime() + backoffMs).toISOString(), counters: { ...job.counters, transientRetries: job.counters.transientRetries + 1 } }; - job = record22(deps3, job, "waiting_retry", { + job = record22(deps4, job, "waiting_retry", { nodeId: node.nodeId, category: input.classified.category, retryAt: job.retryAt, @@ -71217,9 +71222,9 @@ function applyRecoveryDecision(deps3, input) { const elapsed = Math.max(0, Date.parse(at) - Date.parse(job.createdAt)); const remaining = Math.max(0, job.budgets.maxWallClockMs - elapsed); const waitMs = Math.min(Math.max(retryDelayMs, 6e4), Math.max(remaining, retryDelayMs)); - job = transition22(deps3, job, "WAITING_RETRY"); - job = { ...job, retryAt: new Date(now4(deps3).getTime() + waitMs).toISOString() }; - job = record22(deps3, job, "waiting_retry", { + job = transition22(deps4, job, "WAITING_RETRY"); + job = { ...job, retryAt: new Date(now4(deps4).getTime() + waitMs).toISOString() }; + job = record22(deps4, job, "waiting_retry", { nodeId: node.nodeId, retryAt: job.retryAt, reasonCode: decision.reasonCode, @@ -71228,17 +71233,17 @@ function applyRecoveryDecision(deps3, input) { return finish5(job, "wait-retry"); } case "REPAIR": { - job = transition22(deps3, job, "DIAGNOSING"); + job = transition22(deps4, job, "DIAGNOSING"); return finish5(job, "diagnose"); } case "REPLAN": { - job = transition22(deps3, job, "DIAGNOSING"); + job = transition22(deps4, job, "DIAGNOSING"); return finish5(job, "diagnose"); } case "RESTART_FRESH_CONTEXT": { - job = transition22(deps3, job, "READY"); + job = transition22(deps4, job, "READY"); job = { ...job, currentNodeId: node.nodeId }; - job = record22(deps3, job, "context_threshold_reached", { + job = record22(deps4, job, "context_threshold_reached", { nodeId: node.nodeId, taskId: node.parentTaskId, decisionId: decision.decisionId, @@ -71247,9 +71252,9 @@ function applyRecoveryDecision(deps3, input) { return finish5(job, "retry-strategy-change"); } case "EXPAND_CONTEXT": { - job = transition22(deps3, job, "READY"); + job = transition22(deps4, job, "READY"); job = { ...job, currentNodeId: node.nodeId }; - job = record22(deps3, job, "context_threshold_reached", { + job = record22(deps4, job, "context_threshold_reached", { nodeId: node.nodeId, taskId: node.parentTaskId, decisionId: decision.decisionId, @@ -71259,9 +71264,9 @@ function applyRecoveryDecision(deps3, input) { return finish5(job, "retry-strategy-change"); } case "RETRY_DIFFERENT_LOCAL_MODE": { - job = transition22(deps3, job, "READY"); + job = transition22(deps4, job, "READY"); job = { ...job, currentNodeId: node.nodeId }; - job = recordEscalation(deps3, job, { + job = recordEscalation(deps4, job, { nodeId: node.nodeId, role: "EXECUTOR", reason: "LOCAL_DIRECT_TO_HARNESS", @@ -71271,9 +71276,9 @@ function applyRecoveryDecision(deps3, input) { } case "ESCALATE_INTELLIGENCE": case "ESCALATE_LANE": { - job = transition22(deps3, job, "READY"); + job = transition22(deps4, job, "READY"); job = { ...job, currentNodeId: node.nodeId }; - job = recordEscalation(deps3, job, { + job = recordEscalation(deps4, job, { nodeId: node.nodeId, role: "EXECUTOR", reason: decision.health === "STALLED" || decision.health === "OSCILLATING" ? "NO_PROGRESS" : "LOCAL_EXECUTION_ESCALATED", @@ -71282,9 +71287,9 @@ function applyRecoveryDecision(deps3, input) { return finish5(job, "retry-strategy-change"); } case "REQUEST_HUMAN_DECISION": { - job = transition22(deps3, job, "NEEDS_CLARIFICATION"); + job = transition22(deps4, job, "NEEDS_CLARIFICATION"); const question = { - id: `q-${newId4(deps3)}`.slice(0, 64), + id: `q-${newId4(deps4)}`.slice(0, 64), question: `Task ${node.parentTaskId} cannot proceed automatically: ${decision.reason.slice(0, 600)} Decide explicitly, then resume the job.`, whyItMatters: `${decision.reasonCode} has no safe automatic response.`, options: [], @@ -71292,7 +71297,7 @@ function applyRecoveryDecision(deps3, input) { askedAt: at, round: Math.min( job.counters.clarificationRounds + 1, - deps3.config.orchestration.clarification.maxRounds + deps4.config.orchestration.clarification.maxRounds ) }; job = { @@ -71300,7 +71305,7 @@ function applyRecoveryDecision(deps3, input) { openQuestions: [...job.openQuestions, question], counters: { ...job.counters, clarificationRounds: question.round } }; - job = record22(deps3, job, "clarification_requested", { + job = record22(deps4, job, "clarification_requested", { nodeId: node.nodeId, category: input.classified.category, reasonCode: decision.reasonCode @@ -71318,10 +71323,10 @@ function applyRecoveryDecision(deps3, input) { } } } -function finalizeDispatchAttempt(deps3, job, node, outcome, status) { - const survivalDeps = { workspace: deps3.workspace, clock: deps3.clock, idFactory: deps3.idFactory }; +function finalizeDispatchAttempt(deps4, job, node, outcome, status) { + const survivalDeps = { workspace: deps4.workspace, clock: deps4.clock, idFactory: deps4.idFactory }; let attemptId = job.currentAttemptId; - if (attemptId === void 0 || readTaskAttempt(deps3.workspace, job.jobId, attemptId) === void 0) { + if (attemptId === void 0 || readTaskAttempt(deps4.workspace, job.jobId, attemptId) === void 0) { attemptId = beginTaskAttempt(survivalDeps, { jobId: job.jobId, nodeId: node.nodeId, @@ -71332,7 +71337,7 @@ function finalizeDispatchAttempt(deps3, job, node, outcome, status) { runId: outcome.context.runId }).attemptId; } - const existing = readTaskAttempt(deps3.workspace, job.jobId, attemptId); + const existing = readTaskAttempt(deps4.workspace, job.jobId, attemptId); if (existing !== void 0 && isFinalAttemptStatus(existing.status)) { return attemptId; } @@ -71360,37 +71365,37 @@ function finalizeDispatchAttempt(deps3, job, node, outcome, status) { }); return attemptId; } -function completeExecutorDispatch(deps3, jobId, outcome) { - assertJobsEnabled(deps3); - const policy = policyOf2(deps3); - let job = requireJobState(deps3.workspace, jobId); - let graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); +function completeExecutorDispatch(deps4, jobId, outcome) { + assertJobsEnabled(deps4); + const policy = policyOf2(deps4); + let job = requireJobState(deps4.workspace, jobId); + let graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); const node = requireNode(graph, outcome.context.nodeId); - const at = now4(deps3).toISOString(); + const at = now4(deps4).toISOString(); const verified = outcome.evidenceStatus === "verified" || outcome.evidenceStatus === "manually-accepted"; const attemptStatus = outcome.failure === void 0 && verified ? "COMPLETED" : outcome.failure?.category === "CANCELLED" ? "CANCELLED" : "FAILED"; - const attemptId = finalizeDispatchAttempt(deps3, job, node, outcome, attemptStatus); + const attemptId = finalizeDispatchAttempt(deps4, job, node, outcome, attemptStatus); job = { ...job, currentAttemptId: void 0 }; - job = record22(deps3, job, "attempt_completed", { + job = record22(deps4, job, "attempt_completed", { nodeId: node.nodeId, taskId: node.parentTaskId, attemptId, status: attemptStatus }); - const lane = readTaskAttempt(deps3.workspace, jobId, attemptId)?.lane ?? null; - const evaluation = buildAttemptEvaluation(deps3, job, node, outcome, attemptId, lane, at); - recordEvaluation(reliabilityDepsFor(deps3, jobId), evaluation); + const lane = readTaskAttempt(deps4.workspace, jobId, attemptId)?.lane ?? null; + const evaluation = buildAttemptEvaluation(deps4, job, node, outcome, attemptId, lane, at); + recordEvaluation(reliabilityDepsFor(deps4, jobId), evaluation); recordCalibrationForAttempt({ - workspace: deps3.workspace, + workspace: deps4.workspace, policy: policy.scheduler.adaptive, jobId, nodeId: node.nodeId, attemptId, - now: now4(deps3) + now: now4(deps4) }); const evaluationBlocksCompletion = policy.reliability.enabled && evaluation.status !== "PASS"; if (evaluationBlocksCompletion && outcome.failure === void 0 && verified) { - job = record22(deps3, job, "evaluation_failed", { + job = record22(deps4, job, "evaluation_failed", { nodeId: node.nodeId, taskId: node.parentTaskId, attemptId, @@ -71401,7 +71406,7 @@ function completeExecutorDispatch(deps3, jobId, outcome) { }); } if (outcome.failure === void 0 && verified && !evaluationBlocksCompletion) { - recordSuccessfulAttempt(reliabilityDepsFor(deps3, jobId), { + recordSuccessfulAttempt(reliabilityDepsFor(deps4, jobId), { jobId, nodeId: node.nodeId, taskId: node.parentTaskId, @@ -71410,7 +71415,7 @@ function completeExecutorDispatch(deps3, jobId, outcome) { lane, evaluationStatus: evaluation.status }); - ({ job, graph } = appendAttempt(deps3, job, graph, outcome.context, "succeeded")); + ({ job, graph } = appendAttempt(deps4, job, graph, outcome.context, "succeeded")); graph = transitionNode(graph, node.nodeId, "COMPLETED"); graph = withNode(graph, { ...requireNode(graph, node.nodeId), @@ -71431,14 +71436,14 @@ function completeExecutorDispatch(deps3, jobId, outcome) { at } }; - job = record22(deps3, job, "node_completed", { + job = record22(deps4, job, "node_completed", { nodeId: node.nodeId, taskId: node.parentTaskId, evidenceStatus: outcome.evidenceStatus, ...outcome.context.runId !== void 0 ? { runId: outcome.context.runId } : {} }); const milestone = createTaskCheckpoint( - { workspace: deps3.workspace, clock: deps3.clock, idFactory: deps3.idFactory }, + { workspace: deps4.workspace, clock: deps4.clock, idFactory: deps4.idFactory }, { jobId, nodeId: node.nodeId, @@ -71465,42 +71470,42 @@ function completeExecutorDispatch(deps3, jobId, outcome) { relevantArtifacts: outcome.context.runId !== void 0 ? [outcome.context.runId] : [] } ); - job = record22(deps3, job, "task_checkpoint_created", { + job = record22(deps4, job, "task_checkpoint_created", { nodeId: node.nodeId, taskId: node.parentTaskId, checkpointId: milestone.checkpointId, reason: "milestone" }); if (allNodesComplete(graph)) { - const closure = assessCompletion(deps3.completionGate, jobId); + const closure = assessCompletion(deps4.completionGate, jobId); if (closure !== void 0 && !closure.mayComplete) { - job = record22(deps3, job, "closure_audit_completed", { + job = record22(deps4, job, "closure_audit_completed", { directive: "CONTRACT_CLOSURE_AUDIT", unclosed: closure.unclosed, reason: closure.reason.slice(0, 300) }); - job = transition22(deps3, job, "READY"); - persistGraph(deps3, job, graph); + job = transition22(deps4, job, "READY"); + persistGraph(deps4, job, graph); return { - job: persist22(deps3, { ...job, closurePhase: "CONTRACT_CLOSURE_AUDIT" }), + job: persist22(deps4, { ...job, closurePhase: "CONTRACT_CLOSURE_AUDIT" }), nextAction: "node-complete", evaluation }; } - job = transition22(deps3, job, "COMPLETED"); - job = record22(deps3, job, "job_completed", {}); + job = transition22(deps4, job, "COMPLETED"); + job = record22(deps4, job, "job_completed", {}); job = { ...job, finalizedAt: at, finalOutcome: "COMPLETED" }; - persistGraph(deps3, job, graph); - return { job: persist22(deps3, job), nextAction: "job-complete", evaluation }; + persistGraph(deps4, job, graph); + return { job: persist22(deps4, job), nextAction: "job-complete", evaluation }; } - job = transition22(deps3, job, "READY"); + job = transition22(deps4, job, "READY"); const next = graph.nodes.find((candidate) => candidate.status === "READY"); job = { ...job, currentNodeId: next?.nodeId }; if (next !== void 0) { - job = record22(deps3, job, "node_ready", { nodeId: next.nodeId, taskId: next.parentTaskId }); + job = record22(deps4, job, "node_ready", { nodeId: next.nodeId, taskId: next.parentTaskId }); } - persistGraph(deps3, job, graph); - return { job: persist22(deps3, job), nextAction: "node-complete", evaluation }; + persistGraph(deps4, job, graph); + return { job: persist22(deps4, job), nextAction: "node-complete", evaluation }; } const failureInput = outcome.failure ?? (evaluationBlocksCompletion && verified ? { // The verifiers passed; evaluation did not. Saying so precisely @@ -71532,7 +71537,7 @@ function completeExecutorDispatch(deps3, jobId, outcome) { consecutiveNoProgress: node.consecutiveNoProgress, maxNoProgressCycles: job.budgets.maxNoProgressCycles }); - ({ job, graph } = appendAttempt(deps3, job, graph, outcome.context, "failed", { + ({ job, graph } = appendAttempt(deps4, job, graph, outcome.context, "failed", { failureCategory: classified2.category, failureFingerprint: classified2.fingerprint })); @@ -71549,13 +71554,13 @@ function completeExecutorDispatch(deps3, jobId, outcome) { ...outcome.mode === "repair" ? { repairCycles: requireNode(graph, node.nodeId).repairCycles + 1 } : {} }); if (classified2.category === "VERIFICATION_FAILURE") { - job = record22(deps3, job, "verification_failed", { + job = record22(deps4, job, "verification_failed", { nodeId: node.nodeId, fingerprint: classified2.fingerprint, source: failureInput.source }); } - job = record22(deps3, job, "execution_finished", { + job = record22(deps4, job, "execution_finished", { nodeId: node.nodeId, outcome: "failed", category: classified2.category, @@ -71564,22 +71569,22 @@ function completeExecutorDispatch(deps3, jobId, outcome) { }); graph = transitionNode(graph, node.nodeId, "READY"); const blockWith = (category, code2, message2, remediation) => { - let blocked2 = transition22(deps3, job, "BLOCKED"); - blocked2 = record22(deps3, blocked2, category === "BUDGET_EXHAUSTED" ? "budget_exhausted" : "job_blocked", { + let blocked2 = transition22(deps4, job, "BLOCKED"); + blocked2 = record22(deps4, blocked2, category === "BUDGET_EXHAUSTED" ? "budget_exhausted" : "job_blocked", { nodeId: node.nodeId, category, reason: message2.slice(0, 500) }); blocked2 = { ...blocked2, blocker: { category, code: code2, message: message2, remediation, at } }; - persistGraph(deps3, blocked2, graph); - return { job: persist22(deps3, blocked2), nextAction: "blocked", classified: classified2 }; + persistGraph(deps4, blocked2, graph); + return { job: persist22(deps4, blocked2), nextAction: "blocked", classified: classified2 }; }; if (classified2.category === "CANCELLED") { - let cancelled = transition22(deps3, job, "CANCELLED"); - cancelled = record22(deps3, cancelled, "job_cancelled", { nodeId: node.nodeId }); + let cancelled = transition22(deps4, job, "CANCELLED"); + cancelled = record22(deps4, cancelled, "job_cancelled", { nodeId: node.nodeId }); cancelled = { ...cancelled, finalizedAt: at, finalOutcome: "CANCELLED" }; - persistGraph(deps3, cancelled, graph); - return { job: persist22(deps3, cancelled), nextAction: "blocked", classified: classified2 }; + persistGraph(deps4, cancelled, graph); + return { job: persist22(deps4, cancelled), nextAction: "blocked", classified: classified2 }; } if (classified2.policy.terminal) { return blockWith( @@ -71602,25 +71607,25 @@ function completeExecutorDispatch(deps3, jobId, outcome) { baseBackoffMs: Math.max(policy.retryDelayMs, 1), maxBackoffMs: Math.max(policy.retryDelayMs * 16, policy.retryDelayMs) }); - let waiting = transition22(deps3, job, "WAITING_RETRY"); + let waiting = transition22(deps4, job, "WAITING_RETRY"); waiting = { ...waiting, - retryAt: new Date(now4(deps3).getTime() + backoffMs).toISOString(), + retryAt: new Date(now4(deps4).getTime() + backoffMs).toISOString(), counters: { ...waiting.counters, transientRetries: waiting.counters.transientRetries + 1 } }; - waiting = record22(deps3, waiting, "waiting_retry", { + waiting = record22(deps4, waiting, "waiting_retry", { nodeId: node.nodeId, category: classified2.category, retryAt: waiting.retryAt }); - persistGraph(deps3, waiting, graph); - return { job: persist22(deps3, waiting), nextAction: "wait-retry", classified: classified2 }; + persistGraph(deps4, waiting, graph); + return { job: persist22(deps4, waiting), nextAction: "wait-retry", classified: classified2 }; } if (classified2.policy.clarifiable && !classified2.policy.repairable) { - let clarify = transition22(deps3, job, "NEEDS_CLARIFICATION"); + let clarify = transition22(deps4, job, "NEEDS_CLARIFICATION"); const awaitingCcrIds = [...classified2.message.matchAll(CCR_ID_PATTERN)].map((hit) => hit[0]); const question = { - id: `q-${newId4(deps3)}`.slice(0, 64), + id: `q-${newId4(deps4)}`.slice(0, 64), question: `Task ${node.parentTaskId} cannot proceed: ${classified2.message.slice(0, 600)} Resolve the prerequisite (or decide otherwise), then resume the job.`, whyItMatters: `${classified2.category} has no safe automatic response.`, options: [], @@ -71628,7 +71633,7 @@ function completeExecutorDispatch(deps3, jobId, outcome) { askedAt: at, round: Math.min( clarify.counters.clarificationRounds + 1, - deps3.config.orchestration.clarification.maxRounds + deps4.config.orchestration.clarification.maxRounds ), ...awaitingCcrIds.length > 0 ? { awaitingCcrIds } : {} }; @@ -71637,15 +71642,15 @@ function completeExecutorDispatch(deps3, jobId, outcome) { openQuestions: [...clarify.openQuestions, question], counters: { ...clarify.counters, clarificationRounds: question.round } }; - clarify = record22(deps3, clarify, "clarification_requested", { + clarify = record22(deps4, clarify, "clarification_requested", { nodeId: node.nodeId, category: classified2.category }); - persistGraph(deps3, clarify, graph); - return { job: persist22(deps3, clarify), nextAction: "clarify", classified: classified2 }; + persistGraph(deps4, clarify, graph); + return { job: persist22(deps4, clarify), nextAction: "clarify", classified: classified2 }; } if (policy.reliability.enabled) { - const contextMiss = assessDispatchContextMiss(deps3, { + const contextMiss = assessDispatchContextMiss(deps4, { jobId, nodeId: node.nodeId, attemptId, @@ -71653,7 +71658,7 @@ function completeExecutorDispatch(deps3, jobId, outcome) { ...outcome.reliability?.workerReportedText !== void 0 ? { workerReportedText: outcome.reliability.workerReportedText } : {}, ...outcome.reliability?.directModelRequestedRepository === true ? { directModelRequestedRepository: true } : {} }); - const governed = governFailedAttempt(reliabilityDepsFor(deps3, jobId), { + const governed = governFailedAttempt(reliabilityDepsFor(deps4, jobId), { jobId, nodeId: node.nodeId, taskId: node.parentTaskId, @@ -71662,7 +71667,7 @@ function completeExecutorDispatch(deps3, jobId, outcome) { classified: classified2, evaluation, lane, - executionMode: readTaskAttempt(deps3.workspace, jobId, attemptId)?.executionMode ?? null, + executionMode: readTaskAttempt(deps4.workspace, jobId, attemptId)?.executionMode ?? null, planRevision: node.planRevision, diffFingerprint: observation2.diffFingerprint ?? null, ...outcome.reliability?.harnessFailureKind !== void 0 ? { harnessFailureKind: outcome.reliability.harnessFailureKind } : {}, @@ -71686,7 +71691,7 @@ function completeExecutorDispatch(deps3, jobId, outcome) { ...outcome.context.runId !== void 0 ? { evidenceRefs: [outcome.context.runId] } : {} }); if (contextMiss.signals.length > 0) { - recordJobEvent(deps3, jobId, "context_insufficient", { + recordJobEvent(deps4, jobId, "context_insufficient", { nodeId: node.nodeId, taskId: node.parentTaskId, attemptId, @@ -71697,7 +71702,7 @@ function completeExecutorDispatch(deps3, jobId, outcome) { }); } if (governed.decision.action === "EXPAND_CONTEXT") { - applyContextExpansion(deps3, { + applyContextExpansion(deps4, { jobId, nodeId: node.nodeId, taskId: node.parentTaskId, @@ -71705,13 +71710,13 @@ function completeExecutorDispatch(deps3, jobId, outcome) { at }); } else if (contextMiss.offer.exhausted) { - recordJobEvent(deps3, jobId, "context_expansion_exhausted", { + recordJobEvent(deps4, jobId, "context_expansion_exhausted", { nodeId: node.nodeId, taskId: node.parentTaskId, reason: contextMiss.offer.reason.slice(0, 500) }); } - return applyRecoveryDecision(deps3, { + return applyRecoveryDecision(deps4, { job, graph, node: requireNode(graph, node.nodeId), @@ -71741,9 +71746,9 @@ function completeExecutorDispatch(deps3, jobId, outcome) { ["The implementation changes and all failure evidence are preserved."] ); } - const diagnosing = transition22(deps3, job, "DIAGNOSING"); - persistGraph(deps3, diagnosing, graph); - return { job: persist22(deps3, diagnosing), nextAction: "diagnose", classified: classified2 }; + const diagnosing = transition22(deps4, job, "DIAGNOSING"); + persistGraph(deps4, diagnosing, graph); + return { job: persist22(deps4, diagnosing), nextAction: "diagnose", classified: classified2 }; } return blockWith( classified2.category, @@ -71752,16 +71757,16 @@ function completeExecutorDispatch(deps3, jobId, outcome) { classified2.policy.remediation ); } -function applyDiagnosis(deps3, jobId, result) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); - let graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); +function applyDiagnosis(deps4, jobId, result) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); + let graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); const node = requireNode(graph, result.context.nodeId); - const at = now4(deps3).toISOString(); + const at = now4(deps4).toISOString(); if (job.status !== "DIAGNOSING") { throw new OrchestrationError("SBO027", `A diagnosis applies only while DIAGNOSING (job is ${job.status}).`); } - ({ job, graph } = appendAttempt(deps3, job, graph, result.context, "succeeded")); + ({ job, graph } = appendAttempt(deps4, job, graph, result.context, "succeeded")); graph = withNode(graph, { ...requireNode(graph, node.nodeId), latestDiagnosis: { @@ -71772,18 +71777,18 @@ function applyDiagnosis(deps3, jobId, result) { ...result.context.agentResultRef !== void 0 ? { agentResultRef: result.context.agentResultRef } : {} } }); - job = record22(deps3, job, "diagnosis_completed", { + job = record22(deps4, job, "diagnosis_completed", { nodeId: node.nodeId, category: result.category, planValidity: result.planValidity, recommendedAction: result.recommendedAction }); - const pending = pendingRecoveryDecision(deps3, jobId, node.nodeId); + const pending = pendingRecoveryDecision(deps4, jobId, node.nodeId); if (pending !== void 0) { const replanBudgetForCaution = requireNode(graph, node.nodeId).replans < job.budgets.maxReplansPerTask && job.counters.jobReplans < job.budgets.maxJobReplans; const narrowsToReplan = pending.action === "REPAIR" && replanBudgetForCaution && (result.planValidity === "INVALID" || result.recommendedAction === "REPLAN"); const effective = narrowsToReplan ? "REPLAN" : pending.action; - job = record22(deps3, job, "recovery_decided", { + job = record22(deps4, job, "recovery_decided", { nodeId: node.nodeId, decisionId: pending.decisionId, action: effective, @@ -71794,16 +71799,16 @@ function applyDiagnosis(deps3, jobId, result) { narrowedByDiagnosis: narrowsToReplan, applied: true }); - markRecoveryDecisionApplied(deps3.workspace, jobId, pending.decisionId); + markRecoveryDecisionApplied(deps4.workspace, jobId, pending.decisionId); if (effective === "REPLAN") { - job = transition22(deps3, job, "REPLANNING"); - persistGraph(deps3, job, graph); - return { job: persist22(deps3, job), applied: "replan" }; + job = transition22(deps4, job, "REPLANNING"); + persistGraph(deps4, job, graph); + return { job: persist22(deps4, job), applied: "replan" }; } if (effective === "REPAIR") { - job = transition22(deps3, job, "READY"); - persistGraph(deps3, job, graph); - return { job: persist22(deps3, job), applied: "repair" }; + job = transition22(deps4, job, "READY"); + persistGraph(deps4, job, graph); + return { job: persist22(deps4, job), applied: "repair" }; } } const policyOfFailure = classifyFailure({ @@ -71814,37 +71819,37 @@ function applyDiagnosis(deps3, jobId, result) { const repairBudgetLeft = requireNode(graph, node.nodeId).repairCycles < job.budgets.maxRepairCyclesPerTask; const replanBudgetLeft = requireNode(graph, node.nodeId).replans < job.budgets.maxReplansPerTask && job.counters.jobReplans < job.budgets.maxJobReplans; if (result.recommendedAction === "REPAIR" && policyOfFailure.repairable && result.planValidity === "VALID" && repairBudgetLeft) { - job = transition22(deps3, job, "READY"); - persistGraph(deps3, job, graph); - return { job: persist22(deps3, job), applied: "repair" }; + job = transition22(deps4, job, "READY"); + persistGraph(deps4, job, graph); + return { job: persist22(deps4, job), applied: "repair" }; } const wantsReplan = result.recommendedAction === "REPLAN" || result.planValidity === "INVALID" || result.recommendedAction === "REPAIR" && (!repairBudgetLeft || !policyOfFailure.repairable); if (wantsReplan && policyOfFailure.replannable !== false && replanBudgetLeft) { - job = transition22(deps3, job, "REPLANNING"); - persistGraph(deps3, job, graph); - return { job: persist22(deps3, job), applied: "replan" }; + job = transition22(deps4, job, "REPLANNING"); + persistGraph(deps4, job, graph); + return { job: persist22(deps4, job), applied: "replan" }; } if (result.recommendedAction === "RETRY" && policyOfFailure.retryable) { if (job.counters.transientRetries < job.budgets.maxTransientRetries) { - const delay = policyOf2(deps3).retryDelayMs; - job = transition22(deps3, job, "WAITING_RETRY"); + const delay = policyOf2(deps4).retryDelayMs; + job = transition22(deps4, job, "WAITING_RETRY"); job = { ...job, - retryAt: new Date(now4(deps3).getTime() + delay).toISOString(), + retryAt: new Date(now4(deps4).getTime() + delay).toISOString(), counters: { ...job.counters, transientRetries: job.counters.transientRetries + 1 } }; - job = record22(deps3, job, "waiting_retry", { nodeId: node.nodeId, retryAt: job.retryAt }); - persistGraph(deps3, job, graph); - return { job: persist22(deps3, job), applied: "wait-retry" }; + job = record22(deps4, job, "waiting_retry", { nodeId: node.nodeId, retryAt: job.retryAt }); + persistGraph(deps4, job, graph); + return { job: persist22(deps4, job), applied: "wait-retry" }; } } if (result.recommendedAction === "CLARIFY" || policyOfFailure.clarifiable) { - job = transition22(deps3, job, "NEEDS_CLARIFICATION"); - job = record22(deps3, job, "clarification_requested", { nodeId: node.nodeId }); - persistGraph(deps3, job, graph); - return { job: persist22(deps3, job), applied: "clarify" }; + job = transition22(deps4, job, "NEEDS_CLARIFICATION"); + job = record22(deps4, job, "clarification_requested", { nodeId: node.nodeId }); + persistGraph(deps4, job, graph); + return { job: persist22(deps4, job), applied: "clarify" }; } - job = transition22(deps3, job, "BLOCKED"); + job = transition22(deps4, job, "BLOCKED"); job = { ...job, blocker: { @@ -71855,14 +71860,14 @@ function applyDiagnosis(deps3, jobId, result) { at } }; - job = record22(deps3, job, "job_blocked", { nodeId: node.nodeId, category: result.category }); - persistGraph(deps3, job, graph); - return { job: persist22(deps3, job), applied: "blocked" }; + job = record22(deps4, job, "job_blocked", { nodeId: node.nodeId, category: result.category }); + persistGraph(deps4, job, graph); + return { job: persist22(deps4, job), applied: "blocked" }; } -function supersedeNode(deps3, jobId, input) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); - const graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); +function supersedeNode(deps4, jobId, input) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); + const graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); const node = requireNode(graph, input.nodeId); if (node.replans >= job.budgets.maxReplansPerTask || job.counters.jobReplans >= job.budgets.maxJobReplans) { throw new OrchestrationError("SBO013", "No replan budget remains; the node cannot be superseded.", { @@ -71872,42 +71877,42 @@ function supersedeNode(deps3, jobId, input) { const revised = reviseGraphSuperseding(graph, { supersedeNodeId: input.nodeId, replanReason: input.reason, - createdAt: now4(deps3).toISOString() + createdAt: now4(deps4).toISOString() }); - storeGraphRevision(deps3.workspace, jobId, revised); + storeGraphRevision(deps4.workspace, jobId, revised); job = { ...job, graphRevision: revised.revision, currentNodeId: node.supersededBy, counters: { ...job.counters, jobReplans: job.counters.jobReplans + 1 } }; - job = record22(deps3, job, "graph_revised", { + job = record22(deps4, job, "graph_revised", { revision: revised.revision, supersedes: graph.revision, supersededNode: input.nodeId, reason: input.reason.slice(0, 500) }); - job = record22(deps3, job, "node_superseded", { nodeId: input.nodeId }); - if (job.status === "REPLANNING") job = transition22(deps3, job, "READY"); - return { job: persist22(deps3, job), graph: revised }; + job = record22(deps4, job, "node_superseded", { nodeId: input.nodeId }); + if (job.status === "REPLANNING") job = transition22(deps4, job, "READY"); + return { job: persist22(deps4, job), graph: revised }; } -function askClarification(deps3, jobId, questions) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); +function askClarification(deps4, jobId, questions) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); if (isFinalJobStatus(job.status)) { throw new OrchestrationError("SBO026", `Job is ${job.status}; no questions can be asked.`); } - const maxRounds = deps3.config.orchestration.clarification.maxRounds; + const maxRounds = deps4.config.orchestration.clarification.maxRounds; if (job.counters.clarificationRounds >= maxRounds) { throw new OrchestrationError("SBO008", `All ${maxRounds} clarification rounds are used.`, { failureCategory: "BUDGET_EXHAUSTED" }); } - const at = now4(deps3).toISOString(); + const at = now4(deps4).toISOString(); const round2 = job.counters.clarificationRounds + 1; - const added = questions.slice(0, deps3.config.orchestration.clarification.maxQuestionsPerRound).map( + const added = questions.slice(0, deps4.config.orchestration.clarification.maxQuestionsPerRound).map( (candidate) => ({ - id: `q-${newId4(deps3)}`.slice(0, 64), + id: `q-${newId4(deps4)}`.slice(0, 64), question: candidate.question.slice(0, 1e3), whyItMatters: candidate.whyItMatters.slice(0, 1e3), options: [], @@ -71921,16 +71926,16 @@ function askClarification(deps3, jobId, questions) { openQuestions: [...job.openQuestions, ...added], counters: { ...job.counters, clarificationRounds: round2 } }; - if (job.status !== "NEEDS_CLARIFICATION") job = transition22(deps3, job, "NEEDS_CLARIFICATION"); - job = record22(deps3, job, "clarification_requested", { + if (job.status !== "NEEDS_CLARIFICATION") job = transition22(deps4, job, "NEEDS_CLARIFICATION"); + job = record22(deps4, job, "clarification_requested", { round: round2, questionIds: added.map((question) => question.id) }); - return persist22(deps3, job); + return persist22(deps4, job); } var CCR_ID_PATTERN = /\bCCR-\d{3,}\b/g; -function reconcileDecidedCcrs(deps3, jobId, decided2) { - let job = requireJobState(deps3.workspace, jobId); +function reconcileDecidedCcrs(deps4, jobId, decided2) { + let job = requireJobState(deps4.workspace, jobId); if (job.status !== "NEEDS_CLARIFICATION") return { job, closed: [] }; const answered = job.openQuestions.filter((question) => { const waiting = question.awaitingCcrIds ?? [...question.question.matchAll(CCR_ID_PATTERN)].map((h2) => h2[0]); @@ -71939,22 +71944,22 @@ function reconcileDecidedCcrs(deps3, jobId, decided2) { if (answered.length === 0) return { job, closed: [] }; const closed = answered.map((question) => question.id); const remaining = job.openQuestions.filter((question) => !closed.includes(question.id)); - job = persist22(deps3, { ...job, openQuestions: remaining }); - job = record22(deps3, job, "clarification_resolved", { + job = persist22(deps4, { ...job, openQuestions: remaining }); + job = record22(deps4, job, "clarification_resolved", { questionIds: closed, by: "ccr-decision" }); - if (remaining.length === 0) job = transition22(deps3, job, "READY"); - return { job: persist22(deps3, job), closed }; + if (remaining.length === 0) job = transition22(deps4, job, "READY"); + return { job: persist22(deps4, job), closed }; } var UNIT_ID_PATTERN = /\bwu-[A-Za-z0-9][\w-]*\b/g; -function reviveUnitsNamedBy(deps3, job, question, answer) { +function reviveUnitsNamedBy(deps4, job, question, answer) { const named = [...question.matchAll(UNIT_ID_PATTERN)].map((hit) => hit[0]); if (named.length === 0) return; - const graph = job.graphRevision > 0 ? readGraphRevision(deps3.workspace, job.jobId, job.graphRevision) : void 0; + const graph = job.graphRevision > 0 ? readGraphRevision(deps4.workspace, job.jobId, job.graphRevision) : void 0; if (graph === void 0) return; for (const node of graph.nodes) { - const workGraph = readLatestWorkGraph(deps3.workspace, job.jobId, node.nodeId); + const workGraph = readLatestWorkGraph(deps4.workspace, job.jobId, node.nodeId); if (workGraph === void 0) continue; let changed = false; const units = workGraph.units.map((unit) => { @@ -71971,23 +71976,23 @@ function reviveUnitsNamedBy(deps3, job, question, answer) { }; }); if (changed) { - storeWorkGraph(deps3.workspace, job.jobId, { ...workGraph, units }); + storeWorkGraph(deps4.workspace, job.jobId, { ...workGraph, units }); } } } -function answerClarification(deps3, jobId, answers) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); +function answerClarification(deps4, jobId, answers) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); if (job.status !== "NEEDS_CLARIFICATION") { throw new OrchestrationError("SBO027", `Answers apply only while NEEDS_CLARIFICATION (job is ${job.status}).`); } - const at = now4(deps3).toISOString(); + const at = now4(deps4).toISOString(); const answered = /* @__PURE__ */ new Set(); const decisions = answers.filter((answer) => job.openQuestions.some((question) => question.id === answer.questionId)).map((answer) => { answered.add(answer.questionId); const question = job.openQuestions.find((candidate) => candidate.id === answer.questionId); return { - id: `d-${newId4(deps3)}`.slice(0, 64), + id: `d-${newId4(deps4)}`.slice(0, 64), questionId: answer.questionId, question: question?.question ?? "", answer: answer.answer.slice(0, 2e3), @@ -72004,41 +72009,41 @@ function answerClarification(deps3, jobId, answers) { openQuestions: job.openQuestions.filter((question) => !answered.has(question.id)) }; for (const decision of decisions) { - reviveUnitsNamedBy(deps3, job, decision.question, decision.answer); + reviveUnitsNamedBy(deps4, job, decision.question, decision.answer); } - job = record22(deps3, job, "clarification_resolved", { + job = record22(deps4, job, "clarification_resolved", { decisionIds: decisions.map((decision) => decision.id), remaining: job.openQuestions.length }); if (job.openQuestions.length === 0) { - job = transition22(deps3, job, "READY"); + job = transition22(deps4, job, "READY"); } - return persist22(deps3, job); + return persist22(deps4, job); } -function cancelJob(deps3, jobId, reason3) { - let job = requireJobState(deps3.workspace, jobId); +function cancelJob(deps4, jobId, reason3) { + let job = requireJobState(deps4.workspace, jobId); if (isFinalJobStatus(job.status)) return job; - const at = now4(deps3).toISOString(); - job = transition22(deps3, job, "CANCELLED"); - job = record22(deps3, job, "job_cancelled", { reason: reason3.slice(0, 500) }); - return persist22(deps3, { ...job, finalizedAt: at, finalOutcome: "CANCELLED" }); + const at = now4(deps4).toISOString(); + job = transition22(deps4, job, "CANCELLED"); + job = record22(deps4, job, "job_cancelled", { reason: reason3.slice(0, 500) }); + return persist22(deps4, { ...job, finalizedAt: at, finalOutcome: "CANCELLED" }); } var TRANSIENT_UNIT_FAILURES = ["TRANSIENT_TOOL", "TRANSIENT_TRANSPORT"]; -function selfHealOnResume(deps3, jobId) { +function selfHealOnResume(deps4, jobId) { const repairs = []; - let job = requireJobState(deps3.workspace, jobId); - const lock = diagnoseInteractiveLock(deps3.workspace, () => now4(deps3)); + let job = requireJobState(deps4.workspace, jobId); + const lock = diagnoseInteractiveLock(deps4.workspace, () => now4(deps4)); if (lock.state === "stale" && lock.safeToRemove) { - removeDiagnosedLock(deps3.workspace, () => now4(deps3)); + removeDiagnosedLock(deps4.workspace, () => now4(deps4)); repairs.push({ code: "STALE_RUN_LOCK_REMOVED", detail: lock.findings.join(" ").slice(0, 280) }); if (job.humanWaitSince === void 0) { const diedAt = Date.parse(job.updatedAt); - const idle = Number.isNaN(diedAt) ? 0 : Math.max(0, now4(deps3).getTime() - diedAt); + const idle = Number.isNaN(diedAt) ? 0 : Math.max(0, now4(deps4).getTime() - diedAt); if (idle > 0) { - job = persist22(deps3, { + job = persist22(deps4, { ...job, counters: { ...job.counters, deadIdleMs: (job.counters.deadIdleMs ?? 0) + idle } }); @@ -72051,9 +72056,9 @@ function selfHealOnResume(deps3, jobId) { } if (job.humanWaitSince !== void 0) { const since = Date.parse(job.humanWaitSince); - const banked = Number.isNaN(since) ? 0 : Math.max(0, now4(deps3).getTime() - since); + const banked = Number.isNaN(since) ? 0 : Math.max(0, now4(deps4).getTime() - since); const { humanWaitSince: _banked, ...rest } = job; - job = persist22(deps3, { + job = persist22(deps4, { ...rest, counters: { ...job.counters, humanWaitMs: (job.counters.humanWaitMs ?? 0) + banked } }); @@ -72063,29 +72068,29 @@ function selfHealOnResume(deps3, jobId) { }); } if (job.status === "BLOCKED" && job.blocker?.category === "BUDGET_EXHAUSTED") { - const worked = workedMsOf(job, now4(deps3).getTime()); + const worked = workedMsOf(job, now4(deps4).getTime()); const stillOver = worked >= job.budgets.maxWallClockMs || job.counters.agentRuns >= job.budgets.maxAgentRuns; if (!stillOver) { const { blocker: _stale, ...rest } = job; - job = persist22(deps3, rest); - job = transition22(deps3, job, "READY"); - job = persist22(deps3, job); + job = persist22(deps4, rest); + job = transition22(deps4, job, "READY"); + job = persist22(deps4, job); repairs.push({ code: "BUDGET_VERDICT_RECOMPUTED", detail: `BUDGET_EXHAUSTED no longer holds: worked ${Math.round(worked / 6e4)}m of ${Math.round(job.budgets.maxWallClockMs / 6e4)}m, ${job.counters.agentRuns} of ${job.budgets.maxAgentRuns} dispatches` }); } } - const graph = job.graphRevision > 0 ? readGraphRevision(deps3.workspace, jobId, job.graphRevision) : void 0; + const graph = job.graphRevision > 0 ? readGraphRevision(deps4.workspace, jobId, job.graphRevision) : void 0; if (graph !== void 0) { for (const node of graph.nodes) { - const workGraph = readLatestWorkGraph(deps3.workspace, jobId, node.nodeId); + const workGraph = readLatestWorkGraph(deps4.workspace, jobId, node.nodeId); if (workGraph === void 0) continue; const revived = workGraph.units.filter( (unit) => unit.status === "FAILED" && TRANSIENT_UNIT_FAILURES.includes(unit.latestFailure?.category ?? "") ); if (revived.length === 0) continue; - storeWorkGraph(deps3.workspace, jobId, { + storeWorkGraph(deps4.workspace, jobId, { ...workGraph, units: workGraph.units.map((unit) => { if (!revived.includes(unit)) return unit; @@ -72100,10 +72105,10 @@ function selfHealOnResume(deps3, jobId) { } } if (repairs.length > 0) { - job = requireJobState(deps3.workspace, jobId); + job = requireJobState(deps4.workspace, jobId); job = persist22( - deps3, - record22(deps3, job, "self_heal_applied", { + deps4, + record22(deps4, job, "self_heal_applied", { repairs: repairs.map((repair) => ({ code: repair.code, detail: repair.detail.slice(0, 200) })) }) ); @@ -72119,8 +72124,8 @@ var OPERATOR_FIXABLE_BLOCKER_CATEGORIES = [ "TRANSIENT_TOOL", "INVALID_CONFIGURATION" ]; -function retryBlockedJob(deps3, jobId, input) { - let job = requireJobState(deps3.workspace, jobId); +function retryBlockedJob(deps4, jobId, input) { + let job = requireJobState(deps4.workspace, jobId); if (job.status !== "BLOCKED") { return { job, cleared: false, reason: `the job is ${job.status}, not BLOCKED` }; } @@ -72135,83 +72140,83 @@ function retryBlockedJob(deps3, jobId, input) { reason: `the blocker is ${category}, which is not something fixing the machine resolves` }; } - job = transition22(deps3, job, "READY"); + job = transition22(deps4, job, "READY"); const { blocker: _cleared, ...rest } = job; - job = persist22(deps3, rest); - job = record22(deps3, job, "job_unblocked", { + job = persist22(deps4, rest); + job = record22(deps4, job, "job_unblocked", { category, code: job.blocker?.code ?? null, reason: input.reason.slice(0, 500) }); - return { job: persist22(deps3, job), cleared: true }; + return { job: persist22(deps4, job), cleared: true }; } -function blockJob(deps3, jobId, input) { - let job = requireJobState(deps3.workspace, jobId); +function blockJob(deps4, jobId, input) { + let job = requireJobState(deps4.workspace, jobId); if (job.status === "BLOCKED") return job; - const at = now4(deps3).toISOString(); - job = transition22(deps3, job, "BLOCKED"); - job = record22(deps3, job, input.category === "BUDGET_EXHAUSTED" ? "budget_exhausted" : "job_blocked", { + const at = now4(deps4).toISOString(); + job = transition22(deps4, job, "BLOCKED"); + job = record22(deps4, job, input.category === "BUDGET_EXHAUSTED" ? "budget_exhausted" : "job_blocked", { code: input.code, reason: input.message.slice(0, 500) }); - return persist22(deps3, { + return persist22(deps4, { ...job, blocker: { category: input.category, code: input.code, message: input.message, remediation: input.remediation, at } }); } -function clearRetryWait(deps3, jobId, at) { - let job = requireJobState(deps3.workspace, jobId); +function clearRetryWait(deps4, jobId, at) { + let job = requireJobState(deps4.workspace, jobId); if (job.status !== "WAITING_RETRY") return job; - const instant = at ?? now4(deps3); + const instant = at ?? now4(deps4); if (job.retryAt !== void 0 && Date.parse(job.retryAt) > instant.getTime()) return job; - job = transition22(deps3, job, "READY"); + job = transition22(deps4, job, "READY"); delete job.retryAt; - return persist22(deps3, job); + return persist22(deps4, job); } -function promoteNodeForQuotaOvertake(deps3, jobId, input) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); - let graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); +function promoteNodeForQuotaOvertake(deps4, jobId, input) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); + let graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); const node = requireNode(graph, input.nodeId); if (node.status !== "PENDING") { return job; } graph = transitionNode(graph, node.nodeId, "READY"); - job = record22(deps3, job, "node_ready", { + job = record22(deps4, job, "node_ready", { nodeId: node.nodeId, taskId: node.parentTaskId, quotaOvertake: true, detail: input.detail.slice(0, 300) }); - persistGraph(deps3, job, graph); - return persist22(deps3, job); + persistGraph(deps4, job, graph); + return persist22(deps4, job); } -function deferJobForQuota(deps3, jobId, input) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); - const at = now4(deps3); +function deferJobForQuota(deps4, jobId, input) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); + const at = now4(deps4); const retryAt = input.until !== null && Date.parse(input.until) > at.getTime() ? input.until : new Date(at.getTime() + Math.max(1e3, input.pollMs)).toISOString(); if (job.status !== "WAITING_RETRY") { - job = transition22(deps3, job, "WAITING_RETRY"); + job = transition22(deps4, job, "WAITING_RETRY"); } job = { ...job, retryAt }; - job = record22(deps3, job, "task_deferred", { + job = record22(deps4, job, "task_deferred", { nodeId: input.nodeId, taskId: input.taskId, reasonCode: input.reasonCode.slice(0, 100), retryAt, detail: input.detail.slice(0, 500) }); - return persist22(deps3, job); + return persist22(deps4, job); } -function checkpointJob(deps3, jobId, nextAction) { - let job = requireJobState(deps3.workspace, jobId); - const graph = job.graphRevision > 0 ? readGraphRevision(deps3.workspace, jobId, job.graphRevision) : void 0; +function checkpointJob(deps4, jobId, nextAction) { + let job = requireJobState(deps4.workspace, jobId); + const graph = job.graphRevision > 0 ? readGraphRevision(deps4.workspace, jobId, job.graphRevision) : void 0; const nodes = graph?.nodes ?? []; const checkpoint = jobCheckpointSchema.parse({ schemaVersion: JOB_CHECKPOINT_SCHEMA_VERSION, jobId, - createdAt: now4(deps3).toISOString(), + createdAt: now4(deps4).toISOString(), specName: job.specName, status: job.status, graphRevision: job.graphRevision, @@ -72225,21 +72230,21 @@ function checkpointJob(deps3, jobId, nextAction) { ...job.operationalWait !== void 0 ? { operationalWait: job.operationalWait } : {}, nextAction: nextAction.slice(0, 2e3) }); - writeJobCheckpoint(deps3.workspace, jobId, checkpoint); - job = record22(deps3, job, "checkpoint_created", { status: job.status }); - persist22(deps3, job); + writeJobCheckpoint(deps4.workspace, jobId, checkpoint); + job = record22(deps4, job, "checkpoint_created", { status: job.status }); + persist22(deps4, job); return checkpoint; } -async function resumeJob(deps3, jobId) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); +async function resumeJob(deps4, jobId) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); const warnings = []; const reconciled = []; - const checkpoint = readJobCheckpoint(deps3.workspace, jobId); + const checkpoint = readJobCheckpoint(deps4.workspace, jobId); if (isFinalJobStatus(job.status)) { return { job, - graph: job.graphRevision > 0 ? readGraphRevision(deps3.workspace, jobId, job.graphRevision) : void 0, + graph: job.graphRevision > 0 ? readGraphRevision(deps4.workspace, jobId, job.graphRevision) : void 0, finalized: true, reconciled, planStale: false, @@ -72250,14 +72255,14 @@ async function resumeJob(deps3, jobId) { nextAction: "Create a new job for further work." }; } - const currentFingerprint = jobPolicyFingerprint(deps3.config.orchestration); + const currentFingerprint = jobPolicyFingerprint(deps4.config.orchestration); const policyChanged = currentFingerprint !== job.policyFingerprint; if (policyChanged) { warnings.push( "The job policy changed since this job began. The job continues under the budgets recorded at its start." ); } - let graph = job.graphRevision > 0 ? requireGraphRevision(deps3.workspace, jobId, job.graphRevision) : void 0; + let graph = job.graphRevision > 0 ? requireGraphRevision(deps4.workspace, jobId, job.graphRevision) : void 0; if (graph !== void 0) { for (const node of graph.nodes) { if (node.status === "RUNNING" || node.status === "REPAIRING") { @@ -72268,16 +72273,16 @@ async function resumeJob(deps3, jobId) { } if (job.status === "RUNNING" || job.status === "REPAIRING" || job.status === "PLANNING") { const interrupted = job.status; - job = { ...job, status: "READY", updatedAt: now4(deps3).toISOString() }; + job = { ...job, status: "READY", updatedAt: now4(deps4).toISOString() }; reconciled.push(`job: ${interrupted} \u2192 READY (interrupted process)`); } const interruptedAttempts = reconcileInterruptedAttempts( - { workspace: deps3.workspace, clock: deps3.clock }, + { workspace: deps4.workspace, clock: deps4.clock }, jobId ); for (const attempt of interruptedAttempts) { reconciled.push(`attempt ${attempt.attemptId}: RUNNING \u2192 INTERRUPTED (worker disappeared)`); - job = record22(deps3, job, "attempt_interrupted", { + job = record22(deps4, job, "attempt_interrupted", { nodeId: attempt.nodeId, taskId: attempt.taskId, attemptId: attempt.attemptId, @@ -72288,15 +72293,15 @@ async function resumeJob(deps3, jobId) { job = { ...job, currentAttemptId: void 0 }; } const interruptedReservations = reconcileInterruptedApiReservations( - deps3.workspace, + deps4.workspace, jobId, - now4(deps3) + now4(deps4) ); for (const reservation of interruptedReservations) { reconciled.push( `api budget ${reservation.reservationId}: RESERVED \u2192 UNKNOWN ($${reservation.reservedUsd.toFixed(4)} stays charged; remote usage cannot be ruled out)` ); - job = record22(deps3, job, "api_budget_reconciled", { + job = record22(deps4, job, "api_budget_reconciled", { nodeId: reservation.nodeId, taskId: reservation.taskId, reservationId: reservation.reservationId, @@ -72306,22 +72311,22 @@ async function resumeJob(deps3, jobId) { costSource: reservation.costSource }); } - const snapshot2 = await captureGitSnapshot(deps3.workspace.rootDir, { clock: () => now4(deps3) }); + const snapshot2 = await captureGitSnapshot(deps4.workspace.rootDir, { clock: () => now4(deps4) }); let planStale = false; let planStaleReasons = []; if (graph !== void 0 && job.currentNodeId !== void 0) { const node = findNode(graph, job.currentNodeId); if (node !== void 0 && node.planRevision > 0) { - const raw = readNodePlan(deps3.workspace, jobId, node.nodeId, node.planRevision); + const raw = readNodePlan(deps4.workspace, jobId, node.nodeId, node.planRevision); const parsed = raw !== void 0 ? executionPlanSchema.safeParse(raw) : void 0; if (parsed === void 0 || !parsed.success) { warnings.push(`The plan for node ${node.nodeId} is missing or unreadable; a fresh plan is required.`); graph = withNode(graph, { ...node, planApproved: false, planRevision: 0 }); } else { - const current = capturePlanBinding(deps3.workspace, { + const current = capturePlanBinding(deps4.workspace, { specName: job.specName, taskId: node.parentTaskId, - policy: deps3.config.orchestration, + policy: deps4.config.orchestration, gitHead: snapshot2.head }); const freshness = evaluatePlanFreshness(parsed.data, current); @@ -72331,31 +72336,31 @@ async function resumeJob(deps3, jobId) { warnings.push("The recorded plan no longer matches the repository; it will not be executed as-is."); graph = withNode(graph, { ...node, planApproved: false }); if (job.status === "READY") { - job = transition22(deps3, job, "REPLANNING"); + job = transition22(deps4, job, "REPLANNING"); } } } } } - const lock = readInteractiveLock(deps3.workspace); + const lock = readInteractiveLock(deps4.workspace); if (lock.state === "held") { warnings.push( `The repository lock is held by run ${lock.lock.runId}; recover it with \`specbridge run recover-lock\` before dispatching.` ); } - if (graph !== void 0) persistGraph(deps3, job, graph); - job = record22(deps3, job, "job_resumed", { + if (graph !== void 0) persistGraph(deps4, job, graph); + job = record22(deps4, job, "job_resumed", { reconciled: reconciled.length, planStale, policyChanged }); if (reconciled.length > 0 || planStale) { - job = record22(deps3, job, "repository_reconciled", { + job = record22(deps4, job, "repository_reconciled", { ...snapshot2.head !== void 0 ? { gitHead: snapshot2.head } : {}, planStale }); } - job = persist22(deps3, job); + job = persist22(deps4, job); return { job, graph, @@ -72371,9 +72376,9 @@ async function resumeJob(deps3, jobId) { nextAction: planStale ? "Produce a replacement plan: the recorded plan is stale." : "Continue with the scheduler decision." }; } -function recordObjectiveWorkerAttempt(deps3, jobId, input) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); +function recordObjectiveWorkerAttempt(deps4, jobId, input) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); if (job.counters.agentRuns >= job.budgets.maxAgentRuns) { throw new OrchestrationError( "SBO032", @@ -72381,25 +72386,25 @@ function recordObjectiveWorkerAttempt(deps3, jobId, input) { { failureCategory: "BUDGET_EXHAUSTED" } ); } - let graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); + let graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); ({ job, graph } = appendAttempt( - deps3, + deps4, job, graph, { nodeId: input.nodeId, role: input.role, workerId: input.workerId, - startedAt: now4(deps3).toISOString(), + startedAt: now4(deps4).toISOString(), ...input.usage !== void 0 ? { usage: input.usage } : {} }, input.outcome === "succeeded" ? "succeeded" : input.outcome )); - persistGraph(deps3, job, graph); - return persist22(deps3, job); + persistGraph(deps4, job, graph); + return persist22(deps4, job); } -function countLocalInferenceCall(deps3, jobId) { - let job = requireJobState(deps3.workspace, jobId); +function countLocalInferenceCall(deps4, jobId) { + let job = requireJobState(deps4.workspace, jobId); if (job.counters.localInferenceCalls >= job.budgets.maxLocalInferenceCalls) { throw new OrchestrationError( "SBO032", @@ -72411,22 +72416,22 @@ function countLocalInferenceCall(deps3, jobId) { ...job, counters: { ...job.counters, localInferenceCalls: job.counters.localInferenceCalls + 1 } }; - return persist22(deps3, job); + return persist22(deps4, job); } -function assessDispatchContextMiss(deps3, input) { - const at = now4(deps3).toISOString(); +function assessDispatchContextMiss(deps4, input) { + const at = now4(deps4).toISOString(); const idle = { signals: [], missingPaths: [], offer: { available: false, nextLevel: "TOP_WORKING_SET", reason: "", exhausted: false } }; - if (deps3.config.orchestration.jobs.context.efficiency.strategy === "LEGACY") return idle; + if (deps4.config.orchestration.jobs.context.efficiency.strategy === "LEGACY") return idle; try { - const plan = listContextSelectionPlans(deps3.workspace, input.jobId, { + const plan = listContextSelectionPlans(deps4.workspace, input.jobId, { nodeId: input.nodeId, attemptId: input.attemptId }).at(-1); - const cached2 = readRepositoryIndexCache(deps3.workspace); + const cached2 = readRepositoryIndexCache(deps4.workspace); const index = cached2 === void 0 ? void 0 : new RepositoryContextIndex(cached2); const miss = assessContextMiss({ plan, @@ -72436,30 +72441,30 @@ function assessDispatchContextMiss(deps3, input) { ...input.directModelRequestedRepository === true ? { directModelRequestedRepository: true } : {} }); if (miss.signals.length === 0) return idle; - const state = readContextExpansionState(deps3.workspace, input.jobId, input.nodeId) ?? initialExpansionState({ taskId: plan?.taskId ?? input.nodeId, nodeId: input.nodeId, now: at }); + const state = readContextExpansionState(deps4.workspace, input.jobId, input.nodeId) ?? initialExpansionState({ taskId: plan?.taskId ?? input.nodeId, nodeId: input.nodeId, now: at }); return { signals: miss.signals, missingPaths: miss.missingPaths, - offer: offerContextExpansion({ config: deps3.config, state, signals: miss.signals }) + offer: offerContextExpansion({ config: deps4.config, state, signals: miss.signals }) }; } catch { return idle; } } -function applyContextExpansion(deps3, input) { +function applyContextExpansion(deps4, input) { try { - const state = readContextExpansionState(deps3.workspace, input.jobId, input.nodeId) ?? initialExpansionState({ taskId: input.taskId, nodeId: input.nodeId, now: input.at }); + const state = readContextExpansionState(deps4.workspace, input.jobId, input.nodeId) ?? initialExpansionState({ taskId: input.taskId, nodeId: input.nodeId, now: input.at }); const signals2 = input.signals; const decision = planContextExpansion({ - strategy: deps3.config.orchestration.jobs.context.efficiency.strategy, - policy: expansionPolicyFrom(deps3.config), + strategy: deps4.config.orchestration.jobs.context.efficiency.strategy, + policy: expansionPolicyFrom(deps4.config), state, signals: signals2 }); if (!decision.expand) return; const next = applyExpansion(state, decision, { signals: signals2, now: input.at }); - writeContextExpansionState(deps3.workspace, input.jobId, input.nodeId, next); - recordJobEvent(deps3, input.jobId, "context_expanded", { + writeContextExpansionState(deps4.workspace, input.jobId, input.nodeId, next); + recordJobEvent(deps4, input.jobId, "context_expanded", { nodeId: input.nodeId, taskId: input.taskId, level: next.level, @@ -72469,10 +72474,10 @@ function applyContextExpansion(deps3, input) { } catch { } } -function enterResourceWait(deps3, jobId, input) { - const previous = requireJobState(deps3.workspace, jobId); - const wait = buildWait(deps3, previous, input); - return applyJobTransition(deps3, jobId, { +function enterResourceWait(deps4, jobId, input) { + const previous = requireJobState(deps4.workspace, jobId); + const wait = buildWait(deps4, previous, input); + return applyJobTransition(deps4, jobId, { to: "WAITING_RESOURCE", event: "resource_wait_started", payload: { @@ -72488,10 +72493,10 @@ function enterResourceWait(deps3, jobId, input) { } }); } -function enterProviderRecovery(deps3, jobId, input) { - const previous = requireJobState(deps3.workspace, jobId); - const wait = buildWait(deps3, previous, input); - return applyJobTransition(deps3, jobId, { +function enterProviderRecovery(deps4, jobId, input) { + const previous = requireJobState(deps4.workspace, jobId); + const wait = buildWait(deps4, previous, input); + return applyJobTransition(deps4, jobId, { to: "RECOVERING_PROVIDER", event: "provider_recovery_started", payload: { kind: input.kind, detail: input.detail.slice(0, 300), attempt: wait.recoveryAttempts }, @@ -72501,32 +72506,32 @@ function enterProviderRecovery(deps3, jobId, input) { } }); } -function enterToolchainRepair(deps3, jobId, input) { - const previous = requireJobState(deps3.workspace, jobId); - return applyJobTransition(deps3, jobId, { +function enterToolchainRepair(deps4, jobId, input) { + const previous = requireJobState(deps4.workspace, jobId); + return applyJobTransition(deps4, jobId, { to: "REPAIRING_TOOLCHAIN", event: "toolchain_repair_started", payload: { kind: input.kind, detail: input.detail.slice(0, 300) }, patch: { - operationalWait: buildWait(deps3, previous, input), + operationalWait: buildWait(deps4, previous, input), autonomyCounters: bump(previous, "toolchainRepairs") } }); } -function enterEnvironmentRepair(deps3, jobId, input) { - const previous = requireJobState(deps3.workspace, jobId); - return applyJobTransition(deps3, jobId, { +function enterEnvironmentRepair(deps4, jobId, input) { + const previous = requireJobState(deps4.workspace, jobId); + return applyJobTransition(deps4, jobId, { to: "REPAIRING_ENVIRONMENT", event: "environment_failed", payload: { kind: input.kind, detail: input.detail.slice(0, 300) }, patch: { - operationalWait: buildWait(deps3, previous, input), + operationalWait: buildWait(deps4, previous, input), autonomyCounters: bump(previous, "environmentRepairs") } }); } -function clearOperationalState(deps3, jobId, input) { - const job = requireJobState(deps3.workspace, jobId); +function clearOperationalState(deps4, jobId, input) { + const job = requireJobState(deps4.workspace, jobId); if (!isOperationalJobStatus(job.status)) { throw new OrchestrationError( "SBO027", @@ -72535,7 +72540,7 @@ function clearOperationalState(deps3, jobId, input) { ); } const event = eventForOperationalExit(job.status); - return applyJobTransition(deps3, jobId, { + return applyJobTransition(deps4, jobId, { to: input.to ?? "READY", event, payload: { @@ -72563,8 +72568,8 @@ function eventForOperationalExit(status) { return "resource_wait_ended"; } } -function enterQualifying(deps3, jobId, input) { - return applyJobTransition(deps3, jobId, { +function enterQualifying(deps4, jobId, input) { + return applyJobTransition(deps4, jobId, { to: "QUALIFYING", event: "closure_audit_completed", payload: { @@ -72574,10 +72579,10 @@ function enterQualifying(deps3, jobId, input) { patch: { closurePhase: input.phase, operationalWait: void 0 } }); } -function escalateAuthority(deps3, jobId, input) { - const job = requireJobState(deps3.workspace, jobId); +function escalateAuthority(deps4, jobId, input) { + const job = requireJobState(deps4.workspace, jobId); if (job.authorityRequest !== void 0 && job.authorityRequest.resolvedAt === void 0) { - return job.status === "NEEDS_AUTHORITY" ? job : applyJobTransition(deps3, jobId, { + return job.status === "NEEDS_AUTHORITY" ? job : applyJobTransition(deps4, jobId, { to: "NEEDS_AUTHORITY", event: "authority_escalated", payload: { surface: job.authorityRequest.surface, existing: true } @@ -72585,7 +72590,7 @@ function escalateAuthority(deps3, jobId, input) { } const request = authorityRequestSchema.parse({ requestId: `auth-${Date.now().toString(36)}-${job.counters.escalations + 1}`, - at: new Date(deps3.clock !== void 0 ? deps3.clock().getTime() : Date.now()).toISOString(), + at: new Date(deps4.clock !== void 0 ? deps4.clock().getTime() : Date.now()).toISOString(), surface: input.surface, reason: input.reason, question: input.question.slice(0, 2e3), @@ -72595,7 +72600,7 @@ function escalateAuthority(deps3, jobId, input) { options: [...input.options ?? []].slice(0, 10), observedSignals: [...input.observedSignals ?? []].slice(0, 20) }); - return applyJobTransition(deps3, jobId, { + return applyJobTransition(deps4, jobId, { to: "NEEDS_AUTHORITY", event: "authority_escalated", payload: { surface: request.surface, reason: request.reason, requestId: request.requestId }, @@ -72606,8 +72611,8 @@ function escalateAuthority(deps3, jobId, input) { } }); } -function buildWait(deps3, job, input) { - const at = new Date(deps3.clock !== void 0 ? deps3.clock().getTime() : Date.now()).toISOString(); +function buildWait(deps4, job, input) { + const at = new Date(deps4.clock !== void 0 ? deps4.clock().getTime() : Date.now()).toISOString(); const existing = job.operationalWait !== void 0 && job.operationalWait.kind === input.kind ? job.operationalWait : void 0; return operationalWaitSchema.parse({ kind: input.kind, @@ -72635,9 +72640,9 @@ function bump(job, key) { const current = counters[key]; return { ...counters, [key]: (typeof current === "number" ? current : 0) + 1 }; } -function countAutonomyEvent(deps3, jobId, key, event, payload = {}) { - const job = requireJobState(deps3.workspace, jobId); - return applyJobTransition(deps3, jobId, { +function countAutonomyEvent(deps4, jobId, key, event, payload = {}) { + const job = requireJobState(deps4.workspace, jobId); + return applyJobTransition(deps4, jobId, { to: job.status, event, payload, @@ -73757,6 +73762,23 @@ function writeResearchUseRecord(workspace, value) { `); return record32; } +function listResearchUseRecords(workspace) { + const dir = researchUsesDir(workspace); + if (!(0, import_fs45.existsSync)(dir)) return []; + const records = []; + for (const entry2 of (0, import_fs45.readdirSync)(dir, { withFileTypes: true })) { + if (!entry2.isFile() || !entry2.name.endsWith(".json")) continue; + try { + const value = JSON.parse((0, import_fs45.readFileSync)(import_path48.default.join(dir, entry2.name), "utf8")); + const version2 = value !== null && typeof value === "object" && typeof value.schemaVersion === "string" ? value.schemaVersion : ""; + if (majorOf3(version2) !== majorOf3(RESEARCH_USE_SCHEMA_VERSION)) continue; + const parsed = researchUseRecordSchema.safeParse(value); + if (parsed.success) records.push(parsed.data); + } catch { + } + } + return records.sort((a2, b) => a2.createdAt.localeCompare(b.createdAt)); +} function listResearchRecords(workspace) { const dir = researchRecordsDir(workspace); if (!(0, import_fs45.existsSync)(dir)) return { records: [], diagnostics: [] }; @@ -74480,17 +74502,17 @@ function recordResearchReplanTelemetry(workspace, now52) { updatedAt: now52.toISOString() }); } -function nowOf(deps3) { - return deps3.clock?.() ?? /* @__PURE__ */ new Date(); +function nowOf(deps4) { + return deps4.clock?.() ?? /* @__PURE__ */ new Date(); } -function newUseId(deps3) { - return `use-${(deps3.idFactory ?? import_crypto23.randomUUID)()}`.slice(0, 128); +function newUseId(deps4) { + return `use-${(deps4.idFactory ?? import_crypto23.randomUUID)()}`.slice(0, 128); } -function recordLifecycleUse(deps3, researchId, scope, useKind, effect) { +function recordLifecycleUse(deps4, researchId, scope, useKind, effect) { if (scope.lifecycle === void 0) return; - writeResearchUseRecord(deps3.workspace, { + writeResearchUseRecord(deps4.workspace, { schemaVersion: RESEARCH_USE_SCHEMA_VERSION, - useId: newUseId(deps3), + useId: newUseId(deps4), researchId, phase: scope.lifecycle.phase, reason: scope.lifecycle.reason, @@ -74498,17 +74520,17 @@ function recordLifecycleUse(deps3, researchId, scope, useKind, effect) { effect: effect ?? scope.lifecycle.requestedEffect ?? "EVIDENCE", ...scope.lifecycle.usedBy !== void 0 ? { usedBy: scope.lifecycle.usedBy } : {}, authority: "EVIDENCE_ONLY", - createdAt: nowOf(deps3).toISOString() + createdAt: nowOf(deps4).toISOString() }); } function failure2(classification, failureSource, message2, retryable = false) { return { classification, failureSource, message: message2, retryable }; } -function selectedBridge(deps3) { - if (deps3.bridge !== void 0) return deps3.bridge; - if (deps3.config.research.provider === "deerflow") { - return new DeerFlowResearchBridge(deps3.config.research.providers.deerflow, { - clock: () => nowOf(deps3) +function selectedBridge(deps4) { + if (deps4.bridge !== void 0) return deps4.bridge; + if (deps4.config.research.provider === "deerflow") { + return new DeerFlowResearchBridge(deps4.config.research.providers.deerflow, { + clock: () => nowOf(deps4) }); } return void 0; @@ -74546,14 +74568,14 @@ function budgetFailure(policy, records, request, scope) { } return void 0; } -function evaluateAndRecordResearchGate(deps3, input, phase) { +function evaluateAndRecordResearchGate(deps4, input, phase) { const result = evaluateResearchGate(input); - recordResearchGateTelemetry(deps3.workspace, result.decision, nowOf(deps3), phase); + recordResearchGateTelemetry(deps4.workspace, result.decision, nowOf(deps4), phase); return result; } -async function getResearchProviderHealth(deps3, signal) { - const now52 = nowOf(deps3).toISOString(); - const policy = deps3.config.research; +async function getResearchProviderHealth(deps4, signal) { + const now52 = nowOf(deps4).toISOString(); + const policy = deps4.config.research; if (!policy.enabled) { return { provider: policy.provider, @@ -74570,7 +74592,7 @@ async function getResearchProviderHealth(deps3, signal) { detail: "the selected research provider is disabled; no health request was made" }; } - const bridge = selectedBridge(deps3); + const bridge = selectedBridge(deps4); if (bridge === void 0 || bridge.providerId() !== policy.provider) { return { provider: policy.provider, @@ -74581,15 +74603,15 @@ async function getResearchProviderHealth(deps3, signal) { } return bridge.health(signal); } -async function startResearch(deps3, raw, scope = {}, signal) { +async function startResearch(deps4, raw, scope = {}, signal) { const request = researchRequestSchema.parse(raw); - const policy = deps3.config.research; - const existing = listResearchRecords(deps3.workspace).records; + const policy = deps4.config.research; + const existing = listResearchRecords(deps4.workspace).records; const reuse = findResearchReuse(existing, request); const refreshCurrentFacts = scope.refreshCurrentFacts === true && request.freshness.currentFactSensitive; if (!refreshCurrentFacts && reuse.exact?.report !== void 0) { - recordResearchReuseTelemetry(deps3.workspace, nowOf(deps3), scope.lifecycle?.phase); - recordLifecycleUse(deps3, reuse.exact.researchId, scope, "REUSED"); + recordResearchReuseTelemetry(deps4.workspace, nowOf(deps4), scope.lifecycle?.phase); + recordLifecycleUse(deps4, reuse.exact.researchId, scope, "REUSED"); return { ok: true, reused: true, record: reuse.exact, report: reuse.exact.report }; } if (existing.some((record42) => record42.researchId === request.researchId)) { @@ -74613,10 +74635,10 @@ async function startResearch(deps3, raw, scope = {}, signal) { } const refused = budgetFailure(policy, existing, request, scope); if (refused !== void 0) { - recordResearchBudgetRefusalTelemetry(deps3.workspace, nowOf(deps3)); + recordResearchBudgetRefusalTelemetry(deps4.workspace, nowOf(deps4)); return { ok: false, failure: refused }; } - const bridge = selectedBridge(deps3); + const bridge = selectedBridge(deps4); if (bridge === void 0 || bridge.providerId() !== policy.provider) { return { ok: false, @@ -74627,7 +74649,7 @@ async function startResearch(deps3, raw, scope = {}, signal) { ) }; } - const createdAt = nowOf(deps3).toISOString(); + const createdAt = nowOf(deps4).toISOString(); const baseRecord = { schemaVersion: RESEARCH_RECORD_SCHEMA_VERSION, researchId: request.researchId, @@ -74655,7 +74677,7 @@ async function startResearch(deps3, raw, scope = {}, signal) { createdAt, updatedAt: createdAt }; - writeResearchRecord(deps3.workspace, baseRecord); + writeResearchRecord(deps4.workspace, baseRecord); const started = Date.now(); let providerResult = await bridge.investigate(request, signal); if (providerResult.ok) { @@ -74672,9 +74694,9 @@ async function startResearch(deps3, raw, scope = {}, signal) { }; } } - const completed = nowOf(deps3); + const completed = nowOf(deps4); recordResearchProviderTelemetry( - deps3.workspace, + deps4.workspace, providerResult, Math.max(0, Date.now() - started), completed, @@ -74682,7 +74704,7 @@ async function startResearch(deps3, raw, scope = {}, signal) { scope.lifecycle?.phase ); if (!providerResult.ok) { - const record42 = writeResearchRecord(deps3.workspace, { + const record42 = writeResearchRecord(deps4.workspace, { ...baseRecord, status: providerResult.failure.classification === "CANCELLED" ? "CANCELLED" : "FAILED", failure: providerResult.failure, @@ -74691,7 +74713,7 @@ async function startResearch(deps3, raw, scope = {}, signal) { }); return { ok: false, failure: providerResult.failure, record: record42 }; } - const record32 = writeResearchRecord(deps3.workspace, { + const record32 = writeResearchRecord(deps4.workspace, { ...baseRecord, status: providerResult.report.status === "COMPLETED" ? "COMPLETED" : "INCONCLUSIVE", report: providerResult.report, @@ -74699,12 +74721,12 @@ async function startResearch(deps3, raw, scope = {}, signal) { ...providerResult.report.usage !== void 0 ? { usage: providerResult.report.usage } : {}, updatedAt: completed.toISOString() }); - recordLifecycleUse(deps3, record32.researchId, scope, "NEW"); + recordLifecycleUse(deps4, record32.researchId, scope, "NEW"); return { ok: true, reused: false, record: record32, report: providerResult.report }; } -function recordResearchLifecycleEffect(deps3, input) { +function recordResearchLifecycleEffect(deps4, input) { recordLifecycleUse( - deps3, + deps4, input.researchId, { lifecycle: { @@ -74759,11 +74781,11 @@ function classifiedGate(classification, supplied, priorResearchAvailable) { return { ...base, dependsOnExternalFacts: false, dependsOnCurrentFacts: false }; } } -async function considerLifecycleResearch(deps3, raw, signal) { +async function considerLifecycleResearch(deps4, raw, signal) { const input = lifecycleResearchInputSchema.parse(raw); - const priorResearchAvailable = input.request === void 0 ? false : findResearchReuse(listResearchRecords(deps3.workspace).records, input.request).exact !== void 0; + const priorResearchAvailable = input.request === void 0 ? false : findResearchReuse(listResearchRecords(deps4.workspace).records, input.request).exact !== void 0; const gate = evaluateAndRecordResearchGate( - deps3, + deps4, classifiedGate(input.classification, input.gate, priorResearchAvailable), input.phase ); @@ -74781,7 +74803,7 @@ async function considerLifecycleResearch(deps3, raw, signal) { }, ...input.refreshCurrentFacts ? { refreshCurrentFacts: true } : {} }; - const execution = await startResearch(deps3, input.request, scope, signal); + const execution = await startResearch(deps4, input.request, scope, signal); return { classification: input.classification, gate, execution }; } var decisionPreparationInputSchema = external_exports.object({ @@ -74809,11 +74831,11 @@ function reportContext(report) { ...report.conflicts.slice(0, 4).map((item) => `Research conflict: ${item}`) ].slice(0, 20); } -async function prepareDecisionBrief(deps3, raw, signal) { +async function prepareDecisionBrief(deps4, raw, signal) { const input = decisionPreparationInputSchema.parse(raw); const researchInput = input.research; const result = researchInput === void 0 ? void 0 : await considerLifecycleResearch( - deps3, + deps4, { ...researchInput, phase: "INTAKE_DECISION", @@ -74826,7 +74848,7 @@ async function prepareDecisionBrief(deps3, raw, signal) { ); const execution = result?.execution; const report = execution?.ok === true ? execution.report : void 0; - if (report !== void 0) recordResearchDecisionPreparedTelemetry(deps3.workspace, deps3.clock?.() ?? /* @__PURE__ */ new Date()); + if (report !== void 0) recordResearchDecisionPreparedTelemetry(deps4.workspace, deps4.clock?.() ?? /* @__PURE__ */ new Date()); return decisionBriefSchema.parse({ questionId: input.questionId, question: input.question, @@ -80249,7 +80271,7 @@ async function dispatchLocalHarnessExecution(input) { const lane = input.lane ?? "LOCAL"; const label = lane === "API" ? "api harness" : "local harness"; const source = lane === "API" ? "api-harness" : "local-harness"; - const deps3 = { + const deps4 = { workspace: input.workspace, config: input.config, ...input.clock !== void 0 ? { clock: input.clock } : {}, @@ -80269,7 +80291,7 @@ async function dispatchLocalHarnessExecution(input) { false ); } - const begin = await beginInteractiveTask(deps3, { + const begin = await beginInteractiveTask(deps4, { specName: input.specName, taskId: input.node.parentTaskId, allowDirty: input.allowDirty, @@ -80287,7 +80309,7 @@ async function dispatchLocalHarnessExecution(input) { input.onProgress?.(`${label}: run ${begin.runId} started for task ${begin.task.id}`); const abort = async (reason3) => { try { - await abortInteractiveTask(deps3, { runId: begin.runId, reason: reason3.slice(0, 500) }); + await abortInteractiveTask(deps4, { runId: begin.runId, reason: reason3.slice(0, 500) }); } catch { } }; @@ -80389,7 +80411,7 @@ async function dispatchLocalHarnessExecution(input) { } input.onProgress?.(`${label}: agent reported completion; running trusted verification`); const report = result.report; - const completion = await completeInteractiveTask(deps3, { + const completion = await completeInteractiveTask(deps4, { runId: begin.runId, summary: `[${source}] ${report?.summary ?? "harness attempt"}`.slice(0, 2e3), ...report?.changedFiles !== void 0 ? { reportedChangedFiles: [...report.changedFiles] } : {}, @@ -80498,8 +80520,8 @@ function observeHarnessActivity(result) { function dispatchApiHarnessExecution(input) { return dispatchLocalHarnessExecution({ ...input, lane: "API" }); } -function costOf(tokens, costPerMillion) { - return tokens / 1e6 * costPerMillion; +function costOf(tokens2, costPerMillion) { + return tokens2 / 1e6 * costPerMillion; } function roundUsd(value) { return Math.round(value * 1e4) / 1e4; @@ -82506,10 +82528,10 @@ function createSchedulingRuntime(config2, workspace, input) { lastObservedAt: void 0 }; } -function estimateNodeContextRatio(deps3, jobId, nodeId) { - const checkpoint = readLatestTaskCheckpoint(deps3.workspace, jobId, nodeId); +function estimateNodeContextRatio(deps4, jobId, nodeId) { + const checkpoint = readLatestTaskCheckpoint(deps4.workspace, jobId, nodeId); if (checkpoint === void 0) return null; - const budget = contextBudgetFromPolicy(deps3.config.orchestration.jobs.context); + const budget = contextBudgetFromPolicy(deps4.config.orchestration.jobs.context); const usable = usableInputTokens(budget); const serialized = JSON.stringify({ objective: checkpoint.objective, @@ -82526,8 +82548,8 @@ function estimateNodeContextRatio(deps3, jobId, nodeId) { }); return Math.round(estimateTokens(serialized) / usable * 1e4) / 1e4; } -function localExecutorAttemptsUsed(deps3, jobId, nodeId) { - return listTaskAttempts(deps3.workspace, jobId, { nodeId }).filter( +function localExecutorAttemptsUsed(deps4, jobId, nodeId) { + return listTaskAttempts(deps4.workspace, jobId, { nodeId }).filter( (attempt) => attempt.lane === "LOCAL" && attempt.role === "EXECUTOR" && (attempt.status === "FAILED" || attempt.status === "INTERRUPTED") ).length; } @@ -82537,14 +82559,14 @@ var LOCAL_ESCALATION_REASONS = [ "LOCAL_EXECUTION_ESCALATED" ]; var DIRECT_TO_HARNESS_REASON = "LOCAL_DIRECT_TO_HARNESS"; -async function buildLaneContext(runtime, deps3, jobId, job, graph) { - const ledger = readExecutionLedger(deps3.workspace, jobId); +async function buildLaneContext(runtime, deps4, jobId, job, graph) { + const ledger = readExecutionLedger(deps4.workspace, jobId); const observations = deriveBurnObservations(ledger); const { fiveHour, weekly } = await runtime.manager.snapshot(); const forecast = buildQuotaForecast({ fiveHour, weekly, - now: (deps3.clock ?? (() => /* @__PURE__ */ new Date()))(), + now: (deps4.clock ?? (() => /* @__PURE__ */ new Date()))(), policy: runtime.policy, observedFiveHourBurnRatePerMinute: observedFiveHourBurnRate(observations) }); @@ -82556,7 +82578,7 @@ async function buildLaneContext(runtime, deps3, jobId, job, graph) { const routings = /* @__PURE__ */ new Map(); const ready = (graph?.nodes ?? []).filter((node) => node.status === "READY"); for (const node of ready) { - routings.set(node.nodeId, assessNode(runtime, deps3, jobId, job, node, forecast, reserve, observations)); + routings.set(node.nodeId, assessNode(runtime, deps4, jobId, job, node, forecast, reserve, observations)); } if (runtime.apiBridgeEnabled && ready.length > 0) { const readyLocalNodeIds = ready.filter((node) => routings.get(node.nodeId)?.routing.lane === "LOCAL").map((node) => node.nodeId); @@ -82567,12 +82589,12 @@ async function buildLaneContext(runtime, deps3, jobId, job, graph) { for (const node of ready) { const assessment = routings.get(node.nodeId); if (assessment === void 0 || assessment.routing.lane !== "DEFER") continue; - const bridged = assessApiGapBridge(runtime, deps3, jobId, job, node, assessment, { + const bridged = assessApiGapBridge(runtime, deps4, jobId, job, node, assessment, { forecast, readyLocalNodeIds, readyRunnableNodeIds, graph, - now: (deps3.clock ?? (() => /* @__PURE__ */ new Date()))() + now: (deps4.clock ?? (() => /* @__PURE__ */ new Date()))() }); if (bridged !== void 0) routings.set(node.nodeId, bridged); } @@ -82586,7 +82608,7 @@ async function buildLaneContext(runtime, deps3, jobId, job, graph) { break; } if (node.status !== "PENDING") break; - const assessment = assessNode(runtime, deps3, jobId, job, node, forecast, reserve, observations); + const assessment = assessNode(runtime, deps4, jobId, job, node, forecast, reserve, observations); if (assessment.routing.lane === "LOCAL") { routings.set(node.nodeId, assessment); overtakeCandidate = { @@ -82598,7 +82620,7 @@ async function buildLaneContext(runtime, deps3, jobId, job, graph) { if (assessment.routing.lane !== "DEFER") break; } } - const adaptive = runtime.adaptiveEnabled ? applyAdaptiveRanking(runtime, deps3, jobId, job, ready, routings, forecast) : void 0; + const adaptive = runtime.adaptiveEnabled ? applyAdaptiveRanking(runtime, deps4, jobId, job, ready, routings, forecast) : void 0; return { context: { policy: runtime.policy, @@ -82613,12 +82635,12 @@ async function buildLaneContext(runtime, deps3, jobId, job, graph) { adaptive }; } -function applyAdaptiveRanking(runtime, deps3, jobId, job, ready, routings, forecast) { - const now52 = (deps3.clock ?? (() => /* @__PURE__ */ new Date()))(); +function applyAdaptiveRanking(runtime, deps4, jobId, job, ready, routings, forecast) { + const now52 = (deps4.clock ?? (() => /* @__PURE__ */ new Date()))(); let loaded; try { loaded = loadAdaptiveProfiles({ - workspace: deps3.workspace, + workspace: deps4.workspace, policy: runtime.adaptivePolicy, now: now52 }); @@ -82632,7 +82654,7 @@ function applyAdaptiveRanking(runtime, deps3, jobId, job, ready, routings, forec if (assessment === void 0) continue; const signature2 = assessment.signature; if (signature2 === void 0) continue; - const reliability = readTaskReliabilityState(deps3.workspace, jobId, node.nodeId); + const reliability = readTaskReliabilityState(deps4.workspace, jobId, node.nodeId); signatures.set(node.nodeId, signature2); const candidates = generateCandidates({ routing: assessment, @@ -82685,7 +82707,7 @@ function applyAdaptiveRanking(runtime, deps3, jobId, job, ready, routings, forec signatures }; } -function assessApiGapBridge(runtime, deps3, jobId, job, node, assessment, context) { +function assessApiGapBridge(runtime, deps4, jobId, job, node, assessment, context) { const apiPolicy = runtime.policy.api; const gapReason = runtime.subscriptionWorkerAvailable ? subscriptionGapReasonFor(assessment.routing.reasonCode) : "SUBSCRIPTION_WORKER_UNAVAILABLE"; if (gapReason === void 0) return void 0; @@ -82707,13 +82729,13 @@ function assessApiGapBridge(runtime, deps3, jobId, job, node, assessment, contex safetyMultiplier: apiPolicy.gap.costSafetyMultiplier }); const budget = assessApiBudget({ - state: readApiBudgetState(deps3.workspace, jobId), + state: readApiBudgetState(deps4.workspace, jobId), policy: apiPolicy.budget, taskId: node.parentTaskId, safeCostUsd: cost.safeCostUsd }); const approval = runtime.apiBinding.profileName === null ? null : checkApiSpendApproval({ - approvals: listApiSpendApprovals(deps3.workspace, jobId, { nodeId: node.nodeId }), + approvals: listApiSpendApprovals(deps4.workspace, jobId, { nodeId: node.nodeId }), nodeId: node.nodeId, taskFingerprint: taskSpendFingerprint(node), profileName: runtime.apiBinding.profileName, @@ -82737,8 +82759,8 @@ function assessApiGapBridge(runtime, deps3, jobId, job, node, assessment, contex void job; return { ...assessment, routing: applyApiGapBridge(assessment.routing, plan), apiBridge: plan }; } -function assessNode(runtime, deps3, jobId, job, node, forecast, reserve, observations) { - const attemptsUsed = localExecutorAttemptsUsed(deps3, jobId, node.nodeId); +function assessNode(runtime, deps4, jobId, job, node, forecast, reserve, observations) { + const attemptsUsed = localExecutorAttemptsUsed(deps4, jobId, node.nodeId); const stickyEscalation = job.escalations.some( (entry2) => entry2.nodeId === node.nodeId && LOCAL_ESCALATION_REASONS.includes(entry2.reason) ); @@ -82771,7 +82793,7 @@ function assessNode(runtime, deps3, jobId, job, node, forecast, reserve, observa localWorkerAvailable: runtime.localWorkerAvailable && !stickyEscalation, localExecutionAvailable: runtime.localExecutionAvailable && !stickyEscalation, localEscalationRequired: stickyEscalation || attemptsUsed >= runtime.policy.maxLocalAttempts, - contextUsageRatio: estimateNodeContextRatio(deps3, jobId, node.nodeId), + contextUsageRatio: estimateNodeContextRatio(deps4, jobId, node.nodeId), policy: runtime.policy }); const directToHarness = job.escalations.some( @@ -82784,7 +82806,7 @@ function assessNode(runtime, deps3, jobId, job, node, forecast, reserve, observa complexity: node.complexity, priorDirectFailureNeedsRepository: directToHarness }); - const reliability = readTaskReliabilityState(deps3.workspace, jobId, node.nodeId); + const reliability = readTaskReliabilityState(deps4.workspace, jobId, node.nodeId); const signature2 = buildTaskSignature({ category: suitability.category, complexity: node.complexity ?? "MEDIUM", @@ -82813,20 +82835,20 @@ function assessNode(runtime, deps3, jobId, job, node, forecast, reserve, observa }); return { suitability, estimate: estimate2, routing, shape, localExecution, signature: signature2 }; } -function runtimeResearchForJob(deps3, jobId) { - return listResearchRecords(deps3.workspace).records.filter((record32) => record32.scope?.jobId === jobId && record32.lifecycle?.phase === "RUNTIME_INVESTIGATION" && record32.report !== void 0).sort((left, right) => right.updatedAt.localeCompare(left.updatedAt)).slice(0, 3); +function runtimeResearchForJob(deps4, jobId) { + return listResearchRecords(deps4.workspace).records.filter((record32) => record32.scope?.jobId === jobId && record32.lifecycle?.phase === "RUNTIME_INVESTIGATION" && record32.report !== void 0).sort((left, right) => right.updatedAt.localeCompare(left.updatedAt)).slice(0, 3); } -function recordResearchInformedReplan(deps3, jobId, nodeId, reason3) { - const records = runtimeResearchForJob(deps3, jobId); +function recordResearchInformedReplan(deps4, jobId, nodeId, reason3) { + const records = runtimeResearchForJob(deps4, jobId); if (records.length === 0) return; - const now52 = (deps3.clock ?? (() => /* @__PURE__ */ new Date()))(); - recordResearchReplanTelemetry(deps3.workspace, now52); + const now52 = (deps4.clock ?? (() => /* @__PURE__ */ new Date()))(); + recordResearchReplanTelemetry(deps4.workspace, now52); for (const record32 of records) { recordResearchLifecycleEffect({ - workspace: deps3.workspace, - config: deps3.config, - ...deps3.clock !== void 0 ? { clock: deps3.clock } : {}, - ...deps3.idFactory !== void 0 ? { idFactory: deps3.idFactory } : {} + workspace: deps4.workspace, + config: deps4.config, + ...deps4.clock !== void 0 ? { clock: deps4.clock } : {}, + ...deps4.idFactory !== void 0 ? { idFactory: deps4.idFactory } : {} }, { researchId: record32.researchId, phase: "RUNTIME_INVESTIGATION", @@ -82835,7 +82857,7 @@ function recordResearchInformedReplan(deps3, jobId, nodeId, reason3) { usedBy: nodeId }); } - recordJobEvent(deps3, jobId, "research_replan_caused", { + recordJobEvent(deps4, jobId, "research_replan_caused", { nodeId, researchIds: records.map((record32) => record32.researchId), reason: reason3.slice(0, 500), @@ -82876,31 +82898,31 @@ ${(0, import_fs44.readFileSync)(file.path, "utf8")}`); } } var agentResultSequence = 0; -function persistAgentResult(deps3, jobId, role, raw) { +function persistAgentResult(deps4, jobId, role, raw) { agentResultSequence += 1; const name = `${Date.now()}-${String(agentResultSequence).padStart(4, "0")}-${role.toLowerCase()}.json`; try { return storeAgentResult( - deps3.workspace, + deps4.workspace, jobId, name, JSON.parse(raw), - { maxBytes: deps3.config.orchestration.jobs.maxAgentResultBytes } + { maxBytes: deps4.config.orchestration.jobs.maxAgentResultBytes } ).ref; } catch { return void 0; } } -async function driveJob(deps3, jobId, options = {}) { +async function driveJob(deps4, jobId, options = {}) { const emit22 = (kind, message2) => { options.onEvent?.({ kind, message: message2 }); }; const sleep2 = options.sleep ?? defaultSleep; const signal = options.signal; - const policy = deps3.config.orchestration.jobs; - let job = requireJobState(deps3.workspace, jobId); + const policy = deps4.config.orchestration.jobs; + let job = requireJobState(deps4.workspace, jobId); if (job.status !== "CREATED") { - const resume = await resumeJob(deps3, jobId); + const resume = await resumeJob(deps4, jobId); job = resume.job; for (const warning2 of resume.warnings) emit22("note", warning2); if (resume.finalized) { @@ -82908,26 +82930,26 @@ async function driveJob(deps3, jobId, options = {}) { } } const probeCache = { probe: void 0 }; - const localManager = createLocalManager(deps3.config, (event) => { + const localManager = createLocalManager(deps4.config, (event) => { emit22("local-model", `${event.type}: ${event.detail}`); if (event.type === "ready") { - recordJobEvent(deps3, jobId, "local_model_started", { detail: event.detail.slice(0, 200) }); + recordJobEvent(deps4, jobId, "local_model_started", { detail: event.detail.slice(0, 200) }); } if (event.type === "stopped" || event.type === "exited") { - recordJobEvent(deps3, jobId, "local_model_stopped", { + recordJobEvent(deps4, jobId, "local_model_stopped", { kind: event.type, detail: event.detail.slice(0, 200) }); } }); - const missionDriven = policy.objectives.enabled === true && findMissionForSpec(deps3.workspace, job.specName) !== void 0; - const schedulingRuntime = createSchedulingRuntime(deps3.config, deps3.workspace, { + const missionDriven = policy.objectives.enabled === true && findMissionForSpec(deps4.workspace, job.specName) !== void 0; + const schedulingRuntime = createSchedulingRuntime(deps4.config, deps4.workspace, { localManager, missionDriven, // vNext.5: whether prepaid strong compute exists at all. A roster with // no subscription worker is a different gap from an exhausted quota // window — it never "resets" — and the planner must be able to tell. - subscriptionWorkerAvailable: resolveWorkers(deps3.config).some( + subscriptionWorkerAvailable: resolveWorkers(deps4.config).some( (worker) => worker.reasoningTier !== "LOCAL_SMALL" ), options: { @@ -82945,32 +82967,32 @@ async function driveJob(deps3, jobId, options = {}) { for (; ; ) { loops += 1; if (loops > maxLoop) { - blockJob(deps3, jobId, { + blockJob(deps4, jobId, { category: "INTERNAL", code: "DRIVER_LOOP_BOUND", message: `The driver exceeded ${maxLoop} scheduling cycles without finishing; stopping for inspection.`, remediation: ["Inspect the job events; this indicates a scheduling defect, not a task failure."] }); - job = requireJobState(deps3.workspace, jobId); + job = requireJobState(deps4.workspace, jobId); return { stop: { kind: "blocked", reason: "driver loop bound reached" }, job }; } if (signal?.aborted === true) { - checkpointJob(deps3, jobId, "Interrupted; resume with `specbridge orchestrate run` to continue."); - job = requireJobState(deps3.workspace, jobId); + checkpointJob(deps4, jobId, "Interrupted; resume with `specbridge orchestrate run` to continue."); + job = requireJobState(deps4.workspace, jobId); return { stop: { kind: "interrupted" }, job }; } - const scheduleAt = (deps3.clock ?? (() => /* @__PURE__ */ new Date()))(); - job = clearRetryWait(deps3, jobId, scheduleAt); - const graph = activeGraph(deps3, job); - const workers = resolveWorkers(deps3.config); + const scheduleAt = (deps4.clock ?? (() => /* @__PURE__ */ new Date()))(); + job = clearRetryWait(deps4, jobId, scheduleAt); + const graph = activeGraph(deps4, job); + const workers = resolveWorkers(deps4.config); let lane; if (schedulingRuntime !== void 0 && graph !== void 0 && !isFinalJobStatus(job.status)) { - lane = await buildLaneContext(schedulingRuntime, deps3, jobId, job, graph); - emitSchedulingTransitions(deps3, jobId, schedulingRuntime, lane, emit22); + lane = await buildLaneContext(schedulingRuntime, deps4, jobId, job, graph); + emitSchedulingTransitions(deps4, jobId, schedulingRuntime, lane, emit22); if (lane.overtakeCandidate !== void 0 && job.status === "READY") { - promoteNodeForQuotaOvertake(deps3, jobId, lane.overtakeCandidate); + promoteNodeForQuotaOvertake(deps4, jobId, lane.overtakeCandidate); emit22("note", `quota overtake: ${lane.overtakeCandidate.detail}`); - job = requireJobState(deps3.workspace, jobId); + job = requireJobState(deps4.workspace, jobId); continue; } } @@ -82986,24 +83008,24 @@ async function driveJob(deps3, jobId, options = {}) { if (decision.kind !== "WAIT_QUOTA") unboundedQuotaDefers = 0; switch (decision.kind) { case "BUILD_GRAPH": { - const built = await buildJobGraph(deps3, jobId); + const built = await buildJobGraph(deps4, jobId); emit22("note", `Runtime graph: ${built.graph.nodes.length} node(s) from the approved task plan.`); - checkpointJob(deps3, jobId, "Graph built; classify and plan the first node."); + checkpointJob(deps4, jobId, "Graph built; classify and plan the first node."); break; } case "RUN_ROLE": { - const outcome = await handleRoleDecision(deps3, jobId, decision, { + const outcome = await handleRoleDecision(deps4, jobId, decision, { localManager, probeCache, signal, emit: emit22 }); if (outcome === "stop-interrupted") { - checkpointJob(deps3, jobId, "Interrupted during a role run; resume to continue."); - job = requireJobState(deps3.workspace, jobId); + checkpointJob(deps4, jobId, "Interrupted during a role run; resume to continue."); + job = requireJobState(deps4.workspace, jobId); return { stop: { kind: "interrupted" }, job }; } - checkpointJob(deps3, jobId, "Continue with the next scheduler decision."); + checkpointJob(deps4, jobId, "Continue with the next scheduler decision."); break; } case "DISPATCH_EXECUTOR": { @@ -83026,7 +83048,7 @@ async function driveJob(deps3, jobId, options = {}) { let quotaBefore; let contextBefore = null; if (schedulingRuntime !== void 0 && lane !== void 0 && laneName !== void 0 && laneRouting !== void 0) { - schedulingDecisionId = persistLaneDecision(deps3, jobId, { + schedulingDecisionId = persistLaneDecision(deps4, jobId, { nodeId: node.nodeId, taskId: node.parentTaskId, selectedLane: laneName, @@ -83042,7 +83064,7 @@ async function driveJob(deps3, jobId, options = {}) { } : {} }); if (laneName !== "API") { - recordJobEvent(deps3, jobId, laneName === "LOCAL" ? "task_routed_local" : "task_routed_subscription", { + recordJobEvent(deps4, jobId, laneName === "LOCAL" ? "task_routed_local" : "task_routed_subscription", { nodeId: node.nodeId, taskId: node.parentTaskId, reasonCode: laneRouting.routing.reasonCode, @@ -83052,7 +83074,7 @@ async function driveJob(deps3, jobId, options = {}) { }); } if (apiBridgedWhileMaxReturned && laneName === "SUBSCRIPTION") { - recordJobEvent(deps3, jobId, "api_next_task_returned_to_subscription", { + recordJobEvent(deps4, jobId, "api_next_task_returned_to_subscription", { nodeId: node.nodeId, taskId: node.parentTaskId, reasonCode: laneRouting.routing.reasonCode, @@ -83061,7 +83083,7 @@ async function driveJob(deps3, jobId, options = {}) { apiBridgedWhileMaxReturned = false; } if (localExecution !== void 0 && executionMode !== void 0) { - recordJobEvent(deps3, jobId, "local_execution_mode_selected", { + recordJobEvent(deps4, jobId, "local_execution_mode_selected", { nodeId: node.nodeId, taskId: node.parentTaskId, executionMode, @@ -83070,7 +83092,7 @@ async function driveJob(deps3, jobId, options = {}) { suitability: laneRouting.suitability.class }); if (executionMode === "HARNESS") { - recordJobEvent(deps3, jobId, "local_harness_selected", { + recordJobEvent(deps4, jobId, "local_harness_selected", { nodeId: node.nodeId, taskId: node.parentTaskId, profile: localExecution.harness?.profileName ?? "unknown", @@ -83079,7 +83101,7 @@ async function driveJob(deps3, jobId, options = {}) { reasonCode: localExecution.reasonCode ?? "UNKNOWN" }); } else if (localExecution.reasonCode === "LOCAL_HARNESS_NOT_VERIFIED_LOCAL") { - recordJobEvent(deps3, jobId, "local_harness_locality_rejected", { + recordJobEvent(deps4, jobId, "local_harness_locality_rejected", { nodeId: node.nodeId, taskId: node.parentTaskId, bindingStatus: schedulingRuntime?.harnessBinding.status ?? "UNKNOWN", @@ -83087,7 +83109,7 @@ async function driveJob(deps3, jobId, options = {}) { detail: (schedulingRuntime?.harnessBinding.problems[0] ?? "not verified local").slice(0, 300) }); } else if (localExecution.reasonCode === "LOCAL_HARNESS_UNAVAILABLE") { - recordJobEvent(deps3, jobId, "local_harness_unavailable", { + recordJobEvent(deps4, jobId, "local_harness_unavailable", { nodeId: node.nodeId, taskId: node.parentTaskId, bindingStatus: schedulingRuntime?.harnessBinding.status ?? "UNKNOWN", @@ -83096,7 +83118,7 @@ async function driveJob(deps3, jobId, options = {}) { } } if (laneName === "SUBSCRIPTION" && laneRouting.routing.admission?.crossesReset === true) { - recordJobEvent(deps3, jobId, "cross_reset_admitted", { + recordJobEvent(deps4, jobId, "cross_reset_admitted", { nodeId: node.nodeId, taskId: node.parentTaskId, preResetBurnRatio: laneRouting.routing.admission.preResetBurnRatio, @@ -83108,10 +83130,10 @@ async function driveJob(deps3, jobId, options = {}) { fiveHourRemainingRatio: lane.forecast.fiveHourRemainingRatio, weeklyRemainingRatio: lane.forecast.weeklyRemainingRatio }; - contextBefore = estimateNodeContextRatio(deps3, jobId, node.nodeId); + contextBefore = estimateNodeContextRatio(deps4, jobId, node.nodeId); if (decision.compactFirst === true) { - const reconstructed = reconstructTaskContext(deps3, { jobId, nodeId: node.nodeId }); - recordJobEvent(deps3, jobId, "context_compaction_before_dispatch", { + const reconstructed = reconstructTaskContext(deps4, { jobId, nodeId: node.nodeId }); + recordJobEvent(deps4, jobId, "context_compaction_before_dispatch", { nodeId: node.nodeId, contextUsageRatio: contextBefore, passes: reconstructed.assembled.compactions.map((record32) => record32.level), @@ -83135,7 +83157,7 @@ async function driveJob(deps3, jobId, options = {}) { } if (apiLane && schedulingRuntime !== void 0 && apiBridge !== void 0) { const apiPolicy = schedulingRuntime.policy.api; - recordJobEvent(deps3, jobId, "api_gap_detected", { + recordJobEvent(deps4, jobId, "api_gap_detected", { nodeId: node.nodeId, taskId: node.parentTaskId, gapReason: apiBridge.gap.reason, @@ -83147,19 +83169,19 @@ async function driveJob(deps3, jobId, options = {}) { reasonCode: apiBridge.reasonCode }); const reservation = reserveApiBudget({ - workspace: deps3.workspace, + workspace: deps4.workspace, jobId, nodeId: node.nodeId, taskId: node.parentTaskId, policy: apiPolicy.budget, safeCostUsd: apiBridge.cost?.safeCostUsd ?? null, profileName: schedulingRuntime.apiBinding.profileName, - now: (deps3.clock ?? (() => /* @__PURE__ */ new Date()))(), - reservationId: `ar-${(deps3.idFactory ?? (() => `${Date.now()}`))()}`.slice(0, 64), + now: (deps4.clock ?? (() => /* @__PURE__ */ new Date()))(), + reservationId: `ar-${(deps4.idFactory ?? (() => `${Date.now()}`))()}`.slice(0, 64), detail: apiBridge.detail }); if (!reservation.ok) { - recordJobEvent(deps3, jobId, "api_budget_exceeded", { + recordJobEvent(deps4, jobId, "api_budget_exceeded", { nodeId: node.nodeId, taskId: node.parentTaskId, refusal: reservation.admission.refusal ?? "UNKNOWN", @@ -83167,14 +83189,14 @@ async function driveJob(deps3, jobId, options = {}) { detail: reservation.admission.detail.slice(0, 300) }); if (reservation.admission.refusal === "JOB_CEILING" || reservation.admission.refusal === "JOB_ATTEMPTS") { - recordJobEvent(deps3, jobId, "api_budget_exhausted", { + recordJobEvent(deps4, jobId, "api_budget_exhausted", { jobId, refusal: reservation.admission.refusal, encumberedUsd: reservation.admission.job.encumberedUsd }); } emit22("waiting", `api budget refused: ${reservation.admission.detail}`); - job = deferJobForQuota(deps3, jobId, { + job = deferJobForQuota(deps4, jobId, { nodeId: node.nodeId, taskId: node.parentTaskId, until: apiBridge.gap.expectedAvailableAt, @@ -83183,11 +83205,11 @@ async function driveJob(deps3, jobId, options = {}) { pollMs: schedulingRuntime.policy.deferPollMs }); checkpointJob( - deps3, + deps4, jobId, "API budget refused the bridge; the task waits for subscription capacity." ); - job = requireJobState(deps3.workspace, jobId); + job = requireJobState(deps4.workspace, jobId); return { stop: { kind: "deferred", @@ -83199,7 +83221,7 @@ async function driveJob(deps3, jobId, options = {}) { } apiReservationId = reservation.reservation.reservationId; apiApprovalId = apiBridge.approval?.approval?.approvalId; - recordJobEvent(deps3, jobId, "api_budget_reserved", { + recordJobEvent(deps4, jobId, "api_budget_reserved", { nodeId: node.nodeId, taskId: node.parentTaskId, reservationId: apiReservationId, @@ -83212,7 +83234,7 @@ async function driveJob(deps3, jobId, options = {}) { `api budget reserved $${reservation.reservation.reservedUsd.toFixed(4)} for task ${node.parentTaskId}` ); } - beginExecutorDispatch(deps3, jobId, { + beginExecutorDispatch(deps4, jobId, { nodeId: decision.nodeId, mode: decision.mode, workerId: decision.worker.workerId, @@ -83231,7 +83253,7 @@ async function driveJob(deps3, jobId, options = {}) { // later should find comparable history already waiting, not start // learning from zero. ...laneRouting?.signature !== void 0 ? { taskSignature: laneRouting.signature.key } : {}, - contextStrategy: deps3.config.orchestration.jobs.context.efficiency.strategy, + contextStrategy: deps4.config.orchestration.jobs.context.efficiency.strategy, ...localExecution !== void 0 ? { executionShape: localExecution.shape, computeLocality: executionMode === "HARNESS" ? localExecution.harness?.locality ?? "UNKNOWN" : "LOCAL" @@ -83263,27 +83285,27 @@ async function driveJob(deps3, jobId, options = {}) { ...quotaBefore !== void 0 ? { quotaBefore } : {}, ...contextBefore !== null ? { contextUsageBefore: contextBefore } : {} }); - const startedAt = (deps3.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); + const startedAt = (deps4.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); if (apiLane && schedulingRuntime !== void 0 && apiBridge !== void 0) { - const attemptId = requireJobState(deps3.workspace, jobId).currentAttemptId; + const attemptId = requireJobState(deps4.workspace, jobId).currentAttemptId; if (attemptId !== void 0) { if (apiReservationId !== void 0) { bindApiBudgetReservation( - deps3.workspace, + deps4.workspace, jobId, apiReservationId, attemptId, - (deps3.clock ?? (() => /* @__PURE__ */ new Date()))() + (deps4.clock ?? (() => /* @__PURE__ */ new Date()))() ); } if (apiApprovalId !== void 0) { try { - consumeApiSpendApproval(deps3.workspace, jobId, apiApprovalId, attemptId); + consumeApiSpendApproval(deps4.workspace, jobId, apiApprovalId, attemptId); } catch { } } - writeApiHandoffCheckpoint(deps3, jobId, node, attemptId, apiBridge); - recordJobEvent(deps3, jobId, "api_task_dispatched", { + writeApiHandoffCheckpoint(deps4, jobId, node, attemptId, apiBridge); + recordJobEvent(deps4, jobId, "api_task_dispatched", { nodeId: node.nodeId, taskId: node.parentTaskId, attemptId, @@ -83301,12 +83323,12 @@ async function driveJob(deps3, jobId, options = {}) { } } const allowDirty = decision.mode === "repair" || (graph?.nodes.some((candidate) => candidate.status === "COMPLETED") ?? false) || node.attempts.some((attempt) => attempt.role === "EXECUTOR") || node.attempts.some((attempt) => attempt.role === "BUILDER"); - const mission = policy.objectives.enabled === true ? findMissionForSpec(deps3.workspace, job.specName) : void 0; + const mission = policy.objectives.enabled === true ? findMissionForSpec(deps4.workspace, job.specName) : void 0; const localHarnessLane = laneName === "LOCAL" && harnessProfileName !== void 0 && schedulingRuntime !== void 0; const localLane = laneName === "LOCAL" && !localHarnessLane && schedulingRuntime !== void 0 && schedulingRuntime.localInference !== void 0; const apiHarnessLane = apiLane && harnessProfileName !== void 0 && schedulingRuntime !== void 0; - const harnessCheckpoint = localHarnessLane || apiHarnessLane ? readLatestTaskCheckpoint(deps3.workspace, jobId, node.nodeId) : void 0; - const contextSupplement = deps3.config.orchestration.jobs.context.efficiency.strategy === "LEGACY" ? void 0 : await buildDispatchContext(deps3, { + const harnessCheckpoint = localHarnessLane || apiHarnessLane ? readLatestTaskCheckpoint(deps4.workspace, jobId, node.nodeId) : void 0; + const contextSupplement = deps4.config.orchestration.jobs.context.efficiency.strategy === "LEGACY" ? void 0 : await buildDispatchContext(deps4, { jobId, node, shape: localHarnessLane || apiHarnessLane ? "POINTER" : "MATERIALIZED", @@ -83320,9 +83342,9 @@ async function driveJob(deps3, jobId, options = {}) { // evidence pipeline, same completion authority — the only // differences are who is billed and what bounds the attempt. await dispatchApiHarnessExecution({ - workspace: deps3.workspace, - config: deps3.config, - registry: deps3.registry, + workspace: deps4.workspace, + config: deps4.config, + registry: deps4.registry, node, specName: job.specName, jobId, @@ -83342,15 +83364,15 @@ async function driveJob(deps3, jobId, options = {}) { contextPlanId: contextSupplement.planId } : {}, maxWallTimeMs: schedulingRuntime.apiBinding.maxWallTimeMs, - ...deps3.clock !== void 0 ? { clock: deps3.clock } : {}, - ...deps3.idFactory !== void 0 ? { idFactory: deps3.idFactory } : {}, + ...deps4.clock !== void 0 ? { clock: deps4.clock } : {}, + ...deps4.idFactory !== void 0 ? { idFactory: deps4.idFactory } : {}, ...signal !== void 0 ? { signal } : {}, onProgress: (message2) => emit22("note", message2) }) ) : localHarnessLane ? await dispatchLocalHarnessExecution({ - workspace: deps3.workspace, - config: deps3.config, - registry: deps3.registry, + workspace: deps4.workspace, + config: deps4.config, + registry: deps4.registry, node, specName: job.specName, jobId, @@ -83366,13 +83388,13 @@ async function driveJob(deps3, jobId, options = {}) { contextPlanId: contextSupplement.planId } : {}, maxWallTimeMs: schedulingRuntime.harnessBinding.maxWallTimeMs, - ...deps3.clock !== void 0 ? { clock: deps3.clock } : {}, - ...deps3.idFactory !== void 0 ? { idFactory: deps3.idFactory } : {}, + ...deps4.clock !== void 0 ? { clock: deps4.clock } : {}, + ...deps4.idFactory !== void 0 ? { idFactory: deps4.idFactory } : {}, ...signal !== void 0 ? { signal } : {}, onProgress: (message2) => emit22("note", message2) }) : localLane ? await dispatchLocalExecution({ - workspace: deps3.workspace, - config: deps3.config, + workspace: deps4.workspace, + config: deps4.config, node, specName: job.specName, mode: decision.mode, @@ -83385,29 +83407,29 @@ async function driveJob(deps3, jobId, options = {}) { repositoryContext: contextSupplement.rendered, contextPlanId: contextSupplement.planId } : {}, - ...deps3.clock !== void 0 ? { clock: deps3.clock } : {}, - ...deps3.idFactory !== void 0 ? { idFactory: deps3.idFactory } : {}, + ...deps4.clock !== void 0 ? { clock: deps4.clock } : {}, + ...deps4.idFactory !== void 0 ? { idFactory: deps4.idFactory } : {}, ...signal !== void 0 ? { signal } : {}, onProgress: (message2) => emit22("note", message2), - onInferenceCall: () => countLocalInferenceCall(deps3, jobId) + onInferenceCall: () => countLocalInferenceCall(deps4, jobId) }) : mission !== void 0 ? await driveObjective({ - workspace: deps3.workspace, - config: deps3.config, + workspace: deps4.workspace, + config: deps4.config, jobId, specName: job.specName, node, mission, policy, - workers: resolveWorkers(deps3.config), + workers: resolveWorkers(deps4.config), allowDirty, runnerProfile: decision.worker.runnerProfile, localManager, probeCache, - ...deps3.clock !== void 0 ? { clock: deps3.clock } : {}, - ...deps3.idFactory !== void 0 ? { idFactory: deps3.idFactory } : {}, + ...deps4.clock !== void 0 ? { clock: deps4.clock } : {}, + ...deps4.idFactory !== void 0 ? { idFactory: deps4.idFactory } : {}, ...signal !== void 0 ? { signal } : {}, - ...deps3.researchBridge !== void 0 ? { researchBridge: deps3.researchBridge } : {}, - ...deps3.secondaryObjectiveBuilder !== void 0 ? { secondaryBuilder: deps3.secondaryObjectiveBuilder } : {}, + ...deps4.researchBridge !== void 0 ? { researchBridge: deps4.researchBridge } : {}, + ...deps4.secondaryObjectiveBuilder !== void 0 ? { secondaryBuilder: deps4.secondaryObjectiveBuilder } : {}, ...lane?.forecast.schedulerMode !== void 0 ? { schedulerMode: lane.forecast.schedulerMode } : {}, ...lane?.forecast !== void 0 ? { strongResource: strongResourceFromScheduler({ @@ -83419,37 +83441,37 @@ async function driveJob(deps3, jobId, options = {}) { }) } : {}, onProgress: (message2) => emit22("note", message2), - countWorkerRun: (run) => recordObjectiveWorkerAttempt(deps3, jobId, { nodeId: node.nodeId, ...run }), - recordEvent: (type, payload) => recordJobEvent(deps3, jobId, type, payload) + countWorkerRun: (run) => recordObjectiveWorkerAttempt(deps4, jobId, { nodeId: node.nodeId, ...run }), + recordEvent: (type, payload) => recordJobEvent(deps4, jobId, type, payload) }) : await dispatchExecutor({ - workspace: deps3.workspace, - config: deps3.config, - registry: deps3.registry, + workspace: deps4.workspace, + config: deps4.config, + registry: deps4.registry, node, specName: job.specName, mode: decision.mode, allowDirty, runnerProfile: decision.worker.runnerProfile, ...options.executorTimeoutMs !== void 0 ? { timeoutMs: options.executorTimeoutMs } : {}, - ...deps3.clock !== void 0 ? { clock: deps3.clock } : {}, - ...deps3.idFactory !== void 0 ? { idFactory: deps3.idFactory } : {}, + ...deps4.clock !== void 0 ? { clock: deps4.clock } : {}, + ...deps4.idFactory !== void 0 ? { idFactory: deps4.idFactory } : {}, ...signal !== void 0 ? { signal } : {}, onProgress: (message2) => emit22("note", message2) }); const objectiveResourceWait = mission !== void 0 ? dispatch.resourceWait : void 0; if (objectiveResourceWait !== void 0) { - yieldExecutorForResourceWait(deps3, jobId, { + yieldExecutorForResourceWait(deps4, jobId, { nodeId: node.nodeId, detail: objectiveResourceWait.detail }); - job = enterResourceWait(deps3, jobId, { + job = enterResourceWait(deps4, jobId, { kind: objectiveResourceWait.kind, detail: objectiveResourceWait.detail, ...objectiveResourceWait.wakeAt !== void 0 ? { wakeAt: objectiveResourceWait.wakeAt } : {}, nodeId: node.nodeId }); checkpointJob( - deps3, + deps4, jobId, `Waiting for Strong resource recovery; ${objectiveResourceWait.waitingWorkUnitIds.length} WorkUnit(s) remain durably READY.` ); @@ -83469,7 +83491,7 @@ async function driveJob(deps3, jobId, options = {}) { if (localLane) { const localResult = dispatch; if (localResult.failure !== void 0) { - recordJobEvent(deps3, jobId, "local_attempt_failed", { + recordJobEvent(deps4, jobId, "local_attempt_failed", { nodeId: node.nodeId, taskId: node.parentTaskId, category: localResult.failure.category, @@ -83477,29 +83499,29 @@ async function driveJob(deps3, jobId, options = {}) { executionMode: "DIRECT_MODEL" }); } - const harnessCanTakeOver = schedulingRuntime !== void 0 && schedulingRuntime.harnessBinding.available && schedulingRuntime.policy.localExecution.strategy !== "DIRECT_ONLY" && localExecutorAttemptsUsed(deps3, jobId, node.nodeId) < schedulingRuntime.policy.maxLocalAttempts; + const harnessCanTakeOver = schedulingRuntime !== void 0 && schedulingRuntime.harnessBinding.available && schedulingRuntime.policy.localExecution.strategy !== "DIRECT_ONLY" && localExecutorAttemptsUsed(deps4, jobId, node.nodeId) < schedulingRuntime.policy.maxLocalAttempts; const needsRepositoryTools = localResult.failure !== void 0 && directFailureNeedsRepositoryTools(localResult); if (harnessCanTakeOver && needsRepositoryTools) { - noteEscalation(deps3, jobId, { + noteEscalation(deps4, jobId, { nodeId: node.nodeId, role: "EXECUTOR", reason: "LOCAL_DIRECT_TO_HARNESS", detail: (localResult.escalationReason ?? localResult.failure?.message ?? "the direct attempt lacked repository knowledge").slice(0, 500) }); - recordJobEvent(deps3, jobId, "local_direct_to_harness_escalated", { + recordJobEvent(deps4, jobId, "local_direct_to_harness_escalated", { nodeId: node.nodeId, taskId: node.parentTaskId, category: localResult.failure?.category ?? "unknown", detail: (localResult.escalationReason ?? "the direct attempt lacked repository knowledge").slice(0, 300) }); } else if (localResult.escalated) { - noteEscalation(deps3, jobId, { + noteEscalation(deps4, jobId, { nodeId: node.nodeId, role: "EXECUTOR", reason: "LOCAL_EXECUTION_ESCALATED", detail: (localResult.escalationReason ?? localResult.failure?.message ?? "local execution declined").slice(0, 500) }); - recordJobEvent(deps3, jobId, "local_escalation_triggered", { + recordJobEvent(deps4, jobId, "local_escalation_triggered", { nodeId: node.nodeId, taskId: node.parentTaskId, detail: (localResult.escalationReason ?? "bounded local attempts exhausted").slice(0, 300) @@ -83509,7 +83531,7 @@ async function driveJob(deps3, jobId, options = {}) { if (localHarnessLane) { const harnessResult = dispatch; if (harnessResult.failure !== void 0) { - recordJobEvent(deps3, jobId, "local_attempt_failed", { + recordJobEvent(deps4, jobId, "local_attempt_failed", { nodeId: node.nodeId, taskId: node.parentTaskId, category: harnessResult.failure.category, @@ -83518,23 +83540,23 @@ async function driveJob(deps3, jobId, options = {}) { failureKind: harnessResult.failureKind ?? "UNKNOWN" }); } - const localAttemptsAfter = localExecutorAttemptsUsed(deps3, jobId, node.nodeId) + 1; + const localAttemptsAfter = localExecutorAttemptsUsed(deps4, jobId, node.nodeId) + 1; const budgetSpent = schedulingRuntime !== void 0 && localAttemptsAfter >= schedulingRuntime.policy.maxLocalAttempts; const intelligenceFailure = harnessResult.failure !== void 0 && harnessResult.failureKind === "INTELLIGENCE"; if (intelligenceFailure && (harnessResult.escalated || budgetSpent)) { - noteEscalation(deps3, jobId, { + noteEscalation(deps4, jobId, { nodeId: node.nodeId, role: "EXECUTOR", reason: "LOCAL_EXECUTION_ESCALATED", detail: (harnessResult.escalationReason ?? harnessResult.failure?.message ?? "the local harness could not implement the task").slice(0, 500) }); - recordJobEvent(deps3, jobId, "local_harness_to_subscription_escalated", { + recordJobEvent(deps4, jobId, "local_harness_to_subscription_escalated", { nodeId: node.nodeId, taskId: node.parentTaskId, localAttempts: localAttemptsAfter, detail: (harnessResult.escalationReason ?? "local harness attempts exhausted").slice(0, 300) }); - recordJobEvent(deps3, jobId, "local_escalation_triggered", { + recordJobEvent(deps4, jobId, "local_escalation_triggered", { nodeId: node.nodeId, taskId: node.parentTaskId, detail: "the local harness did not produce a verifiable implementation" @@ -83547,7 +83569,7 @@ async function driveJob(deps3, jobId, options = {}) { extraMetrics = { fiveHourQuotaAfter: after.fiveHour?.remainingRatio ?? null, weeklyQuotaAfter: after.weekly?.remainingRatio ?? null, - contextUsageAfter: estimateNodeContextRatio(deps3, jobId, node.nodeId) + contextUsageAfter: estimateNodeContextRatio(deps4, jobId, node.nodeId) }; } if (localHarnessLane || apiHarnessLane) { @@ -83581,19 +83603,19 @@ async function driveJob(deps3, jobId, options = {}) { }; if (apiReservationId !== void 0) { const reconciled = reconcileApiBudget({ - workspace: deps3.workspace, + workspace: deps4.workspace, jobId, reservationId: apiReservationId, observedCostUsd: observedCost.costUsd, costSource: observedCost.source, - now: (deps3.clock ?? (() => /* @__PURE__ */ new Date()))(), + now: (deps4.clock ?? (() => /* @__PURE__ */ new Date()))(), detail: observedCost.detail }); const summary = summarizeApiBudget( - readApiBudgetState(deps3.workspace, jobId), + readApiBudgetState(deps4.workspace, jobId), schedulingRuntime.policy.api.budget ); - recordJobEvent(deps3, jobId, "api_budget_reconciled", { + recordJobEvent(deps4, jobId, "api_budget_reconciled", { nodeId: node.nodeId, taskId: node.parentTaskId, reservationId: apiReservationId, @@ -83605,7 +83627,7 @@ async function driveJob(deps3, jobId, options = {}) { remainingUsd: summary.remainingUsd }); if (observedCost.costUsd === null) { - recordJobEvent(deps3, jobId, "api_cost_unknown", { + recordJobEvent(deps4, jobId, "api_cost_unknown", { nodeId: node.nodeId, taskId: node.parentTaskId, reservationId: apiReservationId, @@ -83618,7 +83640,7 @@ async function driveJob(deps3, jobId, options = {}) { ); } if (apiResult.failure !== void 0) { - recordJobEvent(deps3, jobId, "api_attempt_failed", { + recordJobEvent(deps4, jobId, "api_attempt_failed", { nodeId: node.nodeId, taskId: node.parentTaskId, category: apiResult.failure.category, @@ -83630,7 +83652,7 @@ async function driveJob(deps3, jobId, options = {}) { const fiveHourBack = (after.fiveHour?.remainingRatio ?? 0) > schedulingRuntime.policy.fiveHourExhaustedRatio; const weeklyBack = (after.weekly?.remainingRatio ?? 0) > schedulingRuntime.policy.weeklyExhaustedRatio; if (fiveHourBack && weeklyBack) { - recordJobEvent(deps3, jobId, "api_max_returned", { + recordJobEvent(deps4, jobId, "api_max_returned", { nodeId: node.nodeId, taskId: node.parentTaskId, fiveHourRemainingRatio: after.fiveHour?.remainingRatio ?? null, @@ -83640,11 +83662,11 @@ async function driveJob(deps3, jobId, options = {}) { apiBridgedWhileMaxReturned = true; } } - const acceptanceCriteria = resolveAcceptanceCriteria(deps3, jobId, job.specName, node.nodeId); + const acceptanceCriteria = resolveAcceptanceCriteria(deps4, jobId, job.specName, node.nodeId); const dispatchVerification = dispatch.verification; const reliabilityInput = { ...buildReliabilityInput({ - deps: deps3, + deps: deps4, jobId, dispatch, lane: laneName, @@ -83669,7 +83691,7 @@ async function driveJob(deps3, jobId, options = {}) { ...acceptanceCriteria.length > 0 ? { acceptanceCriteria, criteriaEvidence: buildCriteriaEvidence({ - workspaceRoot: deps3.workspace.rootDir, + workspaceRoot: deps4.workspace.rootDir, changedPaths: (dispatch.changedFiles ?? []).map((file) => file.path), verifierResults: new Map( (dispatchVerification?.commands ?? []).map((command) => [ @@ -83680,7 +83702,7 @@ async function driveJob(deps3, jobId, options = {}) { }) } : {} }; - const result = completeExecutorDispatch(deps3, jobId, { + const result = completeExecutorDispatch(deps4, jobId, { context: { nodeId: decision.nodeId, role: "EXECUTOR", @@ -83707,12 +83729,12 @@ async function driveJob(deps3, jobId, options = {}) { `task ${decision.taskId}: ${dispatch.evidenceStatus ?? dispatch.failure?.category ?? "unknown"} \u2192 ${result.nextAction}` ); checkpointJob( - deps3, + deps4, jobId, result.nextAction === "job-complete" ? "Job complete." : `Executor outcome ${result.nextAction}; continue with the next scheduler decision.` ); if (result.nextAction === "job-complete") { - job = requireJobState(deps3.workspace, jobId); + job = requireJobState(deps4.workspace, jobId); return { stop: { kind: "completed" }, job }; } break; @@ -83725,7 +83747,7 @@ async function driveJob(deps3, jobId, options = {}) { } case "WAIT_QUOTA": { if (schedulingRuntime !== void 0 && lane !== void 0) { - persistLaneDecision(deps3, jobId, { + persistLaneDecision(deps4, jobId, { nodeId: decision.nodeId, taskId: decision.taskId, selectedLane: decision.awaitingApiApproval === true ? "REQUIRE_APPROVAL" : "DEFER", @@ -83737,9 +83759,9 @@ async function driveJob(deps3, jobId, options = {}) { lane, apiBinding: schedulingRuntime.apiBinding }); - recordApiGapObservations(deps3, jobId, schedulingRuntime, decision, graph, emit22); + recordApiGapObservations(deps4, jobId, schedulingRuntime, decision, graph, emit22); } - job = deferJobForQuota(deps3, jobId, { + job = deferJobForQuota(deps4, jobId, { nodeId: decision.nodeId, taskId: decision.taskId, until: decision.until, @@ -83748,7 +83770,7 @@ async function driveJob(deps3, jobId, options = {}) { pollMs: schedulingRuntime?.policy.deferPollMs ?? 6e4 }); emit22("waiting", `quota: ${decision.reasonCode} \u2014 ${decision.reason}`); - const nowMs = (deps3.clock ?? (() => /* @__PURE__ */ new Date()))().getTime(); + const nowMs = (deps4.clock ?? (() => /* @__PURE__ */ new Date()))().getTime(); const waitMs = Math.max(0, Date.parse(job.retryAt ?? new Date(nowMs).toISOString()) - nowMs); const holdMs = schedulingRuntime?.policy.maxQuotaHoldMs ?? 6e5; unboundedQuotaDefers = decision.until === null ? unboundedQuotaDefers + 1 : 0; @@ -83756,8 +83778,8 @@ async function driveJob(deps3, jobId, options = {}) { await sleep2(waitMs, signal); break; } - checkpointJob(deps3, jobId, `Deferred for subscription quota until ${job.retryAt ?? "unknown"}; resume to continue.`); - job = requireJobState(deps3.workspace, jobId); + checkpointJob(deps4, jobId, `Deferred for subscription quota until ${job.retryAt ?? "unknown"}; resume to continue.`); + job = requireJobState(deps4.workspace, jobId); return { stop: { kind: "deferred", until: job.retryAt ?? null, reason: decision.reason }, job @@ -83765,26 +83787,26 @@ async function driveJob(deps3, jobId, options = {}) { } case "AWAIT_HUMAN": { checkpointJob( - deps3, + deps4, jobId, decision.what === "plan-review" ? "Review the pending plan, then resume the job." : decision.what === "authority" ? "Decide the open authority question, then resume the job." : "Answer the open clarification question(s), then resume the job." ); - job = requireJobState(deps3.workspace, jobId); + job = requireJobState(deps4.workspace, jobId); return { stop: { kind: "needs-human", what: decision.what, detail: decision.reason }, job }; } case "JOB_COMPLETE": { - job = completeJobIfDone(deps3, jobId); + job = completeJobIfDone(deps4, jobId); if (job.status !== "COMPLETED") { - checkpointJob(deps3, jobId, "Contract closure decides what remains."); + checkpointJob(deps4, jobId, "Contract closure decides what remains."); return { stop: { kind: "final", status: job.status }, job }; } - checkpointJob(deps3, jobId, "Job complete."); + checkpointJob(deps4, jobId, "Job complete."); return { stop: { kind: "completed" }, job }; } case "JOB_BLOCKED": { - job = requireJobState(deps3.workspace, jobId); + job = requireJobState(deps4.workspace, jobId); if (job.status !== "BLOCKED") { - blockJob(deps3, jobId, { + blockJob(deps4, jobId, { category: decision.budget !== void 0 ? "BUDGET_EXHAUSTED" : "BLOCKED_DEPENDENCY", code: decision.budget ?? "BLOCKED", message: decision.reason, @@ -83794,12 +83816,12 @@ async function driveJob(deps3, jobId, options = {}) { ] }); } - checkpointJob(deps3, jobId, "Blocked; an explicit user action is required."); - job = requireJobState(deps3.workspace, jobId); + checkpointJob(deps4, jobId, "Blocked; an explicit user action is required."); + job = requireJobState(deps4.workspace, jobId); return { stop: { kind: "blocked", reason: decision.reason }, job }; } case "JOB_FINAL": { - job = requireJobState(deps3.workspace, jobId); + job = requireJobState(deps4.workspace, jobId); return { stop: { kind: "final", status: job.status }, job }; } } @@ -83808,11 +83830,11 @@ async function driveJob(deps3, jobId, options = {}) { await localManager?.stop("driver exit"); } } -function resolveAcceptanceCriteria(deps3, jobId, specName, nodeId) { +function resolveAcceptanceCriteria(deps4, jobId, specName, nodeId) { const criteria = []; - const mission = findMissionForSpec(deps3.workspace, specName); + const mission = findMissionForSpec(deps4.workspace, specName); if (mission !== void 0) { - for (const contract of readContractRegistry(deps3.workspace, mission.missionId)) { + for (const contract of readContractRegistry(deps4.workspace, mission.missionId)) { for (const invariant of contract.invariants) { for (const [index, pattern] of invariant.guardPatterns.entries()) { criteria.push({ @@ -83824,7 +83846,7 @@ function resolveAcceptanceCriteria(deps3, jobId, specName, nodeId) { } } } - const checkpoint = readLatestTaskCheckpoint(deps3.workspace, jobId, nodeId); + const checkpoint = readLatestTaskCheckpoint(deps4.workspace, jobId, nodeId); for (const [index, statement] of (checkpoint?.pinned.acceptanceCriteria ?? []).entries()) { criteria.push({ id: `AC-${index + 1}`, text: statement.slice(0, 2e3) }); } @@ -83901,11 +83923,11 @@ function directFailureNeedsRepositoryTools(result) { } return failure3.category === "CAPABILITY_UNAVAILABLE" && result.escalationReason !== void 0; } -function writeApiHandoffCheckpoint(deps3, jobId, node, attemptId, bridge) { +function writeApiHandoffCheckpoint(deps4, jobId, node, attemptId, bridge) { try { - const previous = readLatestTaskCheckpoint(deps3.workspace, jobId, node.nodeId); + const previous = readLatestTaskCheckpoint(deps4.workspace, jobId, node.nodeId); createTaskCheckpoint( - { workspace: deps3.workspace, clock: deps3.clock, idFactory: deps3.idFactory }, + { workspace: deps4.workspace, clock: deps4.clock, idFactory: deps4.idFactory }, { jobId, nodeId: node.nodeId, @@ -83933,11 +83955,11 @@ function writeApiHandoffCheckpoint(deps3, jobId, node, attemptId, bridge) { } catch { } } -function recordApiGapObservations(deps3, jobId, runtime, decision, graph, emit22) { +function recordApiGapObservations(deps4, jobId, runtime, decision, graph, emit22) { const bridge = decision.laneRouting?.apiBridge; if (bridge === void 0) return; - const now52 = (deps3.clock ?? (() => /* @__PURE__ */ new Date()))(); - recordJobEvent(deps3, jobId, "api_gap_detected", { + const now52 = (deps4.clock ?? (() => /* @__PURE__ */ new Date()))(); + recordJobEvent(deps4, jobId, "api_gap_detected", { nodeId: decision.nodeId, taskId: decision.taskId, gapReason: bridge.gap.reason, @@ -83949,7 +83971,7 @@ function recordApiGapObservations(deps3, jobId, runtime, decision, graph, emit22 reasonCode: bridge.reasonCode }); if (bridge.reasonCode === "API_GAP_SHORT_DEFER" || bridge.reasonCode === "API_WASTEFUL_NEAR_RESET") { - recordJobEvent(deps3, jobId, "api_gap_short_deferred", { + recordJobEvent(deps4, jobId, "api_gap_short_deferred", { nodeId: decision.nodeId, taskId: decision.taskId, estimatedGapDurationMs: bridge.gap.timeUntilAvailableMs, @@ -83957,14 +83979,14 @@ function recordApiGapObservations(deps3, jobId, runtime, decision, graph, emit22 }); } if (bridge.reasonCode === "API_COST_UNKNOWN") { - recordJobEvent(deps3, jobId, "api_cost_unknown", { + recordJobEvent(deps4, jobId, "api_cost_unknown", { nodeId: decision.nodeId, taskId: decision.taskId, detail: (bridge.cost?.detail ?? bridge.detail).slice(0, 300) }); } if (bridge.reasonCode === "API_BUDGET_EXCEEDED") { - recordJobEvent(deps3, jobId, "api_budget_exceeded", { + recordJobEvent(deps4, jobId, "api_budget_exceeded", { nodeId: decision.nodeId, taskId: decision.taskId, refusal: bridge.budget?.refusal ?? "UNKNOWN", @@ -83980,7 +84002,7 @@ function recordApiGapObservations(deps3, jobId, runtime, decision, graph, emit22 const safeCost = bridge.cost?.safeCostUsd; if (safeCost === null || safeCost === void 0) return; const requested = requestApiSpendApproval({ - workspace: deps3.workspace, + workspace: deps4.workspace, jobId, nodeId: node.nodeId, taskId: node.parentTaskId, @@ -83989,12 +84011,12 @@ function recordApiGapObservations(deps3, jobId, runtime, decision, graph, emit22 maxAuthorizedCostUsd: safeCost, estimatedCostUsd: bridge.cost?.estimatedCostUsd ?? null, rationale: bridge.detail, - approvalId: `aa-${(deps3.idFactory ?? (() => `${Date.now()}`))()}`.slice(0, 64), + approvalId: `aa-${(deps4.idFactory ?? (() => `${Date.now()}`))()}`.slice(0, 64), now: now52, ttlMs: runtime.policy.api.gap.approvalTtlMs }); if (!requested.created) return; - recordJobEvent(deps3, jobId, "api_approval_required", { + recordJobEvent(deps4, jobId, "api_approval_required", { nodeId: node.nodeId, taskId: node.parentTaskId, approvalId: requested.approval.approvalId, @@ -84011,13 +84033,13 @@ function recordApiGapObservations(deps3, jobId, runtime, decision, graph, emit22 `api spend approval required (${requested.approval.approvalId}): up to $${safeCost.toFixed(4)} on "${profileName}" for task ${node.parentTaskId}` ); } -function persistLaneDecision(deps3, jobId, input) { - const createdAt = (deps3.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); - const decisionId = `sd-${(deps3.idFactory ?? (() => `${Date.now()}`))()}`.slice(0, 64); +function persistLaneDecision(deps4, jobId, input) { + const createdAt = (deps4.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); + const decisionId = `sd-${(deps4.idFactory ?? (() => `${Date.now()}`))()}`.slice(0, 64); const routing = input.laneRouting; try { appendSchedulingDecision( - deps3.workspace, + deps4.workspace, { schemaVersion: "1.0.0", decisionId, @@ -84043,7 +84065,7 @@ function persistLaneDecision(deps3, jobId, input) { preResetBurnRatio: routing?.routing.admission?.preResetBurnRatio ?? null, crossesReset: routing?.routing.admission?.crossesReset ?? false, contextStatus: routing !== void 0 ? { - usageRatio: estimateNodeContextRatio(deps3, jobId, input.nodeId), + usageRatio: estimateNodeContextRatio(deps4, jobId, input.nodeId), compactFirst: routing.routing.compactFirst } : null, localExecution: routing?.localExecution?.mode != null && routing.localExecution.reasonCode !== null ? { @@ -84065,7 +84087,7 @@ function persistLaneDecision(deps3, jobId, input) { // ones where it declined to spend. apiBridge: routing?.apiBridge !== void 0 ? { decision: routing.apiBridge.decision, - spendMode: deps3.config.orchestration.jobs.scheduler.api.spendMode, + spendMode: deps4.config.orchestration.jobs.scheduler.api.spendMode, gapReason: routing.apiBridge.gap.reason, subscriptionAvailableAt: routing.apiBridge.gap.expectedAvailableAt, estimatedGapDurationMs: routing.apiBridge.gap.timeUntilAvailableMs, @@ -84094,11 +84116,11 @@ function persistLaneDecision(deps3, jobId, input) { detail: input.detail.slice(0, 2e3), createdAt }, - { maxRecords: deps3.config.orchestration.jobs.scheduler.maxDecisionRecords } + { maxRecords: deps4.config.orchestration.jobs.scheduler.maxDecisionRecords } ); } catch { } - recordJobEvent(deps3, jobId, "scheduling_decision_created", { + recordJobEvent(deps4, jobId, "scheduling_decision_created", { decisionId, nodeId: input.nodeId, taskId: input.taskId, @@ -84108,14 +84130,14 @@ function persistLaneDecision(deps3, jobId, input) { ...input.deferUntil !== null ? { deferUntil: input.deferUntil } : {} }); if (routing !== void 0) { - recordJobEvent(deps3, jobId, "local_suitability_classified", { + recordJobEvent(deps4, jobId, "local_suitability_classified", { nodeId: input.nodeId, taskId: input.taskId, suitability: routing.suitability.class, category: routing.suitability.category, signals: routing.suitability.signals.slice(0, 5).map((signal) => signal.signal) }); - recordJobEvent(deps3, jobId, "workload_estimated", { + recordJobEvent(deps4, jobId, "workload_estimated", { nodeId: input.nodeId, taskId: input.taskId, expectedWallTimeMs: routing.estimate.expectedWallTimeMs, @@ -84125,7 +84147,7 @@ function persistLaneDecision(deps3, jobId, input) { basis: routing.estimate.basis }); } - persistAdaptiveDecision(deps3, jobId, { + persistAdaptiveDecision(deps4, jobId, { nodeId: input.nodeId, taskId: input.taskId, heuristicLane: input.selectedLane, @@ -84136,7 +84158,7 @@ function persistLaneDecision(deps3, jobId, input) { }); return decisionId; } -function persistAdaptiveDecision(deps3, jobId, input) { +function persistAdaptiveDecision(deps4, jobId, input) { const adaptive = input.lane.adaptive; if (adaptive === void 0) return; const ranking = adaptive.rankings.get(input.nodeId); @@ -84144,7 +84166,7 @@ function persistAdaptiveDecision(deps3, jobId, input) { if (ranking === void 0 || signature2 === void 0) return; try { appendAdaptiveDecision( - deps3.workspace, + deps4.workspace, { schemaVersion: ADAPTIVE_DECISION_SCHEMA_VERSION, decisionId: `ad-${input.decisionId}`.slice(0, 200), @@ -84236,11 +84258,11 @@ function persistAdaptiveDecision(deps3, jobId, input) { profileBuiltAt: adaptive.profiles.builtAt, createdAt: input.createdAt }, - { maxRecords: deps3.config.orchestration.jobs.scheduler.adaptive.maxDecisionRecords } + { maxRecords: deps4.config.orchestration.jobs.scheduler.adaptive.maxDecisionRecords } ); } catch { } - recordJobEvent(deps3, jobId, "adaptive_prediction_created", { + recordJobEvent(deps4, jobId, "adaptive_prediction_created", { nodeId: input.nodeId, taskId: input.taskId, mode: ranking.mode, @@ -84251,7 +84273,7 @@ function persistAdaptiveDecision(deps3, jobId, input) { }); for (const veto of ranking.vetoes) { if (veto.code === "LANE_NOT_ELIGIBLE") continue; - recordJobEvent(deps3, jobId, "adaptive_candidate_vetoed", { + recordJobEvent(deps4, jobId, "adaptive_candidate_vetoed", { nodeId: input.nodeId, taskId: input.taskId, candidateId: veto.candidateId, @@ -84260,7 +84282,7 @@ function persistAdaptiveDecision(deps3, jobId, input) { } const drifting = ranking.ranked.filter((entry2) => entry2.prediction.drift.detected); for (const entry2 of drifting) { - recordJobEvent(deps3, jobId, "adaptive_drift_detected", { + recordJobEvent(deps4, jobId, "adaptive_drift_detected", { nodeId: input.nodeId, candidateId: entry2.prediction.candidate.candidateId, signals: entry2.prediction.drift.signals, @@ -84268,7 +84290,7 @@ function persistAdaptiveDecision(deps3, jobId, input) { }); } if (ranking.adaptiveApplied) { - recordJobEvent(deps3, jobId, "adaptive_candidate_selected", { + recordJobEvent(deps4, jobId, "adaptive_candidate_selected", { nodeId: input.nodeId, taskId: input.taskId, selected: ranking.selectedCandidate?.candidateId ?? null, @@ -84279,7 +84301,7 @@ function persistAdaptiveDecision(deps3, jobId, input) { return; } if (ranking.mode === "SHADOW" && ranking.disagreement) { - recordJobEvent(deps3, jobId, "adaptive_shadow_disagreement", { + recordJobEvent(deps4, jobId, "adaptive_shadow_disagreement", { nodeId: input.nodeId, taskId: input.taskId, executed: ranking.heuristicCandidate?.candidateId ?? null, @@ -84290,7 +84312,7 @@ function persistAdaptiveDecision(deps3, jobId, input) { return; } if (ranking.fallbackReason !== null && ranking.fallbackReason !== "AGREES_WITH_HEURISTIC") { - recordJobEvent(deps3, jobId, "adaptive_fallback_to_heuristic", { + recordJobEvent(deps4, jobId, "adaptive_fallback_to_heuristic", { nodeId: input.nodeId, taskId: input.taskId, reason: ranking.fallbackReason, @@ -84298,10 +84320,10 @@ function persistAdaptiveDecision(deps3, jobId, input) { }); } } -function emitSchedulingTransitions(deps3, jobId, runtime, lane, emit22) { +function emitSchedulingTransitions(deps4, jobId, runtime, lane, emit22) { const forecast = lane.forecast; if (runtime.lastObservedAt !== forecast.observedAt) { - recordJobEvent(deps3, jobId, "quota_snapshot_updated", { + recordJobEvent(deps4, jobId, "quota_snapshot_updated", { fiveHourRemainingRatio: forecast.fiveHourRemainingRatio, weeklyRemainingRatio: forecast.weeklyRemainingRatio, fiveHourResetAt: forecast.fiveHourResetAt, @@ -84313,7 +84335,7 @@ function emitSchedulingTransitions(deps3, jobId, runtime, lane, emit22) { } if (runtime.lastFreshness !== forecast.telemetryFreshness) { if (forecast.telemetryFreshness === "STALE") { - recordJobEvent(deps3, jobId, "quota_telemetry_stale", { + recordJobEvent(deps4, jobId, "quota_telemetry_stale", { observedAt: forecast.observedAt, staleThresholdMs: runtime.policy.telemetryStaleMs }); @@ -84323,7 +84345,7 @@ function emitSchedulingTransitions(deps3, jobId, runtime, lane, emit22) { } if (runtime.lastMode !== forecast.schedulerMode) { if (runtime.lastMode !== void 0) { - recordJobEvent(deps3, jobId, "scheduler_mode_changed", { + recordJobEvent(deps4, jobId, "scheduler_mode_changed", { from: runtime.lastMode, to: forecast.schedulerMode, fiveHourRemainingRatio: forecast.fiveHourRemainingRatio, @@ -84332,16 +84354,16 @@ function emitSchedulingTransitions(deps3, jobId, runtime, lane, emit22) { }); } if (forecast.schedulerMode === "HARVEST") { - recordJobEvent(deps3, jobId, "harvest_entered", { + recordJobEvent(deps4, jobId, "harvest_entered", { fiveHourRemainingRatio: forecast.fiveHourRemainingRatio, timeToFiveHourResetMs: forecast.timeToFiveHourResetMs, reserveRatio: lane.reserve.ratio }); } else if (runtime.lastMode === "HARVEST") { - recordJobEvent(deps3, jobId, "harvest_exited", { to: forecast.schedulerMode }); + recordJobEvent(deps4, jobId, "harvest_exited", { to: forecast.schedulerMode }); } if (forecast.schedulerMode === "EXHAUSTED_5H" || forecast.schedulerMode === "EXHAUSTED_WEEKLY") { - recordJobEvent(deps3, jobId, "quota_exhausted", { + recordJobEvent(deps4, jobId, "quota_exhausted", { window: forecast.schedulerMode === "EXHAUSTED_5H" ? "five-hour" : "weekly", resetAt: forecast.schedulerMode === "EXHAUSTED_5H" ? forecast.fiveHourResetAt : forecast.weeklyResetAt }); @@ -84352,7 +84374,7 @@ function emitSchedulingTransitions(deps3, jobId, runtime, lane, emit22) { const reserveDelta = runtime.lastReserveRatio === void 0 ? Number.POSITIVE_INFINITY : Math.abs(lane.reserve.ratio - runtime.lastReserveRatio); if (reserveDelta >= 0.05) { if (runtime.lastReserveRatio !== void 0) { - recordJobEvent(deps3, jobId, "dynamic_reserve_changed", { + recordJobEvent(deps4, jobId, "dynamic_reserve_changed", { from: runtime.lastReserveRatio, to: lane.reserve.ratio, timeComponent: lane.reserve.basis.timeComponent, @@ -84363,18 +84385,18 @@ function emitSchedulingTransitions(deps3, jobId, runtime, lane, emit22) { runtime.lastReserveRatio = lane.reserve.ratio; } } -async function handleRoleDecision(deps3, jobId, decision, runtime) { - const policy = deps3.config.orchestration.jobs; +async function handleRoleDecision(deps4, jobId, decision, runtime) { + const policy = deps4.config.orchestration.jobs; const role = decision.role; - const job = requireJobState(deps3.workspace, jobId); - const graph = activeGraph(deps3, job); + const job = requireJobState(deps4.workspace, jobId); + const graph = activeGraph(deps4, job); const node = graph !== void 0 ? findNode(graph, decision.nodeId) : void 0; if (node === void 0) { throw new OrchestrationError("SBO031", `Node ${decision.nodeId} vanished between scheduling and the role run.`); } if (decision.escalation !== void 0) { if (!escalationAllowed(policy) && decision.worker.costTier === "PAID") { - askClarification(deps3, jobId, [ + askClarification(deps4, jobId, [ { question: `Escalate ${role} for task ${node.parentTaskId} to the paid large agent? (${decision.escalation.detail})`, whyItMatters: "Escalation mode is manual; paid reasoning needs an explicit decision.", @@ -84383,7 +84405,7 @@ async function handleRoleDecision(deps3, jobId, decision, runtime) { ]); return "continue"; } - noteEscalation(deps3, jobId, { + noteEscalation(deps4, jobId, { nodeId: node.nodeId, role, reason: decision.escalation.reason, @@ -84391,26 +84413,26 @@ async function handleRoleDecision(deps3, jobId, decision, runtime) { }); } if (role === "PLANNER" && job.status === "READY") { - beginPlanning(deps3, jobId, node.nodeId); + beginPlanning(deps4, jobId, node.nodeId); } - recordJobEvent(deps3, jobId, "worker_selected", { + recordJobEvent(deps4, jobId, "worker_selected", { nodeId: node.nodeId, role, workerId: decision.worker.workerId, tier: decision.worker.reasoningTier }); - const startedAt = (deps3.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); - const specExcerpt = specExcerptFor(deps3.workspace, job.specName, 12e3); + const startedAt = (deps4.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); + const specExcerpt = specExcerptFor(deps4.workspace, job.specName, 12e3); const packetBase = { specName: job.specName, taskId: node.parentTaskId, taskTitle: node.title, specExcerpt }; - const activePlan = readActivePlan(deps3, jobId, node); - const packet = buildPacketFor(deps3, jobId, role, packetBase, node, activePlan, job); + const activePlan = readActivePlan(deps4, jobId, node); + const packet = buildPacketFor(deps4, jobId, role, packetBase, node, activePlan, job); runtime.emit("role-started", `${role} for task ${node.parentTaskId} on ${decision.worker.workerId}`); - const result = await runRole(deps3, jobId, role, decision, packet, runtime); + const result = await runRole(deps4, jobId, role, decision, packet, runtime); if (!result.ok) { if (result.kind === "cancelled") return "stop-interrupted"; const attemptContext = { @@ -84420,7 +84442,7 @@ async function handleRoleDecision(deps3, jobId, decision, runtime) { startedAt }; if (decision.worker.reasoningTier === "LOCAL_SMALL") { - recordRoleFailure(deps3, jobId, { + recordRoleFailure(deps4, jobId, { context: attemptContext, outcome: result.kind === "invalid-output" ? "invalid-output" : "failed", escalation: { @@ -84434,12 +84456,12 @@ async function handleRoleDecision(deps3, jobId, decision, runtime) { const previousLargeFailures = node.attempts.filter( (attempt) => attempt.role === role && attempt.workerId === decision.worker.workerId && (attempt.outcome === "failed" || attempt.outcome === "invalid-output") ).length; - recordRoleFailure(deps3, jobId, { + recordRoleFailure(deps4, jobId, { context: attemptContext, outcome: result.kind === "invalid-output" ? "invalid-output" : "failed" }); if (previousLargeFailures >= 1) { - blockJob(deps3, jobId, { + blockJob(deps4, jobId, { category: "CAPABILITY_UNAVAILABLE", code: "LARGE_WORKER_FAILED", message: `The large-agent ${role} failed twice: ${result.problem.slice(0, 500)}`, @@ -84456,7 +84478,7 @@ async function handleRoleDecision(deps3, jobId, decision, runtime) { runtime.emit("role-finished", `${role} failed on the large tier (${result.kind})`); return "continue"; } - const agentResultRef = persistAgentResult(deps3, jobId, role, result.raw); + const agentResultRef = persistAgentResult(deps4, jobId, role, result.raw); const context = { nodeId: node.nodeId, role, @@ -84465,18 +84487,18 @@ async function handleRoleDecision(deps3, jobId, decision, runtime) { ...agentResultRef !== void 0 ? { agentResultRef } : {}, ...result.usage !== void 0 ? { usage: result.usage } : {} }; - await applyRoleOutput(deps3, jobId, role, result, context, node, activePlan); + await applyRoleOutput(deps4, jobId, role, result, context, node, activePlan); runtime.emit("role-finished", `${role} for task ${node.parentTaskId} succeeded`); return "continue"; } -function readActivePlan(deps3, jobId, node) { +function readActivePlan(deps4, jobId, node) { if (node.planRevision === 0) return void 0; - const raw = readNodePlan(deps3.workspace, jobId, node.nodeId, node.planRevision); + const raw = readNodePlan(deps4.workspace, jobId, node.nodeId, node.planRevision); if (raw === void 0) return void 0; const parsed = executionPlanSchema.safeParse(raw); return parsed.success ? parsed.data : void 0; } -function buildPacketFor(deps3, jobId, role, base, node, activePlan, job) { +function buildPacketFor(deps4, jobId, role, base, node, activePlan, job) { switch (role) { case "CLASSIFIER": return buildClassifierPacket(base); @@ -84521,8 +84543,8 @@ function buildPacketFor(deps3, jobId, role, base, node, activePlan, job) { if (activePlan === void 0) { throw new OrchestrationError("SBO031", "The replanner needs the invalidated plan document."); } - const latestAssessment = listFailureAssessments(deps3.workspace, jobId, { nodeId: node.nodeId }).at(-1); - const reliabilityState = readTaskReliabilityState(deps3.workspace, jobId, node.nodeId); + const latestAssessment = listFailureAssessments(deps4.workspace, jobId, { nodeId: node.nodeId }).at(-1); + const reliabilityState = readTaskReliabilityState(deps4.workspace, jobId, node.nodeId); const researchEligibility = latestAssessment === void 0 ? void 0 : evaluateRuntimeResearchTrigger({ explicitExternalKnowledgeGap: false, externalAssumptionContradiction: false, @@ -84535,7 +84557,7 @@ function buildPacketFor(deps3, jobId, role, base, node, activePlan, job) { failureFingerprint: latestAssessment.fingerprint, observations: reliabilityState?.observations ?? [] }); - const researchEvidence = runtimeResearchForJob(deps3, jobId).map((record32) => ({ + const researchEvidence = runtimeResearchForJob(deps4, jobId).map((record32) => ({ researchId: record32.researchId, summary: renderResearchEvidence(record32.report) })); @@ -84561,28 +84583,28 @@ function buildPacketFor(deps3, jobId, role, base, node, activePlan, job) { } } } -async function runRole(deps3, jobId, role, decision, packet, runtime) { +async function runRole(deps4, jobId, role, decision, packet, runtime) { if (decision.worker.reasoningTier === "LOCAL_SMALL") { if (runtime.localManager === void 0) { return { ok: false, kind: "worker-unavailable", problem: "No local model manager is active." }; } return runLocalRole({ manager: runtime.localManager, - config: deps3.config, + config: deps4.config, role, packet, - maxCorrections: deps3.config.orchestration.jobs.maxLocalOutputCorrections, - onInferenceCall: () => countLocalInferenceCall(deps3, jobId), + maxCorrections: deps4.config.orchestration.jobs.maxLocalOutputCorrections, + onInferenceCall: () => countLocalInferenceCall(deps4, jobId), signal: runtime.signal }); } const result = await runLargeRole({ - workspace: deps3.workspace, - config: deps3.config, - runnerProfile: decision.worker.runnerProfile ?? deps3.config.defaultRunner, + workspace: deps4.workspace, + config: deps4.config, + runnerProfile: decision.worker.runnerProfile ?? deps4.config.defaultRunner, role, packet, - scratchDir: import_path46.default.join(jobDir(deps3.workspace, jobId), "scratch"), + scratchDir: import_path46.default.join(jobDir(deps4.workspace, jobId), "scratch"), timeoutMs: 6e5, signal: runtime.signal, cachedProbe: runtime.probeCache.probe @@ -84590,18 +84612,18 @@ async function runRole(deps3, jobId, role, decision, packet, runtime) { if (result.probe !== void 0) runtime.probeCache.probe = result.probe; return result; } -async function applyRoleOutput(deps3, jobId, role, result, context, node, activePlan) { +async function applyRoleOutput(deps4, jobId, role, result, context, node, activePlan) { const producedByTier = context.workerId === "local-llamacpp" ? "LOCAL_SMALL" : "LARGE_AGENT"; switch (role) { case "CLASSIFIER": { const output = result.output; - recordClassification(deps3, jobId, { context, proposedClass: output.complexity }); + recordClassification(deps4, jobId, { context, proposedClass: output.complexity }); return; } case "PLANNER": { const output = result.output; if (output.decision === "ESCALATE" || output.requiresEscalation) { - recordRoleFailure(deps3, jobId, { + recordRoleFailure(deps4, jobId, { context, outcome: "escalated", escalation: { @@ -84612,7 +84634,7 @@ async function applyRoleOutput(deps3, jobId, role, result, context, node, active return; } if (output.steps.length === 0 || output.goal === void 0) { - recordRoleFailure(deps3, jobId, { + recordRoleFailure(deps4, jobId, { context, outcome: "escalated", escalation: { @@ -84622,7 +84644,7 @@ async function applyRoleOutput(deps3, jobId, role, result, context, node, active }); return; } - await recordPlan(deps3, jobId, { + await recordPlan(deps4, jobId, { context, candidate: plannerOutputToCandidate(output), producedByTier @@ -84631,13 +84653,13 @@ async function applyRoleOutput(deps3, jobId, role, result, context, node, active } case "CRITIC": { const output = result.output; - recordCriticVerdict(deps3, jobId, { + recordCriticVerdict(deps4, jobId, { context, verdict: output.verdict, reasons: [...output.reasons, ...output.requestedChanges] }); if (output.verdict === "ESCALATE") { - noteEscalation(deps3, jobId, { + noteEscalation(deps4, jobId, { nodeId: node.nodeId, role: "CRITIC", reason: "CRITIC_ESCALATED", @@ -84648,7 +84670,7 @@ async function applyRoleOutput(deps3, jobId, role, result, context, node, active } case "DIAGNOSER": { const output = result.output; - applyDiagnosis(deps3, jobId, { + applyDiagnosis(deps4, jobId, { context, category: output.category, planValidity: output.planValidity, @@ -84660,7 +84682,7 @@ async function applyRoleOutput(deps3, jobId, role, result, context, node, active case "REPLANNER": { const output = result.output; if (output.decision === "ESCALATE") { - recordRoleFailure(deps3, jobId, { + recordRoleFailure(deps4, jobId, { context, outcome: "escalated", escalation: { @@ -84671,7 +84693,7 @@ async function applyRoleOutput(deps3, jobId, role, result, context, node, active return; } if (output.decision === "BLOCKED") { - blockJob(deps3, jobId, { + blockJob(deps4, jobId, { category: "BLOCKED_DEPENDENCY", code: "REPLANNER_BLOCKED", message: output.reason, @@ -84680,12 +84702,12 @@ async function applyRoleOutput(deps3, jobId, role, result, context, node, active return; } if (output.decision === "SUPERSEDE_NODE") { - supersedeNode(deps3, jobId, { nodeId: node.nodeId, reason: output.reason }); - recordResearchInformedReplan(deps3, jobId, node.nodeId, output.reason); + supersedeNode(deps4, jobId, { nodeId: node.nodeId, reason: output.reason }); + recordResearchInformedReplan(deps4, jobId, node.nodeId, output.reason); return; } if (output.steps.length === 0 || output.goal === void 0) { - recordRoleFailure(deps3, jobId, { + recordRoleFailure(deps4, jobId, { context, outcome: "escalated", escalation: { @@ -84701,7 +84723,7 @@ async function applyRoleOutput(deps3, jobId, role, result, context, node, active activePlan !== void 0 ? { goal: activePlan.goal, steps: activePlan.steps.map((step2) => ({ description: step2.description })) } : void 0 ); if (output.impactsApprovedIntent || screen.impacts) { - const delegated = resolveDelegatedAuthority(deps3.authorityResolver, { + const delegated = resolveDelegatedAuthority(deps4.authorityResolver, { jobId, nodeId: node.nodeId, decisionKinds: screen.decisionKinds, @@ -84710,17 +84732,17 @@ async function applyRoleOutput(deps3, jobId, role, result, context, node, active ${candidate.steps.map((step2) => step2.description).join("\n")}`.slice(0, 4e3) }); if (delegated?.kind === "AUTONOMOUS") { - recordJobEvent(deps3, jobId, "authority_delegated", { + recordJobEvent(deps4, jobId, "authority_delegated", { nodeId: node.nodeId, decisionKinds: [...screen.decisionKinds], reason: delegated.reason.slice(0, 300) }); - await recordPlan(deps3, jobId, { context, candidate, producedByTier }, { replan: true }); - recordResearchInformedReplan(deps3, jobId, node.nodeId, output.reason); + await recordPlan(deps4, jobId, { context, candidate, producedByTier }, { replan: true }); + recordResearchInformedReplan(deps4, jobId, node.nodeId, output.reason); return; } if (delegated?.kind === "NEEDS_AUTHORITY") { - escalateAuthority(deps3, jobId, { + escalateAuthority(deps4, jobId, { surface: delegated.surface, reason: delegated.reason, question: delegated.question, @@ -84730,7 +84752,7 @@ ${candidate.steps.map((step2) => step2.description).join("\n")}`.slice(0, 4e3) }); return; } - askClarification(deps3, jobId, [ + askClarification(deps4, jobId, [ { question: `The proposed replacement plan for task ${node.parentTaskId} may change approved intent${screen.reasons.length > 0 ? ` (${screen.reasons.join("; ")})` : ""}. Proceed, change the spec, or decide otherwise?`, whyItMatters: "Replanning may never silently change approved behavior, public API, architecture, or product decisions.", @@ -84739,16 +84761,16 @@ ${candidate.steps.map((step2) => step2.description).join("\n")}`.slice(0, 4e3) ]); return; } - await recordPlan(deps3, jobId, { context, candidate, producedByTier }, { replan: true }); - recordResearchInformedReplan(deps3, jobId, node.nodeId, output.reason); + await recordPlan(deps4, jobId, { context, candidate, producedByTier }, { replan: true }); + recordResearchInformedReplan(deps4, jobId, node.nodeId, output.reason); return; } } } -async function buildDispatchContext(deps3, input) { - const attemptId = requireJobState(deps3.workspace, input.jobId).currentAttemptId; +async function buildDispatchContext(deps4, input) { + const attemptId = requireJobState(deps4.workspace, input.jobId).currentAttemptId; try { - const built = await buildTaskContextPackage(deps3, { + const built = await buildTaskContextPackage(deps4, { jobId: input.jobId, nodeId: input.node.nodeId, role: "EXECUTOR", @@ -84758,7 +84780,7 @@ async function buildDispatchContext(deps3, input) { ...input.executionMode !== void 0 ? { executionMode: input.executionMode } : {}, ...input.runner !== void 0 ? { runner: input.runner } : {} }); - recordJobEvent(deps3, input.jobId, "context_selected", { + recordJobEvent(deps4, input.jobId, "context_selected", { nodeId: input.node.nodeId, taskId: input.node.parentTaskId, planId: built.plan.planId, @@ -86972,16 +86994,16 @@ function buildContextReport(workspace, jobId) { let expansions = 0; let nativeCompactions = null; let strategy = null; - for (const metric of metrics) { - estimated = add(estimated, metric.estimatedContextTokens); - providerInput = add(providerInput, metric.providerReportedInputTokens); - workingSet = add(workingSet, metric.selectedFiles + metric.selectedSections); - const compressionDelta = metric.compressionSourceChars > 0 ? metric.compressionSourceChars - metric.compressionOutputChars : null; + for (const metric2 of metrics) { + estimated = add(estimated, metric2.estimatedContextTokens); + providerInput = add(providerInput, metric2.providerReportedInputTokens); + workingSet = add(workingSet, metric2.selectedFiles + metric2.selectedSections); + const compressionDelta = metric2.compressionSourceChars > 0 ? metric2.compressionSourceChars - metric2.compressionOutputChars : null; compressionSaved = add(compressionSaved, compressionDelta); - dedupSaved = add(dedupSaved, metric.deduplicationSavedChars > 0 ? metric.deduplicationSavedChars : null); - expansions += metric.contextExpansions; - nativeCompactions = add(nativeCompactions, metric.nativeCompactions); - strategy = metric.strategy; + dedupSaved = add(dedupSaved, metric2.deduplicationSavedChars > 0 ? metric2.deduplicationSavedChars : null); + expansions += metric2.contextExpansions; + nativeCompactions = add(nativeCompactions, metric2.nativeCompactions); + strategy = metric2.strategy; } let providerOutput = null; for (const entry2 of entries) providerOutput = add(providerOutput, entry2.metrics.outputTokens); @@ -88101,10 +88123,10 @@ function collectVersions(config2, overrides = {}) { policyFingerprint: overrides.policyFingerprint ?? null }; } -function startQualificationRun(deps3, request) { - const now52 = deps3.clock().toISOString(); - const runId = request.runId ?? `qual-${deps3.idFactory()}`; - const existing = readDogfoodRun(deps3.workspace, runId); +function startQualificationRun(deps4, request) { + const now52 = deps4.clock().toISOString(); + const runId = request.runId ?? `qual-${deps4.idFactory()}`; + const existing = readDogfoodRun(deps4.workspace, runId); if (existing !== void 0) { throw new OrchestrationError("SBO052", `Qualification run "${runId}" already exists.`, { remediation: [ @@ -88113,15 +88135,15 @@ function startQualificationRun(deps3, request) { ] }); } - const previous = request.previousRunId === void 0 || request.previousRunId === null ? void 0 : readDogfoodRun(deps3.workspace, request.previousRunId); + const previous = request.previousRunId === void 0 || request.previousRunId === null ? void 0 : readDogfoodRun(deps4.workspace, request.previousRunId); const run = dogfoodRunSchema.parse({ schemaVersion: DOGFOOD_RUN_SCHEMA_VERSION, runId, status: "PREFLIGHT", profile: request.profile, target: request.target, - versions: collectVersions(deps3.config, request.versions ?? {}), - configurationFingerprint: configurationFingerprint(deps3.config), + versions: collectVersions(deps4.config, request.versions ?? {}), + configurationFingerprint: configurationFingerprint(deps4.config), missionId: request.missionId ?? null, jobId: request.jobId ?? null, iteration: previous === void 0 ? 1 : previous.iteration + 1, @@ -88136,21 +88158,21 @@ function startQualificationRun(deps3, request) { pausedMs: 0, note: null }); - return writeDogfoodRun(deps3.workspace, run); + return writeDogfoodRun(deps4.workspace, run); } -function transition3(deps3, runId, status, note) { - const run = requireDogfoodRun(deps3.workspace, runId); +function transition3(deps4, runId, status, note) { + const run = requireDogfoodRun(deps4.workspace, runId); if (isFinalDogfoodRunStatus(run.status)) { throw new OrchestrationError( "SBO052", `Qualification run "${runId}" is already ${run.status} and cannot transition to ${status}.` ); } - const now52 = deps3.clock(); + const now52 = deps4.clock(); const elapsed = Math.max(0, now52.getTime() - Date.parse(run.updatedAt)); const activeMs = run.status === "PAUSED" ? run.activeMs : run.activeMs + elapsed; const pausedMs = run.status === "PAUSED" ? run.pausedMs + elapsed : run.pausedMs; - return writeDogfoodRun(deps3.workspace, { + return writeDogfoodRun(deps4.workspace, { ...run, status, activeMs, @@ -88160,10 +88182,10 @@ function transition3(deps3, runId, status, note) { note: note ?? run.note }); } -function markRunRunning(deps3, runId, note) { - return transition3(deps3, runId, "RUNNING", note); +function markRunRunning(deps4, runId, note) { + return transition3(deps4, runId, "RUNNING", note); } -function recordScenarioResult(deps3, input) { +function recordScenarioResult(deps4, input) { const scenario = findScenario(input.scenarioId); if (scenario === void 0) { throw new OrchestrationError( @@ -88186,7 +88208,7 @@ function recordScenarioResult(deps3, input) { { remediation: ["A failed scenario must record what was expected and what was observed."] } ); } - return writeScenarioResult(deps3.workspace, { + return writeScenarioResult(deps4.workspace, { schemaVersion: "1.0.0", runId: input.runId, scenarioId: scenario.id, @@ -88203,7 +88225,7 @@ function recordScenarioResult(deps3, input) { resourceAttribution: { ...input.resourceAttribution ?? {} }, executor: input.executor, durationMs: input.durationMs ?? null, - recordedAt: deps3.clock().toISOString() + recordedAt: deps4.clock().toISOString() }); } function listRuns2(workspace) { @@ -89814,17 +89836,17 @@ function skipReasonFor(scenario, profile, targetAvailable) { return "No executable implementation is registered for this scenario in this invocation."; } function runQualificationScenarios(input) { - const { deps: deps3, run, executor } = input; + const { deps: deps4, run, executor } = input; const only = input.only === void 0 ? null : new Set(input.only); const existing = new Map( - listScenarioResults(deps3.workspace, run.runId).map((result) => [result.scenarioId, result]) + listScenarioResults(deps4.workspace, run.runId).map((result) => [result.scenarioId, result]) ); const targetAvailable = run.target.kind === "REAL_REPOSITORY" && run.target.available; const executed = []; const skipped = []; const preserved = []; const outcomes = new Map( - runPolicyScenarios(deps3.config).map((outcome) => [outcome.scenarioId, outcome]) + runPolicyScenarios(deps4.config).map((outcome) => [outcome.scenarioId, outcome]) ); for (const scenario of QUALIFICATION_SCENARIOS) { if (only !== null && !only.has(scenario.id)) { @@ -89841,7 +89863,7 @@ function runQualificationScenarios(input) { const runnable = outcome !== void 0 && profileSatisfies(run.profile, scenario.minimumProfile); if (runnable) { executed.push( - recordScenarioResult(deps3, { + recordScenarioResult(deps4, { runId: run.runId, scenarioId: scenario.id, status: outcome.passed ? "PASS" : "FAIL", @@ -89858,7 +89880,7 @@ function runQualificationScenarios(input) { continue; } skipped.push( - recordScenarioResult(deps3, { + recordScenarioResult(deps4, { runId: run.runId, scenarioId: scenario.id, status: "SKIPPED_WITH_REASON", @@ -90350,6 +90372,88 @@ ${report.specResults.map((spec, index) => renderSpec(spec, index)).join("\n")} `; } +function percent(metric2) { + return metric2.value === null ? "n/a" : `${(metric2.value * 100).toFixed(1)}%`; +} +function tokens(metric2) { + if (metric2.knownTokens === null) return "n/a (provider did not report usage)"; + const coverage = metric2.coverage.ratio === null ? "n/a" : `${Math.round(metric2.coverage.ratio * 100)}%`; + return `${metric2.knownTokens.toLocaleString("en-US")} known (${coverage} attempt coverage${metric2.coverage.complete ? ", complete" : ", partial"})`; +} +function duration(value) { + if (value === null) return "n/a"; + if (value >= 36e5) return `${(value / 36e5).toFixed(1)}h`; + if (value >= 6e4) return `${(value / 6e4).toFixed(1)}m`; + return `${(value / 1e3).toFixed(1)}s`; +} +function renderExecutionTelemetryReport(report, options = {}) { + const lines = [reportTitle(`Job ${report.jobId} \u2014 ${report.outcome.status}`)]; + lines.push(infoLine(`authoritative state: ${report.outcome.authoritativeJobStatus}`)); + lines.push(infoLine(`elapsed ${duration(report.period.durationMs)} \xB7 active ${duration(report.period.activeExecutionMs)}`)); + lines.push("", sectionTitle("Zero-touch status")); + lines.push( + report.human.zeroTouchAfterSeal ? okLine("ZeroTouchAfterSeal: true (0 human interventions)") : failLine(`ZeroTouchAfterSeal: false (${report.human.interventionsAfterSeal} intervention(s))`) + ); + lines.push(infoLine(`pre-seal decisions ${report.human.decisionsBeforeSeal ?? "n/a"} \xB7 approvals ${report.human.approvals} \xB7 post-seal authority stops ${report.human.authorityEscalationsAfterSeal ?? "n/a"}`)); + lines.push("", sectionTitle("Work summary")); + lines.push(infoLine(`${report.work.total} WorkUnit(s) \xB7 ${report.work.accounting.completed} completed \xB7 ${report.work.accounting.failed} failed \xB7 ${report.work.accounting.waiting} waiting`)); + lines.push(infoLine(`${report.work.completedImplementation} implementation WorkUnit(s) integrated \xB7 ${report.attempts.uniqueImplementationAttempts} unique implementation attempt(s)`)); + lines.push("", sectionTitle("Secondary Builder efficiency")); + lines.push(infoLine(`${report.secondary.eligibility.eligible} eligible \xB7 ${report.secondary.selection.secondarySelected} selected \xB7 ${report.secondary.funnel.initialPass} initial pass \xB7 ${report.secondary.funnel.repairPass} repair pass`)); + lines.push(infoLine(`StrongBuilderAvoidanceRatio ${percent(report.efficiency.strongBuilderAvoidanceRatio)} (${report.efficiency.strongBuilderAvoidanceRatio.numerator ?? "n/a"}/${report.efficiency.strongBuilderAvoidanceRatio.denominator ?? "n/a"})`)); + lines.push(infoLine(`SecondaryInitialSuccessRate ${percent(report.secondary.initialSuccessRate)} \xB7 SecondaryRepairRecoveryRate ${percent(report.secondary.repairRecoveryRate)} \xB7 fallback ${percent(report.secondary.toStrongFallbackRate)}`)); + lines.push(infoLine(`Secondary builder tokens: ${tokens(report.secondary.builderTokens)}`)); + lines.push("", sectionTitle("Strong usage")); + lines.push(infoLine(`${report.strong.builderAttempts} Strong Builder attempt(s) \xB7 ${report.strong.evaluatorAttempts} Strong Evaluator attempt(s)`)); + lines.push(infoLine(`Strong implementation tokens: ${tokens(report.strong.implementationTokens)}`)); + lines.push(infoLine(`Strong evaluator tokens: ${tokens(report.strong.evaluatorTokens)}`)); + lines.push("", sectionTitle("Research efficiency")); + lines.push(infoLine(`scope ${report.research.scope} \xB7 considered ${report.research.considered ?? "n/a"} \xB7 new calls ${report.research.providerCalls} \xB7 reused ${report.research.priorResearchReused}`)); + lines.push(infoLine(`ResearchAvoidanceRatio ${percent(report.research.avoidanceRatio)} \xB7 reuse rate ${percent(report.research.reuseRate)} \xB7 QUICK ${report.research.newQuick} \xB7 DEEP ${report.research.newDeep}`)); + lines.push("", sectionTitle("Subscription cooldown")); + lines.push(infoLine(`${report.cooldown.episodes} episode(s) \xB7 ${duration(report.cooldown.totalDurationMs)} known duration \xB7 ${report.cooldown.usefulWorkDuringSubscriptionCooldown} useful WorkUnit(s)`)); + lines.push( + report.cooldown.avoidableIdlePeriods === 0 ? okLine("AvoidableIdleDuringCooldown: 0") : warnLine(`AvoidableIdleDuringCooldown: ${report.cooldown.avoidableIdlePeriods}`) + ); + lines.push("", sectionTitle("Reliability / resume")); + lines.push(infoLine(`restarts ${report.reliability.processRestarts + report.reliability.supervisorRestarts} \xB7 candidates reused ${report.reliability.candidatesReusedAfterRestart} \xB7 candidate rebuilds ${report.reliability.candidateRebuildsAfterRestart}`)); + lines.push( + report.reliability.completedWorkRedoCount === 0 ? okLine("CompletedWorkRedoCount: 0") : failLine(`CompletedWorkRedoCount: ${report.reliability.completedWorkRedoCount}`) + ); + lines.push("", sectionTitle("Verification & closure")); + lines.push( + report.outcome.verification === "PASS" ? okLine(`verification PASS (${report.verification.passes}/${report.verification.attempts} WorkUnit evaluation passes)`) : report.outcome.verification === "FAIL" ? failLine(`verification FAIL (${report.verification.failures} WorkUnit evaluation failure(s))`) : warnLine(`verification n/a (${report.verification.passes} WorkUnit evaluation pass(es), authoritative job evidence unavailable)`) + ); + lines.push( + report.outcome.closure === "PASS" ? okLine(`closure PASS (${report.closure.earned} earned, ${report.closure.waived} waived)`) : report.outcome.closure === "FAIL" ? failLine(`closure FAIL (${report.closure.unresolved} unresolved)`) : warnLine("closure n/a (no closure ledger)") + ); + if (report.diagnostics.length > 0) { + lines.push("", sectionTitle("Diagnostics")); + for (const diagnostic of report.diagnostics.slice(0, options.verbose === true ? 200 : 10)) { + lines.push( + diagnostic.severity === "error" ? failLine(`${diagnostic.code}: ${diagnostic.message}`) : diagnostic.severity === "warning" ? warnLine(`${diagnostic.code}: ${diagnostic.message}`) : infoLine(`${diagnostic.code}: ${diagnostic.message}`) + ); + } + } + if (options.verbose === true) { + lines.push("", sectionTitle("Objective accounting")); + for (const objective of report.work.objectives) { + lines.push(infoLine(`${objective.objectiveNodeId} \xB7 revision ${objective.graphRevision ?? "n/a"} \xB7 ${objective.total} WorkUnit(s) \xB7 ${objective.implementationAttempts} implementation attempt(s) (${objective.secondaryAttempts} Secondary, ${objective.strongBuilderAttempts} Strong)`)); + } + lines.push("", sectionTitle("WorkUnit accounting")); + for (const unit of report.work.units) { + lines.push(infoLine(`${unit.objectiveNodeId}/${unit.workUnitId} \xB7 ${unit.accounting} \xB7 ${unit.builderPath} \xB7 ${unit.implementationAttempts} attempt(s) \xB7 verification ${unit.verification}`)); + } + if (report.cooldown.timeline.length > 0) { + lines.push("", sectionTitle("Cooldown timeline")); + for (const entry2 of report.cooldown.timeline) { + lines.push(infoLine(`${entry2.at} \xB7 ${entry2.type} \xB7 ${entry2.detail}`)); + } + } + } + return `${lines.join("\n")} +`; +} // ../../packages/cli/src/context.ts var import_node_path7 = __toESM(require("path"), 1); @@ -90725,9 +90829,9 @@ function statusFor2(code2) { } function parseNameStatusZ(raw) { const changes = []; - const tokens = raw.split("\0"); - for (let i2 = 0; i2 < tokens.length; i2 += 1) { - const code2 = tokens[i2]; + const tokens2 = raw.split("\0"); + for (let i2 = 0; i2 < tokens2.length; i2 += 1) { + const code2 = tokens2[i2]; if (code2 === void 0 || code2.length === 0) continue; const changeType = statusFor2(code2); if (changeType === void 0) { @@ -90735,8 +90839,8 @@ function parseNameStatusZ(raw) { continue; } if (changeType === "renamed" || changeType === "copied") { - const oldPath = tokens[i2 + 1]; - const newPath = tokens[i2 + 2]; + const oldPath = tokens2[i2 + 1]; + const newPath = tokens2[i2 + 2]; i2 += 2; if (oldPath === void 0 || newPath === void 0 || newPath.length === 0) continue; changes.push({ @@ -90747,7 +90851,7 @@ function parseNameStatusZ(raw) { symlinkOutsideRepository: false }); } else { - const filePath = tokens[i2 + 1]; + const filePath = tokens2[i2 + 1]; i2 += 1; if (filePath === void 0 || filePath.length === 0) continue; changes.push({ path: filePath, changeType, binary: false, symlinkOutsideRepository: false }); @@ -90757,9 +90861,9 @@ function parseNameStatusZ(raw) { } function parseNumstatZ(raw) { const stats = /* @__PURE__ */ new Map(); - const tokens = raw.split("\0"); - for (let i2 = 0; i2 < tokens.length; i2 += 1) { - const token = tokens[i2]; + const tokens2 = raw.split("\0"); + for (let i2 = 0; i2 < tokens2.length; i2 += 1) { + const token = tokens2[i2]; if (token === void 0 || token.length === 0) continue; const match = /^(-|\d+)\t(-|\d+)\t(.*)$/s.exec(token); if (match === null) continue; @@ -90768,7 +90872,7 @@ function parseNumstatZ(raw) { const binary = match[1] === "-" && match[2] === "-"; let filePath = match[3] ?? ""; if (filePath.length === 0) { - const newPath = tokens[i2 + 2]; + const newPath = tokens2[i2 + 2]; i2 += 2; if (newPath === void 0) continue; filePath = newPath; @@ -102633,10 +102737,10 @@ var import_node_fs9 = require("fs"); // ../../packages/intake/dist/index.js var import_crypto30 = require("crypto"); -var import_fs81 = require("fs"); -var import_path90 = __toESM(require("path"), 1); var import_fs82 = require("fs"); var import_path91 = __toESM(require("path"), 1); +var import_fs83 = require("fs"); +var import_path92 = __toESM(require("path"), 1); // ../../packages/autonomy/dist/index.js var import_crypto29 = require("crypto"); @@ -102655,6 +102759,8 @@ var import_fs79 = require("fs"); var import_path88 = __toESM(require("path"), 1); var import_fs80 = require("fs"); var import_path89 = __toESM(require("path"), 1); +var import_fs81 = require("fs"); +var import_path90 = __toESM(require("path"), 1); var SEAL_STATUSES = [ /** Drafted from mission state; not yet authorized by a human. */ "DRAFT", @@ -103141,26 +103247,26 @@ var AutonomyError = class extends Error { this.retryable = options.retryable ?? false; } }; -function jobDepsOf(deps3) { - return deps3; +function jobDepsOf(deps4) { + return deps4; } -function autonomyPolicyOf(deps3) { - return deps3.config.autonomy; +function autonomyPolicyOf(deps4) { + return deps4.config.autonomy; } -function now5(deps3) { - return (deps3.clock ?? (() => /* @__PURE__ */ new Date()))(); +function now5(deps4) { + return (deps4.clock ?? (() => /* @__PURE__ */ new Date()))(); } -function nowIso5(deps3) { - return now5(deps3).toISOString(); +function nowIso5(deps4) { + return now5(deps4).toISOString(); } -function newId5(deps3) { - return (deps3.idFactory ?? import_crypto29.randomUUID)(); +function newId5(deps4) { + return (deps4.idFactory ?? import_crypto29.randomUUID)(); } -function hostOf(deps3) { - return deps3.host ?? "cli"; +function hostOf(deps4) { + return deps4.host ?? "cli"; } -function newRecordId(deps3, prefix) { - const raw = newId5(deps3).replace(/[^A-Za-z0-9._-]/g, "").slice(0, 40); +function newRecordId(deps4, prefix) { + const raw = newId5(deps4).replace(/[^A-Za-z0-9._-]/g, "").slice(0, 40); return `${prefix}-${raw.length > 0 ? raw : "x"}`; } var ID_PATTERN10 = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/; @@ -103407,13 +103513,13 @@ function computeAuthorityDigest(seal) { }; return sha256Hex(JSON.stringify(canonical)).slice(0, 32); } -function draftSeal(deps3, request) { - const mission = requireMissionState(deps3.workspace, request.missionId); - const policy = autonomyPolicyOf(deps3); - const contracts = readContractRegistry(deps3.workspace, request.missionId); - const constitution = readConstitution(deps3.workspace, request.missionId); - const adrs = readAdrs(deps3.workspace, request.missionId); - const decisions = readDecisions(deps3.workspace, request.missionId).filter( +function draftSeal(deps4, request) { + const mission = requireMissionState(deps4.workspace, request.missionId); + const policy = autonomyPolicyOf(deps4); + const contracts = readContractRegistry(deps4.workspace, request.missionId); + const constitution = readConstitution(deps4.workspace, request.missionId); + const adrs = readAdrs(deps4.workspace, request.missionId); + const decisions = readDecisions(deps4.workspace, request.missionId).filter( (decision) => decision.status === "active" ); const contractRefs = contracts.filter((contract) => contract.status !== "superseded").slice(0, SEAL_LIMITS.maxContractRefs).map((contract) => ({ @@ -103448,20 +103554,20 @@ function draftSeal(deps3, request) { toolsmithCapabilities: [...policy.toolsmith.capabilities] } }; - const sealId = request.sealId ?? newRecordId(deps3, "seal"); + const sealId = request.sealId ?? newRecordId(deps4, "seal"); const seal = missionSealSchema.parse({ schemaVersion: SEAL_SCHEMA_VERSION, sealId, missionId: mission.missionId, ...mission.specName !== void 0 ? { specName: mission.specName } : {}, status: "DRAFT", - createdAt: nowIso5(deps3), + createdAt: nowIso5(deps4), ...request.supersedes !== void 0 ? { supersedes: request.supersedes } : {}, ...base, presentAuthorityKinds: presentAuthorityKinds(base), authorityDigest: computeAuthorityDigest(base) }); - writeImmutableRecord(sealFile(deps3.workspace, sealId), seal, "seal"); + writeImmutableRecord(sealFile(deps4.workspace, sealId), seal, "seal"); return seal; } function presentAuthorityKinds(base) { @@ -103518,8 +103624,8 @@ function gapExplanation(kind) { return `The seal is missing ${kind}.`; } } -function sealMission(deps3, request) { - const existing = requireSeal(deps3.workspace, request.sealId); +function sealMission(deps4, request) { + const existing = requireSeal(deps4.workspace, request.sealId); if (existing.status === "SEALED") return existing; if (isFinalSealStatus(existing.status)) { throw new AutonomyError( @@ -103542,32 +103648,32 @@ function sealMission(deps3, request) { const sealed = missionSealSchema.parse({ ...existing, status: "SEALED", - sealedAt: nowIso5(deps3), - sealedVia: (request.via ?? hostOf(deps3)).slice(0, SEAL_LIMITS.maxShortTextChars) + sealedAt: nowIso5(deps4), + sealedVia: (request.via ?? hostOf(deps4)).slice(0, SEAL_LIMITS.maxShortTextChars) }); - writeJsonRecord(sealFile(deps3.workspace, existing.sealId), sealed); + writeJsonRecord(sealFile(deps4.workspace, existing.sealId), sealed); if (existing.supersedes !== void 0) { - markSuperseded(deps3, existing.supersedes, existing.sealId); + markSuperseded(deps4, existing.supersedes, existing.sealId); } return sealed; } -function markSuperseded(deps3, sealId, bySealId) { - const previous = readSeal(deps3.workspace, sealId); +function markSuperseded(deps4, sealId, bySealId) { + const previous = readSeal(deps4.workspace, sealId); if (previous === void 0 || previous.status === "SUPERSEDED") return; writeJsonRecord( - sealFile(deps3.workspace, sealId), + sealFile(deps4.workspace, sealId), missionSealSchema.parse({ ...previous, status: "SUPERSEDED", supersededBy: bySealId }) ); } -function revokeSeal(deps3, sealId, reason3) { - const seal = requireSeal(deps3.workspace, sealId); +function revokeSeal(deps4, sealId, reason3) { + const seal = requireSeal(deps4.workspace, sealId); const revoked = missionSealSchema.parse({ ...seal, status: "REVOKED", - revokedAt: nowIso5(deps3), + revokedAt: nowIso5(deps4), revokedReason: reason3.slice(0, SEAL_LIMITS.maxTextChars) }); - writeJsonRecord(sealFile(deps3.workspace, sealId), revoked); + writeJsonRecord(sealFile(deps4.workspace, sealId), revoked); return revoked; } function readSeal(workspace, sealId) { @@ -103627,18 +103733,18 @@ function requireExecutableSeal(seal, policy) { details: { reason: assessment.reason ?? "UNKNOWN" } }); } -function bindSealToJob(deps3, jobId, sealId) { - const seal = requireSeal(deps3.workspace, sealId); - requireExecutableSeal(seal, autonomyPolicyOf(deps3)); +function bindSealToJob(deps4, jobId, sealId) { + const seal = requireSeal(deps4.workspace, sealId); + requireExecutableSeal(seal, autonomyPolicyOf(deps4)); const binding = sealBindingSchema.parse({ schemaVersion: SEAL_SCHEMA_VERSION, jobId, sealId, missionId: seal.missionId, - boundAt: nowIso5(deps3), + boundAt: nowIso5(deps4), boundPolicyFingerprint: seal.delegatedAuthority.policyFingerprint }); - writeJsonRecord(bindingFile(deps3.workspace, jobId), binding); + writeJsonRecord(bindingFile(deps4.workspace, jobId), binding); return binding; } function readSealBinding(workspace, jobId) { @@ -104212,12 +104318,12 @@ function progressFingerprint(input) { input.agentRuns ].join(":"); } -function createInProcessDriverHost(deps3, options = {}) { +function createInProcessDriverHost(deps4, options = {}) { return { label: "in-process", async run(request) { try { - const result = await driveJob(deps3, request.jobId, { + const result = await driveJob(deps4, request.jobId, { ...options, ...request.signal !== void 0 ? { signal: request.signal } : {}, ...request.onEvent !== void 0 ? { onEvent: (event) => request.onEvent?.({ kind: event.kind, message: event.message }) } : {} @@ -104267,14 +104373,14 @@ function writeSupervisorState(workspace, state) { writeJsonRecord(supervisorStateFile(workspace), validated); return validated; } -function loadSupervisorState(deps3, ownerId) { - const existing = readSupervisorState(deps3.workspace); +function loadSupervisorState(deps4, ownerId) { + const existing = readSupervisorState(deps4.workspace); if (existing !== void 0) return existing; return supervisorStateSchema.parse({ schemaVersion: SUPERVISOR_SCHEMA_VERSION, ownerId, - startedAt: nowIso5(deps3), - heartbeatAt: nowIso5(deps3), + startedAt: nowIso5(deps4), + heartbeatAt: nowIso5(deps4), pid: process.pid, hostname: safeHostname(), jobs: [] @@ -104295,16 +104401,16 @@ function upsertSupervisedJob(state, job) { function findSupervisedJob(state, jobId) { return state.jobs.find((entry2) => entry2.jobId === jobId); } -function appendSupervisionLog(deps3, entry2) { +function appendSupervisionLog(deps4, entry2) { const validated = supervisionLogEntrySchema.parse({ - at: nowIso5(deps3), + at: nowIso5(deps4), ownerId: entry2.ownerId, ...entry2.jobId !== void 0 ? { jobId: entry2.jobId } : {}, action: entry2.action, ...entry2.detail !== void 0 ? { detail: entry2.detail.slice(0, 4e3) } : {}, ...entry2.generation !== void 0 ? { generation: entry2.generation } : {} }); - appendJsonl2(supervisionLogFile(deps3.workspace), validated); + appendJsonl2(supervisionLogFile(deps4.workspace), validated); return validated; } function readSupervisionLog(workspace, limit = 500) { @@ -104323,8 +104429,8 @@ function supervisorSleep(ms, signal) { }, { once: true }); }); } -function resetSupervisedJobForExplicitResume(deps3, ownerId, jobId) { - const state = loadSupervisorState(deps3, ownerId); +function resetSupervisedJobForExplicitResume(deps4, ownerId, jobId) { + const state = loadSupervisorState(deps4, ownerId); const supervised = state.jobs.find((job) => job.jobId === jobId); if (supervised === void 0) return false; const changed = supervised.consecutiveRestarts > 0 || supervised.backoffMs > 0 || supervised.status === "RELEASED"; @@ -104334,8 +104440,8 @@ function resetSupervisedJobForExplicitResume(deps3, ownerId, jobId) { if (supervised.status === "RELEASED") supervised.status = "REGISTERED"; delete supervised.releasedAt; delete supervised.releaseReason; - writeSupervisorState(deps3.workspace, state); - appendSupervisionLog(deps3, { + writeSupervisorState(deps4.workspace, state); + appendSupervisionLog(deps4, { ownerId, jobId, action: "RESET_ON_EXPLICIT_RESUME", @@ -104343,9 +104449,9 @@ function resetSupervisedJobForExplicitResume(deps3, ownerId, jobId) { }); return true; } -function registerSupervisedJob(deps3, input) { - const ownerId = input.ownerId ?? newId5(deps3); - const state = loadSupervisorState(deps3, ownerId); +function registerSupervisedJob(deps4, input) { + const ownerId = input.ownerId ?? newId5(deps4); + const state = loadSupervisorState(deps4, ownerId); const existing = findSupervisedJob(state, input.jobId); const supervised = supervisedJobSchema.parse( existing ?? { @@ -104353,19 +104459,19 @@ function registerSupervisedJob(deps3, input) { specName: input.specName, ...input.sealId !== void 0 ? { sealId: input.sealId } : {}, status: "REGISTERED", - registeredAt: nowIso5(deps3) + registeredAt: nowIso5(deps4) } ); - writeSupervisorState(deps3.workspace, { + writeSupervisorState(deps4.workspace, { ...upsertSupervisedJob(state, supervised), schemaVersion: SUPERVISOR_SCHEMA_VERSION, - heartbeatAt: nowIso5(deps3) + heartbeatAt: nowIso5(deps4) }); return supervised; } -function acquireJobLease(deps3, jobId, ownerId, policy) { - const at = now5(deps3); - const existing = readLease(deps3.workspace, jobId); +function acquireJobLease(deps4, jobId, ownerId, policy) { + const at = now5(deps4); + const existing = readLease(deps4.workspace, jobId); if (isLeaseLive(existing, at) && existing?.ownerId !== ownerId) { return { acquired: false, ...existing !== void 0 ? { heldBy: existing.ownerId } : {} }; } @@ -104377,11 +104483,11 @@ function acquireJobLease(deps3, jobId, ownerId, policy) { ttlMs: policy.leaseTtlMs, pid: process.pid, ...safeHostname() !== void 0 ? { hostname: safeHostname() } : {}, - host: hostOf(deps3), + host: hostOf(deps4), schemaVersion: SUPERVISOR_SCHEMA_VERSION }); - const lease = writeLease(deps3.workspace, claim2.lease); - appendSupervisionLog(deps3, { + const lease = writeLease(deps4.workspace, claim2.lease); + appendSupervisionLog(deps4, { ownerId, jobId, action: claim2.reclaimed ? "LEASE_EXPIRED_RECLAIMED" : "LEASE_ACQUIRED", @@ -104390,9 +104496,9 @@ function acquireJobLease(deps3, jobId, ownerId, policy) { }); return { acquired: true, lease }; } -function renewJobLease(deps3, jobId, ownerId, policy) { - const at = now5(deps3); - const existing = readLease(deps3.workspace, jobId); +function renewJobLease(deps4, jobId, ownerId, policy) { + const at = now5(deps4); + const existing = readLease(deps4.workspace, jobId); if (existing !== void 0 && existing.ownerId !== ownerId && isLeaseLive(existing, at)) { return void 0; } @@ -104403,30 +104509,30 @@ function renewJobLease(deps3, jobId, ownerId, policy) { now: at, ttlMs: policy.leaseTtlMs, pid: process.pid, - host: hostOf(deps3), + host: hostOf(deps4), schemaVersion: SUPERVISOR_SCHEMA_VERSION }); - return writeLease(deps3.workspace, claim2.lease); + return writeLease(deps4.workspace, claim2.lease); } -function releaseJobLease(deps3, jobId, ownerId, reason3) { - const existing = readLease(deps3.workspace, jobId); +function releaseJobLease(deps4, jobId, ownerId, reason3) { + const existing = readLease(deps4.workspace, jobId); if (existing === void 0 || existing.ownerId !== ownerId) return; - writeLease(deps3.workspace, releaseLeaseRecord(existing, now5(deps3), reason3)); - appendSupervisionLog(deps3, { ownerId, jobId, action: "RELEASED_ON_TERMINAL_STATUS", detail: reason3 }); + writeLease(deps4.workspace, releaseLeaseRecord(existing, now5(deps4), reason3)); + appendSupervisionLog(deps4, { ownerId, jobId, action: "RELEASED_ON_TERMINAL_STATUS", detail: reason3 }); } -async function superviseJob(deps3, jobId, options) { - const policy = autonomyPolicyOf(deps3).supervisor; +async function superviseJob(deps4, jobId, options) { + const policy = autonomyPolicyOf(deps4).supervisor; if (!policy.enabled) { throw new AutonomyError("SBA001", "The supervisor is disabled by `autonomy.supervisor.enabled`.", { remediation: ["Run `specbridge autonomy setup --mode overnight`, or drive the job in the foreground."] }); } - const ownerId = options.ownerId ?? `sup-${newId5(deps3)}`.slice(0, 60); + const ownerId = options.ownerId ?? `sup-${newId5(deps4)}`.slice(0, 60); const sleep2 = options.sleep ?? supervisorSleep; const emit22 = (kind, message2) => { options.onEvent?.({ kind, message: message2 }); }; - const acquisition = acquireJobLease(deps3, jobId, ownerId, policy); + const acquisition = acquireJobLease(deps4, jobId, ownerId, policy); if (!acquisition.acquired) { throw new AutonomyError( "SBA008", @@ -104441,14 +104547,14 @@ async function superviseJob(deps3, jobId, options) { ); } emit22("lease", `lease acquired by ${ownerId} (generation ${acquisition.lease?.generation ?? 1})`); - const sessionStartedAt = options.sessionStartedAt ?? nowIso5(deps3); - let job = requireJobState(deps3.workspace, jobId); - let supervised = registerSupervisedJob(deps3, { + const sessionStartedAt = options.sessionStartedAt ?? nowIso5(deps4); + let job = requireJobState(deps4.workspace, jobId); + let supervised = registerSupervisedJob(deps4, { jobId, specName: job.specName, ownerId }); - recordJobEvent(jobDepsOf(deps3), jobId, "supervisor_attached", { + recordJobEvent(jobDepsOf(deps4), jobId, "supervisor_attached", { ownerId, host: options.host.label }); @@ -104462,10 +104568,10 @@ async function superviseJob(deps3, jobId, options) { stop = { kind: "interrupted" }; break; } - job = requireJobState(deps3.workspace, jobId); - const fingerprint = fingerprintOf(deps3, job); + job = requireJobState(deps4.workspace, jobId); + const fingerprint = fingerprintOf(deps4, job); const decision = decideSupervision({ - now: now5(deps3), + now: now5(deps4), policy, status: job.status, ...job.operationalWait !== void 0 ? { wait: job.operationalWait } : {}, @@ -104479,7 +104585,7 @@ async function superviseJob(deps3, jobId, options) { sessionStartedAt }); emit22("decision", `${decision.action}: ${decision.reason}`); - const outcome = await applyDecision(deps3, { + const outcome = await applyDecision(deps4, { jobId, ownerId, policy, @@ -104495,47 +104601,47 @@ async function superviseJob(deps3, jobId, options) { stop = outcome.stop; break; } - renewJobLease(deps3, jobId, ownerId, policy); - persistSupervised(deps3, ownerId, supervised); + renewJobLease(deps4, jobId, ownerId, policy); + persistSupervised(deps4, ownerId, supervised); } } finally { - persistSupervised(deps3, ownerId, supervised); - releaseJobLease(deps3, jobId, ownerId, stop?.kind ?? "supervision ended"); - recordJobEvent(jobDepsOf(deps3), jobId, "supervisor_detached", { + persistSupervised(deps4, ownerId, supervised); + releaseJobLease(deps4, jobId, ownerId, stop?.kind ?? "supervision ended"); + recordJobEvent(jobDepsOf(deps4), jobId, "supervisor_detached", { ownerId, stop: stop?.kind ?? "unknown", cycles }); } - job = requireJobState(deps3.workspace, jobId); + job = requireJobState(deps4.workspace, jobId); return { stop: stop ?? { kind: "cycles-exhausted" }, job, supervised, cycles }; } -async function applyDecision(deps3, input) { +async function applyDecision(deps4, input) { const { decision, jobId, ownerId, policy } = input; switch (decision.action) { case "RELEASE": { - const job = requireJobState(deps3.workspace, jobId); - appendSupervisionLog(deps3, { + const job = requireJobState(deps4.workspace, jobId); + appendSupervisionLog(deps4, { ownerId, jobId, action: job.status === "COMPLETED" ? "RELEASED_ON_TERMINAL_STATUS" : "SESSION_BUDGET_REACHED", detail: decision.reason }); return { - supervised: { ...input.supervised, status: "RELEASED", releasedAt: nowIso5(deps3), releaseReason: decision.reason }, + supervised: { ...input.supervised, status: "RELEASED", releasedAt: nowIso5(deps4), releaseReason: decision.reason }, stop: job.status === "COMPLETED" ? { kind: "completed", status: job.status } : { kind: "released", reason: decision.reason } }; } case "WAIT_FOR_HUMAN": { - const job = requireJobState(deps3.workspace, jobId); - appendSupervisionLog(deps3, { + const job = requireJobState(deps4.workspace, jobId); + appendSupervisionLog(deps4, { ownerId, jobId, action: "RELEASED_ON_AUTHORITY_STOP", detail: decision.reason }); return { - supervised: { ...input.supervised, status: "RELEASED", releasedAt: nowIso5(deps3), releaseReason: decision.reason }, + supervised: { ...input.supervised, status: "RELEASED", releasedAt: nowIso5(deps4), releaseReason: decision.reason }, stop: { kind: "needs-human", status: decision.status, @@ -104544,21 +104650,21 @@ async function applyDecision(deps3, input) { }; } case "GIVE_UP": { - appendSupervisionLog(deps3, { + appendSupervisionLog(deps4, { ownerId, jobId, action: input.supervised.consecutiveRestarts >= policy.maxConsecutiveRestarts || input.supervised.restarts >= policy.maxRestarts ? "RESTART_BUDGET_EXHAUSTED" : "INDEFINITE_WAIT_CLASSIFIED", detail: decision.reason }); return { - supervised: { ...input.supervised, status: "RELEASED", releasedAt: nowIso5(deps3), releaseReason: decision.reason }, + supervised: { ...input.supervised, status: "RELEASED", releasedAt: nowIso5(deps4), releaseReason: decision.reason }, stop: { kind: "gave-up", reason: decision.reason } }; } case "SLEEP_UNTIL": { - const waitMs = Math.max(0, Date.parse(decision.wakeAt) - now5(deps3).getTime()); - appendSupervisionLog(deps3, { ownerId, jobId, action: "WAKE_SCHEDULED", detail: decision.reason }); - await sleepInSlices(deps3, { + const waitMs = Math.max(0, Date.parse(decision.wakeAt) - now5(deps4).getTime()); + appendSupervisionLog(deps4, { ownerId, jobId, action: "WAKE_SCHEDULED", detail: decision.reason }); + await sleepInSlices(deps4, { totalMs: waitMs, sliceMs: policy.heartbeatIntervalMs, jobId, @@ -104567,10 +104673,10 @@ async function applyDecision(deps3, input) { sleep: input.sleep, signal: input.options.signal }); - appendSupervisionLog(deps3, { ownerId, jobId, action: "WOKEN_ON_SCHEDULE", detail: decision.wakeAt }); - const job = requireJobState(deps3.workspace, jobId); + appendSupervisionLog(deps4, { ownerId, jobId, action: "WOKEN_ON_SCHEDULE", detail: decision.wakeAt }); + const job = requireJobState(deps4.workspace, jobId); if (isOperationalJobStatus(job.status)) { - clearOperationalState(jobDepsOf(deps3), jobId, { resolution: "the scheduled wait elapsed" }); + clearOperationalState(jobDepsOf(deps4), jobId, { resolution: "the scheduled wait elapsed" }); } return { supervised: { ...input.supervised, status: "SLEEPING" } }; } @@ -104583,20 +104689,20 @@ async function applyDecision(deps3, input) { if (decision.action === "RESTART_DRIVER" && decision.backoffMs > 0) { await input.sleep(decision.backoffMs, input.options.signal); } - const job = requireJobState(deps3.workspace, jobId); + const job = requireJobState(deps4.workspace, jobId); if (isOperationalJobStatus(job.status)) { - clearOperationalState(jobDepsOf(deps3), jobId, { + clearOperationalState(jobDepsOf(deps4), jobId, { resolution: "the supervisor is resuming the driver" }); } - appendSupervisionLog(deps3, { + appendSupervisionLog(deps4, { ownerId, jobId, action: decision.action === "START_DRIVER" ? "DRIVER_STARTED" : "DRIVER_RESTARTED", detail: decision.reason }); if (decision.action === "RESTART_DRIVER") { - countAutonomyEvent(jobDepsOf(deps3), jobId, "driverRestarts", "driver_restarted", { + countAutonomyEvent(jobDepsOf(deps4), jobId, "driverRestarts", "driver_restarted", { reason: decision.reason.slice(0, 300), restarts: input.supervised.restarts + 1 }); @@ -104606,10 +104712,10 @@ async function applyDecision(deps3, input) { ...input.options.signal !== void 0 ? { signal: input.options.signal } : {}, onEvent: (event) => input.emit("driver", `${event.kind}: ${event.message}`) }); - const supervised = foldDriverOutcome(deps3, input, outcome, decision.action); + const supervised = foldDriverOutcome(deps4, input, outcome, decision.action); if (outcome.kind === "exited" && outcome.stop.kind === "final") { - const job2 = requireJobState(deps3.workspace, jobId); - appendSupervisionLog(deps3, { + const job2 = requireJobState(deps4.workspace, jobId); + appendSupervisionLog(deps4, { ownerId, jobId, action: "CLOSURE_HANDOFF", @@ -104624,13 +104730,13 @@ async function applyDecision(deps3, input) { } } } -function foldDriverOutcome(deps3, input, outcome, action) { - const after = fingerprintOf(deps3, requireJobState(deps3.workspace, input.jobId)); +function foldDriverOutcome(deps4, input, outcome, action) { + const after = fingerprintOf(deps4, requireJobState(deps4.workspace, input.jobId)); const madeProgress = after !== input.fingerprint; const starts = input.supervised.starts + 1; const restarts = input.supervised.restarts + (action === "RESTART_DRIVER" ? 1 : 0); const unclean = outcome.kind === "crashed"; - appendSupervisionLog(deps3, { + appendSupervisionLog(deps4, { ownerId: input.ownerId, jobId: input.jobId, action: unclean ? "DRIVER_DIED" : "DRIVER_EXITED_CLEANLY", @@ -104645,10 +104751,10 @@ function foldDriverOutcome(deps3, input, outcome, action) { consecutiveRestarts: 0, backoffMs: 0, lastProgressFingerprint: after, - lastProgressAt: nowIso5(deps3), + lastProgressAt: nowIso5(deps4), nextAttemptAt: void 0, lastAction: unclean ? "DRIVER_DIED" : "DRIVER_EXITED_CLEANLY", - lastActionAt: nowIso5(deps3) + lastActionAt: nowIso5(deps4) }); } const backoffMs = nextBackoffMs( @@ -104664,21 +104770,21 @@ function foldDriverOutcome(deps3, input, outcome, action) { consecutiveRestarts: input.supervised.consecutiveRestarts + 1, backoffMs, lastProgressFingerprint: after, - nextAttemptAt: new Date(now5(deps3).getTime() + backoffMs).toISOString(), + nextAttemptAt: new Date(now5(deps4).getTime() + backoffMs).toISOString(), lastAction: unclean ? "DRIVER_DIED" : "DRIVER_EXITED_CLEANLY", - lastActionAt: nowIso5(deps3) + lastActionAt: nowIso5(deps4) }); } -async function sleepInSlices(deps3, input) { +async function sleepInSlices(deps4, input) { let remaining = input.totalMs; while (remaining > 0) { if (input.signal?.aborted === true) return; const slice = Math.min(remaining, Math.max(1, input.sliceMs)); await input.sleep(slice, input.signal); remaining -= slice; - const renewed = renewJobLease(deps3, input.jobId, input.ownerId, input.policy); + const renewed = renewJobLease(deps4, input.jobId, input.ownerId, input.policy); if (renewed === void 0) return; - appendSupervisionLog(deps3, { + appendSupervisionLog(deps4, { ownerId: input.ownerId, jobId: input.jobId, action: "LEASE_RENEWED", @@ -104686,19 +104792,19 @@ async function sleepInSlices(deps3, input) { }); } } -function persistSupervised(deps3, ownerId, supervised) { - const state = loadSupervisorState(deps3, ownerId); - writeSupervisorState(deps3.workspace, { +function persistSupervised(deps4, ownerId, supervised) { + const state = loadSupervisorState(deps4, ownerId); + writeSupervisorState(deps4.workspace, { ...upsertSupervisedJob(state, supervised), ownerId, - heartbeatAt: nowIso5(deps3) + heartbeatAt: nowIso5(deps4) }); } -function fingerprintOf(deps3, job) { +function fingerprintOf(deps4, job) { let completedNodes = 0; let totalAttempts = 0; try { - const graph = readGraphRevision(deps3.workspace, job.jobId, job.graphRevision); + const graph = readGraphRevision(deps4.workspace, job.jobId, job.graphRevision); if (graph !== void 0) { for (const node of graph.nodes) { if (node.status === "COMPLETED") completedNodes += 1; @@ -104878,13 +104984,13 @@ function detectBuildTool(projectDir) { return null; } var DEFAULT_MIN_FREE_DISK = 5 * 1024 * 1024 * 1024; -async function runOvernightPreflight(deps3, request) { - const policy = autonomyPolicyOf(deps3); - const projectDir = request.projectDir ?? deps3.workspace.rootDir; +async function runOvernightPreflight(deps4, request) { + const policy = autonomyPolicyOf(deps4); + const projectDir = request.projectDir ?? deps4.workspace.rootDir; const run = request.probeRunner ?? createProcessProbeRunner(projectDir); - const at = nowIso5(deps3); + const at = nowIso5(deps4); const checks = []; - const seal = resolveSeal(deps3, request); + const seal = resolveSeal(deps4, request); const add2 = (capability, outcome, observed, extra = {}) => { checks.push({ capability, @@ -104898,11 +105004,11 @@ async function runOvernightPreflight(deps3, request) { }; add2( "WORKSPACE_WRITABLE", - isWritableDirectory(deps3.workspace.rootDir) ? "READY" : "HUMAN_REQUIRED", - `workspace root ${deps3.workspace.rootDir}`, + isWritableDirectory(deps4.workspace.rootDir) ? "READY" : "HUMAN_REQUIRED", + `workspace root ${deps4.workspace.rootDir}`, { remediation: ["Grant write access to the workspace, or run from a writable checkout."] } ); - const free = freeDiskBytes(deps3.workspace.rootDir); + const free = freeDiskBytes(deps4.workspace.rootDir); const minFree = request.minFreeDiskBytes ?? DEFAULT_MIN_FREE_DISK; add2( "DISK_SPACE", @@ -104922,8 +105028,8 @@ async function runOvernightPreflight(deps3, request) { ); add2( "PROTECTED_PATHS_CONFIGURED", - deps3.config.execution.protectedPaths.length > 0 ? "READY" : "HUMAN_REQUIRED", - `${deps3.config.execution.protectedPaths.length} protected path pattern(s)`, + deps4.config.execution.protectedPaths.length > 0 ? "READY" : "HUMAN_REQUIRED", + `${deps4.config.execution.protectedPaths.length} protected path pattern(s)`, { remediation: [ "Declare protectedPaths in .specbridge/config.json before running unattended: an overnight run edits files for hours with nobody watching the diff." @@ -104931,7 +105037,7 @@ async function runOvernightPreflight(deps3, request) { } ); addSealChecks(add2, seal, policy); - const strongWorkers = Object.entries(deps3.config.runnerProfiles).filter( + const strongWorkers = Object.entries(deps4.config.runnerProfiles).filter( ([name]) => name !== "mock" ); add2( @@ -104944,7 +105050,7 @@ async function runOvernightPreflight(deps3, request) { ] } ); - const localInference = deps3.config.localInference; + const localInference = deps4.config.localInference; add2( "LOCAL_MODEL_STARTABLE", localInference.enabled ? "READY" : "NOT_APPLICABLE", @@ -104955,7 +105061,7 @@ async function runOvernightPreflight(deps3, request) { ] } ); - const apiPolicy = deps3.config.orchestration.jobs.scheduler.api; + const apiPolicy = deps4.config.orchestration.jobs.scheduler.api; const spendMode = apiPolicy.spendMode; add2( "API_FALLBACK_AUTHORIZED", @@ -104981,8 +105087,8 @@ async function runOvernightPreflight(deps3, request) { ); add2( "TRUSTED_VERIFICATION_CONFIGURED", - deps3.config.verification.commands.length > 0 ? "READY" : "HUMAN_REQUIRED", - `${deps3.config.verification.commands.length} trusted verification command(s)`, + deps4.config.verification.commands.length > 0 ? "READY" : "HUMAN_REQUIRED", + `${deps4.config.verification.commands.length} trusted verification command(s)`, { remediation: [ "Configure verification commands. Without them nothing can close a contract item on trusted evidence, and the run cannot legitimately reach COMPLETED." @@ -105099,7 +105205,7 @@ async function runOvernightPreflight(deps3, request) { ] } ); - const report = buildReport(deps3, { + const report = buildReport(deps4, { request, policy, seal, @@ -105107,15 +105213,15 @@ async function runOvernightPreflight(deps3, request) { at }); writeJsonRecord( - autonomyPath(deps3.workspace, "preflight", `${report.reportId}.json`), + autonomyPath(deps4.workspace, "preflight", `${report.reportId}.json`), report ); return report; } -function resolveSeal(deps3, request) { - if (request.sealId !== void 0) return readSeal(deps3.workspace, request.sealId); - if (request.missionId !== void 0) return latestExecutableSeal(deps3.workspace, request.missionId); - return latestExecutableSeal(deps3.workspace, request.subject); +function resolveSeal(deps4, request) { + if (request.sealId !== void 0) return readSeal(deps4.workspace, request.sealId); + if (request.missionId !== void 0) return latestExecutableSeal(deps4.workspace, request.missionId); + return latestExecutableSeal(deps4.workspace, request.subject); } function addSealChecks(add2, seal, policy) { if (seal === void 0) { @@ -105156,7 +105262,7 @@ function addSealChecks(add2, seal, policy) { function toolsmithGrants(policy, capability) { return policy.toolsmith.enabled && policy.toolsmith.capabilities.includes(capability); } -function buildReport(deps3, input) { +function buildReport(deps4, input) { const humanActions = []; const autonomousActions = []; const unknowns = []; @@ -105174,9 +105280,9 @@ function buildReport(deps3, input) { const verdict = humanActions.length > 0 ? "HUMAN_ACTION_REQUIRED" : unknowns.length > 0 ? "INDETERMINATE" : "OVERNIGHT_READY"; return preflightReportSchema.parse({ schemaVersion: PREFLIGHT_SCHEMA_VERSION, - reportId: input.request.reportId ?? newRecordId(deps3, "pf"), + reportId: input.request.reportId ?? newRecordId(deps4, "pf"), createdAt: input.at, - host: hostOf(deps3), + host: hostOf(deps4), subject: input.request.subject, ...input.request.missionId !== void 0 ? { missionId: input.request.missionId } : {}, ...input.seal !== void 0 ? { sealId: input.seal.sealId } : {}, @@ -105446,9 +105552,9 @@ function listToolsmithRequests(workspace, jobId) { (raw) => toolsmithRequestSchema.parse(raw) ).sort((a2, b) => a2.requestedAt.localeCompare(b.requestedAt)); } -function requestToolsmithCapability(deps3, input) { - const policy = autonomyPolicyOf(deps3); - const ledger = loadLedger(deps3, input.jobId); +function requestToolsmithCapability(deps4, input) { + const policy = autonomyPolicyOf(deps4); + const ledger = loadLedger(deps4, input.jobId); const scope = input.scope ?? preferredScopeFor(input.capability); const decision = decideToolsmithRequest( { @@ -105460,15 +105566,15 @@ function requestToolsmithCapability(deps3, input) { }, { policy, - workspaceRoot: deps3.workspace.rootDir, - protectedPaths: deps3.config.execution.protectedPaths, + workspaceRoot: deps4.workspace.rootDir, + protectedPaths: deps4.config.execution.protectedPaths, grantsUsed: ledger.granted } ); - const at = nowIso5(deps3); + const at = nowIso5(deps4); const request = toolsmithRequestSchema.parse({ schemaVersion: TOOLSMITH_SCHEMA_VERSION, - requestId: input.requestId ?? newRecordId(deps3, "ts"), + requestId: input.requestId ?? newRecordId(deps4, "ts"), jobId: input.jobId, capability: input.capability, purpose: input.purpose.slice(0, 4e3), @@ -105484,19 +105590,19 @@ function requestToolsmithCapability(deps3, input) { ...decision.suggestedAlternative !== void 0 ? { suggestedAlternative: decision.suggestedAlternative } : {} } }); - writeJsonRecord(requestFile(deps3.workspace, input.jobId, request.requestId), request); - saveLedger(deps3, input.jobId, { + writeJsonRecord(requestFile(deps4.workspace, input.jobId, request.requestId), request); + saveLedger(deps4, input.jobId, { ...ledger, granted: ledger.granted + (decision.granted ? 1 : 0), denied: ledger.denied + (decision.granted ? 0 : 1) }); - recordToolsmithEvent(deps3, input.jobId, request, decision); + recordToolsmithEvent(deps4, input.jobId, request, decision); return { request, decision }; } -function recordToolsmithEvent(deps3, jobId, request, decision) { +function recordToolsmithEvent(deps4, jobId, request, decision) { try { recordJobEvent( - jobDepsOf(deps3), + jobDepsOf(deps4), jobId, decision.granted ? "toolsmith_grant_issued" : "toolsmith_grant_denied", { @@ -105513,16 +105619,16 @@ function recordToolsmithEvent(deps3, jobId, request, decision) { function writesFileDirectly(capability) { return capability === "PROJECT_LOCAL_SCRIPT" || capability === "CODE_GENERATION"; } -function loadLedger(deps3, jobId) { - return readToolsmithLedger(deps3.workspace, jobId) ?? toolsmithLedgerSchema.parse({ +function loadLedger(deps4, jobId) { + return readToolsmithLedger(deps4.workspace, jobId) ?? toolsmithLedgerSchema.parse({ schemaVersion: TOOLSMITH_SCHEMA_VERSION, jobId, - updatedAt: nowIso5(deps3) + updatedAt: nowIso5(deps4) }); } -function saveLedger(deps3, jobId, ledger) { - const next = toolsmithLedgerSchema.parse({ ...ledger, updatedAt: nowIso5(deps3) }); - writeJsonRecord(ledgerFile(deps3.workspace, jobId), next); +function saveLedger(deps4, jobId, ledger) { + const next = toolsmithLedgerSchema.parse({ ...ledger, updatedAt: nowIso5(deps4) }); + writeJsonRecord(ledgerFile(deps4.workspace, jobId), next); return next; } function countSelfCreatedTools(workspace, jobId) { @@ -105843,8 +105949,8 @@ function defaultSleep2(ms, signal) { }, { once: true }); }); } -async function provisionEnvironment(deps3, options) { - const policy = autonomyPolicyOf(deps3).environments; +async function provisionEnvironment(deps4, options) { + const policy = autonomyPolicyOf(deps4).environments; if (!policy.enabled) { throw new AutonomyError( "SBA016", @@ -105852,7 +105958,7 @@ async function provisionEnvironment(deps3, options) { { remediation: ["Enable it, or provide the environment yourself before the run."] } ); } - const plan = readEnvironmentPlan(deps3.workspace, options.planId); + const plan = readEnvironmentPlan(deps4.workspace, options.planId); if (plan === void 0) { throw new AutonomyError("SBA014", `No environment plan "${options.planId}" exists.`, { details: { planId: options.planId } @@ -105860,50 +105966,50 @@ async function provisionEnvironment(deps3, options) { } const ordered = orderServicesForReadiness(plan); const sleep2 = options.sleep ?? defaultSleep2; - const probe = options.probeExecutor ?? createReadinessProbeExecutor({ cwd: deps3.workspace.rootDir }); + const probe = options.probeExecutor ?? createReadinessProbeExecutor({ cwd: deps4.workspace.rootDir }); const emit22 = options.onEvent ?? (() => void 0); let instance = writeInstance( - deps3, + deps4, environmentInstanceSchema.parse({ schemaVersion: ENVIRONMENT_SCHEMA_VERSION, - instanceId: options.instanceId ?? newRecordId(deps3, "envi"), + instanceId: options.instanceId ?? newRecordId(deps4, "envi"), planId: plan.planId, ...options.jobId !== void 0 ? { jobId: options.jobId } : {}, status: "PROVISIONING", - createdAt: nowIso5(deps3), + createdAt: nowIso5(deps4), services: ordered.map((service) => ({ serviceId: service.serviceId, status: "PENDING" })) }) ); - emitJobEvent(deps3, options.jobId, "environment_provision_started", { + emitJobEvent(deps4, options.jobId, "environment_provision_started", { planId: plan.planId, instanceId: instance.instanceId, services: ordered.length }); - const startedAtMs = now5(deps3).getTime(); + const startedAtMs = now5(deps4).getTime(); const provisioned = await options.runtime.provision({ plan, - workspaceRoot: deps3.workspace.rootDir, + workspaceRoot: deps4.workspace.rootDir, timeoutMs: policy.readinessTimeoutMs, ...options.signal !== void 0 ? { signal: options.signal } : {} }); if (!provisioned.ok) { emit22(`provisioning failed: ${provisioned.detail}`); - return finishFailed(deps3, options, plan, instance, { + return finishFailed(deps4, options, plan, instance, { failureKind: provisioned.failureKind ?? "RUNTIME_UNAVAILABLE", detail: provisioned.detail }); } - instance = writeInstance(deps3, { + instance = writeInstance(deps4, { ...instance, status: "WAITING_READY", services: instance.services.map((service) => ({ ...service, status: "STARTING", - startedAt: nowIso5(deps3) + startedAt: nowIso5(deps4) })) }); for (const service of ordered) { - const result = await waitForService(deps3, { + const result = await waitForService(deps4, { plan, service, instance, @@ -105914,7 +106020,7 @@ async function provisionEnvironment(deps3, options) { emit: emit22, ...options.signal !== void 0 ? { signal: options.signal } : {} }); - instance = writeInstance(deps3, { + instance = writeInstance(deps4, { ...instance, services: instance.services.map( (entry2) => entry2.serviceId === service.serviceId ? result.state : entry2 @@ -105922,37 +106028,37 @@ async function provisionEnvironment(deps3, options) { repairs: instance.repairs + result.restarts }); if (result.state.status !== "READY") { - return finishFailed(deps3, options, plan, instance, { + return finishFailed(deps4, options, plan, instance, { failureKind: result.state.failureKind ?? "READINESS_TIMEOUT", detail: result.state.lastProbeDetail ?? `service ${service.serviceId} never became ready` }); } } - const ready = writeInstance(deps3, { + const ready = writeInstance(deps4, { ...instance, status: "READY", - readyAt: nowIso5(deps3) + readyAt: nowIso5(deps4) }); - writeEvidence(deps3, plan, ready, now5(deps3).getTime() - startedAtMs, []); - emitJobEvent(deps3, options.jobId, "environment_ready", { + writeEvidence(deps4, plan, ready, now5(deps4).getTime() - startedAtMs, []); + emitJobEvent(deps4, options.jobId, "environment_ready", { instanceId: ready.instanceId, planId: plan.planId }); return ready; } -async function waitForService(deps3, input) { +async function waitForService(deps4, input) { const { service, probe, sleep: sleep2, policy } = input; - const deadlineMs = now5(deps3).getTime() + Math.min(service.readinessTimeoutMs, policy.readinessTimeoutMs); + const deadlineMs = now5(deps4).getTime() + Math.min(service.readinessTimeoutMs, policy.readinessTimeoutMs); const maxRestarts = Math.min(service.maxRestarts, policy.maxServiceRestarts); let state = { serviceId: service.serviceId, status: "WAITING_READY", - startedAt: nowIso5(deps3), + startedAt: nowIso5(deps4), restarts: 0, probeAttempts: 0 }; let restarts = 0; - while (now5(deps3).getTime() < deadlineMs) { + while (now5(deps4).getTime() < deadlineMs) { if (input.signal?.aborted === true) { return { state: { ...state, status: "FAILED", failureKind: "UNKNOWN" }, restarts }; } @@ -105975,7 +106081,7 @@ async function waitForService(deps3, input) { state: { ...state, status: "READY", - readyAt: nowIso5(deps3), + readyAt: nowIso5(deps4), lastProbeKind: lastKind, lastProbeDetail: lastDetail }, @@ -105983,14 +106089,14 @@ async function waitForService(deps3, input) { }; } state = { ...state, lastProbeKind: lastKind, lastProbeDetail: lastDetail }; - const elapsedFraction = 1 - (deadlineMs - now5(deps3).getTime()) / Math.max(1, service.readinessTimeoutMs); + const elapsedFraction = 1 - (deadlineMs - now5(deps4).getTime()) / Math.max(1, service.readinessTimeoutMs); if (restarts < maxRestarts && elapsedFraction > (restarts + 1) / (maxRestarts + 1)) { restarts += 1; input.emit(`${service.serviceId} not ready after ${state.probeAttempts} probes; restarting`); const restarted = await input.runtime.restart({ plan: input.plan, service, - workspaceRoot: deps3.workspace.rootDir, + workspaceRoot: deps4.workspace.rootDir, timeoutMs: policy.readinessTimeoutMs, ...input.signal !== void 0 ? { signal: input.signal } : {} }); @@ -106013,8 +106119,8 @@ async function waitForService(deps3, input) { restarts }; } -async function finishFailed(deps3, options, plan, instance, failure3) { - const policy = autonomyPolicyOf(deps3).environments; +async function finishFailed(deps4, options, plan, instance, failure3) { + const policy = autonomyPolicyOf(deps4).environments; const logRefs = []; if (policy.retainDiagnosticsOnFailure) { for (const service of plan.services) { @@ -106022,15 +106128,15 @@ async function finishFailed(deps3, options, plan, instance, failure3) { const text142 = await options.runtime.logs({ plan, service, - workspaceRoot: deps3.workspace.rootDir, + workspaceRoot: deps4.workspace.rootDir, maxBytes: policy.maxLogBytesPerService }); - if (text142.length > 0) logRefs.push(retainLog(deps3, instance.instanceId, service.serviceId, text142)); + if (text142.length > 0) logRefs.push(retainLog(deps4, instance.instanceId, service.serviceId, text142)); } catch { } } } - const failed = writeInstance(deps3, { + const failed = writeInstance(deps4, { ...instance, status: "FAILED", failureKind: failure3.failureKind, @@ -106040,8 +106146,8 @@ async function finishFailed(deps3, options, plan, instance, failure3) { (service) => service.status === "READY" ? service : { ...service, status: "FAILED" } ) }); - writeEvidence(deps3, plan, failed, null, logRefs); - emitJobEvent(deps3, options.jobId, "environment_failed", { + writeEvidence(deps4, plan, failed, null, logRefs); + emitJobEvent(deps4, options.jobId, "environment_failed", { instanceId: failed.instanceId, planId: plan.planId, failureKind: failure3.failureKind, @@ -106049,7 +106155,7 @@ async function finishFailed(deps3, options, plan, instance, failure3) { }); return failed; } -function retainLog(deps3, instanceId, serviceId, text142) { +function retainLog(deps4, instanceId, serviceId, text142) { const relative = import_path86.default.posix.join( ".specbridge", "autonomy", @@ -106058,42 +106164,42 @@ function retainLog(deps3, instanceId, serviceId, text142) { instanceId, `${serviceId}.log` ); - const absolute = autonomyPath(deps3.workspace, "environments", "logs", instanceId, `${serviceId}.log`); + const absolute = autonomyPath(deps4.workspace, "environments", "logs", instanceId, `${serviceId}.log`); (0, import_fs78.mkdirSync)(import_path86.default.dirname(absolute), { recursive: true }); (0, import_fs78.writeFileSync)(absolute, text142, "utf8"); return relative; } -async function teardownEnvironment(deps3, input) { - const instance = readEnvironmentInstance(deps3.workspace, input.instanceId); +async function teardownEnvironment(deps4, input) { + const instance = readEnvironmentInstance(deps4.workspace, input.instanceId); if (instance === void 0) { throw new AutonomyError("SBA014", `No environment instance "${input.instanceId}" exists.`); } - const plan = readEnvironmentPlan(deps3.workspace, instance.planId); + const plan = readEnvironmentPlan(deps4.workspace, instance.planId); if (plan === void 0) { throw new AutonomyError("SBA014", `Environment plan "${instance.planId}" is missing.`); } - const policy = autonomyPolicyOf(deps3).environments; + const policy = autonomyPolicyOf(deps4).environments; const retain = input.retain ?? (instance.status === "FAILED" && policy.retainDiagnosticsOnFailure); await input.runtime.teardown({ plan, - workspaceRoot: deps3.workspace.rootDir, + workspaceRoot: deps4.workspace.rootDir, timeoutMs: policy.readinessTimeoutMs, retain }); - const stopped = writeInstance(deps3, { + const stopped = writeInstance(deps4, { ...instance, status: "STOPPED", - stoppedAt: nowIso5(deps3), + stoppedAt: nowIso5(deps4), diagnosticsRetained: retain, services: instance.services.map((service) => ({ ...service, status: "STOPPED" })) }); - emitJobEvent(deps3, instance.jobId, "environment_torn_down", { + emitJobEvent(deps4, instance.jobId, "environment_torn_down", { instanceId: stopped.instanceId, retained: retain }); return stopped; } -function writeEvidence(deps3, plan, instance, totalMs, logRefs) { +function writeEvidence(deps4, plan, instance, totalMs, logRefs) { const byId = new Map(plan.services.map((service) => [service.serviceId, service])); const applicationLevelReady = []; const livenessOnlyReady = []; @@ -106111,7 +106217,7 @@ function writeEvidence(deps3, plan, instance, totalMs, logRefs) { schemaVersion: ENVIRONMENT_SCHEMA_VERSION, instanceId: instance.instanceId, planId: plan.planId, - recordedAt: nowIso5(deps3), + recordedAt: nowIso5(deps4), status: instance.status, applicationLevelReady, livenessOnlyReady, @@ -106119,18 +106225,18 @@ function writeEvidence(deps3, plan, instance, totalMs, logRefs) { totalReadinessMs: totalMs, logRefs: [...logRefs].slice(0, 60) }); - writeJsonRecord(environmentEvidenceFile(deps3.workspace, instance.instanceId), evidence); + writeJsonRecord(environmentEvidenceFile(deps4.workspace, instance.instanceId), evidence); return evidence; } -function writeInstance(deps3, instance) { +function writeInstance(deps4, instance) { const validated = environmentInstanceSchema.parse(instance); - writeJsonRecord(environmentInstanceFile(deps3.workspace, validated.instanceId), validated); + writeJsonRecord(environmentInstanceFile(deps4.workspace, validated.instanceId), validated); return validated; } -function emitJobEvent(deps3, jobId, type, payload) { +function emitJobEvent(deps4, jobId, type, payload) { if (jobId === void 0) return; try { - recordJobEvent(jobDepsOf(deps3), jobId, type, payload); + recordJobEvent(jobDepsOf(deps4), jobId, type, payload); } catch { } } @@ -106367,8 +106473,8 @@ function listBrowserResults(workspace) { (raw) => browserScenarioResultSchema.parse(raw) ).sort((a2, b) => a2.startedAt.localeCompare(b.startedAt)); } -async function runBrowserScenario(deps3, options) { - const policy = autonomyPolicyOf(deps3).browser; +async function runBrowserScenario(deps4, options) { + const policy = autonomyPolicyOf(deps4).browser; if (!policy.enabled) { throw new AutonomyError( "SBA018", @@ -106376,7 +106482,7 @@ async function runBrowserScenario(deps3, options) { { remediation: ["Enable it, or close UI criteria on other evidence."] } ); } - const scenario = readBrowserScenario(deps3.workspace, options.scenarioId); + const scenario = readBrowserScenario(deps4.workspace, options.scenarioId); if (scenario === void 0) { throw new AutonomyError("SBA017", `No browser scenario "${options.scenarioId}" exists.`); } @@ -106387,10 +106493,10 @@ async function runBrowserScenario(deps3, options) { { remediation: ["Raise autonomy.browser.maxContexts, or split the scenario."] } ); } - const resultId = options.resultId ?? newRecordId(deps3, "br"); - const startedAt = nowIso5(deps3); - const startedMs = now5(deps3).getTime(); - emitJobEvent2(deps3, options.jobId, "browser_scenario_started", { + const resultId = options.resultId ?? newRecordId(deps4, "br"); + const startedAt = nowIso5(deps4); + const startedMs = now5(deps4).getTime(); + emitJobEvent2(deps4, options.jobId, "browser_scenario_started", { scenarioId: scenario.scenarioId, resultId, contexts: scenario.contexts.length @@ -106398,7 +106504,7 @@ async function runBrowserScenario(deps3, options) { const availability = await options.driver.available(); if (!availability.ok) { return persist3( - deps3, + deps4, browserScenarioResultSchema.parse({ schemaVersion: BROWSER_SCHEMA_VERSION, resultId, @@ -106406,7 +106512,7 @@ async function runBrowserScenario(deps3, options) { ...options.jobId !== void 0 ? { jobId: options.jobId } : {}, status: "SKIPPED_NO_RUNTIME", startedAt, - finishedAt: nowIso5(deps3), + finishedAt: nowIso5(deps4), driver: options.driver.label, skipReason: availability.reason }), @@ -106428,7 +106534,7 @@ async function runBrowserScenario(deps3, options) { }); } catch (cause) { return persist3( - deps3, + deps4, browserScenarioResultSchema.parse({ schemaVersion: BROWSER_SCHEMA_VERSION, resultId, @@ -106436,7 +106542,7 @@ async function runBrowserScenario(deps3, options) { ...options.jobId !== void 0 ? { jobId: options.jobId } : {}, status: "ERRORED", startedAt, - finishedAt: nowIso5(deps3), + finishedAt: nowIso5(deps4), driver: options.driver.label, failureDetail: (cause instanceof Error ? cause.message : String(cause)).slice(0, 4e3) }), @@ -106449,7 +106555,7 @@ async function runBrowserScenario(deps3, options) { failureDetail = "the scenario was cancelled"; break; } - const before = now5(deps3).getTime(); + const before = now5(deps4).getTime(); const outcome = await session.step(step2); const assertion = isAssertionStep(step2); if (assertion) { @@ -106459,7 +106565,7 @@ async function runBrowserScenario(deps3, options) { let evidenceRef; if (outcome.evidence !== void 0 && policy.captureScreenshots) { evidenceRef = writeEvidenceFile( - deps3, + deps4, resultId, `${String(index).padStart(3, "0")}-${outcome.evidence.label}`, outcome.evidence.kind === "SCREENSHOT" ? "png" : "html", @@ -106478,7 +106584,7 @@ async function runBrowserScenario(deps3, options) { context: step2.context, ok: outcome.ok, detail: outcome.detail.slice(0, 4e3), - durationMs: Math.max(0, now5(deps3).getTime() - before), + durationMs: Math.max(0, now5(deps4).getTime() - before), ...evidenceRef !== void 0 ? { evidenceRef } : {} }); if (!outcome.ok) { @@ -106487,7 +106593,7 @@ async function runBrowserScenario(deps3, options) { if (snapshot2.length > 0) { evidence.push({ kind: "DOM_SNAPSHOT", - ref: writeEvidenceFile(deps3, resultId, `${String(index).padStart(3, "0")}-dom`, "html", snapshot2), + ref: writeEvidenceFile(deps4, resultId, `${String(index).padStart(3, "0")}-dom`, "html", snapshot2), label: "dom-at-failure", context: step2.context }); @@ -106500,7 +106606,7 @@ async function runBrowserScenario(deps3, options) { evidence.push({ kind: "CONSOLE_LOG", ref: writeEvidenceFile( - deps3, + deps4, resultId, "console", "json", @@ -106512,7 +106618,7 @@ async function runBrowserScenario(deps3, options) { } const status = failureDetail !== void 0 ? "FAILED" : assertionsRun > 0 ? "PASSED" : "FAILED"; return persist3( - deps3, + deps4, browserScenarioResultSchema.parse({ schemaVersion: BROWSER_SCHEMA_VERSION, resultId, @@ -106520,7 +106626,7 @@ async function runBrowserScenario(deps3, options) { ...options.jobId !== void 0 ? { jobId: options.jobId } : {}, status, startedAt, - finishedAt: nowIso5(deps3), + finishedAt: nowIso5(deps4), driver: options.driver.label, steps, assertionsRun, @@ -106528,7 +106634,7 @@ async function runBrowserScenario(deps3, options) { observations: observations.slice(0, 200), evidence, ...failureDetail !== void 0 ? { failureDetail } : assertionsRun === 0 ? { failureDetail: "the scenario ran no assertions and therefore proved nothing" } : {}, - durationMs: now5(deps3).getTime() - startedMs + durationMs: now5(deps4).getTime() - startedMs }), options.jobId ); @@ -106536,10 +106642,10 @@ async function runBrowserScenario(deps3, options) { await session.close(); } } -function writeEvidenceFile(deps3, resultId, name, extension, data) { +function writeEvidenceFile(deps4, resultId, name, extension, data) { const safe = name.replace(/[^A-Za-z0-9._-]/g, "-").slice(0, 60); const absolute = autonomyPath( - deps3.workspace, + deps4.workspace, "browser", "evidence", resultId, @@ -106556,9 +106662,9 @@ function writeEvidenceFile(deps3, resultId, name, extension, data) { `${safe}.${extension}` ); } -function persist3(deps3, result, jobId) { - writeJsonRecord(browserResultFile(deps3.workspace, result.resultId), result); - emitJobEvent2(deps3, jobId, "browser_scenario_completed", { +function persist3(deps4, result, jobId) { + writeJsonRecord(browserResultFile(deps4.workspace, result.resultId), result); + emitJobEvent2(deps4, jobId, "browser_scenario_completed", { scenarioId: result.scenarioId, resultId: result.resultId, status: result.status, @@ -106567,10 +106673,10 @@ function persist3(deps3, result, jobId) { }); return result; } -function emitJobEvent2(deps3, jobId, type, payload) { +function emitJobEvent2(deps4, jobId, type, payload) { if (jobId === void 0) return; try { - recordJobEvent(jobDepsOf(deps3), jobId, type, payload); + recordJobEvent(jobDepsOf(deps4), jobId, type, payload); } catch { } } @@ -106731,12 +106837,12 @@ async function runStep(page, step2, request, observations) { return { ok: true, detail: `context switched to ${step2.context}` }; } case "EXPECT_SELECTOR": { - const count22 = await page.locator(requireSelector(step2)).count(); - return count22 > 0 ? { ok: true, detail: `${step2.selector} present (${count22})` } : { ok: false, detail: `${step2.selector} was not present` }; + const count32 = await page.locator(requireSelector(step2)).count(); + return count32 > 0 ? { ok: true, detail: `${step2.selector} present (${count32})` } : { ok: false, detail: `${step2.selector} was not present` }; } case "EXPECT_ABSENT": { - const count22 = await page.locator(requireSelector(step2)).count(); - return count22 === 0 ? { ok: true, detail: `${step2.selector} absent` } : { ok: false, detail: `${step2.selector} was present (${count22})` }; + const count32 = await page.locator(requireSelector(step2)).count(); + return count32 === 0 ? { ok: true, detail: `${step2.selector} absent` } : { ok: false, detail: `${step2.selector} was present (${count32})` }; } case "EXPECT_TEXT": { const body = String(await page.innerText("body")).slice(0, 2e5); @@ -107178,10 +107284,10 @@ function readClosureLedger(workspace, jobId) { (raw) => closureLedgerSchema.parse(raw) ); } -function buildClosureLedger(deps3, input) { - const at = nowIso5(deps3); +function buildClosureLedger(deps4, input) { + const at = nowIso5(deps4); const entries = []; - const registry2 = readContractRegistry(deps3.workspace, input.seal.missionId); + const registry2 = readContractRegistry(deps4.workspace, input.seal.missionId); const byContract = new Map(registry2.map((contract) => [contract.contractId, contract])); for (const ref of input.seal.contracts) { const contract = byContract.get(ref.contractId); @@ -107229,7 +107335,7 @@ function buildClosureLedger(deps3, input) { phase: "IMPLEMENTATION", entries }); - writeJsonRecord(closureLedgerFile(deps3.workspace, input.jobId), ledger); + writeJsonRecord(closureLedgerFile(deps4.workspace, input.jobId), ledger); return ledger; } function entry(at, input) { @@ -107248,9 +107354,9 @@ function entry(at, input) { updatedAt: at }; } -function attributeNodeToItems(deps3, input) { - const ledger = requireLedger(deps3.workspace, input.jobId); - const at = nowIso5(deps3); +function attributeNodeToItems(deps4, input) { + const ledger = requireLedger(deps4.workspace, input.jobId); + const at = nowIso5(deps4); const entries = ledger.entries.map((existing) => { if (!input.itemIds.includes(existing.itemId)) return existing; if (existing.attributedNodeIds.includes(input.nodeId)) return existing; @@ -107261,11 +107367,11 @@ function attributeNodeToItems(deps3, input) { updatedAt: at }; }); - return saveLedger2(deps3, { ...ledger, entries }); + return saveLedger2(deps4, { ...ledger, entries }); } -function registerClosureEvidence(deps3, input) { - const ledger = requireLedger(deps3.workspace, input.jobId); - const at = nowIso5(deps3); +function registerClosureEvidence(deps4, input) { + const ledger = requireLedger(deps4.workspace, input.jobId); + const at = nowIso5(deps4); const entries = ledger.entries.map((existing) => { if (!input.itemIds.includes(existing.itemId)) return existing; return { @@ -107286,11 +107392,11 @@ function registerClosureEvidence(deps3, input) { updatedAt: at }; }); - return saveLedger2(deps3, { ...ledger, entries }); + return saveLedger2(deps4, { ...ledger, entries }); } -function waiveClosureItem(deps3, input) { - const ledger = requireLedger(deps3.workspace, input.jobId); - const at = nowIso5(deps3); +function waiveClosureItem(deps4, input) { + const ledger = requireLedger(deps4.workspace, input.jobId); + const at = nowIso5(deps4); const entries = ledger.entries.map( (existing) => existing.itemId === input.itemId ? { ...existing, @@ -107304,19 +107410,19 @@ function waiveClosureItem(deps3, input) { updatedAt: at } : existing ); - return saveLedger2(deps3, { ...ledger, entries }); + return saveLedger2(deps4, { ...ledger, entries }); } -function runClosureAudit(deps3, input) { - const policy = autonomyPolicyOf(deps3).closure; - const ledger = requireLedger(deps3.workspace, input.jobId); +function runClosureAudit(deps4, input) { + const policy = autonomyPolicyOf(deps4).closure; + const ledger = requireLedger(deps4.workspace, input.jobId); const completed = new Set(input.completedNodeIds); - const at = nowIso5(deps3); + const at = nowIso5(deps4); const entries = ledger.entries.map((existing) => { const attributedNodesComplete = existing.attributedNodeIds.length > 0 && existing.attributedNodeIds.every((nodeId) => completed.has(nodeId)); const assessment = assessItemClosure( existing, { - now: now5(deps3), + now: now5(deps4), ...input.gitHead !== void 0 ? { gitHead: input.gitHead } : {}, ...input.maxEvidenceAgeMs !== void 0 ? { maxEvidenceAgeMs: input.maxEvidenceAgeMs } : {} }, @@ -107330,7 +107436,7 @@ function runClosureAudit(deps3, input) { const totals = summarizeClosure(entries); const audit = closureAuditSchema.parse({ schemaVersion: CLOSURE_SCHEMA_VERSION, - auditId: input.auditId ?? newRecordId(deps3, "ca"), + auditId: input.auditId ?? newRecordId(deps4, "ca"), jobId: input.jobId, sealId: ledger.sealId, createdAt: at, @@ -107346,13 +107452,13 @@ function runClosureAudit(deps3, input) { })), rationale: verdict.rationale }); - const saved = saveLedger2(deps3, { ...ledger, entries, phase: verdict.nextPhase }); + const saved = saveLedger2(deps4, { ...ledger, entries, phase: verdict.nextPhase }); writeJsonRecord( - autonomyPath(deps3.workspace, "closure", input.jobId, "audits", `${audit.auditId}.json`), + autonomyPath(deps4.workspace, "closure", input.jobId, "audits", `${audit.auditId}.json`), audit ); try { - recordJobEvent(jobDepsOf(deps3), input.jobId, "closure_audit_completed", { + recordJobEvent(jobDepsOf(deps4), input.jobId, "closure_audit_completed", { auditId: audit.auditId, directive: audit.directive, phase: audit.phase, @@ -107364,24 +107470,24 @@ function runClosureAudit(deps3, input) { } return { ledger: saved, audit }; } -function attributeCompletedWork(deps3, input) { - const mission = requireMissionState(deps3.workspace, input.missionId); - const graph = requireJobState(deps3.workspace, input.jobId).graphRevision > 0 ? readGraphRevision( - deps3.workspace, +function attributeCompletedWork(deps4, input) { + const mission = requireMissionState(deps4.workspace, input.missionId); + const graph = requireJobState(deps4.workspace, input.jobId).graphRevision > 0 ? readGraphRevision( + deps4.workspace, input.jobId, - requireJobState(deps3.workspace, input.jobId).graphRevision + requireJobState(deps4.workspace, input.jobId).graphRevision ) : void 0; if (graph === void 0) return { attributed: 0 }; - const ledger = requireLedger(deps3.workspace, input.jobId); - const seal = latestExecutableSeal(deps3.workspace, input.missionId); + const ledger = requireLedger(deps4.workspace, input.jobId); + const seal = latestExecutableSeal(deps4.workspace, input.missionId); const criterionContracts = new Map( (seal?.acceptanceCriteria ?? []).map((criterion) => [criterion.criterionId, criterion.contractIds]) ); let attributed = 0; for (const node of graph.nodes) { if (node.status !== "COMPLETED") continue; - const contractIds = contractsForObjective(deps3.workspace, mission, node.parentTaskId); - const acceptance = acceptanceForObjective(deps3.workspace, mission, node.parentTaskId).map((line) => line.trim().toLowerCase()).filter((line) => line.length >= 12); + const contractIds = contractsForObjective(deps4.workspace, mission, node.parentTaskId); + const acceptance = acceptanceForObjective(deps4.workspace, mission, node.parentTaskId).map((line) => line.trim().toLowerCase()).filter((line) => line.length >= 12); const itemIds = ledger.entries.filter((entry2) => { const owner = entry2.itemId.split(/[/#]/)[0] ?? ""; if (contractIds.includes(owner)) return true; @@ -107394,13 +107500,13 @@ function attributeCompletedWork(deps3, input) { ); }).map((entry2) => entry2.itemId); if (itemIds.length === 0) continue; - attributeNodeToItems(deps3, { + attributeNodeToItems(deps4, { jobId: input.jobId, nodeId: node.nodeId, taskId: node.parentTaskId, itemIds }); - registerClosureEvidence(deps3, { + registerClosureEvidence(deps4, { jobId: input.jobId, itemIds, kind: "TRUSTED_VERIFICATION", @@ -107412,18 +107518,18 @@ function attributeCompletedWork(deps3, input) { } return { attributed }; } -function generateGapWork(deps3, input) { - const policy = autonomyPolicyOf(deps3).closure; - const ledger = requireLedger(deps3.workspace, input.jobId); +function generateGapWork(deps4, input) { + const policy = autonomyPolicyOf(deps4).closure; + const ledger = requireLedger(deps4.workspace, input.jobId); const byId = new Map(ledger.entries.map((existing) => [existing.itemId, existing])); - const at = nowIso5(deps3); + const at = nowIso5(deps4); const generated = []; for (const unclosed of input.audit.unclosed.slice(0, policy.maxGapWorkPerCycle)) { const existing = byId.get(unclosed.itemId); if (existing === void 0) continue; const gap = unclosed.gaps[0] ?? "NO_EVIDENCE"; const item = gapWorkItemSchema.parse({ - gapId: newRecordId(deps3, "gap"), + gapId: newRecordId(deps4, "gap"), itemId: unclosed.itemId, gapKind: gap, objective: objectiveFor(existing.statement, gap), @@ -107432,14 +107538,14 @@ function generateGapWork(deps3, input) { auditId: input.audit.auditId }); writeJsonRecord( - autonomyPath(deps3.workspace, "closure", input.jobId, "gaps", `${item.gapId}.json`), + autonomyPath(deps4.workspace, "closure", input.jobId, "gaps", `${item.gapId}.json`), item ); generated.push(item); } - saveLedger2(deps3, { ...ledger, gapCycles: ledger.gapCycles + 1 }); + saveLedger2(deps4, { ...ledger, gapCycles: ledger.gapCycles + 1 }); try { - recordJobEvent(jobDepsOf(deps3), input.jobId, "gap_work_generated", { + recordJobEvent(jobDepsOf(deps4), input.jobId, "gap_work_generated", { auditId: input.audit.auditId, generated: generated.length, cycle: ledger.gapCycles + 1 @@ -107462,9 +107568,9 @@ function objectiveFor(statement, gap) { }; return `${prefix[gap]} ${statement}`.slice(0, 4e3); } -function advanceClosurePhase(deps3, input) { - const ledger = requireLedger(deps3.workspace, input.jobId); - return saveLedger2(deps3, { +function advanceClosurePhase(deps4, input) { + const ledger = requireLedger(deps4.workspace, input.jobId); + return saveLedger2(deps4, { ...ledger, phase: input.phase, systemCycles: ledger.systemCycles + (input.systemCycle === true ? 1 : 0), @@ -107483,9 +107589,9 @@ function requireLedger(workspace, jobId) { } return ledger; } -function saveLedger2(deps3, ledger) { - const next = closureLedgerSchema.parse({ ...ledger, updatedAt: nowIso5(deps3) }); - writeJsonRecord(closureLedgerFile(deps3.workspace, next.jobId), next); +function saveLedger2(deps4, ledger) { + const next = closureLedgerSchema.parse({ ...ledger, updatedAt: nowIso5(deps4) }); + writeJsonRecord(closureLedgerFile(deps4.workspace, next.jobId), next); return next; } function createClosureCompletionGate(workspace, policy) { @@ -107572,14 +107678,14 @@ function resultFile(workspace, resultId) { assertAutonomyId("system result", resultId); return autonomyPath(workspace, "system", "results", `${resultId}.json`); } -function saveSystemScenario(deps3, input) { +function saveSystemScenario(deps4, input) { const scenario = systemScenarioSchema.parse({ schemaVersion: SYSTEM_SCENARIO_SCHEMA_VERSION, - scenarioId: input.scenarioId ?? newRecordId(deps3, "ss"), - createdAt: nowIso5(deps3), + scenarioId: input.scenarioId ?? newRecordId(deps4, "ss"), + createdAt: nowIso5(deps4), ...input }); - writeJsonRecord(scenarioFile(deps3.workspace, scenario.scenarioId), scenario); + writeJsonRecord(scenarioFile(deps4.workspace, scenario.scenarioId), scenario); return scenario; } function readSystemScenario(workspace, scenarioId) { @@ -107594,26 +107700,26 @@ function listSystemScenarios(workspace) { (raw) => systemScenarioSchema.parse(raw) ).sort((a2, b) => a2.scenarioId.localeCompare(b.scenarioId)); } -async function runSystemScenario(deps3, options) { - const scenario = readSystemScenario(deps3.workspace, options.scenarioId); +async function runSystemScenario(deps4, options) { + const scenario = readSystemScenario(deps4.workspace, options.scenarioId); if (scenario === void 0) { throw new AutonomyError("SBA024", `No system scenario "${options.scenarioId}" exists.`); } - const resultId = options.resultId ?? newRecordId(deps3, "sr"); - const startedAt = nowIso5(deps3); - emit2(deps3, options.jobId, "system_qualification_started", { + const resultId = options.resultId ?? newRecordId(deps4, "sr"); + const startedAt = nowIso5(deps4); + emit2(deps4, options.jobId, "system_qualification_started", { scenarioId: scenario.scenarioId, resultId }); if (scenario.environmentPlanId !== void 0 && options.runtime === void 0) { - return finish3(deps3, options, scenario, { + return finish3(deps4, options, scenario, { resultId, startedAt, status: "ENVIRONMENT_UNAVAILABLE", failureDetail: `the scenario declares environment plan ${scenario.environmentPlanId} and no environment runtime is available in this session; the product was never exercised` }); } - const instance = scenario.environmentPlanId === void 0 || options.runtime === void 0 ? void 0 : await provisionEnvironment(deps3, { + const instance = scenario.environmentPlanId === void 0 || options.runtime === void 0 ? void 0 : await provisionEnvironment(deps4, { planId: scenario.environmentPlanId, ...options.jobId !== void 0 ? { jobId: options.jobId } : {}, runtime: options.runtime, @@ -107622,7 +107728,7 @@ async function runSystemScenario(deps3, options) { ...options.signal !== void 0 ? { signal: options.signal } : {} }); if (instance !== void 0 && instance.status !== "READY") { - return finish3(deps3, options, scenario, { + return finish3(deps4, options, scenario, { resultId, startedAt, status: "ENVIRONMENT_UNAVAILABLE", @@ -107659,16 +107765,16 @@ async function runSystemScenario(deps3, options) { failureDetail = `step "${step2.name}" declares a fault but the scenario declares no environment plan`; break; } - faultInjected = await injectFault(deps3, { + faultInjected = await injectFault(deps4, { environmentPlanId: scenario.environmentPlanId, runtime: options.runtime, fault: step2.injectFault }); } - const before = now5(deps3).getTime(); + const before = now5(deps4).getTime(); const outcome = await runCommand({ argv: step2.argv, - cwd: deps3.workspace.rootDir, + cwd: deps4.workspace.rootDir, timeoutMs: step2.timeoutMs }); steps.push({ @@ -107676,7 +107782,7 @@ async function runSystemScenario(deps3, options) { name: step2.name, ok: outcome.ok, detail: outcome.detail.slice(0, 4e3), - durationMs: Math.max(0, now5(deps3).getTime() - before), + durationMs: Math.max(0, now5(deps4).getTime() - before), ...faultInjected !== void 0 ? { faultInjected } : {} }); if (!outcome.ok) { @@ -107687,7 +107793,7 @@ async function runSystemScenario(deps3, options) { const browserResultIds = []; if (failureDetail === void 0 && options.browserDriver !== void 0) { for (const browserScenarioId of scenario.browserScenarioIds) { - const browserResult = await runBrowserScenario(deps3, { + const browserResult = await runBrowserScenario(deps4, { scenarioId: browserScenarioId, driver: options.browserDriver, ...options.jobId !== void 0 ? { jobId: options.jobId } : {}, @@ -107703,7 +107809,7 @@ async function runSystemScenario(deps3, options) { } } } - const result = await finish3(deps3, options, scenario, { + const result = await finish3(deps4, options, scenario, { resultId, startedAt, status: failureDetail === void 0 ? "PASSED" : "FAILED", @@ -107713,7 +107819,7 @@ async function runSystemScenario(deps3, options) { ...failureDetail !== void 0 ? { failureDetail } : {} }); if (options.teardown !== false && instance !== void 0 && options.runtime !== void 0) { - await teardownEnvironment(deps3, { + await teardownEnvironment(deps4, { instanceId: instance.instanceId, runtime: options.runtime, retain: result.status !== "PASSED" @@ -107721,9 +107827,9 @@ async function runSystemScenario(deps3, options) { } return result; } -async function injectFault(deps3, input) { +async function injectFault(deps4, input) { const plan = readJsonRecord( - autonomyPath(deps3.workspace, "environments", "plans", `${input.environmentPlanId}.json`), + autonomyPath(deps4.workspace, "environments", "plans", `${input.environmentPlanId}.json`), (raw) => raw ); const service = plan?.services.find((entry2) => entry2.serviceId === input.fault.serviceId); @@ -107731,23 +107837,23 @@ async function injectFault(deps3, input) { await input.runtime.restart({ plan, service, - workspaceRoot: deps3.workspace.rootDir, + workspaceRoot: deps4.workspace.rootDir, timeoutMs: 12e4 }); return `${input.fault.kind} ${input.fault.serviceId}`; } -async function finish3(deps3, options, scenario, input) { +async function finish3(deps4, options, scenario, input) { const result = systemScenarioResultSchema.parse({ schemaVersion: SYSTEM_SCENARIO_SCHEMA_VERSION, scenarioId: scenario.scenarioId, ...options.jobId !== void 0 ? { jobId: options.jobId } : {}, - finishedAt: nowIso5(deps3), + finishedAt: nowIso5(deps4), ...input }); - writeJsonRecord(resultFile(deps3.workspace, result.resultId), result); + writeJsonRecord(resultFile(deps4.workspace, result.resultId), result); if (options.registerClosure === true && scenario.itemIds.length > 0 && options.jobId !== void 0) { if (result.status !== "ENVIRONMENT_UNAVAILABLE") { - registerClosureEvidence(deps3, { + registerClosureEvidence(deps4, { jobId: options.jobId, itemIds: scenario.itemIds, kind: "SYSTEM_SCENARIO", @@ -107757,17 +107863,17 @@ async function finish3(deps3, options, scenario, input) { }); } } - emit2(deps3, options.jobId, "system_qualification_completed", { + emit2(deps4, options.jobId, "system_qualification_completed", { scenarioId: scenario.scenarioId, resultId: result.resultId, status: result.status }); return result; } -function emit2(deps3, jobId, type, payload) { +function emit2(deps4, jobId, type, payload) { if (jobId === void 0) return; try { - recordJobEvent(jobDepsOf(deps3), jobId, type, payload); + recordJobEvent(jobDepsOf(deps4), jobId, type, payload); } catch { } } @@ -107825,11 +107931,11 @@ function resultFile2(workspace, runId) { assertAutonomyId("reproducibility run", runId); return autonomyPath(workspace, "reproducibility", `${runId}.json`); } -async function runReproducibilityQualification(deps3, options) { - const policy = autonomyPolicyOf(deps3).closure; - const runId = options.runId ?? newRecordId(deps3, "rp"); - const startedAt = nowIso5(deps3); - const deadline = now5(deps3).getTime() + policy.reproducibilityTimeoutMs; +async function runReproducibilityQualification(deps4, options) { + const policy = autonomyPolicyOf(deps4).closure; + const runId = options.runId ?? newRecordId(deps4, "rp"); + const startedAt = nowIso5(deps4); + const deadline = now5(deps4).getTime() + policy.reproducibilityTimeoutMs; const run = options.commandRunner ?? (async (input) => { const [executable, ...argv2] = input.argv; if (executable === void 0) return { outcome: "UNAVAILABLE", detail: "empty command" }; @@ -107857,7 +107963,7 @@ async function runReproducibilityQualification(deps3, options) { let failureDetail; let unavailable; for (const step2 of options.steps) { - if (options.signal?.aborted === true || now5(deps3).getTime() > deadline) { + if (options.signal?.aborted === true || now5(deps4).getTime() > deadline) { steps.push({ stepId: step2.stepId, dimension: step2.dimension, @@ -107869,7 +107975,7 @@ async function runReproducibilityQualification(deps3, options) { unavailable = unavailable ?? "the reproducibility window elapsed"; continue; } - const before = now5(deps3).getTime(); + const before = now5(deps4).getTime(); const outcome = await run({ argv: step2.argv, cwd: step2.cwd !== void 0 ? `${options.checkoutPath}/${step2.cwd}` : options.checkoutPath, @@ -107881,7 +107987,7 @@ async function runReproducibilityQualification(deps3, options) { name: step2.name, outcome: outcome.outcome, detail: outcome.detail.slice(0, 4e3), - durationMs: Math.max(0, now5(deps3).getTime() - before) + durationMs: Math.max(0, now5(deps4).getTime() - before) }); if (outcome.outcome === "FAILED") { failureDetail = `${step2.name}: ${outcome.detail}`; @@ -107898,7 +108004,7 @@ async function runReproducibilityQualification(deps3, options) { ...options.jobId !== void 0 ? { jobId: options.jobId } : {}, status, startedAt, - finishedAt: nowIso5(deps3), + finishedAt: nowIso5(deps4), checkoutPath: options.checkoutPath.slice(0, 200), ...options.gitHead !== void 0 ? { gitHead: options.gitHead } : {}, dimensions: [...new Set(options.steps.map((step2) => step2.dimension))], @@ -107906,17 +108012,17 @@ async function runReproducibilityQualification(deps3, options) { ...failureDetail !== void 0 ? { failureDetail } : {}, ...unavailable !== void 0 ? { inconclusiveReason: unavailable } : {} }); - writeJsonRecord(resultFile2(deps3.workspace, runId), result); + writeJsonRecord(resultFile2(deps4.workspace, runId), result); if (options.jobId !== void 0) { if (status === "PASSED") { - advanceClosurePhase(deps3, { + advanceClosurePhase(deps4, { jobId: options.jobId, phase: "FINAL_CONTRACT_AUDIT", reproducibilityPassed: true }); } if (options.itemIds !== void 0 && options.itemIds.length > 0 && status !== "INCONCLUSIVE") { - registerClosureEvidence(deps3, { + registerClosureEvidence(deps4, { jobId: options.jobId, itemIds: options.itemIds, kind: "REPRODUCIBILITY_RUN", @@ -107927,7 +108033,7 @@ async function runReproducibilityQualification(deps3, options) { }); } try { - recordJobEvent(jobDepsOf(deps3), options.jobId, "reproducibility_completed", { + recordJobEvent(jobDepsOf(deps4), options.jobId, "reproducibility_completed", { runId, status, dimensions: result.dimensions.length @@ -107937,13 +108043,13 @@ async function runReproducibilityQualification(deps3, options) { } return result; } -function ensureSystemScenarios(deps3, input) { - const ledger = readClosureLedger(deps3.workspace, input.jobId); +function ensureSystemScenarios(deps4, input) { + const ledger = readClosureLedger(deps4.workspace, input.jobId); const open = ledger?.entries.filter( (entry2) => (entry2.requiresSystemScenario || entry2.requiresBrowserScenario) && !isClosingStatus(entry2.status) ) ?? []; if (open.length === 0) return { scenarios: [], uncovered: [] }; - const existing = listSystemScenarios(deps3.workspace); + const existing = listSystemScenarios(deps4.workspace); const openIds = new Set(open.map((entry2) => entry2.itemId)); const covering = existing.filter( (scenario) => scenario.itemIds.some((itemId) => openIds.has(itemId)) @@ -107951,16 +108057,16 @@ function ensureSystemScenarios(deps3, input) { const covered = new Set(covering.flatMap((scenario) => scenario.itemIds)); const uncoveredIds = open.map((entry2) => entry2.itemId).filter((itemId) => !covered.has(itemId)); if (uncoveredIds.length === 0) return { scenarios: covering, uncovered: [] }; - const commands = deps3.config.verification.commands; + const commands = deps4.config.verification.commands; if (commands.length === 0) { return { scenarios: covering, uncovered: uncoveredIds }; } const plans = listJsonRecords( - autonomyPath(deps3.workspace, "environments", "plans"), + autonomyPath(deps4.workspace, "environments", "plans"), (raw) => environmentPlanSchema.parse(raw) ); - const browserScenarioIds = listBrowserScenarios(deps3.workspace).map((scenario) => scenario.scenarioId).slice(0, 20); - const synthesized = saveSystemScenario(deps3, { + const browserScenarioIds = listBrowserScenarios(deps4.workspace).map((scenario) => scenario.scenarioId).slice(0, 20); + const synthesized = saveSystemScenario(deps4, { scenarioId: `ss-default-${input.jobId}`.slice(0, 200), name: "Default mission qualification scenario", intent: "Synthesized deterministically from the trusted verification commands: run the full suite against the integrated product" + (plans.length === 1 ? " with its declared environment provisioned" : "") + (browserScenarioIds.length > 0 ? ", then the authored browser scenarios" : "") + ".", @@ -107977,8 +108083,8 @@ function ensureSystemScenarios(deps3, input) { }); return { scenarios: [...covering, synthesized], uncovered: [] }; } -async function runSystemScenarioPhase(deps3, options) { - const { scenarios, uncovered } = ensureSystemScenarios(deps3, { jobId: options.jobId }); +async function runSystemScenarioPhase(deps4, options) { + const { scenarios, uncovered } = ensureSystemScenarios(deps4, { jobId: options.jobId }); const result = { executed: 0, passed: 0, @@ -107989,7 +108095,7 @@ async function runSystemScenarioPhase(deps3, options) { for (const scenario of scenarios) { if (options.signal?.aborted === true) break; options.emit?.(`running system scenario ${scenario.scenarioId} (${scenario.name})`); - const run = await runSystemScenario(deps3, { + const run = await runSystemScenario(deps4, { scenarioId: scenario.scenarioId, jobId: options.jobId, ...options.runtime !== void 0 ? { runtime: options.runtime } : {}, @@ -108011,16 +108117,16 @@ async function runSystemScenarioPhase(deps3, options) { `${uncovered.length} scenario-owned item(s) have no scenario to run (no trusted verification commands to synthesize one from)` ); } - advanceClosurePhase(deps3, { + advanceClosurePhase(deps4, { jobId: options.jobId, phase: "SYSTEM_SCENARIO_QUALIFICATION", systemCycle: true }); return result; } -async function runReleaseQualificationPhase(deps3, options) { - const commands = deps3.config.verification.commands; - advanceClosurePhase(deps3, { +async function runReleaseQualificationPhase(deps4, options) { + const commands = deps4.config.verification.commands; + advanceClosurePhase(deps4, { jobId: options.jobId, phase: "RELEASE_QUALIFICATION", releaseQualificationCycle: true @@ -108032,21 +108138,21 @@ async function runReleaseQualificationPhase(deps3, options) { detail = "no trusted verification commands are configured; the integrated tree cannot be qualified"; } else { options.emit?.(`release qualification: running ${commands.length} trusted command(s) against the integrated tree`); - const run = options.verify !== void 0 ? await options.verify(commands) : await runVerificationCommands(deps3.workspace.rootDir, [...commands], { + const run = options.verify !== void 0 ? await options.verify(commands) : await runVerificationCommands(deps4.workspace.rootDir, [...commands], { ...options.signal !== void 0 ? { signal: options.signal } : {} }); passed = run.passed; detail = run.passed ? `all ${commands.length} trusted command(s) passed against the integrated tree` : `required command(s) failed: ${run.requiredFailed.join(", ").slice(0, 300)}`; } if (passed) { - advanceClosurePhase(deps3, { + advanceClosurePhase(deps4, { jobId: options.jobId, phase: "RELEASE_QUALIFICATION", releaseQualificationPassed: true }); } try { - recordJobEvent(jobDepsOf(deps3), options.jobId, "release_qualification_completed", { + recordJobEvent(jobDepsOf(deps4), options.jobId, "release_qualification_completed", { passed, detail: detail.slice(0, 300) }); @@ -108055,25 +108161,25 @@ async function runReleaseQualificationPhase(deps3, options) { options.emit?.(`release qualification: ${passed ? "PASSED" : "FAILED"} \u2014 ${detail}`); return { passed, detail }; } -async function runReproducibilityPhase(deps3, options) { - advanceClosurePhase(deps3, { +async function runReproducibilityPhase(deps4, options) { + advanceClosurePhase(deps4, { jobId: options.jobId, phase: "REPRODUCIBILITY", reproducibilityCycle: true }); - const commands = deps3.config.verification.commands; + const commands = deps4.config.verification.commands; if (commands.length === 0) { const detail = "no trusted verification commands are configured; there is nothing to reproduce"; options.emit?.(`reproducibility: NOT_RUN \u2014 ${detail}`); return { status: "NOT_RUN", detail }; } - const runId = newRecordId(deps3, "rp"); - const checkoutPath = autonomyPath(deps3.workspace, "reproducibility", "checkouts", runId); + const runId = newRecordId(deps4, "rp"); + const checkoutPath = autonomyPath(deps4.workspace, "reproducibility", "checkouts", runId); (0, import_fs80.mkdirSync)(import_path89.default.dirname(checkoutPath), { recursive: true }); const head = await runSafeProcess({ executable: "git", argv: ["rev-parse", "HEAD"], - cwd: deps3.workspace.rootDir, + cwd: deps4.workspace.rootDir, timeoutMs: 6e4, maxStdoutBytes: 4096, maxStderrBytes: 4096 @@ -108082,7 +108188,7 @@ async function runReproducibilityPhase(deps3, options) { const checkout = await runSafeProcess({ executable: "git", argv: ["worktree", "add", "--detach", checkoutPath, "HEAD"], - cwd: deps3.workspace.rootDir, + cwd: deps4.workspace.rootDir, timeoutMs: 3e5, maxStdoutBytes: 64 * 1024, maxStderrBytes: 64 * 1024 @@ -108093,7 +108199,7 @@ async function runReproducibilityPhase(deps3, options) { return { status: "INCONCLUSIVE", detail }; } const steps = []; - const installer = detectNodeInstaller(deps3.workspace); + const installer = detectNodeInstaller(deps4.workspace); if (installer !== void 0) { steps.push({ stepId: "install", @@ -108113,7 +108219,7 @@ async function runReproducibilityPhase(deps3, options) { }); }); try { - const result = await runReproducibilityQualification(deps3, { + const result = await runReproducibilityQualification(deps4, { jobId: options.jobId, steps, checkoutPath, @@ -108125,13 +108231,13 @@ async function runReproducibilityPhase(deps3, options) { const detail = result.status === "PASSED" ? `reproduced from a clean checkout of ${gitHead ?? "HEAD"}` : result.failureDetail ?? result.inconclusiveReason ?? `reproducibility ${result.status}`; options.emit?.(`reproducibility: ${result.status} \u2014 ${detail}`); if (result.status === "PASSED") { - await removeCheckout(deps3.workspace, checkoutPath); + await removeCheckout(deps4.workspace, checkoutPath); } else { options.emit?.(`the checkout is retained for diagnosis at ${checkoutPath}`); } return { status: result.status, detail }; } catch (error2) { - await removeCheckout(deps3.workspace, checkoutPath); + await removeCheckout(deps4.workspace, checkoutPath); throw error2; } } @@ -108152,10 +108258,10 @@ async function removeCheckout(workspace, checkoutPath) { maxStderrBytes: 16 * 1024 }); } -async function runGapRepairs(deps3, options) { - const policy = deps3.config.orchestration.jobs.objectives; - const commands = deps3.config.verification.commands; - const ledger = readClosureLedger(deps3.workspace, options.jobId); +async function runGapRepairs(deps4, options) { + const policy = deps4.config.orchestration.jobs.objectives; + const commands = deps4.config.verification.commands; + const ledger = readClosureLedger(deps4.workspace, options.jobId); const result = { repaired: [], failed: [] }; for (const item of options.items) { if (options.signal?.aborted === true) { @@ -108167,10 +108273,10 @@ async function runGapRepairs(deps3, options) { const fail = (reason3) => { options.emit?.(`gap ${item.gapId} (${item.itemId}): ${reason3}`); result.failed.push({ gapId: item.gapId, reason: reason3 }); - recordGapEvent(deps3, options.jobId, item, false, reason3); + recordGapEvent(deps4, options.jobId, item, false, reason3); }; const worktree = await createWorkerWorktree({ - workspace: deps3.workspace, + workspace: deps4.workspace, jobId: options.jobId, workUnitId: `gap-${item.gapId}`.slice(0, 40), attempt: 1 @@ -108189,13 +108295,13 @@ async function runGapRepairs(deps3, options) { ].join("\n"); options.emit?.(`gap ${item.gapId} (${item.itemId}): repair builder started`); const built = await runLargeObjectiveRole({ - workspace: deps3.workspace, - config: deps3.config, - runnerProfile: deps3.config.defaultRunner, + workspace: deps4.workspace, + config: deps4.config, + runnerProfile: deps4.config.defaultRunner, role: "BUILDER", packet, cwd: worktree.dir, - scratchDir: autonomyPath(deps3.workspace, "closure", options.jobId, "scratch", item.gapId), + scratchDir: autonomyPath(deps4.workspace, "closure", options.jobId, "scratch", item.gapId), timeoutMs: policy.builderTimeoutMs, ...options.signal !== void 0 ? { signal: options.signal } : {} }); @@ -108222,7 +108328,7 @@ async function runGapRepairs(deps3, options) { continue; } const patchFile = import_path89.default.join( - autonomyPath(deps3.workspace, "closure", options.jobId, "scratch", item.gapId), + autonomyPath(deps4.workspace, "closure", options.jobId, "scratch", item.gapId), "repair.patch" ); (0, import_fs80.mkdirSync)(import_path89.default.dirname(patchFile), { recursive: true }); @@ -108230,7 +108336,7 @@ async function runGapRepairs(deps3, options) { const applied = await runSafeProcess({ executable: "git", argv: ["apply", "--3way", patchFile], - cwd: deps3.workspace.rootDir, + cwd: deps4.workspace.rootDir, timeoutMs: 3e5, maxStdoutBytes: 64 * 1024, maxStderrBytes: 64 * 1024 @@ -108239,7 +108345,7 @@ async function runGapRepairs(deps3, options) { fail(`the verified repair no longer applies to the canonical tree: ${applied.stderr.split("\n")[0] ?? applied.status}`); continue; } - registerClosureEvidence(deps3, { + registerClosureEvidence(deps4, { jobId: options.jobId, itemIds: [item.itemId], kind: "TRUSTED_VERIFICATION", @@ -108247,7 +108353,7 @@ async function runGapRepairs(deps3, options) { passed: true, detail: `Gap repair (${item.gapKind}) verified by the full trusted suite in an isolated worktree.` }); - advanceClosurePhase(deps3, { + advanceClosurePhase(deps4, { jobId: options.jobId, phase: "GAP_IMPLEMENTATION", releaseQualificationPassed: false, @@ -108255,16 +108361,16 @@ async function runGapRepairs(deps3, options) { }); result.repaired.push(item.gapId); options.emit?.(`gap ${item.gapId} (${item.itemId}): repaired, verified, and integrated`); - recordGapEvent(deps3, options.jobId, item, true, `${collected.changedFiles.length} file(s) changed`); + recordGapEvent(deps4, options.jobId, item, true, `${collected.changedFiles.length} file(s) changed`); } finally { - await removeWorkerWorktree(deps3.workspace, options.jobId, worktree); + await removeWorkerWorktree(deps4.workspace, options.jobId, worktree); } } return result; } -function recordGapEvent(deps3, jobId, item, ok2, detail) { +function recordGapEvent(deps4, jobId, item, ok2, detail) { try { - recordJobEvent(jobDepsOf(deps3), jobId, "gap_repair_completed", { + recordJobEvent(jobDepsOf(deps4), jobId, "gap_repair_completed", { gapId: item.gapId, itemId: item.itemId, gapKind: item.gapKind, @@ -108359,10 +108465,10 @@ var INTERVENTION_EVENTS = Object.freeze({ // needs a person; only the event name differed. budget_exhausted: "the job stopped on an exhausted budget, needing an explicit user action" }); -function computeAutonomyTelemetry(deps3, input) { - const read = readJobState(deps3.workspace, input.jobId); +function deriveAutonomyTelemetry(deps4, input) { + const read = readJobState(deps4.workspace, input.jobId); const job = read.kind === "ok" ? read.job : void 0; - const events = safeEvents(deps3.workspace, input.jobId); + const events = safeEvents(deps4.workspace, input.jobId); const counters = job?.autonomyCounters; const interventions = []; let providerFailovers = 0; @@ -108371,8 +108477,8 @@ function computeAutonomyTelemetry(deps3, input) { let contextRollovers = 0; let supervisorWakeups = 0; let escalationsAfterBoundary = 0; - const bindingForBoundary = readSealBinding(deps3.workspace, input.jobId); - const boundary = bindingForBoundary !== void 0 ? readSealedAt(deps3, bindingForBoundary.sealId) : void 0; + const bindingForBoundary = readSealBinding(deps4.workspace, input.jobId); + const boundary = bindingForBoundary !== void 0 ? readSealedAt(deps4, bindingForBoundary.sealId) : void 0; const boundaryMs = boundary !== void 0 ? Date.parse(boundary) : Number.NaN; const afterBoundary = (at) => { if (!Number.isFinite(boundaryMs)) return true; @@ -108397,7 +108503,7 @@ function computeAutonomyTelemetry(deps3, input) { if (type === "context_rollover" || type === "fresh_context_selected") contextRollovers += 1; if (type === "driver_restarted" || type === "supervisor_attached") supervisorWakeups += 1; } - const supervisionLog = readSupervisionLog(deps3.workspace, 2e3); + const supervisionLog = readSupervisionLog(deps4.workspace, 2e3); supervisorWakeups += supervisionLog.filter( (entry2) => entry2.action === "WOKEN_ON_SCHEDULE" || entry2.action === "WOKEN_ON_RESOURCE_RETURN" ).length; @@ -108408,21 +108514,21 @@ function computeAutonomyTelemetry(deps3, input) { detail: job.blocker?.message ?? `the job is ${job.status} and cannot proceed without a person` }); } - const ledger = readClosureLedger(deps3.workspace, input.jobId); + const ledger = readClosureLedger(deps4.workspace, input.jobId); const totals = ledger !== void 0 ? summarizeClosure(ledger.entries) : void 0; - const toolsmith = listToolsmithRequests(deps3.workspace, input.jobId); - const browserResults = listBrowserResults(deps3.workspace).filter( + const toolsmith = listToolsmithRequests(deps4.workspace, input.jobId); + const browserResults = listBrowserResults(deps4.workspace).filter( (result) => result.jobId === input.jobId ); - const critiques = listCritiques(deps3.workspace).filter( + const critiques = listCritiques(deps4.workspace).filter( (critique) => critique.jobId === input.jobId ); - const binding = readSealBinding(deps3.workspace, input.jobId); + const binding = readSealBinding(deps4.workspace, input.jobId); const telemetry = autonomyTelemetrySchema.parse({ schemaVersion: TELEMETRY_SCHEMA_VERSION, jobId: input.jobId, ...binding !== void 0 ? { sealId: binding.sealId, missionId: binding.missionId } : {}, - recordedAt: nowIso5(deps3), + recordedAt: nowIso5(deps4), jobStatus: job?.status ?? "UNKNOWN", humanInterventionsAfterSeal: interventions.length, humanAuthorityEscalations: counters?.authorityEscalations ?? 0, @@ -108434,7 +108540,7 @@ function computeAutonomyTelemetry(deps3, input) { quotaWaits: Math.max(quotaWaits, counters?.resourceWaits ?? 0), contextRollovers: Math.max(contextRollovers, counters?.contextRollovers ?? 0), toolsmithActions: toolsmith.length, - selfCreatedTools: countSelfCreatedTools(deps3.workspace, input.jobId), + selfCreatedTools: countSelfCreatedTools(deps4.workspace, input.jobId), toolchainRepairs: counters?.toolchainRepairs ?? 0, environmentRepairs: counters?.environmentRepairs ?? 0, controlPlaneRepairs: counters?.controlPlaneRepairs ?? 0, @@ -108461,7 +108567,11 @@ function computeAutonomyTelemetry(deps3, input) { } : {}, interventions: interventions.slice(0, 200) }); - writeJsonRecord(telemetryFile(deps3.workspace, input.jobId), telemetry); + return telemetry; +} +function computeAutonomyTelemetry(deps4, input) { + const telemetry = deriveAutonomyTelemetry(deps4, input); + writeJsonRecord(telemetryFile(deps4.workspace, input.jobId), telemetry); return telemetry; } function elapsedFromJob(job) { @@ -108471,9 +108581,9 @@ function elapsedFromJob(job) { if (!Number.isFinite(created) || !Number.isFinite(updated)) return null; return Math.max(0, updated - created); } -function readSealedAt(deps3, sealId) { +function readSealedAt(deps4, sealId) { try { - return readSeal(deps3.workspace, sealId)?.sealedAt; + return readSeal(deps4.workspace, sealId)?.sealedAt; } catch { return void 0; } @@ -108500,13 +108610,1353 @@ function formatMeasurement(value, unit) { return String(value); } } -var shortText122 = external_exports.string().max(200); +var EXECUTION_TELEMETRY_REPORT_SCHEMA_VERSION = "1.0.0"; +var count3 = external_exports.number().int().min(0); +var shortText122 = external_exports.string().max(512); +var boundedText6 = external_exports.string().max(2e3); +var ratio3 = external_exports.number().min(0).max(1).nullable(); +var countMap = external_exports.record(external_exports.string(), count3); +var fractionMetricSchema = external_exports.object({ + numerator: count3.nullable(), + denominator: count3.nullable(), + value: ratio3 +}).strict(); +var tokenCoverageSchema = external_exports.object({ + attempts: count3, + withAny: count3, + withInput: count3, + withOutput: count3, + ratio: ratio3, + complete: external_exports.boolean() +}).strict(); +var tokenTelemetrySchema = external_exports.object({ + /** Sum of every reported input-token field; null when none reported. */ + inputTokens: count3.nullable(), + /** Sum of every reported output-token field; null when none reported. */ + outputTokens: count3.nullable(), + /** Sum of known components, even when coverage is partial. */ + knownTokens: count3.nullable(), + /** Total only when every attempt reported both components. */ + completeTokens: count3.nullable(), + coverage: tokenCoverageSchema +}).strict(); +var workAccountingSchema = external_exports.enum([ + "completed", + "failed", + "cancelled", + "waiting", + "not-ready", + "human-authority-pending", + "research-pending", + "context-pending" +]); +var diagnosticSchema = external_exports.object({ + code: shortText122, + severity: external_exports.enum(["info", "warning", "error"]), + message: boundedText6, + evidenceRefs: external_exports.array(shortText122).max(20).default([]) +}).strict(); +var phaseResearchSchema = external_exports.object({ + considered: count3, + avoided: count3, + reused: count3, + newCalls: count3, + quick: count3, + deep: count3, + failed: count3 +}).strict(); +var executionTelemetryReportSchema = external_exports.object({ + schemaVersion: external_exports.literal(EXECUTION_TELEMETRY_REPORT_SCHEMA_VERSION), + jobId: shortText122, + missionId: shortText122.nullable(), + generatedAt: shortText122, + period: external_exports.object({ + startedAt: shortText122, + endedAt: shortText122.nullable(), + durationMs: count3.nullable(), + activeExecutionMs: count3.nullable() + }).strict(), + provenance: external_exports.object({ + sourceJobId: shortText122, + jobGraphRevision: count3, + objectiveGraphRevisions: countMap, + executionLedgerWatermark: external_exports.string().regex(/^[a-f0-9]{64}$/), + eventWatermark: count3, + specbridgeVersion: shortText122.nullable(), + sealId: shortText122.nullable(), + sealedAuthorityDigest: shortText122.nullable(), + runtimePolicyChanged: external_exports.boolean().nullable(), + configuration: external_exports.object({ + secondaryBuildStrategy: shortText122, + researchStrategy: shortText122, + runnerProfiles: external_exports.array(shortText122).max(50) + }).strict() + }).strict(), + outcome: external_exports.object({ + status: external_exports.enum(["COMPLETED", "FAILED", "CANCELLED", "BLOCKED", "WAITING"]), + authoritativeJobStatus: shortText122, + finalOutcome: boundedText6.nullable(), + verification: external_exports.enum(["PASS", "FAIL", "UNAVAILABLE"]), + closure: external_exports.enum(["PASS", "FAIL", "UNAVAILABLE"]) + }).strict(), + work: external_exports.object({ + total: count3, + byKind: countMap, + accounting: external_exports.record(workAccountingSchema, count3), + completedImplementation: count3, + objectives: external_exports.array(external_exports.object({ + objectiveNodeId: shortText122, + graphRevision: count3.nullable(), + total: count3, + accounting: external_exports.record(workAccountingSchema, count3), + implementationAttempts: count3, + secondaryAttempts: count3, + strongBuilderAttempts: count3 + }).strict()).max(200), + units: external_exports.array(external_exports.object({ + workUnitId: shortText122, + objectiveNodeId: shortText122, + kind: shortText122, + status: shortText122, + accounting: workAccountingSchema, + builderPath: external_exports.enum(["SECONDARY", "SECONDARY_REPAIR", "STRONG", "STRONG_FALLBACK", "NONE", "UNKNOWN"]), + implementationAttempts: count3, + verification: external_exports.enum(["PASS", "FAIL", "PENDING", "UNAVAILABLE"]), + integration: external_exports.enum(["INTEGRATED", "NOT_INTEGRATED"]) + }).strict()).max(500), + omittedUnits: count3 + }).strict(), + secondary: external_exports.object({ + eligibility: external_exports.object({ + eligible: count3, + ineligible: count3, + strongRequired: count3, + needsResearch: count3, + needsAuthority: count3, + needsContext: count3, + notReady: count3, + unavailable: count3 + }).strict(), + selection: external_exports.object({ + secondarySelected: count3, + strongSelectedDespiteEligibility: count3, + noBuilderNeeded: count3, + waitingForResource: count3 + }).strict(), + funnel: external_exports.object({ + initialAttempts: count3, + initialPass: count3, + repairAttempted: count3, + repairPass: count3, + toStrongFallback: count3, + unavailableFallback: count3 + }).strict(), + initialSuccessRate: fractionMetricSchema, + repairRecoveryRate: fractionMetricSchema, + toStrongFallbackRate: fractionMetricSchema, + fallbackReasons: countMap, + builderTokens: tokenTelemetrySchema + }).strict(), + strong: external_exports.object({ + builderAttempts: count3, + evaluatorAttempts: count3, + selection: external_exports.object({ + requiredDirect: count3, + byStrategyOff: count3, + byAutoPolicy: count3, + becauseSecondaryUnavailable: count3, + fallbackAfterSecondary: count3 + }).strict(), + implementationTokens: tokenTelemetrySchema, + evaluatorTokens: tokenTelemetrySchema + }).strict(), + research: external_exports.object({ + scope: external_exports.enum(["JOB", "WORKSPACE", "NONE"]), + considered: count3.nullable(), + decisions: countMap, + providerCalls: count3, + successful: count3, + inconclusive: count3, + failed: count3, + priorResearchReused: count3, + newQuick: count3, + newDeep: count3, + avoidanceRatio: fractionMetricSchema, + reuseRate: fractionMetricSchema, + byPhase: external_exports.record(external_exports.string(), phaseResearchSchema), + usage: external_exports.object({ + inputTokens: count3.nullable(), + outputTokens: count3.nullable(), + durationMs: count3.nullable(), + providerReportedCost: external_exports.number().min(0).nullable(), + subagentCount: count3.nullable(), + recordsWithUsage: count3, + providerCalls: count3, + coverage: ratio3 + }).strict() + }).strict(), + cooldown: external_exports.object({ + episodes: count3, + observations: count3, + totalDurationMs: count3.nullable(), + usefulWorkDuringSubscriptionCooldown: count3, + secondaryImplementationWorkDuringCooldown: count3, + researchWorkDuringCooldown: count3, + strongRequiredWaiting: count3, + avoidableIdlePeriods: count3, + intervals: external_exports.array(external_exports.object({ + objectiveNodeId: shortText122, + status: external_exports.enum(["ACTIVE", "RECOVERED"]), + startedAt: shortText122, + endedAt: shortText122.nullable(), + durationMs: count3.nullable(), + completedWorkUnits: count3 + }).strict()).max(200), + timeline: external_exports.array(external_exports.object({ + at: shortText122, + type: shortText122, + objectiveNodeId: shortText122.nullable(), + detail: boundedText6 + }).strict()).max(200) + }).strict(), + attempts: external_exports.object({ + uniqueImplementationAttempts: count3, + meanPerCompletedWorkUnit: external_exports.number().min(0).nullable(), + medianPerCompletedWorkUnit: external_exports.number().min(0).nullable(), + maxPerWorkUnit: count3, + workUnitsWithMultipleAttempts: count3, + byKind: countMap, + completedWorkUnitsPerImplementationAttempt: external_exports.number().min(0).nullable(), + completedWorkUnitsPerStrongBuilderCall: external_exports.number().min(0).nullable(), + completedEligibleWorkUnitsPerSecondaryAttempt: external_exports.number().min(0).nullable() + }).strict(), + verification: external_exports.object({ + attempts: count3, + passes: count3, + failures: count3, + otherVerdicts: count3, + failuresByBuilderBackend: countMap, + failuresRecoveredByRepair: count3, + failuresRecoveredByStrongFallback: count3 + }).strict(), + closure: external_exports.object({ + available: external_exports.boolean(), + items: count3, + earned: count3, + waived: count3, + unresolved: count3, + completionGateOutcome: external_exports.enum(["PASS", "FAIL", "UNAVAILABLE"]), + ratio: ratio3 + }).strict(), + human: external_exports.object({ + decisionsBeforeSeal: count3.nullable(), + approvals: count3, + authorityEscalationsAfterSeal: count3.nullable(), + interventionsAfterSeal: count3, + unexpectedBlockersAfterSeal: count3, + zeroTouchAfterSeal: external_exports.boolean(), + byKind: countMap + }).strict(), + reliability: external_exports.object({ + failureSources: countMap, + recoveryActions: countMap, + noProgressDetections: count3, + repeatedProblemFingerprints: count3, + legitimateResourceWaitsExcluded: count3, + processRestarts: count3, + supervisorRestarts: count3, + candidatesPersisted: count3, + candidatesReusedAfterRestart: count3, + candidateRebuildsAfterRestart: count3, + candidatesLostOrUnreadable: count3, + candidateReadyResumes: count3, + integrationRetries: count3, + completedWorkRedoCount: count3, + completedWorkReusedAfterRestart: count3, + attemptsIncorrectlyRepeated: count3, + unexpectedBlocks: count3, + unrecoveredDriverDeaths: count3 + }).strict(), + efficiency: external_exports.object({ + strongBuilderAvoidanceRatio: fractionMetricSchema, + strongBuilderCallsAvoided: count3, + completedWorkUnitsPerImplementationAttempt: external_exports.number().min(0).nullable(), + baseline: external_exports.object({ + kind: external_exports.enum(["OBSERVED", "QUALIFICATION_FIXTURE"]), + reportId: shortText122, + strongBuilderAttempts: count3, + sameVerificationOutcome: external_exports.boolean(), + sameClosureOutcome: external_exports.boolean() + }).strict().nullable() + }).strict(), + qualificationSummary: external_exports.object({ + strongBuilderAvoidanceRatio: ratio3, + secondaryInitialSuccessRate: ratio3, + secondaryRepairRecoveryRate: ratio3, + secondaryToStrongFallback: count3, + strongImplementationTokens: count3.nullable(), + researchAvoidanceRatio: ratio3, + newResearchCalls: count3, + researchReuse: count3, + usefulWorkDuringSubscriptionCooldown: count3, + humanInterventionsAfterSeal: count3, + completedWorkRedoCount: count3, + unexpectedBlocks: count3, + unrecoveredDriverDeaths: count3 + }).strict(), + diagnostics: external_exports.array(diagnosticSchema).max(200) +}).strict(); +var SECRET_PATTERNS2 = [ + /-----BEGIN (?:RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----/gi, + /\b(?:bearer|basic)\s+[A-Za-z0-9+/=_-]{12,}/gi, + /\b(?:sk|ghp|github_pat|xox[baprs])[_-][A-Za-z0-9_-]{12,}\b/gi, + /\b(?:api[-_ ]?key|auth[-_ ]?token|access[-_ ]?token|password|secret)\s*[:=]\s*\S{8,}/gi +]; +function redactTelemetryText(value) { + let redacted = value; + for (const pattern of SECRET_PATTERNS2) redacted = redacted.replace(pattern, "[REDACTED]"); + return redacted.slice(0, 2e3); +} +function increment2(record5, key, by = 1) { + record5[key] = (record5[key] ?? 0) + by; +} +function metric(numerator, denominator) { + return { + numerator, + denominator, + value: numerator === null || denominator === null || denominator === 0 ? null : numerator / denominator + }; +} +function tokenTelemetry(attempts, usage) { + let input = 0; + let output = 0; + let withInput = 0; + let withOutput = 0; + let withAny = 0; + for (const attempt of attempts) { + const reported = usage(attempt); + const hasInput = reported.input !== null && reported.input !== void 0; + const hasOutput = reported.output !== null && reported.output !== void 0; + if (hasInput) { + input += reported.input ?? 0; + withInput += 1; + } + if (hasOutput) { + output += reported.output ?? 0; + withOutput += 1; + } + if (hasInput || hasOutput) withAny += 1; + } + const attemptCount = attempts.length; + const complete = attemptCount > 0 && withInput === attemptCount && withOutput === attemptCount; + return { + inputTokens: withInput > 0 ? input : null, + outputTokens: withOutput > 0 ? output : null, + knownTokens: withAny > 0 ? input + output : null, + completeTokens: complete ? input + output : null, + coverage: { + attempts: attemptCount, + withAny, + withInput, + withOutput, + ratio: attemptCount === 0 ? null : withAny / attemptCount, + complete + } + }; +} +function timestampMs(value) { + if (value === null || value === void 0) return void 0; + const parsed = Date.parse(value); + return Number.isFinite(parsed) ? parsed : void 0; +} +function outcomeStatus(status) { + if (status === "COMPLETED") return "COMPLETED"; + if (status === "FAILED") return "FAILED"; + if (status === "CANCELLED") return "CANCELLED"; + if (status === "BLOCKED" || status === "NEEDS_AUTHORITY" || status === "NEEDS_CLARIFICATION") { + return "BLOCKED"; + } + return "WAITING"; +} +function verificationOutcome(job, events) { + const status = job.latestEvidence?.evidenceStatus; + if (status === "verified" || status === "manually-accepted") return "PASS"; + const lastFailure = [...events].reverse().find((event) => event.type === "verification_failed"); + if (lastFailure !== void 0 && job.latestEvidence === void 0) return "FAIL"; + return "UNAVAILABLE"; +} +function currentRoutingStates(objectives) { + const current = /* @__PURE__ */ new Map(); + for (const objective of objectives) { + for (const state of objective.routingStates) { + const key = `${objective.objectiveNodeId}\0${state.workUnitId}`; + const prior = current.get(key); + if (prior === void 0 || state.updatedAt.localeCompare(prior.updatedAt, "en") > 0 || state.updatedAt === prior.updatedAt && state.contentHash.localeCompare(prior.contentHash, "en") > 0) { + current.set(key, state); + } + } + } + return current; +} +function uniqueBuilderAttempts(objectives) { + const seen = /* @__PURE__ */ new Map(); + let duplicateIds = 0; + for (const objective of objectives) { + for (const state of objective.routingStates) { + for (const attempt of state.attempts) { + const key = `${objective.objectiveNodeId}\0${state.workUnitId}\0${attempt.attemptId}`; + if (seen.has(key)) { + duplicateIds += 1; + continue; + } + seen.set(key, { ...attempt, objectiveNodeId: objective.objectiveNodeId, workUnitId: state.workUnitId }); + } + } + } + return { + attempts: [...seen.values()].sort( + (left, right) => left.startedAt.localeCompare(right.startedAt, "en") || left.objectiveNodeId.localeCompare(right.objectiveNodeId, "en") || left.workUnitId.localeCompare(right.workUnitId, "en") || left.sequence - right.sequence + ), + duplicateIds + }; +} +function latestUnits(objectives) { + const units = []; + for (const objective of objectives) { + for (const unit of objective.graph?.units ?? []) { + units.push({ objectiveNodeId: objective.objectiveNodeId, unit }); + } + } + return units.sort( + (left, right) => left.objectiveNodeId.localeCompare(right.objectiveNodeId, "en") || left.unit.workUnitId.localeCompare(right.unit.workUnitId, "en") + ); +} +function workAccounting(unit, routing) { + if (unit.status === "INTEGRATED") return "completed"; + if (unit.status === "FAILED") return "failed"; + if (unit.status === "SUPERSEDED") return "cancelled"; + const eligibility = routing?.initialEligibility; + if (eligibility === "NEEDS_AUTHORITY") return "human-authority-pending"; + if (eligibility === "NEEDS_RESEARCH") return "research-pending"; + if (eligibility === "NEEDS_CONTEXT") return "context-pending"; + if (eligibility === "NOT_READY" || unit.status === "PLANNED") return "not-ready"; + return "waiting"; +} +function builderPath(attempts) { + if (attempts.some((attempt) => attempt.kind === "STRONG_FALLBACK")) return "STRONG_FALLBACK"; + if (attempts.some((attempt) => attempt.kind === "STRONG")) return "STRONG"; + if (attempts.some((attempt) => attempt.kind === "SECONDARY_REPAIR")) return "SECONDARY_REPAIR"; + if (attempts.some((attempt) => attempt.kind === "SECONDARY")) return "SECONDARY"; + return attempts.length === 0 ? "NONE" : "UNKNOWN"; +} +function verificationFor(evaluations) { + if (evaluations.some((entry2) => entry2.verdict === "FAIL")) return "FAIL"; + if (evaluations.some((entry2) => entry2.verdict === "PASS")) return "PASS"; + if (evaluations.length > 0) return "PENDING"; + return "UNAVAILABLE"; +} +function fallbackReason(attempts) { + const preceding = [...attempts].reverse().find((attempt) => attempt.kind === "SECONDARY" || attempt.kind === "SECONDARY_REPAIR"); + if (preceding === void 0) return "other"; + if (preceding.noProgress) return "no-progress"; + switch (preceding.outcome) { + case "FAILED_VERIFICATION": + return "verification-failure"; + case "FAILED_OUTPUT": + return "malformed-model-result"; + case "FAILED_RESOURCE": + return "capability-failure"; + case "FAILED_IMPLEMENTATION": + return /context|stale source|insufficient/i.test(preceding.failureSummary ?? "") ? "context-insufficiency" : "implementation-failure"; + default: + return "other"; + } +} +function median4(values) { + if (values.length === 0) return null; + const sorted = [...values].sort((left, right) => left - right); + const middle = Math.floor(sorted.length / 2); + if (sorted.length % 2 === 1) return sorted[middle] ?? null; + return ((sorted[middle - 1] ?? 0) + (sorted[middle] ?? 0)) / 2; +} +function deriveExecutionTelemetryReport(facts) { + const diagnostics = []; + const generatedMs = timestampMs(facts.generatedAt) ?? 0; + const eventTypes = (type) => facts.events.filter((event) => event.type === type); + const currentRouting = currentRoutingStates(facts.objectives); + const { attempts: implementationAttempts, duplicateIds } = uniqueBuilderAttempts(facts.objectives); + const units = latestUnits(facts.objectives); + const evaluations = facts.objectives.flatMap((objective) => objective.evaluations).filter((entry2, index, values) => values.findIndex((other) => other.evaluationId === entry2.evaluationId) === index).sort((left, right) => left.createdAt.localeCompare(right.createdAt, "en")); + if (facts.eventTotal > facts.events.length) { + diagnostics.push({ + code: "EVENT_WINDOW_BOUNDED", + severity: "info", + message: `The report used the newest ${facts.events.length} of ${facts.eventTotal} job events; ledgers and current state remain authoritative for aggregates.`, + evidenceRefs: [] + }); + } + if (facts.objectives.length === 0) { + diagnostics.push({ + code: "OBJECTIVE_TELEMETRY_UNAVAILABLE", + severity: "info", + message: "No objective-runtime records exist; Phase 7/8 metrics are unavailable for this older or direct-execution job.", + evidenceRefs: [] + }); + } + if (facts.autonomy.boundaryStartedAt === null) { + diagnostics.push({ + code: "ZERO_TOUCH_BOUNDARY_UNAVAILABLE", + severity: "info", + message: "No durable seal boundary exists; intervention counting conservatively includes the whole recorded Job history.", + evidenceRefs: [] + }); + } + if (duplicateIds > 0) { + diagnostics.push({ + code: "ATTEMPT_REPLAY_DEDUPLICATED", + severity: "info", + message: `${duplicateIds} replayed builder-attempt record${duplicateIds === 1 ? "" : "s"} were ignored by durable attempt id.`, + evidenceRefs: [] + }); + } + if (facts.researchTelemetryDiagnostic !== void 0) { + diagnostics.push({ + code: "RESEARCH_TELEMETRY_UNREADABLE", + severity: "warning", + message: redactTelemetryText(facts.researchTelemetryDiagnostic), + evidenceRefs: [] + }); + } + for (const diagnostic of facts.researchRecordDiagnostics ?? []) { + diagnostics.push({ + code: diagnostic.code.slice(0, 512), + severity: "warning", + message: redactTelemetryText(diagnostic.message), + evidenceRefs: [] + }); + } + const attemptsByUnit = /* @__PURE__ */ new Map(); + for (const attempt of implementationAttempts) { + const key = `${attempt.objectiveNodeId}\0${attempt.workUnitId}`; + const list = attemptsByUnit.get(key) ?? []; + list.push(attempt); + attemptsByUnit.set(key, list); + } + const evaluationsByUnit = /* @__PURE__ */ new Map(); + for (const evaluation of evaluations) { + const key = `${evaluation.objectiveNodeId}\0${evaluation.workUnitId}`; + const list = evaluationsByUnit.get(key) ?? []; + list.push(evaluation); + evaluationsByUnit.set(key, list); + } + const workAccountingCounts = { + completed: 0, + failed: 0, + cancelled: 0, + waiting: 0, + "not-ready": 0, + "human-authority-pending": 0, + "research-pending": 0, + "context-pending": 0 + }; + const workByKind = {}; + const unitSummaries = []; + for (const entry2 of units) { + const key = `${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`; + const routing = currentRouting.get(key); + const unitAttempts = attemptsByUnit.get(key) ?? []; + const unitEvaluations = evaluationsByUnit.get(key) ?? []; + const accounting = workAccounting(entry2.unit, routing); + workAccountingCounts[accounting] += 1; + increment2(workByKind, entry2.unit.kind); + if (unitSummaries.length < 500) { + unitSummaries.push({ + workUnitId: entry2.unit.workUnitId, + objectiveNodeId: entry2.objectiveNodeId, + kind: entry2.unit.kind, + status: entry2.unit.status, + accounting, + builderPath: builderPath(unitAttempts), + implementationAttempts: unitAttempts.length, + verification: verificationFor(unitEvaluations), + integration: entry2.unit.status === "INTEGRATED" ? "INTEGRATED" : "NOT_INTEGRATED" + }); + } + } + const eligibility = { + eligible: 0, + ineligible: 0, + strongRequired: 0, + needsResearch: 0, + needsAuthority: 0, + needsContext: 0, + notReady: 0, + unavailable: units.filter((entry2) => entry2.unit.kind === "build" && !currentRouting.has(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`)).length + }; + const selection = { + secondarySelected: 0, + strongSelectedDespiteEligibility: 0, + noBuilderNeeded: 0, + waitingForResource: 0 + }; + const strongSelection = { + requiredDirect: 0, + byStrategyOff: 0, + byAutoPolicy: 0, + becauseSecondaryUnavailable: 0, + fallbackAfterSecondary: 0 + }; + const fallbackReasons = {}; + for (const entry2 of units) { + if (entry2.unit.kind !== "build") { + selection.noBuilderNeeded += 1; + continue; + } + const key = `${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`; + const state = currentRouting.get(key); + if (state === void 0) continue; + switch (state.initialEligibility) { + case "ELIGIBLE": + eligibility.eligible += 1; + break; + case "STRONG_REQUIRED": + eligibility.strongRequired += 1; + break; + case "NEEDS_RESEARCH": + eligibility.needsResearch += 1; + break; + case "NEEDS_AUTHORITY": + eligibility.needsAuthority += 1; + break; + case "NEEDS_CONTEXT": + eligibility.needsContext += 1; + break; + case "NOT_READY": + eligibility.notReady += 1; + break; + default: + break; + } + const decisions = state.decisions; + const unitAttempts = attemptsByUnit.get(key) ?? []; + if (entry2.unit.resourceWait !== void 0) selection.waitingForResource += 1; + if (state.initialEligibility === "ELIGIBLE") { + if (decisions.some((decision) => decision.selectedBackend === "SECONDARY")) { + selection.secondarySelected += 1; + } else if (decisions.some((decision) => decision.selectedBackend === "STRONG")) { + selection.strongSelectedDespiteEligibility += 1; + } + } + const directStrong = decisions.find((decision) => decision.selectedBackend === "STRONG"); + if (directStrong !== void 0 && !unitAttempts.some((attempt) => attempt.kind === "STRONG_FALLBACK")) { + if (state.initialEligibility === "STRONG_REQUIRED") strongSelection.requiredDirect += 1; + else if (directStrong.reasons.some((reason3) => reason3.code === "STRATEGY_OFF")) strongSelection.byStrategyOff += 1; + else if (directStrong.reasons.some((reason3) => reason3.code === "SECONDARY_UNAVAILABLE")) { + strongSelection.becauseSecondaryUnavailable += 1; + } else if (directStrong.reasons.some((reason3) => reason3.code === "SUBSCRIPTION_HARVEST" || reason3.code === "SECONDARY_AUTO_POLICY" || reason3.code === "CRITICAL_WORK_PREFERS_STRONG")) { + strongSelection.byAutoPolicy += 1; + } + } + if (unitAttempts.some((attempt) => attempt.kind === "STRONG_FALLBACK")) { + strongSelection.fallbackAfterSecondary += 1; + increment2(fallbackReasons, fallbackReason(unitAttempts)); + } + } + eligibility.ineligible = eligibility.strongRequired + eligibility.needsResearch + eligibility.needsAuthority + eligibility.needsContext + eligibility.notReady; + const eligibleUnits = units.filter((entry2) => { + const state = currentRouting.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`); + return entry2.unit.kind === "build" && state?.initialEligibility === "ELIGIBLE"; + }); + const eligibleCompleted = eligibleUnits.filter((entry2) => entry2.unit.status === "INTEGRATED"); + const eligibleCompletedWithoutStrong = eligibleCompleted.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return !attempts.some((attempt) => attempt.kind === "STRONG" || attempt.kind === "STRONG_FALLBACK"); + }); + const secondaryAttemptedUnits = eligibleUnits.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => (attempt.kind === "SECONDARY" || attempt.kind === "SECONDARY_REPAIR") && attempt.outcome !== "FAILED_RESOURCE" && attempt.outcome !== "CANCELLED"); + }); + const initialAttemptedUnits = eligibleUnits.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => attempt.kind === "SECONDARY" && attempt.outcome !== "FAILED_RESOURCE" && attempt.outcome !== "CANCELLED"); + }); + const initialPassUnits = initialAttemptedUnits.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => attempt.kind === "SECONDARY" && attempt.outcome === "SUCCEEDED"); + }); + const repairAttemptedUnits = eligibleUnits.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => attempt.kind === "SECONDARY_REPAIR" && attempt.outcome !== "FAILED_RESOURCE" && attempt.outcome !== "CANCELLED"); + }); + const repairPassUnits = repairAttemptedUnits.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => attempt.kind === "SECONDARY_REPAIR" && attempt.outcome === "SUCCEEDED"); + }); + const fallbackUnits = eligibleUnits.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => attempt.kind === "STRONG_FALLBACK"); + }); + const unavailableFallbackUnits = eligibleUnits.filter((entry2) => { + const state = currentRouting.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`); + return state?.decisions.some((decision) => decision.selectedBackend === "STRONG" && decision.reasons.some((reason3) => reason3.code === "SECONDARY_UNAVAILABLE")) === true; + }); + const secondaryAttempts = implementationAttempts.filter((attempt) => attempt.kind === "SECONDARY" || attempt.kind === "SECONDARY_REPAIR"); + const strongAttempts = implementationAttempts.filter((attempt) => attempt.kind === "STRONG" || attempt.kind === "STRONG_FALLBACK"); + const strongEvaluatorAttempts = facts.ledger.filter((entry2) => entry2.role === "EVALUATOR" && entry2.lane !== "LOCAL"); + const secondaryTokens = tokenTelemetry(secondaryAttempts, (attempt) => ({ + input: attempt.inputTokens, + output: attempt.outputTokens + })); + const strongTokens = tokenTelemetry(strongAttempts, (attempt) => ({ + input: attempt.inputTokens, + output: attempt.outputTokens + })); + const evaluatorTokens = tokenTelemetry(strongEvaluatorAttempts, (attempt) => ({ + input: attempt.metrics.inputTokens, + output: attempt.metrics.outputTokens + })); + const jobResearchRecords = facts.researchRecords.filter((record5) => record5.scope?.jobId === facts.job.jobId); + const jobResearchIds = new Set(jobResearchRecords.map((record5) => record5.researchId)); + const jobResearchUses = facts.researchUses.filter((use) => jobResearchIds.has(use.researchId)); + const hasJobResearch = jobResearchRecords.length > 0 || jobResearchUses.length > 0; + const hasWorkspaceResearch = (facts.researchTelemetry?.gateConsidered ?? 0) > 0 || facts.researchRecords.length > 0 || facts.researchUses.length > 0; + const researchScope = hasJobResearch ? "JOB" : hasWorkspaceResearch ? "WORKSPACE" : "NONE"; + const reportResearchRecords = hasJobResearch ? jobResearchRecords : facts.researchRecords; + const reportResearchUses = hasJobResearch ? jobResearchUses : facts.researchUses; + const useIds = new Set(reportResearchUses.map((use) => use.useId)); + const uniqueUses = reportResearchUses.filter((use) => { + if (!useIds.has(use.useId)) return false; + useIds.delete(use.useId); + return true; + }); + const providerRecords = reportResearchRecords.filter((record5) => record5.status !== "PENDING"); + const workspaceResearch = researchScope === "WORKSPACE"; + const providerCallCount = workspaceResearch ? facts.researchTelemetry?.providerCalls ?? providerRecords.length : providerRecords.length; + const successfulResearch = workspaceResearch ? facts.researchTelemetry?.successfulResearch ?? providerRecords.filter((record5) => record5.status === "COMPLETED").length : providerRecords.filter((record5) => record5.status === "COMPLETED").length; + const inconclusiveResearch = workspaceResearch ? facts.researchTelemetry?.inconclusiveResearch ?? providerRecords.filter((record5) => record5.status === "INCONCLUSIVE").length : providerRecords.filter((record5) => record5.status === "INCONCLUSIVE").length; + const failedResearch = workspaceResearch ? facts.researchTelemetry?.failedResearch ?? providerRecords.filter((record5) => record5.status === "FAILED").length : providerRecords.filter((record5) => record5.status === "FAILED").length; + const reuseCount = workspaceResearch ? facts.researchTelemetry?.reusedReports ?? uniqueUses.filter((use) => use.useKind === "REUSED").length : uniqueUses.filter((use) => use.useKind === "REUSED").length; + const newQuick = workspaceResearch ? facts.researchTelemetry?.newQuick ?? providerRecords.filter((record5) => record5.depth === "QUICK").length : providerRecords.filter((record5) => record5.depth === "QUICK").length; + const newDeep = workspaceResearch ? facts.researchTelemetry?.newDeep ?? providerRecords.filter((record5) => record5.depth === "DEEP").length : providerRecords.filter((record5) => record5.depth === "DEEP").length; + const researchConsidered = researchScope === "WORKSPACE" ? facts.researchTelemetry?.gateConsidered ?? null : null; + const researchAvoided = researchScope === "WORKSPACE" ? facts.researchTelemetry?.researchAvoided ?? null : null; + const researchDecisions = researchScope === "WORKSPACE" ? { ...facts.researchTelemetry?.decisions ?? {} } : {}; + const byPhase = {}; + for (const phase of ["CONVERSATION", "SPEC_DRAFT", "INTAKE_DECISION", "RUNTIME_INVESTIGATION"]) { + const aggregate = researchScope === "WORKSPACE" ? facts.researchTelemetry?.byPhase[phase] : void 0; + const phaseRecords = providerRecords.filter((record5) => record5.lifecycle?.phase === phase); + const phaseUses = uniqueUses.filter((use) => use.phase === phase); + byPhase[phase] = { + considered: aggregate?.considered ?? 0, + avoided: aggregate?.avoided ?? 0, + reused: researchScope === "WORKSPACE" ? aggregate?.reused ?? phaseUses.filter((use) => use.useKind === "REUSED").length : phaseUses.filter((use) => use.useKind === "REUSED").length, + newCalls: researchScope === "WORKSPACE" ? (aggregate?.newQuick ?? 0) + (aggregate?.newDeep ?? 0) : phaseRecords.length, + quick: researchScope === "WORKSPACE" ? aggregate?.newQuick ?? phaseRecords.filter((record5) => record5.depth === "QUICK").length : phaseRecords.filter((record5) => record5.depth === "QUICK").length, + deep: researchScope === "WORKSPACE" ? aggregate?.newDeep ?? phaseRecords.filter((record5) => record5.depth === "DEEP").length : phaseRecords.filter((record5) => record5.depth === "DEEP").length, + failed: phaseRecords.filter((record5) => record5.status === "FAILED").length + }; + } + let researchInputTokens = 0; + let researchOutputTokens = 0; + let researchDurationMs = 0; + let researchCost = 0; + let researchSubagents = 0; + let researchInputObserved = false; + let researchOutputObserved = false; + let researchDurationObserved = false; + let researchCostObserved = false; + let researchSubagentsObserved = false; + let recordsWithUsage = 0; + for (const record5 of providerRecords) { + const usage = record5.usage ?? record5.report?.usage; + if (usage === void 0) continue; + recordsWithUsage += 1; + if (usage.inputTokens !== void 0) { + researchInputObserved = true; + researchInputTokens += usage.inputTokens; + } + if (usage.outputTokens !== void 0) { + researchOutputObserved = true; + researchOutputTokens += usage.outputTokens; + } + if (usage.durationMs !== void 0) { + researchDurationObserved = true; + researchDurationMs += usage.durationMs; + } + if (usage.providerReportedCost !== void 0) { + researchCostObserved = true; + researchCost += usage.providerReportedCost; + } + if (usage.subagentCount !== void 0) { + researchSubagentsObserved = true; + researchSubagents += usage.subagentCount; + } + } + if (researchScope === "WORKSPACE" && providerRecords.length === 0 && facts.researchTelemetry !== void 0) { + const reported = facts.researchTelemetry.reportedUsage; + if (reported.reports > 0) { + recordsWithUsage = reported.reports; + if (reported.inputTokens > 0) { + researchInputObserved = true; + researchInputTokens = reported.inputTokens; + } + if (reported.outputTokens > 0) { + researchOutputObserved = true; + researchOutputTokens = reported.outputTokens; + } + if (reported.providerReportedCost > 0) { + researchCostObserved = true; + researchCost = reported.providerReportedCost; + } + if (reported.subagentCount > 0) { + researchSubagentsObserved = true; + researchSubagents = reported.subagentCount; + } + } + if (facts.researchTelemetry.totalDurationMs > 0) { + researchDurationObserved = true; + researchDurationMs = facts.researchTelemetry.totalDurationMs; + } + } + const cooldownStates = facts.objectives.map((objective) => objective.cooldown).filter((state) => state !== void 0); + const cooldownIntervals = []; + let cooldownDurationMs = 0; + let cooldownDurationKnown = cooldownStates.length > 0; + let cooldownEpisodes = 0; + for (const state of cooldownStates) { + cooldownEpisodes += state.episodes; + const startedAt = state.currentStartedAt ?? state.firstStartedAt; + const endedAt = state.status === "RECOVERED" ? state.lastEndedAt ?? null : null; + const startMs = timestampMs(startedAt); + const endMs = state.status === "ACTIVE" ? generatedMs : timestampMs(endedAt); + const durationMs = startMs !== void 0 && endMs !== void 0 && endMs >= startMs ? endMs - startMs : null; + if (state.episodes !== 1) cooldownDurationKnown = false; + if (durationMs === null) cooldownDurationKnown = false; + else cooldownDurationMs += durationMs; + cooldownIntervals.push({ + objectiveNodeId: state.objectiveNodeId, + status: state.status, + startedAt, + endedAt, + durationMs, + completedWorkUnits: state.completedDuringCooldown.length + }); + if (state.episodes > 1) { + diagnostics.push({ + code: "COOLDOWN_DURATION_PARTIAL", + severity: "info", + message: `Objective ${state.objectiveNodeId} records ${state.episodes} cooldown episodes but retains only bounded interval endpoints; total duration is unavailable.`, + evidenceRefs: [state.objectiveNodeId] + }); + } + } + const cooldownCompletedKeys = /* @__PURE__ */ new Set(); + const cooldownWaitingKeys = /* @__PURE__ */ new Set(); + for (const state of cooldownStates) { + for (const workUnitId of state.completedDuringCooldown) { + cooldownCompletedKeys.add(`${state.objectiveNodeId}\0${workUnitId}`); + } + for (const workUnitId of state.waitingWorkUnitIds) { + cooldownWaitingKeys.add(`${state.objectiveNodeId}\0${workUnitId}`); + } + } + let secondaryImplementationDuringCooldown = 0; + for (const entry2 of units) { + const key = `${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`; + if (!cooldownCompletedKeys.has(key) || entry2.unit.kind !== "build") continue; + const unitAttempts = attemptsByUnit.get(key) ?? []; + if (unitAttempts.some((attempt) => attempt.kind === "SECONDARY" || attempt.kind === "SECONDARY_REPAIR") && !unitAttempts.some((attempt) => attempt.kind === "STRONG" || attempt.kind === "STRONG_FALLBACK")) { + secondaryImplementationDuringCooldown += 1; + } + } + const withinCooldown = (at) => { + const atMs = timestampMs(at); + if (atMs === void 0) return false; + return cooldownIntervals.some((interval) => { + const start = timestampMs(interval.startedAt); + const end = timestampMs(interval.endedAt) ?? generatedMs; + return start !== void 0 && atMs >= start && atMs <= end; + }); + }; + const researchDuringCooldown = providerRecords.filter((record5) => (record5.status === "COMPLETED" || record5.status === "INCONCLUSIVE") && withinCooldown(record5.report?.completedAt ?? record5.updatedAt)).length; + let avoidableIdlePeriods = 0; + for (const objective of facts.objectives) { + if (objective.cooldown?.status !== "ACTIVE" || objective.graph === void 0) continue; + for (const unit of objective.graph.units) { + if (unit.kind !== "build" || unit.status !== "READY" || unit.resourceWait !== void 0) continue; + const key = `${objective.objectiveNodeId}\0${unit.workUnitId}`; + const state = currentRouting.get(key); + if (state?.initialEligibility !== "ELIGIBLE" || state.strategy === "OFF") continue; + const startMs = timestampMs(objective.cooldown.currentStartedAt); + const dispatched = (attemptsByUnit.get(key) ?? []).some((attempt) => { + const attemptMs = timestampMs(attempt.startedAt); + return (attempt.kind === "SECONDARY" || attempt.kind === "SECONDARY_REPAIR") && attemptMs !== void 0 && (startMs === void 0 || attemptMs >= startMs); + }); + if (!dispatched) avoidableIdlePeriods += 1; + } + } + if (avoidableIdlePeriods > 0) { + diagnostics.push({ + code: "AVOIDABLE_IDLE_DURING_COOLDOWN", + severity: "warning", + message: `${avoidableIdlePeriods} runnable Secondary work period(s) had no durable Secondary dispatch during an active Strong cooldown.`, + evidenceRefs: [] + }); + } + const cooldownEventTypes = /* @__PURE__ */ new Set([ + "resource_cooldown_started", + "resource_cooldown_observed", + "work_unit_resource_wait_started", + "work_unit_resource_wait_ended", + "resource_wait_entered", + "useful_work_during_cooldown", + "resource_recovered" + ]); + const cooldownTimeline = facts.events.filter((event) => cooldownEventTypes.has(event.type)).slice(-200).map((event) => ({ + at: String(event.at ?? ""), + type: event.type, + objectiveNodeId: typeof event["nodeId"] === "string" ? event["nodeId"].slice(0, 512) : null, + detail: cooldownEventDetail(event) + })); + const evaluationFailures = evaluations.filter((entry2) => entry2.verdict === "FAIL"); + const evaluationPasses = evaluations.filter((entry2) => entry2.verdict === "PASS"); + const failuresByBackend = {}; + let failuresRecoveredByRepair = 0; + let failuresRecoveredByStrongFallback = 0; + const failedUnitKeys = /* @__PURE__ */ new Set(); + for (const evaluation of evaluationFailures) { + const key = `${evaluation.objectiveNodeId}\0${evaluation.workUnitId}`; + failedUnitKeys.add(key); + const unitAttempts = attemptsByUnit.get(key) ?? []; + const matching = [...unitAttempts].reverse().find((attempt) => attempt.workUnitAttempt === evaluation.attempt); + increment2(failuresByBackend, matching?.kind ?? "UNKNOWN"); + } + for (const key of failedUnitKeys) { + const unitAttempts = attemptsByUnit.get(key) ?? []; + if (unitAttempts.some((attempt) => attempt.kind === "SECONDARY_REPAIR" && attempt.outcome === "SUCCEEDED")) { + failuresRecoveredByRepair += 1; + } + if (unitAttempts.some((attempt) => attempt.kind === "STRONG_FALLBACK" && attempt.outcome === "SUCCEEDED")) { + failuresRecoveredByStrongFallback += 1; + } + } + const failureSources = {}; + const recoveryActions = {}; + for (const entry2 of facts.ledger) { + if (entry2.failureSource !== null) increment2(failureSources, entry2.failureSource); + else if (!entry2.success && entry2.failureReason !== null) increment2(failureSources, "UNCLASSIFIED"); + if (entry2.recoveryAction !== null) increment2(recoveryActions, entry2.recoveryAction); + } + const repairAttempts = implementationAttempts.filter((attempt) => attempt.kind === "SECONDARY_REPAIR").length; + const strongFallbackAttempts = implementationAttempts.filter((attempt) => attempt.kind === "STRONG_FALLBACK").length; + if (repairAttempts > 0) increment2(recoveryActions, "repair", repairAttempts); + if (strongFallbackAttempts > 0) increment2(recoveryActions, "strong-fallback", strongFallbackAttempts); + const resourceWaitEvents = eventTypes("resource_wait_started").length + eventTypes("resource_wait_entered").length + eventTypes("work_unit_resource_wait_started").length; + if (resourceWaitEvents > 0) increment2(recoveryActions, "resource-wait", resourceWaitEvents); + const restartEvents = eventTypes("job_resumed").length + eventTypes("driver_restarted").length; + if (restartEvents > 0) increment2(recoveryActions, "restart-resume", restartEvents); + const noProgressDetections = implementationAttempts.filter((attempt) => attempt.noProgress).length; + const fingerprintCounts = /* @__PURE__ */ new Map(); + for (const attempt of implementationAttempts) { + if (attempt.problemFingerprint !== void 0) { + fingerprintCounts.set( + attempt.problemFingerprint, + (fingerprintCounts.get(attempt.problemFingerprint) ?? 0) + 1 + ); + } + } + const repeatedProblemFingerprints = [...fingerprintCounts.values()].filter((value) => value > 1).length; + const candidatesPersisted = new Set( + implementationAttempts.map((attempt) => attempt.candidateRef).filter((ref) => ref !== void 0) + ).size; + const candidateRebuilds = eventTypes("candidate_resume_missing").length; + const candidatesReused = cooldownStates.reduce( + (sum, state) => sum + state.candidateReuseAfterRestart, + 0 + ); + const integrationRetries = eventTypes("integration_failed").length; + let completedWorkRedoCount = 0; + for (const entry2 of units) { + if (entry2.unit.integratedAt === void 0) continue; + const integratedMs = timestampMs(entry2.unit.integratedAt); + if (integratedMs === void 0) continue; + const attemptsAfterIntegration = (attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []).filter((attempt) => (timestampMs(attempt.startedAt) ?? 0) > integratedMs); + if (attemptsAfterIntegration.length > 0) completedWorkRedoCount += 1; + } + const lastRestartMs = Math.max( + 0, + ...facts.events.filter((event) => event.type === "job_resumed" || event.type === "driver_restarted").map((event) => timestampMs(event.at) ?? 0) + ); + const completedWorkReusedAfterRestart = lastRestartMs === 0 ? 0 : units.filter((entry2) => { + if (entry2.unit.status !== "INTEGRATED") return false; + const unitAttempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return unitAttempts.length > 0 && unitAttempts.every((attempt) => (timestampMs(attempt.completedAt) ?? Number.MAX_SAFE_INTEGER) <= lastRestartMs); + }).length; + const unresolvedInterrupted = facts.ledger.filter((entry2) => { + if (entry2.status !== "INTERRUPTED") return false; + return !facts.ledger.some((candidate) => candidate.taskId === entry2.taskId && candidate.attemptNumber > entry2.attemptNumber && candidate.status === "COMPLETED"); + }).length; + const unrecoveredDriverDeaths = ["COMPLETED", "FAILED", "CANCELLED"].includes(facts.job.status) ? unresolvedInterrupted : 0; + const unexpectedBlocks = facts.autonomy.interventions.filter((intervention) => intervention.kind === "job_blocked" || intervention.kind === "budget_exhausted" || intervention.kind.startsWith("status:")).length; + if (completedWorkRedoCount > 0) { + diagnostics.push({ + code: "COMPLETED_WORK_REDONE", + severity: "error", + message: `${completedWorkRedoCount} authoritatively integrated WorkUnit(s) have a later implementation attempt without recorded invalidation.`, + evidenceRefs: [] + }); + } + const completedImplementation = units.filter((entry2) => entry2.unit.kind === "build" && entry2.unit.status === "INTEGRATED").length; + const attemptCountsForCompleted = units.filter((entry2) => entry2.unit.status === "INTEGRATED" && entry2.unit.kind === "build").map((entry2) => (attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []).length); + const totalAttemptsForCompleted = attemptCountsForCompleted.reduce((sum, value) => sum + value, 0); + const meanAttempts = attemptCountsForCompleted.length === 0 ? null : totalAttemptsForCompleted / attemptCountsForCompleted.length; + const completedPerAttempt = implementationAttempts.length === 0 ? null : completedImplementation / implementationAttempts.length; + const completedPerStrong = strongAttempts.length === 0 ? null : completedImplementation / strongAttempts.length; + const completedEligiblePerSecondary = secondaryAttempts.length === 0 ? null : eligibleCompleted.length / secondaryAttempts.length; + const closureTotals = facts.closure === void 0 ? void 0 : summarizeClosure(facts.closure.entries); + const closureGate = facts.closure === void 0 ? void 0 : missionMayComplete(facts.closure, facts.closurePolicy); + const closureOutcome = facts.closure === void 0 ? "UNAVAILABLE" : closureGate?.mayComplete === true ? "PASS" : "FAIL"; + const overallVerification = verificationOutcome(facts.job, facts.events); + const boundaryMs = timestampMs(facts.autonomy.boundaryStartedAt); + const decisionsBeforeSeal = boundaryMs === void 0 ? null : facts.events.filter((event) => (event.type === "clarification_resolved" || event.type === "authority_resolved") && (timestampMs(event.at) ?? Number.MAX_SAFE_INTEGER) < boundaryMs).length; + const humanByKind = {}; + for (const intervention of facts.autonomy.interventions) increment2(humanByKind, intervention.kind); + const objectiveRevisions = {}; + for (const objective of facts.objectives) { + if (objective.graph !== void 0) objectiveRevisions[objective.objectiveNodeId] = objective.graph.revision; + } + const ledgerWatermark = sha256Hex(JSON.stringify( + facts.ledger.map((entry2) => [entry2.attemptId, entry2.status, entry2.completedAt]) + )); + const currentPolicyFingerprint = autonomyPolicyFingerprint(facts.currentAutonomyPolicy); + const runtimePolicyChanged = facts.binding === void 0 ? null : currentPolicyFingerprint !== facts.binding.boundPolicyFingerprint; + const strongAvoidance = metric(eligibleCompletedWithoutStrong.length, eligibleCompleted.length); + const secondaryInitial = metric(initialPassUnits.length, initialAttemptedUnits.length); + const secondaryRepair = metric(repairPassUnits.length, repairAttemptedUnits.length); + const secondaryFallback = metric(fallbackUnits.length, secondaryAttemptedUnits.length); + const researchAvoidance = metric(researchAvoided, researchConsidered); + const researchReuse = metric( + reuseCount, + reuseCount + providerCallCount + ); + const implementationByKind = {}; + for (const attempt of implementationAttempts) increment2(implementationByKind, attempt.kind); + const objectiveSummaries = facts.objectives.slice(0, 200).map((objective) => { + const accounting = { + completed: 0, + failed: 0, + cancelled: 0, + waiting: 0, + "not-ready": 0, + "human-authority-pending": 0, + "research-pending": 0, + "context-pending": 0 + }; + for (const unit of objective.graph?.units ?? []) { + const key = `${objective.objectiveNodeId}\0${unit.workUnitId}`; + accounting[workAccounting(unit, currentRouting.get(key))] += 1; + } + const attempts = implementationAttempts.filter((entry2) => entry2.objectiveNodeId === objective.objectiveNodeId); + return { + objectiveNodeId: objective.objectiveNodeId, + graphRevision: objective.graph?.revision ?? null, + total: objective.graph?.units.length ?? 0, + accounting, + implementationAttempts: attempts.length, + secondaryAttempts: attempts.filter((entry2) => entry2.kind === "SECONDARY" || entry2.kind === "SECONDARY_REPAIR").length, + strongBuilderAttempts: attempts.filter((entry2) => entry2.kind === "STRONG" || entry2.kind === "STRONG_FALLBACK").length + }; + }); + const report = executionTelemetryReportSchema.parse({ + schemaVersion: EXECUTION_TELEMETRY_REPORT_SCHEMA_VERSION, + jobId: facts.job.jobId, + missionId: facts.binding?.missionId ?? facts.seal?.missionId ?? null, + generatedAt: facts.generatedAt, + period: { + startedAt: facts.job.createdAt, + endedAt: facts.job.finalizedAt ?? null, + durationMs: timestampMs(facts.job.createdAt) === void 0 ? null : Math.max( + 0, + (timestampMs(facts.job.finalizedAt ?? facts.generatedAt) ?? generatedMs) - (timestampMs(facts.job.createdAt) ?? generatedMs) + ), + activeExecutionMs: timestampMs(facts.job.createdAt) === void 0 ? null : workedMsOf(facts.job, timestampMs(facts.job.finalizedAt ?? facts.generatedAt) ?? generatedMs) + }, + provenance: { + sourceJobId: facts.job.jobId, + jobGraphRevision: facts.job.graphRevision, + objectiveGraphRevisions: objectiveRevisions, + executionLedgerWatermark: ledgerWatermark, + eventWatermark: facts.eventTotal, + specbridgeVersion: facts.specbridgeVersion ?? null, + sealId: facts.binding?.sealId ?? null, + sealedAuthorityDigest: facts.seal?.authorityDigest ?? null, + runtimePolicyChanged, + configuration: { + secondaryBuildStrategy: facts.secondaryBuildStrategy, + researchStrategy: facts.researchStrategy, + runnerProfiles: [...facts.runnerProfiles].sort().slice(0, 50) + } + }, + outcome: { + status: outcomeStatus(facts.job.status), + authoritativeJobStatus: facts.job.status, + finalOutcome: facts.job.finalOutcome === void 0 ? null : redactTelemetryText(facts.job.finalOutcome).slice(0, 2e3), + verification: overallVerification, + closure: closureOutcome + }, + work: { + total: units.length, + byKind: workByKind, + accounting: workAccountingCounts, + completedImplementation, + objectives: objectiveSummaries, + units: unitSummaries, + omittedUnits: Math.max(0, units.length - unitSummaries.length) + }, + secondary: { + eligibility, + selection, + funnel: { + initialAttempts: initialAttemptedUnits.length, + initialPass: initialPassUnits.length, + repairAttempted: repairAttemptedUnits.length, + repairPass: repairPassUnits.length, + toStrongFallback: fallbackUnits.length, + unavailableFallback: unavailableFallbackUnits.length + }, + initialSuccessRate: secondaryInitial, + repairRecoveryRate: secondaryRepair, + toStrongFallbackRate: secondaryFallback, + fallbackReasons, + builderTokens: secondaryTokens + }, + strong: { + builderAttempts: strongAttempts.length, + evaluatorAttempts: strongEvaluatorAttempts.length, + selection: strongSelection, + implementationTokens: strongTokens, + evaluatorTokens + }, + research: { + scope: researchScope, + considered: researchConsidered, + decisions: researchDecisions, + providerCalls: providerCallCount, + successful: successfulResearch, + inconclusive: inconclusiveResearch, + failed: failedResearch, + priorResearchReused: reuseCount, + newQuick, + newDeep, + avoidanceRatio: researchAvoidance, + reuseRate: researchReuse, + byPhase, + usage: { + inputTokens: researchInputObserved ? researchInputTokens : null, + outputTokens: researchOutputObserved ? researchOutputTokens : null, + durationMs: researchDurationObserved ? researchDurationMs : null, + providerReportedCost: researchCostObserved ? researchCost : null, + subagentCount: researchSubagentsObserved ? researchSubagents : null, + recordsWithUsage, + providerCalls: providerCallCount, + coverage: providerCallCount === 0 ? null : Math.min(1, recordsWithUsage / providerCallCount) + } + }, + cooldown: { + episodes: cooldownEpisodes, + observations: eventTypes("resource_cooldown_observed").length, + totalDurationMs: cooldownDurationKnown ? cooldownDurationMs : null, + usefulWorkDuringSubscriptionCooldown: cooldownCompletedKeys.size, + secondaryImplementationWorkDuringCooldown: secondaryImplementationDuringCooldown, + researchWorkDuringCooldown: researchDuringCooldown, + strongRequiredWaiting: cooldownWaitingKeys.size, + avoidableIdlePeriods, + intervals: cooldownIntervals.sort((left, right) => left.startedAt.localeCompare(right.startedAt, "en") || left.objectiveNodeId.localeCompare(right.objectiveNodeId, "en")), + timeline: cooldownTimeline + }, + attempts: { + uniqueImplementationAttempts: implementationAttempts.length, + meanPerCompletedWorkUnit: meanAttempts, + medianPerCompletedWorkUnit: median4(attemptCountsForCompleted), + maxPerWorkUnit: attemptCountsForCompleted.length === 0 ? 0 : Math.max(...attemptCountsForCompleted), + workUnitsWithMultipleAttempts: attemptCountsForCompleted.filter((value) => value > 1).length, + byKind: implementationByKind, + completedWorkUnitsPerImplementationAttempt: completedPerAttempt, + completedWorkUnitsPerStrongBuilderCall: completedPerStrong, + completedEligibleWorkUnitsPerSecondaryAttempt: completedEligiblePerSecondary + }, + verification: { + attempts: evaluations.length, + passes: evaluationPasses.length, + failures: evaluationFailures.length, + otherVerdicts: evaluations.length - evaluationPasses.length - evaluationFailures.length, + failuresByBuilderBackend: failuresByBackend, + failuresRecoveredByRepair, + failuresRecoveredByStrongFallback + }, + closure: { + available: closureTotals !== void 0, + items: closureTotals?.total ?? 0, + earned: closureTotals?.verified ?? 0, + waived: closureTotals?.waived ?? 0, + unresolved: closureTotals === void 0 ? 0 : closureTotals.total - closureTotals.verified - closureTotals.waived - closureTotals.notApplicable, + completionGateOutcome: closureOutcome, + ratio: closureTotals === void 0 ? null : closureRatio(closureTotals) + }, + human: { + decisionsBeforeSeal, + approvals: facts.seal?.sealedAt === void 0 ? 0 : 1, + authorityEscalationsAfterSeal: facts.autonomy.humanAuthorityEscalationsAfterSeal, + interventionsAfterSeal: facts.autonomy.humanInterventionsAfterSeal, + unexpectedBlockersAfterSeal: unexpectedBlocks, + zeroTouchAfterSeal: facts.autonomy.humanInterventionsAfterSeal === 0, + byKind: humanByKind + }, + reliability: { + failureSources, + recoveryActions, + noProgressDetections, + repeatedProblemFingerprints, + legitimateResourceWaitsExcluded: resourceWaitEvents, + processRestarts: eventTypes("job_resumed").length, + supervisorRestarts: eventTypes("driver_restarted").length + eventTypes("supervisor_lease_reclaimed").length, + candidatesPersisted, + candidatesReusedAfterRestart: candidatesReused, + candidateRebuildsAfterRestart: candidateRebuilds, + candidatesLostOrUnreadable: candidateRebuilds, + candidateReadyResumes: candidatesReused, + integrationRetries, + completedWorkRedoCount, + completedWorkReusedAfterRestart, + attemptsIncorrectlyRepeated: completedWorkRedoCount, + unexpectedBlocks, + unrecoveredDriverDeaths + }, + efficiency: { + strongBuilderAvoidanceRatio: strongAvoidance, + strongBuilderCallsAvoided: eligibleCompletedWithoutStrong.length, + completedWorkUnitsPerImplementationAttempt: completedPerAttempt, + baseline: facts.baseline === void 0 ? null : { + kind: facts.baseline.kind, + reportId: facts.baseline.reportId, + strongBuilderAttempts: facts.baseline.strongBuilderAttempts, + sameVerificationOutcome: facts.baseline.verificationOutcome === overallVerification, + sameClosureOutcome: facts.baseline.closureOutcome === closureOutcome + } + }, + qualificationSummary: { + strongBuilderAvoidanceRatio: strongAvoidance.value, + secondaryInitialSuccessRate: secondaryInitial.value, + secondaryRepairRecoveryRate: secondaryRepair.value, + secondaryToStrongFallback: fallbackUnits.length, + strongImplementationTokens: strongTokens.completeTokens, + researchAvoidanceRatio: researchAvoidance.value, + newResearchCalls: providerCallCount, + researchReuse: reuseCount, + usefulWorkDuringSubscriptionCooldown: cooldownCompletedKeys.size, + humanInterventionsAfterSeal: facts.autonomy.humanInterventionsAfterSeal, + completedWorkRedoCount, + unexpectedBlocks, + unrecoveredDriverDeaths + }, + diagnostics: diagnostics.slice(0, 200) + }); + return report; +} +function cooldownEventDetail(event) { + switch (event.type) { + case "resource_cooldown_started": + return `Strong resource cooldown started (${String(event["availability"] ?? "availability unknown")}).`; + case "resource_cooldown_observed": + return "Strong resource cooldown was observed again; this is not a new episode."; + case "work_unit_resource_wait_started": + return `WorkUnit ${String(event["workUnitId"] ?? "(unknown)")} entered a Strong resource wait.`; + case "work_unit_resource_wait_ended": + return `WorkUnit ${String(event["workUnitId"] ?? "(unknown)")} left its Strong resource wait.`; + case "resource_wait_entered": + return "The job entered a global resource wait because no permitted work remained runnable."; + case "useful_work_during_cooldown": + return `${Number(event["newlyCompleted"] ?? 0)} additional WorkUnit(s) completed during cooldown.`; + case "resource_recovered": + return "The Strong resource recovered and waiting work was released."; + default: + return event.type; + } +} +function collectExecutionTelemetryFacts(deps4, jobId, options = {}) { + const job = requireJobState(deps4.workspace, jobId); + const eventPage = readJobEvents(deps4.workspace, jobId, { limit: 500 }); + const objectives = listObjectiveNodes(deps4.workspace, jobId).map( + (objectiveNodeId) => ({ + objectiveNodeId, + graph: readLatestWorkGraph(deps4.workspace, jobId, objectiveNodeId), + routingStates: readBuilderRoutingStates(deps4.workspace, jobId, objectiveNodeId), + cooldown: readObjectiveCooldownState(deps4.workspace, jobId, objectiveNodeId), + evaluations: readEvaluations(deps4.workspace, jobId, objectiveNodeId) + }) + ); + const researchTelemetryRead = readResearchTelemetry(deps4.workspace); + const researchRecords = listResearchRecords(deps4.workspace); + const binding = readSealBinding(deps4.workspace, jobId); + const seal = readJobSeal(deps4.workspace, jobId); + return { + job, + events: eventPage.events, + eventTotal: eventPage.total, + ledger: readExecutionLedger(deps4.workspace, jobId), + objectives, + researchTelemetry: researchTelemetryRead.telemetry, + ...researchTelemetryRead.diagnostic !== void 0 ? { researchTelemetryDiagnostic: researchTelemetryRead.diagnostic } : {}, + researchRecords: researchRecords.records, + researchRecordDiagnostics: researchRecords.diagnostics.map((diagnostic) => ({ + code: diagnostic.code, + message: diagnostic.message + })), + researchUses: listResearchUseRecords(deps4.workspace), + autonomy: deriveAutonomyTelemetry(deps4, { jobId }), + closure: readClosureLedger(deps4.workspace, jobId), + ...binding !== void 0 ? { binding } : {}, + ...seal !== void 0 ? { seal } : {}, + generatedAt: nowIso5(deps4), + ...options.specbridgeVersion !== void 0 ? { specbridgeVersion: options.specbridgeVersion } : {}, + secondaryBuildStrategy: deps4.config.orchestration.jobs.objectives.secondaryBuilder.strategy, + researchStrategy: deps4.config.research.strategy, + runnerProfiles: Object.keys(deps4.config.runnerProfiles), + currentAutonomyPolicy: deps4.config.autonomy, + closurePolicy: deps4.config.autonomy.closure + }; +} +function executionTelemetryReportFile(workspace, jobId) { + if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(jobId)) { + throw new Error(`Invalid job id "${jobId}".`); + } + return assertInsideWorkspace( + workspace.rootDir, + import_path90.default.join(workspace.sidecarDir, "reports", `job-${jobId}-telemetry.json`) + ); +} +function persistExecutionTelemetryReport(workspace, report) { + const validated = executionTelemetryReportSchema.parse(report); + const file = executionTelemetryReportFile(workspace, validated.jobId); + (0, import_fs81.mkdirSync)(import_path90.default.dirname(file), { recursive: true }); + writeFileAtomic(file, `${JSON.stringify(validated, null, 2)} +`); + return file; +} +function computeExecutionTelemetryReport(deps4, jobId, options = {}) { + const report = deriveExecutionTelemetryReport( + collectExecutionTelemetryFacts(deps4, jobId, options) + ); + if (options.persist === true) persistExecutionTelemetryReport(deps4.workspace, report); + return report; +} +var shortText132 = external_exports.string().max(200); var text12 = external_exports.string().max(4e3); var controlPlaneRepairSchema = external_exports.object({ schemaVersion: external_exports.string().regex(/^\d+\.\d+\.\d+$/), - repairId: shortText122, + repairId: shortText132, /** The product job that hit the defect and is suspended for this. */ - productJobId: shortText122, + productJobId: shortText132, defectKind: external_exports.enum(CONTROL_PLANE_DEFECT_KINDS), /** What was observed, in one line. Never a stack trace with paths. */ symptom: text12, @@ -108515,22 +109965,22 @@ var controlPlaneRepairSchema = external_exports.object({ status: external_exports.enum(CONTROL_PLANE_REPAIR_STATUSES), /** Stages completed, in order. The gate is that this is a prefix. */ stagesCompleted: external_exports.array(external_exports.enum(CONTROL_PLANE_REPAIR_STAGES)).max(20).default([]), - createdAt: shortText122, - updatedAt: shortText122, - finishedAt: shortText122.optional(), + createdAt: shortText132, + updatedAt: shortText132, + finishedAt: shortText132.optional(), /** Isolated working copy the patch was developed in. */ - isolationPath: shortText122.optional(), + isolationPath: shortText132.optional(), /** Where the verified build was staged. Never the running installation. */ - artifactPath: shortText122.optional(), + artifactPath: shortText132.optional(), /** Files the patch touched, workspace-relative to the SpecBridge source. */ - changedFiles: external_exports.array(shortText122).max(200).default([]), + changedFiles: external_exports.array(shortText132).max(200).default([]), /** The regression test added, which is mandatory. */ - regressionTestPath: shortText122.optional(), + regressionTestPath: shortText132.optional(), /** Invariants the screen found the patch touching. Non-empty means reject. */ invariantViolations: external_exports.array( external_exports.object({ invariant: external_exports.enum(PROTECTED_CONTROL_PLANE_INVARIANTS), - file: shortText122, + file: shortText132, evidence: text12 }).passthrough() ).max(50).default([]), @@ -108642,8 +110092,8 @@ function classifyFailure2(observation2) { humanRequired: false }; } -async function runUnattendedMission(deps3, options) { - const policy = autonomyPolicyOf(deps3); +async function runUnattendedMission(deps4, options) { + const policy = autonomyPolicyOf(deps4); if (!isUnattendedMode(policy.mode)) { throw new AutonomyError( "SBA001", @@ -108652,11 +110102,11 @@ async function runUnattendedMission(deps3, options) { ); } const seal = requireExecutableSeal( - readJobSeal(deps3.workspace, options.jobId) ?? latestExecutableSeal(deps3.workspace, options.missionId), + readJobSeal(deps4.workspace, options.jobId) ?? latestExecutableSeal(deps4.workspace, options.missionId), policy ); const surfaces = requiredSurfacesFor(seal); - const report = options.preflightReport ?? await runOvernightPreflight(deps3, { + const report = options.preflightReport ?? await runOvernightPreflight(deps4, { subject: options.missionId, missionId: options.missionId, sealId: seal.sealId, @@ -108665,9 +110115,9 @@ async function runUnattendedMission(deps3, options) { }); assertOvernightReady(report); const emit22 = (kind, message2) => options.onEvent?.({ kind, message: message2 }); - if (readJobSeal(deps3.workspace, options.jobId) === void 0) { - bindSealToJob(deps3, options.jobId, seal.sealId); - recordJobEvent(jobDepsOf(deps3), options.jobId, "autonomy_seal_bound", { + if (readJobSeal(deps4.workspace, options.jobId) === void 0) { + bindSealToJob(deps4, options.jobId, seal.sealId); + recordJobEvent(jobDepsOf(deps4), options.jobId, "autonomy_seal_bound", { sealId: seal.sealId, missionId: seal.missionId, mode: policy.mode, @@ -108675,18 +110125,18 @@ async function runUnattendedMission(deps3, options) { criteria: seal.acceptanceCriteria.length }); } - if (readClosureLedger(deps3.workspace, options.jobId) === void 0) { - const ledger = buildClosureLedger(deps3, { jobId: options.jobId, seal }); + if (readClosureLedger(deps4.workspace, options.jobId) === void 0) { + const ledger = buildClosureLedger(deps4, { jobId: options.jobId, seal }); emit22("closure", `closure ledger built with ${ledger.entries.length} sealed item(s)`); } const supervisedDeps = { - ...deps3, - ...shouldDelegateAuthority(policy) ? { authorityResolver: createAuthorityResolver({ workspace: deps3.workspace, policy }) } : {}, - completionGate: createClosureCompletionGate(deps3.workspace, policy.closure) + ...deps4, + ...shouldDelegateAuthority(policy) ? { authorityResolver: createAuthorityResolver({ workspace: deps4.workspace, policy }) } : {}, + completionGate: createClosureCompletionGate(deps4.workspace, policy.closure) }; const host = typeof options.host === "function" ? options.host(supervisedDeps) : options.host; - const sessionStartedAt = nowIso5(deps3); - const startedMs = now5(deps3).getTime(); + const sessionStartedAt = nowIso5(deps4); + const startedMs = now5(deps4).getTime(); const recoveries = []; const audits = []; const maxCycles = options.maxCycles ?? 100; @@ -108735,11 +110185,11 @@ async function runUnattendedMission(deps3, options) { } const telemetry = computeAutonomyTelemetry(supervisedDeps, { jobId: options.jobId, - elapsedWallTimeMs: now5(deps3).getTime() - startedMs + elapsedWallTimeMs: now5(deps4).getTime() - startedMs }); return { stop: stop ?? { kind: "cycles-exhausted" }, - job: requireJobState(deps3.workspace, options.jobId), + job: requireJobState(deps4.workspace, options.jobId), seal, telemetry, audits, @@ -108747,7 +110197,7 @@ async function runUnattendedMission(deps3, options) { cycles }; } -async function resolveSupervisionStop(deps3, input) { +async function resolveSupervisionStop(deps4, input) { switch (input.stop.kind) { case "completed": return { stop: { kind: "completed", rationale: "the job reached a terminal COMPLETED status" } }; @@ -108759,7 +110209,7 @@ async function resolveSupervisionStop(deps3, input) { case "gave-up": return { stop: { kind: "gave-up", reason: input.stop.reason } }; case "needs-human": { - const job = requireJobState(deps3.workspace, input.jobId); + const job = requireJobState(deps4.workspace, input.jobId); if (input.stop.status === "NEEDS_AUTHORITY") { return { stop: { @@ -108775,9 +110225,9 @@ async function resolveSupervisionStop(deps3, input) { case "released": case "cycles-exhausted": default: { - const job = requireJobState(deps3.workspace, input.jobId); + const job = requireJobState(deps4.workspace, input.jobId); if (job.status === "BLOCKED" && job.blocker !== void 0) { - const recovery = applyRecovery(deps3, { + const recovery = applyRecovery(deps4, { jobId: input.jobId, observation: { kind: "blocked", detail: job.blocker.message }, emit: input.emit @@ -108788,10 +110238,10 @@ async function resolveSupervisionStop(deps3, input) { } } } -function applyRecovery(deps3, input) { +function applyRecovery(deps4, input) { const classification = classifyFailure2(input.observation); input.emit?.("recovery", `${classification.status}: ${classification.detail}`); - const jobDeps2 = jobDepsOf(deps3); + const jobDeps2 = jobDepsOf(deps4); const payload = { kind: classification.waitKind, detail: classification.detail, @@ -108829,19 +110279,19 @@ function applyRecovery(deps3, input) { } return classification; } -async function runClosureCycle(deps3, input) { - const job = requireJobState(deps3.workspace, input.jobId); - const graph = safeGraph(deps3, job); +async function runClosureCycle(deps4, input) { + const job = requireJobState(deps4.workspace, input.jobId); + const graph = safeGraph(deps4, job); const completedNodeIds = graph.filter((node) => node.status === "COMPLETED").map((node) => node.nodeId); const implementationComplete = graph.length > 0 && graph.every((node) => node.status === "COMPLETED" || node.status === "SUPERSEDED"); - const swept = attributeCompletedWork(deps3, { + const swept = attributeCompletedWork(deps4, { jobId: input.jobId, missionId: input.missionId }); if (swept.attributed > 0) { input.emit("closure", `attributed completed work to ${swept.attributed} sealed item reference(s)`); } - const { audit } = runClosureAudit(deps3, { + const { audit } = runClosureAudit(deps4, { jobId: input.jobId, completedNodeIds, implementationComplete @@ -108855,7 +110305,7 @@ async function runClosureCycle(deps3, input) { case "NEEDS_AUTHORITY": return { audit, stop: { kind: "needs-authority", question: audit.rationale } }; case "GENERATE_GAP_WORK": { - const generated = generateGapWork(deps3, { jobId: input.jobId, audit }); + const generated = generateGapWork(deps4, { jobId: input.jobId, audit }); input.emit("closure", `generated ${generated.length} gap work item(s)`); if (generated.length === 0) { return { @@ -108866,7 +110316,7 @@ async function runClosureCycle(deps3, input) { } }; } - const repairs = await runGapRepairs(deps3, { + const repairs = await runGapRepairs(deps4, { jobId: input.jobId, items: generated, ...input.signal !== void 0 ? { signal: input.signal } : {}, @@ -108876,15 +110326,15 @@ async function runClosureCycle(deps3, input) { "closure", `gap repairs: ${repairs.repaired.length} integrated, ${repairs.failed.length} failed` ); - clearOperationalStateIfNeeded(deps3, input.jobId); + clearOperationalStateIfNeeded(deps4, input.jobId); return { audit }; } case "RUN_SYSTEM_SCENARIOS": { - enterQualifying(jobDepsOf(deps3), input.jobId, { + enterQualifying(jobDepsOf(deps4), input.jobId, { phase: "SYSTEM_SCENARIO_QUALIFICATION", detail: audit.rationale }); - const scenarios = await runSystemScenarioPhase(deps3, { + const scenarios = await runSystemScenarioPhase(deps4, { jobId: input.jobId, ...input.environmentRuntime !== void 0 ? { runtime: input.environmentRuntime } : {}, ...input.probeExecutor !== void 0 ? { probeExecutor: input.probeExecutor } : {}, @@ -108897,49 +110347,49 @@ async function runClosureCycle(deps3, input) { "closure", `system scenarios: ${scenarios.passed}/${scenarios.executed} passed` + (scenarios.environmentUnavailable > 0 ? `, ${scenarios.environmentUnavailable} environment-unavailable` : "") + (scenarios.uncovered.length > 0 ? `, ${scenarios.uncovered.length} item(s) uncovered` : "") ); - clearOperationalStateIfNeeded(deps3, input.jobId); + clearOperationalStateIfNeeded(deps4, input.jobId); return { audit }; } case "RUN_RELEASE_QUALIFICATION": { - enterQualifying(jobDepsOf(deps3), input.jobId, { phase: "RELEASE_QUALIFICATION" }); - await runReleaseQualificationPhase(deps3, { + enterQualifying(jobDepsOf(deps4), input.jobId, { phase: "RELEASE_QUALIFICATION" }); + await runReleaseQualificationPhase(deps4, { jobId: input.jobId, ...input.signal !== void 0 ? { signal: input.signal } : {}, emit: (message2) => input.emit("closure", message2) }); - clearOperationalStateIfNeeded(deps3, input.jobId); + clearOperationalStateIfNeeded(deps4, input.jobId); return { audit }; } case "RUN_REPRODUCIBILITY": { - enterQualifying(jobDepsOf(deps3), input.jobId, { phase: "REPRODUCIBILITY" }); - await runReproducibilityPhase(deps3, { + enterQualifying(jobDepsOf(deps4), input.jobId, { phase: "REPRODUCIBILITY" }); + await runReproducibilityPhase(deps4, { jobId: input.jobId, ...input.signal !== void 0 ? { signal: input.signal } : {}, emit: (message2) => input.emit("closure", message2) }); - clearOperationalStateIfNeeded(deps3, input.jobId); + clearOperationalStateIfNeeded(deps4, input.jobId); return { audit }; } case "CONTINUE_IMPLEMENTATION": default: - clearOperationalStateIfNeeded(deps3, input.jobId); + clearOperationalStateIfNeeded(deps4, input.jobId); return { audit }; } } -function clearOperationalStateIfNeeded(deps3, jobId) { - const job = requireJobState(deps3.workspace, jobId); +function clearOperationalStateIfNeeded(deps4, jobId) { + const job = requireJobState(deps4.workspace, jobId); if (job.status === "QUALIFYING" || job.operationalWait !== void 0) { try { - clearOperationalState(jobDepsOf(deps3), jobId, { + clearOperationalState(jobDepsOf(deps4), jobId, { resolution: "the closure audit returned work to implementation" }); } catch { } } } -function safeGraph(deps3, job) { +function safeGraph(deps4, job) { try { - const graph = readGraphRevision(deps3.workspace, job.jobId, job.graphRevision); + const graph = readGraphRevision(deps4.workspace, job.jobId, job.graphRevision); return graph?.nodes.map((node) => ({ nodeId: node.nodeId, status: node.status })) ?? []; } catch { return []; @@ -109091,10 +110541,10 @@ var CERTIFICATION_MATRIX = Object.freeze([ expectedBehaviour: "the job stops in NEEDS_AUTHORITY with the question recorded, and the sealed contract is NOT modified" } ]); -var shortText132 = external_exports.string().max(200); +var shortText142 = external_exports.string().max(200); var text13 = external_exports.string().max(4e3); var certificationScenarioResultSchema = external_exports.object({ - scenarioId: shortText132, + scenarioId: shortText142, fault: external_exports.enum(ZERO_TOUCH_FAULTS), expectation: external_exports.enum(ZERO_TOUCH_EXPECTATIONS), outcome: external_exports.enum(ZERO_TOUCH_OUTCOMES), @@ -109105,21 +110555,21 @@ var certificationScenarioResultSchema = external_exports.object({ /** What the runtime actually did, in one or two lines. */ observed: text13, /** The job status the scenario ended in. */ - finalStatus: shortText132.optional(), + finalStatus: shortText142.optional(), /** Operational statuses the job passed through, in order. */ - recoveryPath: external_exports.array(shortText132).max(30).default([]), + recoveryPath: external_exports.array(shortText142).max(30).default([]), /** Present when the scenario could not run here. Never a pass. */ skipReason: text13.optional(), - startedAt: shortText132, - finishedAt: shortText132.optional(), + startedAt: shortText142, + finishedAt: shortText142.optional(), durationMs: external_exports.number().int().min(0).nullable().default(null) }).passthrough(); var certificationRunSchema = external_exports.object({ schemaVersion: external_exports.string().regex(/^\d+\.\d+\.\d+$/), - runId: shortText132, - createdAt: shortText132, - finishedAt: shortText132.optional(), - host: shortText132, + runId: shortText142, + createdAt: shortText142, + finishedAt: shortText142.optional(), + host: shortText142, verdict: external_exports.enum(CERTIFICATION_VERDICTS), results: external_exports.array(certificationScenarioResultSchema).max(100).default([]), /** Totals, hoisted so the headline needs no arithmetic. */ @@ -109142,7 +110592,7 @@ var certificationRunSchema = external_exports.object({ /** Why the verdict is what it is, in one or two lines. */ rationale: text13, /** Scenarios that failed, with what happened, for the report. */ - failures: external_exports.array(external_exports.object({ scenarioId: shortText132, outcome: shortText132, observed: text13 }).passthrough()).max(100).default([]) + failures: external_exports.array(external_exports.object({ scenarioId: shortText142, outcome: shortText142, observed: text13 }).passthrough()).max(100).default([]) }).passthrough(); function listCertificationRuns(workspace) { return listJsonRecords( @@ -109152,8 +110602,6 @@ function listCertificationRuns(workspace) { } // ../../packages/intake/dist/index.js -var import_fs83 = require("fs"); -var import_path92 = __toESM(require("path"), 1); var import_fs84 = require("fs"); var import_path93 = __toESM(require("path"), 1); var import_fs85 = require("fs"); @@ -109164,6 +110612,8 @@ var import_fs87 = require("fs"); var import_path96 = __toESM(require("path"), 1); var import_fs88 = require("fs"); var import_path97 = __toESM(require("path"), 1); +var import_fs89 = require("fs"); +var import_path98 = __toESM(require("path"), 1); var INTAKE_STATUSES = [ /** The source specification is ingested; discovery has not run. */ "INGESTED", @@ -109438,31 +110888,31 @@ var IntakeError = class extends Error { this.retryable = options.retryable ?? false; } }; -function autonomyDepsOf(deps3) { - return deps3; +function autonomyDepsOf(deps4) { + return deps4; } -function missionDepsOf(deps3) { +function missionDepsOf(deps4) { return { - workspace: deps3.workspace, - clock: deps3.clock, - idFactory: deps3.idFactory, - host: deps3.host + workspace: deps4.workspace, + clock: deps4.clock, + idFactory: deps4.idFactory, + host: deps4.host }; } -function now6(deps3) { - return (deps3.clock ?? (() => /* @__PURE__ */ new Date()))(); +function now6(deps4) { + return (deps4.clock ?? (() => /* @__PURE__ */ new Date()))(); } -function nowIso6(deps3) { - return now6(deps3).toISOString(); +function nowIso6(deps4) { + return now6(deps4).toISOString(); } -function hostOf2(deps3) { - return deps3.host ?? "cli"; +function hostOf2(deps4) { + return deps4.host ?? "cli"; } -function newId6(deps3) { - return (deps3.idFactory ?? import_crypto30.randomUUID)(); +function newId6(deps4) { + return (deps4.idFactory ?? import_crypto30.randomUUID)(); } -function newRecordId2(deps3, prefix) { - const raw = newId6(deps3).replace(/[^A-Za-z0-9._-]/g, "").slice(0, 40); +function newRecordId2(deps4, prefix) { + const raw = newId6(deps4).replace(/[^A-Za-z0-9._-]/g, "").slice(0, 40); return `${prefix}-${raw.length > 0 ? raw : "x"}`; } var INTAKE_STATE_SCHEMA_VERSION = "1.0.0"; @@ -109888,41 +111338,41 @@ function assertIntakeId(id) { function intakeRootDir(workspace) { return assertInsideWorkspace( workspace.rootDir, - import_path90.default.join(workspace.rootDir, ".specbridge", INTAKE_DIR_NAME) + import_path91.default.join(workspace.rootDir, ".specbridge", INTAKE_DIR_NAME) ); } function intakeDir(workspace, intakeId) { assertIntakeId(intakeId); - return assertInsideWorkspace(workspace.rootDir, import_path90.default.join(intakeRootDir(workspace), intakeId)); + return assertInsideWorkspace(workspace.rootDir, import_path91.default.join(intakeRootDir(workspace), intakeId)); } function intakePath(workspace, intakeId, ...segments) { return assertInsideWorkspace( workspace.rootDir, - import_path90.default.join(intakeDir(workspace, intakeId), ...segments) + import_path91.default.join(intakeDir(workspace, intakeId), ...segments) ); } function writeJson(file, value) { - (0, import_fs81.mkdirSync)(import_path90.default.dirname(file), { recursive: true }); + (0, import_fs82.mkdirSync)(import_path91.default.dirname(file), { recursive: true }); writeFileAtomic(file, `${JSON.stringify(value, null, 2)} `); } function readJson2(file, parse3) { - if (!(0, import_fs81.existsSync)(file)) return void 0; + if (!(0, import_fs82.existsSync)(file)) return void 0; try { - return parse3(JSON.parse((0, import_fs81.readFileSync)(file, "utf8"))); + return parse3(JSON.parse((0, import_fs82.readFileSync)(file, "utf8"))); } catch { return void 0; } } function appendJsonl3(file, value) { - (0, import_fs81.mkdirSync)(import_path90.default.dirname(file), { recursive: true }); - (0, import_fs81.appendFileSync)(file, `${JSON.stringify(value)} + (0, import_fs82.mkdirSync)(import_path91.default.dirname(file), { recursive: true }); + (0, import_fs82.appendFileSync)(file, `${JSON.stringify(value)} `, "utf8"); } function readFolded(file, key, parse3) { - if (!(0, import_fs81.existsSync)(file)) return []; + if (!(0, import_fs82.existsSync)(file)) return []; const folded = /* @__PURE__ */ new Map(); - for (const line of (0, import_fs81.readFileSync)(file, "utf8").split("\n")) { + for (const line of (0, import_fs82.readFileSync)(file, "utf8").split("\n")) { if (line.trim().length === 0) continue; try { const value = parse3(JSON.parse(line)); @@ -109955,16 +111405,16 @@ function writeIntakeState(workspace, state) { } function listIntakes(workspace) { const root = intakeRootDir(workspace); - if (!(0, import_fs81.existsSync)(root)) return { intakes: [], diagnostics: [] }; + if (!(0, import_fs82.existsSync)(root)) return { intakes: [], diagnostics: [] }; const intakes = []; const diagnostics = []; - for (const entry2 of (0, import_fs81.readdirSync)(root, { withFileTypes: true })) { + for (const entry2 of (0, import_fs82.readdirSync)(root, { withFileTypes: true })) { if (!entry2.isDirectory()) continue; if (!ID_PATTERN11.test(entry2.name)) continue; - const file = import_path90.default.join(root, entry2.name, "intake.json"); - if (!(0, import_fs81.existsSync)(file)) continue; + const file = import_path91.default.join(root, entry2.name, "intake.json"); + if (!(0, import_fs82.existsSync)(file)) continue; try { - intakes.push(specIntakeStateSchema.parse(JSON.parse((0, import_fs81.readFileSync)(file, "utf8")))); + intakes.push(specIntakeStateSchema.parse(JSON.parse((0, import_fs82.readFileSync)(file, "utf8")))); } catch (cause) { diagnostics.push({ intakeId: entry2.name, @@ -109994,8 +111444,8 @@ function sourceFile(workspace, intakeId, contentHash) { } function storeSourceText(workspace, intakeId, contentHash, content) { const file = sourceFile(workspace, intakeId, contentHash); - if (!(0, import_fs81.existsSync)(file)) { - (0, import_fs81.mkdirSync)(import_path90.default.dirname(file), { recursive: true }); + if (!(0, import_fs82.existsSync)(file)) { + (0, import_fs82.mkdirSync)(import_path91.default.dirname(file), { recursive: true }); writeFileAtomic(file, content); } return file; @@ -110080,7 +111530,7 @@ function approvalFile2(workspace, intakeId) { function writeApproval(workspace, approval) { const validated = intakeApprovalSchema.parse(approval); const file = approvalFile2(workspace, validated.intakeId); - if ((0, import_fs81.existsSync)(file)) { + if ((0, import_fs82.existsSync)(file)) { throw new IntakeError( "SBI017", `Spec intake "${validated.intakeId}" is already approved; an approval is immutable.`, @@ -110139,7 +111589,7 @@ function appendIntakeEvent(workspace, intakeId, event) { function baselineFile(workspace) { return assertInsideWorkspace( workspace.rootDir, - import_path90.default.join(intakeRootDir(workspace), "baseline.json") + import_path91.default.join(intakeRootDir(workspace), "baseline.json") ); } function readProductBaseline(workspace) { @@ -110754,7 +112204,7 @@ var BUILD_MARKERS = [ ]; function detectBuildSystem(rootDir) { for (const marker of BUILD_MARKERS) { - if ((0, import_fs82.existsSync)(import_path91.default.join(rootDir, marker.file))) return marker.system; + if ((0, import_fs83.existsSync)(import_path92.default.join(rootDir, marker.file))) return marker.system; } return null; } @@ -110791,33 +112241,33 @@ var PUBLIC_INTERFACE_PATTERNS = [ var TEST_DIR_PATTERN = /^(tests?|spec|specs|__tests__|it|integration-tests?|e2e)$/i; function readGitHead(rootDir) { try { - const dotGit = import_path91.default.join(rootDir, ".git"); - if (!(0, import_fs82.existsSync)(dotGit)) return null; + const dotGit = import_path92.default.join(rootDir, ".git"); + if (!(0, import_fs83.existsSync)(dotGit)) return null; let gitDir = dotGit; - if ((0, import_fs82.statSync)(dotGit).isFile()) { - const pointer = (0, import_fs82.readFileSync)(dotGit, "utf8").trim(); + if ((0, import_fs83.statSync)(dotGit).isFile()) { + const pointer = (0, import_fs83.readFileSync)(dotGit, "utf8").trim(); const match = /^gitdir:\s*(.+)$/.exec(pointer); if (match === null) return null; const target = match[1] ?? ""; - gitDir = import_path91.default.isAbsolute(target) ? target : import_path91.default.resolve(rootDir, target); + gitDir = import_path92.default.isAbsolute(target) ? target : import_path92.default.resolve(rootDir, target); } - const headFile = import_path91.default.join(gitDir, "HEAD"); - if (!(0, import_fs82.existsSync)(headFile)) return null; - const head = (0, import_fs82.readFileSync)(headFile, "utf8").trim(); + const headFile = import_path92.default.join(gitDir, "HEAD"); + if (!(0, import_fs83.existsSync)(headFile)) return null; + const head = (0, import_fs83.readFileSync)(headFile, "utf8").trim(); if (/^[0-9a-f]{40}$/i.test(head)) return head.toLowerCase(); const refMatch = /^ref:\s*(.+)$/.exec(head); if (refMatch === null) return null; const ref = (refMatch[1] ?? "").trim(); for (const dir of refDirsFor(gitDir)) { - const refFile = import_path91.default.join(dir, ...ref.split("/")); - if (!(0, import_fs82.existsSync)(refFile)) continue; - const sha = (0, import_fs82.readFileSync)(refFile, "utf8").trim(); + const refFile = import_path92.default.join(dir, ...ref.split("/")); + if (!(0, import_fs83.existsSync)(refFile)) continue; + const sha = (0, import_fs83.readFileSync)(refFile, "utf8").trim(); if (/^[0-9a-f]{40}$/i.test(sha)) return sha.toLowerCase(); } for (const dir of refDirsFor(gitDir)) { - const packed = import_path91.default.join(dir, "packed-refs"); - if (!(0, import_fs82.existsSync)(packed)) continue; - for (const line of (0, import_fs82.readFileSync)(packed, "utf8").split("\n")) { + const packed = import_path92.default.join(dir, "packed-refs"); + if (!(0, import_fs83.existsSync)(packed)) continue; + for (const line of (0, import_fs83.readFileSync)(packed, "utf8").split("\n")) { const entry2 = /^([0-9a-f]{40})\s+(.+)$/.exec(line.trim()); if (entry2 !== null && entry2[2] === ref) return (entry2[1] ?? "").toLowerCase(); } @@ -110829,20 +112279,20 @@ function readGitHead(rootDir) { } function refDirsFor(gitDir) { const dirs = [gitDir]; - const commonFile = import_path91.default.join(gitDir, "commondir"); - if ((0, import_fs82.existsSync)(commonFile)) { + const commonFile = import_path92.default.join(gitDir, "commondir"); + if ((0, import_fs83.existsSync)(commonFile)) { try { - const target = (0, import_fs82.readFileSync)(commonFile, "utf8").trim(); + const target = (0, import_fs83.readFileSync)(commonFile, "utf8").trim(); if (target.length > 0) { - dirs.push(import_path91.default.isAbsolute(target) ? target : import_path91.default.resolve(gitDir, target)); + dirs.push(import_path92.default.isAbsolute(target) ? target : import_path92.default.resolve(gitDir, target)); } } catch { } } return dirs; } -function groundInRepository(deps3, request) { - const workspace = deps3.workspace; +function groundInRepository(deps4, request) { + const workspace = deps4.workspace; const exclude = new Set(request.excludeMissionIds ?? []); const evidence = []; const notes = []; @@ -110886,7 +112336,7 @@ function groundInRepository(deps3, request) { summary: `existing Kiro spec with ${folder.files.length} document(s)`, authoritative: false, topics: [], - path: import_path91.default.posix.join(".kiro", "specs", folder.name) + path: import_path92.default.posix.join(".kiro", "specs", folder.name) }); } for (const steering of safeSteering(workspace, notes)) { @@ -110897,7 +112347,7 @@ function groundInRepository(deps3, request) { summary: `steering document (${steering.inclusion})`, authoritative: false, topics: [], - path: import_path91.default.posix.join(".kiro", "steering", steering.fileName) + path: import_path92.default.posix.join(".kiro", "steering", steering.fileName) }); } const buildSystem = detectBuildSystem(workspace.rootDir); @@ -110941,7 +112391,7 @@ function groundInRepository(deps3, request) { }); } for (const container of modules.slice(0, 40)) { - const dir = import_path91.default.join(workspace.rootDir, container); + const dir = import_path92.default.join(workspace.rootDir, container); for (const entry2 of safeReaddir(dir, notes)) { if (!entry2.isDirectory()) continue; if (MODULE_DENYLIST.has(entry2.name) || entry2.name.startsWith(".")) continue; @@ -110991,7 +112441,7 @@ function groundInRepository(deps3, request) { return { schemaVersion: INTAKE_GROUNDING_SCHEMA_VERSION, intakeId: request.intakeId, - groundedAt: nowIso6(deps3), + groundedAt: nowIso6(deps4), baselineCommit: readGitHead(workspace.rootDir), existingProduct, evidence: evidence.slice(0, INTAKE_LIMITS.maxEvidence), @@ -111093,7 +112543,7 @@ function safeSteering(workspace, notes) { } function safeReaddir(dir, notes) { try { - return (0, import_fs82.readdirSync)(dir, { withFileTypes: true }); + return (0, import_fs83.readdirSync)(dir, { withFileTypes: true }); } catch (cause) { notes.push(`Directory ${dir} could not be listed: ${message(cause)}.`); return []; @@ -111133,14 +112583,14 @@ function analyzeDeltaAuthority(request) { if (items.length >= INTAKE_LIMITS.maxItems) break; const statement = statementOf(chunk); if (statement.length === 0) continue; - const tokens = tokenSet(statement); + const tokens2 = tokenSet(statement); const surfaces = surfacesFor(chunk, statement); const publicSurface = surfaces.length > 0; const item = classifyStatement({ itemId: `D-${String(++sequence).padStart(3, "0")}`, statement, chunkId: chunk.chunkId, - tokens, + tokens: tokens2, surfaces: surfaces.map((match) => match.surface), topics: topicsFor(chunk, statement), publicSurface, @@ -111195,10 +112645,10 @@ function analyzeDeltaAuthority(request) { ); } for (const cls of AUTHORITY_SENSITIVE_DELTA_CLASSES) { - const count3 = counts[cls] ?? 0; - if (count3 === 0) continue; + const count4 = counts[cls] ?? 0; + if (count4 === 0) continue; reasons.push( - `${count3} statement(s) classified ${cls} and need a product decision before this specification can be approved.` + `${count4} statement(s) classified ${cls} and need a product decision before this specification can be approved.` ); } const complete = items.length > 0 && authoritySensitive.length === 0; @@ -111905,14 +113355,14 @@ function emptyProjectionMap() { function mapFile(workspace, intakeId) { return assertInsideWorkspace( workspace.rootDir, - import_path92.default.join(workspace.rootDir, ".specbridge", "intake", intakeId, "mission-map.json") + import_path93.default.join(workspace.rootDir, ".specbridge", "intake", intakeId, "mission-map.json") ); } function readProjectionMap(workspace, intakeId) { const file = mapFile(workspace, intakeId); - if (!(0, import_fs83.existsSync)(file)) return emptyProjectionMap(); + if (!(0, import_fs84.existsSync)(file)) return emptyProjectionMap(); try { - const raw = JSON.parse((0, import_fs83.readFileSync)(file, "utf8")); + const raw = JSON.parse((0, import_fs84.readFileSync)(file, "utf8")); return { itemContracts: raw.itemContracts ?? {}, itemDecisions: raw.itemDecisions ?? {}, @@ -111927,7 +113377,7 @@ function readProjectionMap(workspace, intakeId) { } function writeProjectionMap(workspace, intakeId, map) { const file = mapFile(workspace, intakeId); - (0, import_fs83.mkdirSync)(import_path92.default.dirname(file), { recursive: true }); + (0, import_fs84.mkdirSync)(import_path93.default.dirname(file), { recursive: true }); writeFileAtomic(file, `${JSON.stringify(map, null, 2)} `); } @@ -112003,7 +113453,7 @@ var BEHAVIOUR_CONTRACT = { var BEHAVIOUR_SURFACE_KEY = "__behaviour__"; var TOPIC_DECISION_RESERVE = 12; var FACT_BUDGET = 120; -function compileMissionTruth(deps3, intakeDeps3, request) { +function compileMissionTruth(deps4, intakeDeps3, request) { const map = readProjectionMap(intakeDeps3.workspace, request.intakeId); const missionBefore = requireMissionState(intakeDeps3.workspace, request.missionId); const missionGoal = missionBefore.goal; @@ -112023,7 +113473,7 @@ function compileMissionTruth(deps3, intakeDeps3, request) { ); const overflowItemIds = []; if (map.sourceTurnId === void 0) { - const { turn } = recordTurn(deps3, request.missionId, { + const { turn } = recordTurn(deps4, request.missionId, { speaker: "user", kind: "statement", text: sourceTurnText(request.source) @@ -112094,7 +113544,7 @@ function compileMissionTruth(deps3, intakeDeps3, request) { resolvedTopics.push(topic); topicDecisionInputs.push(resolution); } - const decisionAssessment = recordAssessment(deps3, request.missionId, { + const decisionAssessment = recordAssessment(deps4, request.missionId, { ...facts.length > 0 ? { facts } : {}, ...decisions.length > 0 || topicDecisionInputs.length > 0 ? { decisions: [...decisions, ...topicDecisionInputs] } : {}, ...map.fieldsWritten !== true ? { missionUpdates: missionFieldsFrom(request) } : {} @@ -112160,7 +113610,7 @@ function compileMissionTruth(deps3, intakeDeps3, request) { let mission = decisionAssessment.mission; let contractIds = []; if (contracts.length > 0) { - const contractAssessment = recordAssessment(deps3, request.missionId, { contracts }); + const contractAssessment = recordAssessment(deps4, request.missionId, { contracts }); mission = contractAssessment.mission; contractIds = contractAssessment.contractIds; submitted.forEach((bucket, index) => { @@ -112334,9 +113784,9 @@ function reconcileCoverage(input) { out.push(existing); continue; } - const tokens = tokenSet(chunk.text); + const tokens2 = tokenSet(chunk.text); const match = authoritative.find( - (evidence) => containment(tokens, tokenSet(evidence.summary)) >= ALREADY_TRUE_CONTAINMENT + (evidence) => containment(tokens2, tokenSet(evidence.summary)) >= ALREADY_TRUE_CONTAINMENT ); if (match !== void 0) { out.push({ chunkId: chunk.chunkId, state: "ALREADY_TRUE", carriedBy: [match.evidenceId] }); @@ -112579,8 +114029,8 @@ function checkProjectionEquivalence(request) { let checked = 0; let traced = 0; for (const stage of stages) { - const file = import_path93.default.join(folder.dir, `${stage}.md`); - if (!(0, import_fs84.existsSync)(file)) { + const file = import_path94.default.join(folder.dir, `${stage}.md`); + if (!(0, import_fs85.existsSync)(file)) { divergences.push({ kind: "UNRELATED_ARTIFACT", stage, @@ -112588,17 +114038,17 @@ function checkProjectionEquivalence(request) { }); continue; } - const content = (0, import_fs84.readFileSync)(file, "utf8"); + const content = (0, import_fs85.readFileSync)(file, "utf8"); artifactHashes[stage] = sha256Hex(content); for (const statement of extractNormativeStatements(stage, content)) { checked += 1; - const tokens = tokenSet(statement.statement); - if (tokens.size === 0) { + const tokens2 = tokenSet(statement.statement); + if (tokens2.size === 0) { traced += 1; continue; } const match = approvedTokens.find( - (element) => containment(tokens, element.tokens) >= TRACE_CONTAINMENT || jaccard(tokens, element.tokens) >= TRACE_JACCARD + (element) => containment(tokens2, element.tokens) >= TRACE_CONTAINMENT || jaccard(tokens2, element.tokens) >= TRACE_JACCARD ); if (match === void 0) { divergences.push({ @@ -112714,8 +114164,8 @@ function recordDerivedApprovals(request) { } return { approved, results }; } -function emptyLedger(deps3, approval) { - const at = nowIso6(deps3); +function emptyLedger(deps4, approval) { + const at = nowIso6(deps4); return { schemaVersion: INTAKE_LIFECYCLE_SCHEMA_VERSION, intakeId: approval.intakeId, @@ -112743,11 +114193,11 @@ function withStep(ledger, step2, patch) { const steps = ledger.steps.some((record5) => record5.step === step2) ? ledger.steps.map((record5) => record5.step === step2 ? merged : record5) : [...ledger.steps, merged]; return { ...ledger, steps }; } -async function runSealAndBuild(deps3, options) { - const approval = requireApproval(deps3.workspace, options.intakeId); - let ledger = readLifecycle(deps3.workspace, options.intakeId) ?? emptyLedger(deps3, approval); +async function runSealAndBuild(deps4, options) { + const approval = requireApproval(deps4.workspace, options.intakeId); + let ledger = readLifecycle(deps4.workspace, options.intakeId) ?? emptyLedger(deps4, approval); const emit3 = (kind, message2) => options.onEvent?.({ kind, message: message2 }); - const autonomy = autonomyDepsOf(deps3); + const autonomy = autonomyDepsOf(deps4); let preflight; let unattended; const outcome = ledger.outcome; @@ -112759,18 +114209,18 @@ async function runSealAndBuild(deps3, options) { }; } if (outcome !== void 0) { - ledger = writeLifecycle(deps3.workspace, { + ledger = writeLifecycle(deps4.workspace, { ...ledger, outcome: void 0, finishedAt: void 0, humanPrerequisites: [], - updatedAt: nowIso6(deps3) + updatedAt: nowIso6(deps4) }); } const persist4 = (next) => { - const written = writeLifecycle(deps3.workspace, { + const written = writeLifecycle(deps4.workspace, { ...next, - updatedAt: nowIso6(deps3) + updatedAt: nowIso6(deps4) }); ledger = written; return written; @@ -112780,12 +114230,12 @@ async function runSealAndBuild(deps3, options) { persist4( withStep(ledger, step2, { status: "RUNNING", - startedAt: nowIso6(deps3), + startedAt: nowIso6(deps4), attempts: record5.attempts + 1 }) ); - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "build_step_started", step: step2 }); @@ -112795,13 +114245,13 @@ async function runSealAndBuild(deps3, options) { persist4( withStep(ledger, step2, { status, - settledAt: nowIso6(deps3), + settledAt: nowIso6(deps4), detail: detail.slice(0, INTAKE_LIMITS.maxTextChars), ...result !== void 0 ? { result } : {} }) ); - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "build_step_completed", step: step2, status, @@ -112813,12 +114263,12 @@ async function runSealAndBuild(deps3, options) { persist4( withStep(ledger, step2, { status: "FAILED", - settledAt: nowIso6(deps3), + settledAt: nowIso6(deps4), detail: detail.slice(0, INTAKE_LIMITS.maxTextChars) }) ); - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "build_step_failed", step: step2, detail: detail.slice(0, 600) @@ -112826,23 +114276,23 @@ async function runSealAndBuild(deps3, options) { emit3("lifecycle", `${step2} FAILED: ${detail}`); }; if (!isStepSettled(stepOf(ledger, "CONTRACT_READY").status)) { - const mission = requireMissionState(deps3.workspace, approval.missionId); + const mission = requireMissionState(deps4.workspace, approval.missionId); if (mission.status !== "IDEA" && mission.status !== "DISCOVERING" && mission.status !== "NEEDS_DECISION") { settle("CONTRACT_READY", "RECONCILED", `the mission is already ${mission.status}`); } else { begin("CONTRACT_READY"); try { - const { mission: ready } = markContractReady(missionDepsOf(deps3), approval.missionId); + const { mission: ready } = markContractReady(missionDepsOf(deps4), approval.missionId); settle("CONTRACT_READY", "COMPLETED", `the mission is ${ready.status}`); } catch (cause) { fail("CONTRACT_READY", messageOf(cause)); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } } } let specName = ledger.specName; if (!isStepSettled(stepOf(ledger, "SYNTHESIZE").status)) { - const mission = requireMissionState(deps3.workspace, approval.missionId); + const mission = requireMissionState(deps4.workspace, approval.missionId); if (mission.specName !== void 0) { specName = mission.specName; ledger = persist4({ ...ledger, specName }); @@ -112850,8 +114300,8 @@ async function runSealAndBuild(deps3, options) { } else { begin("SYNTHESIZE"); try { - const intake = requireIntakeState(deps3.workspace, options.intakeId); - const result = synthesizeMissionSpec(missionDepsOf(deps3), approval.missionId, { + const intake = requireIntakeState(deps4.workspace, options.intakeId); + const result = synthesizeMissionSpec(missionDepsOf(deps4), approval.missionId, { specName: intake.specName ?? void 0 }); specName = result.specName; @@ -112864,23 +114314,23 @@ async function runSealAndBuild(deps3, options) { ); } catch (cause) { fail("SYNTHESIZE", messageOf(cause)); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } } } - specName = specName ?? requireMissionState(deps3.workspace, approval.missionId).specName; + specName = specName ?? requireMissionState(deps4.workspace, approval.missionId).specName; if (specName === void 0) { fail("SYNTHESIZE", "no spec name is recorded after synthesis"); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } if (!isStepSettled(stepOf(ledger, "VALIDATE_PROJECTION").status)) { begin("VALIDATE_PROJECTION"); try { - const equivalence = validateProjection(deps3, approval, specName); - writeProjectionEquivalence(deps3.workspace, equivalence); + const equivalence = validateProjection(deps4, approval, specName); + writeProjectionEquivalence(deps4.workspace, equivalence); if (!equivalence.equivalent) { - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "projection_diverged", divergences: equivalence.divergences.length }); @@ -112888,10 +114338,10 @@ async function runSealAndBuild(deps3, options) { "VALIDATE_PROJECTION", `${equivalence.divergences.length} divergence(s): ` + equivalence.divergences.slice(0, 3).map((divergence) => `${divergence.kind} \u2014 ${divergence.detail}`).join(" | ") ); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "projection_validated", checked: equivalence.checkedStatements, traced: equivalence.tracedStatements @@ -112903,27 +114353,27 @@ async function runSealAndBuild(deps3, options) { ); } catch (cause) { fail("VALIDATE_PROJECTION", messageOf(cause)); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } } if (!isStepSettled(stepOf(ledger, "DERIVE_APPROVALS").status)) { - const state = readSpecState(deps3.workspace, specName).state; + const state = readSpecState(deps4.workspace, specName).state; if (state?.status === "READY_FOR_IMPLEMENTATION") { settle("DERIVE_APPROVALS", "RECONCILED", "every stage of the spec is already approved"); } else { begin("DERIVE_APPROVALS"); try { - const equivalence = validateProjection(deps3, approval, specName); + const equivalence = validateProjection(deps4, approval, specName); const derived = recordDerivedApprovals({ - workspace: deps3.workspace, + workspace: deps4.workspace, approval, specName, equivalence, - clock: deps3.clock ?? (() => /* @__PURE__ */ new Date()) + clock: deps4.clock ?? (() => /* @__PURE__ */ new Date()) }); for (const stage of derived.approved) { - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "derived_approval_recorded", stage, approvalId: approval.approvalId, @@ -112937,13 +114387,13 @@ async function runSealAndBuild(deps3, options) { ); } catch (cause) { fail("DERIVE_APPROVALS", messageOf(cause)); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } } } let sealId = ledger.sealId ?? approval.sealId; if (!isStepSettled(stepOf(ledger, "SEAL").status)) { - const existing = latestExecutableSeal(deps3.workspace, approval.missionId); + const existing = latestExecutableSeal(deps4.workspace, approval.missionId); if (approval.sealId !== void 0 && existing?.sealId === approval.sealId) { sealId = existing.sealId; ledger = persist4({ ...ledger, sealId }); @@ -112953,7 +114403,7 @@ async function runSealAndBuild(deps3, options) { try { const draft = draftSeal(autonomy, { missionId: approval.missionId, - sealId: newRecordId2(deps3, "seal"), + sealId: newRecordId2(deps4, "seal"), maxApiSpendUsd: approval.maxApiSpendUsd, allowedLanes: approval.allowedLanes }); @@ -112963,17 +114413,17 @@ async function runSealAndBuild(deps3, options) { "SEAL", `the seal is missing authority required for unattended execution: ${completeness.missing.join(", ")}` ); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } const seal = sealMission(autonomy, { sealId: draft.sealId, via: `intake-approval:${approval.approvalId}` }); sealId = seal.sealId; - bindApprovalSeal(deps3.workspace, options.intakeId, seal.sealId); + bindApprovalSeal(deps4.workspace, options.intakeId, seal.sealId); ledger = persist4({ ...ledger, sealId }); - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "seal_created", sealId: seal.sealId, approvalId: approval.approvalId, @@ -112988,17 +114438,17 @@ async function runSealAndBuild(deps3, options) { ); } catch (cause) { fail("SEAL", messageOf(cause)); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } } } if (!isStepSettled(stepOf(ledger, "PREFLIGHT").status)) { begin("PREFLIGHT"); try { - preflight = await runPreflight2(deps3, options, approval.missionId, sealId); + preflight = await runPreflight2(deps4, options, approval.missionId, sealId); ledger = persist4({ ...ledger, preflightReportId: preflight.reportId }); - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "preflight_completed", reportId: preflight.reportId, verdict: preflight.verdict @@ -113006,38 +114456,38 @@ async function runSealAndBuild(deps3, options) { settle("PREFLIGHT", "COMPLETED", preflight.verdict, preflight.reportId); } catch (cause) { fail("PREFLIGHT", messageOf(cause)); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } } if (!isStepSettled(stepOf(ledger, "RESOLVE_PREREQUISITES").status)) { begin("RESOLVE_PREREQUISITES"); try { if (preflight === void 0) { - preflight = await runPreflight2(deps3, options, approval.missionId, sealId); + preflight = await runPreflight2(deps4, options, approval.missionId, sealId); ledger = persist4( withStep({ ...ledger, preflightReportId: preflight.reportId }, "PREFLIGHT", { detail: preflight.verdict, result: preflight.reportId, - settledAt: nowIso6(deps3) + settledAt: nowIso6(deps4) }) ); - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "preflight_completed", reportId: preflight.reportId, verdict: preflight.verdict, rechecked: true }); } - const resolution = resolvePrerequisites(deps3, options.intakeId, preflight); + const resolution = resolvePrerequisites(deps4, options.intakeId, preflight); ledger = persist4({ ...ledger, resolvedPrerequisites: resolution.resolved.slice(0, INTAKE_LIMITS.maxItems), humanPrerequisites: resolution.human.slice(0, INTAKE_LIMITS.maxItems) }); for (const resolved2 of resolution.resolved) { - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "prerequisite_resolved", detail: resolved2.slice(0, 400) }); @@ -113047,7 +114497,7 @@ async function runSealAndBuild(deps3, options) { "RESOLVE_PREREQUISITES", `${resolution.human.length} prerequisite(s) only a person can satisfy: ` + resolution.human.slice(0, 4).join(" | ") ); - return finish4(deps3, options, ledger, "HUMAN_PREREQUISITE_REQUIRED", { preflight }); + return finish4(deps4, options, ledger, "HUMAN_PREREQUISITE_REQUIRED", { preflight }); } settle( "RESOLVE_PREREQUISITES", @@ -113056,23 +114506,23 @@ async function runSealAndBuild(deps3, options) { ); } catch (cause) { fail("RESOLVE_PREREQUISITES", messageOf(cause)); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } } let jobId = ledger.jobId; if (!isStepSettled(stepOf(ledger, "CREATE_JOB").status)) { - if (jobId !== void 0 && readJobState(deps3.workspace, jobId).kind === "ok") { + if (jobId !== void 0 && readJobState(deps4.workspace, jobId).kind === "ok") { settle("CREATE_JOB", "RECONCILED", `job ${jobId} already exists`, jobId); } else { begin("CREATE_JOB"); try { - const job = createJob(deps3, { specName, goal: approval.goal }); + const job = createJob(deps4, { specName, goal: approval.goal }); jobId = job.jobId; ledger = persist4({ ...ledger, jobId }); - const intake = requireIntakeState(deps3.workspace, options.intakeId); - writeIntakeState(deps3.workspace, { ...intake, jobId, specName, sealId, status: "BUILDING" }); - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + const intake = requireIntakeState(deps4.workspace, options.intakeId); + writeIntakeState(deps4.workspace, { ...intake, jobId, specName, sealId, status: "BUILDING" }); + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "job_created", jobId, specName @@ -113080,23 +114530,23 @@ async function runSealAndBuild(deps3, options) { settle("CREATE_JOB", "COMPLETED", `job created for spec "${specName}"`, jobId); } catch (cause) { fail("CREATE_JOB", messageOf(cause)); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } } } jobId = jobId ?? stepOf(ledger, "CREATE_JOB").result; if (jobId === void 0) { fail("CREATE_JOB", "no job id is recorded after job creation"); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } { - const retry = retryBlockedJob(deps3, jobId, { + const retry = retryBlockedJob(deps4, jobId, { reason: "the operator resumed the intake after fixing the cause" }); if (retry.cleared) { emit3("lifecycle", `job ${jobId} unblocked and returned to the schedulable path`); - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "build_step_started", step: "LAUNCH", unblocked: true @@ -113104,18 +114554,18 @@ async function runSealAndBuild(deps3, options) { } } { - const healed = selfHealOnResume(deps3, jobId); + const healed = selfHealOnResume(deps4, jobId); for (const repair of healed.repairs) { emit3("lifecycle", `self-heal: ${repair.code} \u2014 ${repair.detail.slice(0, 160)}`); } - resetSupervisedJobForExplicitResume(autonomyDepsOf(deps3), hostOf2(deps3), jobId); + resetSupervisedJobForExplicitResume(autonomyDepsOf(deps4), hostOf2(deps4), jobId); } { const ccrs = new Map( - readCcrs(deps3.workspace, approval.missionId).map((ccr) => [ccr.ccrId, ccr.status]) + readCcrs(deps4.workspace, approval.missionId).map((ccr) => [ccr.ccrId, ccr.status]) ); const reconciled = reconcileDecidedCcrs( - deps3, + deps4, jobId, (ccrId) => ccrs.has(ccrId) && ccrs.get(ccrId) !== "NEEDS_HUMAN" ); @@ -113128,38 +114578,38 @@ async function runSealAndBuild(deps3, options) { } if (options.launch === false) { settle("LAUNCH", "SKIPPED", "launch was not requested; the job is ready to run"); - return finish4(deps3, options, ledger, "LAUNCHED", { preflight }); + return finish4(deps4, options, ledger, "LAUNCHED", { preflight }); } begin("LAUNCH"); try { - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "unattended_launched", jobId, sealId: sealId ?? null }); - unattended = await launchUnattended(deps3, options, { + unattended = await launchUnattended(deps4, options, { missionId: approval.missionId, jobId, preflight }); settle("LAUNCH", "COMPLETED", `the unattended run stopped: ${unattended.stop.kind}`, jobId); const finalOutcome = unattended.stop.kind === "completed" ? "COMPLETED" : unattended.stop.kind === "needs-authority" ? "NEEDS_AUTHORITY" : "LAUNCHED"; - return finish4(deps3, options, ledger, finalOutcome, { preflight, unattended }); + return finish4(deps4, options, ledger, finalOutcome, { preflight, unattended }); } catch (cause) { fail("LAUNCH", messageOf(cause)); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } } -function validateProjection(deps3, approval, specName) { - const mission = requireMissionState(deps3.workspace, approval.missionId); - const contracts = readContractRegistry(deps3.workspace, approval.missionId); - const constitution = readConstitution(deps3.workspace, approval.missionId); - const adrs = readAdrs(deps3.workspace, approval.missionId); - const decisions = readDecisions(deps3.workspace, approval.missionId).filter( +function validateProjection(deps4, approval, specName) { + const mission = requireMissionState(deps4.workspace, approval.missionId); + const contracts = readContractRegistry(deps4.workspace, approval.missionId); + const constitution = readConstitution(deps4.workspace, approval.missionId); + const adrs = readAdrs(deps4.workspace, approval.missionId); + const decisions = readDecisions(deps4.workspace, approval.missionId).filter( (decision) => decision.status === "active" ); - const questions = readQuestions2(deps3.workspace, approval.intakeId); + const questions = readQuestions2(deps4.workspace, approval.intakeId); const currentDigest = computeIntakeAuthorityDigest( canonicalTruthOf({ mission, @@ -113171,10 +114621,10 @@ function validateProjection(deps3, approval, specName) { }) ); return checkProjectionEquivalence({ - workspace: deps3.workspace, + workspace: deps4.workspace, approval, specName, - checkedAt: nowIso6(deps3), + checkedAt: nowIso6(deps4), approvedElements: approvedElements( approval, contracts.map((contract) => ({ @@ -113189,9 +114639,9 @@ function validateProjection(deps3, approval, specName) { currentAuthorityDigest: currentDigest }); } -async function runPreflight2(deps3, options, missionId, sealId) { - const autonomy = autonomyDepsOf(deps3); - const seal = latestExecutableSeal(deps3.workspace, missionId); +async function runPreflight2(deps4, options, missionId, sealId) { + const autonomy = autonomyDepsOf(deps4); + const seal = latestExecutableSeal(deps4.workspace, missionId); const surfaces = requiredSurfacesFor(seal); return runOvernightPreflight(autonomy, { subject: missionId, @@ -113202,10 +114652,10 @@ async function runPreflight2(deps3, options, missionId, sealId) { ...options.probeRunner !== void 0 ? { probeRunner: options.probeRunner } : {} }); } -function resolvePrerequisites(deps3, intakeId, report) { +function resolvePrerequisites(deps4, intakeId, report) { const resolved2 = []; const human = []; - const autonomy = autonomyDepsOf(deps3); + const autonomy = autonomyDepsOf(deps4); for (const check6 of report.checks) { if (check6.outcome === "HUMAN_REQUIRED") { human.push( @@ -113230,7 +114680,7 @@ function resolvePrerequisites(deps3, intakeId, report) { capability, target: check6.capability, purpose: `Overnight preflight classified ${check6.capability} as satisfiable by the runtime; pre-authorizing it before the unattended launch.`, - requestId: newRecordId2(deps3, "ts") + requestId: newRecordId2(deps4, "ts") }); if (decision.request.status === "GRANTED") { resolved2.push(`${check6.capability}: pre-authorized as ${capability}`); @@ -113242,9 +114692,9 @@ function resolvePrerequisites(deps3, intakeId, report) { } return { resolved: resolved2, human }; } -async function launchUnattended(deps3, options, input) { +async function launchUnattended(deps4, options, input) { if (options.runUnattended !== void 0) { - return options.runUnattended(deps3, { missionId: input.missionId, jobId: input.jobId }); + return options.runUnattended(deps4, { missionId: input.missionId, jobId: input.jobId }); } if (options.host === void 0) { throw new IntakeError( @@ -113252,7 +114702,7 @@ async function launchUnattended(deps3, options, input) { "The unattended launch needs a driver host. Pass one, or run with --no-launch and launch with `specbridge overnight run`." ); } - return runUnattendedMission(autonomyDepsOf(deps3), { + return runUnattendedMission(autonomyDepsOf(deps4), { missionId: input.missionId, jobId: input.jobId, host: options.host, @@ -113260,25 +114710,25 @@ async function launchUnattended(deps3, options, input) { ...options.maxCycles !== void 0 ? { maxCycles: options.maxCycles } : {}, ...options.signal !== void 0 ? { signal: options.signal } : {}, ...options.onEvent !== void 0 ? { onEvent: options.onEvent } : {}, - ownerId: hostOf2(deps3) + ownerId: hostOf2(deps4) }); } -function finish4(deps3, options, ledger, outcome, extras) { - const finished7 = writeLifecycle(deps3.workspace, { +function finish4(deps4, options, ledger, outcome, extras) { + const finished7 = writeLifecycle(deps4.workspace, { ...ledger, outcome, - updatedAt: nowIso6(deps3), - finishedAt: nowIso6(deps3) + updatedAt: nowIso6(deps4), + finishedAt: nowIso6(deps4) }); - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "build_finished", outcome, ...finished7.jobId !== void 0 ? { jobId: finished7.jobId } : {} }); - const intake = requireIntakeState(deps3.workspace, options.intakeId); + const intake = requireIntakeState(deps4.workspace, options.intakeId); const status = outcome === "COMPLETED" ? "BUILT" : outcome === "LAUNCHED" ? "BUILDING" : outcome === "NEEDS_AUTHORITY" ? "BUILDING" : "BLOCKED"; - writeIntakeState(deps3.workspace, { + writeIntakeState(deps4.workspace, { ...intake, status, ...finished7.jobId !== void 0 ? { jobId: finished7.jobId } : {}, @@ -113296,7 +114746,7 @@ function finish4(deps3, options, ledger, outcome, extras) { function messageOf(cause) { return cause instanceof Error ? cause.message : String(cause); } -function startSpecIntake(deps3, request) { +function startSpecIntake(deps4, request) { const name = request.name.trim(); if (name.length === 0) { throw new IntakeError("SBI005", "A spec intake needs a name.", { @@ -113315,23 +114765,23 @@ function startSpecIntake(deps3, request) { { remediation: ["Split the specification, or submit the part this feature covers."] } ); } - const intakeId = request.intakeId ?? newRecordId2(deps3, "intake"); + const intakeId = request.intakeId ?? newRecordId2(deps4, "intake"); const contentHash = sha256Hex(content); - const storedPath = storeSourceText(deps3.workspace, intakeId, contentHash, content); + const storedPath = storeSourceText(deps4.workspace, intakeId, contentHash, content); const parsed = parseSpecificationDocument(content); - const at = nowIso6(deps3); + const at = nowIso6(deps4); const goal = request.goal?.trim() ?? deriveGoal(parsed.chunks, name); - const mission = beginMission(missionDepsOf(deps3), { name, goal }); - const source = writeSpecSource(deps3.workspace, { + const mission = beginMission(missionDepsOf(deps4), { name, goal }); + const source = writeSpecSource(deps4.workspace, { schemaVersion: INTAKE_SOURCE_SCHEMA_VERSION, intakeId, kind: request.kind, ...request.originPath !== void 0 ? { originPath: clip(request.originPath, 500) } : {}, receivedAt: at, - receivedVia: hostOf2(deps3), + receivedVia: hostOf2(deps4), byteLength, contentHash, - storedAt: import_path94.default.posix.join( + storedAt: import_path95.default.posix.join( ".specbridge", "intake", intakeId, @@ -113342,7 +114792,7 @@ function startSpecIntake(deps3, request) { chunks: parsed.chunks }); void storedPath; - const intake = writeIntakeState(deps3.workspace, { + const intake = writeIntakeState(deps4.workspace, { schemaVersion: INTAKE_STATE_SCHEMA_VERSION, intakeId, name, @@ -113350,9 +114800,9 @@ function startSpecIntake(deps3, request) { missionId: mission.missionId, createdAt: at, updatedAt: at, - host: hostOf2(deps3), + host: hostOf2(deps4), sourceContentHash: contentHash, - baselineCommit: readGitHead(deps3.workspace.rootDir), + baselineCommit: readGitHead(deps4.workspace.rootDir), counters: { sourceChunks: parsed.chunks.length, normativeChunks: parsed.normativeCount, @@ -113369,13 +114819,13 @@ function startSpecIntake(deps3, request) { sequences: { question: 0, refusal: 0, deltaItem: 0, evidence: 0 }, ...request.specName !== void 0 ? { specName: request.specName } : {} }); - appendIntakeEvent(deps3.workspace, intakeId, { + appendIntakeEvent(deps4.workspace, intakeId, { at, type: "intake_created", name, missionId: mission.missionId }); - appendIntakeEvent(deps3.workspace, intakeId, { + appendIntakeEvent(deps4.workspace, intakeId, { at, type: "source_ingested", kind: request.kind, @@ -113386,53 +114836,53 @@ function startSpecIntake(deps3, request) { }); return { intake, source, mission }; } -function startSpecIntakeFromFile(deps3, request) { - const resolved2 = import_path94.default.resolve(request.file); - if (!(0, import_fs85.existsSync)(resolved2)) { +function startSpecIntakeFromFile(deps4, request) { + const resolved2 = import_path95.default.resolve(request.file); + if (!(0, import_fs86.existsSync)(resolved2)) { throw new IntakeError("SBI007", `No specification file at ${request.file}.`, { remediation: ["Check the path, or pass the specification text with --text."] }); } - const size = (0, import_fs85.statSync)(resolved2).size; + const size = (0, import_fs86.statSync)(resolved2).size; if (size > INTAKE_LIMITS.maxSourceBytes) { throw new IntakeError( "SBI006", `${request.file} is ${size} bytes, over the ${INTAKE_LIMITS.maxSourceBytes}-byte bound.` ); } - const content = (0, import_fs85.readFileSync)(resolved2, "utf8"); - return startSpecIntake(deps3, { + const content = (0, import_fs86.readFileSync)(resolved2, "utf8"); + return startSpecIntake(deps4, { ...request, kind: "file", content, originPath: resolved2 }); } -function runIntakeDiscovery(deps3, intakeId, options = {}) { - let intake = requireIntakeState(deps3.workspace, intakeId); +function runIntakeDiscovery(deps4, intakeId, options = {}) { + let intake = requireIntakeState(deps4.workspace, intakeId); if (intake.status === "ABANDONED") { throw new IntakeError("SBI004", `Spec intake ${intakeId} is ABANDONED and read-only.`); } - const source = requireSpecSource(deps3.workspace, intakeId); - const at = nowIso6(deps3); + const source = requireSpecSource(deps4.workspace, intakeId); + const at = nowIso6(deps4); const grounding = writeGrounding( - deps3.workspace, - groundInRepository(deps3, { + deps4.workspace, + groundInRepository(deps4, { intakeId, excludeMissionIds: [intake.missionId] }) ); - appendIntakeEvent(deps3.workspace, intakeId, { + appendIntakeEvent(deps4.workspace, intakeId, { at, type: "grounding_completed", evidence: grounding.evidence.length, priorMissions: grounding.priorMissionIds.length, existingProduct: grounding.existingProduct }); - const existingContracts = activeProductContracts(deps3.workspace, { + const existingContracts = activeProductContracts(deps4.workspace, { excludeMissionIds: [intake.missionId] }); - const constitutionRules = activeConstitutionRules(deps3.workspace, { + const constitutionRules = activeConstitutionRules(deps4.workspace, { excludeMissionIds: [intake.missionId] }); let analysis = analyzeDeltaAuthority({ @@ -113452,7 +114902,7 @@ function runIntakeDiscovery(deps3, intakeId, options = {}) { let questionSequence = intake.sequences.question; let refusalSequence = intake.sequences.refusal; const newQuestions = []; - const admitted = admitAndRecord(deps3, { + const admitted = admitAndRecord(deps4, { intakeId, missionId: intake.missionId, candidates, @@ -113465,7 +114915,7 @@ function runIntakeDiscovery(deps3, intakeId, options = {}) { questionSequence = admitted.nextQuestionSequence; refusalSequence = admitted.nextRefusalSequence; newQuestions.push(...admitted.opened); - let questions = readQuestions2(deps3.workspace, intakeId); + let questions = readQuestions2(deps4.workspace, intakeId); const openByItem = /* @__PURE__ */ new Map(); for (const question of questions) { if (question.status !== "open") continue; @@ -113494,7 +114944,7 @@ function runIntakeDiscovery(deps3, intakeId, options = {}) { const authoritySensitive = raisedItems.filter( (item) => requiresProductAuthority(item.classification) ); - analysis = writeDeltaAnalysis(deps3.workspace, { + analysis = writeDeltaAnalysis(deps4.workspace, { ...analysis, items: raisedItems, counts: countsOf(raisedItems), @@ -113505,7 +114955,7 @@ function runIntakeDiscovery(deps3, intakeId, options = {}) { "The submitted specification contains no statements the classifier recognised as material." ] : [] }); - appendIntakeEvent(deps3.workspace, intakeId, { + appendIntakeEvent(deps4.workspace, intakeId, { at, type: "delta_analysis_completed", items: analysis.items.length, @@ -113516,7 +114966,7 @@ function runIntakeDiscovery(deps3, intakeId, options = {}) { const blockedItemIds = analysis.items.filter( (item) => item.classification === "UNKNOWN_PRODUCT_AUTHORITY" || item.classification === "CONTRADICTION" || item.classification === "EXISTING_SEALED_CONTRACT_CHANGE" ).map((item) => item.itemId); - const compiled = compileMissionTruth(missionDepsOf(deps3), deps3, { + const compiled = compileMissionTruth(missionDepsOf(deps4), deps4, { intakeId, missionId: intake.missionId, source, @@ -113531,11 +114981,11 @@ function runIntakeDiscovery(deps3, intakeId, options = {}) { ...question.deltaItemId !== void 0 ? { deltaItemId: question.deltaItemId } : {} })) }); - let mission = requireMissionState(deps3.workspace, intake.missionId); - let missionCoverage = refreshCoverage(missionDepsOf(deps3), mission); + let mission = requireMissionState(deps4.workspace, intake.missionId); + let missionCoverage = refreshCoverage(missionDepsOf(deps4), mission); const unknownRequired = missionCoverage.topics.filter((topic) => topic.required && topic.status === "unknown").map((topic) => topic.topicId); if (unknownRequired.length > 0) { - const topicAdmission = admitAndRecord(deps3, { + const topicAdmission = admitAndRecord(deps4, { intakeId, missionId: intake.missionId, candidates: generateRequiredTopicCandidates(unknownRequired), @@ -113548,9 +114998,9 @@ function runIntakeDiscovery(deps3, intakeId, options = {}) { questionSequence = topicAdmission.nextQuestionSequence; refusalSequence = topicAdmission.nextRefusalSequence; newQuestions.push(...topicAdmission.opened); - questions = readQuestions2(deps3.workspace, intakeId); - mission = requireMissionState(deps3.workspace, intake.missionId); - missionCoverage = refreshCoverage(missionDepsOf(deps3), mission); + questions = readQuestions2(deps4.workspace, intakeId); + mission = requireMissionState(deps4.workspace, intake.missionId); + missionCoverage = refreshCoverage(missionDepsOf(deps4), mission); } const coverage = reconcileCoverage({ chunks: source.chunks, @@ -113559,7 +115009,7 @@ function runIntakeDiscovery(deps3, intakeId, options = {}) { evidence: grounding.evidence, overflowItemIds: compiled.overflowItemIds }); - appendIntakeEvent(deps3.workspace, intakeId, { + appendIntakeEvent(deps4.workspace, intakeId, { at, type: "coverage_reconciled", unaccounted: coverage.filter((entry2) => entry2.state === "UNACCOUNTED").length, @@ -113571,29 +115021,29 @@ function runIntakeDiscovery(deps3, intakeId, options = {}) { questions, missionCoverage, overflowed: compiled.overflowItemIds.length > 0, - productContractCount: readContractRegistry(deps3.workspace, intake.missionId).filter( + productContractCount: readContractRegistry(deps4.workspace, intake.missionId).filter( (contract) => contract.status !== "superseded" ).length }); const openCount = questions.filter((question) => question.status === "open").length; const status = readiness.ready ? "READY_FOR_APPROVAL" : openCount > 0 ? "AWAITING_PRODUCT_ANSWERS" : "DISCOVERING"; if (status !== intake.status && intake.status !== "APPROVED" && intake.status !== "BUILDING") { - appendIntakeEvent(deps3.workspace, intakeId, { + appendIntakeEvent(deps4.workspace, intakeId, { at, type: "status_changed", from: intake.status, to: status }); if (status === "READY_FOR_APPROVAL") { - appendIntakeEvent(deps3.workspace, intakeId, { + appendIntakeEvent(deps4.workspace, intakeId, { at, type: "ready_for_approval", - contracts: readContractRegistry(deps3.workspace, intake.missionId).length, + contracts: readContractRegistry(deps4.workspace, intake.missionId).length, criteria: mission.successCriteria.length }); } } - intake = writeIntakeState(deps3.workspace, { + intake = writeIntakeState(deps4.workspace, { ...intake, status: intake.status === "APPROVED" || intake.status === "BUILDING" || intake.status === "BUILT" ? intake.status : status, counters: { @@ -113602,7 +115052,7 @@ function runIntakeDiscovery(deps3, intakeId, options = {}) { deltaItems: analysis.items.length, questionsAsked: questions.length, questionsAnswered: questions.filter((question) => question.status === "answered").length, - questionsRefused: readRefusals(deps3.workspace, intakeId).length, + questionsRefused: readRefusals(deps4.workspace, intakeId).length, groundingPasses: intake.counters.groundingPasses + 1 }, sequences: { @@ -113619,14 +115069,14 @@ function runIntakeDiscovery(deps3, intakeId, options = {}) { analysis, questions, newQuestions, - refusals: readRefusals(deps3.workspace, intakeId), + refusals: readRefusals(deps4.workspace, intakeId), coverage, readiness, missionCoverage }; } -function answerIntakeQuestion(deps3, intakeId, request, options = {}) { - const intake = requireIntakeState(deps3.workspace, intakeId); +function answerIntakeQuestion(deps4, intakeId, request, options = {}) { + const intake = requireIntakeState(deps4.workspace, intakeId); if (intake.status === "APPROVED" || intake.status === "BUILDING" || intake.status === "BUILT") { throw new IntakeError( "SBI003", @@ -113638,7 +115088,7 @@ function answerIntakeQuestion(deps3, intakeId, request, options = {}) { } ); } - const questions = readQuestions2(deps3.workspace, intakeId); + const questions = readQuestions2(deps4.workspace, intakeId); const question = questions.find((candidate) => candidate.questionId === request.questionId); if (question === void 0) { throw new IntakeError("SBI005", `No product question "${request.questionId}" on this intake.`, { @@ -113658,8 +115108,8 @@ function answerIntakeQuestion(deps3, intakeId, request, options = {}) { `Question ${request.questionId} was never mirrored into the mission and cannot record a governed answer.` ); } - const at = nowIso6(deps3); - const result = answerQuestion(missionDepsOf(deps3), intake.missionId, { + const at = nowIso6(deps4); + const result = answerQuestion(missionDepsOf(deps4), intake.missionId, { questionId: question.missionQuestionId, answer }); @@ -113670,14 +115120,14 @@ function answerIntakeQuestion(deps3, intakeId, request, options = {}) { answeredAt: at, decisionId: result.decision.decisionId }; - appendQuestion2(deps3.workspace, intakeId, answered); - appendIntakeEvent(deps3.workspace, intakeId, { + appendQuestion2(deps4.workspace, intakeId, answered); + appendIntakeEvent(deps4.workspace, intakeId, { at, type: "question_answered", questionId: answered.questionId, decisionId: result.decision.decisionId }); - writeIntakeState(deps3.workspace, { + writeIntakeState(deps4.workspace, { ...intake, counters: { ...intake.counters, @@ -113685,23 +115135,23 @@ function answerIntakeQuestion(deps3, intakeId, request, options = {}) { questionsAnswered: intake.counters.questionsAnswered + 1 } }); - const discovery = runIntakeDiscovery(deps3, intakeId, options); + const discovery = runIntakeDiscovery(deps4, intakeId, options); return { question: answered, intake: discovery.intake, discovery }; } -function approveIntake(deps3, request) { - const intake = requireIntakeState(deps3.workspace, request.intakeId); +function approveIntake(deps4, request) { + const intake = requireIntakeState(deps4.workspace, request.intakeId); if (intake.status === "ABANDONED") { throw new IntakeError("SBI004", `Spec intake ${request.intakeId} is ABANDONED.`); } - const existing = readApproval(deps3.workspace, request.intakeId); + const existing = readApproval(deps4.workspace, request.intakeId); if (existing !== void 0) { return { approval: existing, intake, - summary: summaryOf(deps3, intake) + summary: summaryOf(deps4, intake) }; } - const discovery = runIntakeDiscovery(deps3, request.intakeId); + const discovery = runIntakeDiscovery(deps4, request.intakeId); if (!discovery.readiness.ready) { throw new IntakeError( "SBI010", @@ -113722,23 +115172,23 @@ function approveIntake(deps3, request) { } ); } - const mission = requireMissionState(deps3.workspace, intake.missionId); - const contracts = readContractRegistry(deps3.workspace, intake.missionId); - const constitution = readConstitution(deps3.workspace, intake.missionId); - const adrs = readAdrs(deps3.workspace, intake.missionId); - const decisions = readDecisions(deps3.workspace, intake.missionId).filter( + const mission = requireMissionState(deps4.workspace, intake.missionId); + const contracts = readContractRegistry(deps4.workspace, intake.missionId); + const constitution = readConstitution(deps4.workspace, intake.missionId); + const adrs = readAdrs(deps4.workspace, intake.missionId); + const decisions = readDecisions(deps4.workspace, intake.missionId).filter( (decision) => decision.status === "active" ); - const source = requireSpecSource(deps3.workspace, request.intakeId); - const at = nowIso6(deps3); + const source = requireSpecSource(deps4.workspace, request.intakeId); + const at = nowIso6(deps4); const approval = writeApproval( - deps3.workspace, + deps4.workspace, buildIntakeApproval({ - approvalId: request.approvalId ?? newRecordId2(deps3, "approval"), + approvalId: request.approvalId ?? newRecordId2(deps4, "approval"), intakeId: request.intakeId, missionId: intake.missionId, approvedAt: at, - approvedVia: request.via ?? hostOf2(deps3), + approvedVia: request.via ?? hostOf2(deps4), source, mission, contracts, @@ -113751,7 +115201,7 @@ function approveIntake(deps3, request) { allowedLanes: request.allowedLanes ?? ["LOCAL", "SUBSCRIPTION"] }) ); - appendIntakeEvent(deps3.workspace, request.intakeId, { + appendIntakeEvent(deps4.workspace, request.intakeId, { at, type: "intake_approved", approvalId: approval.approvalId, @@ -113761,13 +115211,13 @@ function approveIntake(deps3, request) { criteria: approval.acceptanceCriteria.length, answeredQuestions: approval.resolvedQuestions.length }); - appendIntakeEvent(deps3.workspace, request.intakeId, { + appendIntakeEvent(deps4.workspace, request.intakeId, { at, type: "status_changed", from: intake.status, to: "APPROVED" }); - const approved = writeIntakeState(deps3.workspace, { + const approved = writeIntakeState(deps4.workspace, { ...intake, status: "APPROVED", approvalId: approval.approvalId, @@ -113777,7 +115227,7 @@ function approveIntake(deps3, request) { authorityApprovalCount: intake.counters.authorityApprovalCount + 1 } }); - recordBaselineEntry(deps3, approved, approval, discovery.analysis); + recordBaselineEntry(deps4, approved, approval, discovery.analysis); return { approval, intake: approved, @@ -113789,25 +115239,25 @@ function approveIntake(deps3, request) { }) }; } -function describeIntake(deps3, intakeId) { - const intake = requireIntakeState(deps3.workspace, intakeId); - const contracts = readContractRegistry(deps3.workspace, intake.missionId); +function describeIntake(deps4, intakeId) { + const intake = requireIntakeState(deps4.workspace, intakeId); + const contracts = readContractRegistry(deps4.workspace, intake.missionId); return { intake, - source: readSpecSource(deps3.workspace, intakeId), - grounding: readGrounding(deps3.workspace, intakeId), - analysis: readDeltaAnalysis(deps3.workspace, intakeId), - questions: readQuestions2(deps3.workspace, intakeId), - refusals: readRefusals(deps3.workspace, intakeId), - approval: readApproval(deps3.workspace, intakeId), - lifecycle: readLifecycle(deps3.workspace, intakeId), - summary: summaryOf(deps3, intake), - missionCoverage: readCoverage(deps3.workspace, intake.missionId), + source: readSpecSource(deps4.workspace, intakeId), + grounding: readGrounding(deps4.workspace, intakeId), + analysis: readDeltaAnalysis(deps4.workspace, intakeId), + questions: readQuestions2(deps4.workspace, intakeId), + refusals: readRefusals(deps4.workspace, intakeId), + approval: readApproval(deps4.workspace, intakeId), + lifecycle: readLifecycle(deps4.workspace, intakeId), + summary: summaryOf(deps4, intake), + missionCoverage: readCoverage(deps4.workspace, intake.missionId), contracts }; } -function requireIntakeFor(deps3, subject) { - const found = findIntake(deps3.workspace, subject); +function requireIntakeFor(deps4, subject) { + const found = findIntake(deps4.workspace, subject); if (found === void 0) { throw new IntakeError("SBI001", `No spec intake matches "${subject}".`, { remediation: [ @@ -113818,39 +115268,39 @@ function requireIntakeFor(deps3, subject) { } return found; } -function abandonIntake(deps3, intakeId, reason3) { - const intake = requireIntakeState(deps3.workspace, intakeId); +function abandonIntake(deps4, intakeId, reason3) { + const intake = requireIntakeState(deps4.workspace, intakeId); if (intake.status === "ABANDONED") return intake; - const at = nowIso6(deps3); - appendIntakeEvent(deps3.workspace, intakeId, { + const at = nowIso6(deps4); + appendIntakeEvent(deps4.workspace, intakeId, { at, type: "intake_abandoned", reason: clip(reason3, 500) }); - return writeIntakeState(deps3.workspace, { + return writeIntakeState(deps4.workspace, { ...intake, status: "ABANDONED", abandonedAt: at, abandonReason: clip(reason3, INTAKE_LIMITS.maxTextChars) }); } -function summaryOf(deps3, intake) { - const analysis = readDeltaAnalysis(deps3.workspace, intake.intakeId); +function summaryOf(deps4, intake) { + const analysis = readDeltaAnalysis(deps4.workspace, intake.intakeId); if (analysis === void 0) return void 0; return buildApprovalSummary({ - mission: requireMissionState(deps3.workspace, intake.missionId), - contracts: readContractRegistry(deps3.workspace, intake.missionId), + mission: requireMissionState(deps4.workspace, intake.missionId), + contracts: readContractRegistry(deps4.workspace, intake.missionId), analysis, - questions: readQuestions2(deps3.workspace, intake.intakeId) + questions: readQuestions2(deps4.workspace, intake.intakeId) }); } -function admitAndRecord(deps3, input) { +function admitAndRecord(deps4, input) { const admission = admitQuestions({ candidates: input.candidates, context: { chunks: input.chunks, evidence: input.evidence, - existing: readQuestions2(deps3.workspace, input.intakeId) + existing: readQuestions2(deps4.workspace, input.intakeId) }, at: input.at, questionSequence: input.questionSequence, @@ -113858,7 +115308,7 @@ function admitAndRecord(deps3, input) { }); const opened = []; if (admission.questions.length > 0) { - const assessment = recordAssessment(missionDepsOf(deps3), input.missionId, { + const assessment = recordAssessment(missionDepsOf(deps4), input.missionId, { questions: admission.questions.map((question) => ({ question: question.question, whyItMatters: question.whyItMatters, @@ -113874,9 +115324,9 @@ function admitAndRecord(deps3, input) { ...question, ...missionQuestionId !== void 0 ? { missionQuestionId } : {} }; - appendQuestion2(deps3.workspace, input.intakeId, stored); + appendQuestion2(deps4.workspace, input.intakeId, stored); opened.push(stored); - appendIntakeEvent(deps3.workspace, input.intakeId, { + appendIntakeEvent(deps4.workspace, input.intakeId, { at: input.at, type: "question_opened", questionId: stored.questionId, @@ -113887,8 +115337,8 @@ function admitAndRecord(deps3, input) { }); } for (const refusal of admission.refusals) { - appendRefusal(deps3.workspace, input.intakeId, refusal); - appendIntakeEvent(deps3.workspace, input.intakeId, { + appendRefusal(deps4.workspace, input.intakeId, refusal); + appendIntakeEvent(deps4.workspace, input.intakeId, { at: input.at, type: "question_refused", refusalId: refusal.refusalId, @@ -113915,8 +115365,8 @@ function deriveGoal(chunks, name) { const derived = opening !== void 0 ? firstSentence(opening.text, 600) : ""; return derived.length >= 12 ? derived : `Deliver the ${name} feature as specified.`; } -function recordBaselineEntry(deps3, intake, approval, analysis) { - const baseline = readProductBaseline(deps3.workspace); +function recordBaselineEntry(deps4, intake, approval, analysis) { + const baseline = readProductBaseline(deps4.workspace); const predecessorSealIds = baseline.features.filter((feature) => feature.sealId !== void 0 && feature.intakeId !== intake.intakeId).map((feature) => feature.sealId); const entry2 = { intakeId: intake.intakeId, @@ -113931,19 +115381,19 @@ function recordBaselineEntry(deps3, intake, approval, analysis) { implementationCommits: [] }; const features = baseline.features.filter((feature) => feature.intakeId !== intake.intakeId); - writeProductBaseline(deps3.workspace, { + writeProductBaseline(deps4.workspace, { ...baseline, updatedAt: approval.approvedAt, features: [...features, entry2].slice(-INTAKE_LIMITS.maxItems) }); - appendIntakeEvent(deps3.workspace, intake.intakeId, { + appendIntakeEvent(deps4.workspace, intake.intakeId, { at: approval.approvedAt, type: "baseline_recorded", predecessors: predecessorSealIds.length }); } -function recordFeatureOutcome(deps3, intakeId, outcome) { - const baseline = readProductBaseline(deps3.workspace); +function recordFeatureOutcome(deps4, intakeId, outcome) { + const baseline = readProductBaseline(deps4.workspace); const index = baseline.features.findIndex((feature) => feature.intakeId === intakeId); if (index < 0) return; const existing = baseline.features[index]; @@ -113959,29 +115409,29 @@ function recordFeatureOutcome(deps3, intakeId, outcome) { }; const features = [...baseline.features]; features[index] = updated; - writeProductBaseline(deps3.workspace, { + writeProductBaseline(deps4.workspace, { ...baseline, - updatedAt: nowIso6(deps3), + updatedAt: nowIso6(deps4), features }); } -function listSpecIntakes(deps3) { - return listIntakes(deps3.workspace); +function listSpecIntakes(deps4) { + return listIntakes(deps4.workspace); } var INTAKE_TELEMETRY_SCHEMA_VERSION = "1.0.0"; -function computeIntakeTelemetry(deps3, intakeId) { - const intake = requireIntakeState(deps3.workspace, intakeId); - const approval = readApproval(deps3.workspace, intakeId); - const questions = readQuestions2(deps3.workspace, intakeId); - const refusals = readRefusals(deps3.workspace, intakeId); +function computeIntakeTelemetry(deps4, intakeId) { + const intake = requireIntakeState(deps4.workspace, intakeId); + const approval = readApproval(deps4.workspace, intakeId); + const questions = readQuestions2(deps4.workspace, intakeId); + const refusals = readRefusals(deps4.workspace, intakeId); let autonomy; if (intake.jobId !== void 0) { - autonomy = readAutonomyTelemetry(deps3.workspace, intake.jobId) ?? safeCompute(deps3, intake.jobId); + autonomy = readAutonomyTelemetry(deps4.workspace, intake.jobId) ?? safeCompute(deps4, intake.jobId); } return intakeTelemetrySchema.parse({ schemaVersion: INTAKE_TELEMETRY_SCHEMA_VERSION, intakeId, - recordedAt: nowIso6(deps3), + recordedAt: nowIso6(deps4), status: intake.status, discoveryHumanTurns: intake.counters.discoveryHumanTurns, productQuestionsAsked: questions.length, @@ -113994,9 +115444,9 @@ function computeIntakeTelemetry(deps3, intakeId) { ...intake.sealId !== void 0 ? { sealId: intake.sealId } : {} }); } -function safeCompute(deps3, jobId) { +function safeCompute(deps4, jobId) { try { - return computeAutonomyTelemetry(autonomyDepsOf(deps3), { jobId }); + return computeAutonomyTelemetry(autonomyDepsOf(deps4), { jobId }); } catch { return void 0; } @@ -114125,7 +115575,7 @@ var repositoryManifestSchema = external_exports.object({ function repositoryManifestFile(workspace) { return assertInsideWorkspace( workspace.rootDir, - import_path95.default.join(workspace.sidecarDir, "repositories.json") + import_path96.default.join(workspace.sidecarDir, "repositories.json") ); } var DETECTION_DENYLIST = /* @__PURE__ */ new Set([ @@ -114142,10 +115592,10 @@ var DETECTION_DENYLIST = /* @__PURE__ */ new Set([ ]); function readRepositoryManifest(workspace) { const file = repositoryManifestFile(workspace); - if (!(0, import_fs86.existsSync)(file)) return void 0; + if (!(0, import_fs87.existsSync)(file)) return void 0; let raw; try { - raw = JSON.parse((0, import_fs86.readFileSync)(file, "utf8")); + raw = JSON.parse((0, import_fs87.readFileSync)(file, "utf8")); } catch (cause) { throw new IntakeError("SBI018", `The repository manifest at ${file} is not valid JSON.`, { remediation: ["Fix or delete .specbridge/repositories.json; without it the workspace root is the repository."], @@ -114165,7 +115615,7 @@ function resolveRepositories(workspace) { } seen.add(entry2.id); const absDir = assertInsideWorkspace(workspace.rootDir, entry2.path); - if (!(0, import_fs86.existsSync)(absDir) || !(0, import_fs86.statSync)(absDir).isDirectory()) { + if (!(0, import_fs87.existsSync)(absDir) || !(0, import_fs87.statSync)(absDir).isDirectory()) { throw new IntakeError( "SBI018", `The repository manifest names "${entry2.id}" at ${entry2.path}, which is not a directory.`, @@ -114182,11 +115632,11 @@ function resolveRepositories(workspace) { } const children = []; try { - for (const entry2 of (0, import_fs86.readdirSync)(workspace.rootDir, { withFileTypes: true })) { + for (const entry2 of (0, import_fs87.readdirSync)(workspace.rootDir, { withFileTypes: true })) { if (!entry2.isDirectory()) continue; if (DETECTION_DENYLIST.has(entry2.name) || entry2.name.startsWith(".")) continue; - const absDir = import_path95.default.join(workspace.rootDir, entry2.name); - if (!(0, import_fs86.existsSync)(import_path95.default.join(absDir, ".git"))) continue; + const absDir = import_path96.default.join(workspace.rootDir, entry2.name); + if (!(0, import_fs87.existsSync)(import_path96.default.join(absDir, ".git"))) continue; if (children.length >= BOOTSTRAP_LIMITS.maxRepositories) { notes.push("More child repositories exist than the bootstrap bound; declare a manifest to choose."); break; @@ -114197,7 +115647,7 @@ function resolveRepositories(workspace) { notes.push(`The workspace root could not be listed: ${cause instanceof Error ? cause.message : String(cause)}.`); } if (children.length > 0) { - const rootIsRepo = (0, import_fs86.existsSync)(import_path95.default.join(workspace.rootDir, ".git")); + const rootIsRepo = (0, import_fs87.existsSync)(import_path96.default.join(workspace.rootDir, ".git")); const repositories = rootIsRepo ? [resolved(workspace, rootRepositoryId(workspace), workspace.rootDir, void 0), ...children] : children; return { repositories: repositories.slice(0, BOOTSTRAP_LIMITS.maxRepositories), @@ -114212,18 +115662,18 @@ function resolveRepositories(workspace) { }; } function rootRepositoryId(workspace) { - const base = import_path95.default.basename(workspace.rootDir).replace(/[^A-Za-z0-9._-]/g, "-").replace(/^[^A-Za-z0-9]+/, ""); + const base = import_path96.default.basename(workspace.rootDir).replace(/[^A-Za-z0-9._-]/g, "-").replace(/^[^A-Za-z0-9]+/, ""); return base.length > 0 ? base.slice(0, 64) : "workspace"; } function resolved(workspace, repositoryId, absDir, role) { - const relPath2 = import_path95.default.relative(workspace.rootDir, absDir).replace(/\\/g, "/"); + const relPath2 = import_path96.default.relative(workspace.rootDir, absDir).replace(/\\/g, "/"); return { repositoryId, relPath: relPath2, ...role !== void 0 ? { role } : {}, absDir, gitHead: readGitHead(absDir), - isGitRepository: (0, import_fs86.existsSync)(import_path95.default.join(absDir, ".git")) + isGitRepository: (0, import_fs87.existsSync)(import_path96.default.join(absDir, ".git")) }; } function repositoryOfPath(repositories, workspaceRelativePath) { @@ -114416,7 +115866,7 @@ function synthesizeSystemFindings(input) { }); } const manifestEntries = entries.filter( - (entry2) => MANIFEST_BASENAMES.has(import_path96.default.posix.basename(entry2.path).toLowerCase()) + (entry2) => MANIFEST_BASENAMES.has(import_path97.default.posix.basename(entry2.path).toLowerCase()) ); const architectureLabels = /* @__PURE__ */ new Map(); for (const entry2 of manifestEntries.slice(0, 40)) { @@ -114461,7 +115911,7 @@ function synthesizeSystemFindings(input) { architecture.push({ findingId: ids("arc"), class: "OBSERVED_IMPLEMENTATION", - statement: clip3(`${label} (declared by ${import_path96.default.posix.basename(entry2.path)}).`), + statement: clip3(`${label} (declared by ${import_path97.default.posix.basename(entry2.path)}).`), evidence: [fileRef(entry2)] }); } @@ -114606,7 +116056,7 @@ function synthesizeSystemFindings(input) { findingId: ids("con"), class: "OBSERVED_IMPLEMENTATION", statement: clip3( - `Repository "${repo.repositoryId}" builds with ${import_path96.default.posix.basename(marker.path)}.` + `Repository "${repo.repositoryId}" builds with ${import_path97.default.posix.basename(marker.path)}.` ), evidence: [fileRef(marker)] }); @@ -114678,9 +116128,9 @@ function clip3(value) { } function boundedRead(workspace, relPath2) { try { - const abs = import_path96.default.join(workspace.rootDir, relPath2); - if (!(0, import_fs87.existsSync)(abs)) return void 0; - const body = (0, import_fs87.readFileSync)(abs, "utf8"); + const abs = import_path97.default.join(workspace.rootDir, relPath2); + if (!(0, import_fs88.existsSync)(abs)) return void 0; + const body = (0, import_fs88.readFileSync)(abs, "utf8"); return body.length > MAX_MANIFEST_READ_BYTES ? body.slice(0, MAX_MANIFEST_READ_BYTES) : body; } catch { return void 0; @@ -114721,25 +116171,25 @@ function safeSeals(workspace) { } } function bootstrapDir(workspace) { - return assertInsideWorkspace(workspace.rootDir, import_path97.default.join(workspace.sidecarDir, "bootstrap")); + return assertInsideWorkspace(workspace.rootDir, import_path98.default.join(workspace.sidecarDir, "bootstrap")); } function snapshotFile(workspace) { return assertInsideWorkspace( workspace.rootDir, - import_path97.default.join(bootstrapDir(workspace), "current-system-snapshot.json") + import_path98.default.join(bootstrapDir(workspace), "current-system-snapshot.json") ); } function readCurrentSystemSnapshot(workspace) { const file = snapshotFile(workspace); - if (!(0, import_fs88.existsSync)(file)) return void 0; + if (!(0, import_fs89.existsSync)(file)) return void 0; try { - return currentSystemSnapshotSchema.parse(JSON.parse((0, import_fs88.readFileSync)(file, "utf8"))); + return currentSystemSnapshotSchema.parse(JSON.parse((0, import_fs89.readFileSync)(file, "utf8"))); } catch { return void 0; } } function persistSnapshot(workspace, snapshot2) { - (0, import_fs88.mkdirSync)(bootstrapDir(workspace), { recursive: true }); + (0, import_fs89.mkdirSync)(bootstrapDir(workspace), { recursive: true }); writeFileAtomic(snapshotFile(workspace), `${JSON.stringify(snapshot2, null, 2)} `); } @@ -114781,13 +116231,13 @@ function assessSnapshotFreshness2(workspace, snapshot2) { } return reasons.length === 0 ? { status: "FRESH", reasons: [] } : { status: "STALE", reasons }; } -function bootstrapWorkspace(deps3, options = {}) { - const workspace = deps3.workspace; +function bootstrapWorkspace(deps4, options = {}) { + const workspace = deps4.workspace; const resolution = resolveRepositories(workspace); const ensured = ensureRepositoryIndex({ workspace, - config: deps3.config, - now: nowIso6(deps3), + config: deps4.config, + now: nowIso6(deps4), // Bootstrap has no Git snapshot to name additions, so the refresh walks // for them: a snapshot that missed a brand-new capability file would // claim currency over a repository it has not actually seen. @@ -114837,12 +116287,12 @@ function bootstrapWorkspace(deps3, options = {}) { schemaVersion: BOOTSTRAP_SCHEMA_VERSION, snapshotId: `snap-${contentHash.slice(0, 12)}`, workspaceKey: workspaceKeyFor(workspace.rootDir), - createdAt: nowIso6(deps3), + createdAt: nowIso6(deps4), ...material, indexStats: { entries: ensured.state.entries.length, truncated: ensured.state.truncated, - skipped: Object.values(ensured.state.skippedCounts).reduce((sum, count3) => sum + count3, 0) + skipped: Object.values(ensured.state.skippedCounts).reduce((sum, count4) => sum + count4, 0) }, contentHash }); @@ -114855,32 +116305,32 @@ function bootstrapWorkspace(deps3, options = {}) { }; } function countIndexed(index, repositories, repo) { - let count3 = 0; + let count4 = 0; for (const entry2 of index.entries) { - if (repositoryOfPath(repositories, entry2.path)?.repositoryId === repo.repositoryId) count3 += 1; + if (repositoryOfPath(repositories, entry2.path)?.repositoryId === repo.repositoryId) count4 += 1; } - return count3; + return count4; } function readWorkspaceSnapshot(workspace) { const snapshot2 = readCurrentSystemSnapshot(workspace); return { snapshot: snapshot2, freshness: assessSnapshotFreshness2(workspace, snapshot2) }; } -function inspectWorkspace(deps3, options) { +function inspectWorkspace(deps4, options) { const question = options.question.trim(); if (question.length === 0 || question.length > 2e3) { throw new IntakeError("SBI018", "An inspection question must be 1\u20132000 characters."); } - const policy = deps3.config.orchestration.jobs.context.efficiency; + const policy = deps4.config.orchestration.jobs.context.efficiency; const maxSections = Math.min( Math.max(1, options.maxSections ?? 5), policy.maxSelectedItems ); - const workspace = deps3.workspace; + const workspace = deps4.workspace; const resolution = resolveRepositories(workspace); const ensured = ensureRepositoryIndex({ workspace, - config: deps3.config, - now: nowIso6(deps3) + config: deps4.config, + now: nowIso6(deps4) }); const query = buildRetrievalQuery({ taskId: "workspace-inspect", @@ -114912,7 +116362,7 @@ function inspectWorkspace(deps3, options) { } let body; try { - body = (0, import_fs88.readFileSync)( + body = (0, import_fs89.readFileSync)( assertInsideWorkspace(workspace.rootDir, entry2.path), "utf8" ); @@ -115221,20 +116671,20 @@ Examples: "Pass exactly one of --file, --text, or --stdin." ); } - const deps3 = intakeDeps(runtime); - const started = options.file !== void 0 ? startSpecIntakeFromFile(deps3, { + const deps4 = intakeDeps(runtime); + const started = options.file !== void 0 ? startSpecIntakeFromFile(deps4, { name, file: options.file, ...options.goal !== void 0 ? { goal: options.goal } : {}, ...options.specName !== void 0 ? { specName: options.specName } : {} - }) : startSpecIntake(deps3, { + }) : startSpecIntake(deps4, { name, kind: options.stdin === true ? "stdin" : "text", content: options.stdin === true ? readStdin() : options.text ?? "", ...options.goal !== void 0 ? { goal: options.goal } : {}, ...options.specName !== void 0 ? { specName: options.specName } : {} }); - const discovery = runIntakeDiscovery(deps3, started.intake.intakeId); + const discovery = runIntakeDiscovery(deps4, started.intake.intakeId); if (options.json === true) { jsonOut(runtime, "spec-intake-start/v1", { intake: intakeSummary(discovery.intake), @@ -115277,9 +116727,9 @@ Examples: } ); spec.command("discover ").description("Re-run repository-grounded discovery and show the open product questions").option("--json", "machine-readable output").action((name, options) => { - const deps3 = intakeDeps(runtime); - const intake = requireIntakeFor(deps3, name); - const discovery = runIntakeDiscovery(deps3, intake.intakeId); + const deps4 = intakeDeps(runtime); + const intake = requireIntakeFor(deps4, name); + const discovery = runIntakeDiscovery(deps4, intake.intakeId); if (options.json === true) { jsonOut(runtime, "spec-intake-discover/v1", { intake: intakeSummary(discovery.intake), @@ -115311,7 +116761,7 @@ Examples: renderDiscovery(runtime, discovery); runtime.out(""); if (discovery.readiness.ready) { - const overview = describeIntake(deps3, intake.intakeId); + const overview = describeIntake(deps4, intake.intakeId); if (overview.summary !== void 0) renderSummary(runtime, overview.summary); runtime.out(""); runtime.out(okLine("Specification ready.")); @@ -115323,9 +116773,9 @@ Examples: }); spec.command("answer ").description("Record your answer to one open product question").option("--json", "machine-readable output").action( (name, questionId, answerWords, options) => { - const deps3 = intakeDeps(runtime); - const intake = requireIntakeFor(deps3, name); - const result = answerIntakeQuestion(deps3, intake.intakeId, { + const deps4 = intakeDeps(runtime); + const intake = requireIntakeFor(deps4, name); + const result = answerIntakeQuestion(deps4, intake.intakeId, { questionId, answer: answerWords.join(" ") }); @@ -115347,7 +116797,7 @@ Examples: } if (result.discovery.readiness.ready) { runtime.out(""); - const overview = describeIntake(deps3, intake.intakeId); + const overview = describeIntake(deps4, intake.intakeId); if (overview.summary !== void 0) renderSummary(runtime, overview.summary); runtime.out(""); runtime.out(okLine("Specification ready.")); @@ -115359,9 +116809,9 @@ Examples: ); spec.command("intake [name]").description("Inspect spec intakes; with --resume, continue an interrupted build").option("--resume", "continue the seal-and-build lifecycle idempotently").option("--no-launch", "with --resume, stop after creating the job").option("--json", "machine-readable output").action( async (name, options) => { - const deps3 = intakeDeps(runtime); + const deps4 = intakeDeps(runtime); if (name === void 0) { - const listed = listSpecIntakes(deps3); + const listed = listSpecIntakes(deps4); if (options.json === true) { jsonOut(runtime, "spec-intake-list/v1", { intakes: listed.intakes.map(intakeSummary), @@ -115385,17 +116835,17 @@ Examples: for (const diagnostic of listed.diagnostics) runtime.out(warnLine(diagnostic.message)); return; } - const intake = requireIntakeFor(deps3, name); + const intake = requireIntakeFor(deps4, name); if (options.resume === true) { - await runBuild(runtime, deps3, intake.intakeId, { + await runBuild(runtime, deps4, intake.intakeId, { launch: options.launch !== false, json: options.json === true, subject: name }); return; } - const overview = describeIntake(deps3, intake.intakeId); - const telemetry = computeIntakeTelemetry(deps3, intake.intakeId); + const overview = describeIntake(deps4, intake.intakeId); + const telemetry = computeIntakeTelemetry(deps4, intake.intakeId); if (options.json === true) { jsonOut(runtime, "spec-intake-show/v1", { ...overviewJson(overview), @@ -115434,19 +116884,19 @@ Examples: } ); spec.command("abandon-intake ").description("Abandon a spec intake (final; the record stays readable)").requiredOption("--reason ").action((name, options) => { - const deps3 = intakeDeps(runtime); - const intake = requireIntakeFor(deps3, name); - const abandoned = abandonIntake(deps3, intake.intakeId, options.reason); + const deps4 = intakeDeps(runtime); + const intake = requireIntakeFor(deps4, name); + const abandoned = abandonIntake(deps4, intake.intakeId, options.reason); runtime.out(okLine(`Spec intake ${abandoned.intakeId} is ${abandoned.status}.`)); }); } async function runApproveAndBuild(runtime, name, options) { - const deps3 = intakeDeps(runtime); - const intake = requireIntakeFor(deps3, name); + const deps4 = intakeDeps(runtime); + const intake = requireIntakeFor(deps4, name); const lanes = (options.lanes ?? "LOCAL,SUBSCRIPTION").split(",").map((lane) => lane.trim().toUpperCase()).filter( (lane) => lane === "LOCAL" || lane === "SUBSCRIPTION" || lane === "API" ); - const approved = approveIntake(deps3, { + const approved = approveIntake(deps4, { intakeId: intake.intakeId, via: "cli", maxApiSpendUsd: options.maxSpend !== void 0 ? Number(options.maxSpend) : null, @@ -115462,16 +116912,16 @@ async function runApproveAndBuild(runtime, name, options) { runtime.out(dim2("Everything from here is unattended.")); runtime.out(""); } - await runBuild(runtime, deps3, intake.intakeId, { + await runBuild(runtime, deps4, intake.intakeId, { launch: options.launch, json: options.json === true, subject: name, ...options.maxCycles !== void 0 ? { maxCycles: Number(options.maxCycles) } : {} }); } -async function runBuild(runtime, deps3, intakeId, options) { +async function runBuild(runtime, deps4, intakeId, options) { const context = loadExecutionContext(runtime); - const result = await runSealAndBuild(deps3, { + const result = await runSealAndBuild(deps4, { intakeId, launch: options.launch, // A FACTORY, because the deps the driver runs under are not known until @@ -115487,13 +116937,13 @@ async function runBuild(runtime, deps3, intakeId, options) { if (!options.json) runtime.out(dim2(` ${event.kind}: ${event.message}`)); } }); - recordFeatureOutcome(deps3, intakeId, { + recordFeatureOutcome(deps4, intakeId, { ...result.lifecycle.sealId !== void 0 ? { sealId: result.lifecycle.sealId } : {}, ...result.lifecycle.specName !== void 0 ? { specName: result.lifecycle.specName } : {}, ...result.lifecycle.jobId !== void 0 ? { jobId: result.lifecycle.jobId } : {}, outcome: result.outcome }); - const telemetry = computeIntakeTelemetry(deps3, intakeId); + const telemetry = computeIntakeTelemetry(deps4, intakeId); if (options.json) { jsonOut(runtime, "spec-intake-build/v1", { intakeId, @@ -116147,7 +117597,7 @@ Examples: throw new SpecBridgeError("INVALID_ARGUMENT", "--dry-run plans a single task; combine it with --task or --next."); } const context = loadExecutionContext(runtime); - const deps3 = { + const deps4 = { workspace: context.workspace, config: context.config, registry: context.registry, @@ -116167,7 +117617,7 @@ Examples: ...options.verify === false ? { noVerify: true } : {} }; if (options.all === true) { - const summary = await runAllOpenTasks(deps3, shared); + const summary = await runAllOpenTasks(deps4, shared); runtime.exitCode = summary.exitCode; if (options.json === true) { runtime.outRaw( @@ -116197,7 +117647,7 @@ Examples: } return; } - const outcome = await runApprovedTask(deps3, { + const outcome = await runApprovedTask(deps4, { ...shared, ...options.task !== void 0 ? { taskId: options.task } : { next: true }, ...options.dryRun === true ? { dryRun: true } : {} @@ -118737,8 +120187,8 @@ function selectedFamilies(options) { function countsByStatus(findings2) { const counts = {}; for (const status of STATUS_ORDER) { - const count3 = findings2.filter((candidate) => candidate.status === status).length; - if (count3 > 0) counts[status] = count3; + const count4 = findings2.filter((candidate) => candidate.status === status).length; + if (count4 > 0) counts[status] = count4; } return counts; } @@ -118824,8 +120274,8 @@ Examples: } printFindings(runtime, findings2); runtime.out(sectionTitle("Summary")); - for (const [status, count3] of Object.entries(counts)) { - runtime.out(statusLine(status)(`${status}: ${count3}`)); + for (const [status, count4] of Object.entries(counts)) { + runtime.out(statusLine(status)(`${status}: ${count4}`)); } runtime.out(); if (healthy) { @@ -119550,12 +121000,12 @@ Examples: }); } -// ../../packages/mcp-server/dist/chunk-U6N2BU4S.js +// ../../packages/mcp-server/dist/chunk-XJ3HVTHJ.js var import_buffer7 = require("buffer"); -var import_fs89 = require("fs"); -var import_path98 = __toESM(require("path"), 1); -var import_crypto31 = require("crypto"); +var import_fs90 = require("fs"); var import_path99 = __toESM(require("path"), 1); +var import_crypto31 = require("crypto"); +var import_path100 = __toESM(require("path"), 1); // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v4/core/core.js var NEVER2 = Object.freeze({ @@ -120271,7 +121721,7 @@ var ulid = /^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$/; var xid = /^[0-9a-vA-V]{20}$/; var ksuid = /^[A-Za-z0-9]{27}$/; var nanoid = /^[a-zA-Z0-9_-]{21}$/; -var duration = /^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/; +var duration2 = /^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/; var guid = /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/; var uuid = (version2) => { if (!version2) @@ -120980,7 +122430,7 @@ var $ZodISOTime = /* @__PURE__ */ $constructor("$ZodISOTime", (inst, def) => { $ZodStringFormat.init(inst, def); }); var $ZodISODuration = /* @__PURE__ */ $constructor("$ZodISODuration", (inst, def) => { - def.pattern ?? (def.pattern = duration); + def.pattern ?? (def.pattern = duration2); $ZodStringFormat.init(inst, def); }); var $ZodIPv4 = /* @__PURE__ */ $constructor("$ZodIPv4", (inst, def) => { @@ -123559,7 +125009,7 @@ __export(iso_exports2, { ZodISOTime: () => ZodISOTime, date: () => date2, datetime: () => datetime2, - duration: () => duration2, + duration: () => duration3, time: () => time2 }); var ZodISODateTime = /* @__PURE__ */ $constructor("ZodISODateTime", (inst, def) => { @@ -123587,7 +125037,7 @@ var ZodISODuration = /* @__PURE__ */ $constructor("ZodISODuration", (inst, def) $ZodISODuration.init(inst, def); ZodStringFormat.init(inst, def); }); -function duration2(params) { +function duration3(params) { return _isoDuration(ZodISODuration, params); } @@ -123749,7 +125199,7 @@ var ZodString2 = /* @__PURE__ */ $constructor("ZodString", (inst, def) => { inst.datetime = (params) => inst.check(datetime2(params)); inst.date = (params) => inst.check(date2(params)); inst.time = (params) => inst.check(time2(params)); - inst.duration = (params) => inst.check(duration2(params)); + inst.duration = (params) => inst.check(duration3(params)); }); function string2(params) { return _string(ZodString2, params); @@ -129882,13 +131332,13 @@ var EMPTY_COMPLETION_RESULT = { } }; -// ../../packages/mcp-server/dist/chunk-U6N2BU4S.js -var import_fs90 = require("fs"); +// ../../packages/mcp-server/dist/chunk-XJ3HVTHJ.js var import_fs91 = require("fs"); -var import_path100 = __toESM(require("path"), 1); var import_fs92 = require("fs"); -var import_os3 = __toESM(require("os"), 1); var import_path101 = __toESM(require("path"), 1); +var import_fs93 = require("fs"); +var import_os3 = __toESM(require("os"), 1); +var import_path102 = __toESM(require("path"), 1); // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js var import_node_process11 = __toESM(require("process"), 1); @@ -129982,7 +131432,7 @@ var StdioServerTransport = class { } }; -// ../../packages/mcp-server/dist/chunk-U6N2BU4S.js +// ../../packages/mcp-server/dist/chunk-XJ3HVTHJ.js var MCP_SERVER_NAME = "specbridge"; var MCP_SERVER_VERSION = "1.1.0"; var MCP_SERVER_TITLE = "SpecBridge"; @@ -130347,10 +131797,10 @@ function validateProjectRoot(value, source, cwd) { remediation: ["Pass a plain filesystem path as --project-root."] }; } - const resolved2 = import_path98.default.resolve(cwd, value); + const resolved2 = import_path99.default.resolve(cwd, value); let canonical; try { - canonical = (0, import_fs89.realpathSync)(resolved2); + canonical = (0, import_fs90.realpathSync)(resolved2); } catch { return { ok: false, @@ -130363,7 +131813,7 @@ function validateProjectRoot(value, source, cwd) { } let stats; try { - stats = (0, import_fs89.statSync)(canonical); + stats = (0, import_fs90.statSync)(canonical); } catch { return { ok: false, @@ -130620,8 +132070,8 @@ var paginationShape = external_exports.object({ nextCursor: external_exports.string().optional() }); function repoRelative2(workspace, target) { - const relative = import_path99.default.isAbsolute(target) ? import_path99.default.relative(workspace.rootDir, target) : target; - const posix = relative.split(import_path99.default.sep).join("/"); + const relative = import_path100.default.isAbsolute(target) ? import_path100.default.relative(workspace.rootDir, target) : target; + const posix = relative.split(import_path100.default.sep).join("/"); return posix === "" ? "." : posix; } function toDiagnosticView(workspace, diagnostic) { @@ -131121,7 +132571,7 @@ function registerRunResources(server, context) { throw resourceNotFound(`Run "${runId}"`, "List runs with the run_list tool."); } const directory = runDir(workspace, record5.runId); - const artifactNames = (0, import_fs90.existsSync)(directory) ? (0, import_fs90.readdirSync)(directory).filter((name) => !REDACTED_ARTIFACTS.has(name)).sort((a2, b) => a2.localeCompare(b, "en")) : []; + const artifactNames = (0, import_fs91.existsSync)(directory) ? (0, import_fs91.readdirSync)(directory).filter((name) => !REDACTED_ARTIFACTS.has(name)).sort((a2, b) => a2.localeCompare(b, "en")) : []; return jsonContents(context, uri.href, buildRunDetail(workspace, record5, artifactNames)); } ); @@ -132731,8 +134181,8 @@ function registerTaskCompleteTool(server, context) { handler: async (args, extras) => context.withWriteLock(async () => { assertInputSize("summary", args.summary, LIMITS.maximumShortTextChars); const workspace = context.requireWorkspace(); - const deps3 = { ...interactiveDeps(context, workspace), signal: extras.signal }; - const outcome = await completeInteractiveTask(deps3, { + const deps4 = { ...interactiveDeps(context, workspace), signal: extras.signal }; + const outcome = await completeInteractiveTask(deps4, { runId: args.runId, summary: args.summary, ...args.runVerification !== void 0 ? { runVerification: args.runVerification } : {}, @@ -132937,7 +134387,7 @@ function registerRunReadTool(server, context) { }); } const directory = runDir(workspace, record5.runId); - const artifactNames = (0, import_fs91.existsSync)(directory) ? (0, import_fs91.readdirSync)(directory).filter((name) => !REDACTED_ARTIFACTS2.has(name)).sort((a2, b) => a2.localeCompare(b, "en")) : []; + const artifactNames = (0, import_fs92.existsSync)(directory) ? (0, import_fs92.readdirSync)(directory).filter((name) => !REDACTED_ARTIFACTS2.has(name)).sort((a2, b) => a2.localeCompare(b, "en")) : []; const detail = buildRunDetail(workspace, record5, artifactNames); const lines = [ `Run ${detail.summary.runId} \u2014 ${detail.summary.runType} for spec "${detail.summary.specName}"${detail.summary.taskId !== void 0 ? `, task ${detail.summary.taskId}` : ""}.`, @@ -133297,7 +134747,7 @@ function registerSpecRunVerificationTool(server, context) { durationMs: command.durationMs, timedOut: command.timedOut })); - const reportPath = result.artifactsDir !== void 0 ? import_path100.default.relative(workspace.rootDir, result.artifactsDir).split(import_path100.default.sep).join("/") : void 0; + const reportPath = result.artifactsDir !== void 0 ? import_path101.default.relative(workspace.rootDir, result.artifactsDir).split(import_path101.default.sep).join("/") : void 0; const commandLines = commands.map( (command) => `- ${command.name}: ${command.disposition}${command.disposition === "executed" ? command.passed ? " (passed)" : ` (FAILED, exit ${command.exitCode ?? "none"})` : ""}` ); @@ -133416,18 +134866,18 @@ var conformanceSummaryShape = external_exports.object({ note: external_exports.string() }); async function invocationFreeConformanceSummary(profile) { - const scratch = (0, import_fs92.mkdtempSync)(import_path101.default.join(import_os3.default.tmpdir(), "specbridge-mcp-conformance-")); + const scratch = (0, import_fs93.mkdtempSync)(import_path102.default.join(import_os3.default.tmpdir(), "specbridge-mcp-conformance-")); let result; try { result = await runRunnerConformance({ profile, workspaceRoot: scratch, - runDir: import_path101.default.join(scratch, ".specbridge-conformance-runs"), + runDir: import_path102.default.join(scratch, ".specbridge-conformance-runs"), invocationsAllowed: false, timeoutMs: RUNNER_PROBE_TIMEOUT_MS }); } finally { - (0, import_fs92.rmSync)(scratch, { recursive: true, force: true }); + (0, import_fs93.rmSync)(scratch, { recursive: true, force: true }); } return { passed: result.passed, @@ -134483,7 +135933,7 @@ function orchestrationDeps(context, workspace) { }; } var orchestrationIdArg = external_exports.string().min(1).max(64).describe("Orchestration run id returned by orchestration_begin"); -var boundedText6 = (max) => external_exports.string().min(1).max(max); +var boundedText7 = (max) => external_exports.string().min(1).max(max); var stateSummaryShape = { orchestrationId: external_exports.string(), specName: external_exports.string(), @@ -134569,7 +136019,7 @@ function registerOrchestrationStatusTool(server, context) { }, handler: async (args) => { const workspace = context.requireWorkspace(); - const deps3 = orchestrationDeps(context, workspace); + const deps4 = orchestrationDeps(context, workspace); if (args.orchestrationId === void 0) { const listed = listOrchestrationRuns(workspace); const latest = listed.runs[0]; @@ -134604,7 +136054,7 @@ function registerOrchestrationStatusTool(server, context) { } }; } - const report = await resumeOrchestration(deps3, args.orchestrationId); + const report = await resumeOrchestration(deps4, args.orchestrationId); const detail = describeOrchestration(workspace, report.state, { eventLimit: args.eventLimit ?? 20 }); @@ -134654,7 +136104,7 @@ function registerOrchestrationBeginTool(server, context) { }, inputSchema: { specName: specNameArg, - goal: boundedText6(4e3).describe( + goal: boundedText7(4e3).describe( "The user's stated goal, verbatim. Recorded as data, never executed as instructions." ), taskId: external_exports.string().max(64).optional().describe("Target task, when the user named one") @@ -134667,8 +136117,8 @@ function registerOrchestrationBeginTool(server, context) { }, handler: async (args) => context.withWriteLock(async () => { const workspace = context.requireWorkspace(); - const deps3 = orchestrationDeps(context, workspace); - const state = beginOrchestration(deps3, { + const deps4 = orchestrationDeps(context, workspace); + const state = beginOrchestration(deps4, { specName: args.specName, goal: args.goal, ...args.taskId !== void 0 ? { taskId: args.taskId } : {} @@ -134717,11 +136167,11 @@ function registerOrchestrationAssessIntentTool(server, context) { inputSchema: { orchestrationId: orchestrationIdArg, outcome: external_exports.enum(INTENT_OUTCOMES).describe("Your assessment; SpecBridge may override it"), - summary: boundedText6(2e3).describe("One-line restatement of the user's request"), - reasons: external_exports.array(boundedText6(2e3)).max(20).optional(), + summary: boundedText7(2e3).describe("One-line restatement of the user's request"), + reasons: external_exports.array(boundedText7(2e3)).max(20).optional(), provenance: external_exports.array( external_exports.object({ - fact: boundedText6(2e3), + fact: boundedText7(2e3), source: external_exports.enum(PROVENANCE_KINDS), reference: external_exports.string().max(512).optional() }) @@ -134739,8 +136189,8 @@ function registerOrchestrationAssessIntentTool(server, context) { }, handler: async (args) => context.withWriteLock(async () => { const workspace = context.requireWorkspace(); - const deps3 = orchestrationDeps(context, workspace); - const result = assessIntent(deps3, args.orchestrationId, { + const deps4 = orchestrationDeps(context, workspace); + const result = assessIntent(deps4, args.orchestrationId, { outcome: args.outcome, summary: args.summary, ...args.reasons !== void 0 ? { reasons: args.reasons } : {}, @@ -134784,11 +136234,11 @@ function registerOrchestrationClarifyTool(server, context) { orchestrationId: orchestrationIdArg, questions: external_exports.array( external_exports.object({ - question: boundedText6(1024), - whyItMatters: boundedText6(1024).describe( + question: boundedText7(1024), + whyItMatters: boundedText7(1024).describe( "What the answer changes about the implementation. Required." ), - options: external_exports.array(boundedText6(512)).max(10).optional(), + options: external_exports.array(boundedText7(512)).max(10).optional(), relatedTaskId: external_exports.string().max(64).optional() }) ).min(1).max(20) @@ -134800,9 +136250,9 @@ function registerOrchestrationClarifyTool(server, context) { }, handler: async (args) => context.withWriteLock(async () => { const workspace = context.requireWorkspace(); - const deps3 = orchestrationDeps(context, workspace); + const deps4 = orchestrationDeps(context, workspace); const state = requestClarification( - deps3, + deps4, args.orchestrationId, args.questions.map((question) => ({ question: question.question, @@ -134845,9 +136295,9 @@ function registerOrchestrationResolveClarificationTool(server, context) { decisions: external_exports.array( external_exports.object({ questionId: external_exports.string().min(1).max(64), - answer: boundedText6(4096), + answer: boundedText7(4096), source: external_exports.enum(PROVENANCE_KINDS).describe("Use known-from-user for a direct answer from the user"), - impact: boundedText6(2e3).optional().describe("What this changes about the build"), + impact: boundedText7(2e3).optional().describe("What this changes about the build"), supersedes: external_exports.string().max(64).optional() }) ).min(1).max(20) @@ -134860,9 +136310,9 @@ function registerOrchestrationResolveClarificationTool(server, context) { }, handler: async (args) => context.withWriteLock(async () => { const workspace = context.requireWorkspace(); - const deps3 = orchestrationDeps(context, workspace); + const deps4 = orchestrationDeps(context, workspace); const result = resolveClarification( - deps3, + deps4, args.orchestrationId, args.decisions.map((decision) => ({ questionId: decision.questionId, @@ -134908,26 +136358,26 @@ function registerOrchestrationSubmitPlanTool(server, context) { inputSchema: { orchestrationId: orchestrationIdArg, taskId: external_exports.string().min(1).max(64).describe("The approved task this plan implements"), - goal: boundedText6(2e3), + goal: boundedText7(2e3), steps: external_exports.array( external_exports.object({ id: external_exports.string().max(64).optional(), - description: boundedText6(2e3), + description: boundedText7(2e3), expectedAreas: external_exports.array(external_exports.string().max(512)).max(20).optional(), - expectedEvidence: boundedText6(2e3).optional() + expectedEvidence: boundedText7(2e3).optional() }) ).min(1).max(200), - testStrategy: boundedText6(2e3), - verificationStrategy: boundedText6(2e3), - nonGoals: external_exports.array(boundedText6(2e3)).max(50).optional(), - constraints: external_exports.array(boundedText6(2e3)).max(50).optional(), - relevantEvidence: external_exports.array(boundedText6(2e3)).max(50).optional(), - assumptions: external_exports.array(boundedText6(2e3)).max(50).optional().describe("Labelled assumptions. Planning information, never presented as facts."), - openQuestions: external_exports.array(boundedText6(2e3)).max(50).optional(), + testStrategy: boundedText7(2e3), + verificationStrategy: boundedText7(2e3), + nonGoals: external_exports.array(boundedText7(2e3)).max(50).optional(), + constraints: external_exports.array(boundedText7(2e3)).max(50).optional(), + relevantEvidence: external_exports.array(boundedText7(2e3)).max(50).optional(), + assumptions: external_exports.array(boundedText7(2e3)).max(50).optional().describe("Labelled assumptions. Planning information, never presented as facts."), + openQuestions: external_exports.array(boundedText7(2e3)).max(50).optional(), expectedAreas: external_exports.array(external_exports.string().max(512)).max(50).optional().describe("Expected implementation areas. Planning information, not a prediction of fact."), - rollbackConsiderations: boundedText6(2e3).optional(), - replanTriggers: external_exports.array(boundedText6(2e3)).max(50).optional(), - replanReason: boundedText6(2e3).optional().describe("Required in spirit when replacing a plan") + rollbackConsiderations: boundedText7(2e3).optional(), + replanTriggers: external_exports.array(boundedText7(2e3)).max(50).optional(), + replanReason: boundedText7(2e3).optional().describe("Required in spirit when replacing a plan") }, outputSchema: { ...stateSummaryShape, @@ -134941,8 +136391,8 @@ function registerOrchestrationSubmitPlanTool(server, context) { }, handler: async (args) => context.withWriteLock(async () => { const workspace = context.requireWorkspace(); - const deps3 = orchestrationDeps(context, workspace); - const result = await submitPlan(deps3, args.orchestrationId, { + const deps4 = orchestrationDeps(context, workspace); + const result = await submitPlan(deps4, args.orchestrationId, { taskId: args.taskId, goal: args.goal, steps: args.steps.map((step2) => ({ @@ -135017,13 +136467,13 @@ function registerOrchestrationReviewPlanTool(server, context) { orchestrationId: orchestrationIdArg, planHash: external_exports.string().min(1).max(64).describe("Exact planHash from orchestration_submit_plan"), decision: external_exports.enum(["approved", "rejected"]).describe("The user's decision, not yours"), - note: boundedText6(2e3).optional() + note: boundedText7(2e3).optional() }, outputSchema: { ...stateSummaryShape, decision: external_exports.string(), planRevision: external_exports.number().int() }, handler: async (args) => context.withWriteLock(async () => { const workspace = context.requireWorkspace(); - const deps3 = orchestrationDeps(context, workspace); - const state = reviewPlan(deps3, args.orchestrationId, { + const deps4 = orchestrationDeps(context, workspace); + const state = reviewPlan(deps4, args.orchestrationId, { planHash: args.planHash, decision: args.decision, ...args.note !== void 0 ? { note: args.note } : {}, @@ -135054,15 +136504,15 @@ function registerOrchestrationRecordActionTool(server, context) { inputSchema: { orchestrationId: orchestrationIdArg, action: external_exports.enum(ACTION_CATEGORIES), - target: boundedText6(512).describe("What the action targeted: a path, a verifier, a step"), + target: boundedText7(512).describe("What the action targeted: a path, a verifier, a step"), result: external_exports.enum(OBSERVATION_RESULTS), planStepId: external_exports.string().max(64).optional(), - expectedEvidence: boundedText6(2e3).optional(), + expectedEvidence: boundedText7(2e3).optional(), changedFiles: external_exports.array(external_exports.object({ path: external_exports.string().max(1024), contentHash: external_exports.string().max(128).optional() })).max(500).optional().describe("Observed changes. Claims: the completion gate re-derives them from Git."), failure: external_exports.object({ category: external_exports.enum(FAILURE_CATEGORIES), - message: boundedText6(2e3), - source: boundedText6(512).describe("Verifier name, tool, or step that failed"), + message: boundedText7(2e3), + source: boundedText7(512).describe("Verifier name, tool, or step that failed"), exitCode: external_exports.number().int().optional(), output: external_exports.string().max(16384).optional().describe("Normalized before fingerprinting") }).optional(), @@ -135083,8 +136533,8 @@ function registerOrchestrationRecordActionTool(server, context) { }, handler: async (args) => context.withWriteLock(async () => { const workspace = context.requireWorkspace(); - const deps3 = orchestrationDeps(context, workspace); - const result = await recordActionChecked(deps3, args.orchestrationId, { + const deps4 = orchestrationDeps(context, workspace); + const result = await recordActionChecked(deps4, args.orchestrationId, { action: args.action, target: args.target, result: args.result, @@ -135132,9 +136582,9 @@ function registerOrchestrationCheckpointTool(server, context) { }, inputSchema: { orchestrationId: orchestrationIdArg, - nextAction: boundedText6(2e3).describe("The exact next safe action, in one line"), - observations: external_exports.array(boundedText6(2e3)).max(50).optional(), - latestVerifier: boundedText6(2e3).optional() + nextAction: boundedText7(2e3).describe("The exact next safe action, in one line"), + observations: external_exports.array(boundedText7(2e3)).max(50).optional(), + latestVerifier: boundedText7(2e3).optional() }, outputSchema: { orchestrationId: external_exports.string(), @@ -135147,8 +136597,8 @@ function registerOrchestrationCheckpointTool(server, context) { }, handler: async (args) => context.withWriteLock(async () => { const workspace = context.requireWorkspace(); - const deps3 = orchestrationDeps(context, workspace); - const checkpoint = createCheckpoint(deps3, args.orchestrationId, { + const deps4 = orchestrationDeps(context, workspace); + const checkpoint = createCheckpoint(deps4, args.orchestrationId, { nextAction: args.nextAction, ...args.observations !== void 0 ? { observations: args.observations } : {}, ...args.latestVerifier !== void 0 ? { latestVerifier: args.latestVerifier } : {} @@ -135182,15 +136632,15 @@ function registerOrchestrationFinalizeTool(server, context) { inputSchema: { orchestrationId: orchestrationIdArg, outcome: external_exports.enum(["completed", "aborted", "cancelled"]), - reason: boundedText6(2e3), + reason: boundedText7(2e3), evidenceStatus: external_exports.string().max(64).optional().describe("The evidenceStatus task_complete actually returned. Required for completion."), interactiveRunId: external_exports.string().max(64).optional() }, outputSchema: { ...stateSummaryShape, finalOutcome: external_exports.string(), finalizedAt: external_exports.string().optional() }, handler: async (args) => context.withWriteLock(async () => { const workspace = context.requireWorkspace(); - const deps3 = orchestrationDeps(context, workspace); - const state = finalizeOrchestration(deps3, args.orchestrationId, { + const deps4 = orchestrationDeps(context, workspace); + const state = finalizeOrchestration(deps4, args.orchestrationId, { outcome: args.outcome, reason: args.reason, ...args.evidenceStatus !== void 0 ? { evidenceStatus: args.evidenceStatus } : {}, @@ -135408,6 +136858,56 @@ function registerJobCancelTool(server, context) { } }); } +function percent2(value) { + return value === null ? "n/a" : `${(value * 100).toFixed(1)}%`; +} +function registerJobReportTool(server, context) { + registerDefinedTool(server, context, { + name: "job_report", + title: "Read a Job execution report", + description: "Derive versioned operational and token-conservation telemetry from durable Job, WorkUnit, attempt, research, cooldown, verification, and closure records. Read-only; metrics never grant completion or authority.", + annotations: { + readOnlyHint: true, + destructiveHint: false, + idempotentHint: true, + openWorldHint: false + }, + inputSchema: { + jobId: external_exports.string().min(1).max(64).describe("Job id (job-\u2026) from job_list") + }, + outputSchema: { + report: executionTelemetryReportSchema + }, + handler: async (args) => { + const workspace = context.requireWorkspace(); + const deps4 = { + workspace, + config: requireAgentConfig(workspace), + clock: context.clock, + idFactory: context.idFactory, + host: "mcp" + }; + const report = computeExecutionTelemetryReport(deps4, args.jobId, { + persist: false, + specbridgeVersion: MCP_SERVER_VERSION + }); + const summary = report.qualificationSummary; + return { + text: [ + `Job ${report.jobId}: ${report.outcome.status} (${report.outcome.authoritativeJobStatus})`, + `StrongBuilderAvoidanceRatio: ${percent2(summary.strongBuilderAvoidanceRatio)}`, + `Secondary initial/repair: ${percent2(summary.secondaryInitialSuccessRate)} / ${percent2(summary.secondaryRepairRecoveryRate)}`, + `ResearchAvoidanceRatio: ${percent2(summary.researchAvoidanceRatio)}`, + `UsefulWorkDuringSubscriptionCooldown: ${summary.usefulWorkDuringSubscriptionCooldown}`, + `humanInterventionsAfterSeal: ${summary.humanInterventionsAfterSeal}`, + `CompletedWorkRedoCount: ${summary.completedWorkRedoCount}`, + `Verification / closure: ${report.outcome.verification} / ${report.outcome.closure}` + ].join("\n"), + structured: { report } + }; + } + }); +} function missionDeps(context, workspace) { return { workspace, @@ -135499,14 +136999,14 @@ function registerMissionReadTool(server, context) { }, handler: async (args) => { const workspace = context.requireWorkspace(); - const deps3 = missionDeps(context, workspace); - observeSpecApproval(deps3, args.missionId); + const deps4 = missionDeps(context, workspace); + observeSpecApproval(deps4, args.missionId); const view = args.view ?? "overview"; const limit = args.limit ?? 50; let records = []; switch (view) { case "overview": { - const overview = describeMission(deps3, args.missionId); + const overview = describeMission(deps4, args.missionId); records = [ { goal: overview.mission.goal, @@ -135818,9 +137318,9 @@ function registerMissionSynthesizeTool(server, context) { }, handler: async (args) => { const workspace = context.requireWorkspace(); - const deps3 = missionDeps(context, workspace); - markContractReady(deps3, args.missionId); - const result = synthesizeMissionSpec(deps3, args.missionId, { specName: args.specName }); + const deps4 = missionDeps(context, workspace); + markContractReady(deps4, args.missionId); + const result = synthesizeMissionSpec(deps4, args.missionId, { specName: args.specName }); return { text: `Synthesized spec "${result.specName}" with ${result.objectiveCount} objective(s). The user approves it with: specbridge spec approve ${result.specName} --stage requirements|design|tasks.`, structured: { @@ -136029,14 +137529,14 @@ function registerSpecIntakeStartTool(server, context) { }, handler: async (args) => { const workspace = context.requireWorkspace(); - const deps3 = intakeDeps2(context, workspace); - const started = startSpecIntake(deps3, { + const deps4 = intakeDeps2(context, workspace); + const started = startSpecIntake(deps4, { name: args.name, kind: "text", content: args.specification, ...args.goal !== void 0 ? { goal: args.goal } : {} }); - const discovery = runIntakeDiscovery(deps3, started.intake.intakeId); + const discovery = runIntakeDiscovery(deps4, started.intake.intakeId); const open = discovery.questions.filter((question) => question.status === "open"); return { text: `Spec intake ${started.intake.intakeId} created for "${args.name}". ${started.source.chunks.length} section(s) ingested. ` + (discovery.readiness.ready ? `No product question is open; the specification is ready for the human approval (\`specbridge spec approve ${args.name} --build\`).` : `${open.length} product question(s) need the user's decision.`), @@ -136089,9 +137589,9 @@ function registerSpecIntakeReadTool(server, context) { }, handler: async (args) => { const workspace = context.requireWorkspace(); - const deps3 = intakeDeps2(context, workspace); + const deps4 = intakeDeps2(context, workspace); if (args.subject === void 0) { - const listed = listSpecIntakes(deps3); + const listed = listSpecIntakes(deps4); const all = { intakes: listed.intakes.map((intake) => summarize22(workspace, context, intake.intakeId)) }; @@ -136100,8 +137600,8 @@ function registerSpecIntakeReadTool(server, context) { structured: all }; } - const resolved2 = requireIntakeFor(deps3, args.subject); - const overview = describeIntake(deps3, resolved2.intakeId); + const resolved2 = requireIntakeFor(deps4, args.subject); + const overview = describeIntake(deps4, resolved2.intakeId); const structured = { intake: summarize22(workspace, context, resolved2.intakeId) }; @@ -136180,9 +137680,9 @@ function registerSpecIntakeAnswerTool(server, context) { }, handler: async (args) => { const workspace = context.requireWorkspace(); - const deps3 = intakeDeps2(context, workspace); - const resolved2 = requireIntakeFor(deps3, args.subject); - const result = answerIntakeQuestion(deps3, resolved2.intakeId, { + const deps4 = intakeDeps2(context, workspace); + const resolved2 = requireIntakeFor(deps4, args.subject); + const result = answerIntakeQuestion(deps4, resolved2.intakeId, { questionId: args.questionId, answer: args.answer }); @@ -136924,9 +138424,9 @@ function registerResearchProviderStatusTool(server, context) { health: researchProviderHealthSchema }, handler: async (_args, extras) => { - const deps3 = serviceDeps(context); - const health = await getResearchProviderHealth(deps3, extras.signal); - const policy = deps3.config.research; + const deps4 = serviceDeps(context); + const health = await getResearchProviderHealth(deps4, extras.signal); + const policy = deps4.config.research; const providerEnabled2 = policy.provider === "deerflow" && policy.providers.deerflow.enabled; return { text: `Research ${policy.enabled ? "enabled" : "disabled"}; ${health.provider} health: ${health.status}.`, @@ -136985,6 +138485,7 @@ var TOOL_CATALOG = [ { name: "orchestration_finalize", readOnly: false, summary: "Close a run (completion needs verified evidence)" }, { name: "job_list", readOnly: true, summary: "List long-running orchestration jobs" }, { name: "job_read", readOnly: true, summary: "One job in depth: graph, attempts, questions, checkpoint" }, + { name: "job_report", readOnly: true, summary: "Durable Job operational and token-conservation report" }, { name: "job_cancel", readOnly: false, summary: "Cancel a job (final, idempotent, evidence preserved)" }, { name: "mission_begin", readOnly: false, summary: "Begin Mission Discovery from a product direction" }, { name: "mission_status", readOnly: true, summary: "List missions with lifecycle status and readiness" }, @@ -137071,6 +138572,7 @@ function registerAllTools(server, context) { registerOrchestrationFinalizeTool(server, context); registerJobListTool(server, context); registerJobReadTool(server, context); + registerJobReportTool(server, context); registerJobCancelTool(server, context); registerMissionBeginTool(server, context); registerMissionStatusTool(server, context); @@ -137262,8 +138764,8 @@ async function runMcpServe(argv2, io = { } // ../../packages/mcp-server/dist/index.js -var import_fs93 = require("fs"); -var import_path102 = __toESM(require("path"), 1); +var import_fs94 = require("fs"); +var import_path103 = __toESM(require("path"), 1); async function runMcpDoctor(options = {}) { const checks = []; const env = options.env ?? process.env; @@ -137356,7 +138858,7 @@ async function runMcpDoctor(options = {}) { const pluginRoot = env["CLAUDE_PLUGIN_ROOT"]; if (pluginRoot !== void 0 && pluginRoot.length > 0) { const missing = ["dist/mcp-server.cjs", "dist/cli.cjs"].filter( - (relative) => !(0, import_fs93.existsSync)(import_path102.default.join(pluginRoot, relative)) + (relative) => !(0, import_fs94.existsSync)(import_path103.default.join(pluginRoot, relative)) ); checks.push( missing.length === 0 ? { name: "plugin-bundle", status: "ok", detail: `Bundled executables present under ${pluginRoot}` } : { @@ -138428,7 +139930,7 @@ function registerOrchestrateJobCommands(orchestrate, runtime) { orchestrate.command("run").description("Run the long-running job orchestrator for one approved spec (foreground, resumable)").argument("", "spec name under .kiro/specs/").option("--goal ", "stated goal recorded on the job (default: implement the approved plan)").option("--resume ", "resume an existing job instead of creating one").option("--dry-run", "validate and show what would run, without creating or advancing anything").option("--json", "output a machine-readable JSON report of the final state").action( async (specName, options) => { const context = loadExecutionContext(runtime); - const deps3 = { + const deps4 = { workspace: context.workspace, config: context.config, registry: context.registry, @@ -138497,7 +139999,7 @@ function registerOrchestrateJobCommands(orchestrate, runtime) { `Job ${active.jobId} is already active (${active.status}) for "${specName}". Resume it with --resume ${active.jobId}, or cancel it with \`${CLI_BIN} orchestrate cancel-job ${active.jobId}\`.` ); } - const job = createJob(deps3, { + const job = createJob(deps4, { specName, goal: options.goal ?? `Implement the approved task plan of "${specName}".` }); @@ -138511,7 +140013,7 @@ function registerOrchestrateJobCommands(orchestrate, runtime) { }; process.once("SIGINT", onSigint); try { - const result = await driveJob(deps3, jobId, { + const result = await driveJob(deps4, jobId, { signal: controller.signal, onEvent: (event) => { if (event.kind === "decision") runtime.out(dim2(` \u2192 ${event.message}`)); @@ -138704,8 +140206,8 @@ function registerOrchestrateJobCommands(orchestrate, runtime) { throw new SpecBridgeError("INVALID_ARGUMENT", "Pass exactly one of --approve or --reject."); } const context = loadExecutionContext(runtime); - const deps3 = { workspace: context.workspace, config: context.config, host: "cli" }; - reviewNodePlan(deps3, jobId, { + const deps4 = { workspace: context.workspace, config: context.config, host: "cli" }; + reviewNodePlan(deps4, jobId, { nodeId, decision: options.approve === true ? "approved" : "rejected", note: options.note @@ -138718,8 +140220,8 @@ function registerOrchestrateJobCommands(orchestrate, runtime) { }); orchestrate.command("answer").description("Answer an open clarification question (human decision)").argument("").argument("").argument("").action((jobId, questionId, answerWords) => { const context = loadExecutionContext(runtime); - const deps3 = { workspace: context.workspace, config: context.config, host: "cli" }; - const job = answerClarification(deps3, jobId, [ + const deps4 = { workspace: context.workspace, config: context.config, host: "cli" }; + const job = answerClarification(deps4, jobId, [ { questionId, answer: answerWords.join(" ") } ]); runtime.out(okLine(`Recorded the decision. ${job.openQuestions.length} question(s) remain open.`)); @@ -138729,8 +140231,8 @@ function registerOrchestrateJobCommands(orchestrate, runtime) { }); orchestrate.command("cancel-job").description("Cancel a job (final; never auto-restarted)").argument("").option("--reason ", "reason recorded on the cancellation", "cancelled from the CLI").action((jobId, options) => { const context = loadExecutionContext(runtime); - const deps3 = { workspace: context.workspace, config: context.config, host: "cli" }; - const job = cancelJob(deps3, jobId, options.reason); + const deps4 = { workspace: context.workspace, config: context.config, host: "cli" }; + const job = cancelJob(deps4, jobId, options.reason); runtime.out(okLine(`Job ${jobId} is ${job.status}.`)); }); orchestrate.command("objective").description("One objective in depth: work graph, unit statuses, workers, conflicts, evaluations").argument("").argument("").option("--json", "output a machine-readable JSON report").action((jobId, nodeId, options) => { @@ -138842,16 +140344,16 @@ function registerOrchestrateJobCommands(orchestrate, runtime) { return; } runtime.out(reportTitle("Subscription quota")); - const percent = (ratio3) => ratio3 === null ? "unknown" : `${(ratio3 * 100).toFixed(1)}%`; + const percent3 = (ratio4) => ratio4 === null ? "unknown" : `${(ratio4 * 100).toFixed(1)}%`; const untilText = (ms) => ms === null ? "unknown" : `${Math.round(ms / 6e4)}m`; runtime.out( infoLine( - ` five-hour: ${percent(forecast.fiveHourRemainingRatio)} remaining, reset in ${untilText(forecast.timeToFiveHourResetMs)}` + ` five-hour: ${percent3(forecast.fiveHourRemainingRatio)} remaining, reset in ${untilText(forecast.timeToFiveHourResetMs)}` ) ); runtime.out( infoLine( - ` weekly: ${percent(forecast.weeklyRemainingRatio)} remaining, reset in ${untilText(forecast.timeToWeeklyResetMs)}` + ` weekly: ${percent3(forecast.weeklyRemainingRatio)} remaining, reset in ${untilText(forecast.timeToWeeklyResetMs)}` ) ); runtime.out(infoLine(` scheduler mode: ${forecast.schedulerMode} (telemetry ${forecast.telemetryFreshness})`)); @@ -139117,7 +140619,7 @@ function registerOrchestrateJobCommands(orchestrate, runtime) { if (!policy.enabled) runtime.out(warnLine(" lane scheduling is disabled by configuration.")); runtime.out( infoLine( - ` attempt lanes: ${Object.entries(laneCounts).map(([laneName, count3]) => `${laneName}=${count3}`).join(", ") || "(none yet)"}` + ` attempt lanes: ${Object.entries(laneCounts).map(([laneName, count4]) => `${laneName}=${count4}`).join(", ") || "(none yet)"}` ) ); runtime.out(reportTitle("Local execution (vNext.4)")); @@ -139213,8 +140715,8 @@ function registerOrchestrateJobCommands(orchestrate, runtime) { ` mode ${adaptiveSummary.mode}; ${adaptiveSummary.profileCount} profile(s) from ${adaptiveSummary.observations} observation(s); ${adaptiveSummary.decisions} recent decision(s), ${adaptiveSummary.applied} applied, ${adaptiveSummary.disagreements} disagreement(s)` ) ); - for (const [reason3, count3] of Object.entries(adaptiveSummary.fallbackReasons)) { - runtime.out(dim2(` fell back ${count3}x: ${reason3}`)); + for (const [reason3, count4] of Object.entries(adaptiveSummary.fallbackReasons)) { + runtime.out(dim2(` fell back ${count4}x: ${reason3}`)); } runtime.out(dim2(` detail: ${CLI_BIN} orchestrate adaptive ${jobId}`)); runtime.out(reportTitle("Ready tasks")); @@ -139698,7 +141200,7 @@ function registerOrchestrateJobCommands(orchestrate, runtime) { (fingerprintCounts.get(entry2.failureFingerprint) ?? 0) + 1 ); } - const repeating = [...fingerprintCounts.entries()].filter(([, count3]) => count3 > 1).sort((left, right) => right[1] - left[1]); + const repeating = [...fingerprintCounts.entries()].filter(([, count4]) => count4 > 1).sort((left, right) => right[1] - left[1]); const failedChecks = (latestEvaluation?.deterministicChecks ?? []).filter( (check6) => check6.required && check6.outcome !== "PASSED" ); @@ -139717,7 +141219,7 @@ function registerOrchestrateJobCommands(orchestrate, runtime) { failedChecks, assessment: latestAssessment ?? null, recovery: latestDecision ?? null, - repeatingFingerprints: repeating.map(([fingerprint, count3]) => ({ fingerprint, count: count3 })), + repeatingFingerprints: repeating.map(([fingerprint, count4]) => ({ fingerprint, count: count4 })), remaining, counters: { stagnationEvents: reliability?.stagnationEvents ?? 0, @@ -139764,8 +141266,8 @@ function registerOrchestrateJobCommands(orchestrate, runtime) { if (repeating.length > 0) { runtime.out(""); runtime.out(reportTitle("What keeps happening?")); - for (const [fingerprint, count3] of repeating.slice(0, 5)) { - runtime.out(warnLine(` failure ${fingerprint} recurred ${count3} time(s)`)); + for (const [fingerprint, count4] of repeating.slice(0, 5)) { + runtime.out(warnLine(` failure ${fingerprint} recurred ${count4} time(s)`)); } } if (latestAssessment !== void 0) { @@ -140079,7 +141581,7 @@ function registerOrchestrateQualifyCommands(orchestrate, runtime) { } } let sequence = 0; - const deps3 = { + const deps4 = { workspace: context.workspace, config: context.config, clock: () => runtime.now(), @@ -140088,7 +141590,7 @@ function registerOrchestrateQualifyCommands(orchestrate, runtime) { return `${Date.now().toString(36)}${String(sequence).padStart(3, "0")}`; } }; - const run = options.runId === void 0 ? startQualificationRun(deps3, { + const run = options.runId === void 0 ? startQualificationRun(deps4, { profile, target: resolveTarget(options), missionDirection: options.direction ?? null, @@ -140115,7 +141617,7 @@ function registerOrchestrateQualifyCommands(orchestrate, runtime) { } } const result = executeQualificationRun({ - deps: deps3, + deps: deps4, run, executor: "cli", ...options.scenario === void 0 ? {} : { only: options.scenario }, @@ -140259,9 +141761,9 @@ function registerOrchestrateQualifyCommands(orchestrate, runtime) { ) ); runtime.out(sectionTitle("Zero-tolerance conditions")); - for (const [condition, count3] of Object.entries(report.zeroTolerance)) { - const line = ` ${condition}: ${String(count3)}`; - runtime.out(count3 === 0 ? dim2(line) : failLine(line)); + for (const [condition, count4] of Object.entries(report.zeroTolerance)) { + const line = ` ${condition}: ${String(count4)}`; + runtime.out(count4 === 0 ? dim2(line) : failLine(line)); } if (report.blockers.length > 0) { runtime.out(sectionTitle("Release blockers")); @@ -140730,9 +142232,9 @@ function registerMissionCommands(program2, runtime) { for (const diagnostic of listed.diagnostics) runtime.out(warnLine(diagnostic.message)); }); mission.command("show").description("One mission in depth: status, coverage, open questions, artifacts").argument("").option("--json", "output a machine-readable JSON report").action((missionId, options) => { - const deps3 = missionDeps2(runtime); - observeSpecApproval(deps3, missionId); - const overview = describeMission(deps3, missionId); + const deps4 = missionDeps2(runtime); + observeSpecApproval(deps4, missionId); + const overview = describeMission(deps4, missionId); if (options.json === true) { jsonOut7(runtime, "mission-show", { mission: missionSummary(overview.mission), @@ -141044,8 +142546,8 @@ function registerSetup(autonomy, runtime) { } function registerPolicy(autonomy, runtime) { autonomy.command("policy").description("Print the resolved autonomy policy and the authority boundary").option("--json", "machine-readable output").action((options) => { - const deps3 = autonomyDeps(runtime); - const policy = deps3.config.autonomy; + const deps4 = autonomyDeps(runtime); + const policy = deps4.config.autonomy; if (options.json === true) { jsonOut8(runtime, "autonomy-policy/v1", { policy, @@ -141070,18 +142572,18 @@ function registerPolicy(autonomy, runtime) { function registerSeal(autonomy, runtime) { autonomy.command("seal ").description("Draft, and with --confirm authorize, the delegated intent seal").option("--confirm", "authorize the seal (this is the human authorization)").option("--max-spend ", "monetary ceiling this seal authorizes").option("--lanes ", "comma-separated lanes: LOCAL,SUBSCRIPTION,API", "LOCAL,SUBSCRIPTION").option("--json", "machine-readable output").action( (subject, options) => { - const deps3 = autonomyDeps(runtime); + const deps4 = autonomyDeps(runtime); const missionId = resolveMissionId(runtime, subject); const lanes = options.lanes.split(",").map((lane) => lane.trim().toUpperCase()).filter( (lane) => lane === "LOCAL" || lane === "SUBSCRIPTION" || lane === "API" ); - const draft = draftSeal(deps3, { + const draft = draftSeal(deps4, { missionId, maxApiSpendUsd: options.maxSpend !== void 0 ? Number(options.maxSpend) : null, allowedLanes: lanes.length > 0 ? lanes : ["LOCAL"] }); const completeness = assessSealCompleteness(draft); - const seal = options.confirm === true && completeness.complete ? sealMission(deps3, { sealId: draft.sealId, via: "cli" }) : draft; + const seal = options.confirm === true && completeness.complete ? sealMission(deps4, { sealId: draft.sealId, via: "cli" }) : draft; if (options.json === true) { jsonOut8(runtime, "autonomy-seal/v1", { sealId: seal.sealId, @@ -141149,8 +142651,8 @@ function registerSeal(autonomy, runtime) { } }); autonomy.command("revoke ").description("Withdraw a seal; delegated execution stops immediately").requiredOption("--reason ", "why the authorization is withdrawn").action((sealId, options) => { - const deps3 = autonomyDeps(runtime); - const seal = revokeSeal(deps3, sealId, options.reason); + const deps4 = autonomyDeps(runtime); + const seal = revokeSeal(deps4, sealId, options.reason); runtime.out(okLine(`Seal ${seal.sealId} is ${seal.status}.`)); }); } @@ -141187,11 +142689,11 @@ function renderPreflight(runtime, report) { function registerOvernight(program2, runtime) { const overnight = program2.command("overnight").description("Prepare and launch an unattended mission build"); overnight.command("preflight ").description("Find the human-only prerequisites before you leave the machine").option("--json", "machine-readable output").action(async (subject, options) => { - const deps3 = autonomyDeps(runtime); + const deps4 = autonomyDeps(runtime); const missionId = resolveMissionId(runtime, subject); - const seal = latestExecutableSeal(deps3.workspace, missionId); + const seal = latestExecutableSeal(deps4.workspace, missionId); const surfaces = requiredSurfacesFor(seal); - const report = await runOvernightPreflight(deps3, { + const report = await runOvernightPreflight(deps4, { subject: missionId, missionId, ...seal !== void 0 ? { sealId: seal.sealId } : {}, @@ -141218,14 +142720,14 @@ function registerOvernight(program2, runtime) { overnight.command("run ").description("Launch the unattended build. Progress needs nobody after this").option("--job ", "continue an existing job").option("--goal ", "goal recorded on a newly created job").option("--max-cycles ", "bound on supervise/close cycles (diagnostics)").option("--json", "machine-readable output").action( async (subject, options) => { const context = loadExecutionContext(runtime); - const deps3 = { + const deps4 = { workspace: context.workspace, config: context.config, clock: () => runtime.now(), host: "cli" }; const missionId = resolveMissionId(runtime, subject); - const seal = latestExecutableSeal(deps3.workspace, missionId); + const seal = latestExecutableSeal(deps4.workspace, missionId); if (seal === void 0) { throw new SpecBridgeError( "INVALID_STATE", @@ -141239,11 +142741,11 @@ function registerOvernight(program2, runtime) { `Mission ${missionId} has synthesized no spec yet; there is nothing to build.` ); } - const jobId = options.job ?? createJob(deps3, { + const jobId = options.job ?? createJob(deps4, { specName, goal: options.goal ?? seal.goal }).jobId; - const result = await runUnattendedMission(deps3, { + const result = await runUnattendedMission(deps4, { missionId, jobId, // A factory: the runtime hands back deps carrying the authority @@ -141357,10 +142859,10 @@ function registerInspection(autonomy, runtime) { } }); autonomy.command("report ").description("The autonomy report for one job (read-only)").option("--json", "machine-readable output").action((jobId, options) => { - const deps3 = autonomyDeps(runtime); - const telemetry = computeAutonomyTelemetry(deps3, { jobId }); - const ledger = readClosureLedger(deps3.workspace, jobId); - const job = requireJobState(deps3.workspace, jobId); + const deps4 = autonomyDeps(runtime); + const telemetry = computeAutonomyTelemetry(deps4, { jobId }); + const ledger = readClosureLedger(deps4.workspace, jobId); + const job = requireJobState(deps4.workspace, jobId); if (options.json === true) { jsonOut8(runtime, "autonomy-report/v1", { jobId, @@ -141494,8 +142996,8 @@ function registerClosure(autonomy, runtime) { closure.command("waive ").description( "Waive one sealed closure item with YOUR authority (human decision). A waiver is an attestation, not a shortcut: name the evidence you inspected." ).requiredOption("--reason ", "why this item is satisfied or does not apply \u2014 name the evidence").option("--by ", "who attests", "operator").action((jobId, itemId, options) => { - const deps3 = autonomyDeps(runtime); - const ledger = waiveClosureItem(deps3, { + const deps4 = autonomyDeps(runtime); + const ledger = waiveClosureItem(deps4, { jobId, itemId, reason: options.reason, @@ -141789,6 +143291,37 @@ function registerResearchCommands(program2, runtime) { }); } +// ../../packages/cli/src/commands/report.ts +function deps3(runtime) { + const context = loadExecutionContext(runtime); + return { + workspace: context.workspace, + config: context.config, + clock: () => runtime.now(), + host: "cli" + }; +} +function registerReportCommands(program2, runtime) { + const report = program2.command("report").description("Derived execution telemetry (never completion authority)"); + report.command("job ").description("Report one Job from durable execution facts").option("--json", "emit the versioned machine-readable report").option("--verbose", "include bounded WorkUnit accounting and cooldown timeline").option("--no-persist", "derive without writing .specbridge/reports").action((jobId, options) => { + const reportingDeps = deps3(runtime); + const result = computeExecutionTelemetryReport(reportingDeps, jobId, { + persist: options.persist !== false, + specbridgeVersion: VERSION + }); + if (options.json === true) { + runtime.outRaw(serializeJsonReport(result)); + return; + } + runtime.outRaw(renderExecutionTelemetryReport(result, { verbose: options.verbose === true })); + if (options.persist !== false) { + runtime.out( + `Report: ${relPath(reportingDeps.workspace, executionTelemetryReportFile(reportingDeps.workspace, jobId))}` + ); + } + }); +} + // ../../packages/cli/src/cli.ts function buildProgram(runtime) { const program2 = new Command(); @@ -141851,6 +143384,7 @@ honest error; nothing pretends to work before it does.` registerAutonomyCommands(program2, runtime); registerWorkspaceCommands(program2, runtime); registerResearchCommands(program2, runtime); + registerReportCommands(program2, runtime); return program2; } async function runCli(argv2, ioOverrides) { diff --git a/integrations/claude-code-plugin/specbridge/dist/mcp-server.cjs b/integrations/claude-code-plugin/specbridge/dist/mcp-server.cjs index 85b5e4f..f6b99b6 100644 --- a/integrations/claude-code-plugin/specbridge/dist/mcp-server.cjs +++ b/integrations/claude-code-plugin/specbridge/dist/mcp-server.cjs @@ -597,8 +597,8 @@ var require_Node = __commonJS({ }; const res = toJS.toJS(this, "", ctx); if (typeof onAnchor === "function") - for (const { count: count3, res: res2 } of ctx.anchors.values()) - onAnchor(res2, count3); + for (const { count: count4, res: res2 } of ctx.anchors.values()) + onAnchor(res2, count4); return typeof reviver === "function" ? applyReviver.applyReviver(reviver, { "": res }, "", res) : res; } }; @@ -704,13 +704,13 @@ var require_Alias = __commonJS({ const anchor = anchors2 && source && anchors2.get(source); return anchor ? anchor.count * anchor.aliasCount : 0; } else if (identity3.isCollection(node)) { - let count3 = 0; + let count4 = 0; for (const item of node.items) { const c3 = getAliasCount(doc, item, anchors2); - if (c3 > count3) - count3 = c3; + if (c3 > count4) + count4 = c3; } - return count3; + return count4; } else if (identity3.isPair(node)) { const kc = getAliasCount(doc, node.key, anchors2); const vc = getAliasCount(doc, node.value, anchors2); @@ -3663,8 +3663,8 @@ var require_Document = __commonJS({ }; const res = toJS.toJS(this.contents, jsonArg ?? "", ctx); if (typeof onAnchor === "function") - for (const { count: count3, res: res2 } of ctx.anchors.values()) - onAnchor(res2, count3); + for (const { count: count4, res: res2 } of ctx.anchors.values()) + onAnchor(res2, count4); return typeof reviver === "function" ? applyReviver.applyReviver(reviver, { "": res }, "", res) : res; } /** @@ -3741,12 +3741,12 @@ var require_errors = __commonJS({ lineStr = prev + lineStr; } if (/[^ ]/.test(lineStr)) { - let count3 = 1; + let count4 = 1; const end = error2.linePos[1]; if (end?.line === line && end.col > col) { - count3 = Math.max(1, Math.min(end.col - col, 80 - ci)); + count4 = Math.max(1, Math.min(end.col - col, 80 - ci)); } - const pointer = " ".repeat(ci) + "^".repeat(count3); + const pointer = " ".repeat(ci) + "^".repeat(count4); error2.message += `: ${lineStr} @@ -10044,20 +10044,20 @@ var require_resolve = __commonJS({ return false; } function countKeys(schema) { - let count3 = 0; + let count4 = 0; for (const key in schema) { if (key === "$ref") return Infinity; - count3++; + count4++; if (SIMPLE_INLINED.has(key)) continue; if (typeof schema[key] == "object") { - (0, util_1.eachItem)(schema[key], (sch) => count3 += countKeys(sch)); + (0, util_1.eachItem)(schema[key], (sch) => count4 += countKeys(sch)); } - if (count3 === Infinity) + if (count4 === Infinity) return Infinity; } - return count3; + return count4; } function getFullPath(resolver, id = "", normalize3) { if (normalize3 !== false) @@ -13229,8 +13229,8 @@ var require_contains = __commonJS({ cxt.result(valid, () => cxt.reset()); function validateItemsWithCount() { const schValid = gen.name("_valid"); - const count3 = gen.let("count", 0); - validateItems(schValid, () => gen.if(schValid, () => checkLimits(count3))); + const count4 = gen.let("count", 0); + validateItems(schValid, () => gen.if(schValid, () => checkLimits(count4))); } function validateItems(_valid, block) { gen.forRange("i", 0, len, (i2) => { @@ -13243,16 +13243,16 @@ var require_contains = __commonJS({ block(); }); } - function checkLimits(count3) { - gen.code((0, codegen_1._)`${count3}++`); + function checkLimits(count4) { + gen.code((0, codegen_1._)`${count4}++`); if (max === void 0) { - gen.if((0, codegen_1._)`${count3} >= ${min}`, () => gen.assign(valid, true).break()); + gen.if((0, codegen_1._)`${count4} >= ${min}`, () => gen.assign(valid, true).break()); } else { - gen.if((0, codegen_1._)`${count3} > ${max}`, () => gen.assign(valid, false).break()); + gen.if((0, codegen_1._)`${count4} > ${max}`, () => gen.assign(valid, false).break()); if (min === 1) gen.assign(valid, true); else - gen.if((0, codegen_1._)`${count3} >= ${min}`, () => gen.assign(valid, true)); + gen.if((0, codegen_1._)`${count4} >= ${min}`, () => gen.assign(valid, true)); } } } @@ -15641,20 +15641,20 @@ var require_parse2 = __commonJS({ consume(token.value); }; const negate = () => { - let count3 = 1; + let count4 = 1; while (peek() === "!" && (peek(2) !== "(" || peek(3) === "?")) { advance(); state.start++; - count3++; + count4++; } - if (count3 % 2 === 0) { + if (count4 % 2 === 0) { return false; } state.negated = true; state.start++; return true; }; - const increment2 = (type) => { + const increment3 = (type) => { state[type]++; stack.push(type); }; @@ -15695,7 +15695,7 @@ var require_parse2 = __commonJS({ token.startIndex = state.index; token.tokensIndex = tokens.length; const output = (opts.capture ? "(" : "") + token.open; - increment2("parens"); + increment3("parens"); push2({ type, value: value2, output: state.output ? "" : ONE_CHAR }); push2({ type: "paren", extglob: true, value: advance(), output }); extglobs.push(token); @@ -15871,7 +15871,7 @@ var require_parse2 = __commonJS({ continue; } if (value === "(") { - increment2("parens"); + increment3("parens"); push2({ type: "paren", value }); continue; } @@ -15895,7 +15895,7 @@ var require_parse2 = __commonJS({ } value = `\\${value}`; } else { - increment2("brackets"); + increment3("brackets"); } push2({ type: "bracket", value }); continue; @@ -15934,7 +15934,7 @@ var require_parse2 = __commonJS({ continue; } if (value === "{" && opts.nobrace !== true) { - increment2("braces"); + increment3("braces"); const open = { type: "brace", value, @@ -28454,6 +28454,54 @@ var autonomyPolicySchema = external_exports.object({ closure: closurePolicySchema.default({}), controlPlaneRepair: controlPlaneRepairPolicySchema.default({}) }).passthrough(); +function autonomyPolicyFingerprint(policy) { + const canonical = { + mode: policy.mode, + humanGate: policy.humanGate, + decisions: { + implementation: policy.decisions.implementation, + internalArchitecture: policy.decisions.internalArchitecture, + dependencySelection: policy.decisions.dependencySelection, + toolingCreation: policy.decisions.toolingCreation, + testInfrastructure: policy.decisions.testInfrastructure, + environmentProvisioning: policy.decisions.environmentProvisioning, + browserVerification: policy.decisions.browserVerification, + workDecomposition: policy.decisions.workDecomposition + }, + recovery: { + provider: policy.recovery.provider, + process: policy.recovery.process, + toolchain: policy.recovery.toolchain, + implementation: policy.recovery.implementation, + context: policy.recovery.context, + environment: policy.recovery.environment, + controlPlane: policy.recovery.controlPlane + }, + supervisor: { enabled: policy.supervisor.enabled, maxRestarts: policy.supervisor.maxRestarts }, + toolsmith: { + enabled: policy.toolsmith.enabled, + capabilities: [...policy.toolsmith.capabilities].sort(), + maxGrantsPerJob: policy.toolsmith.maxGrantsPerJob + }, + environments: { enabled: policy.environments.enabled }, + browser: { enabled: policy.browser.enabled }, + critic: { mode: policy.critic.mode }, + closure: { + enabled: policy.closure.enabled, + maxGapClosureCycles: policy.closure.maxGapClosureCycles, + requireSystemScenarios: policy.closure.requireSystemScenarios, + requireReleaseQualification: policy.closure.requireReleaseQualification, + requireReproducibility: policy.closure.requireReproducibility + }, + controlPlaneRepair: { + enabled: policy.controlPlaneRepair.enabled, + maxRepairsPerJob: policy.controlPlaneRepair.maxRepairsPerJob, + requireFullQualification: policy.controlPlaneRepair.requireFullQualification, + requireCanary: policy.controlPlaneRepair.requireCanary + } + }; + return JSON.stringify(canonical); +} var RUNNER_CONFIG_SCHEMA_VERSION = "2.0.0"; var BUILT_IN_PROFILE_NAMES = { "claude-code": "claude-code", @@ -31903,7 +31951,7 @@ function analyzeSpecWorkflow(spec, evaluation, stages) { function buildInitialState(specName, specType, mode, origin, clock) { const shape = workflowShape(specType, mode); const stages = initialStages(shape, specName); - const now5 = isoNow(clock); + const now6 = isoNow(clock); return { schemaVersion: SPEC_STATE_SCHEMA_VERSION, specName, @@ -31911,8 +31959,8 @@ function buildInitialState(specName, specType, mode, origin, clock) { workflowMode: mode, origin, status: deriveWorkflowStatus(shape, stages), - createdAt: now5, - updatedAt: now5, + createdAt: now6, + updatedAt: now6, stages }; } @@ -37377,7 +37425,7 @@ function parseMilliseconds(milliseconds) { // ../../node_modules/.pnpm/pretty-ms@9.3.0/node_modules/pretty-ms/index.js var isZero = (value) => value === 0 || value === 0n; -var pluralize = (word, count3) => count3 === 1 || count3 === 1n ? word : `${word}s`; +var pluralize = (word, count4) => count4 === 1 || count4 === 1n ? word : `${word}s`; var SECOND_ROUNDING_EPSILON = 1e-7; var ONE_DAY_IN_MILLISECONDS = 24n * 60n * 60n * 1000n; function prettyMilliseconds(milliseconds, options) { @@ -39381,10 +39429,10 @@ var errorStream = (stream, error2) => { }; var noop2 = () => { }; -var updateMaxListeners = (passThroughStream, increment2) => { +var updateMaxListeners = (passThroughStream, increment3) => { const maxListeners = passThroughStream.getMaxListeners(); if (maxListeners !== 0 && maxListeners !== Number.POSITIVE_INFINITY) { - passThroughStream.setMaxListeners(maxListeners + increment2); + passThroughStream.setMaxListeners(maxListeners + increment3); } }; var PASSTHROUGH_LISTENERS_COUNT = 2; @@ -39608,12 +39656,12 @@ var SignalExit = class extends SignalExitBase { for (const sig of signals) { this.#sigListeners[sig] = () => { const listeners = this.#process.listeners(sig); - let { count: count3 } = this.#emitter; + let { count: count4 } = this.#emitter; const p = process11; if (typeof p.__signal_exit_emitter__ === "object" && typeof p.__signal_exit_emitter__.count === "number") { - count3 += p.__signal_exit_emitter__.count; + count4 += p.__signal_exit_emitter__.count; } - if (listeners.length === count3) { + if (listeners.length === count4) { this.unload(); const ret = this.#emitter.emit("exit", null, sig); const s = sig === "SIGHUP" ? this.#hupSig : sig; @@ -49318,7 +49366,7 @@ function hashProtectedTree(workspaceRoot, relativeDir, into) { } } async function captureGitSnapshot(workspaceRoot, options = {}) { - const now5 = options.clock?.() ?? /* @__PURE__ */ new Date(); + const now6 = options.clock?.() ?? /* @__PURE__ */ new Date(); const diagnostics = []; const excludedPrefixes = [ ...SNAPSHOT_EXCLUDED_PREFIXES, @@ -49333,7 +49381,7 @@ async function captureGitSnapshot(workspaceRoot, options = {}) { }); return { schemaVersion: GIT_SNAPSHOT_SCHEMA_VERSION, - capturedAt: now5.toISOString(), + capturedAt: now6.toISOString(), gitAvailable: false, detached: false, clean: false, @@ -49407,7 +49455,7 @@ async function captureGitSnapshot(workspaceRoot, options = {}) { hashProtectedTree(workspaceRoot, import_path15.default.join(".specbridge", "state"), protectedHashes); return { schemaVersion: GIT_SNAPSHOT_SCHEMA_VERSION, - capturedAt: now5.toISOString(), + capturedAt: now6.toISOString(), gitAvailable: statusResult.ok, ...head !== void 0 ? { head } : {}, ...branch !== void 0 ? { branch } : {}, @@ -49757,10 +49805,10 @@ function evaluateEvidence(input) { if (!input.taskStillExists) { violations.push("the selected task no longer exists in tasks.md with its recorded text"); } - const outcomeStatus = statusForFailedOutcome(input.runnerOutcome); - if (outcomeStatus !== void 0) { + const outcomeStatus2 = statusForFailedOutcome(input.runnerOutcome); + if (outcomeStatus2 !== void 0) { reasons.push(`the runner outcome was "${input.runnerOutcome}"`); - return { status: outcomeStatus, violations, warnings, reasons }; + return { status: outcomeStatus2, violations, warnings, reasons }; } const agentChanges = agentChangedFiles(input.comparison).filter( (file) => !input.comparison.ambiguousPaths.includes(file.path) @@ -51002,15 +51050,15 @@ function readInteractiveLock(workspace) { } function acquireInteractiveLock(workspace, details) { const lockPath = interactiveLockPath(workspace); - const now5 = (details.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); + const now6 = (details.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); const lock = { schemaVersion: INTERACTIVE_LOCK_SCHEMA_VERSION, runId: details.runId, specName: details.specName, taskId: details.taskId, pid: details.pid ?? process.pid, - createdAt: now5, - heartbeatAt: now5 + createdAt: now6, + heartbeatAt: now6 }; (0, import_fs20.mkdirSync)(import_path21.default.dirname(lockPath), { recursive: true }); try { @@ -51493,8 +51541,8 @@ async function abortInteractiveTask(deps, request) { ...report !== void 0 ? { outcome: classifyInteractiveOutcome(report) } : {} }; } - const now5 = await captureGitSnapshot(workspace.rootDir, { clock: () => clock() }); - const remaining = now5.gitAvailable ? agentChangedFiles(compareSnapshots(state.before, now5)).map((file) => file.path) : []; + const now6 = await captureGitSnapshot(workspace.rootDir, { clock: () => clock() }); + const remaining = now6.gitAvailable ? agentChangedFiles(compareSnapshots(state.before, now6)).map((file) => file.path) : []; const abortedAt = clock().toISOString(); writeRunArtifact( workspace, @@ -52630,14 +52678,14 @@ function refreshRepositoryIndex(previous, options) { function normalize(value) { return value.replace(/\\/g, "/").replace(/^\.\//, ""); } -function safeBuildEntry(rootDir, relativePath, now5, maxFileBytes) { +function safeBuildEntry(rootDir, relativePath, now6, maxFileBytes) { const limit = maxFileBytes ?? REPOSITORY_INDEX_LIMITS.maxFileBytes; try { if ((0, import_fs22.statSync)(import_path24.default.join(rootDir, relativePath)).size > limit) return void 0; } catch { return void 0; } - return buildEntry(rootDir, relativePath, now5); + return buildEntry(rootDir, relativePath, now6); } var RepositoryContextIndex = class { /** @@ -53544,12 +53592,16 @@ var contextEfficiencyMetricsSchema = external_exports.object({ // ../../packages/orchestration/dist/index.js var import_fs26 = require("fs"); var import_path28 = __toESM(require("path"), 1); -var import_crypto13 = require("crypto"); var import_fs27 = require("fs"); var import_path29 = __toESM(require("path"), 1); -var import_crypto14 = require("crypto"); var import_fs28 = require("fs"); var import_path30 = __toESM(require("path"), 1); +var import_crypto13 = require("crypto"); +var import_fs29 = require("fs"); +var import_path31 = __toESM(require("path"), 1); +var import_crypto14 = require("crypto"); +var import_fs30 = require("fs"); +var import_path32 = __toESM(require("path"), 1); var ORCHESTRATION_PHASES = [ /** The run exists; no intent has been assessed yet. */ "CREATED", @@ -56744,6 +56796,10 @@ var jobCheckpointSchema = external_exports.object({ /** The exact next legal action, in one line. */ nextAction: text22 }).passthrough(); +function workedMsOf(job, nowMs) { + const waited = (job.counters.humanWaitMs ?? 0) + (job.counters.deadIdleMs ?? 0) + (job.humanWaitSince === void 0 ? 0 : Math.max(0, nowMs - Date.parse(job.humanWaitSince))); + return Math.max(0, nowMs - Date.parse(job.createdAt) - waited); +} var RECOVERY_TARGETS = [ "WAITING_RESOURCE", "RECOVERING_PROVIDER", @@ -58562,6 +58618,29 @@ function readCandidate(workspace, jobId, nodeId, workUnitId, attempt) { } ); } +function readBuilderRoutingStates(workspace, jobId, nodeId) { + const dir = artifactPath3(workspace, jobId, nodeId, "routing"); + if (!(0, import_fs25.existsSync)(dir)) return []; + const states = []; + for (const name of (0, import_fs25.readdirSync)(dir).sort()) { + if (!name.endsWith(".json") || name === "telemetry.json") continue; + const state = readJson(import_path27.default.join(dir, name), (raw) => { + const result = builderRoutingStateSchema.safeParse(raw); + return result.success ? result.data : void 0; + }); + if (state !== void 0) states.push(state); + } + return states; +} +function readObjectiveCooldownState(workspace, jobId, nodeId) { + return readJson( + artifactPath3(workspace, jobId, nodeId, "resources", "strong-subscription.json"), + (raw) => { + const result = objectiveCooldownStateSchema.safeParse(raw); + return result.success ? result.data : void 0; + } + ); +} function readEvaluations(workspace, jobId, nodeId, workUnitId) { const dir = artifactPath3(workspace, jobId, nodeId, "evaluations"); if (!(0, import_fs25.existsSync)(dir)) return []; @@ -58606,6 +58685,11 @@ function readWorkerRecords(workspace, jobId, nodeId) { } return records; } +function listObjectiveNodes(workspace, jobId) { + const dir = import_path27.default.join(jobDir(workspace, jobId), "objectives"); + if (!(0, import_fs25.existsSync)(dir)) return []; + return (0, import_fs25.readdirSync)(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && ID_PATTERN3.test(entry.name)).map((entry) => entry.name).sort(); +} var EVALUATION_STATUSES = ["PASS", "FAIL", "INCONCLUSIVE"]; var EVALUATION_CHECK_LEVELS = [ "EXECUTION_INTEGRITY", @@ -59033,6 +59117,48 @@ var taskReliabilityStateSchema = external_exports.object({ pendingDecisionId: shortText8.optional(), updatedAt: shortText8 }).passthrough(); +function reliabilityDir(workspace, jobId) { + return assertInsideWorkspace(workspace.rootDir, import_path28.default.join(jobDir(workspace, jobId), "reliability")); +} +function recordDir(workspace, jobId, kind) { + return assertInsideWorkspace(workspace.rootDir, import_path28.default.join(reliabilityDir(workspace, jobId), kind)); +} +function readRecord(file, parse3) { + if (!(0, import_fs26.existsSync)(file)) return void 0; + try { + return parse3(JSON.parse((0, import_fs26.readFileSync)(file, "utf8"))); + } catch { + return void 0; + } +} +function listRecords(workspace, jobId, kind, parse3) { + const dir = recordDir(workspace, jobId, kind); + if (!(0, import_fs26.existsSync)(dir)) return []; + const records = []; + for (const entry of (0, import_fs26.readdirSync)(dir).sort()) { + if (!entry.endsWith(".json")) continue; + const record32 = readRecord(import_path28.default.join(dir, entry), parse3); + if (record32 !== void 0) records.push(record32); + } + return records; +} +function listEvaluationResults(workspace, jobId, filter = {}) { + const all = listRecords(workspace, jobId, "evaluations", (raw) => evaluationResultSchema.parse(raw)); + return filter.nodeId === void 0 ? all : all.filter((entry) => entry.nodeId === filter.nodeId); +} +function listFailureAssessments(workspace, jobId, filter = {}) { + const all = listRecords( + workspace, + jobId, + "assessments", + (raw) => failureAssessmentSchema.parse(raw) + ); + return filter.nodeId === void 0 ? all : all.filter((entry) => entry.nodeId === filter.nodeId); +} +function listRecoveryDecisions(workspace, jobId, filter = {}) { + const all = listRecords(workspace, jobId, "decisions", (raw) => recoveryDecisionSchema.parse(raw)); + return filter.nodeId === void 0 ? all : all.filter((entry) => entry.nodeId === filter.nodeId); +} var TASK_ATTEMPT_STATUSES = [ /** The dispatch is (or was, before a crash) in flight. */ "RUNNING", @@ -59357,6 +59483,102 @@ var executionLedgerEntrySchema = external_exports.object({ runnerVersion: shortText9.nullable().default(null), metrics: attemptMetricsSchema }).passthrough(); +function taskAttemptsDir(workspace, jobId) { + return assertInsideWorkspace( + workspace.rootDir, + import_path29.default.join(jobDir(workspace, jobId), "task-attempts") + ); +} +function listTaskAttempts(workspace, jobId, options = {}) { + const dir = taskAttemptsDir(workspace, jobId); + if (!(0, import_fs27.existsSync)(dir)) return []; + const attempts = []; + for (const entry of (0, import_fs27.readdirSync)(dir, { withFileTypes: true })) { + if (!entry.isFile() || !entry.name.endsWith(".json")) continue; + try { + const parsed = taskAttemptSchema.safeParse( + JSON.parse((0, import_fs27.readFileSync)(import_path29.default.join(dir, entry.name), "utf8")) + ); + if (!parsed.success) continue; + if (options.nodeId !== void 0 && parsed.data.nodeId !== options.nodeId) continue; + if (options.status !== void 0 && parsed.data.status !== options.status) continue; + attempts.push(parsed.data); + } catch { + } + } + attempts.sort( + (a2, b) => a2.startedAt.localeCompare(b.startedAt, "en") || a2.attemptId.localeCompare(b.attemptId, "en") + ); + return attempts; +} +function readExecutionLedger(workspace, jobId, options = {}) { + const attempts = listTaskAttempts(workspace, jobId, { nodeId: options.nodeId }); + const evaluations = new Map( + listEvaluationResults(workspace, jobId, { + ...options.nodeId !== void 0 ? { nodeId: options.nodeId } : {} + }).map((entry) => [entry.attemptId, entry]) + ); + const assessments = new Map( + listFailureAssessments(workspace, jobId, { + ...options.nodeId !== void 0 ? { nodeId: options.nodeId } : {} + }).map((entry) => [entry.attemptId, entry]) + ); + const decisions = new Map( + listRecoveryDecisions(workspace, jobId, { + ...options.nodeId !== void 0 ? { nodeId: options.nodeId } : {} + }).map((entry) => [entry.attemptId, entry]) + ); + return attempts.map((attempt) => { + const evaluation = evaluations.get(attempt.attemptId); + const assessment = assessments.get(attempt.attemptId); + const decision = decisions.get(attempt.attemptId); + return executionLedgerEntrySchema.parse({ + attemptId: attempt.attemptId, + jobId: attempt.jobId, + nodeId: attempt.nodeId, + taskId: attempt.taskId, + role: attempt.role, + provider: attempt.provider, + model: attempt.model, + lane: attempt.lane ?? null, + status: attempt.status, + attemptNumber: attempt.attemptNumber, + startedAt: attempt.startedAt, + completedAt: attempt.completedAt ?? null, + success: attempt.status === "COMPLETED", + failureReason: attempt.failure?.category ?? attempt.interruptedReason ?? null, + localSuitability: attempt.localSuitability ?? null, + taskComplexity: attempt.taskComplexity ?? null, + taskCategory: attempt.taskCategory ?? null, + schedulingDecisionId: attempt.schedulingDecisionId ?? null, + executionMode: attempt.executionMode ?? null, + executionShape: attempt.executionShape ?? null, + computeLocality: attempt.computeLocality ?? null, + apiSpendMode: attempt.apiSpendMode ?? null, + gapReason: attempt.gapReason ?? null, + subscriptionAvailableAt: attempt.subscriptionAvailableAt ?? null, + estimatedGapDurationMs: attempt.estimatedGapDurationMs ?? null, + costSource: attempt.costSource ?? null, + pricingProfile: attempt.pricingProfile ?? null, + apiBudgetReservationId: attempt.apiBudgetReservationId ?? null, + apiApprovalId: attempt.apiApprovalId ?? null, + delaySensitivity: attempt.delaySensitivity ?? null, + evaluationStatus: evaluation?.status ?? null, + evaluationId: evaluation?.evaluationId ?? null, + failureSource: assessment?.source ?? null, + failureFingerprint: assessment?.fingerprint ?? null, + executionHealth: assessment?.health ?? null, + recoveryAction: decision?.action ?? null, + recoveryReasonCode: decision?.reasonCode ?? null, + recoveryDecisionId: decision?.decisionId ?? null, + strategyChange: decision?.strategyChange ?? null, + taskSignature: attempt.taskSignature ?? null, + contextStrategy: attempt.contextStrategy ?? null, + runnerVersion: attempt.runnerVersion ?? null, + metrics: attempt.metrics + }); + }); +} var shortText10 = external_exports.string().min(1).max(200); var apiBudgetReservationSchema = external_exports.object({ reservationId: shortText10, @@ -59484,19 +59706,19 @@ function assessApiBudget(input) { }; } function contextCacheDir(workspace) { - return assertInsideWorkspace(workspace.rootDir, import_path28.default.join(workspace.sidecarDir, "cache")); + return assertInsideWorkspace(workspace.rootDir, import_path30.default.join(workspace.sidecarDir, "cache")); } function repositoryIndexFile(workspace) { return assertInsideWorkspace( workspace.rootDir, - import_path28.default.join(contextCacheDir(workspace), "context-index.json") + import_path30.default.join(contextCacheDir(workspace), "context-index.json") ); } function readRepositoryIndexCache(workspace) { const file = repositoryIndexFile(workspace); - if (!(0, import_fs26.existsSync)(file)) return void 0; + if (!(0, import_fs28.existsSync)(file)) return void 0; try { - const parsed = repositoryContextIndexSchema.safeParse(JSON.parse((0, import_fs26.readFileSync)(file, "utf8"))); + const parsed = repositoryContextIndexSchema.safeParse(JSON.parse((0, import_fs28.readFileSync)(file, "utf8"))); return parsed.success ? parsed.data : void 0; } catch { return void 0; @@ -59505,7 +59727,7 @@ function readRepositoryIndexCache(workspace) { function writeRepositoryIndexCache(workspace, state) { const validated = repositoryContextIndexSchema.parse(state); const file = repositoryIndexFile(workspace); - (0, import_fs26.mkdirSync)(import_path28.default.dirname(file), { recursive: true }); + (0, import_fs28.mkdirSync)(import_path30.default.dirname(file), { recursive: true }); writeFileAtomic(file, `${JSON.stringify(validated)} `); } @@ -61838,13 +62060,13 @@ function findResearchReuse(records, request) { var RESEARCH_DIR_NAME = "research"; var ID_PATTERN7 = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/; function researchRootDir(workspace) { - return assertInsideWorkspace(workspace.rootDir, import_path29.default.join(workspace.sidecarDir, RESEARCH_DIR_NAME)); + return assertInsideWorkspace(workspace.rootDir, import_path31.default.join(workspace.sidecarDir, RESEARCH_DIR_NAME)); } function researchRecordsDir(workspace) { - return assertInsideWorkspace(workspace.rootDir, import_path29.default.join(researchRootDir(workspace), "records")); + return assertInsideWorkspace(workspace.rootDir, import_path31.default.join(researchRootDir(workspace), "records")); } function researchUsesDir(workspace) { - return assertInsideWorkspace(workspace.rootDir, import_path29.default.join(researchRootDir(workspace), "uses")); + return assertInsideWorkspace(workspace.rootDir, import_path31.default.join(researchRootDir(workspace), "uses")); } function assertResearchId(researchId) { if (!ID_PATTERN7.test(researchId)) throw new Error(`Invalid research id "${researchId}".`); @@ -61854,7 +62076,7 @@ function researchRecordFile(workspace, researchId) { assertResearchId(researchId); return assertInsideWorkspace( workspace.rootDir, - import_path29.default.join(researchRecordsDir(workspace), `${researchId}.json`) + import_path31.default.join(researchRecordsDir(workspace), `${researchId}.json`) ); } function majorOf3(value) { @@ -61862,10 +62084,10 @@ function majorOf3(value) { } function readResearchRecord(workspace, researchId) { const file = researchRecordFile(workspace, researchId); - if (!(0, import_fs27.existsSync)(file)) return { kind: "missing" }; + if (!(0, import_fs29.existsSync)(file)) return { kind: "missing" }; let value; try { - value = JSON.parse((0, import_fs27.readFileSync)(file, "utf8")); + value = JSON.parse((0, import_fs29.readFileSync)(file, "utf8")); } catch (cause) { return { kind: "corrupt", problem: cause instanceof Error ? cause.message : String(cause), file }; } @@ -61887,29 +62109,46 @@ function readResearchRecord(workspace, researchId) { function writeResearchRecord(workspace, value) { const record32 = researchRecordSchema.parse(value); const file = researchRecordFile(workspace, record32.researchId); - (0, import_fs27.mkdirSync)(import_path29.default.dirname(file), { recursive: true }); + (0, import_fs29.mkdirSync)(import_path31.default.dirname(file), { recursive: true }); writeFileAtomic(file, `${JSON.stringify(record32, null, 2)} `); return record32; } function researchUseFile(workspace, useId) { - return assertInsideWorkspace(workspace.rootDir, import_path29.default.join(researchUsesDir(workspace), `${useId}.json`)); + return assertInsideWorkspace(workspace.rootDir, import_path31.default.join(researchUsesDir(workspace), `${useId}.json`)); } function writeResearchUseRecord(workspace, value) { const record32 = researchUseRecordSchema.parse(value); const file = researchUseFile(workspace, record32.useId); - if ((0, import_fs27.existsSync)(file)) throw new Error(`research use id ${record32.useId} already exists`); - (0, import_fs27.mkdirSync)(import_path29.default.dirname(file), { recursive: true }); + if ((0, import_fs29.existsSync)(file)) throw new Error(`research use id ${record32.useId} already exists`); + (0, import_fs29.mkdirSync)(import_path31.default.dirname(file), { recursive: true }); writeFileAtomic(file, `${JSON.stringify(record32, null, 2)} `); return record32; } +function listResearchUseRecords(workspace) { + const dir = researchUsesDir(workspace); + if (!(0, import_fs29.existsSync)(dir)) return []; + const records = []; + for (const entry of (0, import_fs29.readdirSync)(dir, { withFileTypes: true })) { + if (!entry.isFile() || !entry.name.endsWith(".json")) continue; + try { + const value = JSON.parse((0, import_fs29.readFileSync)(import_path31.default.join(dir, entry.name), "utf8")); + const version2 = value !== null && typeof value === "object" && typeof value.schemaVersion === "string" ? value.schemaVersion : ""; + if (majorOf3(version2) !== majorOf3(RESEARCH_USE_SCHEMA_VERSION)) continue; + const parsed = researchUseRecordSchema.safeParse(value); + if (parsed.success) records.push(parsed.data); + } catch { + } + } + return records.sort((a2, b) => a2.createdAt.localeCompare(b.createdAt)); +} function listResearchRecords(workspace) { const dir = researchRecordsDir(workspace); - if (!(0, import_fs27.existsSync)(dir)) return { records: [], diagnostics: [] }; + if (!(0, import_fs29.existsSync)(dir)) return { records: [], diagnostics: [] }; const records = []; const diagnostics = []; - for (const entry of (0, import_fs27.readdirSync)(dir, { withFileTypes: true })) { + for (const entry of (0, import_fs29.readdirSync)(dir, { withFileTypes: true })) { if (!entry.isFile() || !entry.name.endsWith(".json")) continue; const researchId = entry.name.slice(0, -5); if (!ID_PATTERN7.test(researchId)) continue; @@ -62477,7 +62716,7 @@ function zeroPhaseCounts() { function avoidanceRatio(avoided, considered) { return considered === 0 ? 0 : avoided / considered; } -function emptyResearchTelemetry(now5) { +function emptyResearchTelemetry(now52) { return { schemaVersion: RESEARCH_TELEMETRY_SCHEMA_VERSION, gateConsidered: 0, @@ -62504,32 +62743,32 @@ function emptyResearchTelemetry(now5) { reports: 0 }, totalDurationMs: 0, - updatedAt: now5.toISOString() + updatedAt: now52.toISOString() }; } function researchTelemetryFile(workspace) { - return assertInsideWorkspace(workspace.rootDir, import_path30.default.join(researchRootDir(workspace), "telemetry.json")); + return assertInsideWorkspace(workspace.rootDir, import_path32.default.join(researchRootDir(workspace), "telemetry.json")); } -function readResearchTelemetry(workspace, now5 = /* @__PURE__ */ new Date()) { +function readResearchTelemetry(workspace, now52 = /* @__PURE__ */ new Date()) { const file = researchTelemetryFile(workspace); - if (!(0, import_fs28.existsSync)(file)) return { telemetry: emptyResearchTelemetry(now5) }; + if (!(0, import_fs30.existsSync)(file)) return { telemetry: emptyResearchTelemetry(now52) }; try { - const parsed = researchTelemetrySchema.safeParse(JSON.parse((0, import_fs28.readFileSync)(file, "utf8"))); - return parsed.success ? { telemetry: parsed.data } : { telemetry: emptyResearchTelemetry(now5), diagnostic: "research telemetry is schema-invalid" }; + const parsed = researchTelemetrySchema.safeParse(JSON.parse((0, import_fs30.readFileSync)(file, "utf8"))); + return parsed.success ? { telemetry: parsed.data } : { telemetry: emptyResearchTelemetry(now52), diagnostic: "research telemetry is schema-invalid" }; } catch { - return { telemetry: emptyResearchTelemetry(now5), diagnostic: "research telemetry is unreadable" }; + return { telemetry: emptyResearchTelemetry(now52), diagnostic: "research telemetry is unreadable" }; } } function writeTelemetry(workspace, value) { const telemetry = researchTelemetrySchema.parse(value); const file = researchTelemetryFile(workspace); - (0, import_fs28.mkdirSync)(import_path30.default.dirname(file), { recursive: true }); + (0, import_fs30.mkdirSync)(import_path32.default.dirname(file), { recursive: true }); writeFileAtomic(file, `${JSON.stringify(telemetry, null, 2)} `); return telemetry; } -function recordResearchGateTelemetry(workspace, decision, now5, phase) { - const current = readResearchTelemetry(workspace, now5).telemetry; +function recordResearchGateTelemetry(workspace, decision, now52, phase) { + const current = readResearchTelemetry(workspace, now52).telemetry; const avoided = decision !== "RESEARCH_QUICK" && decision !== "RESEARCH_DEEP"; const researchAvoided = current.researchAvoided + (avoided ? 1 : 0); const gateConsidered = current.gateConsidered + 1; @@ -62549,7 +62788,7 @@ function recordResearchGateTelemetry(workspace, decision, now5, phase) { } } } : {}, - updatedAt: now5.toISOString() + updatedAt: now52.toISOString() }); } function addUsage(current, usage) { @@ -62563,8 +62802,8 @@ function addUsage(current, usage) { reports: current.reportedUsage.reports + 1 }; } -function recordResearchReuseTelemetry(workspace, now5, phase) { - const current = readResearchTelemetry(workspace, now5).telemetry; +function recordResearchReuseTelemetry(workspace, now52, phase) { + const current = readResearchTelemetry(workspace, now52).telemetry; return writeTelemetry(workspace, { ...current, reusedReports: current.reusedReports + 1, @@ -62574,19 +62813,19 @@ function recordResearchReuseTelemetry(workspace, now5, phase) { [phase]: { ...current.byPhase[phase], reused: current.byPhase[phase].reused + 1 } } } : {}, - updatedAt: now5.toISOString() + updatedAt: now52.toISOString() }); } -function recordResearchBudgetRefusalTelemetry(workspace, now5) { - const current = readResearchTelemetry(workspace, now5).telemetry; +function recordResearchBudgetRefusalTelemetry(workspace, now52) { + const current = readResearchTelemetry(workspace, now52).telemetry; return writeTelemetry(workspace, { ...current, budgetRefusals: current.budgetRefusals + 1, - updatedAt: now5.toISOString() + updatedAt: now52.toISOString() }); } -function recordResearchProviderTelemetry(workspace, result, durationMs, now5, depth, phase) { - const current = readResearchTelemetry(workspace, now5).telemetry; +function recordResearchProviderTelemetry(workspace, result, durationMs, now52, depth, phase) { + const current = readResearchTelemetry(workspace, now52).telemetry; const report = result.ok ? result.report : void 0; return writeTelemetry(workspace, { ...current, @@ -62608,15 +62847,15 @@ function recordResearchProviderTelemetry(workspace, result, durationMs, now5, de } : {}, reportedUsage: addUsage(current, report?.usage), totalDurationMs: current.totalDurationMs + Math.max(0, Math.trunc(durationMs)), - updatedAt: now5.toISOString() + updatedAt: now52.toISOString() }); } -function recordResearchDecisionPreparedTelemetry(workspace, now5) { - const current = readResearchTelemetry(workspace, now5).telemetry; +function recordResearchDecisionPreparedTelemetry(workspace, now52) { + const current = readResearchTelemetry(workspace, now52).telemetry; return writeTelemetry(workspace, { ...current, decisionsPreparedWithResearch: current.decisionsPreparedWithResearch + 1, - updatedAt: now5.toISOString() + updatedAt: now52.toISOString() }); } function nowOf(deps) { @@ -62691,13 +62930,13 @@ function evaluateAndRecordResearchGate(deps, input, phase) { return result; } async function getResearchProviderHealth(deps, signal) { - const now5 = nowOf(deps).toISOString(); + const now52 = nowOf(deps).toISOString(); const policy = deps.config.research; if (!policy.enabled) { return { provider: policy.provider, status: "UNKNOWN", - checkedAt: now5, + checkedAt: now52, detail: "research is disabled; no provider health request was made" }; } @@ -62705,7 +62944,7 @@ async function getResearchProviderHealth(deps, signal) { return { provider: policy.provider, status: "UNKNOWN", - checkedAt: now5, + checkedAt: now52, detail: "the selected research provider is disabled; no health request was made" }; } @@ -62714,7 +62953,7 @@ async function getResearchProviderHealth(deps, signal) { return { provider: policy.provider, status: "UNKNOWN", - checkedAt: now5, + checkedAt: now52, detail: `no ResearchBridge is registered for provider ${policy.provider}` }; } @@ -63325,11 +63564,11 @@ var quotaForecastSchema = external_exports.object({ /** The forecast's own clock reading. */ forecastAt: isoText }).passthrough(); -function timeToResetMs(resetAt, now5) { +function timeToResetMs(resetAt, now52) { if (resetAt === null) return null; const parsed = Date.parse(resetAt); if (Number.isNaN(parsed)) return null; - return Math.max(0, parsed - now5.getTime()); + return Math.max(0, parsed - now52.getTime()); } var shortText15 = external_exports.string().min(1).max(200); var schedulingDecisionSchema = external_exports.object({ @@ -63480,11 +63719,11 @@ var apiSpendApprovalSchema = external_exports.object({ /** The attempt that consumed this approval, when one did. */ consumedByAttemptId: shortText16.nullable().default(null) }).passthrough(); -function assessSnapshotFreshness(snapshot2, now5, staleMs) { +function assessSnapshotFreshness(snapshot2, now52, staleMs) { if (snapshot2 === null || snapshot2.remainingRatio === null) return "UNKNOWN"; const observed = Date.parse(snapshot2.observedAt); if (Number.isNaN(observed)) return "UNKNOWN"; - return now5.getTime() - observed > staleMs ? "STALE" : "FRESH"; + return now52.getTime() - observed > staleMs ? "STALE" : "FRESH"; } function combineFreshness(fiveHour, weekly) { if (fiveHour === "UNKNOWN" && weekly === "UNKNOWN") return "UNKNOWN"; @@ -63510,14 +63749,14 @@ function deriveSchedulerMode(input) { return "NORMAL"; } function buildQuotaForecast(input) { - const { now: now5, policy } = input; - const fiveHourFreshness = assessSnapshotFreshness(input.fiveHour, now5, policy.telemetryStaleMs); - const weeklyFreshness = assessSnapshotFreshness(input.weekly, now5, policy.telemetryStaleMs); + const { now: now52, policy } = input; + const fiveHourFreshness = assessSnapshotFreshness(input.fiveHour, now52, policy.telemetryStaleMs); + const weeklyFreshness = assessSnapshotFreshness(input.weekly, now52, policy.telemetryStaleMs); const freshness = combineFreshness(fiveHourFreshness, weeklyFreshness); const fiveHourRemaining = input.fiveHour?.remainingRatio ?? null; const weeklyRemaining = input.weekly?.remainingRatio ?? null; - const timeToFiveHour = timeToResetMs(input.fiveHour?.resetAt ?? null, now5); - const timeToWeekly = timeToResetMs(input.weekly?.resetAt ?? null, now5); + const timeToFiveHour = timeToResetMs(input.fiveHour?.resetAt ?? null, now52); + const timeToWeekly = timeToResetMs(input.weekly?.resetAt ?? null, now52); const burnRate = input.observedFiveHourBurnRatePerMinute ?? null; const projected = burnRate !== null && timeToFiveHour !== null ? Math.min(1, burnRate * (timeToFiveHour / 6e4)) : null; const schedulerMode = deriveSchedulerMode({ @@ -63540,7 +63779,7 @@ function buildQuotaForecast(input) { schedulerMode, telemetryFreshness: freshness, observedAt: observedTimes[0] ?? null, - forecastAt: now5.toISOString() + forecastAt: now52.toISOString() }); } function formatDuration(ms) { @@ -72701,20 +72940,20 @@ function registerRunResources(server, context) { } // ../../packages/drift/dist/index.js -var import_fs29 = require("fs"); -var import_path31 = __toESM(require("path"), 1); -var import_picomatch = __toESM(require_picomatch2(), 1); -var import_fs30 = require("fs"); -var import_path32 = __toESM(require("path"), 1); var import_fs31 = require("fs"); var import_path33 = __toESM(require("path"), 1); +var import_picomatch = __toESM(require_picomatch2(), 1); var import_fs32 = require("fs"); var import_path34 = __toESM(require("path"), 1); var import_fs33 = require("fs"); var import_path35 = __toESM(require("path"), 1); var import_fs34 = require("fs"); -var import_crypto15 = require("crypto"); var import_path36 = __toESM(require("path"), 1); +var import_fs35 = require("fs"); +var import_path37 = __toESM(require("path"), 1); +var import_fs36 = require("fs"); +var import_crypto15 = require("crypto"); +var import_path38 = __toESM(require("path"), 1); var taskEvidenceSchema = external_exports.object({ taskId: external_exports.string().min(1), status: external_exports.enum(["recorded", "verified", "rejected"]), @@ -72815,24 +73054,24 @@ var verificationPolicySchema = external_exports.object({ } }); function policyDir(workspace) { - return import_path31.default.join(workspace.sidecarDir, "policies"); + return import_path33.default.join(workspace.sidecarDir, "policies"); } function policyPath(workspace, specName) { - const resolved2 = import_path31.default.resolve(policyDir(workspace), `${specName}.json`); - const relative = import_path31.default.relative(workspace.rootDir, resolved2); - if (relative.startsWith("..") || import_path31.default.isAbsolute(relative)) { - return import_path31.default.join(policyDir(workspace), "invalid-spec-name.json"); + const resolved2 = import_path33.default.resolve(policyDir(workspace), `${specName}.json`); + const relative = import_path33.default.relative(workspace.rootDir, resolved2); + if (relative.startsWith("..") || import_path33.default.isAbsolute(relative)) { + return import_path33.default.join(policyDir(workspace), "invalid-spec-name.json"); } return resolved2; } function readVerificationPolicy(workspace, specName, explicitPath) { - const filePath = explicitPath !== void 0 ? import_path31.default.resolve(workspace.rootDir, explicitPath) : policyPath(workspace, specName); - if (!(0, import_fs29.existsSync)(filePath)) { + const filePath = explicitPath !== void 0 ? import_path33.default.resolve(workspace.rootDir, explicitPath) : policyPath(workspace, specName); + if (!(0, import_fs31.existsSync)(filePath)) { return { path: filePath, exists: false, diagnostics: [] }; } let parsed; try { - parsed = JSON.parse((0, import_fs29.readFileSync)(filePath, "utf8")); + parsed = JSON.parse((0, import_fs31.readFileSync)(filePath, "utf8")); } catch (cause) { return { path: filePath, @@ -72895,7 +73134,7 @@ function resolveEffectivePolicy(workspace, specName, options = {}) { const storedMode = policy?.mode ?? "advisory"; const strictFromCli = options.strict === true && storedMode !== "strict"; const mode = options.strict === true ? "strict" : storedMode; - const workspaceRelativePolicyPath = import_path31.default.relative(workspace.rootDir, read.path).split(import_path31.default.sep).join("/"); + const workspaceRelativePolicyPath = import_path33.default.relative(workspace.rootDir, read.path).split(import_path33.default.sep).join("/"); return { specName, mode, @@ -73039,33 +73278,33 @@ function mergeNumstat(files, stats) { function sniffBinary(absolutePath) { let fd; try { - fd = (0, import_fs30.openSync)(absolutePath, "r"); + fd = (0, import_fs32.openSync)(absolutePath, "r"); const buffer = Buffer.alloc(8e3); - const bytesRead = (0, import_fs30.readSync)(fd, buffer, 0, buffer.length, 0); + const bytesRead = (0, import_fs32.readSync)(fd, buffer, 0, buffer.length, 0); return buffer.subarray(0, bytesRead).includes(0); } catch { return false; } finally { - if (fd !== void 0) (0, import_fs30.closeSync)(fd); + if (fd !== void 0) (0, import_fs32.closeSync)(fd); } } function flagSymlinkEscapes(repoRoot, files) { const resolvedRoot = (() => { try { - return (0, import_fs30.realpathSync)(repoRoot); + return (0, import_fs32.realpathSync)(repoRoot); } catch { - return import_path32.default.resolve(repoRoot); + return import_path34.default.resolve(repoRoot); } })(); for (const file of files) { if (file.changeType === "deleted") continue; - const absolute = import_path32.default.join(repoRoot, file.path.split("/").join(import_path32.default.sep)); + const absolute = import_path34.default.join(repoRoot, file.path.split("/").join(import_path34.default.sep)); try { - const stats = (0, import_fs30.lstatSync)(absolute); + const stats = (0, import_fs32.lstatSync)(absolute); if (!stats.isSymbolicLink()) continue; - const target = (0, import_fs30.realpathSync)(absolute); - const relative = import_path32.default.relative(resolvedRoot, target); - if (relative.startsWith("..") || import_path32.default.isAbsolute(relative)) { + const target = (0, import_fs32.realpathSync)(absolute); + const relative = import_path34.default.relative(resolvedRoot, target); + if (relative.startsWith("..") || import_path34.default.isAbsolute(relative)) { file.symlinkOutsideRepository = true; } } catch { @@ -73193,7 +73432,7 @@ async function resolveComparison(repoRoot, request, options = {}) { const known = new Set(files.map((file) => file.path)); for (const token of untracked.stdout.split("\0")) { if (token.length === 0 || known.has(token)) continue; - const absolute = import_path32.default.join(repoRoot, token.split("/").join(import_path32.default.sep)); + const absolute = import_path34.default.join(repoRoot, token.split("/").join(import_path34.default.sep)); files.push({ path: token, changeType: "untracked", @@ -73273,9 +73512,9 @@ function specMatchReasons(specName, policy, validEvidencePaths, designPathRefere function readSpecEvidenceRecords(workspace, specName) { const byTask = /* @__PURE__ */ new Map(); let invalidRecordCount = 0; - const specDir = import_path33.default.join(workspace.sidecarDir, "evidence", specName); - if ((0, import_fs31.existsSync)(specDir)) { - const taskDirs = (0, import_fs31.readdirSync)(specDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort((a2, b) => a2.localeCompare(b, "en")); + const specDir = import_path35.default.join(workspace.sidecarDir, "evidence", specName); + if ((0, import_fs33.existsSync)(specDir)) { + const taskDirs = (0, import_fs33.readdirSync)(specDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort((a2, b) => a2.localeCompare(b, "en")); for (const taskDir of taskDirs) { const { records, diagnostics } = listTaskEvidence(workspace, specName, taskDir); invalidRecordCount += diagnostics.length; @@ -73289,7 +73528,7 @@ function readSpecEvidenceRecords(workspace, specName) { return { byTask, invalidRecordCount }; } async function buildSpecVerificationContext(options) { - const { workspace, folder, comparison, caches, now: now5 } = options; + const { workspace, folder, comparison, caches, now: now6 } = options; const spec = analyzeSpec(workspace, folder); const evaluation = spec.state !== void 0 ? evaluateWorkflow(workspace, spec.state) : void 0; const policy = resolveEffectivePolicy(workspace, folder.name, { @@ -73322,7 +73561,7 @@ async function buildSpecVerificationContext(options) { } if (effective("tasks") && tasksStage !== void 0) { const planHash2 = typeof tasksStage.approvedPlanHash === "string" ? tasksStage.approvedPlanHash : tryTaskPlanHashOfFile( - import_path33.default.join(workspace.rootDir, tasksStage.file.split("/").join(import_path33.default.sep)) + import_path35.default.join(workspace.rootDir, tasksStage.file.split("/").join(import_path35.default.sep)) ); if (planHash2 !== void 0) approved.tasksPlanHash = planHash2; } @@ -73344,7 +73583,7 @@ async function buildSpecVerificationContext(options) { approved, approvedAt, tasks: currentTasks, - now: now5 + now: now6 }; const recordedShas = /* @__PURE__ */ new Set(); for (const records of rawEvidence.byTask.values()) { @@ -73396,7 +73635,7 @@ async function buildSpecVerificationContext(options) { freshness, matchedBy: options.matchedBy ?? [], readBaseContent: makeBaseContentReader(workspace, comparison, caches, options.signal), - now: now5 + now: now6 }; } async function orchestrateVerificationCommands(options) { @@ -73544,7 +73783,7 @@ async function evaluateGlobalRules(rules, context) { return { diagnostics, disabledRules }; } function repoRelative2(workspace, absolutePath) { - return import_path34.default.relative(workspace.rootDir, absolutePath).split(import_path34.default.sep).join("/"); + return import_path36.default.relative(workspace.rootDir, absolutePath).split(import_path36.default.sep).join("/"); } function isSpecInfraPath(candidate) { return candidate === ".git" || candidate.startsWith(".git/") || candidate.startsWith(".kiro/") || candidate.startsWith(".specbridge/"); @@ -74225,14 +74464,14 @@ var sbv018 = { if (designDocument === void 0) return []; const designFile = designDocument.filePath; const designRepoPath = designFile !== void 0 ? repoRelative2(context.workspace, designFile) : void 0; - const specDir = import_path34.default.join(context.workspace.rootDir, ".kiro", "specs", context.specName); + const specDir = import_path36.default.join(context.workspace.rootDir, ".kiro", "specs", context.specName); return context.traceability.designPathReferences.filter((reference) => !reference.isGlob).filter((reference) => { - const fromRoot = import_path34.default.join( + const fromRoot = import_path36.default.join( context.workspace.rootDir, - reference.path.split("/").join(import_path34.default.sep) + reference.path.split("/").join(import_path36.default.sep) ); - const fromSpecDir = import_path34.default.join(specDir, reference.path.split("/").join(import_path34.default.sep)); - return !(0, import_fs32.existsSync)(fromRoot) && !(0, import_fs32.existsSync)(fromSpecDir); + const fromSpecDir = import_path36.default.join(specDir, reference.path.split("/").join(import_path36.default.sep)); + return !(0, import_fs34.existsSync)(fromRoot) && !(0, import_fs34.existsSync)(fromSpecDir); }).map( (reference) => makeDiagnostic({ rule: this, @@ -74476,9 +74715,9 @@ function loadSpecMatchingInfo(workspace, folder, options) { } } const evidencePaths = /* @__PURE__ */ new Set(); - const evidenceDir2 = import_path35.default.join(workspace.sidecarDir, "evidence", folder.name); - if ((0, import_fs33.existsSync)(evidenceDir2)) { - for (const entry of (0, import_fs34.readdirSync)(evidenceDir2, { withFileTypes: true })) { + const evidenceDir2 = import_path37.default.join(workspace.sidecarDir, "evidence", folder.name); + if ((0, import_fs35.existsSync)(evidenceDir2)) { + for (const entry of (0, import_fs36.readdirSync)(evidenceDir2, { withFileTypes: true })) { if (!entry.isDirectory()) continue; const { records } = listTaskEvidence(workspace, folder.name, entry.name); for (const record4 of records) { @@ -74535,7 +74774,7 @@ var VERIFY_EXIT_CODES = { commandTimeout: 5 }; async function verifySpecs(request) { - const now5 = (request.clock ?? (() => /* @__PURE__ */ new Date()))(); + const now6 = (request.clock ?? (() => /* @__PURE__ */ new Date()))(); const verificationId = (request.idFactory ?? import_crypto15.randomUUID)(); const workspace = request.workspace; const configRead = readAgentConfig(workspace); @@ -74577,7 +74816,7 @@ async function verifySpecs(request) { ...request.strict !== void 0 ? { strict: request.strict } : {}, ...request.explicitPolicyPath !== void 0 ? { explicitPolicyPath: request.explicitPolicyPath } : {}, ...matchedBy !== void 0 ? { matchedBy: dedupe(matchedBy) } : {}, - now: now5, + now: now6, ...request.signal !== void 0 ? { signal: request.signal } : {} }) ); @@ -74587,8 +74826,8 @@ async function verifySpecs(request) { let artifactsDir; const ensureArtifactsDir = () => { if (artifactsDir === void 0) { - const base = request.reportsDir ?? import_path36.default.join(workspace.sidecarDir, "reports"); - artifactsDir = import_path36.default.join(base, verificationId); + const base = request.reportsDir ?? import_path38.default.join(workspace.sidecarDir, "reports"); + artifactsDir = import_path38.default.join(base, verificationId); } return artifactsDir; }; @@ -74611,8 +74850,8 @@ async function verifySpecs(request) { onCommandFinished: (result, stdout, stderr) => { const dir = ensureArtifactsDir(); const safeName = result.name.replace(/[^A-Za-z0-9._-]+/g, "-"); - writeFileAtomic(import_path36.default.join(dir, "commands", `${safeName}.stdout.log`), stdout); - writeFileAtomic(import_path36.default.join(dir, "commands", `${safeName}.stderr.log`), stderr); + writeFileAtomic(import_path38.default.join(dir, "commands", `${safeName}.stdout.log`), stdout); + writeFileAtomic(import_path38.default.join(dir, "commands", `${safeName}.stderr.log`), stderr); } } : {} }) : { mode: "none", commands: [], missingRequired: [] }; @@ -74630,7 +74869,7 @@ async function verifySpecs(request) { unmappedFiles: affectedResult.unmapped, ambiguousFiles: affectedResult.ambiguous, commands, - now: now5 + now: now6 }; const globalResult = await evaluateGlobalRules(rules, globalContext); const selectedNames = new Set(specContexts.map((context) => context.specName)); @@ -74742,7 +74981,7 @@ async function verifySpecs(request) { schemaVersion: VERIFICATION_REPORT_SCHEMA_VERSION, tool: { name: "specbridge", version: request.toolVersion }, verificationId, - createdAt: now5.toISOString(), + createdAt: now6.toISOString(), comparison: comparison.descriptor, selection: { mode: selectionMode, @@ -74763,7 +75002,7 @@ async function verifySpecs(request) { verificationReportSchema.parse(report); if (persistArtifacts && artifactsDir !== void 0) { writeFileAtomic( - import_path36.default.join(artifactsDir, "report.json"), + import_path38.default.join(artifactsDir, "report.json"), `${JSON.stringify(report, null, 2)} ` ); @@ -77987,17 +78226,17 @@ var TEMPLATE_PROVIDER_TEMPLATES_DIR = "templates"; var MAX_TEMPLATE_PROVIDER_PACKS = 20; // ../../packages/extensions/dist/index.js -var import_fs38 = require("fs"); -var import_path41 = __toESM(require("path"), 1); +var import_fs40 = require("fs"); +var import_path43 = __toESM(require("path"), 1); // ../../packages/templates/dist/index.js -var import_fs35 = require("fs"); -var import_path37 = __toESM(require("path"), 1); -var import_fs36 = require("fs"); -var import_path38 = __toESM(require("path"), 1); var import_fs37 = require("fs"); var import_path39 = __toESM(require("path"), 1); +var import_fs38 = require("fs"); var import_path40 = __toESM(require("path"), 1); +var import_fs39 = require("fs"); +var import_path41 = __toESM(require("path"), 1); +var import_path42 = __toESM(require("path"), 1); var SPECBRIDGE_VERSION = "1.0.0"; var TEMPLATE_ERROR_CODES = { SBT001: "template not found", @@ -78826,11 +79065,11 @@ function readTemplatePackDirectory(dir) { { path: currentDir } ); } - const entries = (0, import_fs35.readdirSync)(currentDir, { withFileTypes: true }).sort( + const entries = (0, import_fs37.readdirSync)(currentDir, { withFileTypes: true }).sort( (a2, b) => a2.name.localeCompare(b.name, "en") ); for (const entry of entries) { - const entryPath = import_path37.default.join(currentDir, entry.name); + const entryPath = import_path39.default.join(currentDir, entry.name); const entryRelative = relative === "" ? entry.name : `${relative}/${entry.name}`; const stat = statNoFollow(entryPath); if (stat.isSymbolicLink()) { @@ -78882,7 +79121,7 @@ function readTemplatePackDirectory(dir) { { path: dir } ); } - const buffer = (0, import_fs35.readFileSync)(entryPath); + const buffer = (0, import_fs37.readFileSync)(entryPath); const text15 = buffer.toString("utf8"); if (!Buffer.from(text15, "utf8").equals(buffer)) { throw new TemplateError( @@ -78908,7 +79147,7 @@ function readTemplatePackDirectory(dir) { } function statNoFollow(target) { try { - return (0, import_fs35.lstatSync)(target); + return (0, import_fs37.lstatSync)(target); } catch (cause) { throw new TemplateError( "SBT007", @@ -79186,7 +79425,7 @@ var BUILTIN_TEMPLATE_PACKS = [ } ]; function projectTemplatesDir(workspace) { - return import_path38.default.join(workspace.sidecarDir, "templates"); + return import_path40.default.join(workspace.sidecarDir, "templates"); } function builtinEntries(options) { const entries = []; @@ -79211,11 +79450,11 @@ function builtinEntries(options) { function projectEntries(workspace, options, diagnostics) { if (workspace === void 0) return []; const dir = projectTemplatesDir(workspace); - if (!(0, import_fs36.existsSync)(dir)) return []; + if (!(0, import_fs38.existsSync)(dir)) return []; const entries = []; let names; try { - names = (0, import_fs36.readdirSync)(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.isSymbolicLink()).map((entry) => entry.name).sort((a2, b) => a2.localeCompare(b, "en")); + names = (0, import_fs38.readdirSync)(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.isSymbolicLink()).map((entry) => entry.name).sort((a2, b) => a2.localeCompare(b, "en")); } catch (cause) { diagnostics.push({ severity: "warning", @@ -79225,7 +79464,7 @@ function projectEntries(workspace, options, diagnostics) { return []; } for (const name of names) { - const packDir = import_path38.default.join(dir, name); + const packDir = import_path40.default.join(dir, name); let pack; try { const data = readTemplatePackDirectory(packDir); @@ -79468,7 +79707,7 @@ var templateRecordSchema = external_exports.discriminatedUnion("type", [ templateScaffoldRecordSchema ]); function templateRecordsPath(workspace) { - return import_path39.default.join(workspace.sidecarDir, TEMPLATE_RECORDS_FILE_NAME); + return import_path41.default.join(workspace.sidecarDir, TEMPLATE_RECORDS_FILE_NAME); } var recordCounter = 0; function newTemplateRecordId(clock = systemClock) { @@ -79479,8 +79718,8 @@ function appendTemplateRecord(workspace, record4) { const validated = templateRecordSchema.parse(record4); const filePath = templateRecordsPath(workspace); try { - (0, import_fs37.mkdirSync)(workspace.sidecarDir, { recursive: true }); - (0, import_fs37.appendFileSync)(filePath, `${JSON.stringify(validated)} + (0, import_fs39.mkdirSync)(workspace.sidecarDir, { recursive: true }); + (0, import_fs39.appendFileSync)(filePath, `${JSON.stringify(validated)} `, "utf8"); } catch (cause) { throw ioError("append template record to", filePath, cause); @@ -79647,7 +79886,7 @@ function planTemplateApplication(workspace, catalog, request, clock = systemCloc }; } function toPosix2(relative) { - return relative.split(import_path40.default.sep).join("/"); + return relative.split(import_path42.default.sep).join("/"); } function executeTemplateApplication(workspace, plan, clock = systemClock, recordId) { let creation; @@ -79677,8 +79916,8 @@ function executeTemplateApplication(workspace, plan, clock = systemClock, record })), variableNames: plan.variableNames, createdPaths: [ - ...creation.writtenFiles.map((file) => toPosix2(import_path40.default.relative(workspace.rootDir, file))), - toPosix2(import_path40.default.relative(workspace.rootDir, creation.statePath)) + ...creation.writtenFiles.map((file) => toPosix2(import_path42.default.relative(workspace.rootDir, file))), + toPosix2(import_path42.default.relative(workspace.rootDir, creation.statePath)) ] }; appendTemplateRecord(workspace, record4); @@ -79687,13 +79926,13 @@ function executeTemplateApplication(workspace, plan, clock = systemClock, record // ../../packages/extensions/dist/index.js var import_crypto17 = require("crypto"); -var import_fs39 = require("fs"); -var import_path42 = __toESM(require("path"), 1); -var import_child_process = require("child_process"); -var import_fs40 = require("fs"); -var import_path43 = __toESM(require("path"), 1); var import_fs41 = require("fs"); var import_path44 = __toESM(require("path"), 1); +var import_child_process = require("child_process"); +var import_fs42 = require("fs"); +var import_path45 = __toESM(require("path"), 1); +var import_fs43 = require("fs"); +var import_path46 = __toESM(require("path"), 1); var ExtensionError = class extends SpecBridgeError { extensionCode; /** Actionable next step, always present. */ @@ -79937,7 +80176,7 @@ var FORBIDDEN_LIFECYCLE_SCRIPTS = [ "postuninstall" ]; function readExtensionPackageDirectory(dir) { - const rootStat = (0, import_fs38.lstatSync)(dir, { throwIfNoEntry: false }); + const rootStat = (0, import_fs40.lstatSync)(dir, { throwIfNoEntry: false }); if (rootStat === void 0 || !rootStat.isDirectory()) { throw new ExtensionError( "SBE008", @@ -79962,7 +80201,7 @@ function readExtensionPackageDirectory(dir) { "Flatten the package layout." ); } - for (const entry of (0, import_fs38.readdirSync)(currentDir, { withFileTypes: true })) { + for (const entry of (0, import_fs40.readdirSync)(currentDir, { withFileTypes: true })) { const relativePath = relativePrefix === "" ? entry.name : `${relativePrefix}/${entry.name}`; if (entry.isSymbolicLink()) { throw new ExtensionError( @@ -79988,7 +80227,7 @@ function readExtensionPackageDirectory(dir) { "Remove the directory before validating or packaging." ); } - walk(import_path41.default.join(currentDir, entry.name), relativePath, depth + 1); + walk(import_path43.default.join(currentDir, entry.name), relativePath, depth + 1); continue; } if (!entry.isFile()) { @@ -80005,7 +80244,7 @@ function readExtensionPackageDirectory(dir) { "Reduce the package contents." ); } - const content = (0, import_fs38.readFileSync)(import_path41.default.join(currentDir, entry.name)); + const content = (0, import_fs40.readFileSync)(import_path43.default.join(currentDir, entry.name)); totalBytes += content.length; if (totalBytes > EXTENSION_LIMITS.maxExtractedTotalBytes) { throw new ExtensionError( @@ -80278,10 +80517,10 @@ var EXTENSION_STATE_FILE_NAME = "state.json"; var EXTENSION_GRANTS_FILE_NAME = "grants.json"; var EXTENSION_STATE_SCHEMA_VERSION = "1.0.0"; function extensionsDir(workspace) { - return import_path42.default.join(workspace.sidecarDir, EXTENSIONS_DIR_NAME); + return import_path44.default.join(workspace.sidecarDir, EXTENSIONS_DIR_NAME); } function installedRootDir(workspace) { - return import_path42.default.join(extensionsDir(workspace), "installed"); + return import_path44.default.join(extensionsDir(workspace), "installed"); } function installedVersionDir(workspace, id, version2) { if (!validateExtensionId(id).valid || parseSemver(version2) === void 0) { @@ -80291,7 +80530,7 @@ function installedVersionDir(workspace, id, version2) { "Use a valid extension ID and X.Y.Z version." ); } - const dir = import_path42.default.join(installedRootDir(workspace), id, version2); + const dir = import_path44.default.join(installedRootDir(workspace), id, version2); assertInsideWorkspace(workspace.rootDir, dir); return dir; } @@ -80335,12 +80574,12 @@ function emptyPermissionGrants() { return { schemaVersion: EXTENSION_STATE_SCHEMA_VERSION, grants: {} }; } function readValidatedJson(filePath, schema, empty, label) { - if (!(0, import_fs39.existsSync)(filePath)) { + if (!(0, import_fs41.existsSync)(filePath)) { return { value: empty, diagnostics: [], exists: false }; } let text15; try { - text15 = (0, import_fs39.readFileSync)(filePath, "utf8"); + text15 = (0, import_fs41.readFileSync)(filePath, "utf8"); } catch (cause) { return { value: empty, @@ -80390,10 +80629,10 @@ function readValidatedJson(filePath, schema, empty, label) { return { value: result.data, diagnostics: [], exists: true }; } function extensionStatePath(workspace) { - return import_path42.default.join(extensionsDir(workspace), EXTENSION_STATE_FILE_NAME); + return import_path44.default.join(extensionsDir(workspace), EXTENSION_STATE_FILE_NAME); } function permissionGrantsPath(workspace) { - return import_path42.default.join(extensionsDir(workspace), EXTENSION_GRANTS_FILE_NAME); + return import_path44.default.join(extensionsDir(workspace), EXTENSION_GRANTS_FILE_NAME); } function readExtensionState(workspace) { const { value, diagnostics, exists } = readValidatedJson( @@ -80574,9 +80813,9 @@ function resolveEntrypoint(installedDir, entrypoint) { if (problem !== void 0) { throw new ExtensionError("SBE012", `entrypoint "${entrypoint}": ${problem}.`, "Fix the extension manifest."); } - const resolved2 = import_path43.default.join(installedDir, ...entrypoint.split("/")); - const relative = import_path43.default.relative(installedDir, resolved2); - if (relative.startsWith("..") || import_path43.default.isAbsolute(relative)) { + const resolved2 = import_path45.default.join(installedDir, ...entrypoint.split("/")); + const relative = import_path45.default.relative(installedDir, resolved2); + if (relative.startsWith("..") || import_path45.default.isAbsolute(relative)) { throw new ExtensionError( "SBE012", `entrypoint "${entrypoint}" escapes the installed extension directory.`, @@ -80584,9 +80823,9 @@ function resolveEntrypoint(installedDir, entrypoint) { ); } let current = installedDir; - for (const segment of relative.split(import_path43.default.sep)) { - current = import_path43.default.join(current, segment); - const stat = (0, import_fs40.lstatSync)(current, { throwIfNoEntry: false }); + for (const segment of relative.split(import_path45.default.sep)) { + current = import_path45.default.join(current, segment); + const stat = (0, import_fs42.lstatSync)(current, { throwIfNoEntry: false }); if (stat === void 0) { throw new ExtensionError( "SBE012", @@ -80602,7 +80841,7 @@ function resolveEntrypoint(installedDir, entrypoint) { ); } } - const finalStat = (0, import_fs40.lstatSync)(resolved2, { throwIfNoEntry: false }); + const finalStat = (0, import_fs42.lstatSync)(resolved2, { throwIfNoEntry: false }); if (finalStat === void 0 || !finalStat.isFile()) { throw new ExtensionError( "SBE012", @@ -81133,14 +81372,14 @@ async function probeExtensionHandshake(enabled, options = {}) { } function compatibilityOf(workspace, record4, specbridgeVersion) { try { - const manifestPath = import_path44.default.join( + const manifestPath = import_path46.default.join( installedVersionDir(workspace, record4.id, record4.version), EXTENSION_MANIFEST_FILE_NAME ); - if (!(0, import_fs41.existsSync)(manifestPath)) { + if (!(0, import_fs43.existsSync)(manifestPath)) { return { compatibility: "unknown", deprecated: false }; } - const parsed = parseExtensionManifest((0, import_fs41.readFileSync)(manifestPath, "utf8")); + const parsed = parseExtensionManifest((0, import_fs43.readFileSync)(manifestPath, "utf8")); if (parsed.manifest === void 0) { return { compatibility: "unknown", deprecated: false }; } @@ -82518,10 +82757,10 @@ function registerTemplateApplyTool(server, context) { } // ../../packages/registry/dist/index.js -var import_fs42 = require("fs"); -var import_path45 = __toESM(require("path"), 1); -var import_fs43 = require("fs"); -var import_path46 = __toESM(require("path"), 1); +var import_fs44 = require("fs"); +var import_path47 = __toESM(require("path"), 1); +var import_fs45 = require("fs"); +var import_path48 = __toESM(require("path"), 1); var BUILTIN_REGISTRY_INDEX_JSON = '{\n "schemaVersion": "1.0.0",\n "name": "specbridge-examples",\n "updatedAt": "2026-01-01T00:00:00.000Z",\n "extensions": [\n {\n "id": "example-analyzer",\n "displayName": "example-analyzer",\n "description": "Deterministic spec diagnostics contributed by the example-analyzer analyzer extension.",\n "kind": "analyzer",\n "latestVersion": "1.0.0",\n "versions": [\n {\n "version": "1.0.0",\n "archiveUrl": "https://example.invalid/specbridge-extensions/example-analyzer-1.0.0.specbridge-extension.zip",\n "sha256": "e6e0948a315b09e53bd18997dce21888af9adbb3997fbf82955399dcf3252a19",\n "manifest": {\n "protocolVersion": "1.0.0",\n "compatibility": {\n "specbridge": ">=0.7.1 <2.0.0"\n },\n "permissions": {\n "specRead": true,\n "repositoryRead": false,\n "repositoryWrite": false,\n "network": false,\n "childProcess": false,\n "environmentVariables": []\n }\n }\n }\n ],\n "repository": "https://github.com/HelloThisWorld/specbridge",\n "license": "MIT",\n "keywords": [\n "analyzer",\n "specbridge-extension"\n ]\n },\n {\n "id": "example-exporter",\n "displayName": "example-exporter",\n "description": "Candidate export files produced by the example-exporter exporter extension.",\n "kind": "exporter",\n "latestVersion": "1.0.0",\n "versions": [\n {\n "version": "1.0.0",\n "archiveUrl": "https://example.invalid/specbridge-extensions/example-exporter-1.0.0.specbridge-extension.zip",\n "sha256": "68f42755a4e56d0e318012ec8c0e3b093e44429182ca93b02d9fb4ce2ec308a3",\n "manifest": {\n "protocolVersion": "1.0.0",\n "compatibility": {\n "specbridge": ">=0.7.1 <2.0.0"\n },\n "permissions": {\n "specRead": true,\n "repositoryRead": false,\n "repositoryWrite": false,\n "network": false,\n "childProcess": false,\n "environmentVariables": []\n }\n }\n }\n ],\n "repository": "https://github.com/HelloThisWorld/specbridge",\n "license": "MIT",\n "keywords": [\n "exporter",\n "specbridge-extension"\n ]\n },\n {\n "id": "example-runner",\n "displayName": "example-runner",\n "description": "An out-of-process runner adapter provided by the example-runner extension.",\n "kind": "runner",\n "latestVersion": "1.0.0",\n "versions": [\n {\n "version": "1.0.0",\n "archiveUrl": "https://example.invalid/specbridge-extensions/example-runner-1.0.0.specbridge-extension.zip",\n "sha256": "5ef3db937d872bfe09495695e9ecb0a3cf3beaf9e006fabdc2972ef55ace80ef",\n "manifest": {\n "protocolVersion": "1.0.0",\n "compatibility": {\n "specbridge": ">=0.7.1 <2.0.0"\n },\n "permissions": {\n "specRead": true,\n "repositoryRead": true,\n "repositoryWrite": true,\n "network": false,\n "childProcess": false,\n "environmentVariables": []\n }\n }\n }\n ],\n "repository": "https://github.com/HelloThisWorld/specbridge",\n "license": "MIT",\n "keywords": [\n "runner",\n "specbridge-extension"\n ]\n },\n {\n "id": "example-template-provider",\n "displayName": "example-template-provider",\n "description": "Spec template packs contributed by the example-template-provider template-provider extension.",\n "kind": "template-provider",\n "latestVersion": "1.0.0",\n "versions": [\n {\n "version": "1.0.0",\n "archiveUrl": "https://example.invalid/specbridge-extensions/example-template-provider-1.0.0.specbridge-extension.zip",\n "sha256": "f7caa11a13473f0891cc8d237ec4f9f2962a2dd1bd2baba4e9d01570de29044b",\n "manifest": {\n "protocolVersion": "1.0.0",\n "compatibility": {\n "specbridge": ">=0.7.1 <2.0.0"\n },\n "permissions": {\n "specRead": false,\n "repositoryRead": false,\n "repositoryWrite": false,\n "network": false,\n "childProcess": false,\n "environmentVariables": []\n }\n }\n }\n ],\n "repository": "https://github.com/HelloThisWorld/specbridge",\n "license": "MIT",\n "keywords": [\n "template-provider",\n "specbridge-extension"\n ]\n },\n {\n "id": "example-verifier",\n "displayName": "example-verifier",\n "description": "Verification diagnostics contributed by the example-verifier verifier extension.",\n "kind": "verifier",\n "latestVersion": "1.0.0",\n "versions": [\n {\n "version": "1.0.0",\n "archiveUrl": "https://example.invalid/specbridge-extensions/example-verifier-1.0.0.specbridge-extension.zip",\n "sha256": "d531c9078fcbeef6573a95773eefafd409d798bac1223c83748e0229ae0225bf",\n "manifest": {\n "protocolVersion": "1.0.0",\n "compatibility": {\n "specbridge": ">=0.7.1 <2.0.0"\n },\n "permissions": {\n "specRead": true,\n "repositoryRead": false,\n "repositoryWrite": false,\n "network": false,\n "childProcess": false,\n "environmentVariables": []\n }\n }\n }\n ],\n "repository": "https://github.com/HelloThisWorld/specbridge",\n "license": "MIT",\n "keywords": [\n "verifier",\n "specbridge-extension"\n ]\n }\n ]\n}\n'; var REGISTRY_ERROR_CODES = { SBR001: "registry not found", @@ -82677,20 +82916,20 @@ var cachedRegistrySchema = external_exports.object({ index: registryIndexSchema }).passthrough(); function registryCacheDir(workspace) { - return import_path45.default.join(workspace.sidecarDir, REGISTRY_CACHE_DIR_NAME); + return import_path47.default.join(workspace.sidecarDir, REGISTRY_CACHE_DIR_NAME); } function registryCachePath(workspace, name) { - const target = import_path45.default.join(registryCacheDir(workspace), `${name}.json`); + const target = import_path47.default.join(registryCacheDir(workspace), `${name}.json`); assertInsideWorkspace(workspace.rootDir, target); return target; } function readRegistryCache(workspace, name) { const filePath = registryCachePath(workspace, name); - if (!(0, import_fs42.existsSync)(filePath)) { + if (!(0, import_fs44.existsSync)(filePath)) { return { diagnostics: [] }; } try { - const parsed = cachedRegistrySchema.safeParse(JSON.parse((0, import_fs42.readFileSync)(filePath, "utf8"))); + const parsed = cachedRegistrySchema.safeParse(JSON.parse((0, import_fs44.readFileSync)(filePath, "utf8"))); if (!parsed.success) { return { diagnostics: [ @@ -82730,9 +82969,9 @@ function resolveRegistryIndex(workspace, source) { return { sourceName: source.name, index: parsed.index, origin: "builtin", diagnostics: [] }; } if (source.type === "local-file") { - const filePath = import_path45.default.resolve(workspace.rootDir, source.file); + const filePath = import_path47.default.resolve(workspace.rootDir, source.file); assertInsideWorkspace(workspace.rootDir, filePath); - if (!(0, import_fs42.existsSync)(filePath)) { + if (!(0, import_fs44.existsSync)(filePath)) { return { sourceName: source.name, index: { schemaVersion: "1.0.0", name: source.name, updatedAt: "unknown", extensions: [] }, @@ -82747,7 +82986,7 @@ function resolveRegistryIndex(workspace, source) { ] }; } - const text15 = (0, import_fs42.readFileSync)(filePath, "utf8"); + const text15 = (0, import_fs44.readFileSync)(filePath, "utf8"); const parsed = parseRegistryIndex(text15); if (parsed.index === void 0) { throw new RegistryError( @@ -82843,7 +83082,7 @@ var registriesConfigSchema = external_exports.object({ registries: external_exports.array(registrySourceSchema).max(20) }).passthrough(); function registriesConfigPath(workspace) { - return import_path46.default.join(workspace.sidecarDir, REGISTRIES_FILE_NAME); + return import_path48.default.join(workspace.sidecarDir, REGISTRIES_FILE_NAME); } function defaultRegistriesConfig() { return { @@ -82853,12 +83092,12 @@ function defaultRegistriesConfig() { } function readRegistriesConfig(workspace) { const filePath = registriesConfigPath(workspace); - if (!(0, import_fs43.existsSync)(filePath)) { + if (!(0, import_fs45.existsSync)(filePath)) { return { config: defaultRegistriesConfig(), diagnostics: [], exists: false }; } let parsed; try { - parsed = JSON.parse((0, import_fs43.readFileSync)(filePath, "utf8")); + parsed = JSON.parse((0, import_fs45.readFileSync)(filePath, "utf8")); } catch (cause) { return { config: defaultRegistriesConfig(), @@ -84230,826 +84469,290 @@ function registerJobCancelTool(server, context) { }); } -// ../../packages/mcp-server/src/tools/mission-tools.ts -function missionDeps(context, workspace) { - return { - workspace, - clock: context.clock, - idFactory: context.idFactory, - host: "mcp" - }; -} -var missionIdArg = external_exports.string().min(1).max(64).describe("Mission id (m-\u2026) from mission_begin or mission_status"); -var missionSummaryShape = { - missionId: external_exports.string(), - name: external_exports.string(), - status: external_exports.string(), - specName: external_exports.string().optional(), - openQuestions: external_exports.number().int(), - decisions: external_exports.number().int(), - contracts: external_exports.number().int(), - contractReady: external_exports.boolean().optional() -}; -function summarize3(context, workspace, missionId) { - const mission = requireMissionState(workspace, missionId); - const coverage = readCoverage(workspace, missionId); - return { - missionId: mission.missionId, - name: mission.name, - status: mission.status, - ...mission.specName !== void 0 ? { specName: mission.specName } : {}, - openQuestions: mission.counters.openQuestions, - decisions: mission.counters.decisions, - contracts: mission.counters.contracts, - ...coverage !== void 0 ? { contractReady: coverage.contractReady } : {} - }; -} -function registerMissionBeginTool(server, context) { - registerDefinedTool(server, context, { - name: "mission_begin", - title: "Begin a mission", - description: "Begin Mission Discovery from a high-level product direction. Creates the durable mission record under .specbridge/missions/. Discovery itself is a conversation: record every material visible exchange with mission_record_turn and its structured meaning with mission_assess.", - annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }, - inputSchema: { - name: external_exports.string().min(1).max(120).describe("Short mission name (also the default spec name)"), - goal: external_exports.string().min(1).max(4e3).describe("The user's product direction, verbatim") - }, - outputSchema: { mission: external_exports.object(missionSummaryShape) }, - handler: async (args) => { - const workspace = context.requireWorkspace(); - const mission = beginMission(missionDeps(context, workspace), { name: args.name, goal: args.goal }); - return { - text: `Mission ${mission.missionId} (${mission.name}) created in status ${mission.status}. Record the user's direction as the first turn.`, - structured: { mission: summarize3(context, workspace, mission.missionId) } - }; - } - }); -} -function registerMissionStatusTool(server, context) { - registerDefinedTool(server, context, { - name: "mission_status", - title: "List missions", - description: "List missions (newest first) with lifecycle status, counters, and readiness. Read-only.", - annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, - inputSchema: {}, - outputSchema: { missions: external_exports.array(external_exports.object(missionSummaryShape)) }, - handler: async () => { - const workspace = context.requireWorkspace(); - const listed = listMissions(workspace); - const missions = listed.missions.slice(0, 50).map((mission) => summarize3(context, workspace, mission.missionId)); - return { - text: missions.length === 0 ? "No missions exist. Begin one with mission_begin." : missions.map((mission) => `- ${mission.missionId} ${mission.status} (${mission.name})`).join("\n"), - structured: { missions } - }; - } - }); +// ../../packages/autonomy/dist/index.js +var import_fs46 = require("fs"); +var import_path49 = __toESM(require("path"), 1); +var import_fs47 = require("fs"); +var import_path50 = __toESM(require("path"), 1); +var SEAL_STATUSES = [ + /** Drafted from mission state; not yet authorized by a human. */ + "DRAFT", + /** A human authorized it. The only status delegated execution may use. */ + "SEALED", + /** A later seal replaced it. Historical, still readable, never executable. */ + "SUPERSEDED", + /** Explicitly withdrawn by a human. Delegated execution stops immediately. */ + "REVOKED" +]; +var SEALED_AUTHORITY_KINDS = [ + /** The product goal, verbatim. */ + "GOAL", + /** What the product explicitly will not do. */ + "NON_GOALS", + /** Recorded human decisions with provenance. */ + "DECISIONS", + /** Constitution rules: the invariants the product is built under. */ + "CONSTITUTION", + /** Architecture decision records. */ + "ADRS", + /** Product engineering contracts and their revisions. */ + "CONTRACTS", + /** Individual requirements inside those contracts. */ + "REQUIREMENTS", + /** How the product is judged done. */ + "ACCEPTANCE_CRITERIA", + /** The spending ceiling and resource policy the run may consume. */ + "RESOURCE_POLICY", + /** The autonomy/delegation policy in force at seal time. */ + "AUTONOMY_POLICY" +]; +var SUPERVISION_STATUSES = [ + /** Registered for supervision; no driver has been started yet. */ + "REGISTERED", + /** A driver holds a live lease and is executing. */ + "ACTIVE", + /** Waiting on a resource, a backoff, or a scheduled wake time. */ + "SLEEPING", + /** The previous driver died; a replacement is being started. */ + "RESTARTING", + /** Final: the job reached a terminal status. */ + "RELEASED" +]; +var SUPERVISION_ACTIONS = [ + "LEASE_ACQUIRED", + "LEASE_RENEWED", + "LEASE_EXPIRED_RECLAIMED", + "DRIVER_STARTED", + "DRIVER_EXITED_CLEANLY", + "DRIVER_DIED", + /** A person explicitly resumed; the give-up ledger starts fresh. */ + "RESET_ON_EXPLICIT_RESUME", + /** Planned work exhausted with the closure gate unsatisfied; the closure lifecycle takes over. */ + "CLOSURE_HANDOFF", + "DRIVER_RESTARTED", + "ATTEMPT_RECONCILED", + "WAKE_SCHEDULED", + "WOKEN_ON_SCHEDULE", + "WOKEN_ON_RESOURCE_RETURN", + "PROVIDER_HEALTH_RECHECKED", + "LOCAL_RUNTIME_RESTARTED", + "STALE_PROCESS_REAPED", + "RESTART_BUDGET_EXHAUSTED", + "SESSION_BUDGET_REACHED", + "INDEFINITE_WAIT_CLASSIFIED", + "RELEASED_ON_TERMINAL_STATUS", + "RELEASED_ON_AUTHORITY_STOP" +]; +var PREFLIGHT_CAPABILITIES = [ + "WORKSPACE_WRITABLE", + "REPOSITORY_CLEAN_ENOUGH", + "GIT_AVAILABLE", + "DISK_SPACE", + "PROTECTED_PATHS_CONFIGURED", + "SEAL_PRESENT", + "SEAL_COMPLETE", + "AUTONOMY_POLICY_COMPLETE", + "SUPERVISOR_CAPABLE", + "STRONG_WORKER_AVAILABLE", + "LOCAL_MODEL_STARTABLE", + "API_FALLBACK_AUTHORIZED", + "SPEND_CEILING_DECLARED", + "TRUSTED_VERIFICATION_CONFIGURED", + "PACKAGE_MANAGER_AVAILABLE", + "PACKAGE_REGISTRY_REACHABLE", + "BUILD_TOOLCHAIN_AVAILABLE", + "CONTAINER_RUNTIME", + "CONTAINER_COMPOSE", + "BROWSER_RUNTIME", + "TOOLSMITH_POLICY_SUFFICIENT", + "ENVIRONMENT_POLICY_SUFFICIENT", + "KNOWN_CREDENTIALS_PRESENT", + "CONTROL_PLANE_REPAIR_CONFIGURED" +]; +var PREFLIGHT_OUTCOMES = [ + /** Observed present and usable right now. */ + "READY", + /** Absent now, and the runtime is authorized and able to provide it. */ + "SATISFIABLE_AUTONOMOUSLY", + /** Absent, and only a human can supply it. Blocks an unattended launch. */ + "HUMAN_REQUIRED", + /** Not needed for this mission's declared surfaces. */ + "NOT_APPLICABLE", + /** The probe itself could not reach a conclusion. Never a pass. */ + "UNKNOWN" +]; +var PREFLIGHT_VERDICTS = [ + /** Every required capability is READY or autonomously satisfiable. */ + "OVERNIGHT_READY", + /** At least one capability needs a person before launch. */ + "HUMAN_ACTION_REQUIRED", + /** A probe could not decide something required. Never launch on this. */ + "INDETERMINATE" +]; +var TOOLSMITH_REQUEST_STATUSES = [ + "REQUESTED", + "GRANTED", + "DENIED", + "APPLIED", + "FAILED" +]; +var TOOLSMITH_DENIAL_REASONS = [ + "CAPABILITY_NOT_ENABLED", + "TOOLSMITH_DISABLED", + "GRANT_BUDGET_EXHAUSTED", + "TARGET_OUTSIDE_WORKSPACE", + "TARGET_PROTECTED_PATH", + "REGISTRY_NOT_ALLOWED", + "REQUIRES_ADMIN_PRIVILEGE", + "WOULD_CREATE_AUTHORITY", + "DOWNLOAD_TOO_LARGE", + "PORTABLE_ALTERNATIVE_REQUIRED" +]; +var TOOL_INSTALL_SCOPES = [ + "PROJECT_LOCAL", + "PORTABLE", + "CONTAINERIZED", + "USER_LOCAL" +]; +var SERVICE_KINDS = [ + "CONTAINER", + "COMPOSE_PROJECT", + "PROCESS", + "DATABASE", + "MESSAGE_BROKER", + "CACHE", + "APPLICATION_SERVER", + "FRONTEND_SERVER", + "WORKER" +]; +var READINESS_PROBE_KINDS = [ + /** The process/container exists and has not exited. Weakest evidence. */ + "PROCESS_ALIVE", + /** A TCP connection is accepted. */ + "TCP_CONNECT", + /** An HTTP request returns an expected status. */ + "HTTP_STATUS", + /** An HTTP body matches an expected pattern. */ + "HTTP_BODY", + /** A command exits zero inside or against the service. */ + "COMMAND_EXIT", + /** A protocol-level handshake succeeded (SQL ping, broker metadata, …). */ + "PROTOCOL_HANDSHAKE", + /** The container runtime reports its own healthcheck as healthy. */ + "CONTAINER_HEALTHCHECK" +]; +var ENVIRONMENT_STATUSES = [ + "PLANNED", + "PROVISIONING", + "WAITING_READY", + "READY", + "DEGRADED", + "REPAIRING", + "FAILED", + "STOPPED" +]; +var SERVICE_STATUSES = [ + "PENDING", + "STARTING", + "WAITING_READY", + "READY", + "UNHEALTHY", + "RESTARTING", + "FAILED", + "STOPPED" +]; +var ENVIRONMENT_FAILURE_KINDS = [ + "RUNTIME_UNAVAILABLE", + "IMAGE_PULL_FAILED", + "PORT_CONFLICT", + "READINESS_TIMEOUT", + "SERVICE_CRASHED", + "DEPENDENCY_UNREADY", + "CONFIGURATION_INVALID", + "RESOURCE_EXHAUSTED", + "UNKNOWN" +]; +var BROWSER_STEP_KINDS = [ + "NAVIGATE", + "CLICK", + "TYPE", + "FILL_FORM", + "SUBMIT", + "WAIT_FOR_SELECTOR", + "WAIT_FOR_TEXT", + "EXPECT_SELECTOR", + "EXPECT_TEXT", + "EXPECT_ABSENT", + "EXPECT_URL", + "EXPECT_NO_CONSOLE_ERRORS", + "EXPECT_NO_FAILED_REQUESTS", + "SCREENSHOT", + "SET_VIEWPORT", + "RELOAD", + "SWITCH_CONTEXT" +]; +var BROWSER_ASSERTION_STEPS = [ + "EXPECT_SELECTOR", + "EXPECT_TEXT", + "EXPECT_ABSENT", + "EXPECT_URL", + "EXPECT_NO_CONSOLE_ERRORS", + "EXPECT_NO_FAILED_REQUESTS" +]; +var BROWSER_SCENARIO_STATUSES = [ + "PASSED", + "FAILED", + "ERRORED", + "SKIPPED_NO_RUNTIME", + "NOT_RUN" +]; +var BROWSER_EVIDENCE_KINDS = [ + "SCREENSHOT", + "DOM_SNAPSHOT", + "CONSOLE_LOG", + "NETWORK_FAILURES", + "STEP_TRACE", + "VIEWPORT_MATRIX" +]; +var UX_FINDING_KINDS = [ + "OVERLAPPING_ELEMENTS", + "CLIPPED_CONTENT", + "UNREADABLE_LAYOUT", + "BROKEN_RESPONSIVE", + "DEAD_INTERACTION", + "MISSING_LOADING_STATE", + "MISSING_ERROR_STATE", + "MISSING_EMPTY_STATE", + "INCONSISTENT_UX", + "UNUSABLE_CONTROL", + "VISUAL_REGRESSION", + "AESTHETIC_PREFERENCE" +]; +var UX_FINDING_SEVERITIES = ["MATERIAL", "MINOR", "COSMETIC"]; +var UX_CRITIQUE_VERDICTS = [ + "NO_MATERIAL_FINDINGS", + "MATERIAL_FINDINGS", + "NOT_RUN", + "INSUFFICIENT_EVIDENCE" +]; +var CLOSURE_STATUSES = [ + /** Nothing claims to implement this item. */ + "NOT_STARTED", + /** Work exists and is in flight. */ + "IN_PROGRESS", + /** Implementation exists and is attributed, but nothing has proven it. */ + "IMPLEMENTED", + /** Trusted evidence demonstrates the item holds. The only closing state. */ + "VERIFIED", + /** A human explicitly waived it, with a recorded reason. */ + "WAIVED", + /** Explicitly out of scope for this seal, by recorded decision. */ + "NOT_APPLICABLE" +]; +var CLOSING_STATUSES = ["VERIFIED", "WAIVED", "NOT_APPLICABLE"]; +function isClosingStatus(status) { + return CLOSING_STATUSES.includes(status); } -function registerMissionReadTool(server, context) { - registerDefinedTool(server, context, { - name: "mission_read", - title: "Read one mission", - description: "Read one mission in depth. `view` selects the record family: overview (default), facts, decisions, questions, conversation, coverage, constitution, adrs, or ccrs. Bounded; read-only.", - annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, - inputSchema: { - missionId: missionIdArg, - view: external_exports.enum(["overview", "facts", "decisions", "questions", "conversation", "coverage", "constitution", "adrs", "ccrs"]).optional().describe("Which record family to read (default overview)"), - limit: external_exports.number().int().min(1).max(200).optional().describe("Bounded page size for list views") - }, - outputSchema: { - mission: external_exports.object(missionSummaryShape), - view: external_exports.string(), - records: external_exports.array(external_exports.record(external_exports.unknown())) - }, - handler: async (args) => { - const workspace = context.requireWorkspace(); - const deps = missionDeps(context, workspace); - observeSpecApproval(deps, args.missionId); - const view = args.view ?? "overview"; - const limit = args.limit ?? 50; - let records = []; - switch (view) { - case "overview": { - const overview = describeMission(deps, args.missionId); - records = [ - { - goal: overview.mission.goal, - nonGoals: overview.mission.nonGoals, - targetUsers: overview.mission.targetUsers, - constraints: overview.mission.constraints, - successCriteria: overview.mission.successCriteria, - assumptions: overview.mission.assumptions, - constitutionVersion: overview.constitutionVersion, - activeConstitutionRules: overview.activeConstitutionRules, - contractCount: overview.contractCount, - adrCount: overview.adrCount, - blockingQuestions: overview.blockingQuestions, - openCcrs: overview.openCcrs - } - ]; - break; - } - case "facts": - records = readFacts(workspace, args.missionId).slice(-limit); - break; - case "decisions": - records = readDecisions(workspace, args.missionId).slice(-limit); - break; - case "questions": - records = readQuestions(workspace, args.missionId).slice(-limit); - break; - case "conversation": - records = readTurns(workspace, args.missionId, { limit }).turns; - break; - case "coverage": { - const coverage = readCoverage(workspace, args.missionId); - records = coverage !== void 0 ? [coverage] : []; - break; - } - case "constitution": { - const constitution = readConstitution(workspace, args.missionId); - records = constitution !== void 0 ? [constitution] : []; - break; - } - case "adrs": - records = readAdrs(workspace, args.missionId).slice(-limit); - break; - case "ccrs": - records = readCcrs(workspace, args.missionId).slice(-limit); - break; - } - return { - text: `${view}: ${records.length} record(s).`, - structured: { mission: summarize3(context, workspace, args.missionId), view, records } - }; - } - }); -} -function registerMissionRecordTurnTool(server, context) { - registerDefinedTool(server, context, { - name: "mission_record_turn", - title: "Record a visible discovery turn", - description: "Persist one USER-VISIBLE discovery exchange verbatim: what the user said, or what the agent visibly asked, interpreted, or presented. Turns are the provenance roots every decision traces back to. Never record hidden reasoning \u2014 only what both sides could see.", - annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }, - inputSchema: { - missionId: missionIdArg, - speaker: external_exports.enum(TURN_SPEAKERS).describe("Who produced the visible text"), - kind: external_exports.enum(TURN_KINDS).describe("What kind of exchange this is"), - text: external_exports.string().min(1).max(8e3).describe("The visible text, verbatim"), - inReplyTo: external_exports.string().max(64).optional().describe("Turn id this replies to"), - refs: external_exports.array(external_exports.string().max(64)).max(30).optional().describe("Record ids this turn addresses") - }, - outputSchema: { turnId: external_exports.string(), missionStatus: external_exports.string() }, - handler: async (args) => { - const workspace = context.requireWorkspace(); - const result = recordTurn(missionDeps(context, workspace), args.missionId, { - speaker: args.speaker, - kind: args.kind, - text: args.text, - inReplyTo: args.inReplyTo, - refs: args.refs - }); - return { - text: `Recorded ${result.turn.turnId} (${args.speaker} ${args.kind}). Mission is ${result.mission.status}.`, - structured: { turnId: result.turn.turnId, missionStatus: result.mission.status } - }; - } - }); -} -var factInput = external_exports.object({ - statement: external_exports.string().min(1).max(4e3), - provenance: external_exports.enum(MISSION_PROVENANCE_KINDS), - sourceTurnId: external_exports.string().max(64).optional(), - topics: external_exports.array(external_exports.enum(DISCOVERY_TOPICS)).max(10).optional(), - supersedesFactId: external_exports.string().max(64).optional() -}); -var questionInput = external_exports.object({ - question: external_exports.string().min(1).max(4e3), - whyItMatters: external_exports.string().min(1).max(4e3), - topics: external_exports.array(external_exports.enum(DISCOVERY_TOPICS)).max(10).optional(), - affectedSurfaces: external_exports.array(external_exports.enum(IRREVERSIBLE_SURFACES)).max(10).optional(), - materiality: external_exports.enum(MATERIALITY_LEVELS).optional(), - options: external_exports.array(external_exports.string().max(2e3)).max(10).optional(), - sourceTurnId: external_exports.string().max(64).optional() -}); -var decisionInput = external_exports.object({ - decision: external_exports.string().min(1).max(4e3), - rationale: external_exports.string().max(4e3).optional(), - provenance: external_exports.enum(MISSION_PROVENANCE_KINDS), - sourceTurnId: external_exports.string().max(64).optional(), - questionId: external_exports.string().max(64).optional(), - topics: external_exports.array(external_exports.enum(DISCOVERY_TOPICS)).max(10).optional(), - marksNotApplicable: external_exports.array(external_exports.enum(DISCOVERY_TOPICS)).max(10).optional(), - supersedesDecisionId: external_exports.string().max(64).optional() -}); -var constitutionRuleInput = external_exports.object({ - statement: external_exports.string().min(1).max(4e3), - rationale: external_exports.string().max(4e3).optional(), - decisionIds: external_exports.array(external_exports.string().max(64)).min(1).max(30), - affectedContractIds: external_exports.array(external_exports.string().max(64)).max(30).optional(), - guardPatterns: external_exports.array(external_exports.string().min(1).max(200)).max(10).optional(), - supersedesRuleId: external_exports.string().max(64).optional() -}); -var adrInput = external_exports.object({ - title: external_exports.string().min(1).max(512), - context: external_exports.string().min(1).max(4e3), - decision: external_exports.string().min(1).max(4e3), - alternatives: external_exports.array(external_exports.string().max(4e3)).max(20).optional(), - rationale: external_exports.string().min(1).max(4e3), - consequences: external_exports.array(external_exports.string().max(4e3)).max(20).optional(), - revisitConditions: external_exports.array(external_exports.string().max(4e3)).max(20).optional(), - decisionIds: external_exports.array(external_exports.string().max(64)).max(30).optional(), - turnIds: external_exports.array(external_exports.string().max(64)).max(30).optional(), - supersedesAdrId: external_exports.string().max(64).optional() -}); -var contractInput = external_exports.object({ - title: external_exports.string().min(1).max(512), - summary: external_exports.string().min(1).max(4e3), - classification: external_exports.enum(["public", "internal"]), - compatibilityPolicy: external_exports.enum(["frozen", "additive-only", "evolving", "internal"]), - dependsOn: external_exports.array(external_exports.string().max(64)).max(30).optional(), - requirements: external_exports.array(external_exports.object({ statement: external_exports.string().min(1).max(4e3), decisionIds: external_exports.array(external_exports.string().max(64)).max(30).optional() })).min(1).max(60), - invariants: external_exports.array( - external_exports.object({ - statement: external_exports.string().min(1).max(4e3), - constitutionRuleIds: external_exports.array(external_exports.string().max(64)).max(30).optional(), - guardPatterns: external_exports.array(external_exports.string().min(1).max(200)).max(10).optional() - }) - ).max(60).optional(), - decisionIds: external_exports.array(external_exports.string().max(64)).min(1).max(30), - turnIds: external_exports.array(external_exports.string().max(64)).max(30).optional() -}); -function registerMissionAssessTool(server, context) { - registerDefinedTool(server, context, { - name: "mission_assess", - title: "Record a structured discovery assessment", - description: "Submit the STRUCTURED meaning of the discovery conversation: facts, questions, decisions, constitution rules, ADRs, contracts, and mission field updates. SpecBridge governs every record: decisions need safe provenance (a user-provenance decision must cite a USER turn), question materiality passes the deterministic irreversibility screen (it can only be RAISED), durable artifacts must trace to recorded decisions, and coverage recomputes deterministically. Blocking questions prevent CONTRACT_READY; implementation-detail questions never do.", - annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }, - inputSchema: { - missionId: missionIdArg, - facts: external_exports.array(factInput).max(20).optional(), - questions: external_exports.array(questionInput).max(20).optional(), - decisions: external_exports.array(decisionInput).max(20).optional(), - constitutionRules: external_exports.array(constitutionRuleInput).max(10).optional(), - adrs: external_exports.array(adrInput).max(10).optional(), - contracts: external_exports.array(contractInput).max(10).optional(), - missionUpdates: external_exports.object({ - nonGoals: external_exports.array(external_exports.string().max(4e3)).max(50).optional(), - targetUsers: external_exports.array(external_exports.string().max(4e3)).max(50).optional(), - constraints: external_exports.array(external_exports.string().max(4e3)).max(50).optional(), - successCriteria: external_exports.array(external_exports.string().max(4e3)).max(50).optional(), - assumptions: external_exports.array( - external_exports.object({ - statement: external_exports.string().min(1).max(4e3), - topics: external_exports.array(external_exports.enum(DISCOVERY_TOPICS)).max(10).optional(), - questionId: external_exports.string().max(64).optional() - }) - ).max(50).optional() - }).optional() - }, - outputSchema: { - missionStatus: external_exports.string(), - contractReady: external_exports.boolean(), - factIds: external_exports.array(external_exports.string()), - questionIds: external_exports.array(external_exports.string()), - decisionIds: external_exports.array(external_exports.string()), - constitutionRuleIds: external_exports.array(external_exports.string()), - adrIds: external_exports.array(external_exports.string()), - contractIds: external_exports.array(external_exports.string()), - materialityRaised: external_exports.array( - external_exports.object({ questionId: external_exports.string(), from: external_exports.string(), to: external_exports.string() }) - ), - blockingQuestionIds: external_exports.array(external_exports.string()), - unresolvedRequiredTopics: external_exports.array(external_exports.string()) - }, - handler: async (args) => { - const workspace = context.requireWorkspace(); - const result = recordAssessment(missionDeps(context, workspace), args.missionId, { - facts: args.facts, - questions: args.questions, - decisions: args.decisions, - constitutionRules: args.constitutionRules, - adrs: args.adrs, - contracts: args.contracts, - missionUpdates: args.missionUpdates - }); - const raised = result.materialityRaised.map((entry) => `${entry.questionId} raised ${entry.from} \u2192 ${entry.to}`).join("; "); - return { - text: `Recorded ${result.factIds.length} fact(s), ${result.questionIds.length} question(s), ${result.decisionIds.length} decision(s), ${result.constitutionRuleIds.length} rule(s), ${result.adrIds.length} ADR(s), ${result.contractIds.length} contract(s). Mission is ${result.mission.status}; contract-ready: ${result.coverage.contractReady}.` + (raised.length > 0 ? ` Materiality screen: ${raised}.` : ""), - structured: { - missionStatus: result.mission.status, - contractReady: result.coverage.contractReady, - factIds: result.factIds, - questionIds: result.questionIds, - decisionIds: result.decisionIds, - constitutionRuleIds: result.constitutionRuleIds, - adrIds: result.adrIds, - contractIds: result.contractIds, - materialityRaised: result.materialityRaised, - blockingQuestionIds: result.coverage.blockingQuestionIds, - unresolvedRequiredTopics: result.coverage.unresolvedRequiredTopics - } - }; - } - }); -} -function registerMissionQuestionsTool(server, context) { - registerDefinedTool(server, context, { - name: "mission_questions", - title: "Open discovery questions", - description: "The open questions with materiality and why each matters. Blocking questions gate CONTRACT_READY. Read-only.", - annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, - inputSchema: { missionId: missionIdArg }, - outputSchema: { - questions: external_exports.array( - external_exports.object({ - questionId: external_exports.string(), - question: external_exports.string(), - whyItMatters: external_exports.string(), - materiality: external_exports.string(), - topics: external_exports.array(external_exports.string()), - options: external_exports.array(external_exports.string()) - }) - ) - }, - handler: async (args) => { - const workspace = context.requireWorkspace(); - requireMissionState(workspace, args.missionId); - const questions = readQuestions(workspace, args.missionId).filter((question) => question.status === "open").map((question) => ({ - questionId: question.questionId, - question: question.question, - whyItMatters: question.whyItMatters, - materiality: question.materiality, - topics: [...question.topics], - options: [...question.options] - })); - return { - text: questions.length === 0 ? "No open questions." : questions.map((question) => `- ${question.questionId} [${question.materiality}] ${question.question}`).join("\n"), - structured: { questions } - }; - } - }); -} -function registerMissionAnswerTool(server, context) { - registerDefinedTool(server, context, { - name: "mission_answer", - title: "Record the user\u2019s answer to a question", - description: "Record the USER'S answer to one open discovery question: an answering user turn plus a known-from-user decision bound to it. Relay their words; never answer on their behalf.", - annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }, - inputSchema: { - missionId: missionIdArg, - questionId: external_exports.string().min(1).max(64), - answer: external_exports.string().min(1).max(4e3).describe("The user's answer, verbatim"), - marksNotApplicable: external_exports.array(external_exports.enum(DISCOVERY_TOPICS)).max(10).optional() - }, - outputSchema: { - decisionId: external_exports.string(), - missionStatus: external_exports.string(), - contractReady: external_exports.boolean() - }, - handler: async (args) => { - const workspace = context.requireWorkspace(); - const result = answerQuestion(missionDeps(context, workspace), args.missionId, { - questionId: args.questionId, - answer: args.answer, - marksNotApplicable: args.marksNotApplicable - }); - return { - text: `Recorded ${result.decision.decisionId}. Mission is ${result.mission.status}; contract-ready: ${result.coverage.contractReady}.`, - structured: { - decisionId: result.decision.decisionId, - missionStatus: result.mission.status, - contractReady: result.coverage.contractReady - } - }; - } - }); -} -function registerMissionSynthesizeTool(server, context) { - registerDefinedTool(server, context, { - name: "mission_synthesize", - title: "Synthesize the Kiro spec", - description: "Move a coverage-complete mission to CONTRACT_READY and compile its contract set into Kiro spec candidates: requirements.md, design.md, and OBJECTIVE-oriented tasks.md \u2014 through the existing creation machinery. Approval stays entirely human (`specbridge spec approve \u2026`); nothing here or anywhere on MCP can approve a stage. Fails closed when blocking questions or required topics remain.", - annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }, - inputSchema: { - missionId: missionIdArg, - specName: external_exports.string().max(64).optional().describe("Spec name (default: the mission name)") - }, - outputSchema: { - specName: external_exports.string(), - objectiveCount: external_exports.number().int(), - files: external_exports.array(external_exports.object({ fileName: external_exports.string(), bytes: external_exports.number().int() })) - }, - handler: async (args) => { - const workspace = context.requireWorkspace(); - const deps = missionDeps(context, workspace); - markContractReady(deps, args.missionId); - const result = synthesizeMissionSpec(deps, args.missionId, { specName: args.specName }); - return { - text: `Synthesized spec "${result.specName}" with ${result.objectiveCount} objective(s). The user approves it with: specbridge spec approve ${result.specName} --stage requirements|design|tasks.`, - structured: { - specName: result.specName, - objectiveCount: result.objectiveCount, - files: result.files - } - }; - } - }); -} -function registerContractListTool(server, context) { - registerDefinedTool(server, context, { - name: "contract_list", - title: "List product contracts", - description: "The mission\u2019s product contract registry (current revisions) plus the Architecture Constitution. Read-only.", - annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, - inputSchema: { missionId: missionIdArg }, - outputSchema: { - constitutionVersion: external_exports.number().int(), - rules: external_exports.array(external_exports.object({ ruleId: external_exports.string(), statement: external_exports.string(), status: external_exports.string() })), - contracts: external_exports.array( - external_exports.object({ - contractId: external_exports.string(), - revision: external_exports.number().int(), - title: external_exports.string(), - classification: external_exports.string(), - compatibilityPolicy: external_exports.string() - }) - ) - }, - handler: async (args) => { - const workspace = context.requireWorkspace(); - requireMissionState(workspace, args.missionId); - const constitution = readConstitution(workspace, args.missionId); - const contracts = readContractRegistry(workspace, args.missionId).map((contract) => ({ - contractId: contract.contractId, - revision: contract.revision, - title: contract.title, - classification: contract.classification, - compatibilityPolicy: contract.compatibilityPolicy - })); - return { - text: contracts.map((contract) => `- ${contract.contractId} r${contract.revision} ${contract.title}`).join("\n") || "No contracts recorded.", - structured: { - constitutionVersion: constitution?.version ?? 0, - rules: (constitution?.rules ?? []).map((rule) => ({ - ruleId: rule.ruleId, - statement: rule.statement, - status: rule.status - })), - contracts - } - }; - } - }); -} -function registerContractReadTool(server, context) { - registerDefinedTool(server, context, { - name: "contract_read", - title: "Read one product contract", - description: "One contract in depth: requirements, invariants, dependencies, provenance, revision lineage. Read-only.", - annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, - inputSchema: { - missionId: missionIdArg, - contractId: external_exports.string().min(1).max(64), - revision: external_exports.number().int().min(1).optional().describe("A specific revision (default: current)") - }, - outputSchema: { contract: external_exports.record(external_exports.unknown()) }, - handler: async (args) => { - const workspace = context.requireWorkspace(); - requireMissionState(workspace, args.missionId); - const contract = readContract(workspace, args.missionId, args.contractId, args.revision); - if (contract === void 0) { - return { - text: `Contract ${args.contractId}${args.revision !== void 0 ? ` r${args.revision}` : ""} does not exist.`, - structured: { contract: {} } - }; - } - return { - text: `${contract.contractId} r${contract.revision}: ${contract.title} \u2014 ${contract.requirements.length} requirement(s), ${contract.invariants.length} invariant(s).`, - structured: { contract } - }; - } - }); -} -function registerContractChangeRequestTool(server, context) { - registerDefinedTool(server, context, { - name: "contract_change_request", - title: "Create a contract change request", - description: "Create a durable ContractChangeRequest against a product contract. Anyone may RAISE one; only the human decides it (CLI: `specbridge mission ccr --approve|--reject`). A material request (public contract, frozen/additive policy, or irreversible surface) lands NEEDS_HUMAN and stops affected execution. This tool can never approve anything.", - annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }, - inputSchema: { - missionId: missionIdArg, - contractId: external_exports.string().min(1).max(64), - problem: external_exports.string().min(1).max(4e3).describe("What the current contract cannot express"), - proposal: external_exports.string().min(1).max(4e3).describe("The proposed change"), - affected: external_exports.array(external_exports.string().max(2e3)).max(30).optional().describe("Areas the change would touch") - }, - outputSchema: { - ccrId: external_exports.string(), - status: external_exports.string(), - material: external_exports.boolean() - }, - handler: async (args) => { - const workspace = context.requireWorkspace(); - const result = createContractChangeRequest(missionDeps(context, workspace), args.missionId, { - contractId: args.contractId, - problem: args.problem, - proposal: args.proposal, - affected: args.affected, - raisedBy: "mcp" - }); - return { - text: `${result.ccr.ccrId} created (${result.ccr.status}). ` + (result.material ? "It is material: the human decides it with `specbridge mission ccr \u2026 --approve|--reject`." : "It is recorded for the next contract review."), - structured: { ccrId: result.ccr.ccrId, status: result.ccr.status, material: result.material } - }; - } - }); -} - -// ../../packages/intake/dist/index.js -var import_crypto18 = require("crypto"); -var import_fs45 = require("fs"); -var import_path48 = __toESM(require("path"), 1); -var import_fs46 = require("fs"); -var import_path49 = __toESM(require("path"), 1); - -// ../../packages/autonomy/dist/index.js -var import_fs44 = require("fs"); -var import_path47 = __toESM(require("path"), 1); -var SEAL_STATUSES = [ - /** Drafted from mission state; not yet authorized by a human. */ - "DRAFT", - /** A human authorized it. The only status delegated execution may use. */ - "SEALED", - /** A later seal replaced it. Historical, still readable, never executable. */ - "SUPERSEDED", - /** Explicitly withdrawn by a human. Delegated execution stops immediately. */ - "REVOKED" -]; -var SEALED_AUTHORITY_KINDS = [ - /** The product goal, verbatim. */ - "GOAL", - /** What the product explicitly will not do. */ - "NON_GOALS", - /** Recorded human decisions with provenance. */ - "DECISIONS", - /** Constitution rules: the invariants the product is built under. */ - "CONSTITUTION", - /** Architecture decision records. */ - "ADRS", - /** Product engineering contracts and their revisions. */ - "CONTRACTS", - /** Individual requirements inside those contracts. */ - "REQUIREMENTS", - /** How the product is judged done. */ - "ACCEPTANCE_CRITERIA", - /** The spending ceiling and resource policy the run may consume. */ - "RESOURCE_POLICY", - /** The autonomy/delegation policy in force at seal time. */ - "AUTONOMY_POLICY" -]; -var SUPERVISION_STATUSES = [ - /** Registered for supervision; no driver has been started yet. */ - "REGISTERED", - /** A driver holds a live lease and is executing. */ - "ACTIVE", - /** Waiting on a resource, a backoff, or a scheduled wake time. */ - "SLEEPING", - /** The previous driver died; a replacement is being started. */ - "RESTARTING", - /** Final: the job reached a terminal status. */ - "RELEASED" -]; -var SUPERVISION_ACTIONS = [ - "LEASE_ACQUIRED", - "LEASE_RENEWED", - "LEASE_EXPIRED_RECLAIMED", - "DRIVER_STARTED", - "DRIVER_EXITED_CLEANLY", - "DRIVER_DIED", - /** A person explicitly resumed; the give-up ledger starts fresh. */ - "RESET_ON_EXPLICIT_RESUME", - /** Planned work exhausted with the closure gate unsatisfied; the closure lifecycle takes over. */ - "CLOSURE_HANDOFF", - "DRIVER_RESTARTED", - "ATTEMPT_RECONCILED", - "WAKE_SCHEDULED", - "WOKEN_ON_SCHEDULE", - "WOKEN_ON_RESOURCE_RETURN", - "PROVIDER_HEALTH_RECHECKED", - "LOCAL_RUNTIME_RESTARTED", - "STALE_PROCESS_REAPED", - "RESTART_BUDGET_EXHAUSTED", - "SESSION_BUDGET_REACHED", - "INDEFINITE_WAIT_CLASSIFIED", - "RELEASED_ON_TERMINAL_STATUS", - "RELEASED_ON_AUTHORITY_STOP" -]; -var PREFLIGHT_CAPABILITIES = [ - "WORKSPACE_WRITABLE", - "REPOSITORY_CLEAN_ENOUGH", - "GIT_AVAILABLE", - "DISK_SPACE", - "PROTECTED_PATHS_CONFIGURED", - "SEAL_PRESENT", - "SEAL_COMPLETE", - "AUTONOMY_POLICY_COMPLETE", - "SUPERVISOR_CAPABLE", - "STRONG_WORKER_AVAILABLE", - "LOCAL_MODEL_STARTABLE", - "API_FALLBACK_AUTHORIZED", - "SPEND_CEILING_DECLARED", - "TRUSTED_VERIFICATION_CONFIGURED", - "PACKAGE_MANAGER_AVAILABLE", - "PACKAGE_REGISTRY_REACHABLE", - "BUILD_TOOLCHAIN_AVAILABLE", - "CONTAINER_RUNTIME", - "CONTAINER_COMPOSE", - "BROWSER_RUNTIME", - "TOOLSMITH_POLICY_SUFFICIENT", - "ENVIRONMENT_POLICY_SUFFICIENT", - "KNOWN_CREDENTIALS_PRESENT", - "CONTROL_PLANE_REPAIR_CONFIGURED" -]; -var PREFLIGHT_OUTCOMES = [ - /** Observed present and usable right now. */ - "READY", - /** Absent now, and the runtime is authorized and able to provide it. */ - "SATISFIABLE_AUTONOMOUSLY", - /** Absent, and only a human can supply it. Blocks an unattended launch. */ - "HUMAN_REQUIRED", - /** Not needed for this mission's declared surfaces. */ - "NOT_APPLICABLE", - /** The probe itself could not reach a conclusion. Never a pass. */ - "UNKNOWN" -]; -var PREFLIGHT_VERDICTS = [ - /** Every required capability is READY or autonomously satisfiable. */ - "OVERNIGHT_READY", - /** At least one capability needs a person before launch. */ - "HUMAN_ACTION_REQUIRED", - /** A probe could not decide something required. Never launch on this. */ - "INDETERMINATE" -]; -var TOOLSMITH_REQUEST_STATUSES = [ - "REQUESTED", - "GRANTED", - "DENIED", - "APPLIED", - "FAILED" -]; -var TOOLSMITH_DENIAL_REASONS = [ - "CAPABILITY_NOT_ENABLED", - "TOOLSMITH_DISABLED", - "GRANT_BUDGET_EXHAUSTED", - "TARGET_OUTSIDE_WORKSPACE", - "TARGET_PROTECTED_PATH", - "REGISTRY_NOT_ALLOWED", - "REQUIRES_ADMIN_PRIVILEGE", - "WOULD_CREATE_AUTHORITY", - "DOWNLOAD_TOO_LARGE", - "PORTABLE_ALTERNATIVE_REQUIRED" -]; -var TOOL_INSTALL_SCOPES = [ - "PROJECT_LOCAL", - "PORTABLE", - "CONTAINERIZED", - "USER_LOCAL" -]; -var SERVICE_KINDS = [ - "CONTAINER", - "COMPOSE_PROJECT", - "PROCESS", - "DATABASE", - "MESSAGE_BROKER", - "CACHE", - "APPLICATION_SERVER", - "FRONTEND_SERVER", - "WORKER" -]; -var READINESS_PROBE_KINDS = [ - /** The process/container exists and has not exited. Weakest evidence. */ - "PROCESS_ALIVE", - /** A TCP connection is accepted. */ - "TCP_CONNECT", - /** An HTTP request returns an expected status. */ - "HTTP_STATUS", - /** An HTTP body matches an expected pattern. */ - "HTTP_BODY", - /** A command exits zero inside or against the service. */ - "COMMAND_EXIT", - /** A protocol-level handshake succeeded (SQL ping, broker metadata, …). */ - "PROTOCOL_HANDSHAKE", - /** The container runtime reports its own healthcheck as healthy. */ - "CONTAINER_HEALTHCHECK" -]; -var ENVIRONMENT_STATUSES = [ - "PLANNED", - "PROVISIONING", - "WAITING_READY", - "READY", - "DEGRADED", - "REPAIRING", - "FAILED", - "STOPPED" -]; -var SERVICE_STATUSES = [ - "PENDING", - "STARTING", - "WAITING_READY", - "READY", - "UNHEALTHY", - "RESTARTING", - "FAILED", - "STOPPED" -]; -var ENVIRONMENT_FAILURE_KINDS = [ - "RUNTIME_UNAVAILABLE", - "IMAGE_PULL_FAILED", - "PORT_CONFLICT", - "READINESS_TIMEOUT", - "SERVICE_CRASHED", - "DEPENDENCY_UNREADY", - "CONFIGURATION_INVALID", - "RESOURCE_EXHAUSTED", - "UNKNOWN" -]; -var BROWSER_STEP_KINDS = [ - "NAVIGATE", - "CLICK", - "TYPE", - "FILL_FORM", - "SUBMIT", - "WAIT_FOR_SELECTOR", - "WAIT_FOR_TEXT", - "EXPECT_SELECTOR", - "EXPECT_TEXT", - "EXPECT_ABSENT", - "EXPECT_URL", - "EXPECT_NO_CONSOLE_ERRORS", - "EXPECT_NO_FAILED_REQUESTS", - "SCREENSHOT", - "SET_VIEWPORT", - "RELOAD", - "SWITCH_CONTEXT" -]; -var BROWSER_ASSERTION_STEPS = [ - "EXPECT_SELECTOR", - "EXPECT_TEXT", - "EXPECT_ABSENT", - "EXPECT_URL", - "EXPECT_NO_CONSOLE_ERRORS", - "EXPECT_NO_FAILED_REQUESTS" -]; -var BROWSER_SCENARIO_STATUSES = [ - "PASSED", - "FAILED", - "ERRORED", - "SKIPPED_NO_RUNTIME", - "NOT_RUN" -]; -var BROWSER_EVIDENCE_KINDS = [ - "SCREENSHOT", - "DOM_SNAPSHOT", - "CONSOLE_LOG", - "NETWORK_FAILURES", - "STEP_TRACE", - "VIEWPORT_MATRIX" -]; -var UX_FINDING_KINDS = [ - "OVERLAPPING_ELEMENTS", - "CLIPPED_CONTENT", - "UNREADABLE_LAYOUT", - "BROKEN_RESPONSIVE", - "DEAD_INTERACTION", - "MISSING_LOADING_STATE", - "MISSING_ERROR_STATE", - "MISSING_EMPTY_STATE", - "INCONSISTENT_UX", - "UNUSABLE_CONTROL", - "VISUAL_REGRESSION", - "AESTHETIC_PREFERENCE" -]; -var UX_FINDING_SEVERITIES = ["MATERIAL", "MINOR", "COSMETIC"]; -var UX_CRITIQUE_VERDICTS = [ - "NO_MATERIAL_FINDINGS", - "MATERIAL_FINDINGS", - "NOT_RUN", - "INSUFFICIENT_EVIDENCE" -]; -var CLOSURE_STATUSES = [ - /** Nothing claims to implement this item. */ - "NOT_STARTED", - /** Work exists and is in flight. */ - "IN_PROGRESS", - /** Implementation exists and is attributed, but nothing has proven it. */ - "IMPLEMENTED", - /** Trusted evidence demonstrates the item holds. The only closing state. */ - "VERIFIED", - /** A human explicitly waived it, with a recorded reason. */ - "WAIVED", - /** Explicitly out of scope for this seal, by recorded decision. */ - "NOT_APPLICABLE" -]; var CLOSURE_EVIDENCE_KINDS = [ "TRUSTED_VERIFICATION", "UNIT_TEST", @@ -85178,33 +84881,107 @@ var ZERO_TOUCH_OUTCOMES = [ "NOT_RUN" ]; var CERTIFICATION_VERDICTS = ["CERTIFIED", "NOT_CERTIFIED", "INCOMPLETE"]; +var SBA_CODES = { + SBA001: "autonomy disabled by policy", + SBA002: "mission seal not found", + SBA003: "mission seal invalid", + SBA004: "mission seal not executable", + SBA005: "mission seal incomplete", + SBA006: "autonomy policy drift since seal", + SBA007: "product authority required", + SBA008: "supervisor lease held by another owner", + SBA009: "supervisor state invalid", + SBA010: "supervisor restart budget exhausted", + SBA011: "overnight preflight refused launch", + SBA012: "toolsmith capability denied", + SBA013: "toolsmith grant budget exhausted", + SBA014: "environment plan invalid", + SBA015: "environment provisioning failed", + SBA016: "environment runtime unavailable", + SBA017: "browser scenario invalid", + SBA018: "browser runtime unavailable", + SBA019: "ux critique rejected", + SBA020: "contract closure incomplete", + SBA021: "closure budget exhausted", + SBA022: "control plane repair refused", + SBA023: "control plane repair would weaken an invariant", + SBA024: "autonomy record invalid", + SBA025: "certification run invalid" +}; +var AutonomyError = class extends Error { + code; + category; + remediation; + details; + retryable; + constructor(code, message2, options = {}) { + super(message2); + this.name = "AutonomyError"; + this.code = code; + this.category = SBA_CODES[code]; + this.remediation = options.remediation ?? []; + this.details = options.details ?? {}; + this.retryable = options.retryable ?? false; + } +}; +function now3(deps) { + return (deps.clock ?? (() => /* @__PURE__ */ new Date()))(); +} +function nowIso2(deps) { + return now3(deps).toISOString(); +} +var ID_PATTERN4 = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/; +function assertAutonomyId(kind, id) { + if (!ID_PATTERN4.test(id)) { + throw new AutonomyError("SBA024", `Invalid ${kind} id "${id}".`, { + remediation: ["Ids are generated by SpecBridge; pass one returned by an autonomy operation."], + details: { kind, id } + }); + } + return id; +} function autonomyDir(workspace) { return assertInsideWorkspace( workspace.rootDir, - import_path47.default.join(workspace.rootDir, ".specbridge", "autonomy") + import_path49.default.join(workspace.rootDir, ".specbridge", "autonomy") ); } function autonomyPath(workspace, ...segments) { - return assertInsideWorkspace(workspace.rootDir, import_path47.default.join(autonomyDir(workspace), ...segments)); + return assertInsideWorkspace(workspace.rootDir, import_path49.default.join(autonomyDir(workspace), ...segments)); } function readJsonRecord(file, parse3) { - if (!(0, import_fs44.existsSync)(file)) return void 0; + if (!(0, import_fs46.existsSync)(file)) return void 0; try { - return parse3(JSON.parse((0, import_fs44.readFileSync)(file, "utf8"))); + return parse3(JSON.parse((0, import_fs46.readFileSync)(file, "utf8"))); } catch { return void 0; } } function listJsonRecords(dir, parse3) { - if (!(0, import_fs44.existsSync)(dir)) return []; + if (!(0, import_fs46.existsSync)(dir)) return []; const out = []; - for (const entry2 of (0, import_fs44.readdirSync)(dir).sort()) { + for (const entry2 of (0, import_fs46.readdirSync)(dir).sort()) { if (!entry2.endsWith(".json")) continue; - const value = readJsonRecord(import_path47.default.join(dir, entry2), parse3); + const value = readJsonRecord(import_path49.default.join(dir, entry2), parse3); if (value !== void 0) out.push(value); } return out; } +function readJsonl2(file, parse3, limit = 5e3) { + if (!(0, import_fs46.existsSync)(file)) return { entries: [], skipped: 0 }; + const lines = (0, import_fs46.readFileSync)(file, "utf8").split("\n").filter((line) => line.trim().length > 0); + const slice = lines.slice(-limit); + const entries = []; + let skipped = 0; + for (const line of slice) { + try { + entries.push(parse3(JSON.parse(line))); + } catch { + skipped += 1; + } + } + return { entries, skipped }; +} var SEAL_LIMITS = { maxShortTextChars: 200, maxTextChars: 4e3, @@ -85310,11 +85087,30 @@ var sealBindingSchema = external_exports.object({ function sealsDir(workspace) { return autonomyPath(workspace, "seals"); } +function sealFile(workspace, sealId) { + assertAutonomyId("seal", sealId); + return autonomyPath(workspace, "seals", `${sealId}.json`); +} +function bindingFile(workspace, jobId) { + assertAutonomyId("job", jobId); + return autonomyPath(workspace, "bindings", `${jobId}.json`); +} +function readSeal(workspace, sealId) { + return readJsonRecord(sealFile(workspace, sealId), (raw) => missionSealSchema.parse(raw)); +} function listSeals(workspace, missionId) { const seals = listJsonRecords(sealsDir(workspace), (raw) => missionSealSchema.parse(raw)); const filtered = missionId === void 0 ? seals : seals.filter((s) => s.missionId === missionId); return filtered.sort((a2, b) => a2.createdAt.localeCompare(b.createdAt)); } +function readSealBinding(workspace, jobId) { + return readJsonRecord(bindingFile(workspace, jobId), (raw) => sealBindingSchema.parse(raw)); +} +function readJobSeal(workspace, jobId) { + const binding = readSealBinding(workspace, jobId); + if (binding === void 0) return void 0; + return readSeal(workspace, binding.sealId); +} var DELEGATED_SURFACES = Object.freeze({ "implementation-structure": "implementation", "internal-architecture": "internalArchitecture", @@ -85427,6 +85223,16 @@ var supervisionLogEntrySchema = external_exports.object({ detail: text23.optional(), generation: external_exports.number().int().min(0).optional() }).passthrough(); +function supervisionLogFile(workspace) { + return autonomyPath(workspace, "supervisor", "log.jsonl"); +} +function readSupervisionLog(workspace, limit = 500) { + return readJsonl2( + supervisionLogFile(workspace), + (raw) => supervisionLogEntrySchema.parse(raw), + limit + ).entries; +} var shortText33 = external_exports.string().max(200); var text32 = external_exports.string().max(4e3); var capabilityCheckSchema = external_exports.object({ @@ -85528,6 +85334,24 @@ var CANONICAL_SCOPE = Object.freeze({ USER_LOCAL_CLI: "USER_LOCAL", BROWSER_RUNTIME: "USER_LOCAL" }); +function toolsmithDir(workspace, jobId) { + assertAutonomyId("job", jobId); + return autonomyPath(workspace, "toolsmith", jobId); +} +function listToolsmithRequests(workspace, jobId) { + return listJsonRecords( + toolsmithDir(workspace, jobId), + (raw) => toolsmithRequestSchema.parse(raw) + ).sort((a2, b) => a2.requestedAt.localeCompare(b.requestedAt)); +} +function writesFileDirectly(capability) { + return capability === "PROJECT_LOCAL_SCRIPT" || capability === "CODE_GENERATION"; +} +function countSelfCreatedTools(workspace, jobId) { + return listToolsmithRequests(workspace, jobId).filter( + (request) => request.status === "APPLIED" && writesFileDirectly(request.capability) + ).length; +} var PACKAGE_MANAGER_INSTALL_ARGV = Object.freeze({ pnpm: ["install", "--frozen-lockfile=false"], npm: ["install"], @@ -85766,6 +85590,12 @@ var browserScenarioResultSchema = external_exports.object({ /** The first failing step's detail, hoisted for the report. */ failureDetail: text62.optional() }).passthrough(); +function listBrowserResults(workspace) { + return listJsonRecords( + autonomyPath(workspace, "browser", "results"), + (raw) => browserScenarioResultSchema.parse(raw) + ).sort((a2, b) => a2.startedAt.localeCompare(b.startedAt)); +} var shortText72 = external_exports.string().max(200); var text72 = external_exports.string().max(4e3); var uxFindingSchema = external_exports.object({ @@ -85803,6 +85633,9 @@ var uxCritiqueSchema = external_exports.object({ /** True when the critique was recorded but may not create work. */ advisoryOnly: external_exports.boolean().default(false) }).passthrough(); +function listCritiques(workspace) { + return listJsonRecords(autonomyPath(workspace, "critic"), (raw) => uxCritiqueSchema.parse(raw)); +} var shortText82 = external_exports.string().max(200); var text82 = external_exports.string().max(4e3); var closureEvidenceRefSchema = external_exports.object({ @@ -85913,6 +85746,92 @@ var gapWorkItemSchema = external_exports.object({ /** The audit that generated it. */ auditId: shortText82 }).passthrough(); +function summarizeClosure(entries) { + const totals = { + total: entries.length, + verified: 0, + implemented: 0, + inProgress: 0, + notStarted: 0, + waived: 0, + notApplicable: 0 + }; + for (const entry2 of entries) { + switch (entry2.status) { + case "VERIFIED": + totals.verified += 1; + break; + case "IMPLEMENTED": + totals.implemented += 1; + break; + case "IN_PROGRESS": + totals.inProgress += 1; + break; + case "NOT_STARTED": + totals.notStarted += 1; + break; + case "WAIVED": + totals.waived += 1; + break; + case "NOT_APPLICABLE": + totals.notApplicable += 1; + break; + default: + break; + } + } + return totals; +} +function closureRatio(totals) { + if (totals.total === 0) return null; + return (totals.verified + totals.waived + totals.notApplicable) / totals.total; +} +function missionMayComplete(ledger, policy) { + const unclosed = ledger.entries.filter((entry2) => !isClosingStatus(entry2.status)); + if (ledger.entries.length === 0) { + return { + mayComplete: false, + reason: "the closure ledger is empty: a seal with no auditable contract items cannot be shown to be complete", + unclosedIds: [] + }; + } + if (unclosed.length > 0) { + return { + mayComplete: false, + reason: `${unclosed.length} sealed contract item(s) are not closed on trusted evidence`, + unclosedIds: unclosed.map((entry2) => entry2.itemId).slice(0, 100) + }; + } + if (policy.requireReleaseQualification && !ledger.releaseQualificationPassed) { + return { + mayComplete: false, + reason: "every item closes, but the release qualification has not passed against the integrated tree", + unclosedIds: [] + }; + } + if (policy.requireReproducibility && !ledger.reproducibilityPassed) { + return { + mayComplete: false, + reason: "every item closes, but reproducibility has not been demonstrated from a clean environment", + unclosedIds: [] + }; + } + return { + mayComplete: true, + reason: `all ${ledger.entries.length} sealed contract item(s) are closed`, + unclosedIds: [] + }; +} +function closureLedgerFile(workspace, jobId) { + assertAutonomyId("job", jobId); + return autonomyPath(workspace, "closure", jobId, "ledger.json"); +} +function readClosureLedger(workspace, jobId) { + return readJsonRecord( + closureLedgerFile(workspace, jobId), + (raw) => closureLedgerSchema.parse(raw) + ); +} var shortText92 = external_exports.string().max(200); var text92 = external_exports.string().max(4e3); var systemStepSchema = external_exports.object({ @@ -86021,6 +85940,7 @@ var reproducibilityResultSchema = external_exports.object({ inconclusiveReason: text10.optional(), failureDetail: text10.optional() }).passthrough(); +var TELEMETRY_SCHEMA_VERSION = "1.0.0"; var shortText112 = external_exports.string().max(200); var text11 = external_exports.string().max(4e3); var autonomyTelemetrySchema = external_exports.object({ @@ -86095,13 +86015,1478 @@ var INTERVENTION_EVENTS = Object.freeze({ // needs a person; only the event name differed. budget_exhausted: "the job stopped on an exhausted budget, needing an explicit user action" }); -var shortText122 = external_exports.string().max(200); +function deriveAutonomyTelemetry(deps, input) { + const read = readJobState(deps.workspace, input.jobId); + const job = read.kind === "ok" ? read.job : void 0; + const events = safeEvents(deps.workspace, input.jobId); + const counters = job?.autonomyCounters; + const interventions = []; + let providerFailovers = 0; + let providerFailures = 0; + let quotaWaits = 0; + let contextRollovers = 0; + let supervisorWakeups = 0; + let escalationsAfterBoundary = 0; + const bindingForBoundary = readSealBinding(deps.workspace, input.jobId); + const boundary = bindingForBoundary !== void 0 ? readSealedAt(deps, bindingForBoundary.sealId) : void 0; + const boundaryMs = boundary !== void 0 ? Date.parse(boundary) : Number.NaN; + const afterBoundary = (at) => { + if (!Number.isFinite(boundaryMs)) return true; + const eventMs = Date.parse(at); + return !Number.isFinite(eventMs) || eventMs >= boundaryMs; + }; + for (const event of events) { + const type = String(event["type"] ?? ""); + const at = String(event["at"] ?? ""); + const explanation = INTERVENTION_EVENTS[type]; + if (explanation !== void 0 && afterBoundary(at)) { + interventions.push({ at, kind: type, detail: explanation }); + } + if (type === "authority_escalated" && afterBoundary(at)) escalationsAfterBoundary += 1; + if (type === "worker_escalated" || type === "local_harness_to_subscription_escalated") { + providerFailovers += 1; + } + if (type === "local_model_stopped" || type === "local_harness_unavailable") providerFailures += 1; + if (type === "quota_exhausted" || type === "task_deferred" || type === "resource_wait_started") { + quotaWaits += 1; + } + if (type === "context_rollover" || type === "fresh_context_selected") contextRollovers += 1; + if (type === "driver_restarted" || type === "supervisor_attached") supervisorWakeups += 1; + } + const supervisionLog = readSupervisionLog(deps.workspace, 2e3); + supervisorWakeups += supervisionLog.filter( + (entry2) => entry2.action === "WOKEN_ON_SCHEDULE" || entry2.action === "WOKEN_ON_RESOURCE_RETURN" + ).length; + if (job !== void 0 && requiresHumanAttention(job.status) && job.status !== "NEEDS_AUTHORITY" && interventions.length === 0) { + interventions.push({ + at: job.updatedAt, + kind: `status:${job.status}`, + detail: job.blocker?.message ?? `the job is ${job.status} and cannot proceed without a person` + }); + } + const ledger = readClosureLedger(deps.workspace, input.jobId); + const totals = ledger !== void 0 ? summarizeClosure(ledger.entries) : void 0; + const toolsmith = listToolsmithRequests(deps.workspace, input.jobId); + const browserResults = listBrowserResults(deps.workspace).filter( + (result) => result.jobId === input.jobId + ); + const critiques = listCritiques(deps.workspace).filter( + (critique) => critique.jobId === input.jobId + ); + const binding = readSealBinding(deps.workspace, input.jobId); + const telemetry = autonomyTelemetrySchema.parse({ + schemaVersion: TELEMETRY_SCHEMA_VERSION, + jobId: input.jobId, + ...binding !== void 0 ? { sealId: binding.sealId, missionId: binding.missionId } : {}, + recordedAt: nowIso2(deps), + jobStatus: job?.status ?? "UNKNOWN", + humanInterventionsAfterSeal: interventions.length, + humanAuthorityEscalations: counters?.authorityEscalations ?? 0, + humanAuthorityEscalationsAfterSeal: boundary === void 0 ? null : escalationsAfterBoundary, + boundaryStartedAt: boundary ?? null, + autonomousRecoveryCount: counters?.autonomousRecoveries ?? 0, + providerFailovers, + providerFailures, + quotaWaits: Math.max(quotaWaits, counters?.resourceWaits ?? 0), + contextRollovers: Math.max(contextRollovers, counters?.contextRollovers ?? 0), + toolsmithActions: toolsmith.length, + selfCreatedTools: countSelfCreatedTools(deps.workspace, input.jobId), + toolchainRepairs: counters?.toolchainRepairs ?? 0, + environmentRepairs: counters?.environmentRepairs ?? 0, + controlPlaneRepairs: counters?.controlPlaneRepairs ?? 0, + gapClosureCycles: ledger?.gapCycles ?? counters?.gapClosureCycles ?? 0, + systemQualificationCycles: ledger?.systemCycles ?? counters?.systemQualificationCycles ?? 0, + browserScenariosRun: browserResults.length, + uxCritiquesRun: critiques.length, + driverRestarts: counters?.driverRestarts ?? 0, + supervisorWakeups, + elapsedWallTimeMs: input.elapsedWallTimeMs ?? elapsedFromJob(job), + // Provider-reported only. `null` when nothing reported, which is a + // different fact from "it was free". + reportedTokens: job?.counters.reportedTokens ?? null, + reportedCostUsd: job?.counters.reportedCostUsd ?? null, + contractClosureRatio: totals !== void 0 ? closureRatio(totals) : null, + ...totals !== void 0 ? { + closure: { + total: totals.total, + verified: totals.verified, + implemented: totals.implemented, + notStarted: totals.notStarted, + waived: totals.waived + } + } : {}, + interventions: interventions.slice(0, 200) + }); + return telemetry; +} +function elapsedFromJob(job) { + if (job === void 0) return null; + const created = Date.parse(job.createdAt); + const updated = Date.parse(job.finalizedAt ?? job.updatedAt); + if (!Number.isFinite(created) || !Number.isFinite(updated)) return null; + return Math.max(0, updated - created); +} +function readSealedAt(deps, sealId) { + try { + return readSeal(deps.workspace, sealId)?.sealedAt; + } catch { + return void 0; + } +} +function safeEvents(workspace, jobId) { + try { + return readJobEvents(workspace, jobId, { limit: 1e4 }).events; + } catch { + return []; + } +} +var EXECUTION_TELEMETRY_REPORT_SCHEMA_VERSION = "1.0.0"; +var count3 = external_exports.number().int().min(0); +var shortText122 = external_exports.string().max(512); +var boundedText7 = external_exports.string().max(2e3); +var ratio2 = external_exports.number().min(0).max(1).nullable(); +var countMap = external_exports.record(external_exports.string(), count3); +var fractionMetricSchema = external_exports.object({ + numerator: count3.nullable(), + denominator: count3.nullable(), + value: ratio2 +}).strict(); +var tokenCoverageSchema = external_exports.object({ + attempts: count3, + withAny: count3, + withInput: count3, + withOutput: count3, + ratio: ratio2, + complete: external_exports.boolean() +}).strict(); +var tokenTelemetrySchema = external_exports.object({ + /** Sum of every reported input-token field; null when none reported. */ + inputTokens: count3.nullable(), + /** Sum of every reported output-token field; null when none reported. */ + outputTokens: count3.nullable(), + /** Sum of known components, even when coverage is partial. */ + knownTokens: count3.nullable(), + /** Total only when every attempt reported both components. */ + completeTokens: count3.nullable(), + coverage: tokenCoverageSchema +}).strict(); +var workAccountingSchema = external_exports.enum([ + "completed", + "failed", + "cancelled", + "waiting", + "not-ready", + "human-authority-pending", + "research-pending", + "context-pending" +]); +var diagnosticSchema = external_exports.object({ + code: shortText122, + severity: external_exports.enum(["info", "warning", "error"]), + message: boundedText7, + evidenceRefs: external_exports.array(shortText122).max(20).default([]) +}).strict(); +var phaseResearchSchema = external_exports.object({ + considered: count3, + avoided: count3, + reused: count3, + newCalls: count3, + quick: count3, + deep: count3, + failed: count3 +}).strict(); +var executionTelemetryReportSchema = external_exports.object({ + schemaVersion: external_exports.literal(EXECUTION_TELEMETRY_REPORT_SCHEMA_VERSION), + jobId: shortText122, + missionId: shortText122.nullable(), + generatedAt: shortText122, + period: external_exports.object({ + startedAt: shortText122, + endedAt: shortText122.nullable(), + durationMs: count3.nullable(), + activeExecutionMs: count3.nullable() + }).strict(), + provenance: external_exports.object({ + sourceJobId: shortText122, + jobGraphRevision: count3, + objectiveGraphRevisions: countMap, + executionLedgerWatermark: external_exports.string().regex(/^[a-f0-9]{64}$/), + eventWatermark: count3, + specbridgeVersion: shortText122.nullable(), + sealId: shortText122.nullable(), + sealedAuthorityDigest: shortText122.nullable(), + runtimePolicyChanged: external_exports.boolean().nullable(), + configuration: external_exports.object({ + secondaryBuildStrategy: shortText122, + researchStrategy: shortText122, + runnerProfiles: external_exports.array(shortText122).max(50) + }).strict() + }).strict(), + outcome: external_exports.object({ + status: external_exports.enum(["COMPLETED", "FAILED", "CANCELLED", "BLOCKED", "WAITING"]), + authoritativeJobStatus: shortText122, + finalOutcome: boundedText7.nullable(), + verification: external_exports.enum(["PASS", "FAIL", "UNAVAILABLE"]), + closure: external_exports.enum(["PASS", "FAIL", "UNAVAILABLE"]) + }).strict(), + work: external_exports.object({ + total: count3, + byKind: countMap, + accounting: external_exports.record(workAccountingSchema, count3), + completedImplementation: count3, + objectives: external_exports.array(external_exports.object({ + objectiveNodeId: shortText122, + graphRevision: count3.nullable(), + total: count3, + accounting: external_exports.record(workAccountingSchema, count3), + implementationAttempts: count3, + secondaryAttempts: count3, + strongBuilderAttempts: count3 + }).strict()).max(200), + units: external_exports.array(external_exports.object({ + workUnitId: shortText122, + objectiveNodeId: shortText122, + kind: shortText122, + status: shortText122, + accounting: workAccountingSchema, + builderPath: external_exports.enum(["SECONDARY", "SECONDARY_REPAIR", "STRONG", "STRONG_FALLBACK", "NONE", "UNKNOWN"]), + implementationAttempts: count3, + verification: external_exports.enum(["PASS", "FAIL", "PENDING", "UNAVAILABLE"]), + integration: external_exports.enum(["INTEGRATED", "NOT_INTEGRATED"]) + }).strict()).max(500), + omittedUnits: count3 + }).strict(), + secondary: external_exports.object({ + eligibility: external_exports.object({ + eligible: count3, + ineligible: count3, + strongRequired: count3, + needsResearch: count3, + needsAuthority: count3, + needsContext: count3, + notReady: count3, + unavailable: count3 + }).strict(), + selection: external_exports.object({ + secondarySelected: count3, + strongSelectedDespiteEligibility: count3, + noBuilderNeeded: count3, + waitingForResource: count3 + }).strict(), + funnel: external_exports.object({ + initialAttempts: count3, + initialPass: count3, + repairAttempted: count3, + repairPass: count3, + toStrongFallback: count3, + unavailableFallback: count3 + }).strict(), + initialSuccessRate: fractionMetricSchema, + repairRecoveryRate: fractionMetricSchema, + toStrongFallbackRate: fractionMetricSchema, + fallbackReasons: countMap, + builderTokens: tokenTelemetrySchema + }).strict(), + strong: external_exports.object({ + builderAttempts: count3, + evaluatorAttempts: count3, + selection: external_exports.object({ + requiredDirect: count3, + byStrategyOff: count3, + byAutoPolicy: count3, + becauseSecondaryUnavailable: count3, + fallbackAfterSecondary: count3 + }).strict(), + implementationTokens: tokenTelemetrySchema, + evaluatorTokens: tokenTelemetrySchema + }).strict(), + research: external_exports.object({ + scope: external_exports.enum(["JOB", "WORKSPACE", "NONE"]), + considered: count3.nullable(), + decisions: countMap, + providerCalls: count3, + successful: count3, + inconclusive: count3, + failed: count3, + priorResearchReused: count3, + newQuick: count3, + newDeep: count3, + avoidanceRatio: fractionMetricSchema, + reuseRate: fractionMetricSchema, + byPhase: external_exports.record(external_exports.string(), phaseResearchSchema), + usage: external_exports.object({ + inputTokens: count3.nullable(), + outputTokens: count3.nullable(), + durationMs: count3.nullable(), + providerReportedCost: external_exports.number().min(0).nullable(), + subagentCount: count3.nullable(), + recordsWithUsage: count3, + providerCalls: count3, + coverage: ratio2 + }).strict() + }).strict(), + cooldown: external_exports.object({ + episodes: count3, + observations: count3, + totalDurationMs: count3.nullable(), + usefulWorkDuringSubscriptionCooldown: count3, + secondaryImplementationWorkDuringCooldown: count3, + researchWorkDuringCooldown: count3, + strongRequiredWaiting: count3, + avoidableIdlePeriods: count3, + intervals: external_exports.array(external_exports.object({ + objectiveNodeId: shortText122, + status: external_exports.enum(["ACTIVE", "RECOVERED"]), + startedAt: shortText122, + endedAt: shortText122.nullable(), + durationMs: count3.nullable(), + completedWorkUnits: count3 + }).strict()).max(200), + timeline: external_exports.array(external_exports.object({ + at: shortText122, + type: shortText122, + objectiveNodeId: shortText122.nullable(), + detail: boundedText7 + }).strict()).max(200) + }).strict(), + attempts: external_exports.object({ + uniqueImplementationAttempts: count3, + meanPerCompletedWorkUnit: external_exports.number().min(0).nullable(), + medianPerCompletedWorkUnit: external_exports.number().min(0).nullable(), + maxPerWorkUnit: count3, + workUnitsWithMultipleAttempts: count3, + byKind: countMap, + completedWorkUnitsPerImplementationAttempt: external_exports.number().min(0).nullable(), + completedWorkUnitsPerStrongBuilderCall: external_exports.number().min(0).nullable(), + completedEligibleWorkUnitsPerSecondaryAttempt: external_exports.number().min(0).nullable() + }).strict(), + verification: external_exports.object({ + attempts: count3, + passes: count3, + failures: count3, + otherVerdicts: count3, + failuresByBuilderBackend: countMap, + failuresRecoveredByRepair: count3, + failuresRecoveredByStrongFallback: count3 + }).strict(), + closure: external_exports.object({ + available: external_exports.boolean(), + items: count3, + earned: count3, + waived: count3, + unresolved: count3, + completionGateOutcome: external_exports.enum(["PASS", "FAIL", "UNAVAILABLE"]), + ratio: ratio2 + }).strict(), + human: external_exports.object({ + decisionsBeforeSeal: count3.nullable(), + approvals: count3, + authorityEscalationsAfterSeal: count3.nullable(), + interventionsAfterSeal: count3, + unexpectedBlockersAfterSeal: count3, + zeroTouchAfterSeal: external_exports.boolean(), + byKind: countMap + }).strict(), + reliability: external_exports.object({ + failureSources: countMap, + recoveryActions: countMap, + noProgressDetections: count3, + repeatedProblemFingerprints: count3, + legitimateResourceWaitsExcluded: count3, + processRestarts: count3, + supervisorRestarts: count3, + candidatesPersisted: count3, + candidatesReusedAfterRestart: count3, + candidateRebuildsAfterRestart: count3, + candidatesLostOrUnreadable: count3, + candidateReadyResumes: count3, + integrationRetries: count3, + completedWorkRedoCount: count3, + completedWorkReusedAfterRestart: count3, + attemptsIncorrectlyRepeated: count3, + unexpectedBlocks: count3, + unrecoveredDriverDeaths: count3 + }).strict(), + efficiency: external_exports.object({ + strongBuilderAvoidanceRatio: fractionMetricSchema, + strongBuilderCallsAvoided: count3, + completedWorkUnitsPerImplementationAttempt: external_exports.number().min(0).nullable(), + baseline: external_exports.object({ + kind: external_exports.enum(["OBSERVED", "QUALIFICATION_FIXTURE"]), + reportId: shortText122, + strongBuilderAttempts: count3, + sameVerificationOutcome: external_exports.boolean(), + sameClosureOutcome: external_exports.boolean() + }).strict().nullable() + }).strict(), + qualificationSummary: external_exports.object({ + strongBuilderAvoidanceRatio: ratio2, + secondaryInitialSuccessRate: ratio2, + secondaryRepairRecoveryRate: ratio2, + secondaryToStrongFallback: count3, + strongImplementationTokens: count3.nullable(), + researchAvoidanceRatio: ratio2, + newResearchCalls: count3, + researchReuse: count3, + usefulWorkDuringSubscriptionCooldown: count3, + humanInterventionsAfterSeal: count3, + completedWorkRedoCount: count3, + unexpectedBlocks: count3, + unrecoveredDriverDeaths: count3 + }).strict(), + diagnostics: external_exports.array(diagnosticSchema).max(200) +}).strict(); +var SECRET_PATTERNS2 = [ + /-----BEGIN (?:RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----/gi, + /\b(?:bearer|basic)\s+[A-Za-z0-9+/=_-]{12,}/gi, + /\b(?:sk|ghp|github_pat|xox[baprs])[_-][A-Za-z0-9_-]{12,}\b/gi, + /\b(?:api[-_ ]?key|auth[-_ ]?token|access[-_ ]?token|password|secret)\s*[:=]\s*\S{8,}/gi +]; +function redactTelemetryText(value) { + let redacted = value; + for (const pattern of SECRET_PATTERNS2) redacted = redacted.replace(pattern, "[REDACTED]"); + return redacted.slice(0, 2e3); +} +function increment2(record4, key, by = 1) { + record4[key] = (record4[key] ?? 0) + by; +} +function metric(numerator, denominator) { + return { + numerator, + denominator, + value: numerator === null || denominator === null || denominator === 0 ? null : numerator / denominator + }; +} +function tokenTelemetry(attempts, usage) { + let input = 0; + let output = 0; + let withInput = 0; + let withOutput = 0; + let withAny = 0; + for (const attempt of attempts) { + const reported = usage(attempt); + const hasInput = reported.input !== null && reported.input !== void 0; + const hasOutput = reported.output !== null && reported.output !== void 0; + if (hasInput) { + input += reported.input ?? 0; + withInput += 1; + } + if (hasOutput) { + output += reported.output ?? 0; + withOutput += 1; + } + if (hasInput || hasOutput) withAny += 1; + } + const attemptCount = attempts.length; + const complete = attemptCount > 0 && withInput === attemptCount && withOutput === attemptCount; + return { + inputTokens: withInput > 0 ? input : null, + outputTokens: withOutput > 0 ? output : null, + knownTokens: withAny > 0 ? input + output : null, + completeTokens: complete ? input + output : null, + coverage: { + attempts: attemptCount, + withAny, + withInput, + withOutput, + ratio: attemptCount === 0 ? null : withAny / attemptCount, + complete + } + }; +} +function timestampMs(value) { + if (value === null || value === void 0) return void 0; + const parsed = Date.parse(value); + return Number.isFinite(parsed) ? parsed : void 0; +} +function outcomeStatus(status) { + if (status === "COMPLETED") return "COMPLETED"; + if (status === "FAILED") return "FAILED"; + if (status === "CANCELLED") return "CANCELLED"; + if (status === "BLOCKED" || status === "NEEDS_AUTHORITY" || status === "NEEDS_CLARIFICATION") { + return "BLOCKED"; + } + return "WAITING"; +} +function verificationOutcome(job, events) { + const status = job.latestEvidence?.evidenceStatus; + if (status === "verified" || status === "manually-accepted") return "PASS"; + const lastFailure = [...events].reverse().find((event) => event.type === "verification_failed"); + if (lastFailure !== void 0 && job.latestEvidence === void 0) return "FAIL"; + return "UNAVAILABLE"; +} +function currentRoutingStates(objectives) { + const current = /* @__PURE__ */ new Map(); + for (const objective of objectives) { + for (const state of objective.routingStates) { + const key = `${objective.objectiveNodeId}\0${state.workUnitId}`; + const prior = current.get(key); + if (prior === void 0 || state.updatedAt.localeCompare(prior.updatedAt, "en") > 0 || state.updatedAt === prior.updatedAt && state.contentHash.localeCompare(prior.contentHash, "en") > 0) { + current.set(key, state); + } + } + } + return current; +} +function uniqueBuilderAttempts(objectives) { + const seen = /* @__PURE__ */ new Map(); + let duplicateIds = 0; + for (const objective of objectives) { + for (const state of objective.routingStates) { + for (const attempt of state.attempts) { + const key = `${objective.objectiveNodeId}\0${state.workUnitId}\0${attempt.attemptId}`; + if (seen.has(key)) { + duplicateIds += 1; + continue; + } + seen.set(key, { ...attempt, objectiveNodeId: objective.objectiveNodeId, workUnitId: state.workUnitId }); + } + } + } + return { + attempts: [...seen.values()].sort( + (left, right) => left.startedAt.localeCompare(right.startedAt, "en") || left.objectiveNodeId.localeCompare(right.objectiveNodeId, "en") || left.workUnitId.localeCompare(right.workUnitId, "en") || left.sequence - right.sequence + ), + duplicateIds + }; +} +function latestUnits(objectives) { + const units = []; + for (const objective of objectives) { + for (const unit of objective.graph?.units ?? []) { + units.push({ objectiveNodeId: objective.objectiveNodeId, unit }); + } + } + return units.sort( + (left, right) => left.objectiveNodeId.localeCompare(right.objectiveNodeId, "en") || left.unit.workUnitId.localeCompare(right.unit.workUnitId, "en") + ); +} +function workAccounting(unit, routing) { + if (unit.status === "INTEGRATED") return "completed"; + if (unit.status === "FAILED") return "failed"; + if (unit.status === "SUPERSEDED") return "cancelled"; + const eligibility = routing?.initialEligibility; + if (eligibility === "NEEDS_AUTHORITY") return "human-authority-pending"; + if (eligibility === "NEEDS_RESEARCH") return "research-pending"; + if (eligibility === "NEEDS_CONTEXT") return "context-pending"; + if (eligibility === "NOT_READY" || unit.status === "PLANNED") return "not-ready"; + return "waiting"; +} +function builderPath(attempts) { + if (attempts.some((attempt) => attempt.kind === "STRONG_FALLBACK")) return "STRONG_FALLBACK"; + if (attempts.some((attempt) => attempt.kind === "STRONG")) return "STRONG"; + if (attempts.some((attempt) => attempt.kind === "SECONDARY_REPAIR")) return "SECONDARY_REPAIR"; + if (attempts.some((attempt) => attempt.kind === "SECONDARY")) return "SECONDARY"; + return attempts.length === 0 ? "NONE" : "UNKNOWN"; +} +function verificationFor(evaluations) { + if (evaluations.some((entry2) => entry2.verdict === "FAIL")) return "FAIL"; + if (evaluations.some((entry2) => entry2.verdict === "PASS")) return "PASS"; + if (evaluations.length > 0) return "PENDING"; + return "UNAVAILABLE"; +} +function fallbackReason(attempts) { + const preceding = [...attempts].reverse().find((attempt) => attempt.kind === "SECONDARY" || attempt.kind === "SECONDARY_REPAIR"); + if (preceding === void 0) return "other"; + if (preceding.noProgress) return "no-progress"; + switch (preceding.outcome) { + case "FAILED_VERIFICATION": + return "verification-failure"; + case "FAILED_OUTPUT": + return "malformed-model-result"; + case "FAILED_RESOURCE": + return "capability-failure"; + case "FAILED_IMPLEMENTATION": + return /context|stale source|insufficient/i.test(preceding.failureSummary ?? "") ? "context-insufficiency" : "implementation-failure"; + default: + return "other"; + } +} +function median(values) { + if (values.length === 0) return null; + const sorted = [...values].sort((left, right) => left - right); + const middle = Math.floor(sorted.length / 2); + if (sorted.length % 2 === 1) return sorted[middle] ?? null; + return ((sorted[middle - 1] ?? 0) + (sorted[middle] ?? 0)) / 2; +} +function deriveExecutionTelemetryReport(facts) { + const diagnostics = []; + const generatedMs = timestampMs(facts.generatedAt) ?? 0; + const eventTypes = (type) => facts.events.filter((event) => event.type === type); + const currentRouting = currentRoutingStates(facts.objectives); + const { attempts: implementationAttempts, duplicateIds } = uniqueBuilderAttempts(facts.objectives); + const units = latestUnits(facts.objectives); + const evaluations = facts.objectives.flatMap((objective) => objective.evaluations).filter((entry2, index, values) => values.findIndex((other) => other.evaluationId === entry2.evaluationId) === index).sort((left, right) => left.createdAt.localeCompare(right.createdAt, "en")); + if (facts.eventTotal > facts.events.length) { + diagnostics.push({ + code: "EVENT_WINDOW_BOUNDED", + severity: "info", + message: `The report used the newest ${facts.events.length} of ${facts.eventTotal} job events; ledgers and current state remain authoritative for aggregates.`, + evidenceRefs: [] + }); + } + if (facts.objectives.length === 0) { + diagnostics.push({ + code: "OBJECTIVE_TELEMETRY_UNAVAILABLE", + severity: "info", + message: "No objective-runtime records exist; Phase 7/8 metrics are unavailable for this older or direct-execution job.", + evidenceRefs: [] + }); + } + if (facts.autonomy.boundaryStartedAt === null) { + diagnostics.push({ + code: "ZERO_TOUCH_BOUNDARY_UNAVAILABLE", + severity: "info", + message: "No durable seal boundary exists; intervention counting conservatively includes the whole recorded Job history.", + evidenceRefs: [] + }); + } + if (duplicateIds > 0) { + diagnostics.push({ + code: "ATTEMPT_REPLAY_DEDUPLICATED", + severity: "info", + message: `${duplicateIds} replayed builder-attempt record${duplicateIds === 1 ? "" : "s"} were ignored by durable attempt id.`, + evidenceRefs: [] + }); + } + if (facts.researchTelemetryDiagnostic !== void 0) { + diagnostics.push({ + code: "RESEARCH_TELEMETRY_UNREADABLE", + severity: "warning", + message: redactTelemetryText(facts.researchTelemetryDiagnostic), + evidenceRefs: [] + }); + } + for (const diagnostic of facts.researchRecordDiagnostics ?? []) { + diagnostics.push({ + code: diagnostic.code.slice(0, 512), + severity: "warning", + message: redactTelemetryText(diagnostic.message), + evidenceRefs: [] + }); + } + const attemptsByUnit = /* @__PURE__ */ new Map(); + for (const attempt of implementationAttempts) { + const key = `${attempt.objectiveNodeId}\0${attempt.workUnitId}`; + const list = attemptsByUnit.get(key) ?? []; + list.push(attempt); + attemptsByUnit.set(key, list); + } + const evaluationsByUnit = /* @__PURE__ */ new Map(); + for (const evaluation of evaluations) { + const key = `${evaluation.objectiveNodeId}\0${evaluation.workUnitId}`; + const list = evaluationsByUnit.get(key) ?? []; + list.push(evaluation); + evaluationsByUnit.set(key, list); + } + const workAccountingCounts = { + completed: 0, + failed: 0, + cancelled: 0, + waiting: 0, + "not-ready": 0, + "human-authority-pending": 0, + "research-pending": 0, + "context-pending": 0 + }; + const workByKind = {}; + const unitSummaries = []; + for (const entry2 of units) { + const key = `${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`; + const routing = currentRouting.get(key); + const unitAttempts = attemptsByUnit.get(key) ?? []; + const unitEvaluations = evaluationsByUnit.get(key) ?? []; + const accounting = workAccounting(entry2.unit, routing); + workAccountingCounts[accounting] += 1; + increment2(workByKind, entry2.unit.kind); + if (unitSummaries.length < 500) { + unitSummaries.push({ + workUnitId: entry2.unit.workUnitId, + objectiveNodeId: entry2.objectiveNodeId, + kind: entry2.unit.kind, + status: entry2.unit.status, + accounting, + builderPath: builderPath(unitAttempts), + implementationAttempts: unitAttempts.length, + verification: verificationFor(unitEvaluations), + integration: entry2.unit.status === "INTEGRATED" ? "INTEGRATED" : "NOT_INTEGRATED" + }); + } + } + const eligibility = { + eligible: 0, + ineligible: 0, + strongRequired: 0, + needsResearch: 0, + needsAuthority: 0, + needsContext: 0, + notReady: 0, + unavailable: units.filter((entry2) => entry2.unit.kind === "build" && !currentRouting.has(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`)).length + }; + const selection = { + secondarySelected: 0, + strongSelectedDespiteEligibility: 0, + noBuilderNeeded: 0, + waitingForResource: 0 + }; + const strongSelection = { + requiredDirect: 0, + byStrategyOff: 0, + byAutoPolicy: 0, + becauseSecondaryUnavailable: 0, + fallbackAfterSecondary: 0 + }; + const fallbackReasons = {}; + for (const entry2 of units) { + if (entry2.unit.kind !== "build") { + selection.noBuilderNeeded += 1; + continue; + } + const key = `${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`; + const state = currentRouting.get(key); + if (state === void 0) continue; + switch (state.initialEligibility) { + case "ELIGIBLE": + eligibility.eligible += 1; + break; + case "STRONG_REQUIRED": + eligibility.strongRequired += 1; + break; + case "NEEDS_RESEARCH": + eligibility.needsResearch += 1; + break; + case "NEEDS_AUTHORITY": + eligibility.needsAuthority += 1; + break; + case "NEEDS_CONTEXT": + eligibility.needsContext += 1; + break; + case "NOT_READY": + eligibility.notReady += 1; + break; + default: + break; + } + const decisions = state.decisions; + const unitAttempts = attemptsByUnit.get(key) ?? []; + if (entry2.unit.resourceWait !== void 0) selection.waitingForResource += 1; + if (state.initialEligibility === "ELIGIBLE") { + if (decisions.some((decision) => decision.selectedBackend === "SECONDARY")) { + selection.secondarySelected += 1; + } else if (decisions.some((decision) => decision.selectedBackend === "STRONG")) { + selection.strongSelectedDespiteEligibility += 1; + } + } + const directStrong = decisions.find((decision) => decision.selectedBackend === "STRONG"); + if (directStrong !== void 0 && !unitAttempts.some((attempt) => attempt.kind === "STRONG_FALLBACK")) { + if (state.initialEligibility === "STRONG_REQUIRED") strongSelection.requiredDirect += 1; + else if (directStrong.reasons.some((reason) => reason.code === "STRATEGY_OFF")) strongSelection.byStrategyOff += 1; + else if (directStrong.reasons.some((reason) => reason.code === "SECONDARY_UNAVAILABLE")) { + strongSelection.becauseSecondaryUnavailable += 1; + } else if (directStrong.reasons.some((reason) => reason.code === "SUBSCRIPTION_HARVEST" || reason.code === "SECONDARY_AUTO_POLICY" || reason.code === "CRITICAL_WORK_PREFERS_STRONG")) { + strongSelection.byAutoPolicy += 1; + } + } + if (unitAttempts.some((attempt) => attempt.kind === "STRONG_FALLBACK")) { + strongSelection.fallbackAfterSecondary += 1; + increment2(fallbackReasons, fallbackReason(unitAttempts)); + } + } + eligibility.ineligible = eligibility.strongRequired + eligibility.needsResearch + eligibility.needsAuthority + eligibility.needsContext + eligibility.notReady; + const eligibleUnits = units.filter((entry2) => { + const state = currentRouting.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`); + return entry2.unit.kind === "build" && state?.initialEligibility === "ELIGIBLE"; + }); + const eligibleCompleted = eligibleUnits.filter((entry2) => entry2.unit.status === "INTEGRATED"); + const eligibleCompletedWithoutStrong = eligibleCompleted.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return !attempts.some((attempt) => attempt.kind === "STRONG" || attempt.kind === "STRONG_FALLBACK"); + }); + const secondaryAttemptedUnits = eligibleUnits.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => (attempt.kind === "SECONDARY" || attempt.kind === "SECONDARY_REPAIR") && attempt.outcome !== "FAILED_RESOURCE" && attempt.outcome !== "CANCELLED"); + }); + const initialAttemptedUnits = eligibleUnits.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => attempt.kind === "SECONDARY" && attempt.outcome !== "FAILED_RESOURCE" && attempt.outcome !== "CANCELLED"); + }); + const initialPassUnits = initialAttemptedUnits.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => attempt.kind === "SECONDARY" && attempt.outcome === "SUCCEEDED"); + }); + const repairAttemptedUnits = eligibleUnits.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => attempt.kind === "SECONDARY_REPAIR" && attempt.outcome !== "FAILED_RESOURCE" && attempt.outcome !== "CANCELLED"); + }); + const repairPassUnits = repairAttemptedUnits.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => attempt.kind === "SECONDARY_REPAIR" && attempt.outcome === "SUCCEEDED"); + }); + const fallbackUnits = eligibleUnits.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => attempt.kind === "STRONG_FALLBACK"); + }); + const unavailableFallbackUnits = eligibleUnits.filter((entry2) => { + const state = currentRouting.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`); + return state?.decisions.some((decision) => decision.selectedBackend === "STRONG" && decision.reasons.some((reason) => reason.code === "SECONDARY_UNAVAILABLE")) === true; + }); + const secondaryAttempts = implementationAttempts.filter((attempt) => attempt.kind === "SECONDARY" || attempt.kind === "SECONDARY_REPAIR"); + const strongAttempts = implementationAttempts.filter((attempt) => attempt.kind === "STRONG" || attempt.kind === "STRONG_FALLBACK"); + const strongEvaluatorAttempts = facts.ledger.filter((entry2) => entry2.role === "EVALUATOR" && entry2.lane !== "LOCAL"); + const secondaryTokens = tokenTelemetry(secondaryAttempts, (attempt) => ({ + input: attempt.inputTokens, + output: attempt.outputTokens + })); + const strongTokens = tokenTelemetry(strongAttempts, (attempt) => ({ + input: attempt.inputTokens, + output: attempt.outputTokens + })); + const evaluatorTokens = tokenTelemetry(strongEvaluatorAttempts, (attempt) => ({ + input: attempt.metrics.inputTokens, + output: attempt.metrics.outputTokens + })); + const jobResearchRecords = facts.researchRecords.filter((record4) => record4.scope?.jobId === facts.job.jobId); + const jobResearchIds = new Set(jobResearchRecords.map((record4) => record4.researchId)); + const jobResearchUses = facts.researchUses.filter((use) => jobResearchIds.has(use.researchId)); + const hasJobResearch = jobResearchRecords.length > 0 || jobResearchUses.length > 0; + const hasWorkspaceResearch = (facts.researchTelemetry?.gateConsidered ?? 0) > 0 || facts.researchRecords.length > 0 || facts.researchUses.length > 0; + const researchScope = hasJobResearch ? "JOB" : hasWorkspaceResearch ? "WORKSPACE" : "NONE"; + const reportResearchRecords = hasJobResearch ? jobResearchRecords : facts.researchRecords; + const reportResearchUses = hasJobResearch ? jobResearchUses : facts.researchUses; + const useIds = new Set(reportResearchUses.map((use) => use.useId)); + const uniqueUses = reportResearchUses.filter((use) => { + if (!useIds.has(use.useId)) return false; + useIds.delete(use.useId); + return true; + }); + const providerRecords = reportResearchRecords.filter((record4) => record4.status !== "PENDING"); + const workspaceResearch = researchScope === "WORKSPACE"; + const providerCallCount = workspaceResearch ? facts.researchTelemetry?.providerCalls ?? providerRecords.length : providerRecords.length; + const successfulResearch = workspaceResearch ? facts.researchTelemetry?.successfulResearch ?? providerRecords.filter((record4) => record4.status === "COMPLETED").length : providerRecords.filter((record4) => record4.status === "COMPLETED").length; + const inconclusiveResearch = workspaceResearch ? facts.researchTelemetry?.inconclusiveResearch ?? providerRecords.filter((record4) => record4.status === "INCONCLUSIVE").length : providerRecords.filter((record4) => record4.status === "INCONCLUSIVE").length; + const failedResearch = workspaceResearch ? facts.researchTelemetry?.failedResearch ?? providerRecords.filter((record4) => record4.status === "FAILED").length : providerRecords.filter((record4) => record4.status === "FAILED").length; + const reuseCount = workspaceResearch ? facts.researchTelemetry?.reusedReports ?? uniqueUses.filter((use) => use.useKind === "REUSED").length : uniqueUses.filter((use) => use.useKind === "REUSED").length; + const newQuick = workspaceResearch ? facts.researchTelemetry?.newQuick ?? providerRecords.filter((record4) => record4.depth === "QUICK").length : providerRecords.filter((record4) => record4.depth === "QUICK").length; + const newDeep = workspaceResearch ? facts.researchTelemetry?.newDeep ?? providerRecords.filter((record4) => record4.depth === "DEEP").length : providerRecords.filter((record4) => record4.depth === "DEEP").length; + const researchConsidered = researchScope === "WORKSPACE" ? facts.researchTelemetry?.gateConsidered ?? null : null; + const researchAvoided = researchScope === "WORKSPACE" ? facts.researchTelemetry?.researchAvoided ?? null : null; + const researchDecisions = researchScope === "WORKSPACE" ? { ...facts.researchTelemetry?.decisions ?? {} } : {}; + const byPhase = {}; + for (const phase of ["CONVERSATION", "SPEC_DRAFT", "INTAKE_DECISION", "RUNTIME_INVESTIGATION"]) { + const aggregate = researchScope === "WORKSPACE" ? facts.researchTelemetry?.byPhase[phase] : void 0; + const phaseRecords = providerRecords.filter((record4) => record4.lifecycle?.phase === phase); + const phaseUses = uniqueUses.filter((use) => use.phase === phase); + byPhase[phase] = { + considered: aggregate?.considered ?? 0, + avoided: aggregate?.avoided ?? 0, + reused: researchScope === "WORKSPACE" ? aggregate?.reused ?? phaseUses.filter((use) => use.useKind === "REUSED").length : phaseUses.filter((use) => use.useKind === "REUSED").length, + newCalls: researchScope === "WORKSPACE" ? (aggregate?.newQuick ?? 0) + (aggregate?.newDeep ?? 0) : phaseRecords.length, + quick: researchScope === "WORKSPACE" ? aggregate?.newQuick ?? phaseRecords.filter((record4) => record4.depth === "QUICK").length : phaseRecords.filter((record4) => record4.depth === "QUICK").length, + deep: researchScope === "WORKSPACE" ? aggregate?.newDeep ?? phaseRecords.filter((record4) => record4.depth === "DEEP").length : phaseRecords.filter((record4) => record4.depth === "DEEP").length, + failed: phaseRecords.filter((record4) => record4.status === "FAILED").length + }; + } + let researchInputTokens = 0; + let researchOutputTokens = 0; + let researchDurationMs = 0; + let researchCost = 0; + let researchSubagents = 0; + let researchInputObserved = false; + let researchOutputObserved = false; + let researchDurationObserved = false; + let researchCostObserved = false; + let researchSubagentsObserved = false; + let recordsWithUsage = 0; + for (const record4 of providerRecords) { + const usage = record4.usage ?? record4.report?.usage; + if (usage === void 0) continue; + recordsWithUsage += 1; + if (usage.inputTokens !== void 0) { + researchInputObserved = true; + researchInputTokens += usage.inputTokens; + } + if (usage.outputTokens !== void 0) { + researchOutputObserved = true; + researchOutputTokens += usage.outputTokens; + } + if (usage.durationMs !== void 0) { + researchDurationObserved = true; + researchDurationMs += usage.durationMs; + } + if (usage.providerReportedCost !== void 0) { + researchCostObserved = true; + researchCost += usage.providerReportedCost; + } + if (usage.subagentCount !== void 0) { + researchSubagentsObserved = true; + researchSubagents += usage.subagentCount; + } + } + if (researchScope === "WORKSPACE" && providerRecords.length === 0 && facts.researchTelemetry !== void 0) { + const reported = facts.researchTelemetry.reportedUsage; + if (reported.reports > 0) { + recordsWithUsage = reported.reports; + if (reported.inputTokens > 0) { + researchInputObserved = true; + researchInputTokens = reported.inputTokens; + } + if (reported.outputTokens > 0) { + researchOutputObserved = true; + researchOutputTokens = reported.outputTokens; + } + if (reported.providerReportedCost > 0) { + researchCostObserved = true; + researchCost = reported.providerReportedCost; + } + if (reported.subagentCount > 0) { + researchSubagentsObserved = true; + researchSubagents = reported.subagentCount; + } + } + if (facts.researchTelemetry.totalDurationMs > 0) { + researchDurationObserved = true; + researchDurationMs = facts.researchTelemetry.totalDurationMs; + } + } + const cooldownStates = facts.objectives.map((objective) => objective.cooldown).filter((state) => state !== void 0); + const cooldownIntervals = []; + let cooldownDurationMs = 0; + let cooldownDurationKnown = cooldownStates.length > 0; + let cooldownEpisodes = 0; + for (const state of cooldownStates) { + cooldownEpisodes += state.episodes; + const startedAt = state.currentStartedAt ?? state.firstStartedAt; + const endedAt = state.status === "RECOVERED" ? state.lastEndedAt ?? null : null; + const startMs = timestampMs(startedAt); + const endMs = state.status === "ACTIVE" ? generatedMs : timestampMs(endedAt); + const durationMs = startMs !== void 0 && endMs !== void 0 && endMs >= startMs ? endMs - startMs : null; + if (state.episodes !== 1) cooldownDurationKnown = false; + if (durationMs === null) cooldownDurationKnown = false; + else cooldownDurationMs += durationMs; + cooldownIntervals.push({ + objectiveNodeId: state.objectiveNodeId, + status: state.status, + startedAt, + endedAt, + durationMs, + completedWorkUnits: state.completedDuringCooldown.length + }); + if (state.episodes > 1) { + diagnostics.push({ + code: "COOLDOWN_DURATION_PARTIAL", + severity: "info", + message: `Objective ${state.objectiveNodeId} records ${state.episodes} cooldown episodes but retains only bounded interval endpoints; total duration is unavailable.`, + evidenceRefs: [state.objectiveNodeId] + }); + } + } + const cooldownCompletedKeys = /* @__PURE__ */ new Set(); + const cooldownWaitingKeys = /* @__PURE__ */ new Set(); + for (const state of cooldownStates) { + for (const workUnitId of state.completedDuringCooldown) { + cooldownCompletedKeys.add(`${state.objectiveNodeId}\0${workUnitId}`); + } + for (const workUnitId of state.waitingWorkUnitIds) { + cooldownWaitingKeys.add(`${state.objectiveNodeId}\0${workUnitId}`); + } + } + let secondaryImplementationDuringCooldown = 0; + for (const entry2 of units) { + const key = `${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`; + if (!cooldownCompletedKeys.has(key) || entry2.unit.kind !== "build") continue; + const unitAttempts = attemptsByUnit.get(key) ?? []; + if (unitAttempts.some((attempt) => attempt.kind === "SECONDARY" || attempt.kind === "SECONDARY_REPAIR") && !unitAttempts.some((attempt) => attempt.kind === "STRONG" || attempt.kind === "STRONG_FALLBACK")) { + secondaryImplementationDuringCooldown += 1; + } + } + const withinCooldown = (at) => { + const atMs = timestampMs(at); + if (atMs === void 0) return false; + return cooldownIntervals.some((interval) => { + const start = timestampMs(interval.startedAt); + const end = timestampMs(interval.endedAt) ?? generatedMs; + return start !== void 0 && atMs >= start && atMs <= end; + }); + }; + const researchDuringCooldown = providerRecords.filter((record4) => (record4.status === "COMPLETED" || record4.status === "INCONCLUSIVE") && withinCooldown(record4.report?.completedAt ?? record4.updatedAt)).length; + let avoidableIdlePeriods = 0; + for (const objective of facts.objectives) { + if (objective.cooldown?.status !== "ACTIVE" || objective.graph === void 0) continue; + for (const unit of objective.graph.units) { + if (unit.kind !== "build" || unit.status !== "READY" || unit.resourceWait !== void 0) continue; + const key = `${objective.objectiveNodeId}\0${unit.workUnitId}`; + const state = currentRouting.get(key); + if (state?.initialEligibility !== "ELIGIBLE" || state.strategy === "OFF") continue; + const startMs = timestampMs(objective.cooldown.currentStartedAt); + const dispatched = (attemptsByUnit.get(key) ?? []).some((attempt) => { + const attemptMs = timestampMs(attempt.startedAt); + return (attempt.kind === "SECONDARY" || attempt.kind === "SECONDARY_REPAIR") && attemptMs !== void 0 && (startMs === void 0 || attemptMs >= startMs); + }); + if (!dispatched) avoidableIdlePeriods += 1; + } + } + if (avoidableIdlePeriods > 0) { + diagnostics.push({ + code: "AVOIDABLE_IDLE_DURING_COOLDOWN", + severity: "warning", + message: `${avoidableIdlePeriods} runnable Secondary work period(s) had no durable Secondary dispatch during an active Strong cooldown.`, + evidenceRefs: [] + }); + } + const cooldownEventTypes = /* @__PURE__ */ new Set([ + "resource_cooldown_started", + "resource_cooldown_observed", + "work_unit_resource_wait_started", + "work_unit_resource_wait_ended", + "resource_wait_entered", + "useful_work_during_cooldown", + "resource_recovered" + ]); + const cooldownTimeline = facts.events.filter((event) => cooldownEventTypes.has(event.type)).slice(-200).map((event) => ({ + at: String(event.at ?? ""), + type: event.type, + objectiveNodeId: typeof event["nodeId"] === "string" ? event["nodeId"].slice(0, 512) : null, + detail: cooldownEventDetail(event) + })); + const evaluationFailures = evaluations.filter((entry2) => entry2.verdict === "FAIL"); + const evaluationPasses = evaluations.filter((entry2) => entry2.verdict === "PASS"); + const failuresByBackend = {}; + let failuresRecoveredByRepair = 0; + let failuresRecoveredByStrongFallback = 0; + const failedUnitKeys = /* @__PURE__ */ new Set(); + for (const evaluation of evaluationFailures) { + const key = `${evaluation.objectiveNodeId}\0${evaluation.workUnitId}`; + failedUnitKeys.add(key); + const unitAttempts = attemptsByUnit.get(key) ?? []; + const matching = [...unitAttempts].reverse().find((attempt) => attempt.workUnitAttempt === evaluation.attempt); + increment2(failuresByBackend, matching?.kind ?? "UNKNOWN"); + } + for (const key of failedUnitKeys) { + const unitAttempts = attemptsByUnit.get(key) ?? []; + if (unitAttempts.some((attempt) => attempt.kind === "SECONDARY_REPAIR" && attempt.outcome === "SUCCEEDED")) { + failuresRecoveredByRepair += 1; + } + if (unitAttempts.some((attempt) => attempt.kind === "STRONG_FALLBACK" && attempt.outcome === "SUCCEEDED")) { + failuresRecoveredByStrongFallback += 1; + } + } + const failureSources = {}; + const recoveryActions = {}; + for (const entry2 of facts.ledger) { + if (entry2.failureSource !== null) increment2(failureSources, entry2.failureSource); + else if (!entry2.success && entry2.failureReason !== null) increment2(failureSources, "UNCLASSIFIED"); + if (entry2.recoveryAction !== null) increment2(recoveryActions, entry2.recoveryAction); + } + const repairAttempts = implementationAttempts.filter((attempt) => attempt.kind === "SECONDARY_REPAIR").length; + const strongFallbackAttempts = implementationAttempts.filter((attempt) => attempt.kind === "STRONG_FALLBACK").length; + if (repairAttempts > 0) increment2(recoveryActions, "repair", repairAttempts); + if (strongFallbackAttempts > 0) increment2(recoveryActions, "strong-fallback", strongFallbackAttempts); + const resourceWaitEvents = eventTypes("resource_wait_started").length + eventTypes("resource_wait_entered").length + eventTypes("work_unit_resource_wait_started").length; + if (resourceWaitEvents > 0) increment2(recoveryActions, "resource-wait", resourceWaitEvents); + const restartEvents = eventTypes("job_resumed").length + eventTypes("driver_restarted").length; + if (restartEvents > 0) increment2(recoveryActions, "restart-resume", restartEvents); + const noProgressDetections = implementationAttempts.filter((attempt) => attempt.noProgress).length; + const fingerprintCounts = /* @__PURE__ */ new Map(); + for (const attempt of implementationAttempts) { + if (attempt.problemFingerprint !== void 0) { + fingerprintCounts.set( + attempt.problemFingerprint, + (fingerprintCounts.get(attempt.problemFingerprint) ?? 0) + 1 + ); + } + } + const repeatedProblemFingerprints = [...fingerprintCounts.values()].filter((value) => value > 1).length; + const candidatesPersisted = new Set( + implementationAttempts.map((attempt) => attempt.candidateRef).filter((ref) => ref !== void 0) + ).size; + const candidateRebuilds = eventTypes("candidate_resume_missing").length; + const candidatesReused = cooldownStates.reduce( + (sum, state) => sum + state.candidateReuseAfterRestart, + 0 + ); + const integrationRetries = eventTypes("integration_failed").length; + let completedWorkRedoCount = 0; + for (const entry2 of units) { + if (entry2.unit.integratedAt === void 0) continue; + const integratedMs = timestampMs(entry2.unit.integratedAt); + if (integratedMs === void 0) continue; + const attemptsAfterIntegration = (attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []).filter((attempt) => (timestampMs(attempt.startedAt) ?? 0) > integratedMs); + if (attemptsAfterIntegration.length > 0) completedWorkRedoCount += 1; + } + const lastRestartMs = Math.max( + 0, + ...facts.events.filter((event) => event.type === "job_resumed" || event.type === "driver_restarted").map((event) => timestampMs(event.at) ?? 0) + ); + const completedWorkReusedAfterRestart = lastRestartMs === 0 ? 0 : units.filter((entry2) => { + if (entry2.unit.status !== "INTEGRATED") return false; + const unitAttempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return unitAttempts.length > 0 && unitAttempts.every((attempt) => (timestampMs(attempt.completedAt) ?? Number.MAX_SAFE_INTEGER) <= lastRestartMs); + }).length; + const unresolvedInterrupted = facts.ledger.filter((entry2) => { + if (entry2.status !== "INTERRUPTED") return false; + return !facts.ledger.some((candidate) => candidate.taskId === entry2.taskId && candidate.attemptNumber > entry2.attemptNumber && candidate.status === "COMPLETED"); + }).length; + const unrecoveredDriverDeaths = ["COMPLETED", "FAILED", "CANCELLED"].includes(facts.job.status) ? unresolvedInterrupted : 0; + const unexpectedBlocks = facts.autonomy.interventions.filter((intervention) => intervention.kind === "job_blocked" || intervention.kind === "budget_exhausted" || intervention.kind.startsWith("status:")).length; + if (completedWorkRedoCount > 0) { + diagnostics.push({ + code: "COMPLETED_WORK_REDONE", + severity: "error", + message: `${completedWorkRedoCount} authoritatively integrated WorkUnit(s) have a later implementation attempt without recorded invalidation.`, + evidenceRefs: [] + }); + } + const completedImplementation = units.filter((entry2) => entry2.unit.kind === "build" && entry2.unit.status === "INTEGRATED").length; + const attemptCountsForCompleted = units.filter((entry2) => entry2.unit.status === "INTEGRATED" && entry2.unit.kind === "build").map((entry2) => (attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []).length); + const totalAttemptsForCompleted = attemptCountsForCompleted.reduce((sum, value) => sum + value, 0); + const meanAttempts = attemptCountsForCompleted.length === 0 ? null : totalAttemptsForCompleted / attemptCountsForCompleted.length; + const completedPerAttempt = implementationAttempts.length === 0 ? null : completedImplementation / implementationAttempts.length; + const completedPerStrong = strongAttempts.length === 0 ? null : completedImplementation / strongAttempts.length; + const completedEligiblePerSecondary = secondaryAttempts.length === 0 ? null : eligibleCompleted.length / secondaryAttempts.length; + const closureTotals = facts.closure === void 0 ? void 0 : summarizeClosure(facts.closure.entries); + const closureGate = facts.closure === void 0 ? void 0 : missionMayComplete(facts.closure, facts.closurePolicy); + const closureOutcome = facts.closure === void 0 ? "UNAVAILABLE" : closureGate?.mayComplete === true ? "PASS" : "FAIL"; + const overallVerification = verificationOutcome(facts.job, facts.events); + const boundaryMs = timestampMs(facts.autonomy.boundaryStartedAt); + const decisionsBeforeSeal = boundaryMs === void 0 ? null : facts.events.filter((event) => (event.type === "clarification_resolved" || event.type === "authority_resolved") && (timestampMs(event.at) ?? Number.MAX_SAFE_INTEGER) < boundaryMs).length; + const humanByKind = {}; + for (const intervention of facts.autonomy.interventions) increment2(humanByKind, intervention.kind); + const objectiveRevisions = {}; + for (const objective of facts.objectives) { + if (objective.graph !== void 0) objectiveRevisions[objective.objectiveNodeId] = objective.graph.revision; + } + const ledgerWatermark = sha256Hex(JSON.stringify( + facts.ledger.map((entry2) => [entry2.attemptId, entry2.status, entry2.completedAt]) + )); + const currentPolicyFingerprint = autonomyPolicyFingerprint(facts.currentAutonomyPolicy); + const runtimePolicyChanged = facts.binding === void 0 ? null : currentPolicyFingerprint !== facts.binding.boundPolicyFingerprint; + const strongAvoidance = metric(eligibleCompletedWithoutStrong.length, eligibleCompleted.length); + const secondaryInitial = metric(initialPassUnits.length, initialAttemptedUnits.length); + const secondaryRepair = metric(repairPassUnits.length, repairAttemptedUnits.length); + const secondaryFallback = metric(fallbackUnits.length, secondaryAttemptedUnits.length); + const researchAvoidance = metric(researchAvoided, researchConsidered); + const researchReuse = metric( + reuseCount, + reuseCount + providerCallCount + ); + const implementationByKind = {}; + for (const attempt of implementationAttempts) increment2(implementationByKind, attempt.kind); + const objectiveSummaries = facts.objectives.slice(0, 200).map((objective) => { + const accounting = { + completed: 0, + failed: 0, + cancelled: 0, + waiting: 0, + "not-ready": 0, + "human-authority-pending": 0, + "research-pending": 0, + "context-pending": 0 + }; + for (const unit of objective.graph?.units ?? []) { + const key = `${objective.objectiveNodeId}\0${unit.workUnitId}`; + accounting[workAccounting(unit, currentRouting.get(key))] += 1; + } + const attempts = implementationAttempts.filter((entry2) => entry2.objectiveNodeId === objective.objectiveNodeId); + return { + objectiveNodeId: objective.objectiveNodeId, + graphRevision: objective.graph?.revision ?? null, + total: objective.graph?.units.length ?? 0, + accounting, + implementationAttempts: attempts.length, + secondaryAttempts: attempts.filter((entry2) => entry2.kind === "SECONDARY" || entry2.kind === "SECONDARY_REPAIR").length, + strongBuilderAttempts: attempts.filter((entry2) => entry2.kind === "STRONG" || entry2.kind === "STRONG_FALLBACK").length + }; + }); + const report = executionTelemetryReportSchema.parse({ + schemaVersion: EXECUTION_TELEMETRY_REPORT_SCHEMA_VERSION, + jobId: facts.job.jobId, + missionId: facts.binding?.missionId ?? facts.seal?.missionId ?? null, + generatedAt: facts.generatedAt, + period: { + startedAt: facts.job.createdAt, + endedAt: facts.job.finalizedAt ?? null, + durationMs: timestampMs(facts.job.createdAt) === void 0 ? null : Math.max( + 0, + (timestampMs(facts.job.finalizedAt ?? facts.generatedAt) ?? generatedMs) - (timestampMs(facts.job.createdAt) ?? generatedMs) + ), + activeExecutionMs: timestampMs(facts.job.createdAt) === void 0 ? null : workedMsOf(facts.job, timestampMs(facts.job.finalizedAt ?? facts.generatedAt) ?? generatedMs) + }, + provenance: { + sourceJobId: facts.job.jobId, + jobGraphRevision: facts.job.graphRevision, + objectiveGraphRevisions: objectiveRevisions, + executionLedgerWatermark: ledgerWatermark, + eventWatermark: facts.eventTotal, + specbridgeVersion: facts.specbridgeVersion ?? null, + sealId: facts.binding?.sealId ?? null, + sealedAuthorityDigest: facts.seal?.authorityDigest ?? null, + runtimePolicyChanged, + configuration: { + secondaryBuildStrategy: facts.secondaryBuildStrategy, + researchStrategy: facts.researchStrategy, + runnerProfiles: [...facts.runnerProfiles].sort().slice(0, 50) + } + }, + outcome: { + status: outcomeStatus(facts.job.status), + authoritativeJobStatus: facts.job.status, + finalOutcome: facts.job.finalOutcome === void 0 ? null : redactTelemetryText(facts.job.finalOutcome).slice(0, 2e3), + verification: overallVerification, + closure: closureOutcome + }, + work: { + total: units.length, + byKind: workByKind, + accounting: workAccountingCounts, + completedImplementation, + objectives: objectiveSummaries, + units: unitSummaries, + omittedUnits: Math.max(0, units.length - unitSummaries.length) + }, + secondary: { + eligibility, + selection, + funnel: { + initialAttempts: initialAttemptedUnits.length, + initialPass: initialPassUnits.length, + repairAttempted: repairAttemptedUnits.length, + repairPass: repairPassUnits.length, + toStrongFallback: fallbackUnits.length, + unavailableFallback: unavailableFallbackUnits.length + }, + initialSuccessRate: secondaryInitial, + repairRecoveryRate: secondaryRepair, + toStrongFallbackRate: secondaryFallback, + fallbackReasons, + builderTokens: secondaryTokens + }, + strong: { + builderAttempts: strongAttempts.length, + evaluatorAttempts: strongEvaluatorAttempts.length, + selection: strongSelection, + implementationTokens: strongTokens, + evaluatorTokens + }, + research: { + scope: researchScope, + considered: researchConsidered, + decisions: researchDecisions, + providerCalls: providerCallCount, + successful: successfulResearch, + inconclusive: inconclusiveResearch, + failed: failedResearch, + priorResearchReused: reuseCount, + newQuick, + newDeep, + avoidanceRatio: researchAvoidance, + reuseRate: researchReuse, + byPhase, + usage: { + inputTokens: researchInputObserved ? researchInputTokens : null, + outputTokens: researchOutputObserved ? researchOutputTokens : null, + durationMs: researchDurationObserved ? researchDurationMs : null, + providerReportedCost: researchCostObserved ? researchCost : null, + subagentCount: researchSubagentsObserved ? researchSubagents : null, + recordsWithUsage, + providerCalls: providerCallCount, + coverage: providerCallCount === 0 ? null : Math.min(1, recordsWithUsage / providerCallCount) + } + }, + cooldown: { + episodes: cooldownEpisodes, + observations: eventTypes("resource_cooldown_observed").length, + totalDurationMs: cooldownDurationKnown ? cooldownDurationMs : null, + usefulWorkDuringSubscriptionCooldown: cooldownCompletedKeys.size, + secondaryImplementationWorkDuringCooldown: secondaryImplementationDuringCooldown, + researchWorkDuringCooldown: researchDuringCooldown, + strongRequiredWaiting: cooldownWaitingKeys.size, + avoidableIdlePeriods, + intervals: cooldownIntervals.sort((left, right) => left.startedAt.localeCompare(right.startedAt, "en") || left.objectiveNodeId.localeCompare(right.objectiveNodeId, "en")), + timeline: cooldownTimeline + }, + attempts: { + uniqueImplementationAttempts: implementationAttempts.length, + meanPerCompletedWorkUnit: meanAttempts, + medianPerCompletedWorkUnit: median(attemptCountsForCompleted), + maxPerWorkUnit: attemptCountsForCompleted.length === 0 ? 0 : Math.max(...attemptCountsForCompleted), + workUnitsWithMultipleAttempts: attemptCountsForCompleted.filter((value) => value > 1).length, + byKind: implementationByKind, + completedWorkUnitsPerImplementationAttempt: completedPerAttempt, + completedWorkUnitsPerStrongBuilderCall: completedPerStrong, + completedEligibleWorkUnitsPerSecondaryAttempt: completedEligiblePerSecondary + }, + verification: { + attempts: evaluations.length, + passes: evaluationPasses.length, + failures: evaluationFailures.length, + otherVerdicts: evaluations.length - evaluationPasses.length - evaluationFailures.length, + failuresByBuilderBackend: failuresByBackend, + failuresRecoveredByRepair, + failuresRecoveredByStrongFallback + }, + closure: { + available: closureTotals !== void 0, + items: closureTotals?.total ?? 0, + earned: closureTotals?.verified ?? 0, + waived: closureTotals?.waived ?? 0, + unresolved: closureTotals === void 0 ? 0 : closureTotals.total - closureTotals.verified - closureTotals.waived - closureTotals.notApplicable, + completionGateOutcome: closureOutcome, + ratio: closureTotals === void 0 ? null : closureRatio(closureTotals) + }, + human: { + decisionsBeforeSeal, + approvals: facts.seal?.sealedAt === void 0 ? 0 : 1, + authorityEscalationsAfterSeal: facts.autonomy.humanAuthorityEscalationsAfterSeal, + interventionsAfterSeal: facts.autonomy.humanInterventionsAfterSeal, + unexpectedBlockersAfterSeal: unexpectedBlocks, + zeroTouchAfterSeal: facts.autonomy.humanInterventionsAfterSeal === 0, + byKind: humanByKind + }, + reliability: { + failureSources, + recoveryActions, + noProgressDetections, + repeatedProblemFingerprints, + legitimateResourceWaitsExcluded: resourceWaitEvents, + processRestarts: eventTypes("job_resumed").length, + supervisorRestarts: eventTypes("driver_restarted").length + eventTypes("supervisor_lease_reclaimed").length, + candidatesPersisted, + candidatesReusedAfterRestart: candidatesReused, + candidateRebuildsAfterRestart: candidateRebuilds, + candidatesLostOrUnreadable: candidateRebuilds, + candidateReadyResumes: candidatesReused, + integrationRetries, + completedWorkRedoCount, + completedWorkReusedAfterRestart, + attemptsIncorrectlyRepeated: completedWorkRedoCount, + unexpectedBlocks, + unrecoveredDriverDeaths + }, + efficiency: { + strongBuilderAvoidanceRatio: strongAvoidance, + strongBuilderCallsAvoided: eligibleCompletedWithoutStrong.length, + completedWorkUnitsPerImplementationAttempt: completedPerAttempt, + baseline: facts.baseline === void 0 ? null : { + kind: facts.baseline.kind, + reportId: facts.baseline.reportId, + strongBuilderAttempts: facts.baseline.strongBuilderAttempts, + sameVerificationOutcome: facts.baseline.verificationOutcome === overallVerification, + sameClosureOutcome: facts.baseline.closureOutcome === closureOutcome + } + }, + qualificationSummary: { + strongBuilderAvoidanceRatio: strongAvoidance.value, + secondaryInitialSuccessRate: secondaryInitial.value, + secondaryRepairRecoveryRate: secondaryRepair.value, + secondaryToStrongFallback: fallbackUnits.length, + strongImplementationTokens: strongTokens.completeTokens, + researchAvoidanceRatio: researchAvoidance.value, + newResearchCalls: providerCallCount, + researchReuse: reuseCount, + usefulWorkDuringSubscriptionCooldown: cooldownCompletedKeys.size, + humanInterventionsAfterSeal: facts.autonomy.humanInterventionsAfterSeal, + completedWorkRedoCount, + unexpectedBlocks, + unrecoveredDriverDeaths + }, + diagnostics: diagnostics.slice(0, 200) + }); + return report; +} +function cooldownEventDetail(event) { + switch (event.type) { + case "resource_cooldown_started": + return `Strong resource cooldown started (${String(event["availability"] ?? "availability unknown")}).`; + case "resource_cooldown_observed": + return "Strong resource cooldown was observed again; this is not a new episode."; + case "work_unit_resource_wait_started": + return `WorkUnit ${String(event["workUnitId"] ?? "(unknown)")} entered a Strong resource wait.`; + case "work_unit_resource_wait_ended": + return `WorkUnit ${String(event["workUnitId"] ?? "(unknown)")} left its Strong resource wait.`; + case "resource_wait_entered": + return "The job entered a global resource wait because no permitted work remained runnable."; + case "useful_work_during_cooldown": + return `${Number(event["newlyCompleted"] ?? 0)} additional WorkUnit(s) completed during cooldown.`; + case "resource_recovered": + return "The Strong resource recovered and waiting work was released."; + default: + return event.type; + } +} +function collectExecutionTelemetryFacts(deps, jobId, options = {}) { + const job = requireJobState(deps.workspace, jobId); + const eventPage = readJobEvents(deps.workspace, jobId, { limit: 500 }); + const objectives = listObjectiveNodes(deps.workspace, jobId).map( + (objectiveNodeId) => ({ + objectiveNodeId, + graph: readLatestWorkGraph(deps.workspace, jobId, objectiveNodeId), + routingStates: readBuilderRoutingStates(deps.workspace, jobId, objectiveNodeId), + cooldown: readObjectiveCooldownState(deps.workspace, jobId, objectiveNodeId), + evaluations: readEvaluations(deps.workspace, jobId, objectiveNodeId) + }) + ); + const researchTelemetryRead = readResearchTelemetry(deps.workspace); + const researchRecords = listResearchRecords(deps.workspace); + const binding = readSealBinding(deps.workspace, jobId); + const seal = readJobSeal(deps.workspace, jobId); + return { + job, + events: eventPage.events, + eventTotal: eventPage.total, + ledger: readExecutionLedger(deps.workspace, jobId), + objectives, + researchTelemetry: researchTelemetryRead.telemetry, + ...researchTelemetryRead.diagnostic !== void 0 ? { researchTelemetryDiagnostic: researchTelemetryRead.diagnostic } : {}, + researchRecords: researchRecords.records, + researchRecordDiagnostics: researchRecords.diagnostics.map((diagnostic) => ({ + code: diagnostic.code, + message: diagnostic.message + })), + researchUses: listResearchUseRecords(deps.workspace), + autonomy: deriveAutonomyTelemetry(deps, { jobId }), + closure: readClosureLedger(deps.workspace, jobId), + ...binding !== void 0 ? { binding } : {}, + ...seal !== void 0 ? { seal } : {}, + generatedAt: nowIso2(deps), + ...options.specbridgeVersion !== void 0 ? { specbridgeVersion: options.specbridgeVersion } : {}, + secondaryBuildStrategy: deps.config.orchestration.jobs.objectives.secondaryBuilder.strategy, + researchStrategy: deps.config.research.strategy, + runnerProfiles: Object.keys(deps.config.runnerProfiles), + currentAutonomyPolicy: deps.config.autonomy, + closurePolicy: deps.config.autonomy.closure + }; +} +function executionTelemetryReportFile(workspace, jobId) { + if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(jobId)) { + throw new Error(`Invalid job id "${jobId}".`); + } + return assertInsideWorkspace( + workspace.rootDir, + import_path50.default.join(workspace.sidecarDir, "reports", `job-${jobId}-telemetry.json`) + ); +} +function persistExecutionTelemetryReport(workspace, report) { + const validated = executionTelemetryReportSchema.parse(report); + const file = executionTelemetryReportFile(workspace, validated.jobId); + (0, import_fs47.mkdirSync)(import_path50.default.dirname(file), { recursive: true }); + writeFileAtomic(file, `${JSON.stringify(validated, null, 2)} +`); + return file; +} +function computeExecutionTelemetryReport(deps, jobId, options = {}) { + const report = deriveExecutionTelemetryReport( + collectExecutionTelemetryFacts(deps, jobId, options) + ); + if (options.persist === true) persistExecutionTelemetryReport(deps.workspace, report); + return report; +} +var shortText132 = external_exports.string().max(200); var text12 = external_exports.string().max(4e3); var controlPlaneRepairSchema = external_exports.object({ schemaVersion: external_exports.string().regex(/^\d+\.\d+\.\d+$/), - repairId: shortText122, + repairId: shortText132, /** The product job that hit the defect and is suspended for this. */ - productJobId: shortText122, + productJobId: shortText132, defectKind: external_exports.enum(CONTROL_PLANE_DEFECT_KINDS), /** What was observed, in one line. Never a stack trace with paths. */ symptom: text12, @@ -86110,238 +87495,830 @@ var controlPlaneRepairSchema = external_exports.object({ status: external_exports.enum(CONTROL_PLANE_REPAIR_STATUSES), /** Stages completed, in order. The gate is that this is a prefix. */ stagesCompleted: external_exports.array(external_exports.enum(CONTROL_PLANE_REPAIR_STAGES)).max(20).default([]), - createdAt: shortText122, - updatedAt: shortText122, - finishedAt: shortText122.optional(), + createdAt: shortText132, + updatedAt: shortText132, + finishedAt: shortText132.optional(), /** Isolated working copy the patch was developed in. */ - isolationPath: shortText122.optional(), + isolationPath: shortText132.optional(), /** Where the verified build was staged. Never the running installation. */ - artifactPath: shortText122.optional(), + artifactPath: shortText132.optional(), /** Files the patch touched, workspace-relative to the SpecBridge source. */ - changedFiles: external_exports.array(shortText122).max(200).default([]), + changedFiles: external_exports.array(shortText132).max(200).default([]), /** The regression test added, which is mandatory. */ - regressionTestPath: shortText122.optional(), + regressionTestPath: shortText132.optional(), /** Invariants the screen found the patch touching. Non-empty means reject. */ invariantViolations: external_exports.array( external_exports.object({ - invariant: external_exports.enum(PROTECTED_CONTROL_PLANE_INVARIANTS), - file: shortText122, - evidence: text12 - }).passthrough() - ).max(50).default([]), - /** Why the repair ended where it did. */ - outcomeDetail: text12.optional() -}).passthrough(); -var CERTIFICATION_MATRIX = Object.freeze([ - { - id: "ZT-01", - fault: "STRONG_PROVIDER_UNAVAILABLE", - title: "the subscription provider is temporarily down", - situation: "The strong worker returns 529/overloaded for every dispatch.", - injection: "driver host returns a crashed outcome carrying the provider signature", - expectation: "SELF_RECOVERED", - expectedBehaviour: "WAITING_RESOURCE with a provider cooldown, re-checked and resumed without a human" - }, - { - id: "ZT-02", - fault: "STRONG_QUOTA_EXHAUSTED", - title: "the subscription quota is exhausted until a known reset", - situation: "The provider reports no remaining capacity and names a reset time.", - injection: "driver host returns a deferred stop carrying retryAt", - expectation: "SELF_RECOVERED", - expectedBehaviour: "WAITING_RESOURCE with wakeAt set; the supervisor sleeps and wakes itself" - }, - { - id: "ZT-03", - fault: "LOCAL_RUNTIME_CRASH", - title: "the local llama.cpp process crashes", - situation: "The managed local inference server exits mid-dispatch.", - injection: "driver host crashes with a local-model signature", - expectation: "SELF_RECOVERED", - expectedBehaviour: "RECOVERING_PROVIDER, the runtime restarts the local runtime and continues" - }, - { - id: "ZT-04", - fault: "INVALID_STRUCTURED_OUTPUT", - title: "a model returns structured output that does not validate", - situation: "The local model produces JSON the agent contract rejects.", - injection: "driver host crashes with an invalid-output signature", - expectation: "SELF_RECOVERED", - expectedBehaviour: "a bounded retry, then escalation to a stronger tier. Never a question" - }, - { - id: "ZT-05", - fault: "CONTEXT_EXHAUSTION", - title: "the context window is exceeded mid-task", - situation: "A dispatch fails because the prompt exceeds the model context.", - injection: "driver host crashes with a context-length signature", - expectation: "SELF_RECOVERED", - expectedBehaviour: "checkpoint, compact, reconstruct in a fresh session, continue. Task memory is not the context window" - }, - { - id: "ZT-06", - fault: "WORKER_PROCESS_TERMINATED", - title: "a worker process is killed", - situation: "The runner child process is terminated by the OS.", - injection: "driver host crashes with a process-termination signature", - expectation: "SELF_RECOVERED", - expectedBehaviour: "the attempt is reconciled as INTERRUPTED and re-dispatched" - }, - { - id: "ZT-07", - fault: "DRIVER_PROCESS_TERMINATED", - title: "the driver itself dies", - situation: "The orchestrating driver process is killed without cleanup.", - injection: "driver host crashes on its first run and succeeds on the next", - expectation: "SELF_RECOVERED", - expectedBehaviour: "the supervisor observes the dead driver and restarts it under the same lease" - }, - { - id: "ZT-08", - fault: "CONTAINER_SERVICE_CRASH", - title: "a container service crashes", - situation: "A compose service exits during a system scenario.", - injection: "driver host crashes with a container signature", - expectation: "SELF_RECOVERED", - expectedBehaviour: "REPAIRING_ENVIRONMENT; the service is restarted within its budget" - }, - { - id: "ZT-09", - fault: "DELAYED_SERVICE_READINESS", - title: "a service takes far longer than expected to become ready", - situation: "Postgres accepts TCP long before it accepts a connection.", - injection: "readiness probe reports not-ready for several attempts", - expectation: "SELF_RECOVERED", - expectedBehaviour: "the readiness loop waits, restarts within budget, and proceeds when it answers" - }, - { - id: "ZT-10", - fault: "MISSING_PROJECT_DEPENDENCY", - title: "a project dependency is missing", - situation: 'A build fails with "cannot find module".', - injection: "driver host crashes with a missing-module signature", - expectation: "SELF_RECOVERED", - expectedBehaviour: "REPAIRING_TOOLCHAIN; the Toolsmith installs it. A missing package is engineering" - }, - { - id: "ZT-11", - fault: "MISSING_BROWSER_RUNTIME", - title: "no browser runtime is installed", - situation: "A UI acceptance criterion needs a browser and none exists.", - injection: "browser driver reports unavailable", - expectation: "SELF_RECOVERED", - expectedBehaviour: "the scenario records SKIPPED_NO_RUNTIME, the criterion stays unclosed, and the Toolsmith is asked for the runtime" - }, - { - id: "ZT-12", - fault: "FAILING_IMPLEMENTATION_TEST", - title: "the implementation is wrong and the tests say so", - situation: "A trusted verification command fails against the produced code.", - injection: "closure evidence registered as failing", - expectation: "SELF_RECOVERED", - expectedBehaviour: "the item stays unclosed with EVIDENCE_FAILED and gap work repairs it" - }, - { - id: "ZT-13", - fault: "WRONG_STRATEGY_REQUIRES_REPLAN", - title: "the approach is wrong and needs replanning", - situation: "A replan proposes restructuring the internal architecture.", - injection: "the authority resolver is asked about an architecture-flavoured replan", - expectation: "SELF_RECOVERED", - expectedBehaviour: "the replan proceeds under delegated authority. Internal architecture is not a promise" - }, - { - id: "ZT-14", - fault: "TRANSIENT_NETWORK_FAILURE", - title: "a transient network failure", - situation: "A registry or provider connection is refused once.", - injection: "driver host crashes with a network signature, then succeeds", - expectation: "SELF_RECOVERED", - expectedBehaviour: "RECOVERING_PROVIDER and a bounded retry" - }, - { - id: "ZT-15", - fault: "CONTROL_PLANE_RUNNER_DEFECT", - title: "a SpecBridge runner defect", - situation: "The provider CLI rejects an argument SpecBridge passes.", - injection: "driver host crashes with an unknown-option signature", - expectation: "SELF_RECOVERED", - expectedBehaviour: "REPAIRING_CONTROL_PLANE; the governed repair path runs and the operator does not become the SpecBridge maintainer" - }, - { - id: "ZT-16", - fault: "SEALED_CONTRACT_CHANGE_REQUIRED", - title: "completing the work requires changing a sealed public contract", - situation: "The only way to satisfy a requirement is to change the public API the human already approved.", - injection: "the authority resolver is asked about a public-api replan", - expectation: "NEEDS_AUTHORITY", - expectedBehaviour: "the job stops in NEEDS_AUTHORITY with the question recorded, and the sealed contract is NOT modified" - } -]); -var shortText132 = external_exports.string().max(200); -var text13 = external_exports.string().max(4e3); -var certificationScenarioResultSchema = external_exports.object({ - scenarioId: shortText132, - fault: external_exports.enum(ZERO_TOUCH_FAULTS), - expectation: external_exports.enum(ZERO_TOUCH_EXPECTATIONS), - outcome: external_exports.enum(ZERO_TOUCH_OUTCOMES), - /** Human interventions observed. Anything above zero fails the scenario. */ - humanInterventions: external_exports.number().int().min(0), - /** Authority escalations. Expected exactly on the authority scenario. */ - authorityEscalations: external_exports.number().int().min(0), - /** What the runtime actually did, in one or two lines. */ - observed: text13, - /** The job status the scenario ended in. */ - finalStatus: shortText132.optional(), - /** Operational statuses the job passed through, in order. */ - recoveryPath: external_exports.array(shortText132).max(30).default([]), - /** Present when the scenario could not run here. Never a pass. */ - skipReason: text13.optional(), - startedAt: shortText132, - finishedAt: shortText132.optional(), - durationMs: external_exports.number().int().min(0).nullable().default(null) -}).passthrough(); -var certificationRunSchema = external_exports.object({ - schemaVersion: external_exports.string().regex(/^\d+\.\d+\.\d+$/), - runId: shortText132, - createdAt: shortText132, - finishedAt: shortText132.optional(), - host: shortText132, - verdict: external_exports.enum(CERTIFICATION_VERDICTS), - results: external_exports.array(certificationScenarioResultSchema).max(100).default([]), - /** Totals, hoisted so the headline needs no arithmetic. */ - totals: external_exports.object({ - total: external_exports.number().int().min(0), - selfRecovered: external_exports.number().int().min(0), - needsAuthority: external_exports.number().int().min(0), - askedHuman: external_exports.number().int().min(0), - stuck: external_exports.number().int().min(0), - selfAuthorized: external_exports.number().int().min(0), - skipped: external_exports.number().int().min(0), - notRun: external_exports.number().int().min(0) - }).passthrough(), - /** - * Total human interventions across every scenario. The headline number: - * a certified run has zero, and any non-zero value is named here rather - * than buried in a per-scenario field. - */ - humanInterventionsAfterSeal: external_exports.number().int().min(0), - /** Why the verdict is what it is, in one or two lines. */ - rationale: text13, - /** Scenarios that failed, with what happened, for the report. */ - failures: external_exports.array(external_exports.object({ scenarioId: shortText132, outcome: shortText132, observed: text13 }).passthrough()).max(100).default([]) -}).passthrough(); + invariant: external_exports.enum(PROTECTED_CONTROL_PLANE_INVARIANTS), + file: shortText132, + evidence: text12 + }).passthrough() + ).max(50).default([]), + /** Why the repair ended where it did. */ + outcomeDetail: text12.optional() +}).passthrough(); +var CERTIFICATION_MATRIX = Object.freeze([ + { + id: "ZT-01", + fault: "STRONG_PROVIDER_UNAVAILABLE", + title: "the subscription provider is temporarily down", + situation: "The strong worker returns 529/overloaded for every dispatch.", + injection: "driver host returns a crashed outcome carrying the provider signature", + expectation: "SELF_RECOVERED", + expectedBehaviour: "WAITING_RESOURCE with a provider cooldown, re-checked and resumed without a human" + }, + { + id: "ZT-02", + fault: "STRONG_QUOTA_EXHAUSTED", + title: "the subscription quota is exhausted until a known reset", + situation: "The provider reports no remaining capacity and names a reset time.", + injection: "driver host returns a deferred stop carrying retryAt", + expectation: "SELF_RECOVERED", + expectedBehaviour: "WAITING_RESOURCE with wakeAt set; the supervisor sleeps and wakes itself" + }, + { + id: "ZT-03", + fault: "LOCAL_RUNTIME_CRASH", + title: "the local llama.cpp process crashes", + situation: "The managed local inference server exits mid-dispatch.", + injection: "driver host crashes with a local-model signature", + expectation: "SELF_RECOVERED", + expectedBehaviour: "RECOVERING_PROVIDER, the runtime restarts the local runtime and continues" + }, + { + id: "ZT-04", + fault: "INVALID_STRUCTURED_OUTPUT", + title: "a model returns structured output that does not validate", + situation: "The local model produces JSON the agent contract rejects.", + injection: "driver host crashes with an invalid-output signature", + expectation: "SELF_RECOVERED", + expectedBehaviour: "a bounded retry, then escalation to a stronger tier. Never a question" + }, + { + id: "ZT-05", + fault: "CONTEXT_EXHAUSTION", + title: "the context window is exceeded mid-task", + situation: "A dispatch fails because the prompt exceeds the model context.", + injection: "driver host crashes with a context-length signature", + expectation: "SELF_RECOVERED", + expectedBehaviour: "checkpoint, compact, reconstruct in a fresh session, continue. Task memory is not the context window" + }, + { + id: "ZT-06", + fault: "WORKER_PROCESS_TERMINATED", + title: "a worker process is killed", + situation: "The runner child process is terminated by the OS.", + injection: "driver host crashes with a process-termination signature", + expectation: "SELF_RECOVERED", + expectedBehaviour: "the attempt is reconciled as INTERRUPTED and re-dispatched" + }, + { + id: "ZT-07", + fault: "DRIVER_PROCESS_TERMINATED", + title: "the driver itself dies", + situation: "The orchestrating driver process is killed without cleanup.", + injection: "driver host crashes on its first run and succeeds on the next", + expectation: "SELF_RECOVERED", + expectedBehaviour: "the supervisor observes the dead driver and restarts it under the same lease" + }, + { + id: "ZT-08", + fault: "CONTAINER_SERVICE_CRASH", + title: "a container service crashes", + situation: "A compose service exits during a system scenario.", + injection: "driver host crashes with a container signature", + expectation: "SELF_RECOVERED", + expectedBehaviour: "REPAIRING_ENVIRONMENT; the service is restarted within its budget" + }, + { + id: "ZT-09", + fault: "DELAYED_SERVICE_READINESS", + title: "a service takes far longer than expected to become ready", + situation: "Postgres accepts TCP long before it accepts a connection.", + injection: "readiness probe reports not-ready for several attempts", + expectation: "SELF_RECOVERED", + expectedBehaviour: "the readiness loop waits, restarts within budget, and proceeds when it answers" + }, + { + id: "ZT-10", + fault: "MISSING_PROJECT_DEPENDENCY", + title: "a project dependency is missing", + situation: 'A build fails with "cannot find module".', + injection: "driver host crashes with a missing-module signature", + expectation: "SELF_RECOVERED", + expectedBehaviour: "REPAIRING_TOOLCHAIN; the Toolsmith installs it. A missing package is engineering" + }, + { + id: "ZT-11", + fault: "MISSING_BROWSER_RUNTIME", + title: "no browser runtime is installed", + situation: "A UI acceptance criterion needs a browser and none exists.", + injection: "browser driver reports unavailable", + expectation: "SELF_RECOVERED", + expectedBehaviour: "the scenario records SKIPPED_NO_RUNTIME, the criterion stays unclosed, and the Toolsmith is asked for the runtime" + }, + { + id: "ZT-12", + fault: "FAILING_IMPLEMENTATION_TEST", + title: "the implementation is wrong and the tests say so", + situation: "A trusted verification command fails against the produced code.", + injection: "closure evidence registered as failing", + expectation: "SELF_RECOVERED", + expectedBehaviour: "the item stays unclosed with EVIDENCE_FAILED and gap work repairs it" + }, + { + id: "ZT-13", + fault: "WRONG_STRATEGY_REQUIRES_REPLAN", + title: "the approach is wrong and needs replanning", + situation: "A replan proposes restructuring the internal architecture.", + injection: "the authority resolver is asked about an architecture-flavoured replan", + expectation: "SELF_RECOVERED", + expectedBehaviour: "the replan proceeds under delegated authority. Internal architecture is not a promise" + }, + { + id: "ZT-14", + fault: "TRANSIENT_NETWORK_FAILURE", + title: "a transient network failure", + situation: "A registry or provider connection is refused once.", + injection: "driver host crashes with a network signature, then succeeds", + expectation: "SELF_RECOVERED", + expectedBehaviour: "RECOVERING_PROVIDER and a bounded retry" + }, + { + id: "ZT-15", + fault: "CONTROL_PLANE_RUNNER_DEFECT", + title: "a SpecBridge runner defect", + situation: "The provider CLI rejects an argument SpecBridge passes.", + injection: "driver host crashes with an unknown-option signature", + expectation: "SELF_RECOVERED", + expectedBehaviour: "REPAIRING_CONTROL_PLANE; the governed repair path runs and the operator does not become the SpecBridge maintainer" + }, + { + id: "ZT-16", + fault: "SEALED_CONTRACT_CHANGE_REQUIRED", + title: "completing the work requires changing a sealed public contract", + situation: "The only way to satisfy a requirement is to change the public API the human already approved.", + injection: "the authority resolver is asked about a public-api replan", + expectation: "NEEDS_AUTHORITY", + expectedBehaviour: "the job stops in NEEDS_AUTHORITY with the question recorded, and the sealed contract is NOT modified" + } +]); +var shortText142 = external_exports.string().max(200); +var text13 = external_exports.string().max(4e3); +var certificationScenarioResultSchema = external_exports.object({ + scenarioId: shortText142, + fault: external_exports.enum(ZERO_TOUCH_FAULTS), + expectation: external_exports.enum(ZERO_TOUCH_EXPECTATIONS), + outcome: external_exports.enum(ZERO_TOUCH_OUTCOMES), + /** Human interventions observed. Anything above zero fails the scenario. */ + humanInterventions: external_exports.number().int().min(0), + /** Authority escalations. Expected exactly on the authority scenario. */ + authorityEscalations: external_exports.number().int().min(0), + /** What the runtime actually did, in one or two lines. */ + observed: text13, + /** The job status the scenario ended in. */ + finalStatus: shortText142.optional(), + /** Operational statuses the job passed through, in order. */ + recoveryPath: external_exports.array(shortText142).max(30).default([]), + /** Present when the scenario could not run here. Never a pass. */ + skipReason: text13.optional(), + startedAt: shortText142, + finishedAt: shortText142.optional(), + durationMs: external_exports.number().int().min(0).nullable().default(null) +}).passthrough(); +var certificationRunSchema = external_exports.object({ + schemaVersion: external_exports.string().regex(/^\d+\.\d+\.\d+$/), + runId: shortText142, + createdAt: shortText142, + finishedAt: shortText142.optional(), + host: shortText142, + verdict: external_exports.enum(CERTIFICATION_VERDICTS), + results: external_exports.array(certificationScenarioResultSchema).max(100).default([]), + /** Totals, hoisted so the headline needs no arithmetic. */ + totals: external_exports.object({ + total: external_exports.number().int().min(0), + selfRecovered: external_exports.number().int().min(0), + needsAuthority: external_exports.number().int().min(0), + askedHuman: external_exports.number().int().min(0), + stuck: external_exports.number().int().min(0), + selfAuthorized: external_exports.number().int().min(0), + skipped: external_exports.number().int().min(0), + notRun: external_exports.number().int().min(0) + }).passthrough(), + /** + * Total human interventions across every scenario. The headline number: + * a certified run has zero, and any non-zero value is named here rather + * than buried in a per-scenario field. + */ + humanInterventionsAfterSeal: external_exports.number().int().min(0), + /** Why the verdict is what it is, in one or two lines. */ + rationale: text13, + /** Scenarios that failed, with what happened, for the report. */ + failures: external_exports.array(external_exports.object({ scenarioId: shortText142, outcome: shortText142, observed: text13 }).passthrough()).max(100).default([]) +}).passthrough(); + +// ../../packages/mcp-server/src/tools/job-report.ts +function percent(value) { + return value === null ? "n/a" : `${(value * 100).toFixed(1)}%`; +} +function registerJobReportTool(server, context) { + registerDefinedTool(server, context, { + name: "job_report", + title: "Read a Job execution report", + description: "Derive versioned operational and token-conservation telemetry from durable Job, WorkUnit, attempt, research, cooldown, verification, and closure records. Read-only; metrics never grant completion or authority.", + annotations: { + readOnlyHint: true, + destructiveHint: false, + idempotentHint: true, + openWorldHint: false + }, + inputSchema: { + jobId: external_exports.string().min(1).max(64).describe("Job id (job-\u2026) from job_list") + }, + outputSchema: { + report: executionTelemetryReportSchema + }, + handler: async (args) => { + const workspace = context.requireWorkspace(); + const deps = { + workspace, + config: requireAgentConfig(workspace), + clock: context.clock, + idFactory: context.idFactory, + host: "mcp" + }; + const report = computeExecutionTelemetryReport(deps, args.jobId, { + persist: false, + specbridgeVersion: MCP_SERVER_VERSION + }); + const summary = report.qualificationSummary; + return { + text: [ + `Job ${report.jobId}: ${report.outcome.status} (${report.outcome.authoritativeJobStatus})`, + `StrongBuilderAvoidanceRatio: ${percent(summary.strongBuilderAvoidanceRatio)}`, + `Secondary initial/repair: ${percent(summary.secondaryInitialSuccessRate)} / ${percent(summary.secondaryRepairRecoveryRate)}`, + `ResearchAvoidanceRatio: ${percent(summary.researchAvoidanceRatio)}`, + `UsefulWorkDuringSubscriptionCooldown: ${summary.usefulWorkDuringSubscriptionCooldown}`, + `humanInterventionsAfterSeal: ${summary.humanInterventionsAfterSeal}`, + `CompletedWorkRedoCount: ${summary.completedWorkRedoCount}`, + `Verification / closure: ${report.outcome.verification} / ${report.outcome.closure}` + ].join("\n"), + structured: { report } + }; + } + }); +} + +// ../../packages/mcp-server/src/tools/mission-tools.ts +function missionDeps(context, workspace) { + return { + workspace, + clock: context.clock, + idFactory: context.idFactory, + host: "mcp" + }; +} +var missionIdArg = external_exports.string().min(1).max(64).describe("Mission id (m-\u2026) from mission_begin or mission_status"); +var missionSummaryShape = { + missionId: external_exports.string(), + name: external_exports.string(), + status: external_exports.string(), + specName: external_exports.string().optional(), + openQuestions: external_exports.number().int(), + decisions: external_exports.number().int(), + contracts: external_exports.number().int(), + contractReady: external_exports.boolean().optional() +}; +function summarize3(context, workspace, missionId) { + const mission = requireMissionState(workspace, missionId); + const coverage = readCoverage(workspace, missionId); + return { + missionId: mission.missionId, + name: mission.name, + status: mission.status, + ...mission.specName !== void 0 ? { specName: mission.specName } : {}, + openQuestions: mission.counters.openQuestions, + decisions: mission.counters.decisions, + contracts: mission.counters.contracts, + ...coverage !== void 0 ? { contractReady: coverage.contractReady } : {} + }; +} +function registerMissionBeginTool(server, context) { + registerDefinedTool(server, context, { + name: "mission_begin", + title: "Begin a mission", + description: "Begin Mission Discovery from a high-level product direction. Creates the durable mission record under .specbridge/missions/. Discovery itself is a conversation: record every material visible exchange with mission_record_turn and its structured meaning with mission_assess.", + annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }, + inputSchema: { + name: external_exports.string().min(1).max(120).describe("Short mission name (also the default spec name)"), + goal: external_exports.string().min(1).max(4e3).describe("The user's product direction, verbatim") + }, + outputSchema: { mission: external_exports.object(missionSummaryShape) }, + handler: async (args) => { + const workspace = context.requireWorkspace(); + const mission = beginMission(missionDeps(context, workspace), { name: args.name, goal: args.goal }); + return { + text: `Mission ${mission.missionId} (${mission.name}) created in status ${mission.status}. Record the user's direction as the first turn.`, + structured: { mission: summarize3(context, workspace, mission.missionId) } + }; + } + }); +} +function registerMissionStatusTool(server, context) { + registerDefinedTool(server, context, { + name: "mission_status", + title: "List missions", + description: "List missions (newest first) with lifecycle status, counters, and readiness. Read-only.", + annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, + inputSchema: {}, + outputSchema: { missions: external_exports.array(external_exports.object(missionSummaryShape)) }, + handler: async () => { + const workspace = context.requireWorkspace(); + const listed = listMissions(workspace); + const missions = listed.missions.slice(0, 50).map((mission) => summarize3(context, workspace, mission.missionId)); + return { + text: missions.length === 0 ? "No missions exist. Begin one with mission_begin." : missions.map((mission) => `- ${mission.missionId} ${mission.status} (${mission.name})`).join("\n"), + structured: { missions } + }; + } + }); +} +function registerMissionReadTool(server, context) { + registerDefinedTool(server, context, { + name: "mission_read", + title: "Read one mission", + description: "Read one mission in depth. `view` selects the record family: overview (default), facts, decisions, questions, conversation, coverage, constitution, adrs, or ccrs. Bounded; read-only.", + annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, + inputSchema: { + missionId: missionIdArg, + view: external_exports.enum(["overview", "facts", "decisions", "questions", "conversation", "coverage", "constitution", "adrs", "ccrs"]).optional().describe("Which record family to read (default overview)"), + limit: external_exports.number().int().min(1).max(200).optional().describe("Bounded page size for list views") + }, + outputSchema: { + mission: external_exports.object(missionSummaryShape), + view: external_exports.string(), + records: external_exports.array(external_exports.record(external_exports.unknown())) + }, + handler: async (args) => { + const workspace = context.requireWorkspace(); + const deps = missionDeps(context, workspace); + observeSpecApproval(deps, args.missionId); + const view = args.view ?? "overview"; + const limit = args.limit ?? 50; + let records = []; + switch (view) { + case "overview": { + const overview = describeMission(deps, args.missionId); + records = [ + { + goal: overview.mission.goal, + nonGoals: overview.mission.nonGoals, + targetUsers: overview.mission.targetUsers, + constraints: overview.mission.constraints, + successCriteria: overview.mission.successCriteria, + assumptions: overview.mission.assumptions, + constitutionVersion: overview.constitutionVersion, + activeConstitutionRules: overview.activeConstitutionRules, + contractCount: overview.contractCount, + adrCount: overview.adrCount, + blockingQuestions: overview.blockingQuestions, + openCcrs: overview.openCcrs + } + ]; + break; + } + case "facts": + records = readFacts(workspace, args.missionId).slice(-limit); + break; + case "decisions": + records = readDecisions(workspace, args.missionId).slice(-limit); + break; + case "questions": + records = readQuestions(workspace, args.missionId).slice(-limit); + break; + case "conversation": + records = readTurns(workspace, args.missionId, { limit }).turns; + break; + case "coverage": { + const coverage = readCoverage(workspace, args.missionId); + records = coverage !== void 0 ? [coverage] : []; + break; + } + case "constitution": { + const constitution = readConstitution(workspace, args.missionId); + records = constitution !== void 0 ? [constitution] : []; + break; + } + case "adrs": + records = readAdrs(workspace, args.missionId).slice(-limit); + break; + case "ccrs": + records = readCcrs(workspace, args.missionId).slice(-limit); + break; + } + return { + text: `${view}: ${records.length} record(s).`, + structured: { mission: summarize3(context, workspace, args.missionId), view, records } + }; + } + }); +} +function registerMissionRecordTurnTool(server, context) { + registerDefinedTool(server, context, { + name: "mission_record_turn", + title: "Record a visible discovery turn", + description: "Persist one USER-VISIBLE discovery exchange verbatim: what the user said, or what the agent visibly asked, interpreted, or presented. Turns are the provenance roots every decision traces back to. Never record hidden reasoning \u2014 only what both sides could see.", + annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }, + inputSchema: { + missionId: missionIdArg, + speaker: external_exports.enum(TURN_SPEAKERS).describe("Who produced the visible text"), + kind: external_exports.enum(TURN_KINDS).describe("What kind of exchange this is"), + text: external_exports.string().min(1).max(8e3).describe("The visible text, verbatim"), + inReplyTo: external_exports.string().max(64).optional().describe("Turn id this replies to"), + refs: external_exports.array(external_exports.string().max(64)).max(30).optional().describe("Record ids this turn addresses") + }, + outputSchema: { turnId: external_exports.string(), missionStatus: external_exports.string() }, + handler: async (args) => { + const workspace = context.requireWorkspace(); + const result = recordTurn(missionDeps(context, workspace), args.missionId, { + speaker: args.speaker, + kind: args.kind, + text: args.text, + inReplyTo: args.inReplyTo, + refs: args.refs + }); + return { + text: `Recorded ${result.turn.turnId} (${args.speaker} ${args.kind}). Mission is ${result.mission.status}.`, + structured: { turnId: result.turn.turnId, missionStatus: result.mission.status } + }; + } + }); +} +var factInput = external_exports.object({ + statement: external_exports.string().min(1).max(4e3), + provenance: external_exports.enum(MISSION_PROVENANCE_KINDS), + sourceTurnId: external_exports.string().max(64).optional(), + topics: external_exports.array(external_exports.enum(DISCOVERY_TOPICS)).max(10).optional(), + supersedesFactId: external_exports.string().max(64).optional() +}); +var questionInput = external_exports.object({ + question: external_exports.string().min(1).max(4e3), + whyItMatters: external_exports.string().min(1).max(4e3), + topics: external_exports.array(external_exports.enum(DISCOVERY_TOPICS)).max(10).optional(), + affectedSurfaces: external_exports.array(external_exports.enum(IRREVERSIBLE_SURFACES)).max(10).optional(), + materiality: external_exports.enum(MATERIALITY_LEVELS).optional(), + options: external_exports.array(external_exports.string().max(2e3)).max(10).optional(), + sourceTurnId: external_exports.string().max(64).optional() +}); +var decisionInput = external_exports.object({ + decision: external_exports.string().min(1).max(4e3), + rationale: external_exports.string().max(4e3).optional(), + provenance: external_exports.enum(MISSION_PROVENANCE_KINDS), + sourceTurnId: external_exports.string().max(64).optional(), + questionId: external_exports.string().max(64).optional(), + topics: external_exports.array(external_exports.enum(DISCOVERY_TOPICS)).max(10).optional(), + marksNotApplicable: external_exports.array(external_exports.enum(DISCOVERY_TOPICS)).max(10).optional(), + supersedesDecisionId: external_exports.string().max(64).optional() +}); +var constitutionRuleInput = external_exports.object({ + statement: external_exports.string().min(1).max(4e3), + rationale: external_exports.string().max(4e3).optional(), + decisionIds: external_exports.array(external_exports.string().max(64)).min(1).max(30), + affectedContractIds: external_exports.array(external_exports.string().max(64)).max(30).optional(), + guardPatterns: external_exports.array(external_exports.string().min(1).max(200)).max(10).optional(), + supersedesRuleId: external_exports.string().max(64).optional() +}); +var adrInput = external_exports.object({ + title: external_exports.string().min(1).max(512), + context: external_exports.string().min(1).max(4e3), + decision: external_exports.string().min(1).max(4e3), + alternatives: external_exports.array(external_exports.string().max(4e3)).max(20).optional(), + rationale: external_exports.string().min(1).max(4e3), + consequences: external_exports.array(external_exports.string().max(4e3)).max(20).optional(), + revisitConditions: external_exports.array(external_exports.string().max(4e3)).max(20).optional(), + decisionIds: external_exports.array(external_exports.string().max(64)).max(30).optional(), + turnIds: external_exports.array(external_exports.string().max(64)).max(30).optional(), + supersedesAdrId: external_exports.string().max(64).optional() +}); +var contractInput = external_exports.object({ + title: external_exports.string().min(1).max(512), + summary: external_exports.string().min(1).max(4e3), + classification: external_exports.enum(["public", "internal"]), + compatibilityPolicy: external_exports.enum(["frozen", "additive-only", "evolving", "internal"]), + dependsOn: external_exports.array(external_exports.string().max(64)).max(30).optional(), + requirements: external_exports.array(external_exports.object({ statement: external_exports.string().min(1).max(4e3), decisionIds: external_exports.array(external_exports.string().max(64)).max(30).optional() })).min(1).max(60), + invariants: external_exports.array( + external_exports.object({ + statement: external_exports.string().min(1).max(4e3), + constitutionRuleIds: external_exports.array(external_exports.string().max(64)).max(30).optional(), + guardPatterns: external_exports.array(external_exports.string().min(1).max(200)).max(10).optional() + }) + ).max(60).optional(), + decisionIds: external_exports.array(external_exports.string().max(64)).min(1).max(30), + turnIds: external_exports.array(external_exports.string().max(64)).max(30).optional() +}); +function registerMissionAssessTool(server, context) { + registerDefinedTool(server, context, { + name: "mission_assess", + title: "Record a structured discovery assessment", + description: "Submit the STRUCTURED meaning of the discovery conversation: facts, questions, decisions, constitution rules, ADRs, contracts, and mission field updates. SpecBridge governs every record: decisions need safe provenance (a user-provenance decision must cite a USER turn), question materiality passes the deterministic irreversibility screen (it can only be RAISED), durable artifacts must trace to recorded decisions, and coverage recomputes deterministically. Blocking questions prevent CONTRACT_READY; implementation-detail questions never do.", + annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }, + inputSchema: { + missionId: missionIdArg, + facts: external_exports.array(factInput).max(20).optional(), + questions: external_exports.array(questionInput).max(20).optional(), + decisions: external_exports.array(decisionInput).max(20).optional(), + constitutionRules: external_exports.array(constitutionRuleInput).max(10).optional(), + adrs: external_exports.array(adrInput).max(10).optional(), + contracts: external_exports.array(contractInput).max(10).optional(), + missionUpdates: external_exports.object({ + nonGoals: external_exports.array(external_exports.string().max(4e3)).max(50).optional(), + targetUsers: external_exports.array(external_exports.string().max(4e3)).max(50).optional(), + constraints: external_exports.array(external_exports.string().max(4e3)).max(50).optional(), + successCriteria: external_exports.array(external_exports.string().max(4e3)).max(50).optional(), + assumptions: external_exports.array( + external_exports.object({ + statement: external_exports.string().min(1).max(4e3), + topics: external_exports.array(external_exports.enum(DISCOVERY_TOPICS)).max(10).optional(), + questionId: external_exports.string().max(64).optional() + }) + ).max(50).optional() + }).optional() + }, + outputSchema: { + missionStatus: external_exports.string(), + contractReady: external_exports.boolean(), + factIds: external_exports.array(external_exports.string()), + questionIds: external_exports.array(external_exports.string()), + decisionIds: external_exports.array(external_exports.string()), + constitutionRuleIds: external_exports.array(external_exports.string()), + adrIds: external_exports.array(external_exports.string()), + contractIds: external_exports.array(external_exports.string()), + materialityRaised: external_exports.array( + external_exports.object({ questionId: external_exports.string(), from: external_exports.string(), to: external_exports.string() }) + ), + blockingQuestionIds: external_exports.array(external_exports.string()), + unresolvedRequiredTopics: external_exports.array(external_exports.string()) + }, + handler: async (args) => { + const workspace = context.requireWorkspace(); + const result = recordAssessment(missionDeps(context, workspace), args.missionId, { + facts: args.facts, + questions: args.questions, + decisions: args.decisions, + constitutionRules: args.constitutionRules, + adrs: args.adrs, + contracts: args.contracts, + missionUpdates: args.missionUpdates + }); + const raised = result.materialityRaised.map((entry) => `${entry.questionId} raised ${entry.from} \u2192 ${entry.to}`).join("; "); + return { + text: `Recorded ${result.factIds.length} fact(s), ${result.questionIds.length} question(s), ${result.decisionIds.length} decision(s), ${result.constitutionRuleIds.length} rule(s), ${result.adrIds.length} ADR(s), ${result.contractIds.length} contract(s). Mission is ${result.mission.status}; contract-ready: ${result.coverage.contractReady}.` + (raised.length > 0 ? ` Materiality screen: ${raised}.` : ""), + structured: { + missionStatus: result.mission.status, + contractReady: result.coverage.contractReady, + factIds: result.factIds, + questionIds: result.questionIds, + decisionIds: result.decisionIds, + constitutionRuleIds: result.constitutionRuleIds, + adrIds: result.adrIds, + contractIds: result.contractIds, + materialityRaised: result.materialityRaised, + blockingQuestionIds: result.coverage.blockingQuestionIds, + unresolvedRequiredTopics: result.coverage.unresolvedRequiredTopics + } + }; + } + }); +} +function registerMissionQuestionsTool(server, context) { + registerDefinedTool(server, context, { + name: "mission_questions", + title: "Open discovery questions", + description: "The open questions with materiality and why each matters. Blocking questions gate CONTRACT_READY. Read-only.", + annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, + inputSchema: { missionId: missionIdArg }, + outputSchema: { + questions: external_exports.array( + external_exports.object({ + questionId: external_exports.string(), + question: external_exports.string(), + whyItMatters: external_exports.string(), + materiality: external_exports.string(), + topics: external_exports.array(external_exports.string()), + options: external_exports.array(external_exports.string()) + }) + ) + }, + handler: async (args) => { + const workspace = context.requireWorkspace(); + requireMissionState(workspace, args.missionId); + const questions = readQuestions(workspace, args.missionId).filter((question) => question.status === "open").map((question) => ({ + questionId: question.questionId, + question: question.question, + whyItMatters: question.whyItMatters, + materiality: question.materiality, + topics: [...question.topics], + options: [...question.options] + })); + return { + text: questions.length === 0 ? "No open questions." : questions.map((question) => `- ${question.questionId} [${question.materiality}] ${question.question}`).join("\n"), + structured: { questions } + }; + } + }); +} +function registerMissionAnswerTool(server, context) { + registerDefinedTool(server, context, { + name: "mission_answer", + title: "Record the user\u2019s answer to a question", + description: "Record the USER'S answer to one open discovery question: an answering user turn plus a known-from-user decision bound to it. Relay their words; never answer on their behalf.", + annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }, + inputSchema: { + missionId: missionIdArg, + questionId: external_exports.string().min(1).max(64), + answer: external_exports.string().min(1).max(4e3).describe("The user's answer, verbatim"), + marksNotApplicable: external_exports.array(external_exports.enum(DISCOVERY_TOPICS)).max(10).optional() + }, + outputSchema: { + decisionId: external_exports.string(), + missionStatus: external_exports.string(), + contractReady: external_exports.boolean() + }, + handler: async (args) => { + const workspace = context.requireWorkspace(); + const result = answerQuestion(missionDeps(context, workspace), args.missionId, { + questionId: args.questionId, + answer: args.answer, + marksNotApplicable: args.marksNotApplicable + }); + return { + text: `Recorded ${result.decision.decisionId}. Mission is ${result.mission.status}; contract-ready: ${result.coverage.contractReady}.`, + structured: { + decisionId: result.decision.decisionId, + missionStatus: result.mission.status, + contractReady: result.coverage.contractReady + } + }; + } + }); +} +function registerMissionSynthesizeTool(server, context) { + registerDefinedTool(server, context, { + name: "mission_synthesize", + title: "Synthesize the Kiro spec", + description: "Move a coverage-complete mission to CONTRACT_READY and compile its contract set into Kiro spec candidates: requirements.md, design.md, and OBJECTIVE-oriented tasks.md \u2014 through the existing creation machinery. Approval stays entirely human (`specbridge spec approve \u2026`); nothing here or anywhere on MCP can approve a stage. Fails closed when blocking questions or required topics remain.", + annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }, + inputSchema: { + missionId: missionIdArg, + specName: external_exports.string().max(64).optional().describe("Spec name (default: the mission name)") + }, + outputSchema: { + specName: external_exports.string(), + objectiveCount: external_exports.number().int(), + files: external_exports.array(external_exports.object({ fileName: external_exports.string(), bytes: external_exports.number().int() })) + }, + handler: async (args) => { + const workspace = context.requireWorkspace(); + const deps = missionDeps(context, workspace); + markContractReady(deps, args.missionId); + const result = synthesizeMissionSpec(deps, args.missionId, { specName: args.specName }); + return { + text: `Synthesized spec "${result.specName}" with ${result.objectiveCount} objective(s). The user approves it with: specbridge spec approve ${result.specName} --stage requirements|design|tasks.`, + structured: { + specName: result.specName, + objectiveCount: result.objectiveCount, + files: result.files + } + }; + } + }); +} +function registerContractListTool(server, context) { + registerDefinedTool(server, context, { + name: "contract_list", + title: "List product contracts", + description: "The mission\u2019s product contract registry (current revisions) plus the Architecture Constitution. Read-only.", + annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, + inputSchema: { missionId: missionIdArg }, + outputSchema: { + constitutionVersion: external_exports.number().int(), + rules: external_exports.array(external_exports.object({ ruleId: external_exports.string(), statement: external_exports.string(), status: external_exports.string() })), + contracts: external_exports.array( + external_exports.object({ + contractId: external_exports.string(), + revision: external_exports.number().int(), + title: external_exports.string(), + classification: external_exports.string(), + compatibilityPolicy: external_exports.string() + }) + ) + }, + handler: async (args) => { + const workspace = context.requireWorkspace(); + requireMissionState(workspace, args.missionId); + const constitution = readConstitution(workspace, args.missionId); + const contracts = readContractRegistry(workspace, args.missionId).map((contract) => ({ + contractId: contract.contractId, + revision: contract.revision, + title: contract.title, + classification: contract.classification, + compatibilityPolicy: contract.compatibilityPolicy + })); + return { + text: contracts.map((contract) => `- ${contract.contractId} r${contract.revision} ${contract.title}`).join("\n") || "No contracts recorded.", + structured: { + constitutionVersion: constitution?.version ?? 0, + rules: (constitution?.rules ?? []).map((rule) => ({ + ruleId: rule.ruleId, + statement: rule.statement, + status: rule.status + })), + contracts + } + }; + } + }); +} +function registerContractReadTool(server, context) { + registerDefinedTool(server, context, { + name: "contract_read", + title: "Read one product contract", + description: "One contract in depth: requirements, invariants, dependencies, provenance, revision lineage. Read-only.", + annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, + inputSchema: { + missionId: missionIdArg, + contractId: external_exports.string().min(1).max(64), + revision: external_exports.number().int().min(1).optional().describe("A specific revision (default: current)") + }, + outputSchema: { contract: external_exports.record(external_exports.unknown()) }, + handler: async (args) => { + const workspace = context.requireWorkspace(); + requireMissionState(workspace, args.missionId); + const contract = readContract(workspace, args.missionId, args.contractId, args.revision); + if (contract === void 0) { + return { + text: `Contract ${args.contractId}${args.revision !== void 0 ? ` r${args.revision}` : ""} does not exist.`, + structured: { contract: {} } + }; + } + return { + text: `${contract.contractId} r${contract.revision}: ${contract.title} \u2014 ${contract.requirements.length} requirement(s), ${contract.invariants.length} invariant(s).`, + structured: { contract } + }; + } + }); +} +function registerContractChangeRequestTool(server, context) { + registerDefinedTool(server, context, { + name: "contract_change_request", + title: "Create a contract change request", + description: "Create a durable ContractChangeRequest against a product contract. Anyone may RAISE one; only the human decides it (CLI: `specbridge mission ccr --approve|--reject`). A material request (public contract, frozen/additive policy, or irreversible surface) lands NEEDS_HUMAN and stops affected execution. This tool can never approve anything.", + annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }, + inputSchema: { + missionId: missionIdArg, + contractId: external_exports.string().min(1).max(64), + problem: external_exports.string().min(1).max(4e3).describe("What the current contract cannot express"), + proposal: external_exports.string().min(1).max(4e3).describe("The proposed change"), + affected: external_exports.array(external_exports.string().max(2e3)).max(30).optional().describe("Areas the change would touch") + }, + outputSchema: { + ccrId: external_exports.string(), + status: external_exports.string(), + material: external_exports.boolean() + }, + handler: async (args) => { + const workspace = context.requireWorkspace(); + const result = createContractChangeRequest(missionDeps(context, workspace), args.missionId, { + contractId: args.contractId, + problem: args.problem, + proposal: args.proposal, + affected: args.affected, + raisedBy: "mcp" + }); + return { + text: `${result.ccr.ccrId} created (${result.ccr.status}). ` + (result.material ? "It is material: the human decides it with `specbridge mission ccr \u2026 --approve|--reject`." : "It is recorded for the next contract review."), + structured: { ccrId: result.ccr.ccrId, status: result.ccr.status, material: result.material } + }; + } + }); +} // ../../packages/intake/dist/index.js -var import_fs47 = require("fs"); -var import_path50 = __toESM(require("path"), 1); -var import_path51 = __toESM(require("path"), 1); +var import_crypto18 = require("crypto"); var import_fs48 = require("fs"); -var import_path52 = __toESM(require("path"), 1); +var import_path51 = __toESM(require("path"), 1); var import_fs49 = require("fs"); -var import_path53 = __toESM(require("path"), 1); +var import_path52 = __toESM(require("path"), 1); var import_fs50 = require("fs"); +var import_path53 = __toESM(require("path"), 1); var import_path54 = __toESM(require("path"), 1); +var import_fs51 = require("fs"); +var import_path55 = __toESM(require("path"), 1); +var import_fs52 = require("fs"); +var import_path56 = __toESM(require("path"), 1); +var import_fs53 = require("fs"); +var import_path57 = __toESM(require("path"), 1); var INTAKE_STATUSES = [ /** The source specification is ingested; discovery has not run. */ "INGESTED", @@ -86616,11 +88593,11 @@ function missionDepsOf(deps) { host: deps.host }; } -function now3(deps) { +function now5(deps) { return (deps.clock ?? (() => /* @__PURE__ */ new Date()))(); } -function nowIso2(deps) { - return now3(deps).toISOString(); +function nowIso3(deps) { + return now5(deps).toISOString(); } function hostOf(deps) { return deps.host ?? "cli"; @@ -87039,10 +89016,10 @@ var intakeTelemetrySchema = external_exports.object({ jobId: shortText19.optional(), sealId: shortText19.optional() }).passthrough(); -var ID_PATTERN4 = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/; +var ID_PATTERN5 = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/; var INTAKE_DIR_NAME = "intake"; function assertIntakeId(id) { - if (!ID_PATTERN4.test(id)) { + if (!ID_PATTERN5.test(id)) { throw new IntakeError("SBI005", `Invalid spec intake id "${id}".`, { remediation: ["Ids are generated by SpecBridge; pass one returned by an intake operation."], details: { id } @@ -87053,41 +89030,41 @@ function assertIntakeId(id) { function intakeRootDir(workspace) { return assertInsideWorkspace( workspace.rootDir, - import_path48.default.join(workspace.rootDir, ".specbridge", INTAKE_DIR_NAME) + import_path51.default.join(workspace.rootDir, ".specbridge", INTAKE_DIR_NAME) ); } function intakeDir(workspace, intakeId) { assertIntakeId(intakeId); - return assertInsideWorkspace(workspace.rootDir, import_path48.default.join(intakeRootDir(workspace), intakeId)); + return assertInsideWorkspace(workspace.rootDir, import_path51.default.join(intakeRootDir(workspace), intakeId)); } function intakePath(workspace, intakeId, ...segments) { return assertInsideWorkspace( workspace.rootDir, - import_path48.default.join(intakeDir(workspace, intakeId), ...segments) + import_path51.default.join(intakeDir(workspace, intakeId), ...segments) ); } function writeJson(file, value) { - (0, import_fs45.mkdirSync)(import_path48.default.dirname(file), { recursive: true }); + (0, import_fs48.mkdirSync)(import_path51.default.dirname(file), { recursive: true }); writeFileAtomic(file, `${JSON.stringify(value, null, 2)} `); } function readJson2(file, parse3) { - if (!(0, import_fs45.existsSync)(file)) return void 0; + if (!(0, import_fs48.existsSync)(file)) return void 0; try { - return parse3(JSON.parse((0, import_fs45.readFileSync)(file, "utf8"))); + return parse3(JSON.parse((0, import_fs48.readFileSync)(file, "utf8"))); } catch { return void 0; } } function appendJsonl2(file, value) { - (0, import_fs45.mkdirSync)(import_path48.default.dirname(file), { recursive: true }); - (0, import_fs45.appendFileSync)(file, `${JSON.stringify(value)} + (0, import_fs48.mkdirSync)(import_path51.default.dirname(file), { recursive: true }); + (0, import_fs48.appendFileSync)(file, `${JSON.stringify(value)} `, "utf8"); } function readFolded(file, key, parse3) { - if (!(0, import_fs45.existsSync)(file)) return []; + if (!(0, import_fs48.existsSync)(file)) return []; const folded = /* @__PURE__ */ new Map(); - for (const line of (0, import_fs45.readFileSync)(file, "utf8").split("\n")) { + for (const line of (0, import_fs48.readFileSync)(file, "utf8").split("\n")) { if (line.trim().length === 0) continue; try { const value = parse3(JSON.parse(line)); @@ -87120,16 +89097,16 @@ function writeIntakeState(workspace, state) { } function listIntakes(workspace) { const root = intakeRootDir(workspace); - if (!(0, import_fs45.existsSync)(root)) return { intakes: [], diagnostics: [] }; + if (!(0, import_fs48.existsSync)(root)) return { intakes: [], diagnostics: [] }; const intakes = []; const diagnostics = []; - for (const entry of (0, import_fs45.readdirSync)(root, { withFileTypes: true })) { + for (const entry of (0, import_fs48.readdirSync)(root, { withFileTypes: true })) { if (!entry.isDirectory()) continue; - if (!ID_PATTERN4.test(entry.name)) continue; - const file = import_path48.default.join(root, entry.name, "intake.json"); - if (!(0, import_fs45.existsSync)(file)) continue; + if (!ID_PATTERN5.test(entry.name)) continue; + const file = import_path51.default.join(root, entry.name, "intake.json"); + if (!(0, import_fs48.existsSync)(file)) continue; try { - intakes.push(specIntakeStateSchema.parse(JSON.parse((0, import_fs45.readFileSync)(file, "utf8")))); + intakes.push(specIntakeStateSchema.parse(JSON.parse((0, import_fs48.readFileSync)(file, "utf8")))); } catch (cause) { diagnostics.push({ intakeId: entry.name, @@ -87159,8 +89136,8 @@ function sourceFile(workspace, intakeId, contentHash) { } function storeSourceText(workspace, intakeId, contentHash, content) { const file = sourceFile(workspace, intakeId, contentHash); - if (!(0, import_fs45.existsSync)(file)) { - (0, import_fs45.mkdirSync)(import_path48.default.dirname(file), { recursive: true }); + if (!(0, import_fs48.existsSync)(file)) { + (0, import_fs48.mkdirSync)(import_path51.default.dirname(file), { recursive: true }); writeFileAtomic(file, content); } return file; @@ -87252,7 +89229,7 @@ function appendIntakeEvent(workspace, intakeId, event) { function baselineFile(workspace) { return assertInsideWorkspace( workspace.rootDir, - import_path48.default.join(intakeRootDir(workspace), "baseline.json") + import_path51.default.join(intakeRootDir(workspace), "baseline.json") ); } function readProductBaseline(workspace) { @@ -87862,7 +89839,7 @@ var BUILD_MARKERS = [ ]; function detectBuildSystem(rootDir) { for (const marker of BUILD_MARKERS) { - if ((0, import_fs46.existsSync)(import_path49.default.join(rootDir, marker.file))) return marker.system; + if ((0, import_fs49.existsSync)(import_path52.default.join(rootDir, marker.file))) return marker.system; } return null; } @@ -87899,33 +89876,33 @@ var PUBLIC_INTERFACE_PATTERNS = [ var TEST_DIR_PATTERN = /^(tests?|spec|specs|__tests__|it|integration-tests?|e2e)$/i; function readGitHead(rootDir) { try { - const dotGit = import_path49.default.join(rootDir, ".git"); - if (!(0, import_fs46.existsSync)(dotGit)) return null; + const dotGit = import_path52.default.join(rootDir, ".git"); + if (!(0, import_fs49.existsSync)(dotGit)) return null; let gitDir = dotGit; - if ((0, import_fs46.statSync)(dotGit).isFile()) { - const pointer = (0, import_fs46.readFileSync)(dotGit, "utf8").trim(); + if ((0, import_fs49.statSync)(dotGit).isFile()) { + const pointer = (0, import_fs49.readFileSync)(dotGit, "utf8").trim(); const match = /^gitdir:\s*(.+)$/.exec(pointer); if (match === null) return null; const target = match[1] ?? ""; - gitDir = import_path49.default.isAbsolute(target) ? target : import_path49.default.resolve(rootDir, target); + gitDir = import_path52.default.isAbsolute(target) ? target : import_path52.default.resolve(rootDir, target); } - const headFile = import_path49.default.join(gitDir, "HEAD"); - if (!(0, import_fs46.existsSync)(headFile)) return null; - const head = (0, import_fs46.readFileSync)(headFile, "utf8").trim(); + const headFile = import_path52.default.join(gitDir, "HEAD"); + if (!(0, import_fs49.existsSync)(headFile)) return null; + const head = (0, import_fs49.readFileSync)(headFile, "utf8").trim(); if (/^[0-9a-f]{40}$/i.test(head)) return head.toLowerCase(); const refMatch = /^ref:\s*(.+)$/.exec(head); if (refMatch === null) return null; const ref = (refMatch[1] ?? "").trim(); for (const dir of refDirsFor(gitDir)) { - const refFile = import_path49.default.join(dir, ...ref.split("/")); - if (!(0, import_fs46.existsSync)(refFile)) continue; - const sha = (0, import_fs46.readFileSync)(refFile, "utf8").trim(); + const refFile = import_path52.default.join(dir, ...ref.split("/")); + if (!(0, import_fs49.existsSync)(refFile)) continue; + const sha = (0, import_fs49.readFileSync)(refFile, "utf8").trim(); if (/^[0-9a-f]{40}$/i.test(sha)) return sha.toLowerCase(); } for (const dir of refDirsFor(gitDir)) { - const packed = import_path49.default.join(dir, "packed-refs"); - if (!(0, import_fs46.existsSync)(packed)) continue; - for (const line of (0, import_fs46.readFileSync)(packed, "utf8").split("\n")) { + const packed = import_path52.default.join(dir, "packed-refs"); + if (!(0, import_fs49.existsSync)(packed)) continue; + for (const line of (0, import_fs49.readFileSync)(packed, "utf8").split("\n")) { const entry = /^([0-9a-f]{40})\s+(.+)$/.exec(line.trim()); if (entry !== null && entry[2] === ref) return (entry[1] ?? "").toLowerCase(); } @@ -87937,12 +89914,12 @@ function readGitHead(rootDir) { } function refDirsFor(gitDir) { const dirs = [gitDir]; - const commonFile = import_path49.default.join(gitDir, "commondir"); - if ((0, import_fs46.existsSync)(commonFile)) { + const commonFile = import_path52.default.join(gitDir, "commondir"); + if ((0, import_fs49.existsSync)(commonFile)) { try { - const target = (0, import_fs46.readFileSync)(commonFile, "utf8").trim(); + const target = (0, import_fs49.readFileSync)(commonFile, "utf8").trim(); if (target.length > 0) { - dirs.push(import_path49.default.isAbsolute(target) ? target : import_path49.default.resolve(gitDir, target)); + dirs.push(import_path52.default.isAbsolute(target) ? target : import_path52.default.resolve(gitDir, target)); } } catch { } @@ -87994,7 +89971,7 @@ function groundInRepository(deps, request) { summary: `existing Kiro spec with ${folder.files.length} document(s)`, authoritative: false, topics: [], - path: import_path49.default.posix.join(".kiro", "specs", folder.name) + path: import_path52.default.posix.join(".kiro", "specs", folder.name) }); } for (const steering of safeSteering(workspace, notes)) { @@ -88005,7 +89982,7 @@ function groundInRepository(deps, request) { summary: `steering document (${steering.inclusion})`, authoritative: false, topics: [], - path: import_path49.default.posix.join(".kiro", "steering", steering.fileName) + path: import_path52.default.posix.join(".kiro", "steering", steering.fileName) }); } const buildSystem = detectBuildSystem(workspace.rootDir); @@ -88049,7 +90026,7 @@ function groundInRepository(deps, request) { }); } for (const container of modules.slice(0, 40)) { - const dir = import_path49.default.join(workspace.rootDir, container); + const dir = import_path52.default.join(workspace.rootDir, container); for (const entry of safeReaddir(dir, notes)) { if (!entry.isDirectory()) continue; if (MODULE_DENYLIST.has(entry.name) || entry.name.startsWith(".")) continue; @@ -88099,7 +90076,7 @@ function groundInRepository(deps, request) { return { schemaVersion: INTAKE_GROUNDING_SCHEMA_VERSION, intakeId: request.intakeId, - groundedAt: nowIso2(deps), + groundedAt: nowIso3(deps), baselineCommit: readGitHead(workspace.rootDir), existingProduct, evidence: evidence.slice(0, INTAKE_LIMITS.maxEvidence), @@ -88201,7 +90178,7 @@ function safeSteering(workspace, notes) { } function safeReaddir(dir, notes) { try { - return (0, import_fs46.readdirSync)(dir, { withFileTypes: true }); + return (0, import_fs49.readdirSync)(dir, { withFileTypes: true }); } catch (cause) { notes.push(`Directory ${dir} could not be listed: ${message(cause)}.`); return []; @@ -88303,10 +90280,10 @@ function analyzeDeltaAuthority(request) { ); } for (const cls of AUTHORITY_SENSITIVE_DELTA_CLASSES) { - const count3 = counts[cls] ?? 0; - if (count3 === 0) continue; + const count4 = counts[cls] ?? 0; + if (count4 === 0) continue; reasons.push( - `${count3} statement(s) classified ${cls} and need a product decision before this specification can be approved.` + `${count4} statement(s) classified ${cls} and need a product decision before this specification can be approved.` ); } const complete = items.length > 0 && authoritySensitive.length === 0; @@ -89013,14 +90990,14 @@ function emptyProjectionMap() { function mapFile(workspace, intakeId) { return assertInsideWorkspace( workspace.rootDir, - import_path50.default.join(workspace.rootDir, ".specbridge", "intake", intakeId, "mission-map.json") + import_path53.default.join(workspace.rootDir, ".specbridge", "intake", intakeId, "mission-map.json") ); } function readProjectionMap(workspace, intakeId) { const file = mapFile(workspace, intakeId); - if (!(0, import_fs47.existsSync)(file)) return emptyProjectionMap(); + if (!(0, import_fs50.existsSync)(file)) return emptyProjectionMap(); try { - const raw = JSON.parse((0, import_fs47.readFileSync)(file, "utf8")); + const raw = JSON.parse((0, import_fs50.readFileSync)(file, "utf8")); return { itemContracts: raw.itemContracts ?? {}, itemDecisions: raw.itemDecisions ?? {}, @@ -89035,7 +91012,7 @@ function readProjectionMap(workspace, intakeId) { } function writeProjectionMap(workspace, intakeId, map) { const file = mapFile(workspace, intakeId); - (0, import_fs47.mkdirSync)(import_path50.default.dirname(file), { recursive: true }); + (0, import_fs50.mkdirSync)(import_path53.default.dirname(file), { recursive: true }); writeFileAtomic(file, `${JSON.stringify(map, null, 2)} `); } @@ -89585,7 +91562,7 @@ function startSpecIntake(deps, request) { const contentHash = sha256Hex(content); const storedPath = storeSourceText(deps.workspace, intakeId, contentHash, content); const parsed = parseSpecificationDocument(content); - const at = nowIso2(deps); + const at = nowIso3(deps); const goal = request.goal?.trim() ?? deriveGoal(parsed.chunks, name); const mission = beginMission(missionDepsOf(deps), { name, goal }); const source = writeSpecSource(deps.workspace, { @@ -89597,7 +91574,7 @@ function startSpecIntake(deps, request) { receivedVia: hostOf(deps), byteLength, contentHash, - storedAt: import_path51.default.posix.join( + storedAt: import_path54.default.posix.join( ".specbridge", "intake", intakeId, @@ -89658,7 +91635,7 @@ function runIntakeDiscovery(deps, intakeId, options = {}) { throw new IntakeError("SBI004", `Spec intake ${intakeId} is ABANDONED and read-only.`); } const source = requireSpecSource(deps.workspace, intakeId); - const at = nowIso2(deps); + const at = nowIso3(deps); const grounding = writeGrounding( deps.workspace, groundInRepository(deps, { @@ -89902,7 +91879,7 @@ function answerIntakeQuestion(deps, intakeId, request, options = {}) { `Question ${request.questionId} was never mirrored into the mission and cannot record a governed answer.` ); } - const at = nowIso2(deps); + const at = nowIso3(deps); const result = answerQuestion(missionDepsOf(deps), intake.missionId, { questionId: question.missionQuestionId, answer @@ -90169,7 +92146,7 @@ var repositoryManifestSchema = external_exports.object({ function repositoryManifestFile(workspace) { return assertInsideWorkspace( workspace.rootDir, - import_path52.default.join(workspace.sidecarDir, "repositories.json") + import_path55.default.join(workspace.sidecarDir, "repositories.json") ); } var DETECTION_DENYLIST = /* @__PURE__ */ new Set([ @@ -90186,10 +92163,10 @@ var DETECTION_DENYLIST = /* @__PURE__ */ new Set([ ]); function readRepositoryManifest(workspace) { const file = repositoryManifestFile(workspace); - if (!(0, import_fs48.existsSync)(file)) return void 0; + if (!(0, import_fs51.existsSync)(file)) return void 0; let raw; try { - raw = JSON.parse((0, import_fs48.readFileSync)(file, "utf8")); + raw = JSON.parse((0, import_fs51.readFileSync)(file, "utf8")); } catch (cause) { throw new IntakeError("SBI018", `The repository manifest at ${file} is not valid JSON.`, { remediation: ["Fix or delete .specbridge/repositories.json; without it the workspace root is the repository."], @@ -90209,7 +92186,7 @@ function resolveRepositories(workspace) { } seen.add(entry.id); const absDir = assertInsideWorkspace(workspace.rootDir, entry.path); - if (!(0, import_fs48.existsSync)(absDir) || !(0, import_fs48.statSync)(absDir).isDirectory()) { + if (!(0, import_fs51.existsSync)(absDir) || !(0, import_fs51.statSync)(absDir).isDirectory()) { throw new IntakeError( "SBI018", `The repository manifest names "${entry.id}" at ${entry.path}, which is not a directory.`, @@ -90226,11 +92203,11 @@ function resolveRepositories(workspace) { } const children = []; try { - for (const entry of (0, import_fs48.readdirSync)(workspace.rootDir, { withFileTypes: true })) { + for (const entry of (0, import_fs51.readdirSync)(workspace.rootDir, { withFileTypes: true })) { if (!entry.isDirectory()) continue; if (DETECTION_DENYLIST.has(entry.name) || entry.name.startsWith(".")) continue; - const absDir = import_path52.default.join(workspace.rootDir, entry.name); - if (!(0, import_fs48.existsSync)(import_path52.default.join(absDir, ".git"))) continue; + const absDir = import_path55.default.join(workspace.rootDir, entry.name); + if (!(0, import_fs51.existsSync)(import_path55.default.join(absDir, ".git"))) continue; if (children.length >= BOOTSTRAP_LIMITS.maxRepositories) { notes.push("More child repositories exist than the bootstrap bound; declare a manifest to choose."); break; @@ -90241,7 +92218,7 @@ function resolveRepositories(workspace) { notes.push(`The workspace root could not be listed: ${cause instanceof Error ? cause.message : String(cause)}.`); } if (children.length > 0) { - const rootIsRepo = (0, import_fs48.existsSync)(import_path52.default.join(workspace.rootDir, ".git")); + const rootIsRepo = (0, import_fs51.existsSync)(import_path55.default.join(workspace.rootDir, ".git")); const repositories = rootIsRepo ? [resolved(workspace, rootRepositoryId(workspace), workspace.rootDir, void 0), ...children] : children; return { repositories: repositories.slice(0, BOOTSTRAP_LIMITS.maxRepositories), @@ -90256,18 +92233,18 @@ function resolveRepositories(workspace) { }; } function rootRepositoryId(workspace) { - const base = import_path52.default.basename(workspace.rootDir).replace(/[^A-Za-z0-9._-]/g, "-").replace(/^[^A-Za-z0-9]+/, ""); + const base = import_path55.default.basename(workspace.rootDir).replace(/[^A-Za-z0-9._-]/g, "-").replace(/^[^A-Za-z0-9]+/, ""); return base.length > 0 ? base.slice(0, 64) : "workspace"; } function resolved(workspace, repositoryId, absDir, role) { - const relPath = import_path52.default.relative(workspace.rootDir, absDir).replace(/\\/g, "/"); + const relPath = import_path55.default.relative(workspace.rootDir, absDir).replace(/\\/g, "/"); return { repositoryId, relPath, ...role !== void 0 ? { role } : {}, absDir, gitHead: readGitHead(absDir), - isGitRepository: (0, import_fs48.existsSync)(import_path52.default.join(absDir, ".git")) + isGitRepository: (0, import_fs51.existsSync)(import_path55.default.join(absDir, ".git")) }; } function repositoryOfPath(repositories, workspaceRelativePath) { @@ -90460,7 +92437,7 @@ function synthesizeSystemFindings(input) { }); } const manifestEntries = entries.filter( - (entry) => MANIFEST_BASENAMES.has(import_path53.default.posix.basename(entry.path).toLowerCase()) + (entry) => MANIFEST_BASENAMES.has(import_path56.default.posix.basename(entry.path).toLowerCase()) ); const architectureLabels = /* @__PURE__ */ new Map(); for (const entry of manifestEntries.slice(0, 40)) { @@ -90505,7 +92482,7 @@ function synthesizeSystemFindings(input) { architecture.push({ findingId: ids("arc"), class: "OBSERVED_IMPLEMENTATION", - statement: clip3(`${label} (declared by ${import_path53.default.posix.basename(entry.path)}).`), + statement: clip3(`${label} (declared by ${import_path56.default.posix.basename(entry.path)}).`), evidence: [fileRef(entry)] }); } @@ -90650,7 +92627,7 @@ function synthesizeSystemFindings(input) { findingId: ids("con"), class: "OBSERVED_IMPLEMENTATION", statement: clip3( - `Repository "${repo.repositoryId}" builds with ${import_path53.default.posix.basename(marker.path)}.` + `Repository "${repo.repositoryId}" builds with ${import_path56.default.posix.basename(marker.path)}.` ), evidence: [fileRef(marker)] }); @@ -90722,9 +92699,9 @@ function clip3(value) { } function boundedRead(workspace, relPath) { try { - const abs = import_path53.default.join(workspace.rootDir, relPath); - if (!(0, import_fs49.existsSync)(abs)) return void 0; - const body = (0, import_fs49.readFileSync)(abs, "utf8"); + const abs = import_path56.default.join(workspace.rootDir, relPath); + if (!(0, import_fs52.existsSync)(abs)) return void 0; + const body = (0, import_fs52.readFileSync)(abs, "utf8"); return body.length > MAX_MANIFEST_READ_BYTES ? body.slice(0, MAX_MANIFEST_READ_BYTES) : body; } catch { return void 0; @@ -90765,25 +92742,25 @@ function safeSeals(workspace) { } } function bootstrapDir(workspace) { - return assertInsideWorkspace(workspace.rootDir, import_path54.default.join(workspace.sidecarDir, "bootstrap")); + return assertInsideWorkspace(workspace.rootDir, import_path57.default.join(workspace.sidecarDir, "bootstrap")); } function snapshotFile(workspace) { return assertInsideWorkspace( workspace.rootDir, - import_path54.default.join(bootstrapDir(workspace), "current-system-snapshot.json") + import_path57.default.join(bootstrapDir(workspace), "current-system-snapshot.json") ); } function readCurrentSystemSnapshot(workspace) { const file = snapshotFile(workspace); - if (!(0, import_fs50.existsSync)(file)) return void 0; + if (!(0, import_fs53.existsSync)(file)) return void 0; try { - return currentSystemSnapshotSchema.parse(JSON.parse((0, import_fs50.readFileSync)(file, "utf8"))); + return currentSystemSnapshotSchema.parse(JSON.parse((0, import_fs53.readFileSync)(file, "utf8"))); } catch { return void 0; } } function persistSnapshot(workspace, snapshot2) { - (0, import_fs50.mkdirSync)(bootstrapDir(workspace), { recursive: true }); + (0, import_fs53.mkdirSync)(bootstrapDir(workspace), { recursive: true }); writeFileAtomic(snapshotFile(workspace), `${JSON.stringify(snapshot2, null, 2)} `); } @@ -90831,7 +92808,7 @@ function bootstrapWorkspace(deps, options = {}) { const ensured = ensureRepositoryIndex({ workspace, config: deps.config, - now: nowIso2(deps), + now: nowIso3(deps), // Bootstrap has no Git snapshot to name additions, so the refresh walks // for them: a snapshot that missed a brand-new capability file would // claim currency over a repository it has not actually seen. @@ -90881,12 +92858,12 @@ function bootstrapWorkspace(deps, options = {}) { schemaVersion: BOOTSTRAP_SCHEMA_VERSION, snapshotId: `snap-${contentHash.slice(0, 12)}`, workspaceKey: workspaceKeyFor(workspace.rootDir), - createdAt: nowIso2(deps), + createdAt: nowIso3(deps), ...material, indexStats: { entries: ensured.state.entries.length, truncated: ensured.state.truncated, - skipped: Object.values(ensured.state.skippedCounts).reduce((sum, count3) => sum + count3, 0) + skipped: Object.values(ensured.state.skippedCounts).reduce((sum, count4) => sum + count4, 0) }, contentHash }); @@ -90899,11 +92876,11 @@ function bootstrapWorkspace(deps, options = {}) { }; } function countIndexed(index, repositories, repo) { - let count3 = 0; + let count4 = 0; for (const entry of index.entries) { - if (repositoryOfPath(repositories, entry.path)?.repositoryId === repo.repositoryId) count3 += 1; + if (repositoryOfPath(repositories, entry.path)?.repositoryId === repo.repositoryId) count4 += 1; } - return count3; + return count4; } function readWorkspaceSnapshot(workspace) { const snapshot2 = readCurrentSystemSnapshot(workspace); @@ -90924,7 +92901,7 @@ function inspectWorkspace(deps, options) { const ensured = ensureRepositoryIndex({ workspace, config: deps.config, - now: nowIso2(deps) + now: nowIso3(deps) }); const query = buildRetrievalQuery({ taskId: "workspace-inspect", @@ -90956,7 +92933,7 @@ function inspectWorkspace(deps, options) { } let body; try { - body = (0, import_fs50.readFileSync)( + body = (0, import_fs53.readFileSync)( assertInsideWorkspace(workspace.rootDir, entry.path), "utf8" ); @@ -92039,6 +94016,7 @@ function registerAllTools(server, context) { registerOrchestrationFinalizeTool(server, context); registerJobListTool(server, context); registerJobReadTool(server, context); + registerJobReportTool(server, context); registerJobCancelTool(server, context); registerMissionBeginTool(server, context); registerMissionStatusTool(server, context); diff --git a/integrations/codex-plugin/specbridge/dist/checksums.json b/integrations/codex-plugin/specbridge/dist/checksums.json index c297a09..cccedd2 100644 --- a/integrations/codex-plugin/specbridge/dist/checksums.json +++ b/integrations/codex-plugin/specbridge/dist/checksums.json @@ -7,16 +7,16 @@ "bytes": 155992 }, "cli.cjs": { - "sha256": "9b6d58aef80578e88c81a1c48606cb13ac0d02d41d9acccc7e3cc67348c1c698", - "bytes": 5739368 + "sha256": "91d51d28006410e893ba0f19b1989e0e170a4c2820bf3fd2770a84686777fe2c", + "bytes": 5814917 }, "mcp-launcher.cjs": { "sha256": "205d2730178bcdb5a06e199a42a6a6fb0977f42d706f3d445aec801a60874b3e", "bytes": 4567 }, "mcp-server.cjs": { - "sha256": "f096d9dff325c106c15334e6c67baef15771789e5aa2ddd06858894987ae9b4c", - "bytes": 3669226 + "sha256": "0cf0895d3af59c3de92fbf899965f2c093145e1f5aa3bf23846ec59e9a5568d6", + "bytes": 3758229 } } } diff --git a/integrations/codex-plugin/specbridge/dist/cli.cjs b/integrations/codex-plugin/specbridge/dist/cli.cjs index b8dc769..def6b81 100644 --- a/integrations/codex-plugin/specbridge/dist/cli.cjs +++ b/integrations/codex-plugin/specbridge/dist/cli.cjs @@ -3597,8 +3597,8 @@ var require_Node = __commonJS({ }; const res = toJS.toJS(this, "", ctx); if (typeof onAnchor === "function") - for (const { count: count3, res: res2 } of ctx.anchors.values()) - onAnchor(res2, count3); + for (const { count: count4, res: res2 } of ctx.anchors.values()) + onAnchor(res2, count4); return typeof reviver === "function" ? applyReviver.applyReviver(reviver, { "": res }, "", res) : res; } }; @@ -3704,13 +3704,13 @@ var require_Alias = __commonJS({ const anchor = anchors2 && source && anchors2.get(source); return anchor ? anchor.count * anchor.aliasCount : 0; } else if (identity3.isCollection(node)) { - let count3 = 0; + let count4 = 0; for (const item of node.items) { const c3 = getAliasCount(doc, item, anchors2); - if (c3 > count3) - count3 = c3; + if (c3 > count4) + count4 = c3; } - return count3; + return count4; } else if (identity3.isPair(node)) { const kc = getAliasCount(doc, node.key, anchors2); const vc = getAliasCount(doc, node.value, anchors2); @@ -6663,8 +6663,8 @@ var require_Document = __commonJS({ }; const res = toJS.toJS(this.contents, jsonArg ?? "", ctx); if (typeof onAnchor === "function") - for (const { count: count3, res: res2 } of ctx.anchors.values()) - onAnchor(res2, count3); + for (const { count: count4, res: res2 } of ctx.anchors.values()) + onAnchor(res2, count4); return typeof reviver === "function" ? applyReviver.applyReviver(reviver, { "": res }, "", res) : res; } /** @@ -6741,12 +6741,12 @@ var require_errors = __commonJS({ lineStr = prev + lineStr; } if (/[^ ]/.test(lineStr)) { - let count3 = 1; + let count4 = 1; const end = error2.linePos[1]; if (end?.line === line && end.col > col) { - count3 = Math.max(1, Math.min(end.col - col, 80 - ci)); + count4 = Math.max(1, Math.min(end.col - col, 80 - ci)); } - const pointer = " ".repeat(ci) + "^".repeat(count3); + const pointer = " ".repeat(ci) + "^".repeat(count4); error2.message += `: ${lineStr} @@ -6765,7 +6765,7 @@ ${pointer} var require_resolve_props = __commonJS({ "../../node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/dist/compose/resolve-props.js"(exports2) { "use strict"; - function resolveProps(tokens, { flow, indicator, next, offset, onError, parentIndent, startOnNewline }) { + function resolveProps(tokens2, { flow, indicator, next, offset, onError, parentIndent, startOnNewline }) { let spaceBefore = false; let atNewline = startOnNewline; let hasSpace = startOnNewline; @@ -6780,7 +6780,7 @@ var require_resolve_props = __commonJS({ let comma = null; let found = null; let start = null; - for (const token of tokens) { + for (const token of tokens2) { if (reqSpace) { if (token.type !== "space" && token.type !== "newline" && token.type !== "comma") onError(token.offset, "MISSING_CHAR", "Tags and anchors must be separated from the next token by white space"); @@ -6871,7 +6871,7 @@ var require_resolve_props = __commonJS({ hasSpace = false; } } - const last = tokens[tokens.length - 1]; + const last = tokens2[tokens2.length - 1]; const end = last ? last.offset + last.source.length : offset; if (reqSpace && next && next.type !== "space" && next.type !== "newline" && next.type !== "comma" && (next.type !== "scalar" || next.source !== "")) { onError(next.offset, "MISSING_CHAR", "Tags and anchors must be separated from the next token by white space"); @@ -8210,8 +8210,8 @@ ${cb}` : comment; * @param forceDoc - If the stream contains no document, still emit a final document including any comments and directives that would be applied to a subsequent document. * @param endOffset - Should be set if `forceDoc` is also set, to set the document range end and to indicate errors correctly. */ - *compose(tokens, forceDoc = false, endOffset = -1) { - for (const token of tokens) + *compose(tokens2, forceDoc = false, endOffset = -1) { + for (const token of tokens2) yield* this.next(token); yield* this.end(forceDoc, endOffset); } @@ -11246,7 +11246,7 @@ var require_scan = __commonJS({ const length = input.length - 1; const scanToEnd = opts.parts === true || opts.scanToEnd === true; const slashes = []; - const tokens = []; + const tokens2 = []; const parts = []; let str = input; let index = -1; @@ -11330,7 +11330,7 @@ var require_scan = __commonJS({ } if (code2 === CHAR_FORWARD_SLASH) { slashes.push(index); - tokens.push(token); + tokens2.push(token); token = { value: "", depth: 0, isGlob: false }; if (finished7 === true) continue; if (prev === CHAR_DOT && index === start + 1) { @@ -11483,9 +11483,9 @@ var require_scan = __commonJS({ if (opts.tokens === true) { state.maxDepth = 0; if (!isPathSeparator(code2)) { - tokens.push(token); + tokens2.push(token); } - state.tokens = tokens; + state.tokens = tokens2; } if (opts.parts === true || opts.tokens === true) { let prevIndex; @@ -11495,13 +11495,13 @@ var require_scan = __commonJS({ const value = input.slice(n2, i2); if (opts.tokens) { if (idx === 0 && start !== 0) { - tokens[idx].isPrefix = true; - tokens[idx].value = prefix; + tokens2[idx].isPrefix = true; + tokens2[idx].value = prefix; } else { - tokens[idx].value = value; + tokens2[idx].value = value; } - depth(tokens[idx]); - state.maxDepth += tokens[idx].depth; + depth(tokens2[idx]); + state.maxDepth += tokens2[idx].depth; } if (idx !== 0 || value !== "") { parts.push(value); @@ -11512,9 +11512,9 @@ var require_scan = __commonJS({ const value = input.slice(prevIndex + 1); parts.push(value); if (opts.tokens) { - tokens[tokens.length - 1].value = value; - depth(tokens[tokens.length - 1]); - state.maxDepth += tokens[tokens.length - 1].depth; + tokens2[tokens2.length - 1].value = value; + depth(tokens2[tokens2.length - 1]); + state.maxDepth += tokens2[tokens2.length - 1].depth; } } state.slashes = slashes; @@ -11791,7 +11791,7 @@ var require_parse2 = __commonJS({ throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); } const bos = { type: "bos", value: "", output: opts.prepend || "" }; - const tokens = [bos]; + const tokens2 = [bos]; const capture = opts.capture ? "" : "?:"; const PLATFORM_CHARS = constants5.globChars(opts.windows); const EXTGLOB_CHARS = constants5.extglobChars(PLATFORM_CHARS); @@ -11836,7 +11836,7 @@ var require_parse2 = __commonJS({ parens: 0, quotes: 0, globstar: false, - tokens + tokens: tokens2 }; input = utils.removePrefix(input, state); len = input.length; @@ -11858,20 +11858,20 @@ var require_parse2 = __commonJS({ consume(token.value); }; const negate = () => { - let count3 = 1; + let count4 = 1; while (peek() === "!" && (peek(2) !== "(" || peek(3) === "?")) { advance(); state.start++; - count3++; + count4++; } - if (count3 % 2 === 0) { + if (count4 % 2 === 0) { return false; } state.negated = true; state.start++; return true; }; - const increment2 = (type) => { + const increment3 = (type) => { state[type]++; stack.push(type); }; @@ -11901,7 +11901,7 @@ var require_parse2 = __commonJS({ return; } tok.prev = prev; - tokens.push(tok); + tokens2.push(tok); prev = tok; }; const extglobOpen = (type, value2) => { @@ -11910,9 +11910,9 @@ var require_parse2 = __commonJS({ token.parens = state.parens; token.output = state.output; token.startIndex = state.index; - token.tokensIndex = tokens.length; + token.tokensIndex = tokens2.length; const output = (opts.capture ? "(" : "") + token.open; - increment2("parens"); + increment3("parens"); push2({ type, value: value2, output: state.output ? "" : ONE_CHAR }); push2({ type: "paren", extglob: true, value: advance(), output }); extglobs.push(token); @@ -11923,14 +11923,14 @@ var require_parse2 = __commonJS({ const analysis = analyzeRepeatedExtglob(body, opts); if ((token.type === "plus" || token.type === "star") && analysis.risky) { const safeOutput = analysis.safeOutput ? (token.output ? "" : ONE_CHAR) + (opts.capture ? `(${analysis.safeOutput})` : analysis.safeOutput) : void 0; - const open = tokens[token.tokensIndex]; + const open = tokens2[token.tokensIndex]; open.type = "text"; open.value = literal2; open.output = safeOutput || utils.escapeRegex(literal2); - for (let i2 = token.tokensIndex + 1; i2 < tokens.length; i2++) { - tokens[i2].value = ""; - tokens[i2].output = ""; - delete tokens[i2].suffix; + for (let i2 = token.tokensIndex + 1; i2 < tokens2.length; i2++) { + tokens2[i2].value = ""; + tokens2[i2].output = ""; + delete tokens2[i2].suffix; } state.output = token.output + open.output; state.backtrack = true; @@ -12053,7 +12053,7 @@ var require_parse2 = __commonJS({ prev.value = pre + posix; state.backtrack = true; advance(); - if (!bos.output && tokens.indexOf(prev) === 1) { + if (!bos.output && tokens2.indexOf(prev) === 1) { bos.output = ONE_CHAR; } continue; @@ -12088,7 +12088,7 @@ var require_parse2 = __commonJS({ continue; } if (value === "(") { - increment2("parens"); + increment3("parens"); push2({ type: "paren", value }); continue; } @@ -12112,7 +12112,7 @@ var require_parse2 = __commonJS({ } value = `\\${value}`; } else { - increment2("brackets"); + increment3("brackets"); } push2({ type: "bracket", value }); continue; @@ -12151,7 +12151,7 @@ var require_parse2 = __commonJS({ continue; } if (value === "{" && opts.nobrace !== true) { - increment2("braces"); + increment3("braces"); const open = { type: "brace", value, @@ -12171,10 +12171,10 @@ var require_parse2 = __commonJS({ } let output = ")"; if (brace.dots === true) { - const arr = tokens.slice(); + const arr = tokens2.slice(); const range = []; for (let i2 = arr.length - 1; i2 >= 0; i2--) { - tokens.pop(); + tokens2.pop(); if (arr[i2].type === "brace") { break; } @@ -12222,7 +12222,7 @@ var require_parse2 = __commonJS({ state.start = state.index + 1; state.consumed = ""; state.output = ""; - tokens.pop(); + tokens2.pop(); prev = bos; continue; } @@ -14602,9 +14602,9 @@ var require_keyword = __commonJS({ if (Array.isArray(def.keyword) ? !def.keyword.includes(keyword) : def.keyword !== keyword) { throw new Error("ajv implementation error"); } - const deps3 = def.dependencies; - if (deps3 === null || deps3 === void 0 ? void 0 : deps3.some((kwd) => !Object.prototype.hasOwnProperty.call(schema, kwd))) { - throw new Error(`parent schema must have dependencies of ${keyword}: ${deps3.join(",")}`); + const deps4 = def.dependencies; + if (deps4 === null || deps4 === void 0 ? void 0 : deps4.some((kwd) => !Object.prototype.hasOwnProperty.call(schema, kwd))) { + throw new Error(`parent schema must have dependencies of ${keyword}: ${deps4.join(",")}`); } if (def.validateSchema) { const valid = def.validateSchema(schema[keyword]); @@ -14884,20 +14884,20 @@ var require_resolve = __commonJS({ return false; } function countKeys(schema) { - let count3 = 0; + let count4 = 0; for (const key in schema) { if (key === "$ref") return Infinity; - count3++; + count4++; if (SIMPLE_INLINED.has(key)) continue; if (typeof schema[key] == "object") { - (0, util_1.eachItem)(schema[key], (sch) => count3 += countKeys(sch)); + (0, util_1.eachItem)(schema[key], (sch) => count4 += countKeys(sch)); } - if (count3 === Infinity) + if (count4 === Infinity) return Infinity; } - return count3; + return count4; } function getFullPath(resolver, id = "", normalize3) { if (normalize3 !== false) @@ -18069,8 +18069,8 @@ var require_contains = __commonJS({ cxt.result(valid, () => cxt.reset()); function validateItemsWithCount() { const schValid = gen.name("_valid"); - const count3 = gen.let("count", 0); - validateItems(schValid, () => gen.if(schValid, () => checkLimits(count3))); + const count4 = gen.let("count", 0); + validateItems(schValid, () => gen.if(schValid, () => checkLimits(count4))); } function validateItems(_valid, block) { gen.forRange("i", 0, len, (i2) => { @@ -18083,16 +18083,16 @@ var require_contains = __commonJS({ block(); }); } - function checkLimits(count3) { - gen.code((0, codegen_1._)`${count3}++`); + function checkLimits(count4) { + gen.code((0, codegen_1._)`${count4}++`); if (max === void 0) { - gen.if((0, codegen_1._)`${count3} >= ${min}`, () => gen.assign(valid, true).break()); + gen.if((0, codegen_1._)`${count4} >= ${min}`, () => gen.assign(valid, true).break()); } else { - gen.if((0, codegen_1._)`${count3} > ${max}`, () => gen.assign(valid, false).break()); + gen.if((0, codegen_1._)`${count4} > ${max}`, () => gen.assign(valid, false).break()); if (min === 1) gen.assign(valid, true); else - gen.if((0, codegen_1._)`${count3} >= ${min}`, () => gen.assign(valid, true)); + gen.if((0, codegen_1._)`${count4} >= ${min}`, () => gen.assign(valid, true)); } } } @@ -18111,14 +18111,14 @@ var require_dependencies = __commonJS({ var util_1 = require_util(); var code_1 = require_code2(); exports2.error = { - message: ({ params: { property, depsCount, deps: deps3 } }) => { + message: ({ params: { property, depsCount, deps: deps4 } }) => { const property_ies = depsCount === 1 ? "property" : "properties"; - return (0, codegen_1.str)`must have ${property_ies} ${deps3} when property ${property} is present`; + return (0, codegen_1.str)`must have ${property_ies} ${deps4} when property ${property} is present`; }, - params: ({ params: { property, depsCount, deps: deps3, missingProperty } }) => (0, codegen_1._)`{property: ${property}, + params: ({ params: { property, depsCount, deps: deps4, missingProperty } }) => (0, codegen_1._)`{property: ${property}, missingProperty: ${missingProperty}, depsCount: ${depsCount}, - deps: ${deps3}}` + deps: ${deps4}}` // TODO change to reference }; var def = { @@ -18138,8 +18138,8 @@ var require_dependencies = __commonJS({ for (const key in schema) { if (key === "__proto__") continue; - const deps3 = Array.isArray(schema[key]) ? propertyDeps : schemaDeps; - deps3[key] = schema[key]; + const deps4 = Array.isArray(schema[key]) ? propertyDeps : schemaDeps; + deps4[key] = schema[key]; } return [propertyDeps, schemaDeps]; } @@ -18149,23 +18149,23 @@ var require_dependencies = __commonJS({ return; const missing = gen.let("missing"); for (const prop in propertyDeps) { - const deps3 = propertyDeps[prop]; - if (deps3.length === 0) + const deps4 = propertyDeps[prop]; + if (deps4.length === 0) continue; const hasProperty = (0, code_1.propertyInData)(gen, data, prop, it.opts.ownProperties); cxt.setParams({ property: prop, - depsCount: deps3.length, - deps: deps3.join(", ") + depsCount: deps4.length, + deps: deps4.join(", ") }); if (it.allErrors) { gen.if(hasProperty, () => { - for (const depProp of deps3) { + for (const depProp of deps4) { (0, code_1.checkReportMissingProp)(cxt, depProp); } }); } else { - gen.if((0, codegen_1._)`${hasProperty} && (${(0, code_1.checkMissingProp)(cxt, deps3, missing)})`); + gen.if((0, codegen_1._)`${hasProperty} && (${(0, code_1.checkMissingProp)(cxt, deps4, missing)})`); (0, code_1.reportMissingProp)(cxt, missing); gen.else(); } @@ -30480,28 +30480,28 @@ var getJoinLength = (uint8Arrays) => { // ../../node_modules/.pnpm/execa@9.6.1/node_modules/execa/lib/methods/template.js var isTemplateString = (templates) => Array.isArray(templates) && Array.isArray(templates.raw); var parseTemplates = (templates, expressions) => { - let tokens = []; + let tokens2 = []; for (const [index, template2] of templates.entries()) { - tokens = parseTemplate({ + tokens2 = parseTemplate({ templates, expressions, - tokens, + tokens: tokens2, index, template: template2 }); } - if (tokens.length === 0) { + if (tokens2.length === 0) { throw new TypeError("Template script must not be empty"); } - const [file, ...commandArguments] = tokens; + const [file, ...commandArguments] = tokens2; return [file, commandArguments, {}]; }; -var parseTemplate = ({ templates, expressions, tokens, index, template: template2 }) => { +var parseTemplate = ({ templates, expressions, tokens: tokens2, index, template: template2 }) => { if (template2 === void 0) { throw new TypeError(`Invalid backslash sequence: ${templates.raw[index]}`); } const { nextTokens, leadingWhitespaces, trailingWhitespaces } = splitByWhitespaces(template2, templates.raw[index]); - const newTokens = concatTokens(tokens, nextTokens, leadingWhitespaces); + const newTokens = concatTokens(tokens2, nextTokens, leadingWhitespaces); if (index === expressions.length) { return newTokens; } @@ -30543,9 +30543,9 @@ var splitByWhitespaces = (template2, rawTemplate) => { }; var DELIMITERS = /* @__PURE__ */ new Set([" ", " ", "\r", "\n"]); var ESCAPE_LENGTH = { x: 3, u: 5 }; -var concatTokens = (tokens, nextTokens, isSeparated) => isSeparated || tokens.length === 0 || nextTokens.length === 0 ? [...tokens, ...nextTokens] : [ - ...tokens.slice(0, -1), - `${tokens.at(-1)}${nextTokens[0]}`, +var concatTokens = (tokens2, nextTokens, isSeparated) => isSeparated || tokens2.length === 0 || nextTokens.length === 0 ? [...tokens2, ...nextTokens] : [ + ...tokens2.slice(0, -1), + `${tokens2.at(-1)}${nextTokens[0]}`, ...nextTokens.slice(1) ]; var parseExpression = (expression) => { @@ -33463,7 +33463,7 @@ function parseMilliseconds(milliseconds) { // ../../node_modules/.pnpm/pretty-ms@9.3.0/node_modules/pretty-ms/index.js var isZero = (value) => value === 0 || value === 0n; -var pluralize = (word, count3) => count3 === 1 || count3 === 1n ? word : `${word}s`; +var pluralize = (word, count4) => count4 === 1 || count4 === 1n ? word : `${word}s`; var SECOND_ROUNDING_EPSILON = 1e-7; var ONE_DAY_IN_MILLISECONDS = 24n * 60n * 60n * 1000n; function prettyMilliseconds(milliseconds, options) { @@ -35467,10 +35467,10 @@ var errorStream = (stream, error2) => { }; var noop2 = () => { }; -var updateMaxListeners = (passThroughStream, increment2) => { +var updateMaxListeners = (passThroughStream, increment3) => { const maxListeners = passThroughStream.getMaxListeners(); if (maxListeners !== 0 && maxListeners !== Number.POSITIVE_INFINITY) { - passThroughStream.setMaxListeners(maxListeners + increment2); + passThroughStream.setMaxListeners(maxListeners + increment3); } }; var PASSTHROUGH_LISTENERS_COUNT = 2; @@ -35694,12 +35694,12 @@ var SignalExit = class extends SignalExitBase { for (const sig of signals) { this.#sigListeners[sig] = () => { const listeners = this.#process.listeners(sig); - let { count: count3 } = this.#emitter; + let { count: count4 } = this.#emitter; const p = process11; if (typeof p.__signal_exit_emitter__ === "object" && typeof p.__signal_exit_emitter__.count === "number") { - count3 += p.__signal_exit_emitter__.count; + count4 += p.__signal_exit_emitter__.count; } - if (listeners.length === count3) { + if (listeners.length === count4) { this.unload(); const ret = this.#emitter.emit("exit", null, sig); const s = sig === "SIGHUP" ? this.#hupSig : sig; @@ -37121,16 +37121,16 @@ var parseCommandString = (command) => { if (trimmedCommand === "") { return []; } - const tokens = []; + const tokens2 = []; for (const token of trimmedCommand.split(SPACES_REGEXP)) { - const previousToken = tokens.at(-1); + const previousToken = tokens2.at(-1); if (previousToken && previousToken.endsWith("\\")) { - tokens[tokens.length - 1] = `${previousToken.slice(0, -1)} ${token}`; + tokens2[tokens2.length - 1] = `${previousToken.slice(0, -1)} ${token}`; } else { - tokens.push(token); + tokens2.push(token); } } - return tokens; + return tokens2; }; var SPACES_REGEXP = / +/g; @@ -41639,7 +41639,7 @@ async function safeHttpRequest(request) { } async function performSafeHttpRequest(request, signal) { const started = Date.now(); - const duration3 = () => Math.max(0, Date.now() - started); + const duration4 = () => Math.max(0, Date.now() - started); const externalAborted = () => request.signal?.aborted === true; const maxRedirects = request.maxRedirects ?? 0; const initialUrl = new URL(request.url); @@ -41666,14 +41666,14 @@ async function performSafeHttpRequest(request, signal) { }); } catch (cause) { if (externalAborted()) { - return { ok: false, kind: "cancelled", detail: "the request was cancelled", durationMs: duration3() }; + return { ok: false, kind: "cancelled", detail: "the request was cancelled", durationMs: duration4() }; } if (cause instanceof Error && (cause.name === "TimeoutError" || cause.name === "AbortError")) { return { ok: false, kind: "timeout", detail: `the request did not complete within ${request.timeoutMs} ms`, - durationMs: duration3() + durationMs: duration4() }; } const message2 = cause instanceof Error ? cause.message : String(cause); @@ -41681,7 +41681,7 @@ async function performSafeHttpRequest(request, signal) { ok: false, kind: "unreachable", detail: `the endpoint could not be reached (${message2.slice(0, 300)})`, - durationMs: duration3() + durationMs: duration4() }; } if (response.status < 300 || response.status >= 400) break; @@ -41691,7 +41691,7 @@ async function performSafeHttpRequest(request, signal) { kind: "redirect-rejected", status: response.status, detail: maxRedirects === 0 ? `the endpoint answered with a redirect (${response.status}); redirects are never followed` : `the endpoint exceeded the bounded redirect limit of ${maxRedirects}`, - durationMs: duration3() + durationMs: duration4() }; } const location = response.headers.get("location"); @@ -41701,7 +41701,7 @@ async function performSafeHttpRequest(request, signal) { kind: "redirect-rejected", status: response.status, detail: `the endpoint answered with a redirect (${response.status}) without a target`, - durationMs: duration3() + durationMs: duration4() }; } const decision = checkRedirectTarget(currentUrl, location); @@ -41711,7 +41711,7 @@ async function performSafeHttpRequest(request, signal) { kind: "redirect-rejected", status: response.status, detail: decision.detail ?? "the redirect was rejected", - durationMs: duration3() + durationMs: duration4() }; } redirectCount += 1; @@ -41728,21 +41728,21 @@ async function performSafeHttpRequest(request, signal) { body = await readBounded(response, request.maxResponseBytes); } catch (cause) { if (externalAborted()) { - return { ok: false, kind: "cancelled", detail: "the request was cancelled", durationMs: duration3() }; + return { ok: false, kind: "cancelled", detail: "the request was cancelled", durationMs: duration4() }; } if (cause instanceof Error && (cause.name === "TimeoutError" || cause.name === "AbortError")) { return { ok: false, kind: "timeout", detail: `the response body did not complete within ${request.timeoutMs} ms`, - durationMs: duration3() + durationMs: duration4() }; } return { ok: false, kind: "unreachable", detail: `the response body could not be read (${cause instanceof Error ? cause.message.slice(0, 300) : "unknown error"})`, - durationMs: duration3() + durationMs: duration4() }; } if (body === "too-large") { @@ -41751,7 +41751,7 @@ async function performSafeHttpRequest(request, signal) { kind: "response-too-large", status: response.status, detail: `the response exceeded the configured limit of ${request.maxResponseBytes} bytes and was aborted`, - durationMs: duration3() + durationMs: duration4() }; } if (!response.ok) { @@ -41760,7 +41760,7 @@ async function performSafeHttpRequest(request, signal) { kind: "http-error", status: response.status, detail: `the endpoint answered HTTP ${response.status}`, - durationMs: duration3(), + durationMs: duration4(), bodyExcerpt: body.text.slice(0, 500) }; } @@ -41772,7 +41772,7 @@ async function performSafeHttpRequest(request, signal) { kind: "invalid-content-type", status: response.status, detail: `expected application/json but the endpoint answered "${contentType.slice(0, 100) || "(none)"}"`, - durationMs: duration3() + durationMs: duration4() }; } } @@ -41785,7 +41785,7 @@ async function performSafeHttpRequest(request, signal) { // archives). UTF-8 decoding is lossy for binary content, so callers that // need exact bytes opt in here. ...request.binaryBody === true ? { bodyBase64: body.buffer.toString("base64") } : {}, - durationMs: duration3(), + durationMs: duration4(), ...redirects !== void 0 ? { redirects } : {} }; } @@ -46049,9 +46049,9 @@ function hashFileIfRegular(absolutePath) { } function parsePorcelainStatus(raw) { const entries = []; - const tokens = raw.split("\0"); - for (let i2 = 0; i2 < tokens.length; i2 += 1) { - const token = tokens[i2]; + const tokens2 = raw.split("\0"); + for (let i2 = 0; i2 < tokens2.length; i2 += 1) { + const token = tokens2[i2]; if (token === void 0 || token.length === 0) continue; const status = token.slice(0, 2); const filePath = token.slice(3); @@ -46523,10 +46523,10 @@ function evaluateEvidence(input) { if (!input.taskStillExists) { violations.push("the selected task no longer exists in tasks.md with its recorded text"); } - const outcomeStatus = statusForFailedOutcome(input.runnerOutcome); - if (outcomeStatus !== void 0) { + const outcomeStatus2 = statusForFailedOutcome(input.runnerOutcome); + if (outcomeStatus2 !== void 0) { reasons.push(`the runner outcome was "${input.runnerOutcome}"`); - return { status: outcomeStatus, violations, warnings, reasons }; + return { status: outcomeStatus2, violations, warnings, reasons }; } const agentChanges = agentChangedFiles(input.comparison).filter( (file) => !input.comparison.ambiguousPaths.includes(file.path) @@ -47728,11 +47728,11 @@ function validateReferencedFiles(workspace, referenced) { } return { accepted, rejected }; } -async function authoringArgvPreview(deps3, plan, prompt, toolPolicy, timeoutMs) { - const profileConfig = deps3.registry.getProfile(plan.profile).config; +async function authoringArgvPreview(deps4, plan, prompt, toolPolicy, timeoutMs) { + const profileConfig = deps4.registry.getProfile(plan.profile).config; const execution = { - workspaceRoot: deps3.workspace.rootDir, - runDir: import_path24.default.join(deps3.workspace.sidecarDir, "runs", ""), + workspaceRoot: deps4.workspace.rootDir, + runDir: import_path24.default.join(deps4.workspace.sidecarDir, "runs", ""), timeoutMs }; if (profileConfig.runner === "claude-code") { @@ -47771,20 +47771,20 @@ function includedDocumentPaths(specName, steering, documents) { ...documents.map((section) => `.kiro/specs/${specName}/${section.stage}.md`) ]; } -async function runAuthoringAttempts(deps3, request, runId, primary, input, timeoutMs, clock) { +async function runAuthoringAttempts(deps4, request, runId, primary, input, timeoutMs, clock) { const operation = request.intent === "refine" ? "stage-refinement" : "stage-generation"; const attempts = []; - const backoff = deps3.backoff ?? ((ms) => (0, import_promises12.setTimeout)(ms)); + const backoff = deps4.backoff ?? ((ms) => (0, import_promises12.setTimeout)(ms)); const candidates = [primary.profile, ...primary.fallbackChain]; let lastFailure; let parentAttemptId; - const initialTree = candidates.length > 1 ? await captureGitSnapshot(deps3.workspace.rootDir) : void 0; + const initialTree = candidates.length > 1 ? await captureGitSnapshot(deps4.workspace.rootDir) : void 0; const treeFingerprint = (snapshot2) => JSON.stringify(snapshot2.entries.map((entry2) => [entry2.path, entry2.contentHash])); for (let index = 0; index < candidates.length; index += 1) { const profileName = candidates[index]; const isFallback = index > 0; if (isFallback && initialTree !== void 0 && initialTree.gitAvailable) { - const treeNow = await captureGitSnapshot(deps3.workspace.rootDir); + const treeNow = await captureGitSnapshot(deps4.workspace.rootDir); if (treeFingerprint(treeNow) !== treeFingerprint(initialTree)) { attempts.push({ profile: profileName, @@ -47792,7 +47792,7 @@ async function runAuthoringAttempts(deps3, request, runId, primary, input, timeo outcome: "not-attempted", reason: "the repository changed since the run started; fallback never runs after repository modification" }); - appendRunEvent(deps3.workspace, runId, { + appendRunEvent(deps4.workspace, runId, { at: clock().toISOString(), type: "fallback-stopped", profile: profileName, @@ -47801,7 +47801,7 @@ async function runAuthoringAttempts(deps3, request, runId, primary, input, timeo break; } } - const selection = isFallback ? selectRunner(deps3.registry, deps3.config, { operation, explicitProfile: profileName }) : { ok: true, plan: primary }; + const selection = isFallback ? selectRunner(deps4.registry, deps4.config, { operation, explicitProfile: profileName }) : { ok: true, plan: primary }; if (!selection.ok) { attempts.push({ profile: profileName, @@ -47809,7 +47809,7 @@ async function runAuthoringAttempts(deps3, request, runId, primary, input, timeo outcome: "not-attempted", reason: selection.failure.error.message }); - appendRunEvent(deps3.workspace, runId, { + appendRunEvent(deps4.workspace, runId, { at: clock().toISOString(), type: "fallback-skipped", profile: profileName, @@ -47818,15 +47818,15 @@ async function runAuthoringAttempts(deps3, request, runId, primary, input, timeo continue; } const plan = selection.plan; - const runner = deps3.registry.get(plan.profile); - const profileConfig = deps3.registry.getProfile(plan.profile).config; + const runner = deps4.registry.get(plan.profile); + const profileConfig = deps4.registry.getProfile(plan.profile).config; const profileTimeout = request.timeoutMs ?? (profileConfig.runner !== "mock" ? profileConfig.timeoutMs : timeoutMs); let transportRetries = 0; let correctionRetries = 0; let correction; for (; ; ) { const attemptKind = correction !== void 0 ? "correction-retry" : transportRetries > 0 ? "transport-retry" : isFallback ? "fallback" : "initial"; - const attempt = createAttempt(deps3.workspace, { + const attempt = createAttempt(deps4.workspace, { runId, profile: plan.profile, runner: plan.runner, @@ -47840,7 +47840,7 @@ async function runAuthoringAttempts(deps3, request, runId, primary, input, timeo capabilitySnapshot: plan.declaredCapabilities, createdAt: clock().toISOString() }); - appendRunEvent(deps3.workspace, runId, { + appendRunEvent(deps4.workspace, runId, { at: clock().toISOString(), type: "attempt-start", attemptId: attempt.attemptId, @@ -47850,16 +47850,16 @@ async function runAuthoringAttempts(deps3, request, runId, primary, input, timeo const result = await runner.generateStage( { ...input, ...correction !== void 0 ? { correction } : {} }, { - workspaceRoot: deps3.workspace.rootDir, - runDir: runDir(deps3.workspace, runId), + workspaceRoot: deps4.workspace.rootDir, + runDir: runDir(deps4.workspace, runId), timeoutMs: profileTimeout, - ...deps3.signal !== void 0 ? { signal: deps3.signal } : {}, + ...deps4.signal !== void 0 ? { signal: deps4.signal } : {}, ...request.model !== void 0 ? { model: request.model } : {}, ...request.maxTurns !== void 0 ? { maxTurns: request.maxTurns } : {}, ...request.maxBudgetUsd !== void 0 ? { maxBudgetUsd: request.maxBudgetUsd } : {} } ); - finalizeAttempt(deps3.workspace, attempt, { + finalizeAttempt(deps4.workspace, attempt, { finishedAt: clock().toISOString(), outcome: result.outcome, durationMs: result.durationMs, @@ -47876,7 +47876,7 @@ async function runAuthoringAttempts(deps3, request, runId, primary, input, timeo }); if (result.invalidStructuredOutput !== void 0) { writeAttemptArtifact( - deps3.workspace, + deps4.workspace, runId, attempt.attemptId, "invalid-candidate.txt", @@ -47920,7 +47920,7 @@ async function runAuthoringAttempts(deps3, request, runId, primary, input, timeo } const decision = fallbackEligible(operation, result.outcome, result.error); if (!decision.eligible) { - appendRunEvent(deps3.workspace, runId, { + appendRunEvent(deps4.workspace, runId, { at: clock().toISOString(), type: "fallback-stopped", profile: plan.profile, @@ -47934,9 +47934,9 @@ async function runAuthoringAttempts(deps3, request, runId, primary, input, timeo const last = lastFailure; return { kind: "failure", result: last.result, plan: last.plan, attempts }; } -async function authorStage(deps3, request) { - const clock = deps3.clock ?? systemClock; - const { workspace, config: config2 } = deps3; +async function authorStage(deps4, request) { + const clock = deps4.clock ?? systemClock; + const { workspace, config: config2 } = deps4; const folder = requireSpec(workspace, request.specName); const spec = analyzeSpec(workspace, folder); const specName = folder.name; @@ -47985,7 +47985,7 @@ async function authorStage(deps3, request) { } } const operation = request.intent === "refine" ? "stage-refinement" : "stage-generation"; - const selection = selectRunner(deps3.registry, config2, { + const selection = selectRunner(deps4.registry, config2, { operation, ...request.runnerName !== void 0 ? { explicitProfile: request.runnerName } : {} }); @@ -47997,8 +47997,8 @@ async function authorStage(deps3, request) { }; } const plan = selection.plan; - const runner = deps3.registry.get(plan.profile); - const profileConfig = deps3.registry.getProfile(plan.profile).config; + const runner = deps4.registry.get(plan.profile); + const profileConfig = deps4.registry.getProfile(plan.profile).config; const steering = steeringSections(workspace); const contextStages = contextStagesFor(gate.shape, request.stage); const documents = specDocumentSections(spec, evaluation, contextStages); @@ -48031,7 +48031,7 @@ async function authorStage(deps3, request) { const timeoutMs = request.timeoutMs ?? (profileConfig.runner !== "mock" ? profileConfig.timeoutMs : 18e5); const targetFile = stageDocumentPath(workspace, specName, request.stage); if (request.dryRun === true) { - const argvPreview = plan.category === "agent-cli" ? await authoringArgvPreview(deps3, plan, prompt, toolPolicy, timeoutMs) : void 0; + const argvPreview = plan.category === "agent-cli" ? await authoringArgvPreview(deps4, plan, prompt, toolPolicy, timeoutMs) : void 0; return { kind: "dry-run", exitCode: EXIT_CODES.ok, @@ -48069,7 +48069,7 @@ async function authorStage(deps3, request) { }; } } - const runId = (deps3.idFactory ?? import_crypto6.randomUUID)(); + const runId = (deps4.idFactory ?? import_crypto6.randomUUID)(); const createdAt = clock().toISOString(); createRun(workspace, { schemaVersion: RUN_RECORD_SCHEMA_VERSION, @@ -48111,7 +48111,7 @@ async function authorStage(deps3, request) { ); appendRunEvent(workspace, runId, { at: createdAt, type: "runner-start", runner: plan.profile }); const loop = await runAuthoringAttempts( - deps3, + deps4, request, runId, plan, @@ -48280,18 +48280,18 @@ function policyRelevantDirtyPaths(before, evaluation) { return true; }).map((entry2) => entry2.path); } -async function preflightTaskRun(deps3, request) { - const { workspace, config: config2 } = deps3; +async function preflightTaskRun(deps4, request) { + const { workspace, config: config2 } = deps4; const allowDirty = request.allowDirty === true; const verificationCommands = config2.verification.commands; const warnings = []; const operation = request.operation ?? "task-execution"; - const runnerSelection = selectRunner(deps3.registry, config2, { + const runnerSelection = selectRunner(deps4.registry, config2, { operation, ...request.runnerName !== void 0 ? { explicitProfile: request.runnerName } : {} }); const runnerName = runnerSelection.ok ? runnerSelection.plan.profile : runnerSelection.failure.profile ?? request.runnerName ?? config2.defaultRunner; - const profileConfig = deps3.registry.has(runnerName) ? deps3.registry.getProfile(runnerName).config : void 0; + const profileConfig = deps4.registry.has(runnerName) ? deps4.registry.getProfile(runnerName).config : void 0; const timeoutMs = request.timeoutMs ?? profileTimeoutMs(profileConfig); const folder = requireSpec(workspace, request.specName); const spec = analyzeSpec(workspace, folder); @@ -48403,7 +48403,7 @@ async function preflightTaskRun(deps3, request) { `${predecessors.length} earlier task(s) are still open (next would be ${predecessors[0]?.id}); running ${task.id} out of order.` ); } - const runner = deps3.registry.get(runnerName); + const runner = deps4.registry.get(runnerName); base.runner = runner; const detection = await runner.detect({ workspaceRoot: workspace.rootDir, @@ -48420,7 +48420,7 @@ async function preflightTaskRun(deps3, request) { }); } const before = await captureGitSnapshot(workspace.rootDir, { - ...deps3.clock !== void 0 ? { clock: deps3.clock } : {} + ...deps4.clock !== void 0 ? { clock: deps4.clock } : {} }); base.before = before; if (!before.gitAvailable) { @@ -48522,12 +48522,12 @@ function completeTaskCheckbox(workspace, specName, expected, clock) { ...newHash !== void 0 ? { newHash } : {} }; } -async function taskArgvPreview(deps3, preflight, prompt, runIdPreview) { +async function taskArgvPreview(deps4, preflight, prompt, runIdPreview) { const profileConfig = preflight.profileConfig; if (profileConfig === void 0) return void 0; const execution = { - workspaceRoot: deps3.workspace.rootDir, - runDir: import_path26.default.join(deps3.workspace.sidecarDir, "runs", runIdPreview), + workspaceRoot: deps4.workspace.rootDir, + runDir: import_path26.default.join(deps4.workspace.sidecarDir, "runs", runIdPreview), timeoutMs: preflight.timeoutMs }; if (profileConfig.runner === "claude-code") { @@ -48587,8 +48587,8 @@ function exitCodeForEvidence(status, outcome) { function boundaryNoteFor(preflight) { return preflight.runner?.executionBoundaryNote?.("implementation") ?? "Repository access is bounded by the configured runner safety boundary. Permission bypasses are never used."; } -function buildPrompt(deps3, preflight, extraObservations = []) { - const { workspace } = deps3; +function buildPrompt(deps4, preflight, extraObservations = []) { + const { workspace } = deps4; const spec = preflight.spec; const state = preflight.state; const evaluation = preflight.evaluation; @@ -48614,9 +48614,9 @@ function buildPrompt(deps3, preflight, extraObservations = []) { }; return buildTaskExecutionPrompt(input); } -async function runApprovedTask(deps3, request) { - const clock = deps3.clock ?? systemClock; - const preflight = await preflightTaskRun(deps3, { +async function runApprovedTask(deps4, request) { + const clock = deps4.clock ?? systemClock; + const preflight = await preflightTaskRun(deps4, { specName: request.specName, selector: { ...request.taskId !== void 0 ? { taskId: request.taskId } : {}, @@ -48642,11 +48642,11 @@ async function runApprovedTask(deps3, request) { }; } const task = preflight.task; - const prompt = buildPrompt(deps3, preflight, request.extraObservations ?? []); + const prompt = buildPrompt(deps4, preflight, request.extraObservations ?? []); const profileConfig = preflight.profileConfig; if (request.dryRun === true) { - const runIdPreview = (deps3.idFactory ?? import_crypto7.randomUUID)(); - const argvPreview = await taskArgvPreview(deps3, preflight, prompt, runIdPreview); + const runIdPreview = (deps4.idFactory ?? import_crypto7.randomUUID)(); + const argvPreview = await taskArgvPreview(deps4, preflight, prompt, runIdPreview); const artifactBase = `.specbridge/runs/${runIdPreview}`; return { kind: "dry-run", @@ -48691,11 +48691,11 @@ async function runApprovedTask(deps3, request) { } }; } - const runId = (deps3.idFactory ?? import_crypto7.randomUUID)(); - const sessionId = (deps3.idFactory ?? import_crypto7.randomUUID)(); - const parent = latestRunForTask(deps3.workspace, preflight.spec.folder.name, task.id); + const runId = (deps4.idFactory ?? import_crypto7.randomUUID)(); + const sessionId = (deps4.idFactory ?? import_crypto7.randomUUID)(); + const parent = latestRunForTask(deps4.workspace, preflight.spec.folder.name, task.id); const createdAt = clock().toISOString(); - createRun(deps3.workspace, { + createRun(deps4.workspace, { schemaVersion: RUN_RECORD_SCHEMA_VERSION, runId, kind: "task-execution", @@ -48709,9 +48709,9 @@ async function runApprovedTask(deps3, request) { promptVersion: PROMPT_CONTRACT_VERSION, warnings: preflight.warnings }); - writeRunArtifact(deps3.workspace, runId, "prompt.md", prompt); + writeRunArtifact(deps4.workspace, runId, "prompt.md", prompt); writeRunArtifact( - deps3.workspace, + deps4.workspace, runId, "runner-request.json", `${JSON.stringify( @@ -48730,12 +48730,12 @@ async function runApprovedTask(deps3, request) { )} ` ); - appendRunEvent(deps3.workspace, runId, { at: createdAt, type: "runner-start", task: task.id }); - deps3.onProgress?.(`Executing task ${task.id} with ${preflight.runnerName}\u2026`); + appendRunEvent(deps4.workspace, runId, { at: createdAt, type: "runner-start", task: task.id }); + deps4.onProgress?.(`Executing task ${task.id} with ${preflight.runnerName}\u2026`); const runner = preflight.runner; if (runner === void 0) throw new Error("preflight.ok implies runner"); const selectionPlan = preflight.selectionPlan; - const attempt = selectionPlan !== void 0 ? createAttempt(deps3.workspace, { + const attempt = selectionPlan !== void 0 ? createAttempt(deps4.workspace, { runId, profile: selectionPlan.profile, runner: selectionPlan.runner, @@ -48758,17 +48758,17 @@ async function runApprovedTask(deps3, request) { sessionId }, { - workspaceRoot: deps3.workspace.rootDir, - runDir: runDir(deps3.workspace, runId), + workspaceRoot: deps4.workspace.rootDir, + runDir: runDir(deps4.workspace, runId), timeoutMs: preflight.timeoutMs, - ...deps3.signal !== void 0 ? { signal: deps3.signal } : {}, + ...deps4.signal !== void 0 ? { signal: deps4.signal } : {}, ...request.model !== void 0 ? { model: request.model } : {}, ...request.maxTurns !== void 0 ? { maxTurns: request.maxTurns } : {}, ...request.maxBudgetUsd !== void 0 ? { maxBudgetUsd: request.maxBudgetUsd } : {} } ); if (attempt !== void 0 && selectionPlan !== void 0) { - finalizeAttempt(deps3.workspace, attempt, { + finalizeAttempt(deps4.workspace, attempt, { finishedAt: clock().toISOString(), outcome: result.outcome, durationMs: result.durationMs, @@ -48784,7 +48784,7 @@ async function runApprovedTask(deps3, request) { ) }); } - const report = await finalizeTaskRun(deps3, { + const report = await finalizeTaskRun(deps4, { runId, ...parent !== void 0 ? { parentRunId: parent.runId } : {}, specName: preflight.spec.folder.name, @@ -48798,9 +48798,9 @@ async function runApprovedTask(deps3, request) { }); return { kind: "executed", exitCode: report.exitCode, report }; } -async function finalizeTaskRun(deps3, context) { - const clock = deps3.clock ?? systemClock; - const { workspace, config: config2 } = deps3; +async function finalizeTaskRun(deps4, context) { + const clock = deps4.clock ?? systemClock; + const { workspace, config: config2 } = deps4; const { runId, task, result } = context; writeRunArtifact(workspace, runId, "raw-stdout.log", result.rawStdout); writeRunArtifact(workspace, runId, "raw-stderr.log", result.rawStderr); @@ -48871,12 +48871,12 @@ async function finalizeTaskRun(deps3, context) { if (context.noVerify) { verification = skippedVerification(config2.verification.commands); } else if (result.outcome === "completed" && agentChanges.length > 0) { - deps3.onProgress?.("Running trusted verification commands\u2026"); + deps4.onProgress?.("Running trusted verification commands\u2026"); verification = await runVerificationCommands( workspace.rootDir, config2.verification.commands, { - ...deps3.signal !== void 0 ? { signal: deps3.signal } : {}, + ...deps4.signal !== void 0 ? { signal: deps4.signal } : {}, onCommandFinished: (commandResult, stdout, stderr) => { writeRunArtifact( workspace, @@ -49085,12 +49085,12 @@ function taskLineIntact(workspace, specName, task) { return false; } } -async function runAllOpenTasks(deps3, request) { +async function runAllOpenTasks(deps4, request) { const attempted = []; - const stopOnUnverified = deps3.config.execution.stopOnUnverifiedTask; + const stopOnUnverified = deps4.config.execution.stopOnUnverifiedTask; for (; ; ) { const allowDirty = request.allowDirty === true || attempted.length > 0; - const outcome = await runApprovedTask(deps3, { ...request, allowDirty, next: true }); + const outcome = await runApprovedTask(deps4, { ...request, allowDirty, next: true }); if (outcome.kind === "nothing-to-do") { return { attempted, exitCode: attempted.length === 0 ? EXIT_CODES.ok : summaryExit(attempted) }; } @@ -49150,9 +49150,9 @@ function diverges(current, recordedAfter) { } return differences; } -async function resumeRun(deps3, request) { - const clock = deps3.clock ?? systemClock; - const { workspace } = deps3; +async function resumeRun(deps4, request) { + const clock = deps4.clock ?? systemClock; + const { workspace } = deps4; const original = readRunRecord(workspace, request.runId); if (original === void 0) { return refuse( @@ -49190,7 +49190,7 @@ async function resumeRun(deps3, request) { [`specbridge spec run ${original.specName} --task ${original.taskId}`] ); } - const preflight = await preflightTaskRun(deps3, { + const preflight = await preflightTaskRun(deps4, { specName: original.specName, selector: { taskId: original.taskId }, runnerName: original.runner, @@ -49306,7 +49306,7 @@ async function resumeRun(deps3, request) { } }; } - const runId = (deps3.idFactory ?? import_crypto8.randomUUID)(); + const runId = (deps4.idFactory ?? import_crypto8.randomUUID)(); const createdAt = clock().toISOString(); createRun(workspace, { schemaVersion: RUN_RECORD_SCHEMA_VERSION, @@ -49329,7 +49329,7 @@ async function resumeRun(deps3, request) { originalRunId: original.runId, sessionId: original.sessionId }); - deps3.onProgress?.(`Resuming task ${task.id} (session ${original.sessionId})\u2026`); + deps4.onProgress?.(`Resuming task ${task.id} (session ${original.sessionId})\u2026`); const result = await runner.resumeTask( { specName: original.specName, @@ -49343,10 +49343,10 @@ async function resumeRun(deps3, request) { workspaceRoot: workspace.rootDir, runDir: runDir(workspace, runId), timeoutMs: preflight.timeoutMs, - ...deps3.signal !== void 0 ? { signal: deps3.signal } : {} + ...deps4.signal !== void 0 ? { signal: deps4.signal } : {} } ); - const report = await finalizeTaskRun(deps3, { + const report = await finalizeTaskRun(deps4, { runId, parentRunId: original.runId, specName: original.specName, @@ -49529,11 +49529,11 @@ var INTERACTIVE_AGENT_INSTRUCTIONS = [ function blocked(code2, message2, remediation = [], details) { return { kind: "blocked", code: code2, message: message2, remediation, ...details !== void 0 ? { details } : {} }; } -function buildInteractiveContext(deps3, specName, task) { - const folder = requireSpec(deps3.workspace, specName); - const spec = analyzeSpec(deps3.workspace, folder); +function buildInteractiveContext(deps4, specName, task) { + const folder = requireSpec(deps4.workspace, specName); + const spec = analyzeSpec(deps4.workspace, folder); const state = spec.state; - const evaluation = state !== void 0 ? evaluateWorkflow(deps3.workspace, state) : void 0; + const evaluation = state !== void 0 ? evaluateWorkflow(deps4.workspace, state) : void 0; const documentStage = state?.specType === "bugfix" ? "bugfix" : "requirements"; const lines = []; lines.push(`# Interactive task context: ${specName} \u2014 task ${task.id}`); @@ -49543,7 +49543,7 @@ function buildInteractiveContext(deps3, specName, task) { lines.push(`Requirement references: ${task.requirementRefs.join(", ")}`); } lines.push(""); - for (const steering of steeringSections(deps3.workspace)) { + for (const steering of steeringSections(deps4.workspace)) { lines.push(`## Steering: ${steering.name}`); lines.push(""); lines.push(steering.body.trimEnd()); @@ -49564,9 +49564,9 @@ function buildInteractiveContext(deps3, specName, task) { return `${lines.join("\n").replace(/\n+$/, "")} `; } -async function beginInteractiveTask(deps3, request) { - const clock = deps3.clock ?? systemClock; - const { workspace, config: config2 } = deps3; +async function beginInteractiveTask(deps4, request) { + const clock = deps4.clock ?? systemClock; + const { workspace, config: config2 } = deps4; const allowDirty = request.allowDirty === true; const runVerificationOnComplete = request.runVerificationOnComplete !== false; const warnings = []; @@ -49619,7 +49619,7 @@ async function beginInteractiveTask(deps3, request) { `${predecessors.length} earlier task(s) are still open (next would be ${predecessors[0]?.id}); running ${task.id} out of order.` ); } - const runId = (deps3.idFactory ?? import_crypto9.randomUUID)(); + const runId = (deps4.idFactory ?? import_crypto9.randomUUID)(); const acquisition = acquireInteractiveLock(workspace, { runId, specName, @@ -49679,7 +49679,7 @@ async function beginInteractiveTask(deps3, request) { resumeSupported: false, warnings, lifecycleStatus: "AWAITING_AGENT_CHANGES", - host: deps3.host ?? "mcp" + host: deps4.host ?? "mcp" }); const fingerprint = taskFingerprint({ id: task.id, @@ -49709,7 +49709,7 @@ async function beginInteractiveTask(deps3, request) { `${JSON.stringify(buildEvidenceSpecContext(workspace, specName, spec.state, task), null, 2)} ` ); - const contextMarkdown = buildInteractiveContext(deps3, specName, task); + const contextMarkdown = buildInteractiveContext(deps4, specName, task); writeRunArtifact(workspace, runId, "context.md", contextMarkdown); appendRunEvent(workspace, runId, { at: createdAt, @@ -49811,9 +49811,9 @@ function readFinalReport(workspace, runId) { const artifact = readRunArtifactJson(workspace, runId, "report.json"); return artifact?.report; } -async function completeInteractiveTask(deps3, request) { - const clock = deps3.clock ?? systemClock; - const { workspace } = deps3; +async function completeInteractiveTask(deps4, request) { + const clock = deps4.clock ?? systemClock; + const { workspace } = deps4; const loaded = loadInteractiveRun(workspace, request.runId); if (!loaded.ok) return loaded.failure; const { record: record5, state } = loaded; @@ -49911,9 +49911,9 @@ async function completeInteractiveTask(deps3, request) { const finalReport = await finalizeTaskRun( { workspace, - config: deps3.config, - ...deps3.clock !== void 0 ? { clock: deps3.clock } : {}, - ...deps3.signal !== void 0 ? { signal: deps3.signal } : {} + config: deps4.config, + ...deps4.clock !== void 0 ? { clock: deps4.clock } : {}, + ...deps4.signal !== void 0 ? { signal: deps4.signal } : {} }, { runId: request.runId, @@ -49943,9 +49943,9 @@ async function completeInteractiveTask(deps3, request) { finalizedNow: true }; } -async function abortInteractiveTask(deps3, request) { - const clock = deps3.clock ?? systemClock; - const { workspace } = deps3; +async function abortInteractiveTask(deps4, request) { + const clock = deps4.clock ?? systemClock; + const { workspace } = deps4; const reason3 = request.reason.trim(); if (reason3.length === 0) { return blocked("run-state-invalid", "task_abort requires a non-empty reason.", []); @@ -50203,7 +50203,7 @@ var resumeConformanceGroup = { check2("resume", "resume.refusals", "unsafe resumes are refused", "skipped", fixture.error) ]; } - const deps3 = { workspace: fixture.workspace, config: fixture.config, registry: fixture.registry }; + const deps4 = { workspace: fixture.workspace, config: fixture.config, registry: fixture.registry }; createRun(fixture.workspace, { schemaVersion: RUN_RECORD_SCHEMA_VERSION, runId: "conf-resume-verified", @@ -50218,7 +50218,7 @@ var resumeConformanceGroup = { outcome: "completed", warnings: [] }); - const verifiedResume = await resumeRun(deps3, { runId: "conf-resume-verified" }); + const verifiedResume = await resumeRun(deps4, { runId: "conf-resume-verified" }); results.push( check2( "resume", @@ -50241,7 +50241,7 @@ var resumeConformanceGroup = { outcome: "failed", warnings: [] }); - const sessionlessResume = await resumeRun(deps3, { runId: "conf-resume-no-session" }); + const sessionlessResume = await resumeRun(deps4, { runId: "conf-resume-no-session" }); results.push( check2( "resume", @@ -50285,7 +50285,7 @@ var resumeConformanceGroup = { "git-after.json", fakeSnapshot([{ path: "src/from-previous-session.txt", status: " M", contentHash: "deadbeef" }]) ); - const divergedResume = await resumeRun(deps3, { runId: "conf-resume-diverged" }); + const divergedResume = await resumeRun(deps4, { runId: "conf-resume-diverged" }); results.push( check2( "resume", @@ -50649,11 +50649,11 @@ function computeContextUsage(config2, estimatedTokens) { }; } function assessContextHealth(config2, estimatedTokens) { - const ratio3 = estimatedTokens / usableInputTokens(config2); - if (ratio3 >= config2.hardStopThreshold) return "OVERFLOW"; - if (ratio3 >= config2.emergencyCompactionThreshold) return "FORCE_COMPACT"; - if (ratio3 >= config2.proactiveCompactionThreshold) return "PROACTIVE_COMPACT"; - if (ratio3 >= config2.prepareThreshold) return "PREPARE"; + const ratio4 = estimatedTokens / usableInputTokens(config2); + if (ratio4 >= config2.hardStopThreshold) return "OVERFLOW"; + if (ratio4 >= config2.emergencyCompactionThreshold) return "FORCE_COMPACT"; + if (ratio4 >= config2.proactiveCompactionThreshold) return "PROACTIVE_COMPACT"; + if (ratio4 >= config2.prepareThreshold) return "PREPARE"; return "HEALTHY"; } var ContextBudgetError = class extends Error { @@ -51890,17 +51890,17 @@ function extractSymbolReferences(text15) { } function extractTokens(text15) { const bounded22 = text15.slice(0, RETRIEVAL_QUERY_LIMITS.maxScannedTextChars); - const tokens = /* @__PURE__ */ new Set(); + const tokens2 = /* @__PURE__ */ new Set(); for (const raw of bounded22.split(/[^A-Za-z0-9]+/)) { if (raw.length < 3 || raw.length > 40) continue; for (const part of raw.split(/(?<=[a-z0-9])(?=[A-Z])/)) { const token = part.toLowerCase(); if (token.length < 3 || STOP_TOKENS.has(token)) continue; - tokens.add(token); - if (tokens.size >= RETRIEVAL_QUERY_LIMITS.maxTokens) return [...tokens]; + tokens2.add(token); + if (tokens2.size >= RETRIEVAL_QUERY_LIMITS.maxTokens) return [...tokens2]; } } - return [...tokens]; + return [...tokens2]; } function bounded(values) { return [...new Set((values ?? []).map(normalizePath).filter((value) => value !== ""))].slice( @@ -51923,7 +51923,7 @@ function buildRetrievalQuery(input) { ...extractSymbolReferences(actionText) ]) ].slice(0, RETRIEVAL_QUERY_LIMITS.maxSymbols); - const tokens = [ + const tokens2 = [ .../* @__PURE__ */ new Set([ ...extractTokens(objective), ...extractTokens(actionText), @@ -51954,7 +51954,7 @@ function buildRetrievalQuery(input) { checkpointChangedPaths: bounded(input.checkpointChangedPaths), priorRelevantPaths: bounded(input.priorRelevantPaths), symbols, - tokens, + tokens: tokens2, failureFingerprint: input.failureFingerprint, expansionLevel: input.expansionLevel ?? "TOP_WORKING_SET" }; @@ -53278,8 +53278,8 @@ function selectWorkingSet(input) { lines: lineHints.get(candidate.path) ?? [], options: input.sectionOptions }); - const tokens = estimateTokens(section.content) + estimateTokens(candidate.path) + 8; - if (!candidate.mandatory && tokens > input.allocation.maxSingleItemTokens) { + const tokens2 = estimateTokens(section.content) + estimateTokens(candidate.path) + 8; + if (!candidate.mandatory && tokens2 > input.allocation.maxSingleItemTokens) { if (pointers.length < maxPointers) { pointers.push({ path: candidate.path, @@ -53294,11 +53294,11 @@ function selectWorkingSet(input) { path: candidate.path, reason: "TOO_LARGE", score: candidate.score, - detail: truncate(`${tokens} tokens exceeds the ${input.allocation.maxSingleItemTokens}-token per-item ceiling`) + detail: truncate(`${tokens2} tokens exceeds the ${input.allocation.maxSingleItemTokens}-token per-item ceiling`) }); continue; } - if (!candidate.mandatory && spent + tokens > input.allocation.workingSetBudget) { + if (!candidate.mandatory && spent + tokens2 > input.allocation.workingSetBudget) { if (pointers.length < maxPointers) { pointers.push({ path: candidate.path, @@ -53326,7 +53326,7 @@ function selectWorkingSet(input) { ...section.startLine !== void 0 ? { startLine: section.startLine } : {}, ...section.endLine !== void 0 ? { endLine: section.endLine } : {}, ...section.symbol !== void 0 ? { symbol: truncate(section.symbol) } : {}, - estimatedTokens: tokens, + estimatedTokens: tokens2, ...candidate.signals[0]?.detail !== void 0 ? { detail: truncate(candidate.signals[0].detail) } : {} }); items.push({ @@ -53353,7 +53353,7 @@ function selectWorkingSet(input) { sourceHashes: [] } }); - spent += tokens; + spent += tokens2; } return { selected, pointers, excluded, items, refreshedPaths, workingSetTokens: spent }; } @@ -53599,7 +53599,7 @@ function buildContextMetrics(input) { function census(values) { const counts = /* @__PURE__ */ new Map(); for (const value of values) counts.set(value, (counts.get(value) ?? 0) + 1); - return [...counts.entries()].map(([key, count3]) => ({ key, count: count3 })).sort((left, right) => right.count !== left.count ? right.count - left.count : left.key < right.key ? -1 : 1); + return [...counts.entries()].map(([key, count4]) => ({ key, count: count4 })).sort((left, right) => right.count !== left.count ? right.count - left.count : left.key < right.key ? -1 : 1); } function explainContextSelection(input) { const { plan } = input; @@ -55069,12 +55069,12 @@ function readMissionEvents(workspace, missionId, options = {}) { const window = parsed.slice(Math.max(0, parsed.length - offset - limit), parsed.length - offset); return { events: window, total: parsed.length, truncated: parsed.length > window.length }; } -function now(deps3) { - return (deps3.clock ?? systemClock)(); +function now(deps4) { + return (deps4.clock ?? systemClock)(); } -function record2(deps3, mission, type, payload = {}) { - appendMissionEvent(deps3.workspace, mission.missionId, { - at: now(deps3).toISOString(), +function record2(deps4, mission, type, payload = {}) { + appendMissionEvent(deps4.workspace, mission.missionId, { + at: now(deps4).toISOString(), type, ...payload }); @@ -55083,15 +55083,15 @@ function record2(deps3, mission, type, payload = {}) { counters: { ...mission.counters, events: mission.counters.events + 1 } }; } -function transition(deps3, mission, to) { +function transition(deps4, mission, to) { assertMissionTransition(mission.status, to); - const moved = { ...mission, status: to, updatedAt: now(deps3).toISOString() }; - return record2(deps3, moved, "status_changed", { from: mission.status, to }); + const moved = { ...mission, status: to, updatedAt: now(deps4).toISOString() }; + return record2(deps4, moved, "status_changed", { from: mission.status, to }); } -function persist(deps3, mission) { - return writeMissionState(deps3.workspace, { +function persist(deps4, mission) { + return writeMissionState(deps4.workspace, { ...mission, - updatedAt: now(deps3).toISOString() + updatedAt: now(deps4).toISOString() }); } function assertNotFinal(mission) { @@ -55118,7 +55118,7 @@ function assertDiscoveryOpen(mission, what) { function pad(value, width) { return String(value).padStart(width, "0"); } -function beginMission(deps3, request) { +function beginMission(deps4, request) { const name = request.name.trim(); const goal = request.goal.trim(); if (name.length === 0 || goal.length === 0) { @@ -55126,32 +55126,32 @@ function beginMission(deps3, request) { remediation: ["Describe the product direction in one or two sentences."] }); } - const createdAt = now(deps3).toISOString(); + const createdAt = now(deps4).toISOString(); const mission = missionStateSchema.parse({ schemaVersion: MISSION_STATE_SCHEMA_VERSION, - missionId: `m-${(deps3.idFactory ?? import_crypto15.randomUUID)()}`, + missionId: `m-${(deps4.idFactory ?? import_crypto15.randomUUID)()}`, name: name.slice(0, MISSION_LIMITS.maxNameChars), status: "IDEA", goal: goal.slice(0, MISSION_LIMITS.maxTextChars), createdAt, updatedAt: createdAt, - host: deps3.host ?? "cli" + host: deps4.host ?? "cli" }); - initializeMissionRecord(deps3.workspace, mission); - writeConstitution(deps3.workspace, mission.missionId, { + initializeMissionRecord(deps4.workspace, mission); + writeConstitution(deps4.workspace, mission.missionId, { schemaVersion: MISSION_CONSTITUTION_SCHEMA_VERSION, missionId: mission.missionId, version: 0, updatedAt: createdAt, rules: [] }); - const recorded = record2(deps3, mission, "mission_created", { name: mission.name }); - const persisted = persist(deps3, recorded); - refreshCoverage(deps3, persisted); + const recorded = record2(deps4, mission, "mission_created", { name: mission.name }); + const persisted = persist(deps4, recorded); + refreshCoverage(deps4, persisted); return persisted; } -function recordTurn(deps3, missionId, request) { - let mission = requireMissionState(deps3.workspace, missionId); +function recordTurn(deps4, missionId, request) { + let mission = requireMissionState(deps4.workspace, missionId); assertNotFinal(mission); if (mission.counters.turns >= MISSION_LIMITS.maxTurns) { throw new MissionError("SBM006", `The mission reached its ${MISSION_LIMITS.maxTurns}-turn bound.`); @@ -55160,34 +55160,34 @@ function recordTurn(deps3, missionId, request) { if (text24.length === 0) { throw new MissionError("SBM005", "A turn needs visible text."); } - if (request.inReplyTo !== void 0 && findTurn(deps3.workspace, missionId, request.inReplyTo) === void 0) { + if (request.inReplyTo !== void 0 && findTurn(deps4.workspace, missionId, request.inReplyTo) === void 0) { throw new MissionError("SBM005", `Turn "${request.inReplyTo}" does not exist; inReplyTo must reference a recorded turn.`); } const sequence = mission.sequences.turn + 1; const turn = { turnId: `t-${sequence}`, - at: now(deps3).toISOString(), + at: now(deps4).toISOString(), speaker: request.speaker, kind: request.kind, text: text24.slice(0, MISSION_LIMITS.maxTurnTextChars), refs: (request.refs ?? []).slice(0, MISSION_LIMITS.maxRefsPerRecord), ...request.inReplyTo !== void 0 ? { inReplyTo: request.inReplyTo } : {} }; - appendTurn(deps3.workspace, missionId, turn); + appendTurn(deps4.workspace, missionId, turn); mission = { ...mission, sequences: { ...mission.sequences, turn: sequence }, counters: { ...mission.counters, turns: mission.counters.turns + 1 } }; - mission = record2(deps3, mission, "turn_recorded", { + mission = record2(deps4, mission, "turn_recorded", { turnId: turn.turnId, speaker: turn.speaker, kind: turn.kind }); if (mission.status === "IDEA") { - mission = transition(deps3, mission, "DISCOVERING"); + mission = transition(deps4, mission, "DISCOVERING"); } - return { mission: persist(deps3, mission), turn }; + return { mission: persist(deps4, mission), turn }; } function validateSafeRegex(patterns, what) { const validated = []; @@ -55201,14 +55201,14 @@ function validateSafeRegex(patterns, what) { } return validated; } -function requireUserTurn(deps3, missionId, turnId, what) { +function requireUserTurn(deps4, missionId, turnId, what) { if (turnId === void 0) { throw new MissionError( "SBM007", `${what} claims user provenance but references no conversation turn. A user-provenance decision must point at the visible turn that confirms it.` ); } - const turn = findTurn(deps3.workspace, missionId, turnId); + const turn = findTurn(deps4.workspace, missionId, turnId); if (turn === void 0) { throw new MissionError("SBM007", `${what} references turn "${turnId}", which does not exist.`); } @@ -55232,10 +55232,10 @@ function requireDecisions(activeDecisions, decisionIds, what) { } } } -function recordAssessment(deps3, missionId, input) { - let mission = requireMissionState(deps3.workspace, missionId); +function recordAssessment(deps4, missionId, input) { + let mission = requireMissionState(deps4.workspace, missionId); assertDiscoveryOpen(mission, "a discovery assessment"); - const at = now(deps3).toISOString(); + const at = now(deps4).toISOString(); const factIds = []; const questionIds = []; const decisionIds = []; @@ -55247,18 +55247,18 @@ function recordAssessment(deps3, missionId, input) { if (mission.counters.facts >= MISSION_LIMITS.maxFacts) { throw new MissionError("SBM006", `The mission reached its ${MISSION_LIMITS.maxFacts}-fact bound.`); } - if (fact.sourceTurnId !== void 0 && findTurn(deps3.workspace, missionId, fact.sourceTurnId) === void 0) { + if (fact.sourceTurnId !== void 0 && findTurn(deps4.workspace, missionId, fact.sourceTurnId) === void 0) { throw new MissionError("SBM005", `Fact references turn "${fact.sourceTurnId}", which does not exist.`); } if (fact.supersedesFactId !== void 0) { - const existing = readFacts(deps3.workspace, missionId).find( + const existing = readFacts(deps4.workspace, missionId).find( (candidate) => candidate.factId === fact.supersedesFactId ); if (existing === void 0) { throw new MissionError("SBM009", `Fact "${fact.supersedesFactId}" cannot be superseded: it does not exist.`); } - appendFact(deps3.workspace, missionId, { ...existing, status: "superseded" }); - mission = record2(deps3, mission, "fact_superseded", { factId: existing.factId }); + appendFact(deps4.workspace, missionId, { ...existing, status: "superseded" }); + mission = record2(deps4, mission, "fact_superseded", { factId: existing.factId }); } const sequence = mission.sequences.fact + 1; const recordFact = { @@ -55271,14 +55271,14 @@ function recordAssessment(deps3, missionId, input) { ...fact.supersedesFactId !== void 0 ? { supersedes: fact.supersedesFactId } : {}, recordedAt: at }; - appendFact(deps3.workspace, missionId, recordFact); + appendFact(deps4.workspace, missionId, recordFact); factIds.push(recordFact.factId); mission = { ...mission, sequences: { ...mission.sequences, fact: sequence }, counters: { ...mission.counters, facts: mission.counters.facts + 1 } }; - mission = record2(deps3, mission, "fact_recorded", { + mission = record2(deps4, mission, "fact_recorded", { factId: recordFact.factId, provenance: recordFact.provenance }); @@ -55308,7 +55308,7 @@ function recordAssessment(deps3, missionId, input) { ...question.sourceTurnId !== void 0 ? { sourceTurnId: question.sourceTurnId } : {}, askedAt: at }; - appendQuestion(deps3.workspace, missionId, recordQuestion); + appendQuestion(deps4.workspace, missionId, recordQuestion); questionIds.push(recordQuestion.questionId); if (assessment.raisedFrom !== void 0) { materialityRaised.push({ @@ -55326,19 +55326,19 @@ function recordAssessment(deps3, missionId, input) { openQuestions: mission.counters.openQuestions + 1 } }; - mission = record2(deps3, mission, "question_opened", { + mission = record2(deps4, mission, "question_opened", { questionId: recordQuestion.questionId, materiality: recordQuestion.materiality }); } for (const decision of input.decisions ?? []) { - mission = recordDecisionInternal(deps3, missionId, mission, decision, at, decisionIds); + mission = recordDecisionInternal(deps4, missionId, mission, decision, at, decisionIds); } if ((input.constitutionRules ?? []).length > 0) { - const activeDecisions = readDecisions(deps3.workspace, missionId).filter( + const activeDecisions = readDecisions(deps4.workspace, missionId).filter( (decision) => decision.status === "active" ); - let constitution = readConstitution(deps3.workspace, missionId) ?? { + let constitution = readConstitution(deps4.workspace, missionId) ?? { schemaVersion: MISSION_CONSTITUTION_SCHEMA_VERSION, missionId, version: 0, @@ -55363,7 +55363,7 @@ function recordAssessment(deps3, missionId, input) { rules = rules.map( (candidate) => candidate.ruleId === rule.supersedesRuleId ? { ...candidate, status: "superseded" } : candidate ); - mission = record2(deps3, mission, "constitution_rule_superseded", { ruleId: rule.supersedesRuleId }); + mission = record2(deps4, mission, "constitution_rule_superseded", { ruleId: rule.supersedesRuleId }); } const sequence = mission.sequences.constitutionRule + 1; const ruleId = `CON-${pad(sequence, 3)}`; @@ -55395,12 +55395,12 @@ function recordAssessment(deps3, missionId, input) { sequences: { ...mission.sequences, constitutionRule: sequence }, counters: { ...mission.counters, constitutionRules: mission.counters.constitutionRules + 1 } }; - mission = record2(deps3, mission, "constitution_rule_recorded", { ruleId }); + mission = record2(deps4, mission, "constitution_rule_recorded", { ruleId }); } - writeConstitution(deps3.workspace, missionId, constitution); + writeConstitution(deps4.workspace, missionId, constitution); } if ((input.adrs ?? []).length > 0) { - const activeDecisions = readDecisions(deps3.workspace, missionId).filter( + const activeDecisions = readDecisions(deps4.workspace, missionId).filter( (decision) => decision.status === "active" ); for (const adr of input.adrs ?? []) { @@ -55435,18 +55435,18 @@ function recordAssessment(deps3, missionId, input) { ...adr.supersedesAdrId !== void 0 ? { supersedes: adr.supersedesAdrId } : {}, recordedAt: at }); - storeAdr(deps3.workspace, missionId, document); + storeAdr(deps4.workspace, missionId, document); adrIds.push(adrId); mission = { ...mission, sequences: { ...mission.sequences, adr: sequence }, counters: { ...mission.counters, adrs: mission.counters.adrs + 1 } }; - mission = record2(deps3, mission, "adr_recorded", { adrId }); + mission = record2(deps4, mission, "adr_recorded", { adrId }); } } if ((input.contracts ?? []).length > 0) { - const activeDecisions = readDecisions(deps3.workspace, missionId).filter( + const activeDecisions = readDecisions(deps4.workspace, missionId).filter( (decision) => decision.status === "active" ); for (const contract of input.contracts ?? []) { @@ -55484,14 +55484,14 @@ function recordAssessment(deps3, missionId, input) { turnIds: (contract.turnIds ?? []).slice(0, MISSION_LIMITS.maxRefsPerRecord), recordedAt: at }); - storeContractRevision(deps3.workspace, missionId, document); + storeContractRevision(deps4.workspace, missionId, document); contractIds.push(contractId); mission = { ...mission, sequences: { ...mission.sequences, contract: sequence }, counters: { ...mission.counters, contracts: mission.counters.contracts + 1 } }; - mission = record2(deps3, mission, "contract_recorded", { contractId, revision: 1 }); + mission = record2(deps4, mission, "contract_recorded", { contractId, revision: 1 }); } } const updates = input.missionUpdates; @@ -55514,12 +55514,12 @@ function recordAssessment(deps3, missionId, input) { }; } if (mission.status === "IDEA") { - mission = transition(deps3, mission, "DISCOVERING"); + mission = transition(deps4, mission, "DISCOVERING"); } - const coverage = refreshCoverage(deps3, mission); - mission = reconcileStatusWithCoverage(deps3, mission, coverage); + const coverage = refreshCoverage(deps4, mission); + mission = reconcileStatusWithCoverage(deps4, mission, coverage); return { - mission: persist(deps3, mission), + mission: persist(deps4, mission), coverage, factIds, questionIds, @@ -55530,7 +55530,7 @@ function recordAssessment(deps3, missionId, input) { materialityRaised }; } -function recordDecisionInternal(deps3, missionId, mission, input, at, outIds) { +function recordDecisionInternal(deps4, missionId, mission, input, at, outIds) { if (mission.counters.decisions >= MISSION_LIMITS.maxDecisions) { throw new MissionError("SBM006", `The mission reached its ${MISSION_LIMITS.maxDecisions}-decision bound.`); } @@ -55542,11 +55542,11 @@ function recordDecisionInternal(deps3, missionId, mission, input, at, outIds) { ); } if (input.provenance === "known-from-user") { - requireUserTurn(deps3, missionId, input.sourceTurnId, "A decision"); - } else if (input.sourceTurnId !== void 0 && findTurn(deps3.workspace, missionId, input.sourceTurnId) === void 0) { + requireUserTurn(deps4, missionId, input.sourceTurnId, "A decision"); + } else if (input.sourceTurnId !== void 0 && findTurn(deps4.workspace, missionId, input.sourceTurnId) === void 0) { throw new MissionError("SBM005", `Decision references turn "${input.sourceTurnId}", which does not exist.`); } - const questions = readQuestions(deps3.workspace, missionId); + const questions = readQuestions(deps4.workspace, missionId); let answeredQuestion; if (input.questionId !== void 0) { answeredQuestion = questions.find((question) => question.questionId === input.questionId); @@ -55555,14 +55555,14 @@ function recordDecisionInternal(deps3, missionId, mission, input, at, outIds) { } } if (input.supersedesDecisionId !== void 0) { - const previous = readDecisions(deps3.workspace, missionId).find( + const previous = readDecisions(deps4.workspace, missionId).find( (candidate) => candidate.decisionId === input.supersedesDecisionId ); if (previous === void 0) { throw new MissionError("SBM009", `Decision "${input.supersedesDecisionId}" cannot be superseded: it does not exist.`); } - appendDecision(deps3.workspace, missionId, { ...previous, status: "superseded" }); - mission = record2(deps3, mission, "decision_superseded", { decisionId: previous.decisionId }); + appendDecision(deps4.workspace, missionId, { ...previous, status: "superseded" }); + mission = record2(deps4, mission, "decision_superseded", { decisionId: previous.decisionId }); } const sequence = mission.sequences.decision + 1; const decision = { @@ -55581,20 +55581,20 @@ function recordDecisionInternal(deps3, missionId, mission, input, at, outIds) { resultingArtifactIds: [], decidedAt: at }; - appendDecision(deps3.workspace, missionId, decision); + appendDecision(deps4.workspace, missionId, decision); outIds.push(decision.decisionId); mission = { ...mission, sequences: { ...mission.sequences, decision: sequence }, counters: { ...mission.counters, decisions: mission.counters.decisions + 1 } }; - mission = record2(deps3, mission, "decision_recorded", { + mission = record2(deps4, mission, "decision_recorded", { decisionId: decision.decisionId, provenance: decision.provenance, ...decision.questionId !== void 0 ? { questionId: decision.questionId } : {} }); if (answeredQuestion !== void 0 && answeredQuestion.status === "open") { - appendQuestion(deps3.workspace, missionId, { + appendQuestion(deps4.workspace, missionId, { ...answeredQuestion, status: "answered", resolvedByDecisionId: decision.decisionId @@ -55603,17 +55603,17 @@ function recordDecisionInternal(deps3, missionId, mission, input, at, outIds) { ...mission, counters: { ...mission.counters, openQuestions: Math.max(0, mission.counters.openQuestions - 1) } }; - mission = record2(deps3, mission, "question_answered", { + mission = record2(deps4, mission, "question_answered", { questionId: answeredQuestion.questionId, decisionId: decision.decisionId }); } return mission; } -function answerQuestion(deps3, missionId, request) { - const mission = requireMissionState(deps3.workspace, missionId); +function answerQuestion(deps4, missionId, request) { + const mission = requireMissionState(deps4.workspace, missionId); assertDiscoveryOpen(mission, "an answer"); - const question = readQuestions(deps3.workspace, missionId).find( + const question = readQuestions(deps4.workspace, missionId).find( (candidate) => candidate.questionId === request.questionId ); if (question === void 0) { @@ -55626,13 +55626,13 @@ function answerQuestion(deps3, missionId, request) { if (answer.length === 0) { throw new MissionError("SBM005", "An answer needs text."); } - const { turn } = recordTurn(deps3, missionId, { + const { turn } = recordTurn(deps4, missionId, { speaker: "user", kind: "statement", text: answer, refs: [question.questionId] }); - const assessment = recordAssessment(deps3, missionId, { + const assessment = recordAssessment(deps4, missionId, { decisions: [ { decision: answer, @@ -55645,7 +55645,7 @@ function answerQuestion(deps3, missionId, request) { ] }); const decisionId = assessment.decisionIds[0]; - const decision = readDecisions(deps3.workspace, missionId).find( + const decision = readDecisions(deps4.workspace, missionId).find( (candidate) => candidate.decisionId === decisionId ); if (decision === void 0) { @@ -55653,34 +55653,34 @@ function answerQuestion(deps3, missionId, request) { } return { mission: assessment.mission, decision, coverage: assessment.coverage }; } -function refreshCoverage(deps3, mission) { +function refreshCoverage(deps4, mission) { const coverage = computeCoverage({ missionId: mission.missionId, - facts: readFacts(deps3.workspace, mission.missionId), - questions: readQuestions(deps3.workspace, mission.missionId), - decisions: readDecisions(deps3.workspace, mission.missionId), - now: now(deps3) + facts: readFacts(deps4.workspace, mission.missionId), + questions: readQuestions(deps4.workspace, mission.missionId), + decisions: readDecisions(deps4.workspace, mission.missionId), + now: now(deps4) }); - writeCoverage(deps3.workspace, mission.missionId, coverage); + writeCoverage(deps4.workspace, mission.missionId, coverage); return coverage; } -function reconcileStatusWithCoverage(deps3, mission, coverage) { +function reconcileStatusWithCoverage(deps4, mission, coverage) { const blocking = coverage.blockingQuestionIds.length > 0; if (mission.status === "DISCOVERING" && blocking) { - return transition(deps3, mission, "NEEDS_DECISION"); + return transition(deps4, mission, "NEEDS_DECISION"); } if (mission.status === "NEEDS_DECISION" && !blocking) { - return transition(deps3, mission, "DISCOVERING"); + return transition(deps4, mission, "DISCOVERING"); } if (mission.status === "CONTRACT_READY" && !coverage.contractReady) { - return transition(deps3, mission, blocking ? "NEEDS_DECISION" : "DISCOVERING"); + return transition(deps4, mission, blocking ? "NEEDS_DECISION" : "DISCOVERING"); } return mission; } -function markContractReady(deps3, missionId) { - let mission = requireMissionState(deps3.workspace, missionId); +function markContractReady(deps4, missionId) { + let mission = requireMissionState(deps4.workspace, missionId); assertNotFinal(mission); - const coverage = refreshCoverage(deps3, mission); + const coverage = refreshCoverage(deps4, mission); if (!coverage.contractReady) { throw new MissionError( "SBM008", @@ -55698,36 +55698,36 @@ function markContractReady(deps3, missionId) { ); } if (mission.status !== "CONTRACT_READY") { - mission = transition(deps3, mission, "CONTRACT_READY"); - mission = persist(deps3, mission); + mission = transition(deps4, mission, "CONTRACT_READY"); + mission = persist(deps4, mission); } return { mission, coverage }; } -function reopenDiscovery(deps3, missionId, reason3) { - let mission = requireMissionState(deps3.workspace, missionId); +function reopenDiscovery(deps4, missionId, reason3) { + let mission = requireMissionState(deps4.workspace, missionId); assertNotFinal(mission); if (DISCOVERY_STATUSES.includes(mission.status) && mission.status !== "CONTRACT_READY") { return mission; } - mission = transition(deps3, mission, "DISCOVERING"); - mission = record2(deps3, mission, "status_changed", { reason: reason3.slice(0, 500), reopened: true }); - return persist(deps3, mission); + mission = transition(deps4, mission, "DISCOVERING"); + mission = record2(deps4, mission, "status_changed", { reason: reason3.slice(0, 500), reopened: true }); + return persist(deps4, mission); } -function abandonMission(deps3, missionId, reason3) { - let mission = requireMissionState(deps3.workspace, missionId); +function abandonMission(deps4, missionId, reason3) { + let mission = requireMissionState(deps4.workspace, missionId); if (isFinalMissionStatus(mission.status)) return mission; - const at = now(deps3).toISOString(); - mission = transition(deps3, mission, "ABANDONED"); - mission = record2(deps3, mission, "mission_abandoned", { reason: reason3.slice(0, 500) }); - return persist(deps3, { ...mission, abandonedAt: at, abandonReason: reason3.slice(0, MISSION_LIMITS.maxTextChars) }); + const at = now(deps4).toISOString(); + mission = transition(deps4, mission, "ABANDONED"); + mission = record2(deps4, mission, "mission_abandoned", { reason: reason3.slice(0, 500) }); + return persist(deps4, { ...mission, abandonedAt: at, abandonReason: reason3.slice(0, MISSION_LIMITS.maxTextChars) }); } -function createContractChangeRequest(deps3, missionId, request) { - let mission = requireMissionState(deps3.workspace, missionId); +function createContractChangeRequest(deps4, missionId, request) { + let mission = requireMissionState(deps4.workspace, missionId); assertNotFinal(mission); if (mission.counters.ccrs >= MISSION_LIMITS.maxCcrs) { throw new MissionError("SBM006", `The mission reached its ${MISSION_LIMITS.maxCcrs}-change-request bound.`); } - const contract = readContract(deps3.workspace, missionId, request.contractId); + const contract = readContract(deps4.workspace, missionId, request.contractId); if (contract === void 0) { throw new MissionError("SBM009", `Contract "${request.contractId}" does not exist in this mission's registry.`); } @@ -55737,7 +55737,7 @@ function createContractChangeRequest(deps3, missionId, request) { }); const material = contract.classification === "public" || contract.compatibilityPolicy === "frozen" || contract.compatibilityPolicy === "additive-only" || screen.level === "blocking"; const sequence = mission.sequences.ccr + 1; - const at = now(deps3).toISOString(); + const at = now(deps4).toISOString(); const ccr = contractChangeRequestSchema.parse({ schemaVersion: MISSION_CCR_SCHEMA_VERSION, ccrId: `CCR-${pad(sequence, 3)}`, @@ -55752,31 +55752,31 @@ function createContractChangeRequest(deps3, missionId, request) { ...request.originJobId !== void 0 ? { originJobId: request.originJobId } : {}, createdAt: at }); - writeCcr(deps3.workspace, missionId, ccr); + writeCcr(deps4.workspace, missionId, ccr); mission = { ...mission, sequences: { ...mission.sequences, ccr: sequence }, counters: { ...mission.counters, ccrs: mission.counters.ccrs + 1 } }; - mission = record2(deps3, mission, "ccr_created", { + mission = record2(deps4, mission, "ccr_created", { ccrId: ccr.ccrId, contractId: ccr.contractId, status: ccr.status, raisedBy: ccr.raisedBy }); - return { mission: persist(deps3, mission), ccr, material }; + return { mission: persist(deps4, mission), ccr, material }; } -function decideContractChangeRequest(deps3, missionId, request) { - let mission = requireMissionState(deps3.workspace, missionId); +function decideContractChangeRequest(deps4, missionId, request) { + let mission = requireMissionState(deps4.workspace, missionId); assertNotFinal(mission); - const existing = readCcr(deps3.workspace, missionId, request.ccrId); + const existing = readCcr(deps4.workspace, missionId, request.ccrId); if (existing === void 0) { throw new MissionError("SBM009", `Change request "${request.ccrId}" does not exist.`); } if (existing.status !== "PROPOSED" && existing.status !== "NEEDS_HUMAN") { throw new MissionError("SBM013", `Change request ${existing.ccrId} is already ${existing.status}.`); } - const at = now(deps3).toISOString(); + const at = now(deps4).toISOString(); if (request.decision === "rejected") { const rejected = { ...existing, @@ -55784,17 +55784,17 @@ function decideContractChangeRequest(deps3, missionId, request) { decidedAt: at, ...request.note !== void 0 ? { decisionNote: request.note.slice(0, MISSION_LIMITS.maxTextChars) } : {} }; - writeCcr(deps3.workspace, missionId, rejected); - mission = record2(deps3, mission, "ccr_decided", { ccrId: existing.ccrId, decision: "rejected" }); - return { mission: persist(deps3, mission), ccr: rejected }; + writeCcr(deps4.workspace, missionId, rejected); + mission = record2(deps4, mission, "ccr_decided", { ccrId: existing.ccrId, decision: "rejected" }); + return { mission: persist(deps4, mission), ccr: rejected }; } - const current = readContract(deps3.workspace, missionId, existing.contractId); + const current = readContract(deps4.workspace, missionId, existing.contractId); if (current === void 0) { throw new MissionError("SBM009", `Contract "${existing.contractId}" vanished from the registry.`); } const decisionIds = []; mission = recordDecisionInternal( - deps3, + deps4, missionId, mission, { @@ -55843,7 +55843,7 @@ function decideContractChangeRequest(deps3, missionId, request) { status: "active" }); } - storeContractRevision(deps3.workspace, missionId, nextRevision); + storeContractRevision(deps4.workspace, missionId, nextRevision); const approved = { ...existing, status: "APPROVED", @@ -55851,27 +55851,27 @@ function decideContractChangeRequest(deps3, missionId, request) { ...request.note !== void 0 ? { decisionNote: request.note.slice(0, MISSION_LIMITS.maxTextChars) } : {}, resultingRevision: nextRevisionNumber }; - writeCcr(deps3.workspace, missionId, approved); - mission = record2(deps3, mission, "ccr_decided", { ccrId: existing.ccrId, decision: "approved" }); - mission = record2(deps3, mission, "contract_revised", { + writeCcr(deps4.workspace, missionId, approved); + mission = record2(deps4, mission, "ccr_decided", { ccrId: existing.ccrId, decision: "approved" }); + mission = record2(deps4, mission, "contract_revised", { contractId: current.contractId, revision: nextRevisionNumber, ccrId: existing.ccrId }); - mission = record2(deps3, mission, "ccr_applied", { + mission = record2(deps4, mission, "ccr_applied", { ccrId: existing.ccrId, contractId: current.contractId, revision: nextRevisionNumber }); - return { mission: persist(deps3, mission), ccr: approved, contract: nextRevision }; + return { mission: persist(deps4, mission), ccr: approved, contract: nextRevision }; } -function describeMission(deps3, missionId) { - const mission = requireMissionState(deps3.workspace, missionId); - const coverage = refreshCoverage(deps3, mission); - const questions = readQuestions(deps3.workspace, missionId); +function describeMission(deps4, missionId) { + const mission = requireMissionState(deps4.workspace, missionId); + const coverage = refreshCoverage(deps4, mission); + const questions = readQuestions(deps4.workspace, missionId); const openQuestions = questions.filter((question) => question.status === "open"); - const constitution = readConstitution(deps3.workspace, missionId); - const openCcrs = readCcrs(deps3.workspace, missionId).filter( + const constitution = readConstitution(deps4.workspace, missionId); + const openCcrs = readCcrs(deps4.workspace, missionId).filter( (ccr) => ccr.status === "PROPOSED" || ccr.status === "NEEDS_HUMAN" ); return { @@ -55879,12 +55879,12 @@ function describeMission(deps3, missionId) { coverage, openQuestions, blockingQuestions: openQuestions.filter((question) => question.materiality === "blocking"), - activeDecisionCount: readDecisions(deps3.workspace, missionId).filter( + activeDecisionCount: readDecisions(deps4.workspace, missionId).filter( (decision) => decision.status === "active" ).length, constitutionVersion: constitution?.version ?? 0, activeConstitutionRules: constitution?.rules.filter((rule) => rule.status === "active").length ?? 0, - contractCount: readContractRegistry(deps3.workspace, missionId).length, + contractCount: readContractRegistry(deps4.workspace, missionId).length, adrCount: mission.counters.adrs, openCcrs }; @@ -55958,9 +55958,9 @@ function assignSuccessCriteria(successCriteria, contracts) { const criterionTokens = tokenize(statement); let best = contracts.length - 1; let bestScore = 0; - contractTokens.forEach((tokens, contractIndex) => { + contractTokens.forEach((tokens2, contractIndex) => { let score = 0; - for (const token of criterionTokens) if (tokens.has(token)) score += 1; + for (const token of criterionTokens) if (tokens2.has(token)) score += 1; if (score > bestScore) { bestScore = score; best = contractIndex; @@ -56199,8 +56199,8 @@ function validateCompiledDocuments(documents) { } return problems; } -function synthesizeMissionSpec(deps3, missionId, request = {}) { - let mission = requireMissionState(deps3.workspace, missionId); +function synthesizeMissionSpec(deps4, missionId, request = {}) { + let mission = requireMissionState(deps4.workspace, missionId); if (mission.status !== "CONTRACT_READY") { throw new MissionError( "SBM014", @@ -56212,7 +56212,7 @@ function synthesizeMissionSpec(deps3, missionId, request = {}) { } ); } - const coverage = refreshCoverage(deps3, mission); + const coverage = refreshCoverage(deps4, mission); if (!coverage.contractReady) { throw new MissionError("SBM008", `The coverage gate no longer holds: ${coverage.reasons.join(" ")}`); } @@ -56221,10 +56221,10 @@ function synthesizeMissionSpec(deps3, missionId, request = {}) { if (!nameCheck.valid) { throw new MissionError("SBM005", `"${specName}" is not a valid spec name: ${nameCheck.problems.join("; ")}`); } - const contracts = readContractRegistry(deps3.workspace, missionId); - const constitution = readConstitution(deps3.workspace, missionId); - const adrs = readAdrs(deps3.workspace, missionId); - const decisions = readDecisions(deps3.workspace, missionId); + const contracts = readContractRegistry(deps4.workspace, missionId); + const constitution = readConstitution(deps4.workspace, missionId); + const adrs = readAdrs(deps4.workspace, missionId); + const decisions = readDecisions(deps4.workspace, missionId); const compiled = compileMissionDocuments({ mission, contracts, @@ -56236,20 +56236,20 @@ function synthesizeMissionSpec(deps3, missionId, request = {}) { if (problems.length > 0) { throw new MissionError("SBM011", `The compiled spec candidates are invalid: ${problems.join("; ")}.`); } - const at = (deps3.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); + const at = (deps4.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); mission = { ...mission, updatedAt: at }; assertMissionTransition(mission.status, "SPEC_SYNTHESIS"); mission = { ...mission, status: "SPEC_SYNTHESIS" }; - appendMissionEvent(deps3.workspace, missionId, { at, type: "synthesis_started", specName }); - mission = writeMissionState(deps3.workspace, { + appendMissionEvent(deps4.workspace, missionId, { at, type: "synthesis_started", specName }); + mission = writeMissionState(deps4.workspace, { ...mission, counters: { ...mission.counters, events: mission.counters.events + 1 } }); - writeSpecCandidate(deps3.workspace, missionId, "requirements.md", compiled.requirements); - writeSpecCandidate(deps3.workspace, missionId, "design.md", compiled.design); - writeSpecCandidate(deps3.workspace, missionId, "tasks.md", compiled.tasks); + writeSpecCandidate(deps4.workspace, missionId, "requirements.md", compiled.requirements); + writeSpecCandidate(deps4.workspace, missionId, "design.md", compiled.design); + writeSpecCandidate(deps4.workspace, missionId, "tasks.md", compiled.tasks); writeSpecCandidate( - deps3.workspace, + deps4.workspace, missionId, "provenance.json", `${JSON.stringify( @@ -56271,7 +56271,7 @@ function synthesizeMissionSpec(deps3, missionId, request = {}) { ); try { const plan = planSpecCreationFromFiles( - deps3.workspace, + deps4.workspace, { name: specName, specType: "feature", @@ -56285,19 +56285,19 @@ function synthesizeMissionSpec(deps3, missionId, request = {}) { { fileName: "tasks.md", stage: "tasks", content: compiled.tasks } ] }, - deps3.clock ?? (() => /* @__PURE__ */ new Date()) + deps4.clock ?? (() => /* @__PURE__ */ new Date()) ); - executeSpecCreation(deps3.workspace, plan); + executeSpecCreation(deps4.workspace, plan); } catch (cause) { - const failedAt = (deps3.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); - appendMissionEvent(deps3.workspace, missionId, { + const failedAt = (deps4.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); + appendMissionEvent(deps4.workspace, missionId, { at: failedAt, type: "status_changed", from: "SPEC_SYNTHESIS", to: "CONTRACT_READY", reason: "synthesis failed" }); - writeMissionState(deps3.workspace, { + writeMissionState(deps4.workspace, { ...mission, status: "CONTRACT_READY", updatedAt: failedAt, @@ -56310,19 +56310,19 @@ function synthesizeMissionSpec(deps3, missionId, request = {}) { ); } assertMissionTransition("SPEC_SYNTHESIS", "SPEC_REVIEW"); - appendMissionEvent(deps3.workspace, missionId, { + appendMissionEvent(deps4.workspace, missionId, { at, type: "synthesis_completed", specName, objectives: compiled.objectiveCount }); - appendMissionEvent(deps3.workspace, missionId, { + appendMissionEvent(deps4.workspace, missionId, { at, type: "status_changed", from: "SPEC_SYNTHESIS", to: "SPEC_REVIEW" }); - mission = writeMissionState(deps3.workspace, { + mission = writeMissionState(deps4.workspace, { ...mission, status: "SPEC_REVIEW", specName, @@ -56342,33 +56342,33 @@ function synthesizeMissionSpec(deps3, missionId, request = {}) { warnings: [] }; } -function observeSpecApproval(deps3, missionId) { - let mission = requireMissionState(deps3.workspace, missionId); +function observeSpecApproval(deps4, missionId) { + let mission = requireMissionState(deps4.workspace, missionId); if (mission.status !== "SPEC_REVIEW" || mission.specName === void 0) return mission; let approved = false; try { - const spec = analyzeSpec(deps3.workspace, requireSpec(deps3.workspace, mission.specName)); + const spec = analyzeSpec(deps4.workspace, requireSpec(deps4.workspace, mission.specName)); if (spec.state !== void 0) { - approved = evaluateWorkflow(deps3.workspace, spec.state).effectiveStatus === "READY_FOR_IMPLEMENTATION"; + approved = evaluateWorkflow(deps4.workspace, spec.state).effectiveStatus === "READY_FOR_IMPLEMENTATION"; } } catch { return mission; } if (!approved) return mission; - const at = (deps3.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); + const at = (deps4.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); assertMissionTransition("SPEC_REVIEW", "APPROVED"); - appendMissionEvent(deps3.workspace, missionId, { + appendMissionEvent(deps4.workspace, missionId, { at, type: "spec_approval_observed", specName: mission.specName }); - appendMissionEvent(deps3.workspace, missionId, { + appendMissionEvent(deps4.workspace, missionId, { at, type: "status_changed", from: "SPEC_REVIEW", to: "APPROVED" }); - mission = writeMissionState(deps3.workspace, { + mission = writeMissionState(deps4.workspace, { ...mission, status: "APPROVED", approvedAt: at, @@ -58178,14 +58178,14 @@ function orchestrationStorageBytes(workspace, orchestrationId) { walk(dir); return total; } -function policyOf(deps3) { - return deps3.config.orchestration; +function policyOf(deps4) { + return deps4.config.orchestration; } -function now2(deps3) { - return (deps3.clock ?? systemClock)(); +function now2(deps4) { + return (deps4.clock ?? systemClock)(); } -function newId(deps3) { - return (deps3.idFactory ?? import_crypto18.randomUUID)(); +function newId(deps4) { + return (deps4.idFactory ?? import_crypto18.randomUUID)(); } function assertEnabled(policy) { if (policy.enabled) return; @@ -58199,9 +58199,9 @@ function assertEnabled(policy) { } ); } -function record3(deps3, state, type, payload = {}) { - const policy = policyOf(deps3); - const stored = countOrchestrationEvents(deps3.workspace, state.orchestrationId); +function record3(deps4, state, type, payload = {}) { + const policy = policyOf(deps4); + const stored = countOrchestrationEvents(deps4.workspace, state.orchestrationId); if (stored >= state.budgets.maxEvents) { throw new OrchestrationError( "SBO020", @@ -58215,25 +58215,25 @@ function record3(deps3, state, type, payload = {}) { ); } appendOrchestrationEvent( - deps3.workspace, + deps4.workspace, state.orchestrationId, - { at: now2(deps3).toISOString(), type, ...payload }, + { at: now2(deps4).toISOString(), type, ...payload }, { maxEventBytes: policy.history.maxEventBytes } ); return { ...state, counters: { ...state.counters, events: stored + 1 } }; } -function transition2(deps3, state, to) { +function transition2(deps4, state, to) { assertTransition(state.phase, to); - return { ...state, phase: to, updatedAt: now2(deps3).toISOString() }; + return { ...state, phase: to, updatedAt: now2(deps4).toISOString() }; } -function persist2(deps3, state) { - return writeOrchestrationState(deps3.workspace, { +function persist2(deps4, state) { + return writeOrchestrationState(deps4.workspace, { ...state, - updatedAt: now2(deps3).toISOString() + updatedAt: now2(deps4).toISOString() }); } -function beginOrchestration(deps3, request) { - const policy = policyOf(deps3); +function beginOrchestration(deps4, request) { + const policy = policyOf(deps4); assertEnabled(policy); const goal = request.goal.trim(); if (goal.length === 0) { @@ -58241,17 +58241,17 @@ function beginOrchestration(deps3, request) { remediation: ["Describe what the user asked for, in one or two sentences."] }); } - const createdAt = now2(deps3).toISOString(); + const createdAt = now2(deps4).toISOString(); const state = { schemaVersion: ORCHESTRATION_STATE_SCHEMA_VERSION, - orchestrationId: newId(deps3), + orchestrationId: newId(deps4), specName: request.specName, ...request.taskId !== void 0 ? { taskId: request.taskId } : {}, phase: "CREATED", goal: goal.slice(0, 4e3), createdAt, updatedAt: createdAt, - host: deps3.host ?? "mcp", + host: deps4.host ?? "mcp", planningMode: policy.planning.mode, policyFingerprint: orchestrationPolicyFingerprint(policy), budgets: { @@ -58279,18 +58279,18 @@ function beginOrchestration(deps3, request) { planStaleReasons: [], interactiveRunIds: [] }; - createOrchestrationRun(deps3.workspace, state); - const recorded = record3(deps3, state, "orchestration_started", { + createOrchestrationRun(deps4.workspace, state); + const recorded = record3(deps4, state, "orchestration_started", { specName: state.specName, ...state.taskId !== void 0 ? { taskId: state.taskId } : {}, planningMode: state.planningMode }); - return persist2(deps3, recorded); + return persist2(deps4, recorded); } -function assessIntent(deps3, orchestrationId, submission) { - const policy = policyOf(deps3); +function assessIntent(deps4, orchestrationId, submission) { + const policy = policyOf(deps4); assertEnabled(policy); - let state = requireOrchestrationState(deps3.workspace, orchestrationId); + let state = requireOrchestrationState(deps4.workspace, orchestrationId); if (isFinalPhase(state.phase)) { throw new OrchestrationError( "SBO005", @@ -58300,18 +58300,18 @@ function assessIntent(deps3, orchestrationId, submission) { } const validation = validateIntent( { - workspace: deps3.workspace, + workspace: deps4.workspace, specName: state.specName, taskId: state.taskId, policy, orchestrationId }, submission, - { assessedAt: now2(deps3).toISOString() } + { assessedAt: now2(deps4).toISOString() } ); const target = validation.assessment.outcome === "READY" ? "READY_TO_PLAN" : validation.assessment.outcome === "NEEDS_CLARIFICATION" ? "NEEDS_CLARIFICATION" : validation.assessment.outcome === "REJECTED" ? "REJECTED" : "BLOCKED"; state = { ...state, intent: validation.assessment }; - state = transition2(deps3, state, target); + state = transition2(deps4, state, target); if (target === "BLOCKED" && validation.blockers[0] !== void 0) { const first = validation.blockers[0]; state = { @@ -58321,25 +58321,25 @@ function assessIntent(deps3, orchestrationId, submission) { code: first.code, message: first.message, remediation: first.remediation, - at: now2(deps3).toISOString() + at: now2(deps4).toISOString() } }; } if (target === "REJECTED") { state = { ...state, - finalizedAt: now2(deps3).toISOString(), + finalizedAt: now2(deps4).toISOString(), finalOutcome: "REJECTED" }; } - state = record3(deps3, state, "intent_assessed", { + state = record3(deps4, state, "intent_assessed", { outcome: validation.assessment.outcome, overridden: validation.overridden, ...validation.assessment.overriddenFrom !== void 0 ? { submittedOutcome: validation.assessment.overriddenFrom } : {}, blockers: validation.blockers.map((blocker) => blocker.code) }); return { - state: persist2(deps3, state), + state: persist2(deps4, state), overridden: validation.overridden, blockers: validation.blockers.map((blocker) => ({ code: blocker.code, @@ -58348,14 +58348,14 @@ function assessIntent(deps3, orchestrationId, submission) { })) }; } -function requestClarification(deps3, orchestrationId, candidates) { - const policy = policyOf(deps3); +function requestClarification(deps4, orchestrationId, candidates) { + const policy = policyOf(deps4); assertEnabled(policy); - let state = requireOrchestrationState(deps3.workspace, orchestrationId); + let state = requireOrchestrationState(deps4.workspace, orchestrationId); assertActionAllowed(state.phase, "REQUEST_CLARIFICATION"); const round2 = buildClarificationRound(state, candidates, policy, { - askedAt: now2(deps3).toISOString(), - idFactory: () => newId(deps3) + askedAt: now2(deps4).toISOString(), + idFactory: () => newId(deps4) }); state = { ...state, @@ -58363,18 +58363,18 @@ function requestClarification(deps3, orchestrationId, candidates) { counters: { ...state.counters, clarificationRounds: round2.round } }; if (state.phase !== "NEEDS_CLARIFICATION") { - state = transition2(deps3, state, "NEEDS_CLARIFICATION"); + state = transition2(deps4, state, "NEEDS_CLARIFICATION"); } - state = record3(deps3, state, "clarification_requested", { + state = record3(deps4, state, "clarification_requested", { round: round2.round, questionIds: round2.questions.map((question) => question.id) }); - return persist2(deps3, state); + return persist2(deps4, state); } -function resolveClarification(deps3, orchestrationId, candidates) { - const policy = policyOf(deps3); +function resolveClarification(deps4, orchestrationId, candidates) { + const policy = policyOf(deps4); assertEnabled(policy); - let state = requireOrchestrationState(deps3.workspace, orchestrationId); + let state = requireOrchestrationState(deps4.workspace, orchestrationId); if (isFinalPhase(state.phase)) { throw new OrchestrationError( "SBO005", @@ -58382,8 +58382,8 @@ function resolveClarification(deps3, orchestrationId, candidates) { ); } const decisions = buildClarificationDecisions(state, candidates, policy, { - decidedAt: now2(deps3).toISOString(), - idFactory: () => newId(deps3) + decidedAt: now2(deps4).toISOString(), + idFactory: () => newId(deps4) }); const answeredIds = new Set(decisions.map((decision) => decision.questionId)); state = { @@ -58392,19 +58392,19 @@ function resolveClarification(deps3, orchestrationId, candidates) { openQuestions: state.openQuestions.filter((question) => !answeredIds.has(question.id)) }; if (state.openQuestions.length === 0 && state.phase === "NEEDS_CLARIFICATION") { - state = transition2(deps3, state, "READY_TO_PLAN"); + state = transition2(deps4, state, "READY_TO_PLAN"); } - state = record3(deps3, state, "clarification_resolved", { + state = record3(deps4, state, "clarification_resolved", { decisionIds: decisions.map((decision) => decision.id), remainingQuestions: state.openQuestions.length }); const requiresSpecChange = decisions.filter((decision) => /\b(spec|requirement|design|acceptance criteri)\b/i.test(decision.impact ?? "")).map((decision) => decision.id); - return { state: persist2(deps3, state), requiresSpecChange }; + return { state: persist2(deps4, state), requiresSpecChange }; } -async function submitPlan(deps3, orchestrationId, candidate) { - const policy = policyOf(deps3); +async function submitPlan(deps4, orchestrationId, candidate) { + const policy = policyOf(deps4); assertEnabled(policy); - let state = requireOrchestrationState(deps3.workspace, orchestrationId); + let state = requireOrchestrationState(deps4.workspace, orchestrationId); if (isFinalPhase(state.phase)) { throw new OrchestrationError( "SBO005", @@ -58445,26 +58445,26 @@ async function submitPlan(deps3, orchestrationId, candidate) { } ); } - const snapshot2 = await captureGitSnapshot(deps3.workspace.rootDir, { clock: () => now2(deps3) }); - const binding = capturePlanBinding(deps3.workspace, { + const snapshot2 = await captureGitSnapshot(deps4.workspace.rootDir, { clock: () => now2(deps4) }); + const binding = capturePlanBinding(deps4.workspace, { specName: state.specName, taskId: candidate.taskId, policy, gitHead: snapshot2.head }); const revision = state.planRevision + 1; - const previous = replacing ? readPlanRevision(deps3.workspace, orchestrationId, state.planRevision) : void 0; + const previous = replacing ? readPlanRevision(deps4.workspace, orchestrationId, state.planRevision) : void 0; const plan = buildExecutionPlan({ candidate, specName: state.specName, binding, revision, - planId: newId(deps3), - createdAt: now2(deps3).toISOString(), + planId: newId(deps4), + createdAt: now2(deps4).toISOString(), policy, ...previous !== void 0 ? { supersedes: previous.planId } : {} }); - const stored = storePlanRevision(deps3.workspace, orchestrationId, plan); + const stored = storePlanRevision(deps4.workspace, orchestrationId, plan); const materiality = previous !== void 0 ? assessPlanChange(previous, plan) : void 0; const reviewRequired = policy.planning.mode === "review" && (state.planReview?.decision !== "approved" || materiality?.materiality === "material"); state = { @@ -58483,7 +58483,7 @@ async function submitPlan(deps3, orchestrationId, candidate) { } }; if (reviewRequired) delete state.planReview; - state = record3(deps3, state, "plan_created", { + state = record3(deps4, state, "plan_created", { revision, planId: plan.planId, planHash: stored.hash, @@ -58492,24 +58492,24 @@ async function submitPlan(deps3, orchestrationId, candidate) { ...materiality !== void 0 ? { materialChanges: materiality.materialChanges } : {} }); if (replacing) { - state = record3(deps3, state, "replan_started", { + state = record3(deps4, state, "replan_started", { revision, ...candidate.replanReason !== void 0 ? { reason: candidate.replanReason } : {} }); } - state = transition2(deps3, state, reviewRequired ? "AWAITING_PLAN_REVIEW" : "READY_TO_EXECUTE"); + state = transition2(deps4, state, reviewRequired ? "AWAITING_PLAN_REVIEW" : "READY_TO_EXECUTE"); return { - state: persist2(deps3, state), + state: persist2(deps4, state), plan, planHash: stored.hash, reviewRequired, ...materiality !== void 0 ? { materiality } : {} }; } -function reviewPlan(deps3, orchestrationId, request) { - const policy = policyOf(deps3); +function reviewPlan(deps4, orchestrationId, request) { + const policy = policyOf(deps4); assertEnabled(policy); - let state = requireOrchestrationState(deps3.workspace, orchestrationId); + let state = requireOrchestrationState(deps4.workspace, orchestrationId); if (state.phase !== "AWAITING_PLAN_REVIEW") { throw new OrchestrationError( "SBO004", @@ -58529,7 +58529,7 @@ function reviewPlan(deps3, orchestrationId, request) { } ); } - const reviewedAt = now2(deps3).toISOString(); + const reviewedAt = now2(deps4).toISOString(); state = { ...state, planReview: { @@ -58541,21 +58541,21 @@ function reviewPlan(deps3, orchestrationId, request) { ...request.note !== void 0 ? { note: request.note } : {} } }; - state = record3(deps3, state, "plan_reviewed", { + state = record3(deps4, state, "plan_reviewed", { decision: request.decision, revision: state.planRevision, planHash: request.planHash }); - state = transition2(deps3, state, request.decision === "approved" ? "READY_TO_EXECUTE" : "READY_TO_PLAN"); - return persist2(deps3, state); + state = transition2(deps4, state, request.decision === "approved" ? "READY_TO_EXECUTE" : "READY_TO_PLAN"); + return persist2(deps4, state); } -async function checkPlanFreshness(deps3, orchestrationId) { - const policy = policyOf(deps3); - const state = requireOrchestrationState(deps3.workspace, orchestrationId); +async function checkPlanFreshness(deps4, orchestrationId) { + const policy = policyOf(deps4); + const state = requireOrchestrationState(deps4.workspace, orchestrationId); if (state.planRevision === 0) { return { fresh: false, reasons: ["no-plan"], explanations: ["No plan exists yet."], planRevision: 0 }; } - const plan = readPlanRevision(deps3.workspace, orchestrationId, state.planRevision); + const plan = readPlanRevision(deps4.workspace, orchestrationId, state.planRevision); if (plan === void 0) { return { fresh: false, @@ -58564,8 +58564,8 @@ async function checkPlanFreshness(deps3, orchestrationId) { planRevision: state.planRevision }; } - const snapshot2 = await captureGitSnapshot(deps3.workspace.rootDir, { clock: () => now2(deps3) }); - const current = capturePlanBinding(deps3.workspace, { + const snapshot2 = await captureGitSnapshot(deps4.workspace.rootDir, { clock: () => now2(deps4) }); + const current = capturePlanBinding(deps4.workspace, { specName: state.specName, taskId: plan.binding.taskId, policy, @@ -58574,16 +58574,16 @@ async function checkPlanFreshness(deps3, orchestrationId) { const freshness = evaluatePlanFreshness(plan, current); return { ...freshness, planRevision: state.planRevision }; } -async function refreshPlanBinding(deps3, orchestrationId) { - const policy = policyOf(deps3); - let state = requireOrchestrationState(deps3.workspace, orchestrationId); +async function refreshPlanBinding(deps4, orchestrationId) { + const policy = policyOf(deps4); + let state = requireOrchestrationState(deps4.workspace, orchestrationId); if (state.planRevision === 0) { return { state, freshness: { fresh: false, reasons: ["no-plan"], explanations: ["No plan exists yet."], planRevision: 0 } }; } - const plan = readPlanRevision(deps3.workspace, orchestrationId, state.planRevision); + const plan = readPlanRevision(deps4.workspace, orchestrationId, state.planRevision); if (plan === void 0) { throw new OrchestrationError( "SBO010", @@ -58591,8 +58591,8 @@ async function refreshPlanBinding(deps3, orchestrationId) { { remediation: ["Submit a fresh plan; the previous revisions are preserved on disk."] } ); } - const snapshot2 = await captureGitSnapshot(deps3.workspace.rootDir, { clock: () => now2(deps3) }); - const current = capturePlanBinding(deps3.workspace, { + const snapshot2 = await captureGitSnapshot(deps4.workspace.rootDir, { clock: () => now2(deps4) }); + const current = capturePlanBinding(deps4.workspace, { specName: state.specName, taskId: plan.binding.taskId, policy, @@ -58601,16 +58601,16 @@ async function refreshPlanBinding(deps3, orchestrationId) { const freshness = evaluatePlanFreshness(plan, current); if (!freshness.fresh) { state = { ...state, planStaleReasons: freshness.reasons }; - state = record3(deps3, state, "plan_invalidated", { + state = record3(deps4, state, "plan_invalidated", { revision: state.planRevision, reasons: freshness.reasons }); if (state.phase !== "REPLANNING" && !isFinalPhase(state.phase)) { - state = transition2(deps3, state, "REPLANNING"); + state = transition2(deps4, state, "REPLANNING"); } - state = persist2(deps3, state); + state = persist2(deps4, state); } else if (state.planStaleReasons.length > 0) { - state = persist2(deps3, { ...state, planStaleReasons: [] }); + state = persist2(deps4, { ...state, planStaleReasons: [] }); } return { state, @@ -58622,10 +58622,10 @@ async function refreshPlanBinding(deps3, orchestrationId) { } }; } -function recordAction(deps3, orchestrationId, request) { - const policy = policyOf(deps3); +function recordAction(deps4, orchestrationId, request) { + const policy = policyOf(deps4); assertEnabled(policy); - let state = requireOrchestrationState(deps3.workspace, orchestrationId); + let state = requireOrchestrationState(deps4.workspace, orchestrationId); if (isFinalPhase(state.phase)) { throw new OrchestrationError( "SBO005", @@ -58680,7 +58680,7 @@ function recordAction(deps3, orchestrationId, request) { consecutiveNoProgress: state.counters.consecutiveNoProgress, maxNoProgressCycles: state.budgets.maxNoProgressCycles }); - const elapsedMs = Math.max(0, now2(deps3).getTime() - Date.parse(state.createdAt)); + const elapsedMs = Math.max(0, now2(deps4).getTime() - Date.parse(state.createdAt)); const decision = decideNextStep( { failure: classified2, @@ -58704,13 +58704,13 @@ function recordAction(deps3, orchestrationId, request) { ...decision.directive === "REPAIR" ? { repairCycles: state.counters.repairCycles + 1 } : {} } }; - state = record3(deps3, state, "action_recorded", { + state = record3(deps4, state, "action_recorded", { action: request.action, target: request.target.slice(0, 200), ...request.planStepId !== void 0 ? { planStepId: request.planStepId } : {}, result: request.result }); - state = record3(deps3, state, "observation_recorded", { + state = record3(deps4, state, "observation_recorded", { result: request.result, progressed: progress.progressed, consecutiveNoProgress: progress.consecutiveNoProgress, @@ -58720,42 +58720,42 @@ function recordAction(deps3, orchestrationId, request) { directive: decision.directive }); if (classified2?.category === "VERIFICATION_FAILURE") { - state = record3(deps3, state, "verification_failed", { + state = record3(deps4, state, "verification_failed", { source: request.failure?.source ?? "unknown", fingerprint: classified2.fingerprint }); } - state = applyDirective(deps3, state, decision, classified2); + state = applyDirective(deps4, state, decision, classified2); return { - state: persist2(deps3, state), + state: persist2(deps4, state), decision, progress, ...classified2 !== void 0 ? { classifiedFailure: classified2 } : {} }; } -async function recordActionChecked(deps3, orchestrationId, request) { +async function recordActionChecked(deps4, orchestrationId, request) { const needsFreshPlan = request.action === "EDIT" || request.action === "VERIFY" || request.action === "COMPLETE"; if (needsFreshPlan) { - const state = requireOrchestrationState(deps3.workspace, orchestrationId); + const state = requireOrchestrationState(deps4.workspace, orchestrationId); if (state.planRevision > 0 && !isFinalPhase(state.phase)) { - await refreshPlanBinding(deps3, orchestrationId); + await refreshPlanBinding(deps4, orchestrationId); } } - return recordAction(deps3, orchestrationId, request); + return recordAction(deps4, orchestrationId, request); } -function applyDirective(deps3, input, decision, failure3) { +function applyDirective(deps4, input, decision, failure3) { let state = input; - const at = now2(deps3).toISOString(); + const at = now2(deps4).toISOString(); switch (decision.directive) { case "CONTINUE": case "RETRY": case "VERIFY": - if (state.phase === "READY_TO_EXECUTE") state = transition2(deps3, state, "EXECUTING"); + if (state.phase === "READY_TO_EXECUTE") state = transition2(deps4, state, "EXECUTING"); return state; case "REPAIR": { if (state.phase !== "REPAIRING") { - state = transition2(deps3, state, "REPAIRING"); - state = record3(deps3, state, "repair_started", { + state = transition2(deps4, state, "REPAIRING"); + state = record3(deps4, state, "repair_started", { cycle: state.counters.repairCycles, ...failure3 !== void 0 ? { fingerprint: failure3.fingerprint } : {} }); @@ -58767,17 +58767,17 @@ function applyDirective(deps3, input, decision, failure3) { } case "REPLAN": if (state.planRevision > 0 && state.phase !== "REPLANNING") { - state = transition2(deps3, state, "REPLANNING"); + state = transition2(deps4, state, "REPLANNING"); } return state; case "CLARIFY": if (state.phase !== "NEEDS_CLARIFICATION") { - state = transition2(deps3, state, "NEEDS_CLARIFICATION"); + state = transition2(deps4, state, "NEEDS_CLARIFICATION"); } return state; case "BLOCK": { - state = transition2(deps3, state, "BLOCKED"); - state = record3(deps3, state, "execution_blocked", { + state = transition2(deps4, state, "BLOCKED"); + state = record3(deps4, state, "execution_blocked", { ...failure3 !== void 0 ? { category: failure3.category } : {}, reason: decision.reason }); @@ -58793,8 +58793,8 @@ function applyDirective(deps3, input, decision, failure3) { }; } case "STOP_BUDGET_EXHAUSTED": { - state = transition2(deps3, state, "BLOCKED"); - state = record3(deps3, state, "budget_exhausted", { + state = transition2(deps4, state, "BLOCKED"); + state = record3(deps4, state, "budget_exhausted", { budget: decision.exhaustedBudget ?? "unknown", reason: decision.reason }); @@ -58810,18 +58810,18 @@ function applyDirective(deps3, input, decision, failure3) { }; } case "STOP_FINAL": { - state = transition2(deps3, state, "CANCELLED"); - state = record3(deps3, state, "execution_cancelled", { reason: decision.reason }); + state = transition2(deps4, state, "CANCELLED"); + state = record3(deps4, state, "execution_cancelled", { reason: decision.reason }); return { ...state, finalizedAt: at, finalOutcome: "CANCELLED" }; } } } -function finalizeOrchestration(deps3, orchestrationId, request) { - let state = requireOrchestrationState(deps3.workspace, orchestrationId); +function finalizeOrchestration(deps4, orchestrationId, request) { + let state = requireOrchestrationState(deps4.workspace, orchestrationId); if (isFinalPhase(state.phase)) { return state; } - const at = now2(deps3).toISOString(); + const at = now2(deps4).toISOString(); if (request.outcome === "completed") { const accepted = request.evidenceStatus === "verified" || request.evidenceStatus === "manually-accepted"; if (!accepted) { @@ -58837,29 +58837,29 @@ function finalizeOrchestration(deps3, orchestrationId, request) { } ); } - state = transition2(deps3, state, "COMPLETED"); - state = record3(deps3, state, "execution_completed", { + state = transition2(deps4, state, "COMPLETED"); + state = record3(deps4, state, "execution_completed", { evidenceStatus: request.evidenceStatus, ...request.interactiveRunId !== void 0 ? { runId: request.interactiveRunId } : {} }); - return persist2(deps3, { ...state, finalizedAt: at, finalOutcome: "COMPLETED" }); + return persist2(deps4, { ...state, finalizedAt: at, finalOutcome: "COMPLETED" }); } if (request.outcome === "cancelled") { - state = transition2(deps3, state, "CANCELLED"); - state = record3(deps3, state, "execution_cancelled", { reason: request.reason }); - return persist2(deps3, { ...state, finalizedAt: at, finalOutcome: "CANCELLED" }); + state = transition2(deps4, state, "CANCELLED"); + state = record3(deps4, state, "execution_cancelled", { reason: request.reason }); + return persist2(deps4, { ...state, finalizedAt: at, finalOutcome: "CANCELLED" }); } - state = transition2(deps3, state, "ABORTED"); - state = record3(deps3, state, "execution_aborted", { reason: request.reason }); - return persist2(deps3, { ...state, finalizedAt: at, finalOutcome: "ABORTED" }); + state = transition2(deps4, state, "ABORTED"); + state = record3(deps4, state, "execution_aborted", { reason: request.reason }); + return persist2(deps4, { ...state, finalizedAt: at, finalOutcome: "ABORTED" }); } -function createCheckpoint(deps3, orchestrationId, input) { - let state = requireOrchestrationState(deps3.workspace, orchestrationId); - const plan = state.planRevision > 0 ? readPlanRevision(deps3.workspace, orchestrationId, state.planRevision) : void 0; +function createCheckpoint(deps4, orchestrationId, input) { + let state = requireOrchestrationState(deps4.workspace, orchestrationId); + const plan = state.planRevision > 0 ? readPlanRevision(deps4.workspace, orchestrationId, state.planRevision) : void 0; const checkpoint = orchestrationCheckpointSchema.parse({ schemaVersion: ORCHESTRATION_CHECKPOINT_SCHEMA_VERSION, orchestrationId, - createdAt: now2(deps3).toISOString(), + createdAt: now2(deps4).toISOString(), specName: state.specName, ...state.taskId !== void 0 ? { taskId: state.taskId } : {}, phase: state.phase, @@ -58873,9 +58873,9 @@ function createCheckpoint(deps3, orchestrationId, input) { ...state.blocker !== void 0 ? { blocker: state.blocker } : {}, nextAction: input.nextAction }); - writeOrchestrationCheckpoint(deps3.workspace, orchestrationId, checkpoint); - state = record3(deps3, state, "checkpoint_created", { phase: state.phase }); - persist2(deps3, state); + writeOrchestrationCheckpoint(deps4.workspace, orchestrationId, checkpoint); + state = record3(deps4, state, "checkpoint_created", { phase: state.phase }); + persist2(deps4, state); return checkpoint; } function budgetUsage(state) { @@ -59051,10 +59051,10 @@ function describeOrchestration(workspace, state, options = {}) { totalEvents: page.total }; } -async function resumeOrchestration(deps3, orchestrationId) { - const state = requireOrchestrationState(deps3.workspace, orchestrationId); +async function resumeOrchestration(deps4, orchestrationId) { + const state = requireOrchestrationState(deps4.workspace, orchestrationId); const warnings = []; - const checkpoint = readOrchestrationCheckpoint(deps3.workspace, orchestrationId); + const checkpoint = readOrchestrationCheckpoint(deps4.workspace, orchestrationId); if (isFinalPhase(state.phase)) { const explanation2 = explainOrchestration(state); return { @@ -59072,21 +59072,21 @@ async function resumeOrchestration(deps3, orchestrationId) { ] }; } - const currentFingerprint = orchestrationPolicyFingerprint(deps3.config.orchestration); + const currentFingerprint = orchestrationPolicyFingerprint(deps4.config.orchestration); const policyChanged = currentFingerprint !== state.policyFingerprint; if (policyChanged) { warnings.push( "The orchestration policy changed since this run began. The run continues under the budgets recorded at its start; start a new run to adopt the new policy." ); } - const snapshot2 = await captureGitSnapshot(deps3.workspace.rootDir, { - clock: () => (deps3.clock ?? (() => /* @__PURE__ */ new Date()))() + const snapshot2 = await captureGitSnapshot(deps4.workspace.rootDir, { + clock: () => (deps4.clock ?? (() => /* @__PURE__ */ new Date()))() }); let planStale = false; let planStaleReasons = []; let planStaleExplanations = []; if (state.planRevision > 0) { - const freshness = await checkPlanFreshness(deps3, orchestrationId); + const freshness = await checkPlanFreshness(deps4, orchestrationId); planStale = !freshness.fresh; planStaleReasons = freshness.reasons; planStaleExplanations = freshness.explanations; @@ -59098,8 +59098,8 @@ async function resumeOrchestration(deps3, orchestrationId) { } let activeInteractiveRun; if (state.activeInteractiveRunId !== void 0) { - const record32 = readRunRecord(deps3.workspace, state.activeInteractiveRunId); - const lock = readInteractiveLock(deps3.workspace); + const record32 = readRunRecord(deps4.workspace, state.activeInteractiveRunId); + const lock = readInteractiveLock(deps4.workspace); const lockHeld = lock.state === "held" && lock.lock.runId === state.activeInteractiveRunId; activeInteractiveRun = { runId: state.activeInteractiveRunId, @@ -62513,7 +62513,7 @@ function failureResult(category, message2, source, escalated) { }; } async function dispatchLocalExecution(input) { - const deps3 = { + const deps4 = { workspace: input.workspace, config: input.config, ...input.clock !== void 0 ? { clock: input.clock } : {}, @@ -62521,7 +62521,7 @@ async function dispatchLocalExecution(input) { ...input.signal !== void 0 ? { signal: input.signal } : {}, host: "local-executor" }; - const begin = await beginInteractiveTask(deps3, { + const begin = await beginInteractiveTask(deps4, { specName: input.specName, taskId: input.node.parentTaskId, allowDirty: input.allowDirty, @@ -62538,7 +62538,7 @@ async function dispatchLocalExecution(input) { input.onProgress?.(`local executor: run ${begin.runId} started for task ${begin.task.id}`); const abort = async (reason3) => { try { - await abortInteractiveTask(deps3, { runId: begin.runId, reason: reason3.slice(0, 500) }); + await abortInteractiveTask(deps4, { runId: begin.runId, reason: reason3.slice(0, 500) }); } catch { } }; @@ -62649,7 +62649,7 @@ Your previous response was invalid (${lastProblem.slice(0, 300)}). Return ONLY v ); } input.onProgress?.(`local executor: applied ${written.length} file(s); verifying`); - const completion = await completeInteractiveTask(deps3, { + const completion = await completeInteractiveTask(deps4, { runId: begin.runId, summary: `[local-executor] ${output.summary}`.slice(0, 2e3), reportedChangedFiles: written @@ -65085,6 +65085,11 @@ function readAggregationReport(workspace, jobId, nodeId, name) { (raw) => raw !== null && typeof raw === "object" ? raw : void 0 ); } +function listObjectiveNodes(workspace, jobId) { + const dir = import_path36.default.join(jobDir(workspace, jobId), "objectives"); + if (!(0, import_fs34.existsSync)(dir)) return []; + return (0, import_fs34.readdirSync)(dir, { withFileTypes: true }).filter((entry2) => entry2.isDirectory() && ID_PATTERN3.test(entry2.name)).map((entry2) => entry2.name).sort(); +} var EVALUATION_STATUSES = ["PASS", "FAIL", "INCONCLUSIVE"]; var EVALUATION_CHECK_LEVELS = [ "EXECUTION_INTEGRITY", @@ -66154,16 +66159,16 @@ function readLatestTaskCheckpoint(workspace, jobId, nodeId) { } return void 0; } -function now22(deps3) { - return (deps3.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); +function now22(deps4) { + return (deps4.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); } -function newId2(deps3) { - return (deps3.idFactory ?? import_crypto20.randomUUID)(); +function newId2(deps4) { + return (deps4.idFactory ?? import_crypto20.randomUUID)(); } -function beginTaskAttempt(deps3, input) { - const attemptNumber = nextAttemptNumber2(deps3.workspace, input.jobId, input.nodeId); +function beginTaskAttempt(deps4, input) { + const attemptNumber = nextAttemptNumber2(deps4.workspace, input.jobId, input.nodeId); if (input.resumedFromAttemptId !== void 0) { - const previous = readTaskAttempt(deps3.workspace, input.jobId, input.resumedFromAttemptId); + const previous = readTaskAttempt(deps4.workspace, input.jobId, input.resumedFromAttemptId); if (previous === void 0) { throw new OrchestrationError( "SBO049", @@ -66181,7 +66186,7 @@ function beginTaskAttempt(deps3, input) { schemaVersion: TASK_ATTEMPT_SCHEMA_VERSION, // The generated id is used in full: truncating it could alias two ids // from a deterministic factory, and append-only storage refuses aliases. - attemptId: `ta-${String(attemptNumber).padStart(4, "0")}-${newId2(deps3)}`.slice(0, 64), + attemptId: `ta-${String(attemptNumber).padStart(4, "0")}-${newId2(deps4)}`.slice(0, 64), jobId: input.jobId, nodeId: input.nodeId, taskId: input.taskId, @@ -66191,7 +66196,7 @@ function beginTaskAttempt(deps3, input) { model: input.model ?? null, status: "RUNNING", attemptNumber, - startedAt: now22(deps3), + startedAt: now22(deps4), checkpointIds: [], ...input.runId !== void 0 ? { runId: input.runId } : {}, ...input.providerSessionId !== void 0 ? { providerSessionId: input.providerSessionId } : {}, @@ -66239,10 +66244,10 @@ function beginTaskAttempt(deps3, input) { reconciledCostUsd: null } }; - return writeNewTaskAttempt(deps3.workspace, attempt); + return writeNewTaskAttempt(deps4.workspace, attempt); } -function requireOpenAttempt(deps3, jobId, attemptId) { - const attempt = readTaskAttempt(deps3.workspace, jobId, attemptId); +function requireOpenAttempt(deps4, jobId, attemptId) { + const attempt = readTaskAttempt(deps4.workspace, jobId, attemptId); if (attempt === void 0) { throw new OrchestrationError("SBO049", `Attempt ${attemptId} of job ${jobId} was not found.`); } @@ -66255,9 +66260,9 @@ function requireOpenAttempt(deps3, jobId, attemptId) { } return attempt; } -function completeTaskAttempt(deps3, input) { - const attempt = requireOpenAttempt(deps3, input.jobId, input.attemptId); - const completedAt = now22(deps3); +function completeTaskAttempt(deps4, input) { + const attempt = requireOpenAttempt(deps4, input.jobId, input.attemptId); + const completedAt = now22(deps4); const derivedDuration = Math.max(0, Date.parse(completedAt) - Date.parse(attempt.startedAt)); const finalized = { ...attempt, @@ -66272,24 +66277,24 @@ function completeTaskAttempt(deps3, input) { ...input.metrics ?? {} } }; - return updateTaskAttempt(deps3.workspace, finalized); + return updateTaskAttempt(deps4.workspace, finalized); } -function reconcileInterruptedAttempts(deps3, jobId, reason3 = "process-restart") { - const running = listTaskAttempts(deps3.workspace, jobId, { status: "RUNNING" }); +function reconcileInterruptedAttempts(deps4, jobId, reason3 = "process-restart") { + const running = listTaskAttempts(deps4.workspace, jobId, { status: "RUNNING" }); const reconciled = []; for (const attempt of running) { const interrupted = { ...attempt, status: "INTERRUPTED", - completedAt: now22(deps3), + completedAt: now22(deps4), interruptedReason: reason3 }; - reconciled.push(updateTaskAttempt(deps3.workspace, interrupted)); + reconciled.push(updateTaskAttempt(deps4.workspace, interrupted)); } return reconciled; } -function createTaskCheckpoint(deps3, input) { - const attempt = readTaskAttempt(deps3.workspace, input.jobId, input.attemptId); +function createTaskCheckpoint(deps4, input) { + const attempt = readTaskAttempt(deps4.workspace, input.jobId, input.attemptId); if (attempt === void 0) { throw new OrchestrationError( "SBO050", @@ -66302,8 +66307,8 @@ function createTaskCheckpoint(deps3, input) { `Attempt ${input.attemptId} belongs to node ${attempt.nodeId}, not ${input.nodeId}.` ); } - const previous = readLatestTaskCheckpoint(deps3.workspace, input.jobId, input.nodeId); - const seqs = listTaskCheckpointSeqs(deps3.workspace, input.jobId, input.nodeId); + const previous = readLatestTaskCheckpoint(deps4.workspace, input.jobId, input.nodeId); + const seqs = listTaskCheckpointSeqs(deps4.workspace, input.jobId, input.nodeId); const seq = (seqs[seqs.length - 1] ?? 0) + 1; const mergeTexts = (older, newer) => { const merged = [...older]; @@ -66347,14 +66352,14 @@ function createTaskCheckpoint(deps3, input) { nextActions: input.nextActions, relevantArtifacts: input.relevantArtifacts ?? [], relevantContextReferences: input.relevantContextReferences ?? [], - createdAt: now22(deps3) + createdAt: now22(deps4) }); - const stored = writeTaskCheckpoint(deps3.workspace, checkpoint).checkpoint; + const stored = writeTaskCheckpoint(deps4.workspace, checkpoint).checkpoint; const linked = { ...attempt, checkpointIds: [...attempt.checkpointIds, stored.checkpointId].slice(-50) }; - updateTaskAttempt(deps3.workspace, linked); + updateTaskAttempt(deps4.workspace, linked); return stored; } function readExecutionLedger(workspace, jobId, options = {}) { @@ -66474,8 +66479,8 @@ function summarizeExecutionLedger(entries) { if (!entry2.success) { reliability.failedAttempts += 1; reliability.failedAttemptMs = add2(reliability.failedAttemptMs, entry2.metrics.durationMs); - const tokens = entry2.metrics.inputTokens === null && entry2.metrics.outputTokens === null ? null : (entry2.metrics.inputTokens ?? 0) + (entry2.metrics.outputTokens ?? 0); - reliability.failedAttemptTokens = add2(reliability.failedAttemptTokens, tokens); + const tokens2 = entry2.metrics.inputTokens === null && entry2.metrics.outputTokens === null ? null : (entry2.metrics.inputTokens ?? 0) + (entry2.metrics.outputTokens ?? 0); + reliability.failedAttemptTokens = add2(reliability.failedAttemptTokens, tokens2); reliability.failedAttemptCostUsd = add2( reliability.failedAttemptCostUsd, entry2.metrics.reconciledCostUsd ?? entry2.metrics.costUsd @@ -68582,15 +68587,15 @@ ${bullets(checkpoint.nextActions)}` compacted: true }; } -function reconstructTaskContext(deps3, input) { - const job = requireJobState(deps3.workspace, input.jobId); +function reconstructTaskContext(deps4, input) { + const job = requireJobState(deps4.workspace, input.jobId); if (job.graphRevision < 1) { throw new OrchestrationError( "SBO051", `Job ${input.jobId} has no runtime graph yet; there is no task context to reconstruct.` ); } - const graph = requireGraphRevision(deps3.workspace, input.jobId, job.graphRevision); + const graph = requireGraphRevision(deps4.workspace, input.jobId, job.graphRevision); const node = graph.nodes.find((candidate) => candidate.nodeId === input.nodeId); if (node === void 0) { throw new OrchestrationError( @@ -68598,10 +68603,10 @@ function reconstructTaskContext(deps3, input) { `Node ${input.nodeId} does not exist in graph revision ${job.graphRevision} of job ${input.jobId}.` ); } - const checkpoint = readLatestTaskCheckpoint(deps3.workspace, input.jobId, input.nodeId); - const attempts = listTaskAttempts(deps3.workspace, input.jobId, { nodeId: input.nodeId }); - const createdAt = (deps3.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); - const budget = input.budget ?? contextBudgetFromPolicy(deps3.config.orchestration.jobs.context); + const checkpoint = readLatestTaskCheckpoint(deps4.workspace, input.jobId, input.nodeId); + const attempts = listTaskAttempts(deps4.workspace, input.jobId, { nodeId: input.nodeId }); + const createdAt = (deps4.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); + const budget = input.budget ?? contextBudgetFromPolicy(deps4.config.orchestration.jobs.context); const items = [ ...pinnedItems(job, node, checkpoint, createdAt), ...durableItems(checkpoint, createdAt), @@ -68644,28 +68649,28 @@ function reconstructTaskContext(deps3, input) { throw cause; } } -function nowIso(deps3) { - return (deps3.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); +function nowIso(deps4) { + return (deps4.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); } -function latestFailureText(deps3, jobId, nodeId, node) { +function latestFailureText(deps4, jobId, nodeId, node) { const parts = []; if (node.latestFailure !== void 0) { parts.push(`${node.latestFailure.category}: ${node.latestFailure.message}`); } - const assessment = listFailureAssessments(deps3.workspace, jobId, { nodeId }).at(-1); + const assessment = listFailureAssessments(deps4.workspace, jobId, { nodeId }).at(-1); if (assessment !== void 0) { parts.push(assessment.likelyCause); parts.push(...assessment.evidenceRefs); } return parts.join("\n"); } -function recoveryText(deps3, jobId, nodeId) { - const decision = listRecoveryDecisions(deps3.workspace, jobId, { nodeId }).at(-1); +function recoveryText(deps4, jobId, nodeId) { + const decision = listRecoveryDecisions(deps4.workspace, jobId, { nodeId }).at(-1); if (decision === void 0) return ""; return [decision.action, decision.reason, ...decision.remediation].join("\n"); } -function priorRelevantPaths(deps3, jobId, nodeId) { - const plans = listContextSelectionPlans(deps3.workspace, jobId, { nodeId }).slice(-3); +function priorRelevantPaths(deps4, jobId, nodeId) { + const plans = listContextSelectionPlans(deps4.workspace, jobId, { nodeId }).slice(-3); const paths = /* @__PURE__ */ new Set(); for (const plan of plans) { for (const entry2 of plan.selectedWorkingItems) paths.add(entry2.path); @@ -68673,15 +68678,15 @@ function priorRelevantPaths(deps3, jobId, nodeId) { } return [...paths]; } -async function buildTaskContextPackage(deps3, input) { - const job = requireJobState(deps3.workspace, input.jobId); +async function buildTaskContextPackage(deps4, input) { + const job = requireJobState(deps4.workspace, input.jobId); if (job.graphRevision < 1) { throw new OrchestrationError( "SBO051", `Job ${input.jobId} has no runtime graph yet; there is no task context to build.` ); } - const graph = requireGraphRevision(deps3.workspace, input.jobId, job.graphRevision); + const graph = requireGraphRevision(deps4.workspace, input.jobId, job.graphRevision); const node = graph.nodes.find((candidate) => candidate.nodeId === input.nodeId); if (node === void 0) { throw new OrchestrationError( @@ -68689,15 +68694,15 @@ async function buildTaskContextPackage(deps3, input) { `Node ${input.nodeId} does not exist in graph revision ${job.graphRevision} of job ${input.jobId}.` ); } - const contextPolicy = deps3.config.orchestration.jobs.context; + const contextPolicy = deps4.config.orchestration.jobs.context; const policy = contextPolicy.efficiency; const strategy = policy.strategy; - const createdAt = nowIso(deps3); + const createdAt = nowIso(deps4); const budget = input.budget ?? contextBudgetFromPolicy(contextPolicy); - const checkpoint = readLatestTaskCheckpoint(deps3.workspace, input.jobId, input.nodeId); - const attempts = listTaskAttempts(deps3.workspace, input.jobId, { nodeId: input.nodeId }); - const snapshot2 = input.gitSnapshot ?? await captureGitSnapshot(deps3.workspace.rootDir, { - clock: () => (deps3.clock ?? (() => /* @__PURE__ */ new Date()))() + const checkpoint = readLatestTaskCheckpoint(deps4.workspace, input.jobId, input.nodeId); + const attempts = listTaskAttempts(deps4.workspace, input.jobId, { nodeId: input.nodeId }); + const snapshot2 = input.gitSnapshot ?? await captureGitSnapshot(deps4.workspace.rootDir, { + clock: () => (deps4.clock ?? (() => /* @__PURE__ */ new Date()))() }); const nextActions = checkpoint?.nextActions ?? [`Start task ${node.parentTaskId}: ${node.title}`]; const currentActionText = input.currentAction ?? bullets(nextActions); @@ -68720,7 +68725,7 @@ async function buildTaskContextPackage(deps3, input) { freshness: "EPHEMERAL" } ]; - const stored = readContextExpansionState(deps3.workspace, input.jobId, input.nodeId) ?? initialExpansionState({ taskId: node.parentTaskId, nodeId: input.nodeId, now: createdAt }); + const stored = readContextExpansionState(deps4.workspace, input.jobId, input.nodeId) ?? initialExpansionState({ taskId: node.parentTaskId, nodeId: input.nodeId, now: createdAt }); const expansion = input.attemptId !== void 0 ? beginAttemptExpansion(stored, createdAt) : stored; if (strategy === "LEGACY") { const result2 = await buildEfficientContext({ @@ -68741,7 +68746,7 @@ async function buildTaskContextPackage(deps3, input) { checkpointId: checkpoint?.checkpointId, checkpointSummaryItem: checkpoint !== void 0 ? checkpointSummaryItem(checkpoint, createdAt) : void 0 }).catch(rethrowBudget); - return persistAndReturn(deps3, input, { + return persistAndReturn(deps4, input, { job, node, checkpoint, @@ -68753,8 +68758,8 @@ async function buildTaskContextPackage(deps3, input) { }); } const indexed = ensureRepositoryIndex({ - workspace: deps3.workspace, - config: deps3.config, + workspace: deps4.workspace, + config: deps4.config, now: createdAt, gitSnapshot: snapshot2, ...input.rebuildIndex === true ? { rebuild: true } : {} @@ -68768,12 +68773,12 @@ async function buildTaskContextPackage(deps3, input) { objective: checkpoint?.objective ?? node.title, acceptanceCriteria: checkpoint?.pinned.acceptanceCriteria ?? [], currentAction: currentActionText, - failureText: latestFailureText(deps3, input.jobId, input.nodeId, node), - recoveryText: recoveryText(deps3, input.jobId, input.nodeId), - failureFingerprint: readTaskReliabilityState(deps3.workspace, input.jobId, input.nodeId)?.observations.at(-1)?.failureFingerprint ?? void 0, + failureText: latestFailureText(deps4, input.jobId, input.nodeId, node), + recoveryText: recoveryText(deps4, input.jobId, input.nodeId), + failureFingerprint: readTaskReliabilityState(deps4.workspace, input.jobId, input.nodeId)?.observations.at(-1)?.failureFingerprint ?? void 0, changedPaths: snapshot2.entries.map((entry2) => entry2.path.replace(/\\/g, "/")), checkpointChangedPaths: (checkpoint?.changedFiles ?? []).map((file) => file.path), - priorRelevantPaths: priorRelevantPaths(deps3, input.jobId, input.nodeId), + priorRelevantPaths: priorRelevantPaths(deps4, input.jobId, input.nodeId), expansionLevel: expansion.level }); const allocationPolicy = contextAllocationPolicySchema.parse({ @@ -68805,7 +68810,7 @@ async function buildTaskContextPackage(deps3, input) { executionMode: input.executionMode ?? null, runner: input.runner ?? null, index: indexed.index, - rootDir: deps3.workspace.rootDir, + rootDir: deps4.workspace.rootDir, query, rankOptions: { maxCandidates: policy.maxCandidates }, sectionOptions: { @@ -68827,7 +68832,7 @@ async function buildTaskContextPackage(deps3, input) { checkpointSummaryItem: checkpoint !== void 0 ? checkpointSummaryItem(checkpoint, createdAt) : void 0, contextExpansionsSoFar: expansion.expansionsThisTask }).catch(rethrowBudget); - return persistAndReturn(deps3, input, { + return persistAndReturn(deps4, input, { job, node, checkpoint, @@ -68854,13 +68859,13 @@ function rethrowBudget(cause) { } throw cause; } -function persistAndReturn(deps3, input, data) { +function persistAndReturn(deps4, input, data) { const { result } = data; if (input.persist !== false && data.strategy !== "LEGACY") { - writeContextSelectionPlan(deps3.workspace, result.plan); + writeContextSelectionPlan(deps4.workspace, result.plan); if (input.attemptId !== void 0) { - writeContextMetrics(deps3.workspace, input.jobId, input.attemptId, result.metrics); - writeContextExpansionState(deps3.workspace, input.jobId, input.nodeId, { + writeContextMetrics(deps4.workspace, input.jobId, input.attemptId, result.metrics); + writeContextExpansionState(deps4.workspace, input.jobId, input.nodeId, { ...data.expansion, lastWorkingSetTokens: result.metrics.workingSetTokens, baselineWorkingSetTokens: data.expansion.baselineWorkingSetTokens ?? result.metrics.workingSetTokens @@ -70049,22 +70054,22 @@ function evaluateRuntimeResearchTrigger(input) { } return { eligible: false, depth: "QUICK", reason: "no evidence-backed external knowledge trigger is present", repeatedCount: matching.length, materiallyDistinctStrategies: strategies }; } -function now3(deps3) { - return (deps3.clock ?? (() => /* @__PURE__ */ new Date()))(); +function now3(deps4) { + return (deps4.clock ?? (() => /* @__PURE__ */ new Date()))(); } -function newId3(deps3, prefix) { - const raw = (deps3.idFactory ?? (() => `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`))(); +function newId3(deps4, prefix) { + const raw = (deps4.idFactory ?? (() => `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`))(); return `${prefix}-${raw}`.replace(/[^A-Za-z0-9._-]/g, "-").slice(0, 64); } -function emit(deps3, type, payload) { - deps3.recordEvent?.(type, payload); +function emit(deps4, type, payload) { + deps4.recordEvent?.(type, payload); } -function recordEvaluation(deps3, result) { - const stored = writeEvaluationResult(deps3.workspace, result, { - maxRecords: deps3.policy.maxRecordsPerJob +function recordEvaluation(deps4, result) { + const stored = writeEvaluationResult(deps4.workspace, result, { + maxRecords: deps4.policy.maxRecordsPerJob }); emit( - deps3, + deps4, stored.status === "PASS" ? "evaluation_passed" : stored.status === "FAIL" ? "evaluation_failed" : "evaluation_inconclusive", { nodeId: stored.nodeId, @@ -70079,7 +70084,7 @@ function recordEvaluation(deps3, result) { } ); if (stored.semanticReviewRan) { - emit(deps3, "semantic_review_completed", { + emit(deps4, "semantic_review_completed", { nodeId: stored.nodeId, taskId: stored.taskId, attemptId: stored.attemptId, @@ -70089,10 +70094,10 @@ function recordEvaluation(deps3, result) { } return stored; } -function governFailedAttempt(deps3, input) { - const at = now3(deps3).toISOString(); +function governFailedAttempt(deps4, input) { + const at = now3(deps4).toISOString(); const previous = requireTaskReliabilityState( - deps3.workspace, + deps4.workspace, input.jobId, input.nodeId, input.taskId, @@ -70101,11 +70106,11 @@ function governFailedAttempt(deps3, input) { const runawaySignals = detectRunaway( input.activity, { - maxToolCallsPerAttempt: deps3.policy.maxToolCallsPerAttempt, - maxCommandRunsPerAttempt: deps3.policy.maxCommandRunsPerAttempt, - maxAttemptWallTimeMs: deps3.policy.maxAttemptWallTimeMs, - maxContextUsageRatio: deps3.policy.maxContextUsageRatio, - maxTestLoopsPerAttempt: deps3.policy.maxTestLoopsPerAttempt + maxToolCallsPerAttempt: deps4.policy.maxToolCallsPerAttempt, + maxCommandRunsPerAttempt: deps4.policy.maxCommandRunsPerAttempt, + maxAttemptWallTimeMs: deps4.policy.maxAttemptWallTimeMs, + maxContextUsageRatio: deps4.policy.maxContextUsageRatio, + maxTestLoopsPerAttempt: deps4.policy.maxTestLoopsPerAttempt }, previous.observations ); @@ -70132,17 +70137,17 @@ function governFailedAttempt(deps3, input) { const healthAssessment = assessHealth({ window, thresholds: { - sameFailureThreshold: deps3.policy.sameFailureThreshold, + sameFailureThreshold: deps4.policy.sameFailureThreshold, // The same-diff bound is the EXISTING no-progress budget, read from // its owner rather than duplicated under a reliability-specific name. sameDiffThreshold: input.budgets.maxNoProgressCycles, - oscillationThreshold: deps3.policy.oscillationThreshold + oscillationThreshold: deps4.policy.oscillationThreshold }, runawaySignals, passed: false }); if (healthAssessment.health === "RUNAWAY") { - emit(deps3, "execution_runaway", { + emit(deps4, "execution_runaway", { nodeId: input.nodeId, taskId: input.taskId, attemptId: input.attemptId, @@ -70151,7 +70156,7 @@ function governFailedAttempt(deps3, input) { detail: healthAssessment.reasons[0]?.slice(0, 300) ?? "the attempt exceeded its bounds" }); } else if (healthAssessment.health === "OSCILLATING") { - emit(deps3, "execution_oscillating", { + emit(deps4, "execution_oscillating", { nodeId: input.nodeId, taskId: input.taskId, attemptId: input.attemptId, @@ -70159,7 +70164,7 @@ function governFailedAttempt(deps3, input) { failureFingerprint: input.classified.fingerprint }); } else if (healthAssessment.health === "STALLED") { - emit(deps3, "execution_stalled", { + emit(deps4, "execution_stalled", { nodeId: input.nodeId, taskId: input.taskId, attemptId: input.attemptId, @@ -70181,10 +70186,10 @@ function governFailedAttempt(deps3, input) { ...input.contextInsufficiencySignals !== void 0 ? { contextInsufficiencySignals: input.contextInsufficiencySignals } : {} }); const assessment = writeFailureAssessment( - deps3.workspace, + deps4.workspace, failureAssessmentSchema.parse({ schemaVersion: FAILURE_ASSESSMENT_SCHEMA_VERSION, - assessmentId: newId3(deps3, "fa"), + assessmentId: newId3(deps4, "fa"), jobId: input.jobId, nodeId: input.nodeId, taskId: input.taskId, @@ -70205,9 +70210,9 @@ function governFailedAttempt(deps3, input) { evidenceRefs: [...input.evidenceRefs ?? []].slice(0, 40), createdAt: at }), - { maxRecords: deps3.policy.maxRecordsPerJob } + { maxRecords: deps4.policy.maxRecordsPerJob } ); - emit(deps3, "failure_assessed", { + emit(deps4, "failure_assessed", { nodeId: input.nodeId, taskId: input.taskId, attemptId: input.attemptId, @@ -70234,7 +70239,7 @@ function governFailedAttempt(deps3, input) { ...input.evaluation !== void 0 ? { evaluation: input.evaluation } : {}, health: healthAssessment.health, budget, - policy: deps3.policy, + policy: deps4.policy, lane: input.lane ?? null, executionMode: input.executionMode ?? null, planRevision: input.planRevision, @@ -70260,7 +70265,7 @@ function governFailedAttempt(deps3, input) { observations: window }); if (researchEligibility.eligible) { - emit(deps3, "runtime_research_eligible", { + emit(deps4, "runtime_research_eligible", { nodeId: input.nodeId, taskId: input.taskId, attemptId: input.attemptId, @@ -70273,10 +70278,10 @@ function governFailedAttempt(deps3, input) { }); } const decision = writeRecoveryDecision( - deps3.workspace, + deps4.workspace, recoveryDecisionSchema.parse({ schemaVersion: RECOVERY_DECISION_SCHEMA_VERSION, - decisionId: newId3(deps3, "rd"), + decisionId: newId3(deps4, "rd"), jobId: input.jobId, nodeId: input.nodeId, taskId: input.taskId, @@ -70298,10 +70303,10 @@ function governFailedAttempt(deps3, input) { applied: false, createdAt: at }), - { maxRecords: deps3.policy.maxRecordsPerJob } + { maxRecords: deps4.policy.maxRecordsPerJob } ); - emitDecisionEvents(deps3, input, decision, plan); - const state = writeTaskReliabilityState(deps3.workspace, { + emitDecisionEvents(deps4, input, decision, plan); + const state = writeTaskReliabilityState(deps4.workspace, { ...previous, health: healthAssessment.health, observations: window, @@ -70326,10 +70331,10 @@ function governFailedAttempt(deps3, input) { ...researchEligibility.eligible ? { researchEligibility } : {} }; } -function recordSuccessfulAttempt(deps3, input) { - const at = now3(deps3).toISOString(); +function recordSuccessfulAttempt(deps4, input) { + const at = now3(deps4).toISOString(); const previous = requireTaskReliabilityState( - deps3.workspace, + deps4.workspace, input.jobId, input.nodeId, input.taskId, @@ -70356,7 +70361,7 @@ function recordSuccessfulAttempt(deps3, input) { updatedAt: at }; delete next.pendingDecisionId; - return writeTaskReliabilityState(deps3.workspace, next); + return writeTaskReliabilityState(deps4.workspace, next); } function verificationBroken(evaluation) { if (evaluation === void 0) return false; @@ -70377,7 +70382,7 @@ function rememberStrategy(previous, plan, observation2) { const next = [...previous.exhaustedStrategies, key]; return next.length > RELIABILITY_LIMITS.maxListItems ? next.slice(next.length - RELIABILITY_LIMITS.maxListItems) : next; } -function emitDecisionEvents(deps3, input, decision, plan) { +function emitDecisionEvents(deps4, input, decision, plan) { const base = { nodeId: input.nodeId, taskId: input.taskId, @@ -70388,7 +70393,7 @@ function emitDecisionEvents(deps3, input, decision, plan) { health: decision.health, strategyChange: decision.strategyChange }; - emit(deps3, "recovery_decided", { + emit(deps4, "recovery_decided", { ...base, reason: decision.reason.slice(0, 300), remainingAttempts: decision.budgetSnapshot.attemptsMax - decision.budgetSnapshot.attemptsUsed, @@ -70397,10 +70402,10 @@ function emitDecisionEvents(deps3, input, decision, plan) { }); switch (plan.action) { case "RESTART_FRESH_CONTEXT": - emit(deps3, "fresh_context_selected", base); + emit(deps4, "fresh_context_selected", base); break; case "RETRY_DIFFERENT_LOCAL_MODE": - emit(deps3, "local_mode_recovery_selected", { + emit(deps4, "local_mode_recovery_selected", { ...base, fromMode: input.executionMode ?? "unknown", toMode: plan.nextStrategy.executionMode ?? "unknown" @@ -70408,7 +70413,7 @@ function emitDecisionEvents(deps3, input, decision, plan) { break; case "ESCALATE_INTELLIGENCE": case "ESCALATE_LANE": - emit(deps3, "lane_escalation_requested", { + emit(deps4, "lane_escalation_requested", { ...base, requestedKind: plan.requestedCapability?.kind ?? "STRONG", // Said explicitly in the timeline because it is the invariant most @@ -70417,23 +70422,23 @@ function emitDecisionEvents(deps3, input, decision, plan) { }); break; case "WAIT_FOR_RESOURCE": - emit(deps3, "resource_wait_selected", { + emit(deps4, "resource_wait_selected", { ...base, waitMs: plan.waitMs ?? null }); break; case "FAIL_TASK": - emit(deps3, "recovery_budget_exhausted", { + emit(deps4, "recovery_budget_exhausted", { ...base, budgetSnapshot: decision.budgetSnapshot }); - emit(deps3, "task_blocked_after_recovery", { + emit(deps4, "task_blocked_after_recovery", { ...base, remediation: decision.remediation.slice(0, 5) }); break; case "BLOCK": - emit(deps3, "task_blocked_after_recovery", { + emit(deps4, "task_blocked_after_recovery", { ...base, remediation: decision.remediation.slice(0, 5) }); @@ -70442,17 +70447,17 @@ function emitDecisionEvents(deps3, input, decision, plan) { break; } } -function policyOf2(deps3) { - return deps3.config.orchestration.jobs; +function policyOf2(deps4) { + return deps4.config.orchestration.jobs; } -function now4(deps3) { - return (deps3.clock ?? systemClock)(); +function now4(deps4) { + return (deps4.clock ?? systemClock)(); } -function newId4(deps3) { - return (deps3.idFactory ?? import_crypto19.randomUUID)(); +function newId4(deps4) { + return (deps4.idFactory ?? import_crypto19.randomUUID)(); } -function assertJobsEnabled(deps3) { - if (policyOf2(deps3).enabled) return; +function assertJobsEnabled(deps4) { + if (policyOf2(deps4).enabled) return; throw new OrchestrationError( "SBO025", "Job orchestration is disabled by `orchestration.jobs.enabled` in .specbridge/config.json.", @@ -70468,8 +70473,8 @@ function planTextOf(plan) { ).filter((description) => description.length > 0); return [goal, ...descriptions].join("\n").slice(0, 4e3); } -function record22(deps3, job, type, payload = {}) { - const stored = countJobEvents(deps3.workspace, job.jobId); +function record22(deps4, job, type, payload = {}) { + const stored = countJobEvents(deps4.workspace, job.jobId); if (stored >= job.budgets.maxEvents) { throw new OrchestrationError( "SBO020", @@ -70481,16 +70486,16 @@ function record22(deps3, job, type, payload = {}) { ); } appendJobEvent( - deps3.workspace, + deps4.workspace, job.jobId, - { at: now4(deps3).toISOString(), type, ...payload }, - { maxEventBytes: deps3.config.orchestration.history.maxEventBytes } + { at: now4(deps4).toISOString(), type, ...payload }, + { maxEventBytes: deps4.config.orchestration.history.maxEventBytes } ); return { ...job, counters: { ...job.counters, events: stored + 1 } }; } -function transition22(deps3, job, to) { +function transition22(deps4, job, to) { assertJobTransition(job.status, to); - const at = now4(deps3).toISOString(); + const at = now4(deps4).toISOString(); const wasWaiting = requiresHumanAttention(job.status); const willWait = requiresHumanAttention(to); if (!wasWaiting && willWait) { @@ -70498,7 +70503,7 @@ function transition22(deps3, job, to) { } if (wasWaiting && !willWait) { const since = job.humanWaitSince === void 0 ? void 0 : Date.parse(job.humanWaitSince); - const banked = since === void 0 || Number.isNaN(since) ? 0 : Math.max(0, now4(deps3).getTime() - since); + const banked = since === void 0 || Number.isNaN(since) ? 0 : Math.max(0, now4(deps4).getTime() - since); const { humanWaitSince: _stopped, ...rest } = job; return { ...rest, @@ -70512,19 +70517,19 @@ function transition22(deps3, job, to) { } return { ...job, status: to, updatedAt: at }; } -function persist22(deps3, job) { - return writeJobState(deps3.workspace, { ...job, updatedAt: now4(deps3).toISOString() }); +function persist22(deps4, job) { + return writeJobState(deps4.workspace, { ...job, updatedAt: now4(deps4).toISOString() }); } -function persistGraph(deps3, job, graph) { - const existing = readGraphRevision(deps3.workspace, job.jobId, graph.revision); +function persistGraph(deps4, job, graph) { + const existing = readGraphRevision(deps4.workspace, job.jobId, graph.revision); if (existing === void 0) { - return storeGraphRevision(deps3.workspace, job.jobId, graph).graph; + return storeGraphRevision(deps4.workspace, job.jobId, graph).graph; } const validated = jobGraphSchema.parse(graph); const file = assertInsideWorkspace( - deps3.workspace.rootDir, + deps4.workspace.rootDir, import_path35.default.join( - jobDir(deps3.workspace, job.jobId), + jobDir(deps4.workspace, job.jobId), "graphs", `${String(validated.revision).padStart(4, "0")}.json` ) @@ -70534,26 +70539,26 @@ function persistGraph(deps3, job, graph) { `); return validated; } -function createJob(deps3, request) { - assertJobsEnabled(deps3); - const policy = policyOf2(deps3); +function createJob(deps4, request) { + assertJobsEnabled(deps4); + const policy = policyOf2(deps4); const goal = request.goal.trim(); if (goal.length === 0) { throw new OrchestrationError("SBO006", "A job needs a stated goal.", { remediation: ["Describe what should be accomplished, in one or two sentences."] }); } - const createdAt = now4(deps3).toISOString(); + const createdAt = now4(deps4).toISOString(); const job = { schemaVersion: JOB_STATE_SCHEMA_VERSION, - jobId: `job-${newId4(deps3)}`, + jobId: `job-${newId4(deps4)}`, specName: request.specName, status: "CREATED", goal: goal.slice(0, 4e3), createdAt, updatedAt: createdAt, - host: deps3.host ?? "cli", - policyFingerprint: jobPolicyFingerprint(deps3.config.orchestration), + host: deps4.host ?? "cli", + policyFingerprint: jobPolicyFingerprint(deps4.config.orchestration), budgets: { maxAgentRuns: policy.budgets.maxAgentRuns, maxTaskAttempts: policy.budgets.maxTaskAttempts, @@ -70586,24 +70591,24 @@ function createJob(deps3, request) { decisions: [], escalations: [] }; - initializeJobRecord(deps3.workspace, job); - const recorded = record22(deps3, job, "job_created", { specName: job.specName }); - return persist22(deps3, recorded); + initializeJobRecord(deps4.workspace, job); + const recorded = record22(deps4, job, "job_created", { specName: job.specName }); + return persist22(deps4, recorded); } -async function buildJobGraph(deps3, jobId) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); +async function buildJobGraph(deps4, jobId) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); if (job.status !== "CREATED") { throw new OrchestrationError("SBO027", `The graph is built exactly once, from CREATED (job is ${job.status}).`); } - const snapshot2 = await captureGitSnapshot(deps3.workspace.rootDir, { clock: () => now4(deps3) }); - const built = buildInitialGraph(deps3.workspace, { + const snapshot2 = await captureGitSnapshot(deps4.workspace.rootDir, { clock: () => now4(deps4) }); + const built = buildInitialGraph(deps4.workspace, { jobId, specName: job.specName, - createdAt: now4(deps3).toISOString(), + createdAt: now4(deps4).toISOString(), gitHead: snapshot2.head }); - const policy = policyOf2(deps3); + const policy = policyOf2(deps4); const graph = { ...built.graph, nodes: built.graph.nodes.map((node) => { @@ -70617,16 +70622,16 @@ async function buildJobGraph(deps3, jobId) { }; }) }; - storeGraphRevision(deps3.workspace, jobId, graph); + storeGraphRevision(deps4.workspace, jobId, graph); job = { ...job, graphRevision: graph.revision, currentNodeId: graph.nodes[0]?.nodeId }; - job = transition22(deps3, job, "PLANNING"); - job = record22(deps3, job, "graph_created", { + job = transition22(deps4, job, "PLANNING"); + job = record22(deps4, job, "graph_created", { revision: graph.revision, nodes: graph.nodes.length, ...built.skippedCompleted.length > 0 ? { skippedCompleted: built.skippedCompleted.length } : {} }); - job = transition22(deps3, job, "READY"); - return { job: persist22(deps3, job), graph }; + job = transition22(deps4, job, "READY"); + return { job: persist22(deps4, job), graph }; } function complexityInputFor(node) { return { @@ -70638,18 +70643,18 @@ function complexityInputFor(node) { previousReplanCount: node.replans }; } -function activeGraph(deps3, job) { +function activeGraph(deps4, job) { if (job.graphRevision === 0) return void 0; - return requireGraphRevision(deps3.workspace, job.jobId, job.graphRevision); + return requireGraphRevision(deps4.workspace, job.jobId, job.graphRevision); } -function appendAttempt(deps3, job, graph, context, outcome, extras = {}) { +function appendAttempt(deps4, job, graph, context, outcome, extras = {}) { const node = requireNode(graph, context.nodeId); const attempt = { attempt: node.attempts.length + 1, role: context.role, workerId: context.workerId, startedAt: context.startedAt, - finishedAt: now4(deps3).toISOString(), + finishedAt: now4(deps4).toISOString(), outcome, ...context.agentResultRef !== void 0 ? { agentResultRef: context.agentResultRef } : {}, ...context.runId !== void 0 ? { runId: context.runId } : {}, @@ -70671,8 +70676,8 @@ function appendAttempt(deps3, job, graph, context, outcome, extras = {}) { }; return { job: nextJob, graph: nextGraph }; } -function recordEscalation(deps3, job, input) { - const at = now4(deps3).toISOString(); +function recordEscalation(deps4, job, input) { + const at = now4(deps4).toISOString(); const entry2 = { at, ...input.nodeId !== void 0 ? { nodeId: input.nodeId } : {}, @@ -70685,32 +70690,32 @@ function recordEscalation(deps3, job, input) { escalations: [...job.escalations, entry2].slice(-100), counters: { ...job.counters, escalations: job.counters.escalations + 1 } }; - next = record22(deps3, next, "worker_escalated", { + next = record22(deps4, next, "worker_escalated", { ...input.nodeId !== void 0 ? { nodeId: input.nodeId } : {}, role: input.role, reason: input.reason }); return next; } -function beginPlanning(deps3, jobId, nodeId) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); +function beginPlanning(deps4, jobId, nodeId) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); if (job.status === "PLANNING") return job; - job = transition22(deps3, job, "PLANNING"); + job = transition22(deps4, job, "PLANNING"); job = { ...job, currentNodeId: nodeId }; - job = record22(deps3, job, "planning_started", { nodeId }); - return persist22(deps3, job); -} -function recordRoleFailure(deps3, jobId, input) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); - let graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); - ({ job, graph } = appendAttempt(deps3, job, graph, input.context, input.outcome, { + job = record22(deps4, job, "planning_started", { nodeId }); + return persist22(deps4, job); +} +function recordRoleFailure(deps4, jobId, input) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); + let graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); + ({ job, graph } = appendAttempt(deps4, job, graph, input.context, input.outcome, { ...input.failureCategory !== void 0 ? { failureCategory: input.failureCategory } : {}, ...input.escalation !== void 0 ? { escalationReason: input.escalation.reason } : {} })); if (input.escalation !== void 0) { - job = recordEscalation(deps3, job, { + job = recordEscalation(deps4, job, { nodeId: input.context.nodeId, role: input.context.role, reason: input.escalation.reason, @@ -70718,38 +70723,38 @@ function recordRoleFailure(deps3, jobId, input) { }); } if (job.status === "PLANNING") { - job = transition22(deps3, job, "READY"); + job = transition22(deps4, job, "READY"); } - persistGraph(deps3, job, graph); - return persist22(deps3, job); + persistGraph(deps4, job, graph); + return persist22(deps4, job); } -function recordClassification(deps3, jobId, result) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); - let graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); +function recordClassification(deps4, jobId, result) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); + let graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); const node = requireNode(graph, result.context.nodeId); const deterministic = node.complexity ?? "LOW"; const effective = mergeComplexity(deterministic, result.proposedClass); - ({ job, graph } = appendAttempt(deps3, job, graph, result.context, "succeeded")); + ({ job, graph } = appendAttempt(deps4, job, graph, result.context, "succeeded")); graph = withNode(graph, { ...requireNode(graph, node.nodeId), complexity: effective, complexitySignals: effective !== deterministic ? [...node.complexitySignals, `classifier-raised(${deterministic}->${effective})`] : node.complexitySignals }); - job = record22(deps3, job, "classification_completed", { + job = record22(deps4, job, "classification_completed", { nodeId: node.nodeId, deterministic, proposed: result.proposedClass, effective }); - persistGraph(deps3, job, graph); - return { job: persist22(deps3, job), effectiveClass: effective }; + persistGraph(deps4, job, graph); + return { job: persist22(deps4, job), effectiveClass: effective }; } -async function recordPlan(deps3, jobId, result, options = {}) { - assertJobsEnabled(deps3); - const policy = policyOf2(deps3); - let job = requireJobState(deps3.workspace, jobId); - let graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); +async function recordPlan(deps4, jobId, result, options = {}) { + assertJobsEnabled(deps4); + const policy = policyOf2(deps4); + let job = requireJobState(deps4.workspace, jobId); + let graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); const node = requireNode(graph, result.context.nodeId); if (options.replan === true) { if (node.replans >= job.budgets.maxReplansPerTask) { @@ -70767,11 +70772,11 @@ async function recordPlan(deps3, jobId, result, options = {}) { ); } } - const gitHead = options.gitHead ?? (await captureGitSnapshot(deps3.workspace.rootDir, { clock: () => now4(deps3) })).head; - const binding = capturePlanBinding(deps3.workspace, { + const gitHead = options.gitHead ?? (await captureGitSnapshot(deps4.workspace.rootDir, { clock: () => now4(deps4) })).head; + const binding = capturePlanBinding(deps4.workspace, { specName: job.specName, taskId: node.parentTaskId, - policy: deps3.config.orchestration, + policy: deps4.config.orchestration, gitHead }); const revision = node.planRevision + 1; @@ -70781,15 +70786,15 @@ async function recordPlan(deps3, jobId, result, options = {}) { binding, revision, planId: `${node.nodeId}-p${revision}`, - createdAt: now4(deps3).toISOString(), - policy: deps3.config.orchestration + createdAt: now4(deps4).toISOString(), + policy: deps4.config.orchestration }); - storeNodePlan(deps3.workspace, jobId, node.nodeId, revision, plan); - ({ job, graph } = appendAttempt(deps3, job, graph, result.context, "succeeded")); + storeNodePlan(deps4.workspace, jobId, node.nodeId, revision, plan); + ({ job, graph } = appendAttempt(deps4, job, graph, result.context, "succeeded")); const criticApplies = policy.routing.critic !== "disabled" && result.producedByTier === "LOCAL_SMALL"; const complexity = requireNode(graph, node.nodeId).complexity ?? "LOW"; const policyRequiresReview = policy.planReview === "always" || policy.planReview === "high-risk" && complexity === "HIGH"; - const review = resolvePlanReviewRequirement(deps3.authorityResolver, { + const review = resolvePlanReviewRequirement(deps4.authorityResolver, { jobId, nodeId: node.nodeId, policyRequiresReview, @@ -70817,9 +70822,9 @@ ${result.candidate.steps.map((step2) => step2.description).join("\n")}` graph = withNode(graph, withoutVerdict); if (options.replan === true) { job = { ...job, counters: { ...job.counters, jobReplans: job.counters.jobReplans + 1 } }; - job = record22(deps3, job, "replan_started", { nodeId: node.nodeId, revision }); + job = record22(deps4, job, "replan_started", { nodeId: node.nodeId, revision }); } - job = record22(deps3, job, "plan_created", { + job = record22(deps4, job, "plan_created", { nodeId: node.nodeId, revision, producedByTier: result.producedByTier, @@ -70827,21 +70832,21 @@ ${result.candidate.steps.map((step2) => step2.description).join("\n")}` humanReview }); if (job.status === "PLANNING" || job.status === "REPLANNING") { - job = transition22(deps3, job, "READY"); + job = transition22(deps4, job, "READY"); } - persistGraph(deps3, job, graph); - return { job: persist22(deps3, job), plan }; + persistGraph(deps4, job, graph); + return { job: persist22(deps4, job), plan }; } -function recordCriticVerdict(deps3, jobId, result) { - assertJobsEnabled(deps3); - const policy = policyOf2(deps3); - let job = requireJobState(deps3.workspace, jobId); - let graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); +function recordCriticVerdict(deps4, jobId, result) { + assertJobsEnabled(deps4); + const policy = policyOf2(deps4); + let job = requireJobState(deps4.workspace, jobId); + let graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); const node = requireNode(graph, result.context.nodeId); - ({ job, graph } = appendAttempt(deps3, job, graph, result.context, "succeeded")); - const activePlan = readNodePlan(deps3.workspace, jobId, node.nodeId, node.planRevision); + ({ job, graph } = appendAttempt(deps4, job, graph, result.context, "succeeded")); + const activePlan = readNodePlan(deps4.workspace, jobId, node.nodeId, node.planRevision); const policyRequiresReview = policy.planReview === "always" || policy.planReview === "high-risk" && (node.complexity ?? "LOW") === "HIGH"; - const humanReview = resolvePlanReviewRequirement(deps3.authorityResolver, { + const humanReview = resolvePlanReviewRequirement(deps4.authorityResolver, { jobId, nodeId: node.nodeId, policyRequiresReview, @@ -70856,66 +70861,66 @@ function recordCriticVerdict(deps3, jobId, result) { planApproved: accepted && !humanReview, humanReviewRequired: accepted ? humanReview : false }); - job = record22(deps3, job, "critic_completed", { + job = record22(deps4, job, "critic_completed", { nodeId: node.nodeId, planRevision: node.planRevision, verdict: result.verdict, reasons: result.reasons.slice(0, 10).map((reason3) => reason3.slice(0, 200)) }); if (result.verdict === "REVISE" || result.verdict === "ESCALATE") { - job = transition22(deps3, job, "PLANNING"); + job = transition22(deps4, job, "PLANNING"); } - persistGraph(deps3, job, graph); + persistGraph(deps4, job, graph); return { - job: persist22(deps3, job), + job: persist22(deps4, job), verdict: result.verdict, humanReviewRequired: accepted ? humanReview : false }; } -function noteEscalation(deps3, jobId, input) { - let job = requireJobState(deps3.workspace, jobId); +function noteEscalation(deps4, jobId, input) { + let job = requireJobState(deps4.workspace, jobId); const already = job.escalations.some( (entry2) => entry2.nodeId === input.nodeId && entry2.reason === input.reason ); if (already) return job; - job = recordEscalation(deps3, job, input); - return persist22(deps3, job); + job = recordEscalation(deps4, job, input); + return persist22(deps4, job); } -function completeJobIfDone(deps3, jobId) { - let job = requireJobState(deps3.workspace, jobId); +function completeJobIfDone(deps4, jobId) { + let job = requireJobState(deps4.workspace, jobId); if (isFinalJobStatus(job.status)) return job; - const graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); + const graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); if (!allNodesComplete(graph)) { throw new OrchestrationError("SBO027", "The job cannot complete: unfinished nodes remain."); } - const closure = assessCompletion(deps3.completionGate, jobId); + const closure = assessCompletion(deps4.completionGate, jobId); if (closure !== void 0 && !closure.mayComplete) { if (job.status === "QUALIFYING") { return job; } - job = transition22(deps3, job, "QUALIFYING"); - job = record22(deps3, job, "closure_audit_completed", { + job = transition22(deps4, job, "QUALIFYING"); + job = record22(deps4, job, "closure_audit_completed", { directive: "CONTRACT_CLOSURE_AUDIT", unclosed: closure.unclosed, reason: closure.reason.slice(0, 500) }); - return persist22(deps3, { ...job, closurePhase: "CONTRACT_CLOSURE_AUDIT" }); + return persist22(deps4, { ...job, closurePhase: "CONTRACT_CLOSURE_AUDIT" }); } - const at = now4(deps3).toISOString(); - job = transition22(deps3, job, "COMPLETED"); - job = record22(deps3, job, "job_completed", { + const at = now4(deps4).toISOString(); + job = transition22(deps4, job, "COMPLETED"); + job = record22(deps4, job, "job_completed", { reconciled: true, ...closure !== void 0 ? { closure: closure.reason.slice(0, 300) } : {} }); - return persist22(deps3, { ...job, finalizedAt: at, finalOutcome: "COMPLETED" }); + return persist22(deps4, { ...job, finalizedAt: at, finalOutcome: "COMPLETED" }); } -function recordJobEvent(deps3, jobId, type, payload = {}) { - let job = requireJobState(deps3.workspace, jobId); - job = record22(deps3, job, type, payload); - return persist22(deps3, job); +function recordJobEvent(deps4, jobId, type, payload = {}) { + let job = requireJobState(deps4.workspace, jobId); + job = record22(deps4, job, type, payload); + return persist22(deps4, job); } -function applyJobTransition(deps3, jobId, input) { - let job = requireJobState(deps3.workspace, jobId); +function applyJobTransition(deps4, jobId, input) { + let job = requireJobState(deps4.workspace, jobId); if (isFinalJobStatus(job.status)) { throw new OrchestrationError( "SBO026", @@ -70923,14 +70928,14 @@ function applyJobTransition(deps3, jobId, input) { { details: { from: job.status, to: input.to } } ); } - if (job.status !== input.to) job = transition22(deps3, job, input.to); - job = record22(deps3, job, input.event, input.payload ?? {}); - return persist22(deps3, { ...job, ...input.patch ?? {} }); + if (job.status !== input.to) job = transition22(deps4, job, input.to); + job = record22(deps4, job, input.event, input.payload ?? {}); + return persist22(deps4, { ...job, ...input.patch ?? {} }); } -function reviewNodePlan(deps3, jobId, input) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); - let graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); +function reviewNodePlan(deps4, jobId, input) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); + let graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); const node = requireNode(graph, input.nodeId); if (!node.humanReviewRequired) { throw new OrchestrationError("SBO012", `Node ${input.nodeId} has no pending human plan review.`); @@ -70940,7 +70945,7 @@ function reviewNodePlan(deps3, jobId, input) { planApproved: input.decision === "approved", humanReviewRequired: input.decision === "approved" ? false : true }); - job = record22(deps3, job, "plan_reviewed", { + job = record22(deps4, job, "plan_reviewed", { nodeId: node.nodeId, planRevision: node.planRevision, decision: input.decision, @@ -70948,22 +70953,22 @@ function reviewNodePlan(deps3, jobId, input) { }); if (input.decision === "rejected") { graph = withNode(graph, { ...requireNode(graph, node.nodeId), humanReviewRequired: false }); - if (job.status === "READY") job = transition22(deps3, job, "PLANNING"); + if (job.status === "READY") job = transition22(deps4, job, "PLANNING"); } - persistGraph(deps3, job, graph); - return persist22(deps3, job); + persistGraph(deps4, job, graph); + return persist22(deps4, job); } -function beginExecutorDispatch(deps3, jobId, input) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); - let graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); +function beginExecutorDispatch(deps4, jobId, input) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); + let graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); const node = requireNode(graph, input.nodeId); graph = transitionNode(graph, node.nodeId, input.mode === "repair" ? "REPAIRING" : "RUNNING"); - job = transition22(deps3, job, input.mode === "repair" ? "REPAIRING" : "RUNNING"); - const priorAttempts = listTaskAttempts(deps3.workspace, jobId, { nodeId: node.nodeId }); + job = transition22(deps4, job, input.mode === "repair" ? "REPAIRING" : "RUNNING"); + const priorAttempts = listTaskAttempts(deps4.workspace, jobId, { nodeId: node.nodeId }); const lineageParent = [...priorAttempts].reverse().find((prior) => isFinalAttemptStatus(prior.status)); const attempt = beginTaskAttempt( - { workspace: deps3.workspace, clock: deps3.clock, idFactory: deps3.idFactory }, + { workspace: deps4.workspace, clock: deps4.clock, idFactory: deps4.idFactory }, { jobId, nodeId: node.nodeId, @@ -71001,13 +71006,13 @@ function beginExecutorDispatch(deps3, jobId, input) { } ); job = { ...job, currentNodeId: node.nodeId, currentAttemptId: attempt.attemptId }; - job = record22(deps3, job, input.mode === "repair" ? "repair_started" : "execution_started", { + job = record22(deps4, job, input.mode === "repair" ? "repair_started" : "execution_started", { nodeId: node.nodeId, taskId: node.parentTaskId, workerId: input.workerId, ...input.mode === "repair" ? { cycle: node.repairCycles + 1 } : {} }); - job = record22(deps3, job, "attempt_started", { + job = record22(deps4, job, "attempt_started", { nodeId: node.nodeId, taskId: node.parentTaskId, attemptId: attempt.attemptId, @@ -71015,13 +71020,13 @@ function beginExecutorDispatch(deps3, jobId, input) { provider: attempt.provider, ...attempt.resumedFromAttemptId !== void 0 ? { resumedFromAttemptId: attempt.resumedFromAttemptId } : {} }); - persistGraph(deps3, job, graph); - return persist22(deps3, job); + persistGraph(deps4, job, graph); + return persist22(deps4, job); } -function yieldExecutorForResourceWait(deps3, jobId, input) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); - let graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); +function yieldExecutorForResourceWait(deps4, jobId, input) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); + let graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); const node = requireNode(graph, input.nodeId); if (node.status !== "RUNNING" && node.status !== "REPAIRING") { throw new OrchestrationError( @@ -71030,10 +71035,10 @@ function yieldExecutorForResourceWait(deps3, jobId, input) { ); } if (job.currentAttemptId !== void 0) { - const attempt = readTaskAttempt(deps3.workspace, jobId, job.currentAttemptId); + const attempt = readTaskAttempt(deps4.workspace, jobId, job.currentAttemptId); if (attempt !== void 0 && !isFinalAttemptStatus(attempt.status)) { completeTaskAttempt( - { workspace: deps3.workspace, clock: deps3.clock, idFactory: deps3.idFactory }, + { workspace: deps4.workspace, clock: deps4.clock, idFactory: deps4.idFactory }, { jobId, attemptId: attempt.attemptId, @@ -71042,7 +71047,7 @@ function yieldExecutorForResourceWait(deps3, jobId, input) { } ); } - job = record22(deps3, job, "attempt_completed", { + job = record22(deps4, job, "attempt_completed", { nodeId: node.nodeId, taskId: node.parentTaskId, attemptId: job.currentAttemptId, @@ -71052,16 +71057,16 @@ function yieldExecutorForResourceWait(deps3, jobId, input) { }); } graph = transitionNode(graph, node.nodeId, "READY"); - job = transition22(deps3, job, "READY"); + job = transition22(deps4, job, "READY"); job = { ...job, currentAttemptId: void 0, currentNodeId: node.nodeId }; - persistGraph(deps3, job, graph); - return persist22(deps3, job); + persistGraph(deps4, job, graph); + return persist22(deps4, job); } -function buildAttemptEvaluation(deps3, job, node, outcome, attemptId, lane, at) { +function buildAttemptEvaluation(deps4, job, node, outcome, attemptId, lane, at) { const input = outcome.reliability; const status = outcome.evidenceStatus; const verified = status === "verified" || status === "manually-accepted"; @@ -71112,7 +71117,7 @@ function buildAttemptEvaluation(deps3, job, node, outcome, attemptId, lane, at) }; const criteria = input?.acceptanceCriteria !== void 0 && input.criteriaEvidence !== void 0 ? evaluateAcceptanceCriteria(input.acceptanceCriteria, input.criteriaEvidence) : { checks: [], failedCriteria: [], uncheckedCriteria: [] }; return evaluateAttempt({ - evaluationId: `ev-${newId4(deps3)}`.slice(0, 64), + evaluationId: `ev-${newId4(deps4)}`.slice(0, 64), jobId: job.jobId, nodeId: node.nodeId, taskId: node.parentTaskId, @@ -71156,37 +71161,37 @@ function attemptActivity(outcome, startedAt, at) { function numeric(value) { return typeof value === "number" && Number.isFinite(value) ? value : null; } -function reliabilityDepsFor(deps3, jobId) { +function reliabilityDepsFor(deps4, jobId) { return { - workspace: deps3.workspace, - policy: policyOf2(deps3).reliability, - ...deps3.clock !== void 0 ? { clock: deps3.clock } : {}, - ...deps3.idFactory !== void 0 ? { idFactory: deps3.idFactory } : {}, + workspace: deps4.workspace, + policy: policyOf2(deps4).reliability, + ...deps4.clock !== void 0 ? { clock: deps4.clock } : {}, + ...deps4.idFactory !== void 0 ? { idFactory: deps4.idFactory } : {}, recordEvent: (type, payload) => { try { - recordJobEvent(deps3, jobId, type, payload); + recordJobEvent(deps4, jobId, type, payload); } catch { } } }; } -function pendingRecoveryDecision(deps3, jobId, nodeId) { - if (!policyOf2(deps3).reliability.enabled) return void 0; - const state = readTaskReliabilityState(deps3.workspace, jobId, nodeId); +function pendingRecoveryDecision(deps4, jobId, nodeId) { + if (!policyOf2(deps4).reliability.enabled) return void 0; + const state = readTaskReliabilityState(deps4.workspace, jobId, nodeId); const decisionId = state?.pendingDecisionId; if (decisionId === void 0) return void 0; - const decision = readRecoveryDecision(deps3.workspace, jobId, decisionId); + const decision = readRecoveryDecision(deps4.workspace, jobId, decisionId); return decision !== void 0 && !decision.applied ? decision : void 0; } -function applyRecoveryDecision(deps3, input) { +function applyRecoveryDecision(deps4, input) { const { decision, node, at } = input; let job = input.job; const graph = input.graph; - const retryDelayMs = policyOf2(deps3).retryDelayMs; + const retryDelayMs = policyOf2(deps4).retryDelayMs; const finish5 = (next, nextAction) => { - persistGraph(deps3, next, graph); + persistGraph(deps4, next, graph); return { - job: persist22(deps3, next), + job: persist22(deps4, next), nextAction, classified: input.classified, evaluation: input.evaluation, @@ -71199,13 +71204,13 @@ function applyRecoveryDecision(deps3, input) { baseBackoffMs: Math.max(retryDelayMs, 1), maxBackoffMs: Math.max(retryDelayMs * 16, retryDelayMs) }); - job = transition22(deps3, job, "WAITING_RETRY"); + job = transition22(deps4, job, "WAITING_RETRY"); job = { ...job, - retryAt: new Date(now4(deps3).getTime() + backoffMs).toISOString(), + retryAt: new Date(now4(deps4).getTime() + backoffMs).toISOString(), counters: { ...job.counters, transientRetries: job.counters.transientRetries + 1 } }; - job = record22(deps3, job, "waiting_retry", { + job = record22(deps4, job, "waiting_retry", { nodeId: node.nodeId, category: input.classified.category, retryAt: job.retryAt, @@ -71217,9 +71222,9 @@ function applyRecoveryDecision(deps3, input) { const elapsed = Math.max(0, Date.parse(at) - Date.parse(job.createdAt)); const remaining = Math.max(0, job.budgets.maxWallClockMs - elapsed); const waitMs = Math.min(Math.max(retryDelayMs, 6e4), Math.max(remaining, retryDelayMs)); - job = transition22(deps3, job, "WAITING_RETRY"); - job = { ...job, retryAt: new Date(now4(deps3).getTime() + waitMs).toISOString() }; - job = record22(deps3, job, "waiting_retry", { + job = transition22(deps4, job, "WAITING_RETRY"); + job = { ...job, retryAt: new Date(now4(deps4).getTime() + waitMs).toISOString() }; + job = record22(deps4, job, "waiting_retry", { nodeId: node.nodeId, retryAt: job.retryAt, reasonCode: decision.reasonCode, @@ -71228,17 +71233,17 @@ function applyRecoveryDecision(deps3, input) { return finish5(job, "wait-retry"); } case "REPAIR": { - job = transition22(deps3, job, "DIAGNOSING"); + job = transition22(deps4, job, "DIAGNOSING"); return finish5(job, "diagnose"); } case "REPLAN": { - job = transition22(deps3, job, "DIAGNOSING"); + job = transition22(deps4, job, "DIAGNOSING"); return finish5(job, "diagnose"); } case "RESTART_FRESH_CONTEXT": { - job = transition22(deps3, job, "READY"); + job = transition22(deps4, job, "READY"); job = { ...job, currentNodeId: node.nodeId }; - job = record22(deps3, job, "context_threshold_reached", { + job = record22(deps4, job, "context_threshold_reached", { nodeId: node.nodeId, taskId: node.parentTaskId, decisionId: decision.decisionId, @@ -71247,9 +71252,9 @@ function applyRecoveryDecision(deps3, input) { return finish5(job, "retry-strategy-change"); } case "EXPAND_CONTEXT": { - job = transition22(deps3, job, "READY"); + job = transition22(deps4, job, "READY"); job = { ...job, currentNodeId: node.nodeId }; - job = record22(deps3, job, "context_threshold_reached", { + job = record22(deps4, job, "context_threshold_reached", { nodeId: node.nodeId, taskId: node.parentTaskId, decisionId: decision.decisionId, @@ -71259,9 +71264,9 @@ function applyRecoveryDecision(deps3, input) { return finish5(job, "retry-strategy-change"); } case "RETRY_DIFFERENT_LOCAL_MODE": { - job = transition22(deps3, job, "READY"); + job = transition22(deps4, job, "READY"); job = { ...job, currentNodeId: node.nodeId }; - job = recordEscalation(deps3, job, { + job = recordEscalation(deps4, job, { nodeId: node.nodeId, role: "EXECUTOR", reason: "LOCAL_DIRECT_TO_HARNESS", @@ -71271,9 +71276,9 @@ function applyRecoveryDecision(deps3, input) { } case "ESCALATE_INTELLIGENCE": case "ESCALATE_LANE": { - job = transition22(deps3, job, "READY"); + job = transition22(deps4, job, "READY"); job = { ...job, currentNodeId: node.nodeId }; - job = recordEscalation(deps3, job, { + job = recordEscalation(deps4, job, { nodeId: node.nodeId, role: "EXECUTOR", reason: decision.health === "STALLED" || decision.health === "OSCILLATING" ? "NO_PROGRESS" : "LOCAL_EXECUTION_ESCALATED", @@ -71282,9 +71287,9 @@ function applyRecoveryDecision(deps3, input) { return finish5(job, "retry-strategy-change"); } case "REQUEST_HUMAN_DECISION": { - job = transition22(deps3, job, "NEEDS_CLARIFICATION"); + job = transition22(deps4, job, "NEEDS_CLARIFICATION"); const question = { - id: `q-${newId4(deps3)}`.slice(0, 64), + id: `q-${newId4(deps4)}`.slice(0, 64), question: `Task ${node.parentTaskId} cannot proceed automatically: ${decision.reason.slice(0, 600)} Decide explicitly, then resume the job.`, whyItMatters: `${decision.reasonCode} has no safe automatic response.`, options: [], @@ -71292,7 +71297,7 @@ function applyRecoveryDecision(deps3, input) { askedAt: at, round: Math.min( job.counters.clarificationRounds + 1, - deps3.config.orchestration.clarification.maxRounds + deps4.config.orchestration.clarification.maxRounds ) }; job = { @@ -71300,7 +71305,7 @@ function applyRecoveryDecision(deps3, input) { openQuestions: [...job.openQuestions, question], counters: { ...job.counters, clarificationRounds: question.round } }; - job = record22(deps3, job, "clarification_requested", { + job = record22(deps4, job, "clarification_requested", { nodeId: node.nodeId, category: input.classified.category, reasonCode: decision.reasonCode @@ -71318,10 +71323,10 @@ function applyRecoveryDecision(deps3, input) { } } } -function finalizeDispatchAttempt(deps3, job, node, outcome, status) { - const survivalDeps = { workspace: deps3.workspace, clock: deps3.clock, idFactory: deps3.idFactory }; +function finalizeDispatchAttempt(deps4, job, node, outcome, status) { + const survivalDeps = { workspace: deps4.workspace, clock: deps4.clock, idFactory: deps4.idFactory }; let attemptId = job.currentAttemptId; - if (attemptId === void 0 || readTaskAttempt(deps3.workspace, job.jobId, attemptId) === void 0) { + if (attemptId === void 0 || readTaskAttempt(deps4.workspace, job.jobId, attemptId) === void 0) { attemptId = beginTaskAttempt(survivalDeps, { jobId: job.jobId, nodeId: node.nodeId, @@ -71332,7 +71337,7 @@ function finalizeDispatchAttempt(deps3, job, node, outcome, status) { runId: outcome.context.runId }).attemptId; } - const existing = readTaskAttempt(deps3.workspace, job.jobId, attemptId); + const existing = readTaskAttempt(deps4.workspace, job.jobId, attemptId); if (existing !== void 0 && isFinalAttemptStatus(existing.status)) { return attemptId; } @@ -71360,37 +71365,37 @@ function finalizeDispatchAttempt(deps3, job, node, outcome, status) { }); return attemptId; } -function completeExecutorDispatch(deps3, jobId, outcome) { - assertJobsEnabled(deps3); - const policy = policyOf2(deps3); - let job = requireJobState(deps3.workspace, jobId); - let graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); +function completeExecutorDispatch(deps4, jobId, outcome) { + assertJobsEnabled(deps4); + const policy = policyOf2(deps4); + let job = requireJobState(deps4.workspace, jobId); + let graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); const node = requireNode(graph, outcome.context.nodeId); - const at = now4(deps3).toISOString(); + const at = now4(deps4).toISOString(); const verified = outcome.evidenceStatus === "verified" || outcome.evidenceStatus === "manually-accepted"; const attemptStatus = outcome.failure === void 0 && verified ? "COMPLETED" : outcome.failure?.category === "CANCELLED" ? "CANCELLED" : "FAILED"; - const attemptId = finalizeDispatchAttempt(deps3, job, node, outcome, attemptStatus); + const attemptId = finalizeDispatchAttempt(deps4, job, node, outcome, attemptStatus); job = { ...job, currentAttemptId: void 0 }; - job = record22(deps3, job, "attempt_completed", { + job = record22(deps4, job, "attempt_completed", { nodeId: node.nodeId, taskId: node.parentTaskId, attemptId, status: attemptStatus }); - const lane = readTaskAttempt(deps3.workspace, jobId, attemptId)?.lane ?? null; - const evaluation = buildAttemptEvaluation(deps3, job, node, outcome, attemptId, lane, at); - recordEvaluation(reliabilityDepsFor(deps3, jobId), evaluation); + const lane = readTaskAttempt(deps4.workspace, jobId, attemptId)?.lane ?? null; + const evaluation = buildAttemptEvaluation(deps4, job, node, outcome, attemptId, lane, at); + recordEvaluation(reliabilityDepsFor(deps4, jobId), evaluation); recordCalibrationForAttempt({ - workspace: deps3.workspace, + workspace: deps4.workspace, policy: policy.scheduler.adaptive, jobId, nodeId: node.nodeId, attemptId, - now: now4(deps3) + now: now4(deps4) }); const evaluationBlocksCompletion = policy.reliability.enabled && evaluation.status !== "PASS"; if (evaluationBlocksCompletion && outcome.failure === void 0 && verified) { - job = record22(deps3, job, "evaluation_failed", { + job = record22(deps4, job, "evaluation_failed", { nodeId: node.nodeId, taskId: node.parentTaskId, attemptId, @@ -71401,7 +71406,7 @@ function completeExecutorDispatch(deps3, jobId, outcome) { }); } if (outcome.failure === void 0 && verified && !evaluationBlocksCompletion) { - recordSuccessfulAttempt(reliabilityDepsFor(deps3, jobId), { + recordSuccessfulAttempt(reliabilityDepsFor(deps4, jobId), { jobId, nodeId: node.nodeId, taskId: node.parentTaskId, @@ -71410,7 +71415,7 @@ function completeExecutorDispatch(deps3, jobId, outcome) { lane, evaluationStatus: evaluation.status }); - ({ job, graph } = appendAttempt(deps3, job, graph, outcome.context, "succeeded")); + ({ job, graph } = appendAttempt(deps4, job, graph, outcome.context, "succeeded")); graph = transitionNode(graph, node.nodeId, "COMPLETED"); graph = withNode(graph, { ...requireNode(graph, node.nodeId), @@ -71431,14 +71436,14 @@ function completeExecutorDispatch(deps3, jobId, outcome) { at } }; - job = record22(deps3, job, "node_completed", { + job = record22(deps4, job, "node_completed", { nodeId: node.nodeId, taskId: node.parentTaskId, evidenceStatus: outcome.evidenceStatus, ...outcome.context.runId !== void 0 ? { runId: outcome.context.runId } : {} }); const milestone = createTaskCheckpoint( - { workspace: deps3.workspace, clock: deps3.clock, idFactory: deps3.idFactory }, + { workspace: deps4.workspace, clock: deps4.clock, idFactory: deps4.idFactory }, { jobId, nodeId: node.nodeId, @@ -71465,42 +71470,42 @@ function completeExecutorDispatch(deps3, jobId, outcome) { relevantArtifacts: outcome.context.runId !== void 0 ? [outcome.context.runId] : [] } ); - job = record22(deps3, job, "task_checkpoint_created", { + job = record22(deps4, job, "task_checkpoint_created", { nodeId: node.nodeId, taskId: node.parentTaskId, checkpointId: milestone.checkpointId, reason: "milestone" }); if (allNodesComplete(graph)) { - const closure = assessCompletion(deps3.completionGate, jobId); + const closure = assessCompletion(deps4.completionGate, jobId); if (closure !== void 0 && !closure.mayComplete) { - job = record22(deps3, job, "closure_audit_completed", { + job = record22(deps4, job, "closure_audit_completed", { directive: "CONTRACT_CLOSURE_AUDIT", unclosed: closure.unclosed, reason: closure.reason.slice(0, 300) }); - job = transition22(deps3, job, "READY"); - persistGraph(deps3, job, graph); + job = transition22(deps4, job, "READY"); + persistGraph(deps4, job, graph); return { - job: persist22(deps3, { ...job, closurePhase: "CONTRACT_CLOSURE_AUDIT" }), + job: persist22(deps4, { ...job, closurePhase: "CONTRACT_CLOSURE_AUDIT" }), nextAction: "node-complete", evaluation }; } - job = transition22(deps3, job, "COMPLETED"); - job = record22(deps3, job, "job_completed", {}); + job = transition22(deps4, job, "COMPLETED"); + job = record22(deps4, job, "job_completed", {}); job = { ...job, finalizedAt: at, finalOutcome: "COMPLETED" }; - persistGraph(deps3, job, graph); - return { job: persist22(deps3, job), nextAction: "job-complete", evaluation }; + persistGraph(deps4, job, graph); + return { job: persist22(deps4, job), nextAction: "job-complete", evaluation }; } - job = transition22(deps3, job, "READY"); + job = transition22(deps4, job, "READY"); const next = graph.nodes.find((candidate) => candidate.status === "READY"); job = { ...job, currentNodeId: next?.nodeId }; if (next !== void 0) { - job = record22(deps3, job, "node_ready", { nodeId: next.nodeId, taskId: next.parentTaskId }); + job = record22(deps4, job, "node_ready", { nodeId: next.nodeId, taskId: next.parentTaskId }); } - persistGraph(deps3, job, graph); - return { job: persist22(deps3, job), nextAction: "node-complete", evaluation }; + persistGraph(deps4, job, graph); + return { job: persist22(deps4, job), nextAction: "node-complete", evaluation }; } const failureInput = outcome.failure ?? (evaluationBlocksCompletion && verified ? { // The verifiers passed; evaluation did not. Saying so precisely @@ -71532,7 +71537,7 @@ function completeExecutorDispatch(deps3, jobId, outcome) { consecutiveNoProgress: node.consecutiveNoProgress, maxNoProgressCycles: job.budgets.maxNoProgressCycles }); - ({ job, graph } = appendAttempt(deps3, job, graph, outcome.context, "failed", { + ({ job, graph } = appendAttempt(deps4, job, graph, outcome.context, "failed", { failureCategory: classified2.category, failureFingerprint: classified2.fingerprint })); @@ -71549,13 +71554,13 @@ function completeExecutorDispatch(deps3, jobId, outcome) { ...outcome.mode === "repair" ? { repairCycles: requireNode(graph, node.nodeId).repairCycles + 1 } : {} }); if (classified2.category === "VERIFICATION_FAILURE") { - job = record22(deps3, job, "verification_failed", { + job = record22(deps4, job, "verification_failed", { nodeId: node.nodeId, fingerprint: classified2.fingerprint, source: failureInput.source }); } - job = record22(deps3, job, "execution_finished", { + job = record22(deps4, job, "execution_finished", { nodeId: node.nodeId, outcome: "failed", category: classified2.category, @@ -71564,22 +71569,22 @@ function completeExecutorDispatch(deps3, jobId, outcome) { }); graph = transitionNode(graph, node.nodeId, "READY"); const blockWith = (category, code2, message2, remediation) => { - let blocked2 = transition22(deps3, job, "BLOCKED"); - blocked2 = record22(deps3, blocked2, category === "BUDGET_EXHAUSTED" ? "budget_exhausted" : "job_blocked", { + let blocked2 = transition22(deps4, job, "BLOCKED"); + blocked2 = record22(deps4, blocked2, category === "BUDGET_EXHAUSTED" ? "budget_exhausted" : "job_blocked", { nodeId: node.nodeId, category, reason: message2.slice(0, 500) }); blocked2 = { ...blocked2, blocker: { category, code: code2, message: message2, remediation, at } }; - persistGraph(deps3, blocked2, graph); - return { job: persist22(deps3, blocked2), nextAction: "blocked", classified: classified2 }; + persistGraph(deps4, blocked2, graph); + return { job: persist22(deps4, blocked2), nextAction: "blocked", classified: classified2 }; }; if (classified2.category === "CANCELLED") { - let cancelled = transition22(deps3, job, "CANCELLED"); - cancelled = record22(deps3, cancelled, "job_cancelled", { nodeId: node.nodeId }); + let cancelled = transition22(deps4, job, "CANCELLED"); + cancelled = record22(deps4, cancelled, "job_cancelled", { nodeId: node.nodeId }); cancelled = { ...cancelled, finalizedAt: at, finalOutcome: "CANCELLED" }; - persistGraph(deps3, cancelled, graph); - return { job: persist22(deps3, cancelled), nextAction: "blocked", classified: classified2 }; + persistGraph(deps4, cancelled, graph); + return { job: persist22(deps4, cancelled), nextAction: "blocked", classified: classified2 }; } if (classified2.policy.terminal) { return blockWith( @@ -71602,25 +71607,25 @@ function completeExecutorDispatch(deps3, jobId, outcome) { baseBackoffMs: Math.max(policy.retryDelayMs, 1), maxBackoffMs: Math.max(policy.retryDelayMs * 16, policy.retryDelayMs) }); - let waiting = transition22(deps3, job, "WAITING_RETRY"); + let waiting = transition22(deps4, job, "WAITING_RETRY"); waiting = { ...waiting, - retryAt: new Date(now4(deps3).getTime() + backoffMs).toISOString(), + retryAt: new Date(now4(deps4).getTime() + backoffMs).toISOString(), counters: { ...waiting.counters, transientRetries: waiting.counters.transientRetries + 1 } }; - waiting = record22(deps3, waiting, "waiting_retry", { + waiting = record22(deps4, waiting, "waiting_retry", { nodeId: node.nodeId, category: classified2.category, retryAt: waiting.retryAt }); - persistGraph(deps3, waiting, graph); - return { job: persist22(deps3, waiting), nextAction: "wait-retry", classified: classified2 }; + persistGraph(deps4, waiting, graph); + return { job: persist22(deps4, waiting), nextAction: "wait-retry", classified: classified2 }; } if (classified2.policy.clarifiable && !classified2.policy.repairable) { - let clarify = transition22(deps3, job, "NEEDS_CLARIFICATION"); + let clarify = transition22(deps4, job, "NEEDS_CLARIFICATION"); const awaitingCcrIds = [...classified2.message.matchAll(CCR_ID_PATTERN)].map((hit) => hit[0]); const question = { - id: `q-${newId4(deps3)}`.slice(0, 64), + id: `q-${newId4(deps4)}`.slice(0, 64), question: `Task ${node.parentTaskId} cannot proceed: ${classified2.message.slice(0, 600)} Resolve the prerequisite (or decide otherwise), then resume the job.`, whyItMatters: `${classified2.category} has no safe automatic response.`, options: [], @@ -71628,7 +71633,7 @@ function completeExecutorDispatch(deps3, jobId, outcome) { askedAt: at, round: Math.min( clarify.counters.clarificationRounds + 1, - deps3.config.orchestration.clarification.maxRounds + deps4.config.orchestration.clarification.maxRounds ), ...awaitingCcrIds.length > 0 ? { awaitingCcrIds } : {} }; @@ -71637,15 +71642,15 @@ function completeExecutorDispatch(deps3, jobId, outcome) { openQuestions: [...clarify.openQuestions, question], counters: { ...clarify.counters, clarificationRounds: question.round } }; - clarify = record22(deps3, clarify, "clarification_requested", { + clarify = record22(deps4, clarify, "clarification_requested", { nodeId: node.nodeId, category: classified2.category }); - persistGraph(deps3, clarify, graph); - return { job: persist22(deps3, clarify), nextAction: "clarify", classified: classified2 }; + persistGraph(deps4, clarify, graph); + return { job: persist22(deps4, clarify), nextAction: "clarify", classified: classified2 }; } if (policy.reliability.enabled) { - const contextMiss = assessDispatchContextMiss(deps3, { + const contextMiss = assessDispatchContextMiss(deps4, { jobId, nodeId: node.nodeId, attemptId, @@ -71653,7 +71658,7 @@ function completeExecutorDispatch(deps3, jobId, outcome) { ...outcome.reliability?.workerReportedText !== void 0 ? { workerReportedText: outcome.reliability.workerReportedText } : {}, ...outcome.reliability?.directModelRequestedRepository === true ? { directModelRequestedRepository: true } : {} }); - const governed = governFailedAttempt(reliabilityDepsFor(deps3, jobId), { + const governed = governFailedAttempt(reliabilityDepsFor(deps4, jobId), { jobId, nodeId: node.nodeId, taskId: node.parentTaskId, @@ -71662,7 +71667,7 @@ function completeExecutorDispatch(deps3, jobId, outcome) { classified: classified2, evaluation, lane, - executionMode: readTaskAttempt(deps3.workspace, jobId, attemptId)?.executionMode ?? null, + executionMode: readTaskAttempt(deps4.workspace, jobId, attemptId)?.executionMode ?? null, planRevision: node.planRevision, diffFingerprint: observation2.diffFingerprint ?? null, ...outcome.reliability?.harnessFailureKind !== void 0 ? { harnessFailureKind: outcome.reliability.harnessFailureKind } : {}, @@ -71686,7 +71691,7 @@ function completeExecutorDispatch(deps3, jobId, outcome) { ...outcome.context.runId !== void 0 ? { evidenceRefs: [outcome.context.runId] } : {} }); if (contextMiss.signals.length > 0) { - recordJobEvent(deps3, jobId, "context_insufficient", { + recordJobEvent(deps4, jobId, "context_insufficient", { nodeId: node.nodeId, taskId: node.parentTaskId, attemptId, @@ -71697,7 +71702,7 @@ function completeExecutorDispatch(deps3, jobId, outcome) { }); } if (governed.decision.action === "EXPAND_CONTEXT") { - applyContextExpansion(deps3, { + applyContextExpansion(deps4, { jobId, nodeId: node.nodeId, taskId: node.parentTaskId, @@ -71705,13 +71710,13 @@ function completeExecutorDispatch(deps3, jobId, outcome) { at }); } else if (contextMiss.offer.exhausted) { - recordJobEvent(deps3, jobId, "context_expansion_exhausted", { + recordJobEvent(deps4, jobId, "context_expansion_exhausted", { nodeId: node.nodeId, taskId: node.parentTaskId, reason: contextMiss.offer.reason.slice(0, 500) }); } - return applyRecoveryDecision(deps3, { + return applyRecoveryDecision(deps4, { job, graph, node: requireNode(graph, node.nodeId), @@ -71741,9 +71746,9 @@ function completeExecutorDispatch(deps3, jobId, outcome) { ["The implementation changes and all failure evidence are preserved."] ); } - const diagnosing = transition22(deps3, job, "DIAGNOSING"); - persistGraph(deps3, diagnosing, graph); - return { job: persist22(deps3, diagnosing), nextAction: "diagnose", classified: classified2 }; + const diagnosing = transition22(deps4, job, "DIAGNOSING"); + persistGraph(deps4, diagnosing, graph); + return { job: persist22(deps4, diagnosing), nextAction: "diagnose", classified: classified2 }; } return blockWith( classified2.category, @@ -71752,16 +71757,16 @@ function completeExecutorDispatch(deps3, jobId, outcome) { classified2.policy.remediation ); } -function applyDiagnosis(deps3, jobId, result) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); - let graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); +function applyDiagnosis(deps4, jobId, result) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); + let graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); const node = requireNode(graph, result.context.nodeId); - const at = now4(deps3).toISOString(); + const at = now4(deps4).toISOString(); if (job.status !== "DIAGNOSING") { throw new OrchestrationError("SBO027", `A diagnosis applies only while DIAGNOSING (job is ${job.status}).`); } - ({ job, graph } = appendAttempt(deps3, job, graph, result.context, "succeeded")); + ({ job, graph } = appendAttempt(deps4, job, graph, result.context, "succeeded")); graph = withNode(graph, { ...requireNode(graph, node.nodeId), latestDiagnosis: { @@ -71772,18 +71777,18 @@ function applyDiagnosis(deps3, jobId, result) { ...result.context.agentResultRef !== void 0 ? { agentResultRef: result.context.agentResultRef } : {} } }); - job = record22(deps3, job, "diagnosis_completed", { + job = record22(deps4, job, "diagnosis_completed", { nodeId: node.nodeId, category: result.category, planValidity: result.planValidity, recommendedAction: result.recommendedAction }); - const pending = pendingRecoveryDecision(deps3, jobId, node.nodeId); + const pending = pendingRecoveryDecision(deps4, jobId, node.nodeId); if (pending !== void 0) { const replanBudgetForCaution = requireNode(graph, node.nodeId).replans < job.budgets.maxReplansPerTask && job.counters.jobReplans < job.budgets.maxJobReplans; const narrowsToReplan = pending.action === "REPAIR" && replanBudgetForCaution && (result.planValidity === "INVALID" || result.recommendedAction === "REPLAN"); const effective = narrowsToReplan ? "REPLAN" : pending.action; - job = record22(deps3, job, "recovery_decided", { + job = record22(deps4, job, "recovery_decided", { nodeId: node.nodeId, decisionId: pending.decisionId, action: effective, @@ -71794,16 +71799,16 @@ function applyDiagnosis(deps3, jobId, result) { narrowedByDiagnosis: narrowsToReplan, applied: true }); - markRecoveryDecisionApplied(deps3.workspace, jobId, pending.decisionId); + markRecoveryDecisionApplied(deps4.workspace, jobId, pending.decisionId); if (effective === "REPLAN") { - job = transition22(deps3, job, "REPLANNING"); - persistGraph(deps3, job, graph); - return { job: persist22(deps3, job), applied: "replan" }; + job = transition22(deps4, job, "REPLANNING"); + persistGraph(deps4, job, graph); + return { job: persist22(deps4, job), applied: "replan" }; } if (effective === "REPAIR") { - job = transition22(deps3, job, "READY"); - persistGraph(deps3, job, graph); - return { job: persist22(deps3, job), applied: "repair" }; + job = transition22(deps4, job, "READY"); + persistGraph(deps4, job, graph); + return { job: persist22(deps4, job), applied: "repair" }; } } const policyOfFailure = classifyFailure({ @@ -71814,37 +71819,37 @@ function applyDiagnosis(deps3, jobId, result) { const repairBudgetLeft = requireNode(graph, node.nodeId).repairCycles < job.budgets.maxRepairCyclesPerTask; const replanBudgetLeft = requireNode(graph, node.nodeId).replans < job.budgets.maxReplansPerTask && job.counters.jobReplans < job.budgets.maxJobReplans; if (result.recommendedAction === "REPAIR" && policyOfFailure.repairable && result.planValidity === "VALID" && repairBudgetLeft) { - job = transition22(deps3, job, "READY"); - persistGraph(deps3, job, graph); - return { job: persist22(deps3, job), applied: "repair" }; + job = transition22(deps4, job, "READY"); + persistGraph(deps4, job, graph); + return { job: persist22(deps4, job), applied: "repair" }; } const wantsReplan = result.recommendedAction === "REPLAN" || result.planValidity === "INVALID" || result.recommendedAction === "REPAIR" && (!repairBudgetLeft || !policyOfFailure.repairable); if (wantsReplan && policyOfFailure.replannable !== false && replanBudgetLeft) { - job = transition22(deps3, job, "REPLANNING"); - persistGraph(deps3, job, graph); - return { job: persist22(deps3, job), applied: "replan" }; + job = transition22(deps4, job, "REPLANNING"); + persistGraph(deps4, job, graph); + return { job: persist22(deps4, job), applied: "replan" }; } if (result.recommendedAction === "RETRY" && policyOfFailure.retryable) { if (job.counters.transientRetries < job.budgets.maxTransientRetries) { - const delay = policyOf2(deps3).retryDelayMs; - job = transition22(deps3, job, "WAITING_RETRY"); + const delay = policyOf2(deps4).retryDelayMs; + job = transition22(deps4, job, "WAITING_RETRY"); job = { ...job, - retryAt: new Date(now4(deps3).getTime() + delay).toISOString(), + retryAt: new Date(now4(deps4).getTime() + delay).toISOString(), counters: { ...job.counters, transientRetries: job.counters.transientRetries + 1 } }; - job = record22(deps3, job, "waiting_retry", { nodeId: node.nodeId, retryAt: job.retryAt }); - persistGraph(deps3, job, graph); - return { job: persist22(deps3, job), applied: "wait-retry" }; + job = record22(deps4, job, "waiting_retry", { nodeId: node.nodeId, retryAt: job.retryAt }); + persistGraph(deps4, job, graph); + return { job: persist22(deps4, job), applied: "wait-retry" }; } } if (result.recommendedAction === "CLARIFY" || policyOfFailure.clarifiable) { - job = transition22(deps3, job, "NEEDS_CLARIFICATION"); - job = record22(deps3, job, "clarification_requested", { nodeId: node.nodeId }); - persistGraph(deps3, job, graph); - return { job: persist22(deps3, job), applied: "clarify" }; + job = transition22(deps4, job, "NEEDS_CLARIFICATION"); + job = record22(deps4, job, "clarification_requested", { nodeId: node.nodeId }); + persistGraph(deps4, job, graph); + return { job: persist22(deps4, job), applied: "clarify" }; } - job = transition22(deps3, job, "BLOCKED"); + job = transition22(deps4, job, "BLOCKED"); job = { ...job, blocker: { @@ -71855,14 +71860,14 @@ function applyDiagnosis(deps3, jobId, result) { at } }; - job = record22(deps3, job, "job_blocked", { nodeId: node.nodeId, category: result.category }); - persistGraph(deps3, job, graph); - return { job: persist22(deps3, job), applied: "blocked" }; + job = record22(deps4, job, "job_blocked", { nodeId: node.nodeId, category: result.category }); + persistGraph(deps4, job, graph); + return { job: persist22(deps4, job), applied: "blocked" }; } -function supersedeNode(deps3, jobId, input) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); - const graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); +function supersedeNode(deps4, jobId, input) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); + const graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); const node = requireNode(graph, input.nodeId); if (node.replans >= job.budgets.maxReplansPerTask || job.counters.jobReplans >= job.budgets.maxJobReplans) { throw new OrchestrationError("SBO013", "No replan budget remains; the node cannot be superseded.", { @@ -71872,42 +71877,42 @@ function supersedeNode(deps3, jobId, input) { const revised = reviseGraphSuperseding(graph, { supersedeNodeId: input.nodeId, replanReason: input.reason, - createdAt: now4(deps3).toISOString() + createdAt: now4(deps4).toISOString() }); - storeGraphRevision(deps3.workspace, jobId, revised); + storeGraphRevision(deps4.workspace, jobId, revised); job = { ...job, graphRevision: revised.revision, currentNodeId: node.supersededBy, counters: { ...job.counters, jobReplans: job.counters.jobReplans + 1 } }; - job = record22(deps3, job, "graph_revised", { + job = record22(deps4, job, "graph_revised", { revision: revised.revision, supersedes: graph.revision, supersededNode: input.nodeId, reason: input.reason.slice(0, 500) }); - job = record22(deps3, job, "node_superseded", { nodeId: input.nodeId }); - if (job.status === "REPLANNING") job = transition22(deps3, job, "READY"); - return { job: persist22(deps3, job), graph: revised }; + job = record22(deps4, job, "node_superseded", { nodeId: input.nodeId }); + if (job.status === "REPLANNING") job = transition22(deps4, job, "READY"); + return { job: persist22(deps4, job), graph: revised }; } -function askClarification(deps3, jobId, questions) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); +function askClarification(deps4, jobId, questions) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); if (isFinalJobStatus(job.status)) { throw new OrchestrationError("SBO026", `Job is ${job.status}; no questions can be asked.`); } - const maxRounds = deps3.config.orchestration.clarification.maxRounds; + const maxRounds = deps4.config.orchestration.clarification.maxRounds; if (job.counters.clarificationRounds >= maxRounds) { throw new OrchestrationError("SBO008", `All ${maxRounds} clarification rounds are used.`, { failureCategory: "BUDGET_EXHAUSTED" }); } - const at = now4(deps3).toISOString(); + const at = now4(deps4).toISOString(); const round2 = job.counters.clarificationRounds + 1; - const added = questions.slice(0, deps3.config.orchestration.clarification.maxQuestionsPerRound).map( + const added = questions.slice(0, deps4.config.orchestration.clarification.maxQuestionsPerRound).map( (candidate) => ({ - id: `q-${newId4(deps3)}`.slice(0, 64), + id: `q-${newId4(deps4)}`.slice(0, 64), question: candidate.question.slice(0, 1e3), whyItMatters: candidate.whyItMatters.slice(0, 1e3), options: [], @@ -71921,16 +71926,16 @@ function askClarification(deps3, jobId, questions) { openQuestions: [...job.openQuestions, ...added], counters: { ...job.counters, clarificationRounds: round2 } }; - if (job.status !== "NEEDS_CLARIFICATION") job = transition22(deps3, job, "NEEDS_CLARIFICATION"); - job = record22(deps3, job, "clarification_requested", { + if (job.status !== "NEEDS_CLARIFICATION") job = transition22(deps4, job, "NEEDS_CLARIFICATION"); + job = record22(deps4, job, "clarification_requested", { round: round2, questionIds: added.map((question) => question.id) }); - return persist22(deps3, job); + return persist22(deps4, job); } var CCR_ID_PATTERN = /\bCCR-\d{3,}\b/g; -function reconcileDecidedCcrs(deps3, jobId, decided2) { - let job = requireJobState(deps3.workspace, jobId); +function reconcileDecidedCcrs(deps4, jobId, decided2) { + let job = requireJobState(deps4.workspace, jobId); if (job.status !== "NEEDS_CLARIFICATION") return { job, closed: [] }; const answered = job.openQuestions.filter((question) => { const waiting = question.awaitingCcrIds ?? [...question.question.matchAll(CCR_ID_PATTERN)].map((h2) => h2[0]); @@ -71939,22 +71944,22 @@ function reconcileDecidedCcrs(deps3, jobId, decided2) { if (answered.length === 0) return { job, closed: [] }; const closed = answered.map((question) => question.id); const remaining = job.openQuestions.filter((question) => !closed.includes(question.id)); - job = persist22(deps3, { ...job, openQuestions: remaining }); - job = record22(deps3, job, "clarification_resolved", { + job = persist22(deps4, { ...job, openQuestions: remaining }); + job = record22(deps4, job, "clarification_resolved", { questionIds: closed, by: "ccr-decision" }); - if (remaining.length === 0) job = transition22(deps3, job, "READY"); - return { job: persist22(deps3, job), closed }; + if (remaining.length === 0) job = transition22(deps4, job, "READY"); + return { job: persist22(deps4, job), closed }; } var UNIT_ID_PATTERN = /\bwu-[A-Za-z0-9][\w-]*\b/g; -function reviveUnitsNamedBy(deps3, job, question, answer) { +function reviveUnitsNamedBy(deps4, job, question, answer) { const named = [...question.matchAll(UNIT_ID_PATTERN)].map((hit) => hit[0]); if (named.length === 0) return; - const graph = job.graphRevision > 0 ? readGraphRevision(deps3.workspace, job.jobId, job.graphRevision) : void 0; + const graph = job.graphRevision > 0 ? readGraphRevision(deps4.workspace, job.jobId, job.graphRevision) : void 0; if (graph === void 0) return; for (const node of graph.nodes) { - const workGraph = readLatestWorkGraph(deps3.workspace, job.jobId, node.nodeId); + const workGraph = readLatestWorkGraph(deps4.workspace, job.jobId, node.nodeId); if (workGraph === void 0) continue; let changed = false; const units = workGraph.units.map((unit) => { @@ -71971,23 +71976,23 @@ function reviveUnitsNamedBy(deps3, job, question, answer) { }; }); if (changed) { - storeWorkGraph(deps3.workspace, job.jobId, { ...workGraph, units }); + storeWorkGraph(deps4.workspace, job.jobId, { ...workGraph, units }); } } } -function answerClarification(deps3, jobId, answers) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); +function answerClarification(deps4, jobId, answers) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); if (job.status !== "NEEDS_CLARIFICATION") { throw new OrchestrationError("SBO027", `Answers apply only while NEEDS_CLARIFICATION (job is ${job.status}).`); } - const at = now4(deps3).toISOString(); + const at = now4(deps4).toISOString(); const answered = /* @__PURE__ */ new Set(); const decisions = answers.filter((answer) => job.openQuestions.some((question) => question.id === answer.questionId)).map((answer) => { answered.add(answer.questionId); const question = job.openQuestions.find((candidate) => candidate.id === answer.questionId); return { - id: `d-${newId4(deps3)}`.slice(0, 64), + id: `d-${newId4(deps4)}`.slice(0, 64), questionId: answer.questionId, question: question?.question ?? "", answer: answer.answer.slice(0, 2e3), @@ -72004,41 +72009,41 @@ function answerClarification(deps3, jobId, answers) { openQuestions: job.openQuestions.filter((question) => !answered.has(question.id)) }; for (const decision of decisions) { - reviveUnitsNamedBy(deps3, job, decision.question, decision.answer); + reviveUnitsNamedBy(deps4, job, decision.question, decision.answer); } - job = record22(deps3, job, "clarification_resolved", { + job = record22(deps4, job, "clarification_resolved", { decisionIds: decisions.map((decision) => decision.id), remaining: job.openQuestions.length }); if (job.openQuestions.length === 0) { - job = transition22(deps3, job, "READY"); + job = transition22(deps4, job, "READY"); } - return persist22(deps3, job); + return persist22(deps4, job); } -function cancelJob(deps3, jobId, reason3) { - let job = requireJobState(deps3.workspace, jobId); +function cancelJob(deps4, jobId, reason3) { + let job = requireJobState(deps4.workspace, jobId); if (isFinalJobStatus(job.status)) return job; - const at = now4(deps3).toISOString(); - job = transition22(deps3, job, "CANCELLED"); - job = record22(deps3, job, "job_cancelled", { reason: reason3.slice(0, 500) }); - return persist22(deps3, { ...job, finalizedAt: at, finalOutcome: "CANCELLED" }); + const at = now4(deps4).toISOString(); + job = transition22(deps4, job, "CANCELLED"); + job = record22(deps4, job, "job_cancelled", { reason: reason3.slice(0, 500) }); + return persist22(deps4, { ...job, finalizedAt: at, finalOutcome: "CANCELLED" }); } var TRANSIENT_UNIT_FAILURES = ["TRANSIENT_TOOL", "TRANSIENT_TRANSPORT"]; -function selfHealOnResume(deps3, jobId) { +function selfHealOnResume(deps4, jobId) { const repairs = []; - let job = requireJobState(deps3.workspace, jobId); - const lock = diagnoseInteractiveLock(deps3.workspace, () => now4(deps3)); + let job = requireJobState(deps4.workspace, jobId); + const lock = diagnoseInteractiveLock(deps4.workspace, () => now4(deps4)); if (lock.state === "stale" && lock.safeToRemove) { - removeDiagnosedLock(deps3.workspace, () => now4(deps3)); + removeDiagnosedLock(deps4.workspace, () => now4(deps4)); repairs.push({ code: "STALE_RUN_LOCK_REMOVED", detail: lock.findings.join(" ").slice(0, 280) }); if (job.humanWaitSince === void 0) { const diedAt = Date.parse(job.updatedAt); - const idle = Number.isNaN(diedAt) ? 0 : Math.max(0, now4(deps3).getTime() - diedAt); + const idle = Number.isNaN(diedAt) ? 0 : Math.max(0, now4(deps4).getTime() - diedAt); if (idle > 0) { - job = persist22(deps3, { + job = persist22(deps4, { ...job, counters: { ...job.counters, deadIdleMs: (job.counters.deadIdleMs ?? 0) + idle } }); @@ -72051,9 +72056,9 @@ function selfHealOnResume(deps3, jobId) { } if (job.humanWaitSince !== void 0) { const since = Date.parse(job.humanWaitSince); - const banked = Number.isNaN(since) ? 0 : Math.max(0, now4(deps3).getTime() - since); + const banked = Number.isNaN(since) ? 0 : Math.max(0, now4(deps4).getTime() - since); const { humanWaitSince: _banked, ...rest } = job; - job = persist22(deps3, { + job = persist22(deps4, { ...rest, counters: { ...job.counters, humanWaitMs: (job.counters.humanWaitMs ?? 0) + banked } }); @@ -72063,29 +72068,29 @@ function selfHealOnResume(deps3, jobId) { }); } if (job.status === "BLOCKED" && job.blocker?.category === "BUDGET_EXHAUSTED") { - const worked = workedMsOf(job, now4(deps3).getTime()); + const worked = workedMsOf(job, now4(deps4).getTime()); const stillOver = worked >= job.budgets.maxWallClockMs || job.counters.agentRuns >= job.budgets.maxAgentRuns; if (!stillOver) { const { blocker: _stale, ...rest } = job; - job = persist22(deps3, rest); - job = transition22(deps3, job, "READY"); - job = persist22(deps3, job); + job = persist22(deps4, rest); + job = transition22(deps4, job, "READY"); + job = persist22(deps4, job); repairs.push({ code: "BUDGET_VERDICT_RECOMPUTED", detail: `BUDGET_EXHAUSTED no longer holds: worked ${Math.round(worked / 6e4)}m of ${Math.round(job.budgets.maxWallClockMs / 6e4)}m, ${job.counters.agentRuns} of ${job.budgets.maxAgentRuns} dispatches` }); } } - const graph = job.graphRevision > 0 ? readGraphRevision(deps3.workspace, jobId, job.graphRevision) : void 0; + const graph = job.graphRevision > 0 ? readGraphRevision(deps4.workspace, jobId, job.graphRevision) : void 0; if (graph !== void 0) { for (const node of graph.nodes) { - const workGraph = readLatestWorkGraph(deps3.workspace, jobId, node.nodeId); + const workGraph = readLatestWorkGraph(deps4.workspace, jobId, node.nodeId); if (workGraph === void 0) continue; const revived = workGraph.units.filter( (unit) => unit.status === "FAILED" && TRANSIENT_UNIT_FAILURES.includes(unit.latestFailure?.category ?? "") ); if (revived.length === 0) continue; - storeWorkGraph(deps3.workspace, jobId, { + storeWorkGraph(deps4.workspace, jobId, { ...workGraph, units: workGraph.units.map((unit) => { if (!revived.includes(unit)) return unit; @@ -72100,10 +72105,10 @@ function selfHealOnResume(deps3, jobId) { } } if (repairs.length > 0) { - job = requireJobState(deps3.workspace, jobId); + job = requireJobState(deps4.workspace, jobId); job = persist22( - deps3, - record22(deps3, job, "self_heal_applied", { + deps4, + record22(deps4, job, "self_heal_applied", { repairs: repairs.map((repair) => ({ code: repair.code, detail: repair.detail.slice(0, 200) })) }) ); @@ -72119,8 +72124,8 @@ var OPERATOR_FIXABLE_BLOCKER_CATEGORIES = [ "TRANSIENT_TOOL", "INVALID_CONFIGURATION" ]; -function retryBlockedJob(deps3, jobId, input) { - let job = requireJobState(deps3.workspace, jobId); +function retryBlockedJob(deps4, jobId, input) { + let job = requireJobState(deps4.workspace, jobId); if (job.status !== "BLOCKED") { return { job, cleared: false, reason: `the job is ${job.status}, not BLOCKED` }; } @@ -72135,83 +72140,83 @@ function retryBlockedJob(deps3, jobId, input) { reason: `the blocker is ${category}, which is not something fixing the machine resolves` }; } - job = transition22(deps3, job, "READY"); + job = transition22(deps4, job, "READY"); const { blocker: _cleared, ...rest } = job; - job = persist22(deps3, rest); - job = record22(deps3, job, "job_unblocked", { + job = persist22(deps4, rest); + job = record22(deps4, job, "job_unblocked", { category, code: job.blocker?.code ?? null, reason: input.reason.slice(0, 500) }); - return { job: persist22(deps3, job), cleared: true }; + return { job: persist22(deps4, job), cleared: true }; } -function blockJob(deps3, jobId, input) { - let job = requireJobState(deps3.workspace, jobId); +function blockJob(deps4, jobId, input) { + let job = requireJobState(deps4.workspace, jobId); if (job.status === "BLOCKED") return job; - const at = now4(deps3).toISOString(); - job = transition22(deps3, job, "BLOCKED"); - job = record22(deps3, job, input.category === "BUDGET_EXHAUSTED" ? "budget_exhausted" : "job_blocked", { + const at = now4(deps4).toISOString(); + job = transition22(deps4, job, "BLOCKED"); + job = record22(deps4, job, input.category === "BUDGET_EXHAUSTED" ? "budget_exhausted" : "job_blocked", { code: input.code, reason: input.message.slice(0, 500) }); - return persist22(deps3, { + return persist22(deps4, { ...job, blocker: { category: input.category, code: input.code, message: input.message, remediation: input.remediation, at } }); } -function clearRetryWait(deps3, jobId, at) { - let job = requireJobState(deps3.workspace, jobId); +function clearRetryWait(deps4, jobId, at) { + let job = requireJobState(deps4.workspace, jobId); if (job.status !== "WAITING_RETRY") return job; - const instant = at ?? now4(deps3); + const instant = at ?? now4(deps4); if (job.retryAt !== void 0 && Date.parse(job.retryAt) > instant.getTime()) return job; - job = transition22(deps3, job, "READY"); + job = transition22(deps4, job, "READY"); delete job.retryAt; - return persist22(deps3, job); + return persist22(deps4, job); } -function promoteNodeForQuotaOvertake(deps3, jobId, input) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); - let graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); +function promoteNodeForQuotaOvertake(deps4, jobId, input) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); + let graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); const node = requireNode(graph, input.nodeId); if (node.status !== "PENDING") { return job; } graph = transitionNode(graph, node.nodeId, "READY"); - job = record22(deps3, job, "node_ready", { + job = record22(deps4, job, "node_ready", { nodeId: node.nodeId, taskId: node.parentTaskId, quotaOvertake: true, detail: input.detail.slice(0, 300) }); - persistGraph(deps3, job, graph); - return persist22(deps3, job); + persistGraph(deps4, job, graph); + return persist22(deps4, job); } -function deferJobForQuota(deps3, jobId, input) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); - const at = now4(deps3); +function deferJobForQuota(deps4, jobId, input) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); + const at = now4(deps4); const retryAt = input.until !== null && Date.parse(input.until) > at.getTime() ? input.until : new Date(at.getTime() + Math.max(1e3, input.pollMs)).toISOString(); if (job.status !== "WAITING_RETRY") { - job = transition22(deps3, job, "WAITING_RETRY"); + job = transition22(deps4, job, "WAITING_RETRY"); } job = { ...job, retryAt }; - job = record22(deps3, job, "task_deferred", { + job = record22(deps4, job, "task_deferred", { nodeId: input.nodeId, taskId: input.taskId, reasonCode: input.reasonCode.slice(0, 100), retryAt, detail: input.detail.slice(0, 500) }); - return persist22(deps3, job); + return persist22(deps4, job); } -function checkpointJob(deps3, jobId, nextAction) { - let job = requireJobState(deps3.workspace, jobId); - const graph = job.graphRevision > 0 ? readGraphRevision(deps3.workspace, jobId, job.graphRevision) : void 0; +function checkpointJob(deps4, jobId, nextAction) { + let job = requireJobState(deps4.workspace, jobId); + const graph = job.graphRevision > 0 ? readGraphRevision(deps4.workspace, jobId, job.graphRevision) : void 0; const nodes = graph?.nodes ?? []; const checkpoint = jobCheckpointSchema.parse({ schemaVersion: JOB_CHECKPOINT_SCHEMA_VERSION, jobId, - createdAt: now4(deps3).toISOString(), + createdAt: now4(deps4).toISOString(), specName: job.specName, status: job.status, graphRevision: job.graphRevision, @@ -72225,21 +72230,21 @@ function checkpointJob(deps3, jobId, nextAction) { ...job.operationalWait !== void 0 ? { operationalWait: job.operationalWait } : {}, nextAction: nextAction.slice(0, 2e3) }); - writeJobCheckpoint(deps3.workspace, jobId, checkpoint); - job = record22(deps3, job, "checkpoint_created", { status: job.status }); - persist22(deps3, job); + writeJobCheckpoint(deps4.workspace, jobId, checkpoint); + job = record22(deps4, job, "checkpoint_created", { status: job.status }); + persist22(deps4, job); return checkpoint; } -async function resumeJob(deps3, jobId) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); +async function resumeJob(deps4, jobId) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); const warnings = []; const reconciled = []; - const checkpoint = readJobCheckpoint(deps3.workspace, jobId); + const checkpoint = readJobCheckpoint(deps4.workspace, jobId); if (isFinalJobStatus(job.status)) { return { job, - graph: job.graphRevision > 0 ? readGraphRevision(deps3.workspace, jobId, job.graphRevision) : void 0, + graph: job.graphRevision > 0 ? readGraphRevision(deps4.workspace, jobId, job.graphRevision) : void 0, finalized: true, reconciled, planStale: false, @@ -72250,14 +72255,14 @@ async function resumeJob(deps3, jobId) { nextAction: "Create a new job for further work." }; } - const currentFingerprint = jobPolicyFingerprint(deps3.config.orchestration); + const currentFingerprint = jobPolicyFingerprint(deps4.config.orchestration); const policyChanged = currentFingerprint !== job.policyFingerprint; if (policyChanged) { warnings.push( "The job policy changed since this job began. The job continues under the budgets recorded at its start." ); } - let graph = job.graphRevision > 0 ? requireGraphRevision(deps3.workspace, jobId, job.graphRevision) : void 0; + let graph = job.graphRevision > 0 ? requireGraphRevision(deps4.workspace, jobId, job.graphRevision) : void 0; if (graph !== void 0) { for (const node of graph.nodes) { if (node.status === "RUNNING" || node.status === "REPAIRING") { @@ -72268,16 +72273,16 @@ async function resumeJob(deps3, jobId) { } if (job.status === "RUNNING" || job.status === "REPAIRING" || job.status === "PLANNING") { const interrupted = job.status; - job = { ...job, status: "READY", updatedAt: now4(deps3).toISOString() }; + job = { ...job, status: "READY", updatedAt: now4(deps4).toISOString() }; reconciled.push(`job: ${interrupted} \u2192 READY (interrupted process)`); } const interruptedAttempts = reconcileInterruptedAttempts( - { workspace: deps3.workspace, clock: deps3.clock }, + { workspace: deps4.workspace, clock: deps4.clock }, jobId ); for (const attempt of interruptedAttempts) { reconciled.push(`attempt ${attempt.attemptId}: RUNNING \u2192 INTERRUPTED (worker disappeared)`); - job = record22(deps3, job, "attempt_interrupted", { + job = record22(deps4, job, "attempt_interrupted", { nodeId: attempt.nodeId, taskId: attempt.taskId, attemptId: attempt.attemptId, @@ -72288,15 +72293,15 @@ async function resumeJob(deps3, jobId) { job = { ...job, currentAttemptId: void 0 }; } const interruptedReservations = reconcileInterruptedApiReservations( - deps3.workspace, + deps4.workspace, jobId, - now4(deps3) + now4(deps4) ); for (const reservation of interruptedReservations) { reconciled.push( `api budget ${reservation.reservationId}: RESERVED \u2192 UNKNOWN ($${reservation.reservedUsd.toFixed(4)} stays charged; remote usage cannot be ruled out)` ); - job = record22(deps3, job, "api_budget_reconciled", { + job = record22(deps4, job, "api_budget_reconciled", { nodeId: reservation.nodeId, taskId: reservation.taskId, reservationId: reservation.reservationId, @@ -72306,22 +72311,22 @@ async function resumeJob(deps3, jobId) { costSource: reservation.costSource }); } - const snapshot2 = await captureGitSnapshot(deps3.workspace.rootDir, { clock: () => now4(deps3) }); + const snapshot2 = await captureGitSnapshot(deps4.workspace.rootDir, { clock: () => now4(deps4) }); let planStale = false; let planStaleReasons = []; if (graph !== void 0 && job.currentNodeId !== void 0) { const node = findNode(graph, job.currentNodeId); if (node !== void 0 && node.planRevision > 0) { - const raw = readNodePlan(deps3.workspace, jobId, node.nodeId, node.planRevision); + const raw = readNodePlan(deps4.workspace, jobId, node.nodeId, node.planRevision); const parsed = raw !== void 0 ? executionPlanSchema.safeParse(raw) : void 0; if (parsed === void 0 || !parsed.success) { warnings.push(`The plan for node ${node.nodeId} is missing or unreadable; a fresh plan is required.`); graph = withNode(graph, { ...node, planApproved: false, planRevision: 0 }); } else { - const current = capturePlanBinding(deps3.workspace, { + const current = capturePlanBinding(deps4.workspace, { specName: job.specName, taskId: node.parentTaskId, - policy: deps3.config.orchestration, + policy: deps4.config.orchestration, gitHead: snapshot2.head }); const freshness = evaluatePlanFreshness(parsed.data, current); @@ -72331,31 +72336,31 @@ async function resumeJob(deps3, jobId) { warnings.push("The recorded plan no longer matches the repository; it will not be executed as-is."); graph = withNode(graph, { ...node, planApproved: false }); if (job.status === "READY") { - job = transition22(deps3, job, "REPLANNING"); + job = transition22(deps4, job, "REPLANNING"); } } } } } - const lock = readInteractiveLock(deps3.workspace); + const lock = readInteractiveLock(deps4.workspace); if (lock.state === "held") { warnings.push( `The repository lock is held by run ${lock.lock.runId}; recover it with \`specbridge run recover-lock\` before dispatching.` ); } - if (graph !== void 0) persistGraph(deps3, job, graph); - job = record22(deps3, job, "job_resumed", { + if (graph !== void 0) persistGraph(deps4, job, graph); + job = record22(deps4, job, "job_resumed", { reconciled: reconciled.length, planStale, policyChanged }); if (reconciled.length > 0 || planStale) { - job = record22(deps3, job, "repository_reconciled", { + job = record22(deps4, job, "repository_reconciled", { ...snapshot2.head !== void 0 ? { gitHead: snapshot2.head } : {}, planStale }); } - job = persist22(deps3, job); + job = persist22(deps4, job); return { job, graph, @@ -72371,9 +72376,9 @@ async function resumeJob(deps3, jobId) { nextAction: planStale ? "Produce a replacement plan: the recorded plan is stale." : "Continue with the scheduler decision." }; } -function recordObjectiveWorkerAttempt(deps3, jobId, input) { - assertJobsEnabled(deps3); - let job = requireJobState(deps3.workspace, jobId); +function recordObjectiveWorkerAttempt(deps4, jobId, input) { + assertJobsEnabled(deps4); + let job = requireJobState(deps4.workspace, jobId); if (job.counters.agentRuns >= job.budgets.maxAgentRuns) { throw new OrchestrationError( "SBO032", @@ -72381,25 +72386,25 @@ function recordObjectiveWorkerAttempt(deps3, jobId, input) { { failureCategory: "BUDGET_EXHAUSTED" } ); } - let graph = requireGraphRevision(deps3.workspace, jobId, job.graphRevision); + let graph = requireGraphRevision(deps4.workspace, jobId, job.graphRevision); ({ job, graph } = appendAttempt( - deps3, + deps4, job, graph, { nodeId: input.nodeId, role: input.role, workerId: input.workerId, - startedAt: now4(deps3).toISOString(), + startedAt: now4(deps4).toISOString(), ...input.usage !== void 0 ? { usage: input.usage } : {} }, input.outcome === "succeeded" ? "succeeded" : input.outcome )); - persistGraph(deps3, job, graph); - return persist22(deps3, job); + persistGraph(deps4, job, graph); + return persist22(deps4, job); } -function countLocalInferenceCall(deps3, jobId) { - let job = requireJobState(deps3.workspace, jobId); +function countLocalInferenceCall(deps4, jobId) { + let job = requireJobState(deps4.workspace, jobId); if (job.counters.localInferenceCalls >= job.budgets.maxLocalInferenceCalls) { throw new OrchestrationError( "SBO032", @@ -72411,22 +72416,22 @@ function countLocalInferenceCall(deps3, jobId) { ...job, counters: { ...job.counters, localInferenceCalls: job.counters.localInferenceCalls + 1 } }; - return persist22(deps3, job); + return persist22(deps4, job); } -function assessDispatchContextMiss(deps3, input) { - const at = now4(deps3).toISOString(); +function assessDispatchContextMiss(deps4, input) { + const at = now4(deps4).toISOString(); const idle = { signals: [], missingPaths: [], offer: { available: false, nextLevel: "TOP_WORKING_SET", reason: "", exhausted: false } }; - if (deps3.config.orchestration.jobs.context.efficiency.strategy === "LEGACY") return idle; + if (deps4.config.orchestration.jobs.context.efficiency.strategy === "LEGACY") return idle; try { - const plan = listContextSelectionPlans(deps3.workspace, input.jobId, { + const plan = listContextSelectionPlans(deps4.workspace, input.jobId, { nodeId: input.nodeId, attemptId: input.attemptId }).at(-1); - const cached2 = readRepositoryIndexCache(deps3.workspace); + const cached2 = readRepositoryIndexCache(deps4.workspace); const index = cached2 === void 0 ? void 0 : new RepositoryContextIndex(cached2); const miss = assessContextMiss({ plan, @@ -72436,30 +72441,30 @@ function assessDispatchContextMiss(deps3, input) { ...input.directModelRequestedRepository === true ? { directModelRequestedRepository: true } : {} }); if (miss.signals.length === 0) return idle; - const state = readContextExpansionState(deps3.workspace, input.jobId, input.nodeId) ?? initialExpansionState({ taskId: plan?.taskId ?? input.nodeId, nodeId: input.nodeId, now: at }); + const state = readContextExpansionState(deps4.workspace, input.jobId, input.nodeId) ?? initialExpansionState({ taskId: plan?.taskId ?? input.nodeId, nodeId: input.nodeId, now: at }); return { signals: miss.signals, missingPaths: miss.missingPaths, - offer: offerContextExpansion({ config: deps3.config, state, signals: miss.signals }) + offer: offerContextExpansion({ config: deps4.config, state, signals: miss.signals }) }; } catch { return idle; } } -function applyContextExpansion(deps3, input) { +function applyContextExpansion(deps4, input) { try { - const state = readContextExpansionState(deps3.workspace, input.jobId, input.nodeId) ?? initialExpansionState({ taskId: input.taskId, nodeId: input.nodeId, now: input.at }); + const state = readContextExpansionState(deps4.workspace, input.jobId, input.nodeId) ?? initialExpansionState({ taskId: input.taskId, nodeId: input.nodeId, now: input.at }); const signals2 = input.signals; const decision = planContextExpansion({ - strategy: deps3.config.orchestration.jobs.context.efficiency.strategy, - policy: expansionPolicyFrom(deps3.config), + strategy: deps4.config.orchestration.jobs.context.efficiency.strategy, + policy: expansionPolicyFrom(deps4.config), state, signals: signals2 }); if (!decision.expand) return; const next = applyExpansion(state, decision, { signals: signals2, now: input.at }); - writeContextExpansionState(deps3.workspace, input.jobId, input.nodeId, next); - recordJobEvent(deps3, input.jobId, "context_expanded", { + writeContextExpansionState(deps4.workspace, input.jobId, input.nodeId, next); + recordJobEvent(deps4, input.jobId, "context_expanded", { nodeId: input.nodeId, taskId: input.taskId, level: next.level, @@ -72469,10 +72474,10 @@ function applyContextExpansion(deps3, input) { } catch { } } -function enterResourceWait(deps3, jobId, input) { - const previous = requireJobState(deps3.workspace, jobId); - const wait = buildWait(deps3, previous, input); - return applyJobTransition(deps3, jobId, { +function enterResourceWait(deps4, jobId, input) { + const previous = requireJobState(deps4.workspace, jobId); + const wait = buildWait(deps4, previous, input); + return applyJobTransition(deps4, jobId, { to: "WAITING_RESOURCE", event: "resource_wait_started", payload: { @@ -72488,10 +72493,10 @@ function enterResourceWait(deps3, jobId, input) { } }); } -function enterProviderRecovery(deps3, jobId, input) { - const previous = requireJobState(deps3.workspace, jobId); - const wait = buildWait(deps3, previous, input); - return applyJobTransition(deps3, jobId, { +function enterProviderRecovery(deps4, jobId, input) { + const previous = requireJobState(deps4.workspace, jobId); + const wait = buildWait(deps4, previous, input); + return applyJobTransition(deps4, jobId, { to: "RECOVERING_PROVIDER", event: "provider_recovery_started", payload: { kind: input.kind, detail: input.detail.slice(0, 300), attempt: wait.recoveryAttempts }, @@ -72501,32 +72506,32 @@ function enterProviderRecovery(deps3, jobId, input) { } }); } -function enterToolchainRepair(deps3, jobId, input) { - const previous = requireJobState(deps3.workspace, jobId); - return applyJobTransition(deps3, jobId, { +function enterToolchainRepair(deps4, jobId, input) { + const previous = requireJobState(deps4.workspace, jobId); + return applyJobTransition(deps4, jobId, { to: "REPAIRING_TOOLCHAIN", event: "toolchain_repair_started", payload: { kind: input.kind, detail: input.detail.slice(0, 300) }, patch: { - operationalWait: buildWait(deps3, previous, input), + operationalWait: buildWait(deps4, previous, input), autonomyCounters: bump(previous, "toolchainRepairs") } }); } -function enterEnvironmentRepair(deps3, jobId, input) { - const previous = requireJobState(deps3.workspace, jobId); - return applyJobTransition(deps3, jobId, { +function enterEnvironmentRepair(deps4, jobId, input) { + const previous = requireJobState(deps4.workspace, jobId); + return applyJobTransition(deps4, jobId, { to: "REPAIRING_ENVIRONMENT", event: "environment_failed", payload: { kind: input.kind, detail: input.detail.slice(0, 300) }, patch: { - operationalWait: buildWait(deps3, previous, input), + operationalWait: buildWait(deps4, previous, input), autonomyCounters: bump(previous, "environmentRepairs") } }); } -function clearOperationalState(deps3, jobId, input) { - const job = requireJobState(deps3.workspace, jobId); +function clearOperationalState(deps4, jobId, input) { + const job = requireJobState(deps4.workspace, jobId); if (!isOperationalJobStatus(job.status)) { throw new OrchestrationError( "SBO027", @@ -72535,7 +72540,7 @@ function clearOperationalState(deps3, jobId, input) { ); } const event = eventForOperationalExit(job.status); - return applyJobTransition(deps3, jobId, { + return applyJobTransition(deps4, jobId, { to: input.to ?? "READY", event, payload: { @@ -72563,8 +72568,8 @@ function eventForOperationalExit(status) { return "resource_wait_ended"; } } -function enterQualifying(deps3, jobId, input) { - return applyJobTransition(deps3, jobId, { +function enterQualifying(deps4, jobId, input) { + return applyJobTransition(deps4, jobId, { to: "QUALIFYING", event: "closure_audit_completed", payload: { @@ -72574,10 +72579,10 @@ function enterQualifying(deps3, jobId, input) { patch: { closurePhase: input.phase, operationalWait: void 0 } }); } -function escalateAuthority(deps3, jobId, input) { - const job = requireJobState(deps3.workspace, jobId); +function escalateAuthority(deps4, jobId, input) { + const job = requireJobState(deps4.workspace, jobId); if (job.authorityRequest !== void 0 && job.authorityRequest.resolvedAt === void 0) { - return job.status === "NEEDS_AUTHORITY" ? job : applyJobTransition(deps3, jobId, { + return job.status === "NEEDS_AUTHORITY" ? job : applyJobTransition(deps4, jobId, { to: "NEEDS_AUTHORITY", event: "authority_escalated", payload: { surface: job.authorityRequest.surface, existing: true } @@ -72585,7 +72590,7 @@ function escalateAuthority(deps3, jobId, input) { } const request = authorityRequestSchema.parse({ requestId: `auth-${Date.now().toString(36)}-${job.counters.escalations + 1}`, - at: new Date(deps3.clock !== void 0 ? deps3.clock().getTime() : Date.now()).toISOString(), + at: new Date(deps4.clock !== void 0 ? deps4.clock().getTime() : Date.now()).toISOString(), surface: input.surface, reason: input.reason, question: input.question.slice(0, 2e3), @@ -72595,7 +72600,7 @@ function escalateAuthority(deps3, jobId, input) { options: [...input.options ?? []].slice(0, 10), observedSignals: [...input.observedSignals ?? []].slice(0, 20) }); - return applyJobTransition(deps3, jobId, { + return applyJobTransition(deps4, jobId, { to: "NEEDS_AUTHORITY", event: "authority_escalated", payload: { surface: request.surface, reason: request.reason, requestId: request.requestId }, @@ -72606,8 +72611,8 @@ function escalateAuthority(deps3, jobId, input) { } }); } -function buildWait(deps3, job, input) { - const at = new Date(deps3.clock !== void 0 ? deps3.clock().getTime() : Date.now()).toISOString(); +function buildWait(deps4, job, input) { + const at = new Date(deps4.clock !== void 0 ? deps4.clock().getTime() : Date.now()).toISOString(); const existing = job.operationalWait !== void 0 && job.operationalWait.kind === input.kind ? job.operationalWait : void 0; return operationalWaitSchema.parse({ kind: input.kind, @@ -72635,9 +72640,9 @@ function bump(job, key) { const current = counters[key]; return { ...counters, [key]: (typeof current === "number" ? current : 0) + 1 }; } -function countAutonomyEvent(deps3, jobId, key, event, payload = {}) { - const job = requireJobState(deps3.workspace, jobId); - return applyJobTransition(deps3, jobId, { +function countAutonomyEvent(deps4, jobId, key, event, payload = {}) { + const job = requireJobState(deps4.workspace, jobId); + return applyJobTransition(deps4, jobId, { to: job.status, event, payload, @@ -73757,6 +73762,23 @@ function writeResearchUseRecord(workspace, value) { `); return record32; } +function listResearchUseRecords(workspace) { + const dir = researchUsesDir(workspace); + if (!(0, import_fs45.existsSync)(dir)) return []; + const records = []; + for (const entry2 of (0, import_fs45.readdirSync)(dir, { withFileTypes: true })) { + if (!entry2.isFile() || !entry2.name.endsWith(".json")) continue; + try { + const value = JSON.parse((0, import_fs45.readFileSync)(import_path48.default.join(dir, entry2.name), "utf8")); + const version2 = value !== null && typeof value === "object" && typeof value.schemaVersion === "string" ? value.schemaVersion : ""; + if (majorOf3(version2) !== majorOf3(RESEARCH_USE_SCHEMA_VERSION)) continue; + const parsed = researchUseRecordSchema.safeParse(value); + if (parsed.success) records.push(parsed.data); + } catch { + } + } + return records.sort((a2, b) => a2.createdAt.localeCompare(b.createdAt)); +} function listResearchRecords(workspace) { const dir = researchRecordsDir(workspace); if (!(0, import_fs45.existsSync)(dir)) return { records: [], diagnostics: [] }; @@ -74480,17 +74502,17 @@ function recordResearchReplanTelemetry(workspace, now52) { updatedAt: now52.toISOString() }); } -function nowOf(deps3) { - return deps3.clock?.() ?? /* @__PURE__ */ new Date(); +function nowOf(deps4) { + return deps4.clock?.() ?? /* @__PURE__ */ new Date(); } -function newUseId(deps3) { - return `use-${(deps3.idFactory ?? import_crypto23.randomUUID)()}`.slice(0, 128); +function newUseId(deps4) { + return `use-${(deps4.idFactory ?? import_crypto23.randomUUID)()}`.slice(0, 128); } -function recordLifecycleUse(deps3, researchId, scope, useKind, effect) { +function recordLifecycleUse(deps4, researchId, scope, useKind, effect) { if (scope.lifecycle === void 0) return; - writeResearchUseRecord(deps3.workspace, { + writeResearchUseRecord(deps4.workspace, { schemaVersion: RESEARCH_USE_SCHEMA_VERSION, - useId: newUseId(deps3), + useId: newUseId(deps4), researchId, phase: scope.lifecycle.phase, reason: scope.lifecycle.reason, @@ -74498,17 +74520,17 @@ function recordLifecycleUse(deps3, researchId, scope, useKind, effect) { effect: effect ?? scope.lifecycle.requestedEffect ?? "EVIDENCE", ...scope.lifecycle.usedBy !== void 0 ? { usedBy: scope.lifecycle.usedBy } : {}, authority: "EVIDENCE_ONLY", - createdAt: nowOf(deps3).toISOString() + createdAt: nowOf(deps4).toISOString() }); } function failure2(classification, failureSource, message2, retryable = false) { return { classification, failureSource, message: message2, retryable }; } -function selectedBridge(deps3) { - if (deps3.bridge !== void 0) return deps3.bridge; - if (deps3.config.research.provider === "deerflow") { - return new DeerFlowResearchBridge(deps3.config.research.providers.deerflow, { - clock: () => nowOf(deps3) +function selectedBridge(deps4) { + if (deps4.bridge !== void 0) return deps4.bridge; + if (deps4.config.research.provider === "deerflow") { + return new DeerFlowResearchBridge(deps4.config.research.providers.deerflow, { + clock: () => nowOf(deps4) }); } return void 0; @@ -74546,14 +74568,14 @@ function budgetFailure(policy, records, request, scope) { } return void 0; } -function evaluateAndRecordResearchGate(deps3, input, phase) { +function evaluateAndRecordResearchGate(deps4, input, phase) { const result = evaluateResearchGate(input); - recordResearchGateTelemetry(deps3.workspace, result.decision, nowOf(deps3), phase); + recordResearchGateTelemetry(deps4.workspace, result.decision, nowOf(deps4), phase); return result; } -async function getResearchProviderHealth(deps3, signal) { - const now52 = nowOf(deps3).toISOString(); - const policy = deps3.config.research; +async function getResearchProviderHealth(deps4, signal) { + const now52 = nowOf(deps4).toISOString(); + const policy = deps4.config.research; if (!policy.enabled) { return { provider: policy.provider, @@ -74570,7 +74592,7 @@ async function getResearchProviderHealth(deps3, signal) { detail: "the selected research provider is disabled; no health request was made" }; } - const bridge = selectedBridge(deps3); + const bridge = selectedBridge(deps4); if (bridge === void 0 || bridge.providerId() !== policy.provider) { return { provider: policy.provider, @@ -74581,15 +74603,15 @@ async function getResearchProviderHealth(deps3, signal) { } return bridge.health(signal); } -async function startResearch(deps3, raw, scope = {}, signal) { +async function startResearch(deps4, raw, scope = {}, signal) { const request = researchRequestSchema.parse(raw); - const policy = deps3.config.research; - const existing = listResearchRecords(deps3.workspace).records; + const policy = deps4.config.research; + const existing = listResearchRecords(deps4.workspace).records; const reuse = findResearchReuse(existing, request); const refreshCurrentFacts = scope.refreshCurrentFacts === true && request.freshness.currentFactSensitive; if (!refreshCurrentFacts && reuse.exact?.report !== void 0) { - recordResearchReuseTelemetry(deps3.workspace, nowOf(deps3), scope.lifecycle?.phase); - recordLifecycleUse(deps3, reuse.exact.researchId, scope, "REUSED"); + recordResearchReuseTelemetry(deps4.workspace, nowOf(deps4), scope.lifecycle?.phase); + recordLifecycleUse(deps4, reuse.exact.researchId, scope, "REUSED"); return { ok: true, reused: true, record: reuse.exact, report: reuse.exact.report }; } if (existing.some((record42) => record42.researchId === request.researchId)) { @@ -74613,10 +74635,10 @@ async function startResearch(deps3, raw, scope = {}, signal) { } const refused = budgetFailure(policy, existing, request, scope); if (refused !== void 0) { - recordResearchBudgetRefusalTelemetry(deps3.workspace, nowOf(deps3)); + recordResearchBudgetRefusalTelemetry(deps4.workspace, nowOf(deps4)); return { ok: false, failure: refused }; } - const bridge = selectedBridge(deps3); + const bridge = selectedBridge(deps4); if (bridge === void 0 || bridge.providerId() !== policy.provider) { return { ok: false, @@ -74627,7 +74649,7 @@ async function startResearch(deps3, raw, scope = {}, signal) { ) }; } - const createdAt = nowOf(deps3).toISOString(); + const createdAt = nowOf(deps4).toISOString(); const baseRecord = { schemaVersion: RESEARCH_RECORD_SCHEMA_VERSION, researchId: request.researchId, @@ -74655,7 +74677,7 @@ async function startResearch(deps3, raw, scope = {}, signal) { createdAt, updatedAt: createdAt }; - writeResearchRecord(deps3.workspace, baseRecord); + writeResearchRecord(deps4.workspace, baseRecord); const started = Date.now(); let providerResult = await bridge.investigate(request, signal); if (providerResult.ok) { @@ -74672,9 +74694,9 @@ async function startResearch(deps3, raw, scope = {}, signal) { }; } } - const completed = nowOf(deps3); + const completed = nowOf(deps4); recordResearchProviderTelemetry( - deps3.workspace, + deps4.workspace, providerResult, Math.max(0, Date.now() - started), completed, @@ -74682,7 +74704,7 @@ async function startResearch(deps3, raw, scope = {}, signal) { scope.lifecycle?.phase ); if (!providerResult.ok) { - const record42 = writeResearchRecord(deps3.workspace, { + const record42 = writeResearchRecord(deps4.workspace, { ...baseRecord, status: providerResult.failure.classification === "CANCELLED" ? "CANCELLED" : "FAILED", failure: providerResult.failure, @@ -74691,7 +74713,7 @@ async function startResearch(deps3, raw, scope = {}, signal) { }); return { ok: false, failure: providerResult.failure, record: record42 }; } - const record32 = writeResearchRecord(deps3.workspace, { + const record32 = writeResearchRecord(deps4.workspace, { ...baseRecord, status: providerResult.report.status === "COMPLETED" ? "COMPLETED" : "INCONCLUSIVE", report: providerResult.report, @@ -74699,12 +74721,12 @@ async function startResearch(deps3, raw, scope = {}, signal) { ...providerResult.report.usage !== void 0 ? { usage: providerResult.report.usage } : {}, updatedAt: completed.toISOString() }); - recordLifecycleUse(deps3, record32.researchId, scope, "NEW"); + recordLifecycleUse(deps4, record32.researchId, scope, "NEW"); return { ok: true, reused: false, record: record32, report: providerResult.report }; } -function recordResearchLifecycleEffect(deps3, input) { +function recordResearchLifecycleEffect(deps4, input) { recordLifecycleUse( - deps3, + deps4, input.researchId, { lifecycle: { @@ -74759,11 +74781,11 @@ function classifiedGate(classification, supplied, priorResearchAvailable) { return { ...base, dependsOnExternalFacts: false, dependsOnCurrentFacts: false }; } } -async function considerLifecycleResearch(deps3, raw, signal) { +async function considerLifecycleResearch(deps4, raw, signal) { const input = lifecycleResearchInputSchema.parse(raw); - const priorResearchAvailable = input.request === void 0 ? false : findResearchReuse(listResearchRecords(deps3.workspace).records, input.request).exact !== void 0; + const priorResearchAvailable = input.request === void 0 ? false : findResearchReuse(listResearchRecords(deps4.workspace).records, input.request).exact !== void 0; const gate = evaluateAndRecordResearchGate( - deps3, + deps4, classifiedGate(input.classification, input.gate, priorResearchAvailable), input.phase ); @@ -74781,7 +74803,7 @@ async function considerLifecycleResearch(deps3, raw, signal) { }, ...input.refreshCurrentFacts ? { refreshCurrentFacts: true } : {} }; - const execution = await startResearch(deps3, input.request, scope, signal); + const execution = await startResearch(deps4, input.request, scope, signal); return { classification: input.classification, gate, execution }; } var decisionPreparationInputSchema = external_exports.object({ @@ -74809,11 +74831,11 @@ function reportContext(report) { ...report.conflicts.slice(0, 4).map((item) => `Research conflict: ${item}`) ].slice(0, 20); } -async function prepareDecisionBrief(deps3, raw, signal) { +async function prepareDecisionBrief(deps4, raw, signal) { const input = decisionPreparationInputSchema.parse(raw); const researchInput = input.research; const result = researchInput === void 0 ? void 0 : await considerLifecycleResearch( - deps3, + deps4, { ...researchInput, phase: "INTAKE_DECISION", @@ -74826,7 +74848,7 @@ async function prepareDecisionBrief(deps3, raw, signal) { ); const execution = result?.execution; const report = execution?.ok === true ? execution.report : void 0; - if (report !== void 0) recordResearchDecisionPreparedTelemetry(deps3.workspace, deps3.clock?.() ?? /* @__PURE__ */ new Date()); + if (report !== void 0) recordResearchDecisionPreparedTelemetry(deps4.workspace, deps4.clock?.() ?? /* @__PURE__ */ new Date()); return decisionBriefSchema.parse({ questionId: input.questionId, question: input.question, @@ -80249,7 +80271,7 @@ async function dispatchLocalHarnessExecution(input) { const lane = input.lane ?? "LOCAL"; const label = lane === "API" ? "api harness" : "local harness"; const source = lane === "API" ? "api-harness" : "local-harness"; - const deps3 = { + const deps4 = { workspace: input.workspace, config: input.config, ...input.clock !== void 0 ? { clock: input.clock } : {}, @@ -80269,7 +80291,7 @@ async function dispatchLocalHarnessExecution(input) { false ); } - const begin = await beginInteractiveTask(deps3, { + const begin = await beginInteractiveTask(deps4, { specName: input.specName, taskId: input.node.parentTaskId, allowDirty: input.allowDirty, @@ -80287,7 +80309,7 @@ async function dispatchLocalHarnessExecution(input) { input.onProgress?.(`${label}: run ${begin.runId} started for task ${begin.task.id}`); const abort = async (reason3) => { try { - await abortInteractiveTask(deps3, { runId: begin.runId, reason: reason3.slice(0, 500) }); + await abortInteractiveTask(deps4, { runId: begin.runId, reason: reason3.slice(0, 500) }); } catch { } }; @@ -80389,7 +80411,7 @@ async function dispatchLocalHarnessExecution(input) { } input.onProgress?.(`${label}: agent reported completion; running trusted verification`); const report = result.report; - const completion = await completeInteractiveTask(deps3, { + const completion = await completeInteractiveTask(deps4, { runId: begin.runId, summary: `[${source}] ${report?.summary ?? "harness attempt"}`.slice(0, 2e3), ...report?.changedFiles !== void 0 ? { reportedChangedFiles: [...report.changedFiles] } : {}, @@ -80498,8 +80520,8 @@ function observeHarnessActivity(result) { function dispatchApiHarnessExecution(input) { return dispatchLocalHarnessExecution({ ...input, lane: "API" }); } -function costOf(tokens, costPerMillion) { - return tokens / 1e6 * costPerMillion; +function costOf(tokens2, costPerMillion) { + return tokens2 / 1e6 * costPerMillion; } function roundUsd(value) { return Math.round(value * 1e4) / 1e4; @@ -82506,10 +82528,10 @@ function createSchedulingRuntime(config2, workspace, input) { lastObservedAt: void 0 }; } -function estimateNodeContextRatio(deps3, jobId, nodeId) { - const checkpoint = readLatestTaskCheckpoint(deps3.workspace, jobId, nodeId); +function estimateNodeContextRatio(deps4, jobId, nodeId) { + const checkpoint = readLatestTaskCheckpoint(deps4.workspace, jobId, nodeId); if (checkpoint === void 0) return null; - const budget = contextBudgetFromPolicy(deps3.config.orchestration.jobs.context); + const budget = contextBudgetFromPolicy(deps4.config.orchestration.jobs.context); const usable = usableInputTokens(budget); const serialized = JSON.stringify({ objective: checkpoint.objective, @@ -82526,8 +82548,8 @@ function estimateNodeContextRatio(deps3, jobId, nodeId) { }); return Math.round(estimateTokens(serialized) / usable * 1e4) / 1e4; } -function localExecutorAttemptsUsed(deps3, jobId, nodeId) { - return listTaskAttempts(deps3.workspace, jobId, { nodeId }).filter( +function localExecutorAttemptsUsed(deps4, jobId, nodeId) { + return listTaskAttempts(deps4.workspace, jobId, { nodeId }).filter( (attempt) => attempt.lane === "LOCAL" && attempt.role === "EXECUTOR" && (attempt.status === "FAILED" || attempt.status === "INTERRUPTED") ).length; } @@ -82537,14 +82559,14 @@ var LOCAL_ESCALATION_REASONS = [ "LOCAL_EXECUTION_ESCALATED" ]; var DIRECT_TO_HARNESS_REASON = "LOCAL_DIRECT_TO_HARNESS"; -async function buildLaneContext(runtime, deps3, jobId, job, graph) { - const ledger = readExecutionLedger(deps3.workspace, jobId); +async function buildLaneContext(runtime, deps4, jobId, job, graph) { + const ledger = readExecutionLedger(deps4.workspace, jobId); const observations = deriveBurnObservations(ledger); const { fiveHour, weekly } = await runtime.manager.snapshot(); const forecast = buildQuotaForecast({ fiveHour, weekly, - now: (deps3.clock ?? (() => /* @__PURE__ */ new Date()))(), + now: (deps4.clock ?? (() => /* @__PURE__ */ new Date()))(), policy: runtime.policy, observedFiveHourBurnRatePerMinute: observedFiveHourBurnRate(observations) }); @@ -82556,7 +82578,7 @@ async function buildLaneContext(runtime, deps3, jobId, job, graph) { const routings = /* @__PURE__ */ new Map(); const ready = (graph?.nodes ?? []).filter((node) => node.status === "READY"); for (const node of ready) { - routings.set(node.nodeId, assessNode(runtime, deps3, jobId, job, node, forecast, reserve, observations)); + routings.set(node.nodeId, assessNode(runtime, deps4, jobId, job, node, forecast, reserve, observations)); } if (runtime.apiBridgeEnabled && ready.length > 0) { const readyLocalNodeIds = ready.filter((node) => routings.get(node.nodeId)?.routing.lane === "LOCAL").map((node) => node.nodeId); @@ -82567,12 +82589,12 @@ async function buildLaneContext(runtime, deps3, jobId, job, graph) { for (const node of ready) { const assessment = routings.get(node.nodeId); if (assessment === void 0 || assessment.routing.lane !== "DEFER") continue; - const bridged = assessApiGapBridge(runtime, deps3, jobId, job, node, assessment, { + const bridged = assessApiGapBridge(runtime, deps4, jobId, job, node, assessment, { forecast, readyLocalNodeIds, readyRunnableNodeIds, graph, - now: (deps3.clock ?? (() => /* @__PURE__ */ new Date()))() + now: (deps4.clock ?? (() => /* @__PURE__ */ new Date()))() }); if (bridged !== void 0) routings.set(node.nodeId, bridged); } @@ -82586,7 +82608,7 @@ async function buildLaneContext(runtime, deps3, jobId, job, graph) { break; } if (node.status !== "PENDING") break; - const assessment = assessNode(runtime, deps3, jobId, job, node, forecast, reserve, observations); + const assessment = assessNode(runtime, deps4, jobId, job, node, forecast, reserve, observations); if (assessment.routing.lane === "LOCAL") { routings.set(node.nodeId, assessment); overtakeCandidate = { @@ -82598,7 +82620,7 @@ async function buildLaneContext(runtime, deps3, jobId, job, graph) { if (assessment.routing.lane !== "DEFER") break; } } - const adaptive = runtime.adaptiveEnabled ? applyAdaptiveRanking(runtime, deps3, jobId, job, ready, routings, forecast) : void 0; + const adaptive = runtime.adaptiveEnabled ? applyAdaptiveRanking(runtime, deps4, jobId, job, ready, routings, forecast) : void 0; return { context: { policy: runtime.policy, @@ -82613,12 +82635,12 @@ async function buildLaneContext(runtime, deps3, jobId, job, graph) { adaptive }; } -function applyAdaptiveRanking(runtime, deps3, jobId, job, ready, routings, forecast) { - const now52 = (deps3.clock ?? (() => /* @__PURE__ */ new Date()))(); +function applyAdaptiveRanking(runtime, deps4, jobId, job, ready, routings, forecast) { + const now52 = (deps4.clock ?? (() => /* @__PURE__ */ new Date()))(); let loaded; try { loaded = loadAdaptiveProfiles({ - workspace: deps3.workspace, + workspace: deps4.workspace, policy: runtime.adaptivePolicy, now: now52 }); @@ -82632,7 +82654,7 @@ function applyAdaptiveRanking(runtime, deps3, jobId, job, ready, routings, forec if (assessment === void 0) continue; const signature2 = assessment.signature; if (signature2 === void 0) continue; - const reliability = readTaskReliabilityState(deps3.workspace, jobId, node.nodeId); + const reliability = readTaskReliabilityState(deps4.workspace, jobId, node.nodeId); signatures.set(node.nodeId, signature2); const candidates = generateCandidates({ routing: assessment, @@ -82685,7 +82707,7 @@ function applyAdaptiveRanking(runtime, deps3, jobId, job, ready, routings, forec signatures }; } -function assessApiGapBridge(runtime, deps3, jobId, job, node, assessment, context) { +function assessApiGapBridge(runtime, deps4, jobId, job, node, assessment, context) { const apiPolicy = runtime.policy.api; const gapReason = runtime.subscriptionWorkerAvailable ? subscriptionGapReasonFor(assessment.routing.reasonCode) : "SUBSCRIPTION_WORKER_UNAVAILABLE"; if (gapReason === void 0) return void 0; @@ -82707,13 +82729,13 @@ function assessApiGapBridge(runtime, deps3, jobId, job, node, assessment, contex safetyMultiplier: apiPolicy.gap.costSafetyMultiplier }); const budget = assessApiBudget({ - state: readApiBudgetState(deps3.workspace, jobId), + state: readApiBudgetState(deps4.workspace, jobId), policy: apiPolicy.budget, taskId: node.parentTaskId, safeCostUsd: cost.safeCostUsd }); const approval = runtime.apiBinding.profileName === null ? null : checkApiSpendApproval({ - approvals: listApiSpendApprovals(deps3.workspace, jobId, { nodeId: node.nodeId }), + approvals: listApiSpendApprovals(deps4.workspace, jobId, { nodeId: node.nodeId }), nodeId: node.nodeId, taskFingerprint: taskSpendFingerprint(node), profileName: runtime.apiBinding.profileName, @@ -82737,8 +82759,8 @@ function assessApiGapBridge(runtime, deps3, jobId, job, node, assessment, contex void job; return { ...assessment, routing: applyApiGapBridge(assessment.routing, plan), apiBridge: plan }; } -function assessNode(runtime, deps3, jobId, job, node, forecast, reserve, observations) { - const attemptsUsed = localExecutorAttemptsUsed(deps3, jobId, node.nodeId); +function assessNode(runtime, deps4, jobId, job, node, forecast, reserve, observations) { + const attemptsUsed = localExecutorAttemptsUsed(deps4, jobId, node.nodeId); const stickyEscalation = job.escalations.some( (entry2) => entry2.nodeId === node.nodeId && LOCAL_ESCALATION_REASONS.includes(entry2.reason) ); @@ -82771,7 +82793,7 @@ function assessNode(runtime, deps3, jobId, job, node, forecast, reserve, observa localWorkerAvailable: runtime.localWorkerAvailable && !stickyEscalation, localExecutionAvailable: runtime.localExecutionAvailable && !stickyEscalation, localEscalationRequired: stickyEscalation || attemptsUsed >= runtime.policy.maxLocalAttempts, - contextUsageRatio: estimateNodeContextRatio(deps3, jobId, node.nodeId), + contextUsageRatio: estimateNodeContextRatio(deps4, jobId, node.nodeId), policy: runtime.policy }); const directToHarness = job.escalations.some( @@ -82784,7 +82806,7 @@ function assessNode(runtime, deps3, jobId, job, node, forecast, reserve, observa complexity: node.complexity, priorDirectFailureNeedsRepository: directToHarness }); - const reliability = readTaskReliabilityState(deps3.workspace, jobId, node.nodeId); + const reliability = readTaskReliabilityState(deps4.workspace, jobId, node.nodeId); const signature2 = buildTaskSignature({ category: suitability.category, complexity: node.complexity ?? "MEDIUM", @@ -82813,20 +82835,20 @@ function assessNode(runtime, deps3, jobId, job, node, forecast, reserve, observa }); return { suitability, estimate: estimate2, routing, shape, localExecution, signature: signature2 }; } -function runtimeResearchForJob(deps3, jobId) { - return listResearchRecords(deps3.workspace).records.filter((record32) => record32.scope?.jobId === jobId && record32.lifecycle?.phase === "RUNTIME_INVESTIGATION" && record32.report !== void 0).sort((left, right) => right.updatedAt.localeCompare(left.updatedAt)).slice(0, 3); +function runtimeResearchForJob(deps4, jobId) { + return listResearchRecords(deps4.workspace).records.filter((record32) => record32.scope?.jobId === jobId && record32.lifecycle?.phase === "RUNTIME_INVESTIGATION" && record32.report !== void 0).sort((left, right) => right.updatedAt.localeCompare(left.updatedAt)).slice(0, 3); } -function recordResearchInformedReplan(deps3, jobId, nodeId, reason3) { - const records = runtimeResearchForJob(deps3, jobId); +function recordResearchInformedReplan(deps4, jobId, nodeId, reason3) { + const records = runtimeResearchForJob(deps4, jobId); if (records.length === 0) return; - const now52 = (deps3.clock ?? (() => /* @__PURE__ */ new Date()))(); - recordResearchReplanTelemetry(deps3.workspace, now52); + const now52 = (deps4.clock ?? (() => /* @__PURE__ */ new Date()))(); + recordResearchReplanTelemetry(deps4.workspace, now52); for (const record32 of records) { recordResearchLifecycleEffect({ - workspace: deps3.workspace, - config: deps3.config, - ...deps3.clock !== void 0 ? { clock: deps3.clock } : {}, - ...deps3.idFactory !== void 0 ? { idFactory: deps3.idFactory } : {} + workspace: deps4.workspace, + config: deps4.config, + ...deps4.clock !== void 0 ? { clock: deps4.clock } : {}, + ...deps4.idFactory !== void 0 ? { idFactory: deps4.idFactory } : {} }, { researchId: record32.researchId, phase: "RUNTIME_INVESTIGATION", @@ -82835,7 +82857,7 @@ function recordResearchInformedReplan(deps3, jobId, nodeId, reason3) { usedBy: nodeId }); } - recordJobEvent(deps3, jobId, "research_replan_caused", { + recordJobEvent(deps4, jobId, "research_replan_caused", { nodeId, researchIds: records.map((record32) => record32.researchId), reason: reason3.slice(0, 500), @@ -82876,31 +82898,31 @@ ${(0, import_fs44.readFileSync)(file.path, "utf8")}`); } } var agentResultSequence = 0; -function persistAgentResult(deps3, jobId, role, raw) { +function persistAgentResult(deps4, jobId, role, raw) { agentResultSequence += 1; const name = `${Date.now()}-${String(agentResultSequence).padStart(4, "0")}-${role.toLowerCase()}.json`; try { return storeAgentResult( - deps3.workspace, + deps4.workspace, jobId, name, JSON.parse(raw), - { maxBytes: deps3.config.orchestration.jobs.maxAgentResultBytes } + { maxBytes: deps4.config.orchestration.jobs.maxAgentResultBytes } ).ref; } catch { return void 0; } } -async function driveJob(deps3, jobId, options = {}) { +async function driveJob(deps4, jobId, options = {}) { const emit22 = (kind, message2) => { options.onEvent?.({ kind, message: message2 }); }; const sleep2 = options.sleep ?? defaultSleep; const signal = options.signal; - const policy = deps3.config.orchestration.jobs; - let job = requireJobState(deps3.workspace, jobId); + const policy = deps4.config.orchestration.jobs; + let job = requireJobState(deps4.workspace, jobId); if (job.status !== "CREATED") { - const resume = await resumeJob(deps3, jobId); + const resume = await resumeJob(deps4, jobId); job = resume.job; for (const warning2 of resume.warnings) emit22("note", warning2); if (resume.finalized) { @@ -82908,26 +82930,26 @@ async function driveJob(deps3, jobId, options = {}) { } } const probeCache = { probe: void 0 }; - const localManager = createLocalManager(deps3.config, (event) => { + const localManager = createLocalManager(deps4.config, (event) => { emit22("local-model", `${event.type}: ${event.detail}`); if (event.type === "ready") { - recordJobEvent(deps3, jobId, "local_model_started", { detail: event.detail.slice(0, 200) }); + recordJobEvent(deps4, jobId, "local_model_started", { detail: event.detail.slice(0, 200) }); } if (event.type === "stopped" || event.type === "exited") { - recordJobEvent(deps3, jobId, "local_model_stopped", { + recordJobEvent(deps4, jobId, "local_model_stopped", { kind: event.type, detail: event.detail.slice(0, 200) }); } }); - const missionDriven = policy.objectives.enabled === true && findMissionForSpec(deps3.workspace, job.specName) !== void 0; - const schedulingRuntime = createSchedulingRuntime(deps3.config, deps3.workspace, { + const missionDriven = policy.objectives.enabled === true && findMissionForSpec(deps4.workspace, job.specName) !== void 0; + const schedulingRuntime = createSchedulingRuntime(deps4.config, deps4.workspace, { localManager, missionDriven, // vNext.5: whether prepaid strong compute exists at all. A roster with // no subscription worker is a different gap from an exhausted quota // window — it never "resets" — and the planner must be able to tell. - subscriptionWorkerAvailable: resolveWorkers(deps3.config).some( + subscriptionWorkerAvailable: resolveWorkers(deps4.config).some( (worker) => worker.reasoningTier !== "LOCAL_SMALL" ), options: { @@ -82945,32 +82967,32 @@ async function driveJob(deps3, jobId, options = {}) { for (; ; ) { loops += 1; if (loops > maxLoop) { - blockJob(deps3, jobId, { + blockJob(deps4, jobId, { category: "INTERNAL", code: "DRIVER_LOOP_BOUND", message: `The driver exceeded ${maxLoop} scheduling cycles without finishing; stopping for inspection.`, remediation: ["Inspect the job events; this indicates a scheduling defect, not a task failure."] }); - job = requireJobState(deps3.workspace, jobId); + job = requireJobState(deps4.workspace, jobId); return { stop: { kind: "blocked", reason: "driver loop bound reached" }, job }; } if (signal?.aborted === true) { - checkpointJob(deps3, jobId, "Interrupted; resume with `specbridge orchestrate run` to continue."); - job = requireJobState(deps3.workspace, jobId); + checkpointJob(deps4, jobId, "Interrupted; resume with `specbridge orchestrate run` to continue."); + job = requireJobState(deps4.workspace, jobId); return { stop: { kind: "interrupted" }, job }; } - const scheduleAt = (deps3.clock ?? (() => /* @__PURE__ */ new Date()))(); - job = clearRetryWait(deps3, jobId, scheduleAt); - const graph = activeGraph(deps3, job); - const workers = resolveWorkers(deps3.config); + const scheduleAt = (deps4.clock ?? (() => /* @__PURE__ */ new Date()))(); + job = clearRetryWait(deps4, jobId, scheduleAt); + const graph = activeGraph(deps4, job); + const workers = resolveWorkers(deps4.config); let lane; if (schedulingRuntime !== void 0 && graph !== void 0 && !isFinalJobStatus(job.status)) { - lane = await buildLaneContext(schedulingRuntime, deps3, jobId, job, graph); - emitSchedulingTransitions(deps3, jobId, schedulingRuntime, lane, emit22); + lane = await buildLaneContext(schedulingRuntime, deps4, jobId, job, graph); + emitSchedulingTransitions(deps4, jobId, schedulingRuntime, lane, emit22); if (lane.overtakeCandidate !== void 0 && job.status === "READY") { - promoteNodeForQuotaOvertake(deps3, jobId, lane.overtakeCandidate); + promoteNodeForQuotaOvertake(deps4, jobId, lane.overtakeCandidate); emit22("note", `quota overtake: ${lane.overtakeCandidate.detail}`); - job = requireJobState(deps3.workspace, jobId); + job = requireJobState(deps4.workspace, jobId); continue; } } @@ -82986,24 +83008,24 @@ async function driveJob(deps3, jobId, options = {}) { if (decision.kind !== "WAIT_QUOTA") unboundedQuotaDefers = 0; switch (decision.kind) { case "BUILD_GRAPH": { - const built = await buildJobGraph(deps3, jobId); + const built = await buildJobGraph(deps4, jobId); emit22("note", `Runtime graph: ${built.graph.nodes.length} node(s) from the approved task plan.`); - checkpointJob(deps3, jobId, "Graph built; classify and plan the first node."); + checkpointJob(deps4, jobId, "Graph built; classify and plan the first node."); break; } case "RUN_ROLE": { - const outcome = await handleRoleDecision(deps3, jobId, decision, { + const outcome = await handleRoleDecision(deps4, jobId, decision, { localManager, probeCache, signal, emit: emit22 }); if (outcome === "stop-interrupted") { - checkpointJob(deps3, jobId, "Interrupted during a role run; resume to continue."); - job = requireJobState(deps3.workspace, jobId); + checkpointJob(deps4, jobId, "Interrupted during a role run; resume to continue."); + job = requireJobState(deps4.workspace, jobId); return { stop: { kind: "interrupted" }, job }; } - checkpointJob(deps3, jobId, "Continue with the next scheduler decision."); + checkpointJob(deps4, jobId, "Continue with the next scheduler decision."); break; } case "DISPATCH_EXECUTOR": { @@ -83026,7 +83048,7 @@ async function driveJob(deps3, jobId, options = {}) { let quotaBefore; let contextBefore = null; if (schedulingRuntime !== void 0 && lane !== void 0 && laneName !== void 0 && laneRouting !== void 0) { - schedulingDecisionId = persistLaneDecision(deps3, jobId, { + schedulingDecisionId = persistLaneDecision(deps4, jobId, { nodeId: node.nodeId, taskId: node.parentTaskId, selectedLane: laneName, @@ -83042,7 +83064,7 @@ async function driveJob(deps3, jobId, options = {}) { } : {} }); if (laneName !== "API") { - recordJobEvent(deps3, jobId, laneName === "LOCAL" ? "task_routed_local" : "task_routed_subscription", { + recordJobEvent(deps4, jobId, laneName === "LOCAL" ? "task_routed_local" : "task_routed_subscription", { nodeId: node.nodeId, taskId: node.parentTaskId, reasonCode: laneRouting.routing.reasonCode, @@ -83052,7 +83074,7 @@ async function driveJob(deps3, jobId, options = {}) { }); } if (apiBridgedWhileMaxReturned && laneName === "SUBSCRIPTION") { - recordJobEvent(deps3, jobId, "api_next_task_returned_to_subscription", { + recordJobEvent(deps4, jobId, "api_next_task_returned_to_subscription", { nodeId: node.nodeId, taskId: node.parentTaskId, reasonCode: laneRouting.routing.reasonCode, @@ -83061,7 +83083,7 @@ async function driveJob(deps3, jobId, options = {}) { apiBridgedWhileMaxReturned = false; } if (localExecution !== void 0 && executionMode !== void 0) { - recordJobEvent(deps3, jobId, "local_execution_mode_selected", { + recordJobEvent(deps4, jobId, "local_execution_mode_selected", { nodeId: node.nodeId, taskId: node.parentTaskId, executionMode, @@ -83070,7 +83092,7 @@ async function driveJob(deps3, jobId, options = {}) { suitability: laneRouting.suitability.class }); if (executionMode === "HARNESS") { - recordJobEvent(deps3, jobId, "local_harness_selected", { + recordJobEvent(deps4, jobId, "local_harness_selected", { nodeId: node.nodeId, taskId: node.parentTaskId, profile: localExecution.harness?.profileName ?? "unknown", @@ -83079,7 +83101,7 @@ async function driveJob(deps3, jobId, options = {}) { reasonCode: localExecution.reasonCode ?? "UNKNOWN" }); } else if (localExecution.reasonCode === "LOCAL_HARNESS_NOT_VERIFIED_LOCAL") { - recordJobEvent(deps3, jobId, "local_harness_locality_rejected", { + recordJobEvent(deps4, jobId, "local_harness_locality_rejected", { nodeId: node.nodeId, taskId: node.parentTaskId, bindingStatus: schedulingRuntime?.harnessBinding.status ?? "UNKNOWN", @@ -83087,7 +83109,7 @@ async function driveJob(deps3, jobId, options = {}) { detail: (schedulingRuntime?.harnessBinding.problems[0] ?? "not verified local").slice(0, 300) }); } else if (localExecution.reasonCode === "LOCAL_HARNESS_UNAVAILABLE") { - recordJobEvent(deps3, jobId, "local_harness_unavailable", { + recordJobEvent(deps4, jobId, "local_harness_unavailable", { nodeId: node.nodeId, taskId: node.parentTaskId, bindingStatus: schedulingRuntime?.harnessBinding.status ?? "UNKNOWN", @@ -83096,7 +83118,7 @@ async function driveJob(deps3, jobId, options = {}) { } } if (laneName === "SUBSCRIPTION" && laneRouting.routing.admission?.crossesReset === true) { - recordJobEvent(deps3, jobId, "cross_reset_admitted", { + recordJobEvent(deps4, jobId, "cross_reset_admitted", { nodeId: node.nodeId, taskId: node.parentTaskId, preResetBurnRatio: laneRouting.routing.admission.preResetBurnRatio, @@ -83108,10 +83130,10 @@ async function driveJob(deps3, jobId, options = {}) { fiveHourRemainingRatio: lane.forecast.fiveHourRemainingRatio, weeklyRemainingRatio: lane.forecast.weeklyRemainingRatio }; - contextBefore = estimateNodeContextRatio(deps3, jobId, node.nodeId); + contextBefore = estimateNodeContextRatio(deps4, jobId, node.nodeId); if (decision.compactFirst === true) { - const reconstructed = reconstructTaskContext(deps3, { jobId, nodeId: node.nodeId }); - recordJobEvent(deps3, jobId, "context_compaction_before_dispatch", { + const reconstructed = reconstructTaskContext(deps4, { jobId, nodeId: node.nodeId }); + recordJobEvent(deps4, jobId, "context_compaction_before_dispatch", { nodeId: node.nodeId, contextUsageRatio: contextBefore, passes: reconstructed.assembled.compactions.map((record32) => record32.level), @@ -83135,7 +83157,7 @@ async function driveJob(deps3, jobId, options = {}) { } if (apiLane && schedulingRuntime !== void 0 && apiBridge !== void 0) { const apiPolicy = schedulingRuntime.policy.api; - recordJobEvent(deps3, jobId, "api_gap_detected", { + recordJobEvent(deps4, jobId, "api_gap_detected", { nodeId: node.nodeId, taskId: node.parentTaskId, gapReason: apiBridge.gap.reason, @@ -83147,19 +83169,19 @@ async function driveJob(deps3, jobId, options = {}) { reasonCode: apiBridge.reasonCode }); const reservation = reserveApiBudget({ - workspace: deps3.workspace, + workspace: deps4.workspace, jobId, nodeId: node.nodeId, taskId: node.parentTaskId, policy: apiPolicy.budget, safeCostUsd: apiBridge.cost?.safeCostUsd ?? null, profileName: schedulingRuntime.apiBinding.profileName, - now: (deps3.clock ?? (() => /* @__PURE__ */ new Date()))(), - reservationId: `ar-${(deps3.idFactory ?? (() => `${Date.now()}`))()}`.slice(0, 64), + now: (deps4.clock ?? (() => /* @__PURE__ */ new Date()))(), + reservationId: `ar-${(deps4.idFactory ?? (() => `${Date.now()}`))()}`.slice(0, 64), detail: apiBridge.detail }); if (!reservation.ok) { - recordJobEvent(deps3, jobId, "api_budget_exceeded", { + recordJobEvent(deps4, jobId, "api_budget_exceeded", { nodeId: node.nodeId, taskId: node.parentTaskId, refusal: reservation.admission.refusal ?? "UNKNOWN", @@ -83167,14 +83189,14 @@ async function driveJob(deps3, jobId, options = {}) { detail: reservation.admission.detail.slice(0, 300) }); if (reservation.admission.refusal === "JOB_CEILING" || reservation.admission.refusal === "JOB_ATTEMPTS") { - recordJobEvent(deps3, jobId, "api_budget_exhausted", { + recordJobEvent(deps4, jobId, "api_budget_exhausted", { jobId, refusal: reservation.admission.refusal, encumberedUsd: reservation.admission.job.encumberedUsd }); } emit22("waiting", `api budget refused: ${reservation.admission.detail}`); - job = deferJobForQuota(deps3, jobId, { + job = deferJobForQuota(deps4, jobId, { nodeId: node.nodeId, taskId: node.parentTaskId, until: apiBridge.gap.expectedAvailableAt, @@ -83183,11 +83205,11 @@ async function driveJob(deps3, jobId, options = {}) { pollMs: schedulingRuntime.policy.deferPollMs }); checkpointJob( - deps3, + deps4, jobId, "API budget refused the bridge; the task waits for subscription capacity." ); - job = requireJobState(deps3.workspace, jobId); + job = requireJobState(deps4.workspace, jobId); return { stop: { kind: "deferred", @@ -83199,7 +83221,7 @@ async function driveJob(deps3, jobId, options = {}) { } apiReservationId = reservation.reservation.reservationId; apiApprovalId = apiBridge.approval?.approval?.approvalId; - recordJobEvent(deps3, jobId, "api_budget_reserved", { + recordJobEvent(deps4, jobId, "api_budget_reserved", { nodeId: node.nodeId, taskId: node.parentTaskId, reservationId: apiReservationId, @@ -83212,7 +83234,7 @@ async function driveJob(deps3, jobId, options = {}) { `api budget reserved $${reservation.reservation.reservedUsd.toFixed(4)} for task ${node.parentTaskId}` ); } - beginExecutorDispatch(deps3, jobId, { + beginExecutorDispatch(deps4, jobId, { nodeId: decision.nodeId, mode: decision.mode, workerId: decision.worker.workerId, @@ -83231,7 +83253,7 @@ async function driveJob(deps3, jobId, options = {}) { // later should find comparable history already waiting, not start // learning from zero. ...laneRouting?.signature !== void 0 ? { taskSignature: laneRouting.signature.key } : {}, - contextStrategy: deps3.config.orchestration.jobs.context.efficiency.strategy, + contextStrategy: deps4.config.orchestration.jobs.context.efficiency.strategy, ...localExecution !== void 0 ? { executionShape: localExecution.shape, computeLocality: executionMode === "HARNESS" ? localExecution.harness?.locality ?? "UNKNOWN" : "LOCAL" @@ -83263,27 +83285,27 @@ async function driveJob(deps3, jobId, options = {}) { ...quotaBefore !== void 0 ? { quotaBefore } : {}, ...contextBefore !== null ? { contextUsageBefore: contextBefore } : {} }); - const startedAt = (deps3.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); + const startedAt = (deps4.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); if (apiLane && schedulingRuntime !== void 0 && apiBridge !== void 0) { - const attemptId = requireJobState(deps3.workspace, jobId).currentAttemptId; + const attemptId = requireJobState(deps4.workspace, jobId).currentAttemptId; if (attemptId !== void 0) { if (apiReservationId !== void 0) { bindApiBudgetReservation( - deps3.workspace, + deps4.workspace, jobId, apiReservationId, attemptId, - (deps3.clock ?? (() => /* @__PURE__ */ new Date()))() + (deps4.clock ?? (() => /* @__PURE__ */ new Date()))() ); } if (apiApprovalId !== void 0) { try { - consumeApiSpendApproval(deps3.workspace, jobId, apiApprovalId, attemptId); + consumeApiSpendApproval(deps4.workspace, jobId, apiApprovalId, attemptId); } catch { } } - writeApiHandoffCheckpoint(deps3, jobId, node, attemptId, apiBridge); - recordJobEvent(deps3, jobId, "api_task_dispatched", { + writeApiHandoffCheckpoint(deps4, jobId, node, attemptId, apiBridge); + recordJobEvent(deps4, jobId, "api_task_dispatched", { nodeId: node.nodeId, taskId: node.parentTaskId, attemptId, @@ -83301,12 +83323,12 @@ async function driveJob(deps3, jobId, options = {}) { } } const allowDirty = decision.mode === "repair" || (graph?.nodes.some((candidate) => candidate.status === "COMPLETED") ?? false) || node.attempts.some((attempt) => attempt.role === "EXECUTOR") || node.attempts.some((attempt) => attempt.role === "BUILDER"); - const mission = policy.objectives.enabled === true ? findMissionForSpec(deps3.workspace, job.specName) : void 0; + const mission = policy.objectives.enabled === true ? findMissionForSpec(deps4.workspace, job.specName) : void 0; const localHarnessLane = laneName === "LOCAL" && harnessProfileName !== void 0 && schedulingRuntime !== void 0; const localLane = laneName === "LOCAL" && !localHarnessLane && schedulingRuntime !== void 0 && schedulingRuntime.localInference !== void 0; const apiHarnessLane = apiLane && harnessProfileName !== void 0 && schedulingRuntime !== void 0; - const harnessCheckpoint = localHarnessLane || apiHarnessLane ? readLatestTaskCheckpoint(deps3.workspace, jobId, node.nodeId) : void 0; - const contextSupplement = deps3.config.orchestration.jobs.context.efficiency.strategy === "LEGACY" ? void 0 : await buildDispatchContext(deps3, { + const harnessCheckpoint = localHarnessLane || apiHarnessLane ? readLatestTaskCheckpoint(deps4.workspace, jobId, node.nodeId) : void 0; + const contextSupplement = deps4.config.orchestration.jobs.context.efficiency.strategy === "LEGACY" ? void 0 : await buildDispatchContext(deps4, { jobId, node, shape: localHarnessLane || apiHarnessLane ? "POINTER" : "MATERIALIZED", @@ -83320,9 +83342,9 @@ async function driveJob(deps3, jobId, options = {}) { // evidence pipeline, same completion authority — the only // differences are who is billed and what bounds the attempt. await dispatchApiHarnessExecution({ - workspace: deps3.workspace, - config: deps3.config, - registry: deps3.registry, + workspace: deps4.workspace, + config: deps4.config, + registry: deps4.registry, node, specName: job.specName, jobId, @@ -83342,15 +83364,15 @@ async function driveJob(deps3, jobId, options = {}) { contextPlanId: contextSupplement.planId } : {}, maxWallTimeMs: schedulingRuntime.apiBinding.maxWallTimeMs, - ...deps3.clock !== void 0 ? { clock: deps3.clock } : {}, - ...deps3.idFactory !== void 0 ? { idFactory: deps3.idFactory } : {}, + ...deps4.clock !== void 0 ? { clock: deps4.clock } : {}, + ...deps4.idFactory !== void 0 ? { idFactory: deps4.idFactory } : {}, ...signal !== void 0 ? { signal } : {}, onProgress: (message2) => emit22("note", message2) }) ) : localHarnessLane ? await dispatchLocalHarnessExecution({ - workspace: deps3.workspace, - config: deps3.config, - registry: deps3.registry, + workspace: deps4.workspace, + config: deps4.config, + registry: deps4.registry, node, specName: job.specName, jobId, @@ -83366,13 +83388,13 @@ async function driveJob(deps3, jobId, options = {}) { contextPlanId: contextSupplement.planId } : {}, maxWallTimeMs: schedulingRuntime.harnessBinding.maxWallTimeMs, - ...deps3.clock !== void 0 ? { clock: deps3.clock } : {}, - ...deps3.idFactory !== void 0 ? { idFactory: deps3.idFactory } : {}, + ...deps4.clock !== void 0 ? { clock: deps4.clock } : {}, + ...deps4.idFactory !== void 0 ? { idFactory: deps4.idFactory } : {}, ...signal !== void 0 ? { signal } : {}, onProgress: (message2) => emit22("note", message2) }) : localLane ? await dispatchLocalExecution({ - workspace: deps3.workspace, - config: deps3.config, + workspace: deps4.workspace, + config: deps4.config, node, specName: job.specName, mode: decision.mode, @@ -83385,29 +83407,29 @@ async function driveJob(deps3, jobId, options = {}) { repositoryContext: contextSupplement.rendered, contextPlanId: contextSupplement.planId } : {}, - ...deps3.clock !== void 0 ? { clock: deps3.clock } : {}, - ...deps3.idFactory !== void 0 ? { idFactory: deps3.idFactory } : {}, + ...deps4.clock !== void 0 ? { clock: deps4.clock } : {}, + ...deps4.idFactory !== void 0 ? { idFactory: deps4.idFactory } : {}, ...signal !== void 0 ? { signal } : {}, onProgress: (message2) => emit22("note", message2), - onInferenceCall: () => countLocalInferenceCall(deps3, jobId) + onInferenceCall: () => countLocalInferenceCall(deps4, jobId) }) : mission !== void 0 ? await driveObjective({ - workspace: deps3.workspace, - config: deps3.config, + workspace: deps4.workspace, + config: deps4.config, jobId, specName: job.specName, node, mission, policy, - workers: resolveWorkers(deps3.config), + workers: resolveWorkers(deps4.config), allowDirty, runnerProfile: decision.worker.runnerProfile, localManager, probeCache, - ...deps3.clock !== void 0 ? { clock: deps3.clock } : {}, - ...deps3.idFactory !== void 0 ? { idFactory: deps3.idFactory } : {}, + ...deps4.clock !== void 0 ? { clock: deps4.clock } : {}, + ...deps4.idFactory !== void 0 ? { idFactory: deps4.idFactory } : {}, ...signal !== void 0 ? { signal } : {}, - ...deps3.researchBridge !== void 0 ? { researchBridge: deps3.researchBridge } : {}, - ...deps3.secondaryObjectiveBuilder !== void 0 ? { secondaryBuilder: deps3.secondaryObjectiveBuilder } : {}, + ...deps4.researchBridge !== void 0 ? { researchBridge: deps4.researchBridge } : {}, + ...deps4.secondaryObjectiveBuilder !== void 0 ? { secondaryBuilder: deps4.secondaryObjectiveBuilder } : {}, ...lane?.forecast.schedulerMode !== void 0 ? { schedulerMode: lane.forecast.schedulerMode } : {}, ...lane?.forecast !== void 0 ? { strongResource: strongResourceFromScheduler({ @@ -83419,37 +83441,37 @@ async function driveJob(deps3, jobId, options = {}) { }) } : {}, onProgress: (message2) => emit22("note", message2), - countWorkerRun: (run) => recordObjectiveWorkerAttempt(deps3, jobId, { nodeId: node.nodeId, ...run }), - recordEvent: (type, payload) => recordJobEvent(deps3, jobId, type, payload) + countWorkerRun: (run) => recordObjectiveWorkerAttempt(deps4, jobId, { nodeId: node.nodeId, ...run }), + recordEvent: (type, payload) => recordJobEvent(deps4, jobId, type, payload) }) : await dispatchExecutor({ - workspace: deps3.workspace, - config: deps3.config, - registry: deps3.registry, + workspace: deps4.workspace, + config: deps4.config, + registry: deps4.registry, node, specName: job.specName, mode: decision.mode, allowDirty, runnerProfile: decision.worker.runnerProfile, ...options.executorTimeoutMs !== void 0 ? { timeoutMs: options.executorTimeoutMs } : {}, - ...deps3.clock !== void 0 ? { clock: deps3.clock } : {}, - ...deps3.idFactory !== void 0 ? { idFactory: deps3.idFactory } : {}, + ...deps4.clock !== void 0 ? { clock: deps4.clock } : {}, + ...deps4.idFactory !== void 0 ? { idFactory: deps4.idFactory } : {}, ...signal !== void 0 ? { signal } : {}, onProgress: (message2) => emit22("note", message2) }); const objectiveResourceWait = mission !== void 0 ? dispatch.resourceWait : void 0; if (objectiveResourceWait !== void 0) { - yieldExecutorForResourceWait(deps3, jobId, { + yieldExecutorForResourceWait(deps4, jobId, { nodeId: node.nodeId, detail: objectiveResourceWait.detail }); - job = enterResourceWait(deps3, jobId, { + job = enterResourceWait(deps4, jobId, { kind: objectiveResourceWait.kind, detail: objectiveResourceWait.detail, ...objectiveResourceWait.wakeAt !== void 0 ? { wakeAt: objectiveResourceWait.wakeAt } : {}, nodeId: node.nodeId }); checkpointJob( - deps3, + deps4, jobId, `Waiting for Strong resource recovery; ${objectiveResourceWait.waitingWorkUnitIds.length} WorkUnit(s) remain durably READY.` ); @@ -83469,7 +83491,7 @@ async function driveJob(deps3, jobId, options = {}) { if (localLane) { const localResult = dispatch; if (localResult.failure !== void 0) { - recordJobEvent(deps3, jobId, "local_attempt_failed", { + recordJobEvent(deps4, jobId, "local_attempt_failed", { nodeId: node.nodeId, taskId: node.parentTaskId, category: localResult.failure.category, @@ -83477,29 +83499,29 @@ async function driveJob(deps3, jobId, options = {}) { executionMode: "DIRECT_MODEL" }); } - const harnessCanTakeOver = schedulingRuntime !== void 0 && schedulingRuntime.harnessBinding.available && schedulingRuntime.policy.localExecution.strategy !== "DIRECT_ONLY" && localExecutorAttemptsUsed(deps3, jobId, node.nodeId) < schedulingRuntime.policy.maxLocalAttempts; + const harnessCanTakeOver = schedulingRuntime !== void 0 && schedulingRuntime.harnessBinding.available && schedulingRuntime.policy.localExecution.strategy !== "DIRECT_ONLY" && localExecutorAttemptsUsed(deps4, jobId, node.nodeId) < schedulingRuntime.policy.maxLocalAttempts; const needsRepositoryTools = localResult.failure !== void 0 && directFailureNeedsRepositoryTools(localResult); if (harnessCanTakeOver && needsRepositoryTools) { - noteEscalation(deps3, jobId, { + noteEscalation(deps4, jobId, { nodeId: node.nodeId, role: "EXECUTOR", reason: "LOCAL_DIRECT_TO_HARNESS", detail: (localResult.escalationReason ?? localResult.failure?.message ?? "the direct attempt lacked repository knowledge").slice(0, 500) }); - recordJobEvent(deps3, jobId, "local_direct_to_harness_escalated", { + recordJobEvent(deps4, jobId, "local_direct_to_harness_escalated", { nodeId: node.nodeId, taskId: node.parentTaskId, category: localResult.failure?.category ?? "unknown", detail: (localResult.escalationReason ?? "the direct attempt lacked repository knowledge").slice(0, 300) }); } else if (localResult.escalated) { - noteEscalation(deps3, jobId, { + noteEscalation(deps4, jobId, { nodeId: node.nodeId, role: "EXECUTOR", reason: "LOCAL_EXECUTION_ESCALATED", detail: (localResult.escalationReason ?? localResult.failure?.message ?? "local execution declined").slice(0, 500) }); - recordJobEvent(deps3, jobId, "local_escalation_triggered", { + recordJobEvent(deps4, jobId, "local_escalation_triggered", { nodeId: node.nodeId, taskId: node.parentTaskId, detail: (localResult.escalationReason ?? "bounded local attempts exhausted").slice(0, 300) @@ -83509,7 +83531,7 @@ async function driveJob(deps3, jobId, options = {}) { if (localHarnessLane) { const harnessResult = dispatch; if (harnessResult.failure !== void 0) { - recordJobEvent(deps3, jobId, "local_attempt_failed", { + recordJobEvent(deps4, jobId, "local_attempt_failed", { nodeId: node.nodeId, taskId: node.parentTaskId, category: harnessResult.failure.category, @@ -83518,23 +83540,23 @@ async function driveJob(deps3, jobId, options = {}) { failureKind: harnessResult.failureKind ?? "UNKNOWN" }); } - const localAttemptsAfter = localExecutorAttemptsUsed(deps3, jobId, node.nodeId) + 1; + const localAttemptsAfter = localExecutorAttemptsUsed(deps4, jobId, node.nodeId) + 1; const budgetSpent = schedulingRuntime !== void 0 && localAttemptsAfter >= schedulingRuntime.policy.maxLocalAttempts; const intelligenceFailure = harnessResult.failure !== void 0 && harnessResult.failureKind === "INTELLIGENCE"; if (intelligenceFailure && (harnessResult.escalated || budgetSpent)) { - noteEscalation(deps3, jobId, { + noteEscalation(deps4, jobId, { nodeId: node.nodeId, role: "EXECUTOR", reason: "LOCAL_EXECUTION_ESCALATED", detail: (harnessResult.escalationReason ?? harnessResult.failure?.message ?? "the local harness could not implement the task").slice(0, 500) }); - recordJobEvent(deps3, jobId, "local_harness_to_subscription_escalated", { + recordJobEvent(deps4, jobId, "local_harness_to_subscription_escalated", { nodeId: node.nodeId, taskId: node.parentTaskId, localAttempts: localAttemptsAfter, detail: (harnessResult.escalationReason ?? "local harness attempts exhausted").slice(0, 300) }); - recordJobEvent(deps3, jobId, "local_escalation_triggered", { + recordJobEvent(deps4, jobId, "local_escalation_triggered", { nodeId: node.nodeId, taskId: node.parentTaskId, detail: "the local harness did not produce a verifiable implementation" @@ -83547,7 +83569,7 @@ async function driveJob(deps3, jobId, options = {}) { extraMetrics = { fiveHourQuotaAfter: after.fiveHour?.remainingRatio ?? null, weeklyQuotaAfter: after.weekly?.remainingRatio ?? null, - contextUsageAfter: estimateNodeContextRatio(deps3, jobId, node.nodeId) + contextUsageAfter: estimateNodeContextRatio(deps4, jobId, node.nodeId) }; } if (localHarnessLane || apiHarnessLane) { @@ -83581,19 +83603,19 @@ async function driveJob(deps3, jobId, options = {}) { }; if (apiReservationId !== void 0) { const reconciled = reconcileApiBudget({ - workspace: deps3.workspace, + workspace: deps4.workspace, jobId, reservationId: apiReservationId, observedCostUsd: observedCost.costUsd, costSource: observedCost.source, - now: (deps3.clock ?? (() => /* @__PURE__ */ new Date()))(), + now: (deps4.clock ?? (() => /* @__PURE__ */ new Date()))(), detail: observedCost.detail }); const summary = summarizeApiBudget( - readApiBudgetState(deps3.workspace, jobId), + readApiBudgetState(deps4.workspace, jobId), schedulingRuntime.policy.api.budget ); - recordJobEvent(deps3, jobId, "api_budget_reconciled", { + recordJobEvent(deps4, jobId, "api_budget_reconciled", { nodeId: node.nodeId, taskId: node.parentTaskId, reservationId: apiReservationId, @@ -83605,7 +83627,7 @@ async function driveJob(deps3, jobId, options = {}) { remainingUsd: summary.remainingUsd }); if (observedCost.costUsd === null) { - recordJobEvent(deps3, jobId, "api_cost_unknown", { + recordJobEvent(deps4, jobId, "api_cost_unknown", { nodeId: node.nodeId, taskId: node.parentTaskId, reservationId: apiReservationId, @@ -83618,7 +83640,7 @@ async function driveJob(deps3, jobId, options = {}) { ); } if (apiResult.failure !== void 0) { - recordJobEvent(deps3, jobId, "api_attempt_failed", { + recordJobEvent(deps4, jobId, "api_attempt_failed", { nodeId: node.nodeId, taskId: node.parentTaskId, category: apiResult.failure.category, @@ -83630,7 +83652,7 @@ async function driveJob(deps3, jobId, options = {}) { const fiveHourBack = (after.fiveHour?.remainingRatio ?? 0) > schedulingRuntime.policy.fiveHourExhaustedRatio; const weeklyBack = (after.weekly?.remainingRatio ?? 0) > schedulingRuntime.policy.weeklyExhaustedRatio; if (fiveHourBack && weeklyBack) { - recordJobEvent(deps3, jobId, "api_max_returned", { + recordJobEvent(deps4, jobId, "api_max_returned", { nodeId: node.nodeId, taskId: node.parentTaskId, fiveHourRemainingRatio: after.fiveHour?.remainingRatio ?? null, @@ -83640,11 +83662,11 @@ async function driveJob(deps3, jobId, options = {}) { apiBridgedWhileMaxReturned = true; } } - const acceptanceCriteria = resolveAcceptanceCriteria(deps3, jobId, job.specName, node.nodeId); + const acceptanceCriteria = resolveAcceptanceCriteria(deps4, jobId, job.specName, node.nodeId); const dispatchVerification = dispatch.verification; const reliabilityInput = { ...buildReliabilityInput({ - deps: deps3, + deps: deps4, jobId, dispatch, lane: laneName, @@ -83669,7 +83691,7 @@ async function driveJob(deps3, jobId, options = {}) { ...acceptanceCriteria.length > 0 ? { acceptanceCriteria, criteriaEvidence: buildCriteriaEvidence({ - workspaceRoot: deps3.workspace.rootDir, + workspaceRoot: deps4.workspace.rootDir, changedPaths: (dispatch.changedFiles ?? []).map((file) => file.path), verifierResults: new Map( (dispatchVerification?.commands ?? []).map((command) => [ @@ -83680,7 +83702,7 @@ async function driveJob(deps3, jobId, options = {}) { }) } : {} }; - const result = completeExecutorDispatch(deps3, jobId, { + const result = completeExecutorDispatch(deps4, jobId, { context: { nodeId: decision.nodeId, role: "EXECUTOR", @@ -83707,12 +83729,12 @@ async function driveJob(deps3, jobId, options = {}) { `task ${decision.taskId}: ${dispatch.evidenceStatus ?? dispatch.failure?.category ?? "unknown"} \u2192 ${result.nextAction}` ); checkpointJob( - deps3, + deps4, jobId, result.nextAction === "job-complete" ? "Job complete." : `Executor outcome ${result.nextAction}; continue with the next scheduler decision.` ); if (result.nextAction === "job-complete") { - job = requireJobState(deps3.workspace, jobId); + job = requireJobState(deps4.workspace, jobId); return { stop: { kind: "completed" }, job }; } break; @@ -83725,7 +83747,7 @@ async function driveJob(deps3, jobId, options = {}) { } case "WAIT_QUOTA": { if (schedulingRuntime !== void 0 && lane !== void 0) { - persistLaneDecision(deps3, jobId, { + persistLaneDecision(deps4, jobId, { nodeId: decision.nodeId, taskId: decision.taskId, selectedLane: decision.awaitingApiApproval === true ? "REQUIRE_APPROVAL" : "DEFER", @@ -83737,9 +83759,9 @@ async function driveJob(deps3, jobId, options = {}) { lane, apiBinding: schedulingRuntime.apiBinding }); - recordApiGapObservations(deps3, jobId, schedulingRuntime, decision, graph, emit22); + recordApiGapObservations(deps4, jobId, schedulingRuntime, decision, graph, emit22); } - job = deferJobForQuota(deps3, jobId, { + job = deferJobForQuota(deps4, jobId, { nodeId: decision.nodeId, taskId: decision.taskId, until: decision.until, @@ -83748,7 +83770,7 @@ async function driveJob(deps3, jobId, options = {}) { pollMs: schedulingRuntime?.policy.deferPollMs ?? 6e4 }); emit22("waiting", `quota: ${decision.reasonCode} \u2014 ${decision.reason}`); - const nowMs = (deps3.clock ?? (() => /* @__PURE__ */ new Date()))().getTime(); + const nowMs = (deps4.clock ?? (() => /* @__PURE__ */ new Date()))().getTime(); const waitMs = Math.max(0, Date.parse(job.retryAt ?? new Date(nowMs).toISOString()) - nowMs); const holdMs = schedulingRuntime?.policy.maxQuotaHoldMs ?? 6e5; unboundedQuotaDefers = decision.until === null ? unboundedQuotaDefers + 1 : 0; @@ -83756,8 +83778,8 @@ async function driveJob(deps3, jobId, options = {}) { await sleep2(waitMs, signal); break; } - checkpointJob(deps3, jobId, `Deferred for subscription quota until ${job.retryAt ?? "unknown"}; resume to continue.`); - job = requireJobState(deps3.workspace, jobId); + checkpointJob(deps4, jobId, `Deferred for subscription quota until ${job.retryAt ?? "unknown"}; resume to continue.`); + job = requireJobState(deps4.workspace, jobId); return { stop: { kind: "deferred", until: job.retryAt ?? null, reason: decision.reason }, job @@ -83765,26 +83787,26 @@ async function driveJob(deps3, jobId, options = {}) { } case "AWAIT_HUMAN": { checkpointJob( - deps3, + deps4, jobId, decision.what === "plan-review" ? "Review the pending plan, then resume the job." : decision.what === "authority" ? "Decide the open authority question, then resume the job." : "Answer the open clarification question(s), then resume the job." ); - job = requireJobState(deps3.workspace, jobId); + job = requireJobState(deps4.workspace, jobId); return { stop: { kind: "needs-human", what: decision.what, detail: decision.reason }, job }; } case "JOB_COMPLETE": { - job = completeJobIfDone(deps3, jobId); + job = completeJobIfDone(deps4, jobId); if (job.status !== "COMPLETED") { - checkpointJob(deps3, jobId, "Contract closure decides what remains."); + checkpointJob(deps4, jobId, "Contract closure decides what remains."); return { stop: { kind: "final", status: job.status }, job }; } - checkpointJob(deps3, jobId, "Job complete."); + checkpointJob(deps4, jobId, "Job complete."); return { stop: { kind: "completed" }, job }; } case "JOB_BLOCKED": { - job = requireJobState(deps3.workspace, jobId); + job = requireJobState(deps4.workspace, jobId); if (job.status !== "BLOCKED") { - blockJob(deps3, jobId, { + blockJob(deps4, jobId, { category: decision.budget !== void 0 ? "BUDGET_EXHAUSTED" : "BLOCKED_DEPENDENCY", code: decision.budget ?? "BLOCKED", message: decision.reason, @@ -83794,12 +83816,12 @@ async function driveJob(deps3, jobId, options = {}) { ] }); } - checkpointJob(deps3, jobId, "Blocked; an explicit user action is required."); - job = requireJobState(deps3.workspace, jobId); + checkpointJob(deps4, jobId, "Blocked; an explicit user action is required."); + job = requireJobState(deps4.workspace, jobId); return { stop: { kind: "blocked", reason: decision.reason }, job }; } case "JOB_FINAL": { - job = requireJobState(deps3.workspace, jobId); + job = requireJobState(deps4.workspace, jobId); return { stop: { kind: "final", status: job.status }, job }; } } @@ -83808,11 +83830,11 @@ async function driveJob(deps3, jobId, options = {}) { await localManager?.stop("driver exit"); } } -function resolveAcceptanceCriteria(deps3, jobId, specName, nodeId) { +function resolveAcceptanceCriteria(deps4, jobId, specName, nodeId) { const criteria = []; - const mission = findMissionForSpec(deps3.workspace, specName); + const mission = findMissionForSpec(deps4.workspace, specName); if (mission !== void 0) { - for (const contract of readContractRegistry(deps3.workspace, mission.missionId)) { + for (const contract of readContractRegistry(deps4.workspace, mission.missionId)) { for (const invariant of contract.invariants) { for (const [index, pattern] of invariant.guardPatterns.entries()) { criteria.push({ @@ -83824,7 +83846,7 @@ function resolveAcceptanceCriteria(deps3, jobId, specName, nodeId) { } } } - const checkpoint = readLatestTaskCheckpoint(deps3.workspace, jobId, nodeId); + const checkpoint = readLatestTaskCheckpoint(deps4.workspace, jobId, nodeId); for (const [index, statement] of (checkpoint?.pinned.acceptanceCriteria ?? []).entries()) { criteria.push({ id: `AC-${index + 1}`, text: statement.slice(0, 2e3) }); } @@ -83901,11 +83923,11 @@ function directFailureNeedsRepositoryTools(result) { } return failure3.category === "CAPABILITY_UNAVAILABLE" && result.escalationReason !== void 0; } -function writeApiHandoffCheckpoint(deps3, jobId, node, attemptId, bridge) { +function writeApiHandoffCheckpoint(deps4, jobId, node, attemptId, bridge) { try { - const previous = readLatestTaskCheckpoint(deps3.workspace, jobId, node.nodeId); + const previous = readLatestTaskCheckpoint(deps4.workspace, jobId, node.nodeId); createTaskCheckpoint( - { workspace: deps3.workspace, clock: deps3.clock, idFactory: deps3.idFactory }, + { workspace: deps4.workspace, clock: deps4.clock, idFactory: deps4.idFactory }, { jobId, nodeId: node.nodeId, @@ -83933,11 +83955,11 @@ function writeApiHandoffCheckpoint(deps3, jobId, node, attemptId, bridge) { } catch { } } -function recordApiGapObservations(deps3, jobId, runtime, decision, graph, emit22) { +function recordApiGapObservations(deps4, jobId, runtime, decision, graph, emit22) { const bridge = decision.laneRouting?.apiBridge; if (bridge === void 0) return; - const now52 = (deps3.clock ?? (() => /* @__PURE__ */ new Date()))(); - recordJobEvent(deps3, jobId, "api_gap_detected", { + const now52 = (deps4.clock ?? (() => /* @__PURE__ */ new Date()))(); + recordJobEvent(deps4, jobId, "api_gap_detected", { nodeId: decision.nodeId, taskId: decision.taskId, gapReason: bridge.gap.reason, @@ -83949,7 +83971,7 @@ function recordApiGapObservations(deps3, jobId, runtime, decision, graph, emit22 reasonCode: bridge.reasonCode }); if (bridge.reasonCode === "API_GAP_SHORT_DEFER" || bridge.reasonCode === "API_WASTEFUL_NEAR_RESET") { - recordJobEvent(deps3, jobId, "api_gap_short_deferred", { + recordJobEvent(deps4, jobId, "api_gap_short_deferred", { nodeId: decision.nodeId, taskId: decision.taskId, estimatedGapDurationMs: bridge.gap.timeUntilAvailableMs, @@ -83957,14 +83979,14 @@ function recordApiGapObservations(deps3, jobId, runtime, decision, graph, emit22 }); } if (bridge.reasonCode === "API_COST_UNKNOWN") { - recordJobEvent(deps3, jobId, "api_cost_unknown", { + recordJobEvent(deps4, jobId, "api_cost_unknown", { nodeId: decision.nodeId, taskId: decision.taskId, detail: (bridge.cost?.detail ?? bridge.detail).slice(0, 300) }); } if (bridge.reasonCode === "API_BUDGET_EXCEEDED") { - recordJobEvent(deps3, jobId, "api_budget_exceeded", { + recordJobEvent(deps4, jobId, "api_budget_exceeded", { nodeId: decision.nodeId, taskId: decision.taskId, refusal: bridge.budget?.refusal ?? "UNKNOWN", @@ -83980,7 +84002,7 @@ function recordApiGapObservations(deps3, jobId, runtime, decision, graph, emit22 const safeCost = bridge.cost?.safeCostUsd; if (safeCost === null || safeCost === void 0) return; const requested = requestApiSpendApproval({ - workspace: deps3.workspace, + workspace: deps4.workspace, jobId, nodeId: node.nodeId, taskId: node.parentTaskId, @@ -83989,12 +84011,12 @@ function recordApiGapObservations(deps3, jobId, runtime, decision, graph, emit22 maxAuthorizedCostUsd: safeCost, estimatedCostUsd: bridge.cost?.estimatedCostUsd ?? null, rationale: bridge.detail, - approvalId: `aa-${(deps3.idFactory ?? (() => `${Date.now()}`))()}`.slice(0, 64), + approvalId: `aa-${(deps4.idFactory ?? (() => `${Date.now()}`))()}`.slice(0, 64), now: now52, ttlMs: runtime.policy.api.gap.approvalTtlMs }); if (!requested.created) return; - recordJobEvent(deps3, jobId, "api_approval_required", { + recordJobEvent(deps4, jobId, "api_approval_required", { nodeId: node.nodeId, taskId: node.parentTaskId, approvalId: requested.approval.approvalId, @@ -84011,13 +84033,13 @@ function recordApiGapObservations(deps3, jobId, runtime, decision, graph, emit22 `api spend approval required (${requested.approval.approvalId}): up to $${safeCost.toFixed(4)} on "${profileName}" for task ${node.parentTaskId}` ); } -function persistLaneDecision(deps3, jobId, input) { - const createdAt = (deps3.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); - const decisionId = `sd-${(deps3.idFactory ?? (() => `${Date.now()}`))()}`.slice(0, 64); +function persistLaneDecision(deps4, jobId, input) { + const createdAt = (deps4.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); + const decisionId = `sd-${(deps4.idFactory ?? (() => `${Date.now()}`))()}`.slice(0, 64); const routing = input.laneRouting; try { appendSchedulingDecision( - deps3.workspace, + deps4.workspace, { schemaVersion: "1.0.0", decisionId, @@ -84043,7 +84065,7 @@ function persistLaneDecision(deps3, jobId, input) { preResetBurnRatio: routing?.routing.admission?.preResetBurnRatio ?? null, crossesReset: routing?.routing.admission?.crossesReset ?? false, contextStatus: routing !== void 0 ? { - usageRatio: estimateNodeContextRatio(deps3, jobId, input.nodeId), + usageRatio: estimateNodeContextRatio(deps4, jobId, input.nodeId), compactFirst: routing.routing.compactFirst } : null, localExecution: routing?.localExecution?.mode != null && routing.localExecution.reasonCode !== null ? { @@ -84065,7 +84087,7 @@ function persistLaneDecision(deps3, jobId, input) { // ones where it declined to spend. apiBridge: routing?.apiBridge !== void 0 ? { decision: routing.apiBridge.decision, - spendMode: deps3.config.orchestration.jobs.scheduler.api.spendMode, + spendMode: deps4.config.orchestration.jobs.scheduler.api.spendMode, gapReason: routing.apiBridge.gap.reason, subscriptionAvailableAt: routing.apiBridge.gap.expectedAvailableAt, estimatedGapDurationMs: routing.apiBridge.gap.timeUntilAvailableMs, @@ -84094,11 +84116,11 @@ function persistLaneDecision(deps3, jobId, input) { detail: input.detail.slice(0, 2e3), createdAt }, - { maxRecords: deps3.config.orchestration.jobs.scheduler.maxDecisionRecords } + { maxRecords: deps4.config.orchestration.jobs.scheduler.maxDecisionRecords } ); } catch { } - recordJobEvent(deps3, jobId, "scheduling_decision_created", { + recordJobEvent(deps4, jobId, "scheduling_decision_created", { decisionId, nodeId: input.nodeId, taskId: input.taskId, @@ -84108,14 +84130,14 @@ function persistLaneDecision(deps3, jobId, input) { ...input.deferUntil !== null ? { deferUntil: input.deferUntil } : {} }); if (routing !== void 0) { - recordJobEvent(deps3, jobId, "local_suitability_classified", { + recordJobEvent(deps4, jobId, "local_suitability_classified", { nodeId: input.nodeId, taskId: input.taskId, suitability: routing.suitability.class, category: routing.suitability.category, signals: routing.suitability.signals.slice(0, 5).map((signal) => signal.signal) }); - recordJobEvent(deps3, jobId, "workload_estimated", { + recordJobEvent(deps4, jobId, "workload_estimated", { nodeId: input.nodeId, taskId: input.taskId, expectedWallTimeMs: routing.estimate.expectedWallTimeMs, @@ -84125,7 +84147,7 @@ function persistLaneDecision(deps3, jobId, input) { basis: routing.estimate.basis }); } - persistAdaptiveDecision(deps3, jobId, { + persistAdaptiveDecision(deps4, jobId, { nodeId: input.nodeId, taskId: input.taskId, heuristicLane: input.selectedLane, @@ -84136,7 +84158,7 @@ function persistLaneDecision(deps3, jobId, input) { }); return decisionId; } -function persistAdaptiveDecision(deps3, jobId, input) { +function persistAdaptiveDecision(deps4, jobId, input) { const adaptive = input.lane.adaptive; if (adaptive === void 0) return; const ranking = adaptive.rankings.get(input.nodeId); @@ -84144,7 +84166,7 @@ function persistAdaptiveDecision(deps3, jobId, input) { if (ranking === void 0 || signature2 === void 0) return; try { appendAdaptiveDecision( - deps3.workspace, + deps4.workspace, { schemaVersion: ADAPTIVE_DECISION_SCHEMA_VERSION, decisionId: `ad-${input.decisionId}`.slice(0, 200), @@ -84236,11 +84258,11 @@ function persistAdaptiveDecision(deps3, jobId, input) { profileBuiltAt: adaptive.profiles.builtAt, createdAt: input.createdAt }, - { maxRecords: deps3.config.orchestration.jobs.scheduler.adaptive.maxDecisionRecords } + { maxRecords: deps4.config.orchestration.jobs.scheduler.adaptive.maxDecisionRecords } ); } catch { } - recordJobEvent(deps3, jobId, "adaptive_prediction_created", { + recordJobEvent(deps4, jobId, "adaptive_prediction_created", { nodeId: input.nodeId, taskId: input.taskId, mode: ranking.mode, @@ -84251,7 +84273,7 @@ function persistAdaptiveDecision(deps3, jobId, input) { }); for (const veto of ranking.vetoes) { if (veto.code === "LANE_NOT_ELIGIBLE") continue; - recordJobEvent(deps3, jobId, "adaptive_candidate_vetoed", { + recordJobEvent(deps4, jobId, "adaptive_candidate_vetoed", { nodeId: input.nodeId, taskId: input.taskId, candidateId: veto.candidateId, @@ -84260,7 +84282,7 @@ function persistAdaptiveDecision(deps3, jobId, input) { } const drifting = ranking.ranked.filter((entry2) => entry2.prediction.drift.detected); for (const entry2 of drifting) { - recordJobEvent(deps3, jobId, "adaptive_drift_detected", { + recordJobEvent(deps4, jobId, "adaptive_drift_detected", { nodeId: input.nodeId, candidateId: entry2.prediction.candidate.candidateId, signals: entry2.prediction.drift.signals, @@ -84268,7 +84290,7 @@ function persistAdaptiveDecision(deps3, jobId, input) { }); } if (ranking.adaptiveApplied) { - recordJobEvent(deps3, jobId, "adaptive_candidate_selected", { + recordJobEvent(deps4, jobId, "adaptive_candidate_selected", { nodeId: input.nodeId, taskId: input.taskId, selected: ranking.selectedCandidate?.candidateId ?? null, @@ -84279,7 +84301,7 @@ function persistAdaptiveDecision(deps3, jobId, input) { return; } if (ranking.mode === "SHADOW" && ranking.disagreement) { - recordJobEvent(deps3, jobId, "adaptive_shadow_disagreement", { + recordJobEvent(deps4, jobId, "adaptive_shadow_disagreement", { nodeId: input.nodeId, taskId: input.taskId, executed: ranking.heuristicCandidate?.candidateId ?? null, @@ -84290,7 +84312,7 @@ function persistAdaptiveDecision(deps3, jobId, input) { return; } if (ranking.fallbackReason !== null && ranking.fallbackReason !== "AGREES_WITH_HEURISTIC") { - recordJobEvent(deps3, jobId, "adaptive_fallback_to_heuristic", { + recordJobEvent(deps4, jobId, "adaptive_fallback_to_heuristic", { nodeId: input.nodeId, taskId: input.taskId, reason: ranking.fallbackReason, @@ -84298,10 +84320,10 @@ function persistAdaptiveDecision(deps3, jobId, input) { }); } } -function emitSchedulingTransitions(deps3, jobId, runtime, lane, emit22) { +function emitSchedulingTransitions(deps4, jobId, runtime, lane, emit22) { const forecast = lane.forecast; if (runtime.lastObservedAt !== forecast.observedAt) { - recordJobEvent(deps3, jobId, "quota_snapshot_updated", { + recordJobEvent(deps4, jobId, "quota_snapshot_updated", { fiveHourRemainingRatio: forecast.fiveHourRemainingRatio, weeklyRemainingRatio: forecast.weeklyRemainingRatio, fiveHourResetAt: forecast.fiveHourResetAt, @@ -84313,7 +84335,7 @@ function emitSchedulingTransitions(deps3, jobId, runtime, lane, emit22) { } if (runtime.lastFreshness !== forecast.telemetryFreshness) { if (forecast.telemetryFreshness === "STALE") { - recordJobEvent(deps3, jobId, "quota_telemetry_stale", { + recordJobEvent(deps4, jobId, "quota_telemetry_stale", { observedAt: forecast.observedAt, staleThresholdMs: runtime.policy.telemetryStaleMs }); @@ -84323,7 +84345,7 @@ function emitSchedulingTransitions(deps3, jobId, runtime, lane, emit22) { } if (runtime.lastMode !== forecast.schedulerMode) { if (runtime.lastMode !== void 0) { - recordJobEvent(deps3, jobId, "scheduler_mode_changed", { + recordJobEvent(deps4, jobId, "scheduler_mode_changed", { from: runtime.lastMode, to: forecast.schedulerMode, fiveHourRemainingRatio: forecast.fiveHourRemainingRatio, @@ -84332,16 +84354,16 @@ function emitSchedulingTransitions(deps3, jobId, runtime, lane, emit22) { }); } if (forecast.schedulerMode === "HARVEST") { - recordJobEvent(deps3, jobId, "harvest_entered", { + recordJobEvent(deps4, jobId, "harvest_entered", { fiveHourRemainingRatio: forecast.fiveHourRemainingRatio, timeToFiveHourResetMs: forecast.timeToFiveHourResetMs, reserveRatio: lane.reserve.ratio }); } else if (runtime.lastMode === "HARVEST") { - recordJobEvent(deps3, jobId, "harvest_exited", { to: forecast.schedulerMode }); + recordJobEvent(deps4, jobId, "harvest_exited", { to: forecast.schedulerMode }); } if (forecast.schedulerMode === "EXHAUSTED_5H" || forecast.schedulerMode === "EXHAUSTED_WEEKLY") { - recordJobEvent(deps3, jobId, "quota_exhausted", { + recordJobEvent(deps4, jobId, "quota_exhausted", { window: forecast.schedulerMode === "EXHAUSTED_5H" ? "five-hour" : "weekly", resetAt: forecast.schedulerMode === "EXHAUSTED_5H" ? forecast.fiveHourResetAt : forecast.weeklyResetAt }); @@ -84352,7 +84374,7 @@ function emitSchedulingTransitions(deps3, jobId, runtime, lane, emit22) { const reserveDelta = runtime.lastReserveRatio === void 0 ? Number.POSITIVE_INFINITY : Math.abs(lane.reserve.ratio - runtime.lastReserveRatio); if (reserveDelta >= 0.05) { if (runtime.lastReserveRatio !== void 0) { - recordJobEvent(deps3, jobId, "dynamic_reserve_changed", { + recordJobEvent(deps4, jobId, "dynamic_reserve_changed", { from: runtime.lastReserveRatio, to: lane.reserve.ratio, timeComponent: lane.reserve.basis.timeComponent, @@ -84363,18 +84385,18 @@ function emitSchedulingTransitions(deps3, jobId, runtime, lane, emit22) { runtime.lastReserveRatio = lane.reserve.ratio; } } -async function handleRoleDecision(deps3, jobId, decision, runtime) { - const policy = deps3.config.orchestration.jobs; +async function handleRoleDecision(deps4, jobId, decision, runtime) { + const policy = deps4.config.orchestration.jobs; const role = decision.role; - const job = requireJobState(deps3.workspace, jobId); - const graph = activeGraph(deps3, job); + const job = requireJobState(deps4.workspace, jobId); + const graph = activeGraph(deps4, job); const node = graph !== void 0 ? findNode(graph, decision.nodeId) : void 0; if (node === void 0) { throw new OrchestrationError("SBO031", `Node ${decision.nodeId} vanished between scheduling and the role run.`); } if (decision.escalation !== void 0) { if (!escalationAllowed(policy) && decision.worker.costTier === "PAID") { - askClarification(deps3, jobId, [ + askClarification(deps4, jobId, [ { question: `Escalate ${role} for task ${node.parentTaskId} to the paid large agent? (${decision.escalation.detail})`, whyItMatters: "Escalation mode is manual; paid reasoning needs an explicit decision.", @@ -84383,7 +84405,7 @@ async function handleRoleDecision(deps3, jobId, decision, runtime) { ]); return "continue"; } - noteEscalation(deps3, jobId, { + noteEscalation(deps4, jobId, { nodeId: node.nodeId, role, reason: decision.escalation.reason, @@ -84391,26 +84413,26 @@ async function handleRoleDecision(deps3, jobId, decision, runtime) { }); } if (role === "PLANNER" && job.status === "READY") { - beginPlanning(deps3, jobId, node.nodeId); + beginPlanning(deps4, jobId, node.nodeId); } - recordJobEvent(deps3, jobId, "worker_selected", { + recordJobEvent(deps4, jobId, "worker_selected", { nodeId: node.nodeId, role, workerId: decision.worker.workerId, tier: decision.worker.reasoningTier }); - const startedAt = (deps3.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); - const specExcerpt = specExcerptFor(deps3.workspace, job.specName, 12e3); + const startedAt = (deps4.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); + const specExcerpt = specExcerptFor(deps4.workspace, job.specName, 12e3); const packetBase = { specName: job.specName, taskId: node.parentTaskId, taskTitle: node.title, specExcerpt }; - const activePlan = readActivePlan(deps3, jobId, node); - const packet = buildPacketFor(deps3, jobId, role, packetBase, node, activePlan, job); + const activePlan = readActivePlan(deps4, jobId, node); + const packet = buildPacketFor(deps4, jobId, role, packetBase, node, activePlan, job); runtime.emit("role-started", `${role} for task ${node.parentTaskId} on ${decision.worker.workerId}`); - const result = await runRole(deps3, jobId, role, decision, packet, runtime); + const result = await runRole(deps4, jobId, role, decision, packet, runtime); if (!result.ok) { if (result.kind === "cancelled") return "stop-interrupted"; const attemptContext = { @@ -84420,7 +84442,7 @@ async function handleRoleDecision(deps3, jobId, decision, runtime) { startedAt }; if (decision.worker.reasoningTier === "LOCAL_SMALL") { - recordRoleFailure(deps3, jobId, { + recordRoleFailure(deps4, jobId, { context: attemptContext, outcome: result.kind === "invalid-output" ? "invalid-output" : "failed", escalation: { @@ -84434,12 +84456,12 @@ async function handleRoleDecision(deps3, jobId, decision, runtime) { const previousLargeFailures = node.attempts.filter( (attempt) => attempt.role === role && attempt.workerId === decision.worker.workerId && (attempt.outcome === "failed" || attempt.outcome === "invalid-output") ).length; - recordRoleFailure(deps3, jobId, { + recordRoleFailure(deps4, jobId, { context: attemptContext, outcome: result.kind === "invalid-output" ? "invalid-output" : "failed" }); if (previousLargeFailures >= 1) { - blockJob(deps3, jobId, { + blockJob(deps4, jobId, { category: "CAPABILITY_UNAVAILABLE", code: "LARGE_WORKER_FAILED", message: `The large-agent ${role} failed twice: ${result.problem.slice(0, 500)}`, @@ -84456,7 +84478,7 @@ async function handleRoleDecision(deps3, jobId, decision, runtime) { runtime.emit("role-finished", `${role} failed on the large tier (${result.kind})`); return "continue"; } - const agentResultRef = persistAgentResult(deps3, jobId, role, result.raw); + const agentResultRef = persistAgentResult(deps4, jobId, role, result.raw); const context = { nodeId: node.nodeId, role, @@ -84465,18 +84487,18 @@ async function handleRoleDecision(deps3, jobId, decision, runtime) { ...agentResultRef !== void 0 ? { agentResultRef } : {}, ...result.usage !== void 0 ? { usage: result.usage } : {} }; - await applyRoleOutput(deps3, jobId, role, result, context, node, activePlan); + await applyRoleOutput(deps4, jobId, role, result, context, node, activePlan); runtime.emit("role-finished", `${role} for task ${node.parentTaskId} succeeded`); return "continue"; } -function readActivePlan(deps3, jobId, node) { +function readActivePlan(deps4, jobId, node) { if (node.planRevision === 0) return void 0; - const raw = readNodePlan(deps3.workspace, jobId, node.nodeId, node.planRevision); + const raw = readNodePlan(deps4.workspace, jobId, node.nodeId, node.planRevision); if (raw === void 0) return void 0; const parsed = executionPlanSchema.safeParse(raw); return parsed.success ? parsed.data : void 0; } -function buildPacketFor(deps3, jobId, role, base, node, activePlan, job) { +function buildPacketFor(deps4, jobId, role, base, node, activePlan, job) { switch (role) { case "CLASSIFIER": return buildClassifierPacket(base); @@ -84521,8 +84543,8 @@ function buildPacketFor(deps3, jobId, role, base, node, activePlan, job) { if (activePlan === void 0) { throw new OrchestrationError("SBO031", "The replanner needs the invalidated plan document."); } - const latestAssessment = listFailureAssessments(deps3.workspace, jobId, { nodeId: node.nodeId }).at(-1); - const reliabilityState = readTaskReliabilityState(deps3.workspace, jobId, node.nodeId); + const latestAssessment = listFailureAssessments(deps4.workspace, jobId, { nodeId: node.nodeId }).at(-1); + const reliabilityState = readTaskReliabilityState(deps4.workspace, jobId, node.nodeId); const researchEligibility = latestAssessment === void 0 ? void 0 : evaluateRuntimeResearchTrigger({ explicitExternalKnowledgeGap: false, externalAssumptionContradiction: false, @@ -84535,7 +84557,7 @@ function buildPacketFor(deps3, jobId, role, base, node, activePlan, job) { failureFingerprint: latestAssessment.fingerprint, observations: reliabilityState?.observations ?? [] }); - const researchEvidence = runtimeResearchForJob(deps3, jobId).map((record32) => ({ + const researchEvidence = runtimeResearchForJob(deps4, jobId).map((record32) => ({ researchId: record32.researchId, summary: renderResearchEvidence(record32.report) })); @@ -84561,28 +84583,28 @@ function buildPacketFor(deps3, jobId, role, base, node, activePlan, job) { } } } -async function runRole(deps3, jobId, role, decision, packet, runtime) { +async function runRole(deps4, jobId, role, decision, packet, runtime) { if (decision.worker.reasoningTier === "LOCAL_SMALL") { if (runtime.localManager === void 0) { return { ok: false, kind: "worker-unavailable", problem: "No local model manager is active." }; } return runLocalRole({ manager: runtime.localManager, - config: deps3.config, + config: deps4.config, role, packet, - maxCorrections: deps3.config.orchestration.jobs.maxLocalOutputCorrections, - onInferenceCall: () => countLocalInferenceCall(deps3, jobId), + maxCorrections: deps4.config.orchestration.jobs.maxLocalOutputCorrections, + onInferenceCall: () => countLocalInferenceCall(deps4, jobId), signal: runtime.signal }); } const result = await runLargeRole({ - workspace: deps3.workspace, - config: deps3.config, - runnerProfile: decision.worker.runnerProfile ?? deps3.config.defaultRunner, + workspace: deps4.workspace, + config: deps4.config, + runnerProfile: decision.worker.runnerProfile ?? deps4.config.defaultRunner, role, packet, - scratchDir: import_path46.default.join(jobDir(deps3.workspace, jobId), "scratch"), + scratchDir: import_path46.default.join(jobDir(deps4.workspace, jobId), "scratch"), timeoutMs: 6e5, signal: runtime.signal, cachedProbe: runtime.probeCache.probe @@ -84590,18 +84612,18 @@ async function runRole(deps3, jobId, role, decision, packet, runtime) { if (result.probe !== void 0) runtime.probeCache.probe = result.probe; return result; } -async function applyRoleOutput(deps3, jobId, role, result, context, node, activePlan) { +async function applyRoleOutput(deps4, jobId, role, result, context, node, activePlan) { const producedByTier = context.workerId === "local-llamacpp" ? "LOCAL_SMALL" : "LARGE_AGENT"; switch (role) { case "CLASSIFIER": { const output = result.output; - recordClassification(deps3, jobId, { context, proposedClass: output.complexity }); + recordClassification(deps4, jobId, { context, proposedClass: output.complexity }); return; } case "PLANNER": { const output = result.output; if (output.decision === "ESCALATE" || output.requiresEscalation) { - recordRoleFailure(deps3, jobId, { + recordRoleFailure(deps4, jobId, { context, outcome: "escalated", escalation: { @@ -84612,7 +84634,7 @@ async function applyRoleOutput(deps3, jobId, role, result, context, node, active return; } if (output.steps.length === 0 || output.goal === void 0) { - recordRoleFailure(deps3, jobId, { + recordRoleFailure(deps4, jobId, { context, outcome: "escalated", escalation: { @@ -84622,7 +84644,7 @@ async function applyRoleOutput(deps3, jobId, role, result, context, node, active }); return; } - await recordPlan(deps3, jobId, { + await recordPlan(deps4, jobId, { context, candidate: plannerOutputToCandidate(output), producedByTier @@ -84631,13 +84653,13 @@ async function applyRoleOutput(deps3, jobId, role, result, context, node, active } case "CRITIC": { const output = result.output; - recordCriticVerdict(deps3, jobId, { + recordCriticVerdict(deps4, jobId, { context, verdict: output.verdict, reasons: [...output.reasons, ...output.requestedChanges] }); if (output.verdict === "ESCALATE") { - noteEscalation(deps3, jobId, { + noteEscalation(deps4, jobId, { nodeId: node.nodeId, role: "CRITIC", reason: "CRITIC_ESCALATED", @@ -84648,7 +84670,7 @@ async function applyRoleOutput(deps3, jobId, role, result, context, node, active } case "DIAGNOSER": { const output = result.output; - applyDiagnosis(deps3, jobId, { + applyDiagnosis(deps4, jobId, { context, category: output.category, planValidity: output.planValidity, @@ -84660,7 +84682,7 @@ async function applyRoleOutput(deps3, jobId, role, result, context, node, active case "REPLANNER": { const output = result.output; if (output.decision === "ESCALATE") { - recordRoleFailure(deps3, jobId, { + recordRoleFailure(deps4, jobId, { context, outcome: "escalated", escalation: { @@ -84671,7 +84693,7 @@ async function applyRoleOutput(deps3, jobId, role, result, context, node, active return; } if (output.decision === "BLOCKED") { - blockJob(deps3, jobId, { + blockJob(deps4, jobId, { category: "BLOCKED_DEPENDENCY", code: "REPLANNER_BLOCKED", message: output.reason, @@ -84680,12 +84702,12 @@ async function applyRoleOutput(deps3, jobId, role, result, context, node, active return; } if (output.decision === "SUPERSEDE_NODE") { - supersedeNode(deps3, jobId, { nodeId: node.nodeId, reason: output.reason }); - recordResearchInformedReplan(deps3, jobId, node.nodeId, output.reason); + supersedeNode(deps4, jobId, { nodeId: node.nodeId, reason: output.reason }); + recordResearchInformedReplan(deps4, jobId, node.nodeId, output.reason); return; } if (output.steps.length === 0 || output.goal === void 0) { - recordRoleFailure(deps3, jobId, { + recordRoleFailure(deps4, jobId, { context, outcome: "escalated", escalation: { @@ -84701,7 +84723,7 @@ async function applyRoleOutput(deps3, jobId, role, result, context, node, active activePlan !== void 0 ? { goal: activePlan.goal, steps: activePlan.steps.map((step2) => ({ description: step2.description })) } : void 0 ); if (output.impactsApprovedIntent || screen.impacts) { - const delegated = resolveDelegatedAuthority(deps3.authorityResolver, { + const delegated = resolveDelegatedAuthority(deps4.authorityResolver, { jobId, nodeId: node.nodeId, decisionKinds: screen.decisionKinds, @@ -84710,17 +84732,17 @@ async function applyRoleOutput(deps3, jobId, role, result, context, node, active ${candidate.steps.map((step2) => step2.description).join("\n")}`.slice(0, 4e3) }); if (delegated?.kind === "AUTONOMOUS") { - recordJobEvent(deps3, jobId, "authority_delegated", { + recordJobEvent(deps4, jobId, "authority_delegated", { nodeId: node.nodeId, decisionKinds: [...screen.decisionKinds], reason: delegated.reason.slice(0, 300) }); - await recordPlan(deps3, jobId, { context, candidate, producedByTier }, { replan: true }); - recordResearchInformedReplan(deps3, jobId, node.nodeId, output.reason); + await recordPlan(deps4, jobId, { context, candidate, producedByTier }, { replan: true }); + recordResearchInformedReplan(deps4, jobId, node.nodeId, output.reason); return; } if (delegated?.kind === "NEEDS_AUTHORITY") { - escalateAuthority(deps3, jobId, { + escalateAuthority(deps4, jobId, { surface: delegated.surface, reason: delegated.reason, question: delegated.question, @@ -84730,7 +84752,7 @@ ${candidate.steps.map((step2) => step2.description).join("\n")}`.slice(0, 4e3) }); return; } - askClarification(deps3, jobId, [ + askClarification(deps4, jobId, [ { question: `The proposed replacement plan for task ${node.parentTaskId} may change approved intent${screen.reasons.length > 0 ? ` (${screen.reasons.join("; ")})` : ""}. Proceed, change the spec, or decide otherwise?`, whyItMatters: "Replanning may never silently change approved behavior, public API, architecture, or product decisions.", @@ -84739,16 +84761,16 @@ ${candidate.steps.map((step2) => step2.description).join("\n")}`.slice(0, 4e3) ]); return; } - await recordPlan(deps3, jobId, { context, candidate, producedByTier }, { replan: true }); - recordResearchInformedReplan(deps3, jobId, node.nodeId, output.reason); + await recordPlan(deps4, jobId, { context, candidate, producedByTier }, { replan: true }); + recordResearchInformedReplan(deps4, jobId, node.nodeId, output.reason); return; } } } -async function buildDispatchContext(deps3, input) { - const attemptId = requireJobState(deps3.workspace, input.jobId).currentAttemptId; +async function buildDispatchContext(deps4, input) { + const attemptId = requireJobState(deps4.workspace, input.jobId).currentAttemptId; try { - const built = await buildTaskContextPackage(deps3, { + const built = await buildTaskContextPackage(deps4, { jobId: input.jobId, nodeId: input.node.nodeId, role: "EXECUTOR", @@ -84758,7 +84780,7 @@ async function buildDispatchContext(deps3, input) { ...input.executionMode !== void 0 ? { executionMode: input.executionMode } : {}, ...input.runner !== void 0 ? { runner: input.runner } : {} }); - recordJobEvent(deps3, input.jobId, "context_selected", { + recordJobEvent(deps4, input.jobId, "context_selected", { nodeId: input.node.nodeId, taskId: input.node.parentTaskId, planId: built.plan.planId, @@ -86972,16 +86994,16 @@ function buildContextReport(workspace, jobId) { let expansions = 0; let nativeCompactions = null; let strategy = null; - for (const metric of metrics) { - estimated = add(estimated, metric.estimatedContextTokens); - providerInput = add(providerInput, metric.providerReportedInputTokens); - workingSet = add(workingSet, metric.selectedFiles + metric.selectedSections); - const compressionDelta = metric.compressionSourceChars > 0 ? metric.compressionSourceChars - metric.compressionOutputChars : null; + for (const metric2 of metrics) { + estimated = add(estimated, metric2.estimatedContextTokens); + providerInput = add(providerInput, metric2.providerReportedInputTokens); + workingSet = add(workingSet, metric2.selectedFiles + metric2.selectedSections); + const compressionDelta = metric2.compressionSourceChars > 0 ? metric2.compressionSourceChars - metric2.compressionOutputChars : null; compressionSaved = add(compressionSaved, compressionDelta); - dedupSaved = add(dedupSaved, metric.deduplicationSavedChars > 0 ? metric.deduplicationSavedChars : null); - expansions += metric.contextExpansions; - nativeCompactions = add(nativeCompactions, metric.nativeCompactions); - strategy = metric.strategy; + dedupSaved = add(dedupSaved, metric2.deduplicationSavedChars > 0 ? metric2.deduplicationSavedChars : null); + expansions += metric2.contextExpansions; + nativeCompactions = add(nativeCompactions, metric2.nativeCompactions); + strategy = metric2.strategy; } let providerOutput = null; for (const entry2 of entries) providerOutput = add(providerOutput, entry2.metrics.outputTokens); @@ -88101,10 +88123,10 @@ function collectVersions(config2, overrides = {}) { policyFingerprint: overrides.policyFingerprint ?? null }; } -function startQualificationRun(deps3, request) { - const now52 = deps3.clock().toISOString(); - const runId = request.runId ?? `qual-${deps3.idFactory()}`; - const existing = readDogfoodRun(deps3.workspace, runId); +function startQualificationRun(deps4, request) { + const now52 = deps4.clock().toISOString(); + const runId = request.runId ?? `qual-${deps4.idFactory()}`; + const existing = readDogfoodRun(deps4.workspace, runId); if (existing !== void 0) { throw new OrchestrationError("SBO052", `Qualification run "${runId}" already exists.`, { remediation: [ @@ -88113,15 +88135,15 @@ function startQualificationRun(deps3, request) { ] }); } - const previous = request.previousRunId === void 0 || request.previousRunId === null ? void 0 : readDogfoodRun(deps3.workspace, request.previousRunId); + const previous = request.previousRunId === void 0 || request.previousRunId === null ? void 0 : readDogfoodRun(deps4.workspace, request.previousRunId); const run = dogfoodRunSchema.parse({ schemaVersion: DOGFOOD_RUN_SCHEMA_VERSION, runId, status: "PREFLIGHT", profile: request.profile, target: request.target, - versions: collectVersions(deps3.config, request.versions ?? {}), - configurationFingerprint: configurationFingerprint(deps3.config), + versions: collectVersions(deps4.config, request.versions ?? {}), + configurationFingerprint: configurationFingerprint(deps4.config), missionId: request.missionId ?? null, jobId: request.jobId ?? null, iteration: previous === void 0 ? 1 : previous.iteration + 1, @@ -88136,21 +88158,21 @@ function startQualificationRun(deps3, request) { pausedMs: 0, note: null }); - return writeDogfoodRun(deps3.workspace, run); + return writeDogfoodRun(deps4.workspace, run); } -function transition3(deps3, runId, status, note) { - const run = requireDogfoodRun(deps3.workspace, runId); +function transition3(deps4, runId, status, note) { + const run = requireDogfoodRun(deps4.workspace, runId); if (isFinalDogfoodRunStatus(run.status)) { throw new OrchestrationError( "SBO052", `Qualification run "${runId}" is already ${run.status} and cannot transition to ${status}.` ); } - const now52 = deps3.clock(); + const now52 = deps4.clock(); const elapsed = Math.max(0, now52.getTime() - Date.parse(run.updatedAt)); const activeMs = run.status === "PAUSED" ? run.activeMs : run.activeMs + elapsed; const pausedMs = run.status === "PAUSED" ? run.pausedMs + elapsed : run.pausedMs; - return writeDogfoodRun(deps3.workspace, { + return writeDogfoodRun(deps4.workspace, { ...run, status, activeMs, @@ -88160,10 +88182,10 @@ function transition3(deps3, runId, status, note) { note: note ?? run.note }); } -function markRunRunning(deps3, runId, note) { - return transition3(deps3, runId, "RUNNING", note); +function markRunRunning(deps4, runId, note) { + return transition3(deps4, runId, "RUNNING", note); } -function recordScenarioResult(deps3, input) { +function recordScenarioResult(deps4, input) { const scenario = findScenario(input.scenarioId); if (scenario === void 0) { throw new OrchestrationError( @@ -88186,7 +88208,7 @@ function recordScenarioResult(deps3, input) { { remediation: ["A failed scenario must record what was expected and what was observed."] } ); } - return writeScenarioResult(deps3.workspace, { + return writeScenarioResult(deps4.workspace, { schemaVersion: "1.0.0", runId: input.runId, scenarioId: scenario.id, @@ -88203,7 +88225,7 @@ function recordScenarioResult(deps3, input) { resourceAttribution: { ...input.resourceAttribution ?? {} }, executor: input.executor, durationMs: input.durationMs ?? null, - recordedAt: deps3.clock().toISOString() + recordedAt: deps4.clock().toISOString() }); } function listRuns2(workspace) { @@ -89814,17 +89836,17 @@ function skipReasonFor(scenario, profile, targetAvailable) { return "No executable implementation is registered for this scenario in this invocation."; } function runQualificationScenarios(input) { - const { deps: deps3, run, executor } = input; + const { deps: deps4, run, executor } = input; const only = input.only === void 0 ? null : new Set(input.only); const existing = new Map( - listScenarioResults(deps3.workspace, run.runId).map((result) => [result.scenarioId, result]) + listScenarioResults(deps4.workspace, run.runId).map((result) => [result.scenarioId, result]) ); const targetAvailable = run.target.kind === "REAL_REPOSITORY" && run.target.available; const executed = []; const skipped = []; const preserved = []; const outcomes = new Map( - runPolicyScenarios(deps3.config).map((outcome) => [outcome.scenarioId, outcome]) + runPolicyScenarios(deps4.config).map((outcome) => [outcome.scenarioId, outcome]) ); for (const scenario of QUALIFICATION_SCENARIOS) { if (only !== null && !only.has(scenario.id)) { @@ -89841,7 +89863,7 @@ function runQualificationScenarios(input) { const runnable = outcome !== void 0 && profileSatisfies(run.profile, scenario.minimumProfile); if (runnable) { executed.push( - recordScenarioResult(deps3, { + recordScenarioResult(deps4, { runId: run.runId, scenarioId: scenario.id, status: outcome.passed ? "PASS" : "FAIL", @@ -89858,7 +89880,7 @@ function runQualificationScenarios(input) { continue; } skipped.push( - recordScenarioResult(deps3, { + recordScenarioResult(deps4, { runId: run.runId, scenarioId: scenario.id, status: "SKIPPED_WITH_REASON", @@ -90350,6 +90372,88 @@ ${report.specResults.map((spec, index) => renderSpec(spec, index)).join("\n")} `; } +function percent(metric2) { + return metric2.value === null ? "n/a" : `${(metric2.value * 100).toFixed(1)}%`; +} +function tokens(metric2) { + if (metric2.knownTokens === null) return "n/a (provider did not report usage)"; + const coverage = metric2.coverage.ratio === null ? "n/a" : `${Math.round(metric2.coverage.ratio * 100)}%`; + return `${metric2.knownTokens.toLocaleString("en-US")} known (${coverage} attempt coverage${metric2.coverage.complete ? ", complete" : ", partial"})`; +} +function duration(value) { + if (value === null) return "n/a"; + if (value >= 36e5) return `${(value / 36e5).toFixed(1)}h`; + if (value >= 6e4) return `${(value / 6e4).toFixed(1)}m`; + return `${(value / 1e3).toFixed(1)}s`; +} +function renderExecutionTelemetryReport(report, options = {}) { + const lines = [reportTitle(`Job ${report.jobId} \u2014 ${report.outcome.status}`)]; + lines.push(infoLine(`authoritative state: ${report.outcome.authoritativeJobStatus}`)); + lines.push(infoLine(`elapsed ${duration(report.period.durationMs)} \xB7 active ${duration(report.period.activeExecutionMs)}`)); + lines.push("", sectionTitle("Zero-touch status")); + lines.push( + report.human.zeroTouchAfterSeal ? okLine("ZeroTouchAfterSeal: true (0 human interventions)") : failLine(`ZeroTouchAfterSeal: false (${report.human.interventionsAfterSeal} intervention(s))`) + ); + lines.push(infoLine(`pre-seal decisions ${report.human.decisionsBeforeSeal ?? "n/a"} \xB7 approvals ${report.human.approvals} \xB7 post-seal authority stops ${report.human.authorityEscalationsAfterSeal ?? "n/a"}`)); + lines.push("", sectionTitle("Work summary")); + lines.push(infoLine(`${report.work.total} WorkUnit(s) \xB7 ${report.work.accounting.completed} completed \xB7 ${report.work.accounting.failed} failed \xB7 ${report.work.accounting.waiting} waiting`)); + lines.push(infoLine(`${report.work.completedImplementation} implementation WorkUnit(s) integrated \xB7 ${report.attempts.uniqueImplementationAttempts} unique implementation attempt(s)`)); + lines.push("", sectionTitle("Secondary Builder efficiency")); + lines.push(infoLine(`${report.secondary.eligibility.eligible} eligible \xB7 ${report.secondary.selection.secondarySelected} selected \xB7 ${report.secondary.funnel.initialPass} initial pass \xB7 ${report.secondary.funnel.repairPass} repair pass`)); + lines.push(infoLine(`StrongBuilderAvoidanceRatio ${percent(report.efficiency.strongBuilderAvoidanceRatio)} (${report.efficiency.strongBuilderAvoidanceRatio.numerator ?? "n/a"}/${report.efficiency.strongBuilderAvoidanceRatio.denominator ?? "n/a"})`)); + lines.push(infoLine(`SecondaryInitialSuccessRate ${percent(report.secondary.initialSuccessRate)} \xB7 SecondaryRepairRecoveryRate ${percent(report.secondary.repairRecoveryRate)} \xB7 fallback ${percent(report.secondary.toStrongFallbackRate)}`)); + lines.push(infoLine(`Secondary builder tokens: ${tokens(report.secondary.builderTokens)}`)); + lines.push("", sectionTitle("Strong usage")); + lines.push(infoLine(`${report.strong.builderAttempts} Strong Builder attempt(s) \xB7 ${report.strong.evaluatorAttempts} Strong Evaluator attempt(s)`)); + lines.push(infoLine(`Strong implementation tokens: ${tokens(report.strong.implementationTokens)}`)); + lines.push(infoLine(`Strong evaluator tokens: ${tokens(report.strong.evaluatorTokens)}`)); + lines.push("", sectionTitle("Research efficiency")); + lines.push(infoLine(`scope ${report.research.scope} \xB7 considered ${report.research.considered ?? "n/a"} \xB7 new calls ${report.research.providerCalls} \xB7 reused ${report.research.priorResearchReused}`)); + lines.push(infoLine(`ResearchAvoidanceRatio ${percent(report.research.avoidanceRatio)} \xB7 reuse rate ${percent(report.research.reuseRate)} \xB7 QUICK ${report.research.newQuick} \xB7 DEEP ${report.research.newDeep}`)); + lines.push("", sectionTitle("Subscription cooldown")); + lines.push(infoLine(`${report.cooldown.episodes} episode(s) \xB7 ${duration(report.cooldown.totalDurationMs)} known duration \xB7 ${report.cooldown.usefulWorkDuringSubscriptionCooldown} useful WorkUnit(s)`)); + lines.push( + report.cooldown.avoidableIdlePeriods === 0 ? okLine("AvoidableIdleDuringCooldown: 0") : warnLine(`AvoidableIdleDuringCooldown: ${report.cooldown.avoidableIdlePeriods}`) + ); + lines.push("", sectionTitle("Reliability / resume")); + lines.push(infoLine(`restarts ${report.reliability.processRestarts + report.reliability.supervisorRestarts} \xB7 candidates reused ${report.reliability.candidatesReusedAfterRestart} \xB7 candidate rebuilds ${report.reliability.candidateRebuildsAfterRestart}`)); + lines.push( + report.reliability.completedWorkRedoCount === 0 ? okLine("CompletedWorkRedoCount: 0") : failLine(`CompletedWorkRedoCount: ${report.reliability.completedWorkRedoCount}`) + ); + lines.push("", sectionTitle("Verification & closure")); + lines.push( + report.outcome.verification === "PASS" ? okLine(`verification PASS (${report.verification.passes}/${report.verification.attempts} WorkUnit evaluation passes)`) : report.outcome.verification === "FAIL" ? failLine(`verification FAIL (${report.verification.failures} WorkUnit evaluation failure(s))`) : warnLine(`verification n/a (${report.verification.passes} WorkUnit evaluation pass(es), authoritative job evidence unavailable)`) + ); + lines.push( + report.outcome.closure === "PASS" ? okLine(`closure PASS (${report.closure.earned} earned, ${report.closure.waived} waived)`) : report.outcome.closure === "FAIL" ? failLine(`closure FAIL (${report.closure.unresolved} unresolved)`) : warnLine("closure n/a (no closure ledger)") + ); + if (report.diagnostics.length > 0) { + lines.push("", sectionTitle("Diagnostics")); + for (const diagnostic of report.diagnostics.slice(0, options.verbose === true ? 200 : 10)) { + lines.push( + diagnostic.severity === "error" ? failLine(`${diagnostic.code}: ${diagnostic.message}`) : diagnostic.severity === "warning" ? warnLine(`${diagnostic.code}: ${diagnostic.message}`) : infoLine(`${diagnostic.code}: ${diagnostic.message}`) + ); + } + } + if (options.verbose === true) { + lines.push("", sectionTitle("Objective accounting")); + for (const objective of report.work.objectives) { + lines.push(infoLine(`${objective.objectiveNodeId} \xB7 revision ${objective.graphRevision ?? "n/a"} \xB7 ${objective.total} WorkUnit(s) \xB7 ${objective.implementationAttempts} implementation attempt(s) (${objective.secondaryAttempts} Secondary, ${objective.strongBuilderAttempts} Strong)`)); + } + lines.push("", sectionTitle("WorkUnit accounting")); + for (const unit of report.work.units) { + lines.push(infoLine(`${unit.objectiveNodeId}/${unit.workUnitId} \xB7 ${unit.accounting} \xB7 ${unit.builderPath} \xB7 ${unit.implementationAttempts} attempt(s) \xB7 verification ${unit.verification}`)); + } + if (report.cooldown.timeline.length > 0) { + lines.push("", sectionTitle("Cooldown timeline")); + for (const entry2 of report.cooldown.timeline) { + lines.push(infoLine(`${entry2.at} \xB7 ${entry2.type} \xB7 ${entry2.detail}`)); + } + } + } + return `${lines.join("\n")} +`; +} // ../../packages/cli/src/context.ts var import_node_path7 = __toESM(require("path"), 1); @@ -90725,9 +90829,9 @@ function statusFor2(code2) { } function parseNameStatusZ(raw) { const changes = []; - const tokens = raw.split("\0"); - for (let i2 = 0; i2 < tokens.length; i2 += 1) { - const code2 = tokens[i2]; + const tokens2 = raw.split("\0"); + for (let i2 = 0; i2 < tokens2.length; i2 += 1) { + const code2 = tokens2[i2]; if (code2 === void 0 || code2.length === 0) continue; const changeType = statusFor2(code2); if (changeType === void 0) { @@ -90735,8 +90839,8 @@ function parseNameStatusZ(raw) { continue; } if (changeType === "renamed" || changeType === "copied") { - const oldPath = tokens[i2 + 1]; - const newPath = tokens[i2 + 2]; + const oldPath = tokens2[i2 + 1]; + const newPath = tokens2[i2 + 2]; i2 += 2; if (oldPath === void 0 || newPath === void 0 || newPath.length === 0) continue; changes.push({ @@ -90747,7 +90851,7 @@ function parseNameStatusZ(raw) { symlinkOutsideRepository: false }); } else { - const filePath = tokens[i2 + 1]; + const filePath = tokens2[i2 + 1]; i2 += 1; if (filePath === void 0 || filePath.length === 0) continue; changes.push({ path: filePath, changeType, binary: false, symlinkOutsideRepository: false }); @@ -90757,9 +90861,9 @@ function parseNameStatusZ(raw) { } function parseNumstatZ(raw) { const stats = /* @__PURE__ */ new Map(); - const tokens = raw.split("\0"); - for (let i2 = 0; i2 < tokens.length; i2 += 1) { - const token = tokens[i2]; + const tokens2 = raw.split("\0"); + for (let i2 = 0; i2 < tokens2.length; i2 += 1) { + const token = tokens2[i2]; if (token === void 0 || token.length === 0) continue; const match = /^(-|\d+)\t(-|\d+)\t(.*)$/s.exec(token); if (match === null) continue; @@ -90768,7 +90872,7 @@ function parseNumstatZ(raw) { const binary = match[1] === "-" && match[2] === "-"; let filePath = match[3] ?? ""; if (filePath.length === 0) { - const newPath = tokens[i2 + 2]; + const newPath = tokens2[i2 + 2]; i2 += 2; if (newPath === void 0) continue; filePath = newPath; @@ -102633,10 +102737,10 @@ var import_node_fs9 = require("fs"); // ../../packages/intake/dist/index.js var import_crypto30 = require("crypto"); -var import_fs81 = require("fs"); -var import_path90 = __toESM(require("path"), 1); var import_fs82 = require("fs"); var import_path91 = __toESM(require("path"), 1); +var import_fs83 = require("fs"); +var import_path92 = __toESM(require("path"), 1); // ../../packages/autonomy/dist/index.js var import_crypto29 = require("crypto"); @@ -102655,6 +102759,8 @@ var import_fs79 = require("fs"); var import_path88 = __toESM(require("path"), 1); var import_fs80 = require("fs"); var import_path89 = __toESM(require("path"), 1); +var import_fs81 = require("fs"); +var import_path90 = __toESM(require("path"), 1); var SEAL_STATUSES = [ /** Drafted from mission state; not yet authorized by a human. */ "DRAFT", @@ -103141,26 +103247,26 @@ var AutonomyError = class extends Error { this.retryable = options.retryable ?? false; } }; -function jobDepsOf(deps3) { - return deps3; +function jobDepsOf(deps4) { + return deps4; } -function autonomyPolicyOf(deps3) { - return deps3.config.autonomy; +function autonomyPolicyOf(deps4) { + return deps4.config.autonomy; } -function now5(deps3) { - return (deps3.clock ?? (() => /* @__PURE__ */ new Date()))(); +function now5(deps4) { + return (deps4.clock ?? (() => /* @__PURE__ */ new Date()))(); } -function nowIso5(deps3) { - return now5(deps3).toISOString(); +function nowIso5(deps4) { + return now5(deps4).toISOString(); } -function newId5(deps3) { - return (deps3.idFactory ?? import_crypto29.randomUUID)(); +function newId5(deps4) { + return (deps4.idFactory ?? import_crypto29.randomUUID)(); } -function hostOf(deps3) { - return deps3.host ?? "cli"; +function hostOf(deps4) { + return deps4.host ?? "cli"; } -function newRecordId(deps3, prefix) { - const raw = newId5(deps3).replace(/[^A-Za-z0-9._-]/g, "").slice(0, 40); +function newRecordId(deps4, prefix) { + const raw = newId5(deps4).replace(/[^A-Za-z0-9._-]/g, "").slice(0, 40); return `${prefix}-${raw.length > 0 ? raw : "x"}`; } var ID_PATTERN10 = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/; @@ -103407,13 +103513,13 @@ function computeAuthorityDigest(seal) { }; return sha256Hex(JSON.stringify(canonical)).slice(0, 32); } -function draftSeal(deps3, request) { - const mission = requireMissionState(deps3.workspace, request.missionId); - const policy = autonomyPolicyOf(deps3); - const contracts = readContractRegistry(deps3.workspace, request.missionId); - const constitution = readConstitution(deps3.workspace, request.missionId); - const adrs = readAdrs(deps3.workspace, request.missionId); - const decisions = readDecisions(deps3.workspace, request.missionId).filter( +function draftSeal(deps4, request) { + const mission = requireMissionState(deps4.workspace, request.missionId); + const policy = autonomyPolicyOf(deps4); + const contracts = readContractRegistry(deps4.workspace, request.missionId); + const constitution = readConstitution(deps4.workspace, request.missionId); + const adrs = readAdrs(deps4.workspace, request.missionId); + const decisions = readDecisions(deps4.workspace, request.missionId).filter( (decision) => decision.status === "active" ); const contractRefs = contracts.filter((contract) => contract.status !== "superseded").slice(0, SEAL_LIMITS.maxContractRefs).map((contract) => ({ @@ -103448,20 +103554,20 @@ function draftSeal(deps3, request) { toolsmithCapabilities: [...policy.toolsmith.capabilities] } }; - const sealId = request.sealId ?? newRecordId(deps3, "seal"); + const sealId = request.sealId ?? newRecordId(deps4, "seal"); const seal = missionSealSchema.parse({ schemaVersion: SEAL_SCHEMA_VERSION, sealId, missionId: mission.missionId, ...mission.specName !== void 0 ? { specName: mission.specName } : {}, status: "DRAFT", - createdAt: nowIso5(deps3), + createdAt: nowIso5(deps4), ...request.supersedes !== void 0 ? { supersedes: request.supersedes } : {}, ...base, presentAuthorityKinds: presentAuthorityKinds(base), authorityDigest: computeAuthorityDigest(base) }); - writeImmutableRecord(sealFile(deps3.workspace, sealId), seal, "seal"); + writeImmutableRecord(sealFile(deps4.workspace, sealId), seal, "seal"); return seal; } function presentAuthorityKinds(base) { @@ -103518,8 +103624,8 @@ function gapExplanation(kind) { return `The seal is missing ${kind}.`; } } -function sealMission(deps3, request) { - const existing = requireSeal(deps3.workspace, request.sealId); +function sealMission(deps4, request) { + const existing = requireSeal(deps4.workspace, request.sealId); if (existing.status === "SEALED") return existing; if (isFinalSealStatus(existing.status)) { throw new AutonomyError( @@ -103542,32 +103648,32 @@ function sealMission(deps3, request) { const sealed = missionSealSchema.parse({ ...existing, status: "SEALED", - sealedAt: nowIso5(deps3), - sealedVia: (request.via ?? hostOf(deps3)).slice(0, SEAL_LIMITS.maxShortTextChars) + sealedAt: nowIso5(deps4), + sealedVia: (request.via ?? hostOf(deps4)).slice(0, SEAL_LIMITS.maxShortTextChars) }); - writeJsonRecord(sealFile(deps3.workspace, existing.sealId), sealed); + writeJsonRecord(sealFile(deps4.workspace, existing.sealId), sealed); if (existing.supersedes !== void 0) { - markSuperseded(deps3, existing.supersedes, existing.sealId); + markSuperseded(deps4, existing.supersedes, existing.sealId); } return sealed; } -function markSuperseded(deps3, sealId, bySealId) { - const previous = readSeal(deps3.workspace, sealId); +function markSuperseded(deps4, sealId, bySealId) { + const previous = readSeal(deps4.workspace, sealId); if (previous === void 0 || previous.status === "SUPERSEDED") return; writeJsonRecord( - sealFile(deps3.workspace, sealId), + sealFile(deps4.workspace, sealId), missionSealSchema.parse({ ...previous, status: "SUPERSEDED", supersededBy: bySealId }) ); } -function revokeSeal(deps3, sealId, reason3) { - const seal = requireSeal(deps3.workspace, sealId); +function revokeSeal(deps4, sealId, reason3) { + const seal = requireSeal(deps4.workspace, sealId); const revoked = missionSealSchema.parse({ ...seal, status: "REVOKED", - revokedAt: nowIso5(deps3), + revokedAt: nowIso5(deps4), revokedReason: reason3.slice(0, SEAL_LIMITS.maxTextChars) }); - writeJsonRecord(sealFile(deps3.workspace, sealId), revoked); + writeJsonRecord(sealFile(deps4.workspace, sealId), revoked); return revoked; } function readSeal(workspace, sealId) { @@ -103627,18 +103733,18 @@ function requireExecutableSeal(seal, policy) { details: { reason: assessment.reason ?? "UNKNOWN" } }); } -function bindSealToJob(deps3, jobId, sealId) { - const seal = requireSeal(deps3.workspace, sealId); - requireExecutableSeal(seal, autonomyPolicyOf(deps3)); +function bindSealToJob(deps4, jobId, sealId) { + const seal = requireSeal(deps4.workspace, sealId); + requireExecutableSeal(seal, autonomyPolicyOf(deps4)); const binding = sealBindingSchema.parse({ schemaVersion: SEAL_SCHEMA_VERSION, jobId, sealId, missionId: seal.missionId, - boundAt: nowIso5(deps3), + boundAt: nowIso5(deps4), boundPolicyFingerprint: seal.delegatedAuthority.policyFingerprint }); - writeJsonRecord(bindingFile(deps3.workspace, jobId), binding); + writeJsonRecord(bindingFile(deps4.workspace, jobId), binding); return binding; } function readSealBinding(workspace, jobId) { @@ -104212,12 +104318,12 @@ function progressFingerprint(input) { input.agentRuns ].join(":"); } -function createInProcessDriverHost(deps3, options = {}) { +function createInProcessDriverHost(deps4, options = {}) { return { label: "in-process", async run(request) { try { - const result = await driveJob(deps3, request.jobId, { + const result = await driveJob(deps4, request.jobId, { ...options, ...request.signal !== void 0 ? { signal: request.signal } : {}, ...request.onEvent !== void 0 ? { onEvent: (event) => request.onEvent?.({ kind: event.kind, message: event.message }) } : {} @@ -104267,14 +104373,14 @@ function writeSupervisorState(workspace, state) { writeJsonRecord(supervisorStateFile(workspace), validated); return validated; } -function loadSupervisorState(deps3, ownerId) { - const existing = readSupervisorState(deps3.workspace); +function loadSupervisorState(deps4, ownerId) { + const existing = readSupervisorState(deps4.workspace); if (existing !== void 0) return existing; return supervisorStateSchema.parse({ schemaVersion: SUPERVISOR_SCHEMA_VERSION, ownerId, - startedAt: nowIso5(deps3), - heartbeatAt: nowIso5(deps3), + startedAt: nowIso5(deps4), + heartbeatAt: nowIso5(deps4), pid: process.pid, hostname: safeHostname(), jobs: [] @@ -104295,16 +104401,16 @@ function upsertSupervisedJob(state, job) { function findSupervisedJob(state, jobId) { return state.jobs.find((entry2) => entry2.jobId === jobId); } -function appendSupervisionLog(deps3, entry2) { +function appendSupervisionLog(deps4, entry2) { const validated = supervisionLogEntrySchema.parse({ - at: nowIso5(deps3), + at: nowIso5(deps4), ownerId: entry2.ownerId, ...entry2.jobId !== void 0 ? { jobId: entry2.jobId } : {}, action: entry2.action, ...entry2.detail !== void 0 ? { detail: entry2.detail.slice(0, 4e3) } : {}, ...entry2.generation !== void 0 ? { generation: entry2.generation } : {} }); - appendJsonl2(supervisionLogFile(deps3.workspace), validated); + appendJsonl2(supervisionLogFile(deps4.workspace), validated); return validated; } function readSupervisionLog(workspace, limit = 500) { @@ -104323,8 +104429,8 @@ function supervisorSleep(ms, signal) { }, { once: true }); }); } -function resetSupervisedJobForExplicitResume(deps3, ownerId, jobId) { - const state = loadSupervisorState(deps3, ownerId); +function resetSupervisedJobForExplicitResume(deps4, ownerId, jobId) { + const state = loadSupervisorState(deps4, ownerId); const supervised = state.jobs.find((job) => job.jobId === jobId); if (supervised === void 0) return false; const changed = supervised.consecutiveRestarts > 0 || supervised.backoffMs > 0 || supervised.status === "RELEASED"; @@ -104334,8 +104440,8 @@ function resetSupervisedJobForExplicitResume(deps3, ownerId, jobId) { if (supervised.status === "RELEASED") supervised.status = "REGISTERED"; delete supervised.releasedAt; delete supervised.releaseReason; - writeSupervisorState(deps3.workspace, state); - appendSupervisionLog(deps3, { + writeSupervisorState(deps4.workspace, state); + appendSupervisionLog(deps4, { ownerId, jobId, action: "RESET_ON_EXPLICIT_RESUME", @@ -104343,9 +104449,9 @@ function resetSupervisedJobForExplicitResume(deps3, ownerId, jobId) { }); return true; } -function registerSupervisedJob(deps3, input) { - const ownerId = input.ownerId ?? newId5(deps3); - const state = loadSupervisorState(deps3, ownerId); +function registerSupervisedJob(deps4, input) { + const ownerId = input.ownerId ?? newId5(deps4); + const state = loadSupervisorState(deps4, ownerId); const existing = findSupervisedJob(state, input.jobId); const supervised = supervisedJobSchema.parse( existing ?? { @@ -104353,19 +104459,19 @@ function registerSupervisedJob(deps3, input) { specName: input.specName, ...input.sealId !== void 0 ? { sealId: input.sealId } : {}, status: "REGISTERED", - registeredAt: nowIso5(deps3) + registeredAt: nowIso5(deps4) } ); - writeSupervisorState(deps3.workspace, { + writeSupervisorState(deps4.workspace, { ...upsertSupervisedJob(state, supervised), schemaVersion: SUPERVISOR_SCHEMA_VERSION, - heartbeatAt: nowIso5(deps3) + heartbeatAt: nowIso5(deps4) }); return supervised; } -function acquireJobLease(deps3, jobId, ownerId, policy) { - const at = now5(deps3); - const existing = readLease(deps3.workspace, jobId); +function acquireJobLease(deps4, jobId, ownerId, policy) { + const at = now5(deps4); + const existing = readLease(deps4.workspace, jobId); if (isLeaseLive(existing, at) && existing?.ownerId !== ownerId) { return { acquired: false, ...existing !== void 0 ? { heldBy: existing.ownerId } : {} }; } @@ -104377,11 +104483,11 @@ function acquireJobLease(deps3, jobId, ownerId, policy) { ttlMs: policy.leaseTtlMs, pid: process.pid, ...safeHostname() !== void 0 ? { hostname: safeHostname() } : {}, - host: hostOf(deps3), + host: hostOf(deps4), schemaVersion: SUPERVISOR_SCHEMA_VERSION }); - const lease = writeLease(deps3.workspace, claim2.lease); - appendSupervisionLog(deps3, { + const lease = writeLease(deps4.workspace, claim2.lease); + appendSupervisionLog(deps4, { ownerId, jobId, action: claim2.reclaimed ? "LEASE_EXPIRED_RECLAIMED" : "LEASE_ACQUIRED", @@ -104390,9 +104496,9 @@ function acquireJobLease(deps3, jobId, ownerId, policy) { }); return { acquired: true, lease }; } -function renewJobLease(deps3, jobId, ownerId, policy) { - const at = now5(deps3); - const existing = readLease(deps3.workspace, jobId); +function renewJobLease(deps4, jobId, ownerId, policy) { + const at = now5(deps4); + const existing = readLease(deps4.workspace, jobId); if (existing !== void 0 && existing.ownerId !== ownerId && isLeaseLive(existing, at)) { return void 0; } @@ -104403,30 +104509,30 @@ function renewJobLease(deps3, jobId, ownerId, policy) { now: at, ttlMs: policy.leaseTtlMs, pid: process.pid, - host: hostOf(deps3), + host: hostOf(deps4), schemaVersion: SUPERVISOR_SCHEMA_VERSION }); - return writeLease(deps3.workspace, claim2.lease); + return writeLease(deps4.workspace, claim2.lease); } -function releaseJobLease(deps3, jobId, ownerId, reason3) { - const existing = readLease(deps3.workspace, jobId); +function releaseJobLease(deps4, jobId, ownerId, reason3) { + const existing = readLease(deps4.workspace, jobId); if (existing === void 0 || existing.ownerId !== ownerId) return; - writeLease(deps3.workspace, releaseLeaseRecord(existing, now5(deps3), reason3)); - appendSupervisionLog(deps3, { ownerId, jobId, action: "RELEASED_ON_TERMINAL_STATUS", detail: reason3 }); + writeLease(deps4.workspace, releaseLeaseRecord(existing, now5(deps4), reason3)); + appendSupervisionLog(deps4, { ownerId, jobId, action: "RELEASED_ON_TERMINAL_STATUS", detail: reason3 }); } -async function superviseJob(deps3, jobId, options) { - const policy = autonomyPolicyOf(deps3).supervisor; +async function superviseJob(deps4, jobId, options) { + const policy = autonomyPolicyOf(deps4).supervisor; if (!policy.enabled) { throw new AutonomyError("SBA001", "The supervisor is disabled by `autonomy.supervisor.enabled`.", { remediation: ["Run `specbridge autonomy setup --mode overnight`, or drive the job in the foreground."] }); } - const ownerId = options.ownerId ?? `sup-${newId5(deps3)}`.slice(0, 60); + const ownerId = options.ownerId ?? `sup-${newId5(deps4)}`.slice(0, 60); const sleep2 = options.sleep ?? supervisorSleep; const emit22 = (kind, message2) => { options.onEvent?.({ kind, message: message2 }); }; - const acquisition = acquireJobLease(deps3, jobId, ownerId, policy); + const acquisition = acquireJobLease(deps4, jobId, ownerId, policy); if (!acquisition.acquired) { throw new AutonomyError( "SBA008", @@ -104441,14 +104547,14 @@ async function superviseJob(deps3, jobId, options) { ); } emit22("lease", `lease acquired by ${ownerId} (generation ${acquisition.lease?.generation ?? 1})`); - const sessionStartedAt = options.sessionStartedAt ?? nowIso5(deps3); - let job = requireJobState(deps3.workspace, jobId); - let supervised = registerSupervisedJob(deps3, { + const sessionStartedAt = options.sessionStartedAt ?? nowIso5(deps4); + let job = requireJobState(deps4.workspace, jobId); + let supervised = registerSupervisedJob(deps4, { jobId, specName: job.specName, ownerId }); - recordJobEvent(jobDepsOf(deps3), jobId, "supervisor_attached", { + recordJobEvent(jobDepsOf(deps4), jobId, "supervisor_attached", { ownerId, host: options.host.label }); @@ -104462,10 +104568,10 @@ async function superviseJob(deps3, jobId, options) { stop = { kind: "interrupted" }; break; } - job = requireJobState(deps3.workspace, jobId); - const fingerprint = fingerprintOf(deps3, job); + job = requireJobState(deps4.workspace, jobId); + const fingerprint = fingerprintOf(deps4, job); const decision = decideSupervision({ - now: now5(deps3), + now: now5(deps4), policy, status: job.status, ...job.operationalWait !== void 0 ? { wait: job.operationalWait } : {}, @@ -104479,7 +104585,7 @@ async function superviseJob(deps3, jobId, options) { sessionStartedAt }); emit22("decision", `${decision.action}: ${decision.reason}`); - const outcome = await applyDecision(deps3, { + const outcome = await applyDecision(deps4, { jobId, ownerId, policy, @@ -104495,47 +104601,47 @@ async function superviseJob(deps3, jobId, options) { stop = outcome.stop; break; } - renewJobLease(deps3, jobId, ownerId, policy); - persistSupervised(deps3, ownerId, supervised); + renewJobLease(deps4, jobId, ownerId, policy); + persistSupervised(deps4, ownerId, supervised); } } finally { - persistSupervised(deps3, ownerId, supervised); - releaseJobLease(deps3, jobId, ownerId, stop?.kind ?? "supervision ended"); - recordJobEvent(jobDepsOf(deps3), jobId, "supervisor_detached", { + persistSupervised(deps4, ownerId, supervised); + releaseJobLease(deps4, jobId, ownerId, stop?.kind ?? "supervision ended"); + recordJobEvent(jobDepsOf(deps4), jobId, "supervisor_detached", { ownerId, stop: stop?.kind ?? "unknown", cycles }); } - job = requireJobState(deps3.workspace, jobId); + job = requireJobState(deps4.workspace, jobId); return { stop: stop ?? { kind: "cycles-exhausted" }, job, supervised, cycles }; } -async function applyDecision(deps3, input) { +async function applyDecision(deps4, input) { const { decision, jobId, ownerId, policy } = input; switch (decision.action) { case "RELEASE": { - const job = requireJobState(deps3.workspace, jobId); - appendSupervisionLog(deps3, { + const job = requireJobState(deps4.workspace, jobId); + appendSupervisionLog(deps4, { ownerId, jobId, action: job.status === "COMPLETED" ? "RELEASED_ON_TERMINAL_STATUS" : "SESSION_BUDGET_REACHED", detail: decision.reason }); return { - supervised: { ...input.supervised, status: "RELEASED", releasedAt: nowIso5(deps3), releaseReason: decision.reason }, + supervised: { ...input.supervised, status: "RELEASED", releasedAt: nowIso5(deps4), releaseReason: decision.reason }, stop: job.status === "COMPLETED" ? { kind: "completed", status: job.status } : { kind: "released", reason: decision.reason } }; } case "WAIT_FOR_HUMAN": { - const job = requireJobState(deps3.workspace, jobId); - appendSupervisionLog(deps3, { + const job = requireJobState(deps4.workspace, jobId); + appendSupervisionLog(deps4, { ownerId, jobId, action: "RELEASED_ON_AUTHORITY_STOP", detail: decision.reason }); return { - supervised: { ...input.supervised, status: "RELEASED", releasedAt: nowIso5(deps3), releaseReason: decision.reason }, + supervised: { ...input.supervised, status: "RELEASED", releasedAt: nowIso5(deps4), releaseReason: decision.reason }, stop: { kind: "needs-human", status: decision.status, @@ -104544,21 +104650,21 @@ async function applyDecision(deps3, input) { }; } case "GIVE_UP": { - appendSupervisionLog(deps3, { + appendSupervisionLog(deps4, { ownerId, jobId, action: input.supervised.consecutiveRestarts >= policy.maxConsecutiveRestarts || input.supervised.restarts >= policy.maxRestarts ? "RESTART_BUDGET_EXHAUSTED" : "INDEFINITE_WAIT_CLASSIFIED", detail: decision.reason }); return { - supervised: { ...input.supervised, status: "RELEASED", releasedAt: nowIso5(deps3), releaseReason: decision.reason }, + supervised: { ...input.supervised, status: "RELEASED", releasedAt: nowIso5(deps4), releaseReason: decision.reason }, stop: { kind: "gave-up", reason: decision.reason } }; } case "SLEEP_UNTIL": { - const waitMs = Math.max(0, Date.parse(decision.wakeAt) - now5(deps3).getTime()); - appendSupervisionLog(deps3, { ownerId, jobId, action: "WAKE_SCHEDULED", detail: decision.reason }); - await sleepInSlices(deps3, { + const waitMs = Math.max(0, Date.parse(decision.wakeAt) - now5(deps4).getTime()); + appendSupervisionLog(deps4, { ownerId, jobId, action: "WAKE_SCHEDULED", detail: decision.reason }); + await sleepInSlices(deps4, { totalMs: waitMs, sliceMs: policy.heartbeatIntervalMs, jobId, @@ -104567,10 +104673,10 @@ async function applyDecision(deps3, input) { sleep: input.sleep, signal: input.options.signal }); - appendSupervisionLog(deps3, { ownerId, jobId, action: "WOKEN_ON_SCHEDULE", detail: decision.wakeAt }); - const job = requireJobState(deps3.workspace, jobId); + appendSupervisionLog(deps4, { ownerId, jobId, action: "WOKEN_ON_SCHEDULE", detail: decision.wakeAt }); + const job = requireJobState(deps4.workspace, jobId); if (isOperationalJobStatus(job.status)) { - clearOperationalState(jobDepsOf(deps3), jobId, { resolution: "the scheduled wait elapsed" }); + clearOperationalState(jobDepsOf(deps4), jobId, { resolution: "the scheduled wait elapsed" }); } return { supervised: { ...input.supervised, status: "SLEEPING" } }; } @@ -104583,20 +104689,20 @@ async function applyDecision(deps3, input) { if (decision.action === "RESTART_DRIVER" && decision.backoffMs > 0) { await input.sleep(decision.backoffMs, input.options.signal); } - const job = requireJobState(deps3.workspace, jobId); + const job = requireJobState(deps4.workspace, jobId); if (isOperationalJobStatus(job.status)) { - clearOperationalState(jobDepsOf(deps3), jobId, { + clearOperationalState(jobDepsOf(deps4), jobId, { resolution: "the supervisor is resuming the driver" }); } - appendSupervisionLog(deps3, { + appendSupervisionLog(deps4, { ownerId, jobId, action: decision.action === "START_DRIVER" ? "DRIVER_STARTED" : "DRIVER_RESTARTED", detail: decision.reason }); if (decision.action === "RESTART_DRIVER") { - countAutonomyEvent(jobDepsOf(deps3), jobId, "driverRestarts", "driver_restarted", { + countAutonomyEvent(jobDepsOf(deps4), jobId, "driverRestarts", "driver_restarted", { reason: decision.reason.slice(0, 300), restarts: input.supervised.restarts + 1 }); @@ -104606,10 +104712,10 @@ async function applyDecision(deps3, input) { ...input.options.signal !== void 0 ? { signal: input.options.signal } : {}, onEvent: (event) => input.emit("driver", `${event.kind}: ${event.message}`) }); - const supervised = foldDriverOutcome(deps3, input, outcome, decision.action); + const supervised = foldDriverOutcome(deps4, input, outcome, decision.action); if (outcome.kind === "exited" && outcome.stop.kind === "final") { - const job2 = requireJobState(deps3.workspace, jobId); - appendSupervisionLog(deps3, { + const job2 = requireJobState(deps4.workspace, jobId); + appendSupervisionLog(deps4, { ownerId, jobId, action: "CLOSURE_HANDOFF", @@ -104624,13 +104730,13 @@ async function applyDecision(deps3, input) { } } } -function foldDriverOutcome(deps3, input, outcome, action) { - const after = fingerprintOf(deps3, requireJobState(deps3.workspace, input.jobId)); +function foldDriverOutcome(deps4, input, outcome, action) { + const after = fingerprintOf(deps4, requireJobState(deps4.workspace, input.jobId)); const madeProgress = after !== input.fingerprint; const starts = input.supervised.starts + 1; const restarts = input.supervised.restarts + (action === "RESTART_DRIVER" ? 1 : 0); const unclean = outcome.kind === "crashed"; - appendSupervisionLog(deps3, { + appendSupervisionLog(deps4, { ownerId: input.ownerId, jobId: input.jobId, action: unclean ? "DRIVER_DIED" : "DRIVER_EXITED_CLEANLY", @@ -104645,10 +104751,10 @@ function foldDriverOutcome(deps3, input, outcome, action) { consecutiveRestarts: 0, backoffMs: 0, lastProgressFingerprint: after, - lastProgressAt: nowIso5(deps3), + lastProgressAt: nowIso5(deps4), nextAttemptAt: void 0, lastAction: unclean ? "DRIVER_DIED" : "DRIVER_EXITED_CLEANLY", - lastActionAt: nowIso5(deps3) + lastActionAt: nowIso5(deps4) }); } const backoffMs = nextBackoffMs( @@ -104664,21 +104770,21 @@ function foldDriverOutcome(deps3, input, outcome, action) { consecutiveRestarts: input.supervised.consecutiveRestarts + 1, backoffMs, lastProgressFingerprint: after, - nextAttemptAt: new Date(now5(deps3).getTime() + backoffMs).toISOString(), + nextAttemptAt: new Date(now5(deps4).getTime() + backoffMs).toISOString(), lastAction: unclean ? "DRIVER_DIED" : "DRIVER_EXITED_CLEANLY", - lastActionAt: nowIso5(deps3) + lastActionAt: nowIso5(deps4) }); } -async function sleepInSlices(deps3, input) { +async function sleepInSlices(deps4, input) { let remaining = input.totalMs; while (remaining > 0) { if (input.signal?.aborted === true) return; const slice = Math.min(remaining, Math.max(1, input.sliceMs)); await input.sleep(slice, input.signal); remaining -= slice; - const renewed = renewJobLease(deps3, input.jobId, input.ownerId, input.policy); + const renewed = renewJobLease(deps4, input.jobId, input.ownerId, input.policy); if (renewed === void 0) return; - appendSupervisionLog(deps3, { + appendSupervisionLog(deps4, { ownerId: input.ownerId, jobId: input.jobId, action: "LEASE_RENEWED", @@ -104686,19 +104792,19 @@ async function sleepInSlices(deps3, input) { }); } } -function persistSupervised(deps3, ownerId, supervised) { - const state = loadSupervisorState(deps3, ownerId); - writeSupervisorState(deps3.workspace, { +function persistSupervised(deps4, ownerId, supervised) { + const state = loadSupervisorState(deps4, ownerId); + writeSupervisorState(deps4.workspace, { ...upsertSupervisedJob(state, supervised), ownerId, - heartbeatAt: nowIso5(deps3) + heartbeatAt: nowIso5(deps4) }); } -function fingerprintOf(deps3, job) { +function fingerprintOf(deps4, job) { let completedNodes = 0; let totalAttempts = 0; try { - const graph = readGraphRevision(deps3.workspace, job.jobId, job.graphRevision); + const graph = readGraphRevision(deps4.workspace, job.jobId, job.graphRevision); if (graph !== void 0) { for (const node of graph.nodes) { if (node.status === "COMPLETED") completedNodes += 1; @@ -104878,13 +104984,13 @@ function detectBuildTool(projectDir) { return null; } var DEFAULT_MIN_FREE_DISK = 5 * 1024 * 1024 * 1024; -async function runOvernightPreflight(deps3, request) { - const policy = autonomyPolicyOf(deps3); - const projectDir = request.projectDir ?? deps3.workspace.rootDir; +async function runOvernightPreflight(deps4, request) { + const policy = autonomyPolicyOf(deps4); + const projectDir = request.projectDir ?? deps4.workspace.rootDir; const run = request.probeRunner ?? createProcessProbeRunner(projectDir); - const at = nowIso5(deps3); + const at = nowIso5(deps4); const checks = []; - const seal = resolveSeal(deps3, request); + const seal = resolveSeal(deps4, request); const add2 = (capability, outcome, observed, extra = {}) => { checks.push({ capability, @@ -104898,11 +105004,11 @@ async function runOvernightPreflight(deps3, request) { }; add2( "WORKSPACE_WRITABLE", - isWritableDirectory(deps3.workspace.rootDir) ? "READY" : "HUMAN_REQUIRED", - `workspace root ${deps3.workspace.rootDir}`, + isWritableDirectory(deps4.workspace.rootDir) ? "READY" : "HUMAN_REQUIRED", + `workspace root ${deps4.workspace.rootDir}`, { remediation: ["Grant write access to the workspace, or run from a writable checkout."] } ); - const free = freeDiskBytes(deps3.workspace.rootDir); + const free = freeDiskBytes(deps4.workspace.rootDir); const minFree = request.minFreeDiskBytes ?? DEFAULT_MIN_FREE_DISK; add2( "DISK_SPACE", @@ -104922,8 +105028,8 @@ async function runOvernightPreflight(deps3, request) { ); add2( "PROTECTED_PATHS_CONFIGURED", - deps3.config.execution.protectedPaths.length > 0 ? "READY" : "HUMAN_REQUIRED", - `${deps3.config.execution.protectedPaths.length} protected path pattern(s)`, + deps4.config.execution.protectedPaths.length > 0 ? "READY" : "HUMAN_REQUIRED", + `${deps4.config.execution.protectedPaths.length} protected path pattern(s)`, { remediation: [ "Declare protectedPaths in .specbridge/config.json before running unattended: an overnight run edits files for hours with nobody watching the diff." @@ -104931,7 +105037,7 @@ async function runOvernightPreflight(deps3, request) { } ); addSealChecks(add2, seal, policy); - const strongWorkers = Object.entries(deps3.config.runnerProfiles).filter( + const strongWorkers = Object.entries(deps4.config.runnerProfiles).filter( ([name]) => name !== "mock" ); add2( @@ -104944,7 +105050,7 @@ async function runOvernightPreflight(deps3, request) { ] } ); - const localInference = deps3.config.localInference; + const localInference = deps4.config.localInference; add2( "LOCAL_MODEL_STARTABLE", localInference.enabled ? "READY" : "NOT_APPLICABLE", @@ -104955,7 +105061,7 @@ async function runOvernightPreflight(deps3, request) { ] } ); - const apiPolicy = deps3.config.orchestration.jobs.scheduler.api; + const apiPolicy = deps4.config.orchestration.jobs.scheduler.api; const spendMode = apiPolicy.spendMode; add2( "API_FALLBACK_AUTHORIZED", @@ -104981,8 +105087,8 @@ async function runOvernightPreflight(deps3, request) { ); add2( "TRUSTED_VERIFICATION_CONFIGURED", - deps3.config.verification.commands.length > 0 ? "READY" : "HUMAN_REQUIRED", - `${deps3.config.verification.commands.length} trusted verification command(s)`, + deps4.config.verification.commands.length > 0 ? "READY" : "HUMAN_REQUIRED", + `${deps4.config.verification.commands.length} trusted verification command(s)`, { remediation: [ "Configure verification commands. Without them nothing can close a contract item on trusted evidence, and the run cannot legitimately reach COMPLETED." @@ -105099,7 +105205,7 @@ async function runOvernightPreflight(deps3, request) { ] } ); - const report = buildReport(deps3, { + const report = buildReport(deps4, { request, policy, seal, @@ -105107,15 +105213,15 @@ async function runOvernightPreflight(deps3, request) { at }); writeJsonRecord( - autonomyPath(deps3.workspace, "preflight", `${report.reportId}.json`), + autonomyPath(deps4.workspace, "preflight", `${report.reportId}.json`), report ); return report; } -function resolveSeal(deps3, request) { - if (request.sealId !== void 0) return readSeal(deps3.workspace, request.sealId); - if (request.missionId !== void 0) return latestExecutableSeal(deps3.workspace, request.missionId); - return latestExecutableSeal(deps3.workspace, request.subject); +function resolveSeal(deps4, request) { + if (request.sealId !== void 0) return readSeal(deps4.workspace, request.sealId); + if (request.missionId !== void 0) return latestExecutableSeal(deps4.workspace, request.missionId); + return latestExecutableSeal(deps4.workspace, request.subject); } function addSealChecks(add2, seal, policy) { if (seal === void 0) { @@ -105156,7 +105262,7 @@ function addSealChecks(add2, seal, policy) { function toolsmithGrants(policy, capability) { return policy.toolsmith.enabled && policy.toolsmith.capabilities.includes(capability); } -function buildReport(deps3, input) { +function buildReport(deps4, input) { const humanActions = []; const autonomousActions = []; const unknowns = []; @@ -105174,9 +105280,9 @@ function buildReport(deps3, input) { const verdict = humanActions.length > 0 ? "HUMAN_ACTION_REQUIRED" : unknowns.length > 0 ? "INDETERMINATE" : "OVERNIGHT_READY"; return preflightReportSchema.parse({ schemaVersion: PREFLIGHT_SCHEMA_VERSION, - reportId: input.request.reportId ?? newRecordId(deps3, "pf"), + reportId: input.request.reportId ?? newRecordId(deps4, "pf"), createdAt: input.at, - host: hostOf(deps3), + host: hostOf(deps4), subject: input.request.subject, ...input.request.missionId !== void 0 ? { missionId: input.request.missionId } : {}, ...input.seal !== void 0 ? { sealId: input.seal.sealId } : {}, @@ -105446,9 +105552,9 @@ function listToolsmithRequests(workspace, jobId) { (raw) => toolsmithRequestSchema.parse(raw) ).sort((a2, b) => a2.requestedAt.localeCompare(b.requestedAt)); } -function requestToolsmithCapability(deps3, input) { - const policy = autonomyPolicyOf(deps3); - const ledger = loadLedger(deps3, input.jobId); +function requestToolsmithCapability(deps4, input) { + const policy = autonomyPolicyOf(deps4); + const ledger = loadLedger(deps4, input.jobId); const scope = input.scope ?? preferredScopeFor(input.capability); const decision = decideToolsmithRequest( { @@ -105460,15 +105566,15 @@ function requestToolsmithCapability(deps3, input) { }, { policy, - workspaceRoot: deps3.workspace.rootDir, - protectedPaths: deps3.config.execution.protectedPaths, + workspaceRoot: deps4.workspace.rootDir, + protectedPaths: deps4.config.execution.protectedPaths, grantsUsed: ledger.granted } ); - const at = nowIso5(deps3); + const at = nowIso5(deps4); const request = toolsmithRequestSchema.parse({ schemaVersion: TOOLSMITH_SCHEMA_VERSION, - requestId: input.requestId ?? newRecordId(deps3, "ts"), + requestId: input.requestId ?? newRecordId(deps4, "ts"), jobId: input.jobId, capability: input.capability, purpose: input.purpose.slice(0, 4e3), @@ -105484,19 +105590,19 @@ function requestToolsmithCapability(deps3, input) { ...decision.suggestedAlternative !== void 0 ? { suggestedAlternative: decision.suggestedAlternative } : {} } }); - writeJsonRecord(requestFile(deps3.workspace, input.jobId, request.requestId), request); - saveLedger(deps3, input.jobId, { + writeJsonRecord(requestFile(deps4.workspace, input.jobId, request.requestId), request); + saveLedger(deps4, input.jobId, { ...ledger, granted: ledger.granted + (decision.granted ? 1 : 0), denied: ledger.denied + (decision.granted ? 0 : 1) }); - recordToolsmithEvent(deps3, input.jobId, request, decision); + recordToolsmithEvent(deps4, input.jobId, request, decision); return { request, decision }; } -function recordToolsmithEvent(deps3, jobId, request, decision) { +function recordToolsmithEvent(deps4, jobId, request, decision) { try { recordJobEvent( - jobDepsOf(deps3), + jobDepsOf(deps4), jobId, decision.granted ? "toolsmith_grant_issued" : "toolsmith_grant_denied", { @@ -105513,16 +105619,16 @@ function recordToolsmithEvent(deps3, jobId, request, decision) { function writesFileDirectly(capability) { return capability === "PROJECT_LOCAL_SCRIPT" || capability === "CODE_GENERATION"; } -function loadLedger(deps3, jobId) { - return readToolsmithLedger(deps3.workspace, jobId) ?? toolsmithLedgerSchema.parse({ +function loadLedger(deps4, jobId) { + return readToolsmithLedger(deps4.workspace, jobId) ?? toolsmithLedgerSchema.parse({ schemaVersion: TOOLSMITH_SCHEMA_VERSION, jobId, - updatedAt: nowIso5(deps3) + updatedAt: nowIso5(deps4) }); } -function saveLedger(deps3, jobId, ledger) { - const next = toolsmithLedgerSchema.parse({ ...ledger, updatedAt: nowIso5(deps3) }); - writeJsonRecord(ledgerFile(deps3.workspace, jobId), next); +function saveLedger(deps4, jobId, ledger) { + const next = toolsmithLedgerSchema.parse({ ...ledger, updatedAt: nowIso5(deps4) }); + writeJsonRecord(ledgerFile(deps4.workspace, jobId), next); return next; } function countSelfCreatedTools(workspace, jobId) { @@ -105843,8 +105949,8 @@ function defaultSleep2(ms, signal) { }, { once: true }); }); } -async function provisionEnvironment(deps3, options) { - const policy = autonomyPolicyOf(deps3).environments; +async function provisionEnvironment(deps4, options) { + const policy = autonomyPolicyOf(deps4).environments; if (!policy.enabled) { throw new AutonomyError( "SBA016", @@ -105852,7 +105958,7 @@ async function provisionEnvironment(deps3, options) { { remediation: ["Enable it, or provide the environment yourself before the run."] } ); } - const plan = readEnvironmentPlan(deps3.workspace, options.planId); + const plan = readEnvironmentPlan(deps4.workspace, options.planId); if (plan === void 0) { throw new AutonomyError("SBA014", `No environment plan "${options.planId}" exists.`, { details: { planId: options.planId } @@ -105860,50 +105966,50 @@ async function provisionEnvironment(deps3, options) { } const ordered = orderServicesForReadiness(plan); const sleep2 = options.sleep ?? defaultSleep2; - const probe = options.probeExecutor ?? createReadinessProbeExecutor({ cwd: deps3.workspace.rootDir }); + const probe = options.probeExecutor ?? createReadinessProbeExecutor({ cwd: deps4.workspace.rootDir }); const emit22 = options.onEvent ?? (() => void 0); let instance = writeInstance( - deps3, + deps4, environmentInstanceSchema.parse({ schemaVersion: ENVIRONMENT_SCHEMA_VERSION, - instanceId: options.instanceId ?? newRecordId(deps3, "envi"), + instanceId: options.instanceId ?? newRecordId(deps4, "envi"), planId: plan.planId, ...options.jobId !== void 0 ? { jobId: options.jobId } : {}, status: "PROVISIONING", - createdAt: nowIso5(deps3), + createdAt: nowIso5(deps4), services: ordered.map((service) => ({ serviceId: service.serviceId, status: "PENDING" })) }) ); - emitJobEvent(deps3, options.jobId, "environment_provision_started", { + emitJobEvent(deps4, options.jobId, "environment_provision_started", { planId: plan.planId, instanceId: instance.instanceId, services: ordered.length }); - const startedAtMs = now5(deps3).getTime(); + const startedAtMs = now5(deps4).getTime(); const provisioned = await options.runtime.provision({ plan, - workspaceRoot: deps3.workspace.rootDir, + workspaceRoot: deps4.workspace.rootDir, timeoutMs: policy.readinessTimeoutMs, ...options.signal !== void 0 ? { signal: options.signal } : {} }); if (!provisioned.ok) { emit22(`provisioning failed: ${provisioned.detail}`); - return finishFailed(deps3, options, plan, instance, { + return finishFailed(deps4, options, plan, instance, { failureKind: provisioned.failureKind ?? "RUNTIME_UNAVAILABLE", detail: provisioned.detail }); } - instance = writeInstance(deps3, { + instance = writeInstance(deps4, { ...instance, status: "WAITING_READY", services: instance.services.map((service) => ({ ...service, status: "STARTING", - startedAt: nowIso5(deps3) + startedAt: nowIso5(deps4) })) }); for (const service of ordered) { - const result = await waitForService(deps3, { + const result = await waitForService(deps4, { plan, service, instance, @@ -105914,7 +106020,7 @@ async function provisionEnvironment(deps3, options) { emit: emit22, ...options.signal !== void 0 ? { signal: options.signal } : {} }); - instance = writeInstance(deps3, { + instance = writeInstance(deps4, { ...instance, services: instance.services.map( (entry2) => entry2.serviceId === service.serviceId ? result.state : entry2 @@ -105922,37 +106028,37 @@ async function provisionEnvironment(deps3, options) { repairs: instance.repairs + result.restarts }); if (result.state.status !== "READY") { - return finishFailed(deps3, options, plan, instance, { + return finishFailed(deps4, options, plan, instance, { failureKind: result.state.failureKind ?? "READINESS_TIMEOUT", detail: result.state.lastProbeDetail ?? `service ${service.serviceId} never became ready` }); } } - const ready = writeInstance(deps3, { + const ready = writeInstance(deps4, { ...instance, status: "READY", - readyAt: nowIso5(deps3) + readyAt: nowIso5(deps4) }); - writeEvidence(deps3, plan, ready, now5(deps3).getTime() - startedAtMs, []); - emitJobEvent(deps3, options.jobId, "environment_ready", { + writeEvidence(deps4, plan, ready, now5(deps4).getTime() - startedAtMs, []); + emitJobEvent(deps4, options.jobId, "environment_ready", { instanceId: ready.instanceId, planId: plan.planId }); return ready; } -async function waitForService(deps3, input) { +async function waitForService(deps4, input) { const { service, probe, sleep: sleep2, policy } = input; - const deadlineMs = now5(deps3).getTime() + Math.min(service.readinessTimeoutMs, policy.readinessTimeoutMs); + const deadlineMs = now5(deps4).getTime() + Math.min(service.readinessTimeoutMs, policy.readinessTimeoutMs); const maxRestarts = Math.min(service.maxRestarts, policy.maxServiceRestarts); let state = { serviceId: service.serviceId, status: "WAITING_READY", - startedAt: nowIso5(deps3), + startedAt: nowIso5(deps4), restarts: 0, probeAttempts: 0 }; let restarts = 0; - while (now5(deps3).getTime() < deadlineMs) { + while (now5(deps4).getTime() < deadlineMs) { if (input.signal?.aborted === true) { return { state: { ...state, status: "FAILED", failureKind: "UNKNOWN" }, restarts }; } @@ -105975,7 +106081,7 @@ async function waitForService(deps3, input) { state: { ...state, status: "READY", - readyAt: nowIso5(deps3), + readyAt: nowIso5(deps4), lastProbeKind: lastKind, lastProbeDetail: lastDetail }, @@ -105983,14 +106089,14 @@ async function waitForService(deps3, input) { }; } state = { ...state, lastProbeKind: lastKind, lastProbeDetail: lastDetail }; - const elapsedFraction = 1 - (deadlineMs - now5(deps3).getTime()) / Math.max(1, service.readinessTimeoutMs); + const elapsedFraction = 1 - (deadlineMs - now5(deps4).getTime()) / Math.max(1, service.readinessTimeoutMs); if (restarts < maxRestarts && elapsedFraction > (restarts + 1) / (maxRestarts + 1)) { restarts += 1; input.emit(`${service.serviceId} not ready after ${state.probeAttempts} probes; restarting`); const restarted = await input.runtime.restart({ plan: input.plan, service, - workspaceRoot: deps3.workspace.rootDir, + workspaceRoot: deps4.workspace.rootDir, timeoutMs: policy.readinessTimeoutMs, ...input.signal !== void 0 ? { signal: input.signal } : {} }); @@ -106013,8 +106119,8 @@ async function waitForService(deps3, input) { restarts }; } -async function finishFailed(deps3, options, plan, instance, failure3) { - const policy = autonomyPolicyOf(deps3).environments; +async function finishFailed(deps4, options, plan, instance, failure3) { + const policy = autonomyPolicyOf(deps4).environments; const logRefs = []; if (policy.retainDiagnosticsOnFailure) { for (const service of plan.services) { @@ -106022,15 +106128,15 @@ async function finishFailed(deps3, options, plan, instance, failure3) { const text142 = await options.runtime.logs({ plan, service, - workspaceRoot: deps3.workspace.rootDir, + workspaceRoot: deps4.workspace.rootDir, maxBytes: policy.maxLogBytesPerService }); - if (text142.length > 0) logRefs.push(retainLog(deps3, instance.instanceId, service.serviceId, text142)); + if (text142.length > 0) logRefs.push(retainLog(deps4, instance.instanceId, service.serviceId, text142)); } catch { } } } - const failed = writeInstance(deps3, { + const failed = writeInstance(deps4, { ...instance, status: "FAILED", failureKind: failure3.failureKind, @@ -106040,8 +106146,8 @@ async function finishFailed(deps3, options, plan, instance, failure3) { (service) => service.status === "READY" ? service : { ...service, status: "FAILED" } ) }); - writeEvidence(deps3, plan, failed, null, logRefs); - emitJobEvent(deps3, options.jobId, "environment_failed", { + writeEvidence(deps4, plan, failed, null, logRefs); + emitJobEvent(deps4, options.jobId, "environment_failed", { instanceId: failed.instanceId, planId: plan.planId, failureKind: failure3.failureKind, @@ -106049,7 +106155,7 @@ async function finishFailed(deps3, options, plan, instance, failure3) { }); return failed; } -function retainLog(deps3, instanceId, serviceId, text142) { +function retainLog(deps4, instanceId, serviceId, text142) { const relative = import_path86.default.posix.join( ".specbridge", "autonomy", @@ -106058,42 +106164,42 @@ function retainLog(deps3, instanceId, serviceId, text142) { instanceId, `${serviceId}.log` ); - const absolute = autonomyPath(deps3.workspace, "environments", "logs", instanceId, `${serviceId}.log`); + const absolute = autonomyPath(deps4.workspace, "environments", "logs", instanceId, `${serviceId}.log`); (0, import_fs78.mkdirSync)(import_path86.default.dirname(absolute), { recursive: true }); (0, import_fs78.writeFileSync)(absolute, text142, "utf8"); return relative; } -async function teardownEnvironment(deps3, input) { - const instance = readEnvironmentInstance(deps3.workspace, input.instanceId); +async function teardownEnvironment(deps4, input) { + const instance = readEnvironmentInstance(deps4.workspace, input.instanceId); if (instance === void 0) { throw new AutonomyError("SBA014", `No environment instance "${input.instanceId}" exists.`); } - const plan = readEnvironmentPlan(deps3.workspace, instance.planId); + const plan = readEnvironmentPlan(deps4.workspace, instance.planId); if (plan === void 0) { throw new AutonomyError("SBA014", `Environment plan "${instance.planId}" is missing.`); } - const policy = autonomyPolicyOf(deps3).environments; + const policy = autonomyPolicyOf(deps4).environments; const retain = input.retain ?? (instance.status === "FAILED" && policy.retainDiagnosticsOnFailure); await input.runtime.teardown({ plan, - workspaceRoot: deps3.workspace.rootDir, + workspaceRoot: deps4.workspace.rootDir, timeoutMs: policy.readinessTimeoutMs, retain }); - const stopped = writeInstance(deps3, { + const stopped = writeInstance(deps4, { ...instance, status: "STOPPED", - stoppedAt: nowIso5(deps3), + stoppedAt: nowIso5(deps4), diagnosticsRetained: retain, services: instance.services.map((service) => ({ ...service, status: "STOPPED" })) }); - emitJobEvent(deps3, instance.jobId, "environment_torn_down", { + emitJobEvent(deps4, instance.jobId, "environment_torn_down", { instanceId: stopped.instanceId, retained: retain }); return stopped; } -function writeEvidence(deps3, plan, instance, totalMs, logRefs) { +function writeEvidence(deps4, plan, instance, totalMs, logRefs) { const byId = new Map(plan.services.map((service) => [service.serviceId, service])); const applicationLevelReady = []; const livenessOnlyReady = []; @@ -106111,7 +106217,7 @@ function writeEvidence(deps3, plan, instance, totalMs, logRefs) { schemaVersion: ENVIRONMENT_SCHEMA_VERSION, instanceId: instance.instanceId, planId: plan.planId, - recordedAt: nowIso5(deps3), + recordedAt: nowIso5(deps4), status: instance.status, applicationLevelReady, livenessOnlyReady, @@ -106119,18 +106225,18 @@ function writeEvidence(deps3, plan, instance, totalMs, logRefs) { totalReadinessMs: totalMs, logRefs: [...logRefs].slice(0, 60) }); - writeJsonRecord(environmentEvidenceFile(deps3.workspace, instance.instanceId), evidence); + writeJsonRecord(environmentEvidenceFile(deps4.workspace, instance.instanceId), evidence); return evidence; } -function writeInstance(deps3, instance) { +function writeInstance(deps4, instance) { const validated = environmentInstanceSchema.parse(instance); - writeJsonRecord(environmentInstanceFile(deps3.workspace, validated.instanceId), validated); + writeJsonRecord(environmentInstanceFile(deps4.workspace, validated.instanceId), validated); return validated; } -function emitJobEvent(deps3, jobId, type, payload) { +function emitJobEvent(deps4, jobId, type, payload) { if (jobId === void 0) return; try { - recordJobEvent(jobDepsOf(deps3), jobId, type, payload); + recordJobEvent(jobDepsOf(deps4), jobId, type, payload); } catch { } } @@ -106367,8 +106473,8 @@ function listBrowserResults(workspace) { (raw) => browserScenarioResultSchema.parse(raw) ).sort((a2, b) => a2.startedAt.localeCompare(b.startedAt)); } -async function runBrowserScenario(deps3, options) { - const policy = autonomyPolicyOf(deps3).browser; +async function runBrowserScenario(deps4, options) { + const policy = autonomyPolicyOf(deps4).browser; if (!policy.enabled) { throw new AutonomyError( "SBA018", @@ -106376,7 +106482,7 @@ async function runBrowserScenario(deps3, options) { { remediation: ["Enable it, or close UI criteria on other evidence."] } ); } - const scenario = readBrowserScenario(deps3.workspace, options.scenarioId); + const scenario = readBrowserScenario(deps4.workspace, options.scenarioId); if (scenario === void 0) { throw new AutonomyError("SBA017", `No browser scenario "${options.scenarioId}" exists.`); } @@ -106387,10 +106493,10 @@ async function runBrowserScenario(deps3, options) { { remediation: ["Raise autonomy.browser.maxContexts, or split the scenario."] } ); } - const resultId = options.resultId ?? newRecordId(deps3, "br"); - const startedAt = nowIso5(deps3); - const startedMs = now5(deps3).getTime(); - emitJobEvent2(deps3, options.jobId, "browser_scenario_started", { + const resultId = options.resultId ?? newRecordId(deps4, "br"); + const startedAt = nowIso5(deps4); + const startedMs = now5(deps4).getTime(); + emitJobEvent2(deps4, options.jobId, "browser_scenario_started", { scenarioId: scenario.scenarioId, resultId, contexts: scenario.contexts.length @@ -106398,7 +106504,7 @@ async function runBrowserScenario(deps3, options) { const availability = await options.driver.available(); if (!availability.ok) { return persist3( - deps3, + deps4, browserScenarioResultSchema.parse({ schemaVersion: BROWSER_SCHEMA_VERSION, resultId, @@ -106406,7 +106512,7 @@ async function runBrowserScenario(deps3, options) { ...options.jobId !== void 0 ? { jobId: options.jobId } : {}, status: "SKIPPED_NO_RUNTIME", startedAt, - finishedAt: nowIso5(deps3), + finishedAt: nowIso5(deps4), driver: options.driver.label, skipReason: availability.reason }), @@ -106428,7 +106534,7 @@ async function runBrowserScenario(deps3, options) { }); } catch (cause) { return persist3( - deps3, + deps4, browserScenarioResultSchema.parse({ schemaVersion: BROWSER_SCHEMA_VERSION, resultId, @@ -106436,7 +106542,7 @@ async function runBrowserScenario(deps3, options) { ...options.jobId !== void 0 ? { jobId: options.jobId } : {}, status: "ERRORED", startedAt, - finishedAt: nowIso5(deps3), + finishedAt: nowIso5(deps4), driver: options.driver.label, failureDetail: (cause instanceof Error ? cause.message : String(cause)).slice(0, 4e3) }), @@ -106449,7 +106555,7 @@ async function runBrowserScenario(deps3, options) { failureDetail = "the scenario was cancelled"; break; } - const before = now5(deps3).getTime(); + const before = now5(deps4).getTime(); const outcome = await session.step(step2); const assertion = isAssertionStep(step2); if (assertion) { @@ -106459,7 +106565,7 @@ async function runBrowserScenario(deps3, options) { let evidenceRef; if (outcome.evidence !== void 0 && policy.captureScreenshots) { evidenceRef = writeEvidenceFile( - deps3, + deps4, resultId, `${String(index).padStart(3, "0")}-${outcome.evidence.label}`, outcome.evidence.kind === "SCREENSHOT" ? "png" : "html", @@ -106478,7 +106584,7 @@ async function runBrowserScenario(deps3, options) { context: step2.context, ok: outcome.ok, detail: outcome.detail.slice(0, 4e3), - durationMs: Math.max(0, now5(deps3).getTime() - before), + durationMs: Math.max(0, now5(deps4).getTime() - before), ...evidenceRef !== void 0 ? { evidenceRef } : {} }); if (!outcome.ok) { @@ -106487,7 +106593,7 @@ async function runBrowserScenario(deps3, options) { if (snapshot2.length > 0) { evidence.push({ kind: "DOM_SNAPSHOT", - ref: writeEvidenceFile(deps3, resultId, `${String(index).padStart(3, "0")}-dom`, "html", snapshot2), + ref: writeEvidenceFile(deps4, resultId, `${String(index).padStart(3, "0")}-dom`, "html", snapshot2), label: "dom-at-failure", context: step2.context }); @@ -106500,7 +106606,7 @@ async function runBrowserScenario(deps3, options) { evidence.push({ kind: "CONSOLE_LOG", ref: writeEvidenceFile( - deps3, + deps4, resultId, "console", "json", @@ -106512,7 +106618,7 @@ async function runBrowserScenario(deps3, options) { } const status = failureDetail !== void 0 ? "FAILED" : assertionsRun > 0 ? "PASSED" : "FAILED"; return persist3( - deps3, + deps4, browserScenarioResultSchema.parse({ schemaVersion: BROWSER_SCHEMA_VERSION, resultId, @@ -106520,7 +106626,7 @@ async function runBrowserScenario(deps3, options) { ...options.jobId !== void 0 ? { jobId: options.jobId } : {}, status, startedAt, - finishedAt: nowIso5(deps3), + finishedAt: nowIso5(deps4), driver: options.driver.label, steps, assertionsRun, @@ -106528,7 +106634,7 @@ async function runBrowserScenario(deps3, options) { observations: observations.slice(0, 200), evidence, ...failureDetail !== void 0 ? { failureDetail } : assertionsRun === 0 ? { failureDetail: "the scenario ran no assertions and therefore proved nothing" } : {}, - durationMs: now5(deps3).getTime() - startedMs + durationMs: now5(deps4).getTime() - startedMs }), options.jobId ); @@ -106536,10 +106642,10 @@ async function runBrowserScenario(deps3, options) { await session.close(); } } -function writeEvidenceFile(deps3, resultId, name, extension, data) { +function writeEvidenceFile(deps4, resultId, name, extension, data) { const safe = name.replace(/[^A-Za-z0-9._-]/g, "-").slice(0, 60); const absolute = autonomyPath( - deps3.workspace, + deps4.workspace, "browser", "evidence", resultId, @@ -106556,9 +106662,9 @@ function writeEvidenceFile(deps3, resultId, name, extension, data) { `${safe}.${extension}` ); } -function persist3(deps3, result, jobId) { - writeJsonRecord(browserResultFile(deps3.workspace, result.resultId), result); - emitJobEvent2(deps3, jobId, "browser_scenario_completed", { +function persist3(deps4, result, jobId) { + writeJsonRecord(browserResultFile(deps4.workspace, result.resultId), result); + emitJobEvent2(deps4, jobId, "browser_scenario_completed", { scenarioId: result.scenarioId, resultId: result.resultId, status: result.status, @@ -106567,10 +106673,10 @@ function persist3(deps3, result, jobId) { }); return result; } -function emitJobEvent2(deps3, jobId, type, payload) { +function emitJobEvent2(deps4, jobId, type, payload) { if (jobId === void 0) return; try { - recordJobEvent(jobDepsOf(deps3), jobId, type, payload); + recordJobEvent(jobDepsOf(deps4), jobId, type, payload); } catch { } } @@ -106731,12 +106837,12 @@ async function runStep(page, step2, request, observations) { return { ok: true, detail: `context switched to ${step2.context}` }; } case "EXPECT_SELECTOR": { - const count22 = await page.locator(requireSelector(step2)).count(); - return count22 > 0 ? { ok: true, detail: `${step2.selector} present (${count22})` } : { ok: false, detail: `${step2.selector} was not present` }; + const count32 = await page.locator(requireSelector(step2)).count(); + return count32 > 0 ? { ok: true, detail: `${step2.selector} present (${count32})` } : { ok: false, detail: `${step2.selector} was not present` }; } case "EXPECT_ABSENT": { - const count22 = await page.locator(requireSelector(step2)).count(); - return count22 === 0 ? { ok: true, detail: `${step2.selector} absent` } : { ok: false, detail: `${step2.selector} was present (${count22})` }; + const count32 = await page.locator(requireSelector(step2)).count(); + return count32 === 0 ? { ok: true, detail: `${step2.selector} absent` } : { ok: false, detail: `${step2.selector} was present (${count32})` }; } case "EXPECT_TEXT": { const body = String(await page.innerText("body")).slice(0, 2e5); @@ -107178,10 +107284,10 @@ function readClosureLedger(workspace, jobId) { (raw) => closureLedgerSchema.parse(raw) ); } -function buildClosureLedger(deps3, input) { - const at = nowIso5(deps3); +function buildClosureLedger(deps4, input) { + const at = nowIso5(deps4); const entries = []; - const registry2 = readContractRegistry(deps3.workspace, input.seal.missionId); + const registry2 = readContractRegistry(deps4.workspace, input.seal.missionId); const byContract = new Map(registry2.map((contract) => [contract.contractId, contract])); for (const ref of input.seal.contracts) { const contract = byContract.get(ref.contractId); @@ -107229,7 +107335,7 @@ function buildClosureLedger(deps3, input) { phase: "IMPLEMENTATION", entries }); - writeJsonRecord(closureLedgerFile(deps3.workspace, input.jobId), ledger); + writeJsonRecord(closureLedgerFile(deps4.workspace, input.jobId), ledger); return ledger; } function entry(at, input) { @@ -107248,9 +107354,9 @@ function entry(at, input) { updatedAt: at }; } -function attributeNodeToItems(deps3, input) { - const ledger = requireLedger(deps3.workspace, input.jobId); - const at = nowIso5(deps3); +function attributeNodeToItems(deps4, input) { + const ledger = requireLedger(deps4.workspace, input.jobId); + const at = nowIso5(deps4); const entries = ledger.entries.map((existing) => { if (!input.itemIds.includes(existing.itemId)) return existing; if (existing.attributedNodeIds.includes(input.nodeId)) return existing; @@ -107261,11 +107367,11 @@ function attributeNodeToItems(deps3, input) { updatedAt: at }; }); - return saveLedger2(deps3, { ...ledger, entries }); + return saveLedger2(deps4, { ...ledger, entries }); } -function registerClosureEvidence(deps3, input) { - const ledger = requireLedger(deps3.workspace, input.jobId); - const at = nowIso5(deps3); +function registerClosureEvidence(deps4, input) { + const ledger = requireLedger(deps4.workspace, input.jobId); + const at = nowIso5(deps4); const entries = ledger.entries.map((existing) => { if (!input.itemIds.includes(existing.itemId)) return existing; return { @@ -107286,11 +107392,11 @@ function registerClosureEvidence(deps3, input) { updatedAt: at }; }); - return saveLedger2(deps3, { ...ledger, entries }); + return saveLedger2(deps4, { ...ledger, entries }); } -function waiveClosureItem(deps3, input) { - const ledger = requireLedger(deps3.workspace, input.jobId); - const at = nowIso5(deps3); +function waiveClosureItem(deps4, input) { + const ledger = requireLedger(deps4.workspace, input.jobId); + const at = nowIso5(deps4); const entries = ledger.entries.map( (existing) => existing.itemId === input.itemId ? { ...existing, @@ -107304,19 +107410,19 @@ function waiveClosureItem(deps3, input) { updatedAt: at } : existing ); - return saveLedger2(deps3, { ...ledger, entries }); + return saveLedger2(deps4, { ...ledger, entries }); } -function runClosureAudit(deps3, input) { - const policy = autonomyPolicyOf(deps3).closure; - const ledger = requireLedger(deps3.workspace, input.jobId); +function runClosureAudit(deps4, input) { + const policy = autonomyPolicyOf(deps4).closure; + const ledger = requireLedger(deps4.workspace, input.jobId); const completed = new Set(input.completedNodeIds); - const at = nowIso5(deps3); + const at = nowIso5(deps4); const entries = ledger.entries.map((existing) => { const attributedNodesComplete = existing.attributedNodeIds.length > 0 && existing.attributedNodeIds.every((nodeId) => completed.has(nodeId)); const assessment = assessItemClosure( existing, { - now: now5(deps3), + now: now5(deps4), ...input.gitHead !== void 0 ? { gitHead: input.gitHead } : {}, ...input.maxEvidenceAgeMs !== void 0 ? { maxEvidenceAgeMs: input.maxEvidenceAgeMs } : {} }, @@ -107330,7 +107436,7 @@ function runClosureAudit(deps3, input) { const totals = summarizeClosure(entries); const audit = closureAuditSchema.parse({ schemaVersion: CLOSURE_SCHEMA_VERSION, - auditId: input.auditId ?? newRecordId(deps3, "ca"), + auditId: input.auditId ?? newRecordId(deps4, "ca"), jobId: input.jobId, sealId: ledger.sealId, createdAt: at, @@ -107346,13 +107452,13 @@ function runClosureAudit(deps3, input) { })), rationale: verdict.rationale }); - const saved = saveLedger2(deps3, { ...ledger, entries, phase: verdict.nextPhase }); + const saved = saveLedger2(deps4, { ...ledger, entries, phase: verdict.nextPhase }); writeJsonRecord( - autonomyPath(deps3.workspace, "closure", input.jobId, "audits", `${audit.auditId}.json`), + autonomyPath(deps4.workspace, "closure", input.jobId, "audits", `${audit.auditId}.json`), audit ); try { - recordJobEvent(jobDepsOf(deps3), input.jobId, "closure_audit_completed", { + recordJobEvent(jobDepsOf(deps4), input.jobId, "closure_audit_completed", { auditId: audit.auditId, directive: audit.directive, phase: audit.phase, @@ -107364,24 +107470,24 @@ function runClosureAudit(deps3, input) { } return { ledger: saved, audit }; } -function attributeCompletedWork(deps3, input) { - const mission = requireMissionState(deps3.workspace, input.missionId); - const graph = requireJobState(deps3.workspace, input.jobId).graphRevision > 0 ? readGraphRevision( - deps3.workspace, +function attributeCompletedWork(deps4, input) { + const mission = requireMissionState(deps4.workspace, input.missionId); + const graph = requireJobState(deps4.workspace, input.jobId).graphRevision > 0 ? readGraphRevision( + deps4.workspace, input.jobId, - requireJobState(deps3.workspace, input.jobId).graphRevision + requireJobState(deps4.workspace, input.jobId).graphRevision ) : void 0; if (graph === void 0) return { attributed: 0 }; - const ledger = requireLedger(deps3.workspace, input.jobId); - const seal = latestExecutableSeal(deps3.workspace, input.missionId); + const ledger = requireLedger(deps4.workspace, input.jobId); + const seal = latestExecutableSeal(deps4.workspace, input.missionId); const criterionContracts = new Map( (seal?.acceptanceCriteria ?? []).map((criterion) => [criterion.criterionId, criterion.contractIds]) ); let attributed = 0; for (const node of graph.nodes) { if (node.status !== "COMPLETED") continue; - const contractIds = contractsForObjective(deps3.workspace, mission, node.parentTaskId); - const acceptance = acceptanceForObjective(deps3.workspace, mission, node.parentTaskId).map((line) => line.trim().toLowerCase()).filter((line) => line.length >= 12); + const contractIds = contractsForObjective(deps4.workspace, mission, node.parentTaskId); + const acceptance = acceptanceForObjective(deps4.workspace, mission, node.parentTaskId).map((line) => line.trim().toLowerCase()).filter((line) => line.length >= 12); const itemIds = ledger.entries.filter((entry2) => { const owner = entry2.itemId.split(/[/#]/)[0] ?? ""; if (contractIds.includes(owner)) return true; @@ -107394,13 +107500,13 @@ function attributeCompletedWork(deps3, input) { ); }).map((entry2) => entry2.itemId); if (itemIds.length === 0) continue; - attributeNodeToItems(deps3, { + attributeNodeToItems(deps4, { jobId: input.jobId, nodeId: node.nodeId, taskId: node.parentTaskId, itemIds }); - registerClosureEvidence(deps3, { + registerClosureEvidence(deps4, { jobId: input.jobId, itemIds, kind: "TRUSTED_VERIFICATION", @@ -107412,18 +107518,18 @@ function attributeCompletedWork(deps3, input) { } return { attributed }; } -function generateGapWork(deps3, input) { - const policy = autonomyPolicyOf(deps3).closure; - const ledger = requireLedger(deps3.workspace, input.jobId); +function generateGapWork(deps4, input) { + const policy = autonomyPolicyOf(deps4).closure; + const ledger = requireLedger(deps4.workspace, input.jobId); const byId = new Map(ledger.entries.map((existing) => [existing.itemId, existing])); - const at = nowIso5(deps3); + const at = nowIso5(deps4); const generated = []; for (const unclosed of input.audit.unclosed.slice(0, policy.maxGapWorkPerCycle)) { const existing = byId.get(unclosed.itemId); if (existing === void 0) continue; const gap = unclosed.gaps[0] ?? "NO_EVIDENCE"; const item = gapWorkItemSchema.parse({ - gapId: newRecordId(deps3, "gap"), + gapId: newRecordId(deps4, "gap"), itemId: unclosed.itemId, gapKind: gap, objective: objectiveFor(existing.statement, gap), @@ -107432,14 +107538,14 @@ function generateGapWork(deps3, input) { auditId: input.audit.auditId }); writeJsonRecord( - autonomyPath(deps3.workspace, "closure", input.jobId, "gaps", `${item.gapId}.json`), + autonomyPath(deps4.workspace, "closure", input.jobId, "gaps", `${item.gapId}.json`), item ); generated.push(item); } - saveLedger2(deps3, { ...ledger, gapCycles: ledger.gapCycles + 1 }); + saveLedger2(deps4, { ...ledger, gapCycles: ledger.gapCycles + 1 }); try { - recordJobEvent(jobDepsOf(deps3), input.jobId, "gap_work_generated", { + recordJobEvent(jobDepsOf(deps4), input.jobId, "gap_work_generated", { auditId: input.audit.auditId, generated: generated.length, cycle: ledger.gapCycles + 1 @@ -107462,9 +107568,9 @@ function objectiveFor(statement, gap) { }; return `${prefix[gap]} ${statement}`.slice(0, 4e3); } -function advanceClosurePhase(deps3, input) { - const ledger = requireLedger(deps3.workspace, input.jobId); - return saveLedger2(deps3, { +function advanceClosurePhase(deps4, input) { + const ledger = requireLedger(deps4.workspace, input.jobId); + return saveLedger2(deps4, { ...ledger, phase: input.phase, systemCycles: ledger.systemCycles + (input.systemCycle === true ? 1 : 0), @@ -107483,9 +107589,9 @@ function requireLedger(workspace, jobId) { } return ledger; } -function saveLedger2(deps3, ledger) { - const next = closureLedgerSchema.parse({ ...ledger, updatedAt: nowIso5(deps3) }); - writeJsonRecord(closureLedgerFile(deps3.workspace, next.jobId), next); +function saveLedger2(deps4, ledger) { + const next = closureLedgerSchema.parse({ ...ledger, updatedAt: nowIso5(deps4) }); + writeJsonRecord(closureLedgerFile(deps4.workspace, next.jobId), next); return next; } function createClosureCompletionGate(workspace, policy) { @@ -107572,14 +107678,14 @@ function resultFile(workspace, resultId) { assertAutonomyId("system result", resultId); return autonomyPath(workspace, "system", "results", `${resultId}.json`); } -function saveSystemScenario(deps3, input) { +function saveSystemScenario(deps4, input) { const scenario = systemScenarioSchema.parse({ schemaVersion: SYSTEM_SCENARIO_SCHEMA_VERSION, - scenarioId: input.scenarioId ?? newRecordId(deps3, "ss"), - createdAt: nowIso5(deps3), + scenarioId: input.scenarioId ?? newRecordId(deps4, "ss"), + createdAt: nowIso5(deps4), ...input }); - writeJsonRecord(scenarioFile(deps3.workspace, scenario.scenarioId), scenario); + writeJsonRecord(scenarioFile(deps4.workspace, scenario.scenarioId), scenario); return scenario; } function readSystemScenario(workspace, scenarioId) { @@ -107594,26 +107700,26 @@ function listSystemScenarios(workspace) { (raw) => systemScenarioSchema.parse(raw) ).sort((a2, b) => a2.scenarioId.localeCompare(b.scenarioId)); } -async function runSystemScenario(deps3, options) { - const scenario = readSystemScenario(deps3.workspace, options.scenarioId); +async function runSystemScenario(deps4, options) { + const scenario = readSystemScenario(deps4.workspace, options.scenarioId); if (scenario === void 0) { throw new AutonomyError("SBA024", `No system scenario "${options.scenarioId}" exists.`); } - const resultId = options.resultId ?? newRecordId(deps3, "sr"); - const startedAt = nowIso5(deps3); - emit2(deps3, options.jobId, "system_qualification_started", { + const resultId = options.resultId ?? newRecordId(deps4, "sr"); + const startedAt = nowIso5(deps4); + emit2(deps4, options.jobId, "system_qualification_started", { scenarioId: scenario.scenarioId, resultId }); if (scenario.environmentPlanId !== void 0 && options.runtime === void 0) { - return finish3(deps3, options, scenario, { + return finish3(deps4, options, scenario, { resultId, startedAt, status: "ENVIRONMENT_UNAVAILABLE", failureDetail: `the scenario declares environment plan ${scenario.environmentPlanId} and no environment runtime is available in this session; the product was never exercised` }); } - const instance = scenario.environmentPlanId === void 0 || options.runtime === void 0 ? void 0 : await provisionEnvironment(deps3, { + const instance = scenario.environmentPlanId === void 0 || options.runtime === void 0 ? void 0 : await provisionEnvironment(deps4, { planId: scenario.environmentPlanId, ...options.jobId !== void 0 ? { jobId: options.jobId } : {}, runtime: options.runtime, @@ -107622,7 +107728,7 @@ async function runSystemScenario(deps3, options) { ...options.signal !== void 0 ? { signal: options.signal } : {} }); if (instance !== void 0 && instance.status !== "READY") { - return finish3(deps3, options, scenario, { + return finish3(deps4, options, scenario, { resultId, startedAt, status: "ENVIRONMENT_UNAVAILABLE", @@ -107659,16 +107765,16 @@ async function runSystemScenario(deps3, options) { failureDetail = `step "${step2.name}" declares a fault but the scenario declares no environment plan`; break; } - faultInjected = await injectFault(deps3, { + faultInjected = await injectFault(deps4, { environmentPlanId: scenario.environmentPlanId, runtime: options.runtime, fault: step2.injectFault }); } - const before = now5(deps3).getTime(); + const before = now5(deps4).getTime(); const outcome = await runCommand({ argv: step2.argv, - cwd: deps3.workspace.rootDir, + cwd: deps4.workspace.rootDir, timeoutMs: step2.timeoutMs }); steps.push({ @@ -107676,7 +107782,7 @@ async function runSystemScenario(deps3, options) { name: step2.name, ok: outcome.ok, detail: outcome.detail.slice(0, 4e3), - durationMs: Math.max(0, now5(deps3).getTime() - before), + durationMs: Math.max(0, now5(deps4).getTime() - before), ...faultInjected !== void 0 ? { faultInjected } : {} }); if (!outcome.ok) { @@ -107687,7 +107793,7 @@ async function runSystemScenario(deps3, options) { const browserResultIds = []; if (failureDetail === void 0 && options.browserDriver !== void 0) { for (const browserScenarioId of scenario.browserScenarioIds) { - const browserResult = await runBrowserScenario(deps3, { + const browserResult = await runBrowserScenario(deps4, { scenarioId: browserScenarioId, driver: options.browserDriver, ...options.jobId !== void 0 ? { jobId: options.jobId } : {}, @@ -107703,7 +107809,7 @@ async function runSystemScenario(deps3, options) { } } } - const result = await finish3(deps3, options, scenario, { + const result = await finish3(deps4, options, scenario, { resultId, startedAt, status: failureDetail === void 0 ? "PASSED" : "FAILED", @@ -107713,7 +107819,7 @@ async function runSystemScenario(deps3, options) { ...failureDetail !== void 0 ? { failureDetail } : {} }); if (options.teardown !== false && instance !== void 0 && options.runtime !== void 0) { - await teardownEnvironment(deps3, { + await teardownEnvironment(deps4, { instanceId: instance.instanceId, runtime: options.runtime, retain: result.status !== "PASSED" @@ -107721,9 +107827,9 @@ async function runSystemScenario(deps3, options) { } return result; } -async function injectFault(deps3, input) { +async function injectFault(deps4, input) { const plan = readJsonRecord( - autonomyPath(deps3.workspace, "environments", "plans", `${input.environmentPlanId}.json`), + autonomyPath(deps4.workspace, "environments", "plans", `${input.environmentPlanId}.json`), (raw) => raw ); const service = plan?.services.find((entry2) => entry2.serviceId === input.fault.serviceId); @@ -107731,23 +107837,23 @@ async function injectFault(deps3, input) { await input.runtime.restart({ plan, service, - workspaceRoot: deps3.workspace.rootDir, + workspaceRoot: deps4.workspace.rootDir, timeoutMs: 12e4 }); return `${input.fault.kind} ${input.fault.serviceId}`; } -async function finish3(deps3, options, scenario, input) { +async function finish3(deps4, options, scenario, input) { const result = systemScenarioResultSchema.parse({ schemaVersion: SYSTEM_SCENARIO_SCHEMA_VERSION, scenarioId: scenario.scenarioId, ...options.jobId !== void 0 ? { jobId: options.jobId } : {}, - finishedAt: nowIso5(deps3), + finishedAt: nowIso5(deps4), ...input }); - writeJsonRecord(resultFile(deps3.workspace, result.resultId), result); + writeJsonRecord(resultFile(deps4.workspace, result.resultId), result); if (options.registerClosure === true && scenario.itemIds.length > 0 && options.jobId !== void 0) { if (result.status !== "ENVIRONMENT_UNAVAILABLE") { - registerClosureEvidence(deps3, { + registerClosureEvidence(deps4, { jobId: options.jobId, itemIds: scenario.itemIds, kind: "SYSTEM_SCENARIO", @@ -107757,17 +107863,17 @@ async function finish3(deps3, options, scenario, input) { }); } } - emit2(deps3, options.jobId, "system_qualification_completed", { + emit2(deps4, options.jobId, "system_qualification_completed", { scenarioId: scenario.scenarioId, resultId: result.resultId, status: result.status }); return result; } -function emit2(deps3, jobId, type, payload) { +function emit2(deps4, jobId, type, payload) { if (jobId === void 0) return; try { - recordJobEvent(jobDepsOf(deps3), jobId, type, payload); + recordJobEvent(jobDepsOf(deps4), jobId, type, payload); } catch { } } @@ -107825,11 +107931,11 @@ function resultFile2(workspace, runId) { assertAutonomyId("reproducibility run", runId); return autonomyPath(workspace, "reproducibility", `${runId}.json`); } -async function runReproducibilityQualification(deps3, options) { - const policy = autonomyPolicyOf(deps3).closure; - const runId = options.runId ?? newRecordId(deps3, "rp"); - const startedAt = nowIso5(deps3); - const deadline = now5(deps3).getTime() + policy.reproducibilityTimeoutMs; +async function runReproducibilityQualification(deps4, options) { + const policy = autonomyPolicyOf(deps4).closure; + const runId = options.runId ?? newRecordId(deps4, "rp"); + const startedAt = nowIso5(deps4); + const deadline = now5(deps4).getTime() + policy.reproducibilityTimeoutMs; const run = options.commandRunner ?? (async (input) => { const [executable, ...argv2] = input.argv; if (executable === void 0) return { outcome: "UNAVAILABLE", detail: "empty command" }; @@ -107857,7 +107963,7 @@ async function runReproducibilityQualification(deps3, options) { let failureDetail; let unavailable; for (const step2 of options.steps) { - if (options.signal?.aborted === true || now5(deps3).getTime() > deadline) { + if (options.signal?.aborted === true || now5(deps4).getTime() > deadline) { steps.push({ stepId: step2.stepId, dimension: step2.dimension, @@ -107869,7 +107975,7 @@ async function runReproducibilityQualification(deps3, options) { unavailable = unavailable ?? "the reproducibility window elapsed"; continue; } - const before = now5(deps3).getTime(); + const before = now5(deps4).getTime(); const outcome = await run({ argv: step2.argv, cwd: step2.cwd !== void 0 ? `${options.checkoutPath}/${step2.cwd}` : options.checkoutPath, @@ -107881,7 +107987,7 @@ async function runReproducibilityQualification(deps3, options) { name: step2.name, outcome: outcome.outcome, detail: outcome.detail.slice(0, 4e3), - durationMs: Math.max(0, now5(deps3).getTime() - before) + durationMs: Math.max(0, now5(deps4).getTime() - before) }); if (outcome.outcome === "FAILED") { failureDetail = `${step2.name}: ${outcome.detail}`; @@ -107898,7 +108004,7 @@ async function runReproducibilityQualification(deps3, options) { ...options.jobId !== void 0 ? { jobId: options.jobId } : {}, status, startedAt, - finishedAt: nowIso5(deps3), + finishedAt: nowIso5(deps4), checkoutPath: options.checkoutPath.slice(0, 200), ...options.gitHead !== void 0 ? { gitHead: options.gitHead } : {}, dimensions: [...new Set(options.steps.map((step2) => step2.dimension))], @@ -107906,17 +108012,17 @@ async function runReproducibilityQualification(deps3, options) { ...failureDetail !== void 0 ? { failureDetail } : {}, ...unavailable !== void 0 ? { inconclusiveReason: unavailable } : {} }); - writeJsonRecord(resultFile2(deps3.workspace, runId), result); + writeJsonRecord(resultFile2(deps4.workspace, runId), result); if (options.jobId !== void 0) { if (status === "PASSED") { - advanceClosurePhase(deps3, { + advanceClosurePhase(deps4, { jobId: options.jobId, phase: "FINAL_CONTRACT_AUDIT", reproducibilityPassed: true }); } if (options.itemIds !== void 0 && options.itemIds.length > 0 && status !== "INCONCLUSIVE") { - registerClosureEvidence(deps3, { + registerClosureEvidence(deps4, { jobId: options.jobId, itemIds: options.itemIds, kind: "REPRODUCIBILITY_RUN", @@ -107927,7 +108033,7 @@ async function runReproducibilityQualification(deps3, options) { }); } try { - recordJobEvent(jobDepsOf(deps3), options.jobId, "reproducibility_completed", { + recordJobEvent(jobDepsOf(deps4), options.jobId, "reproducibility_completed", { runId, status, dimensions: result.dimensions.length @@ -107937,13 +108043,13 @@ async function runReproducibilityQualification(deps3, options) { } return result; } -function ensureSystemScenarios(deps3, input) { - const ledger = readClosureLedger(deps3.workspace, input.jobId); +function ensureSystemScenarios(deps4, input) { + const ledger = readClosureLedger(deps4.workspace, input.jobId); const open = ledger?.entries.filter( (entry2) => (entry2.requiresSystemScenario || entry2.requiresBrowserScenario) && !isClosingStatus(entry2.status) ) ?? []; if (open.length === 0) return { scenarios: [], uncovered: [] }; - const existing = listSystemScenarios(deps3.workspace); + const existing = listSystemScenarios(deps4.workspace); const openIds = new Set(open.map((entry2) => entry2.itemId)); const covering = existing.filter( (scenario) => scenario.itemIds.some((itemId) => openIds.has(itemId)) @@ -107951,16 +108057,16 @@ function ensureSystemScenarios(deps3, input) { const covered = new Set(covering.flatMap((scenario) => scenario.itemIds)); const uncoveredIds = open.map((entry2) => entry2.itemId).filter((itemId) => !covered.has(itemId)); if (uncoveredIds.length === 0) return { scenarios: covering, uncovered: [] }; - const commands = deps3.config.verification.commands; + const commands = deps4.config.verification.commands; if (commands.length === 0) { return { scenarios: covering, uncovered: uncoveredIds }; } const plans = listJsonRecords( - autonomyPath(deps3.workspace, "environments", "plans"), + autonomyPath(deps4.workspace, "environments", "plans"), (raw) => environmentPlanSchema.parse(raw) ); - const browserScenarioIds = listBrowserScenarios(deps3.workspace).map((scenario) => scenario.scenarioId).slice(0, 20); - const synthesized = saveSystemScenario(deps3, { + const browserScenarioIds = listBrowserScenarios(deps4.workspace).map((scenario) => scenario.scenarioId).slice(0, 20); + const synthesized = saveSystemScenario(deps4, { scenarioId: `ss-default-${input.jobId}`.slice(0, 200), name: "Default mission qualification scenario", intent: "Synthesized deterministically from the trusted verification commands: run the full suite against the integrated product" + (plans.length === 1 ? " with its declared environment provisioned" : "") + (browserScenarioIds.length > 0 ? ", then the authored browser scenarios" : "") + ".", @@ -107977,8 +108083,8 @@ function ensureSystemScenarios(deps3, input) { }); return { scenarios: [...covering, synthesized], uncovered: [] }; } -async function runSystemScenarioPhase(deps3, options) { - const { scenarios, uncovered } = ensureSystemScenarios(deps3, { jobId: options.jobId }); +async function runSystemScenarioPhase(deps4, options) { + const { scenarios, uncovered } = ensureSystemScenarios(deps4, { jobId: options.jobId }); const result = { executed: 0, passed: 0, @@ -107989,7 +108095,7 @@ async function runSystemScenarioPhase(deps3, options) { for (const scenario of scenarios) { if (options.signal?.aborted === true) break; options.emit?.(`running system scenario ${scenario.scenarioId} (${scenario.name})`); - const run = await runSystemScenario(deps3, { + const run = await runSystemScenario(deps4, { scenarioId: scenario.scenarioId, jobId: options.jobId, ...options.runtime !== void 0 ? { runtime: options.runtime } : {}, @@ -108011,16 +108117,16 @@ async function runSystemScenarioPhase(deps3, options) { `${uncovered.length} scenario-owned item(s) have no scenario to run (no trusted verification commands to synthesize one from)` ); } - advanceClosurePhase(deps3, { + advanceClosurePhase(deps4, { jobId: options.jobId, phase: "SYSTEM_SCENARIO_QUALIFICATION", systemCycle: true }); return result; } -async function runReleaseQualificationPhase(deps3, options) { - const commands = deps3.config.verification.commands; - advanceClosurePhase(deps3, { +async function runReleaseQualificationPhase(deps4, options) { + const commands = deps4.config.verification.commands; + advanceClosurePhase(deps4, { jobId: options.jobId, phase: "RELEASE_QUALIFICATION", releaseQualificationCycle: true @@ -108032,21 +108138,21 @@ async function runReleaseQualificationPhase(deps3, options) { detail = "no trusted verification commands are configured; the integrated tree cannot be qualified"; } else { options.emit?.(`release qualification: running ${commands.length} trusted command(s) against the integrated tree`); - const run = options.verify !== void 0 ? await options.verify(commands) : await runVerificationCommands(deps3.workspace.rootDir, [...commands], { + const run = options.verify !== void 0 ? await options.verify(commands) : await runVerificationCommands(deps4.workspace.rootDir, [...commands], { ...options.signal !== void 0 ? { signal: options.signal } : {} }); passed = run.passed; detail = run.passed ? `all ${commands.length} trusted command(s) passed against the integrated tree` : `required command(s) failed: ${run.requiredFailed.join(", ").slice(0, 300)}`; } if (passed) { - advanceClosurePhase(deps3, { + advanceClosurePhase(deps4, { jobId: options.jobId, phase: "RELEASE_QUALIFICATION", releaseQualificationPassed: true }); } try { - recordJobEvent(jobDepsOf(deps3), options.jobId, "release_qualification_completed", { + recordJobEvent(jobDepsOf(deps4), options.jobId, "release_qualification_completed", { passed, detail: detail.slice(0, 300) }); @@ -108055,25 +108161,25 @@ async function runReleaseQualificationPhase(deps3, options) { options.emit?.(`release qualification: ${passed ? "PASSED" : "FAILED"} \u2014 ${detail}`); return { passed, detail }; } -async function runReproducibilityPhase(deps3, options) { - advanceClosurePhase(deps3, { +async function runReproducibilityPhase(deps4, options) { + advanceClosurePhase(deps4, { jobId: options.jobId, phase: "REPRODUCIBILITY", reproducibilityCycle: true }); - const commands = deps3.config.verification.commands; + const commands = deps4.config.verification.commands; if (commands.length === 0) { const detail = "no trusted verification commands are configured; there is nothing to reproduce"; options.emit?.(`reproducibility: NOT_RUN \u2014 ${detail}`); return { status: "NOT_RUN", detail }; } - const runId = newRecordId(deps3, "rp"); - const checkoutPath = autonomyPath(deps3.workspace, "reproducibility", "checkouts", runId); + const runId = newRecordId(deps4, "rp"); + const checkoutPath = autonomyPath(deps4.workspace, "reproducibility", "checkouts", runId); (0, import_fs80.mkdirSync)(import_path89.default.dirname(checkoutPath), { recursive: true }); const head = await runSafeProcess({ executable: "git", argv: ["rev-parse", "HEAD"], - cwd: deps3.workspace.rootDir, + cwd: deps4.workspace.rootDir, timeoutMs: 6e4, maxStdoutBytes: 4096, maxStderrBytes: 4096 @@ -108082,7 +108188,7 @@ async function runReproducibilityPhase(deps3, options) { const checkout = await runSafeProcess({ executable: "git", argv: ["worktree", "add", "--detach", checkoutPath, "HEAD"], - cwd: deps3.workspace.rootDir, + cwd: deps4.workspace.rootDir, timeoutMs: 3e5, maxStdoutBytes: 64 * 1024, maxStderrBytes: 64 * 1024 @@ -108093,7 +108199,7 @@ async function runReproducibilityPhase(deps3, options) { return { status: "INCONCLUSIVE", detail }; } const steps = []; - const installer = detectNodeInstaller(deps3.workspace); + const installer = detectNodeInstaller(deps4.workspace); if (installer !== void 0) { steps.push({ stepId: "install", @@ -108113,7 +108219,7 @@ async function runReproducibilityPhase(deps3, options) { }); }); try { - const result = await runReproducibilityQualification(deps3, { + const result = await runReproducibilityQualification(deps4, { jobId: options.jobId, steps, checkoutPath, @@ -108125,13 +108231,13 @@ async function runReproducibilityPhase(deps3, options) { const detail = result.status === "PASSED" ? `reproduced from a clean checkout of ${gitHead ?? "HEAD"}` : result.failureDetail ?? result.inconclusiveReason ?? `reproducibility ${result.status}`; options.emit?.(`reproducibility: ${result.status} \u2014 ${detail}`); if (result.status === "PASSED") { - await removeCheckout(deps3.workspace, checkoutPath); + await removeCheckout(deps4.workspace, checkoutPath); } else { options.emit?.(`the checkout is retained for diagnosis at ${checkoutPath}`); } return { status: result.status, detail }; } catch (error2) { - await removeCheckout(deps3.workspace, checkoutPath); + await removeCheckout(deps4.workspace, checkoutPath); throw error2; } } @@ -108152,10 +108258,10 @@ async function removeCheckout(workspace, checkoutPath) { maxStderrBytes: 16 * 1024 }); } -async function runGapRepairs(deps3, options) { - const policy = deps3.config.orchestration.jobs.objectives; - const commands = deps3.config.verification.commands; - const ledger = readClosureLedger(deps3.workspace, options.jobId); +async function runGapRepairs(deps4, options) { + const policy = deps4.config.orchestration.jobs.objectives; + const commands = deps4.config.verification.commands; + const ledger = readClosureLedger(deps4.workspace, options.jobId); const result = { repaired: [], failed: [] }; for (const item of options.items) { if (options.signal?.aborted === true) { @@ -108167,10 +108273,10 @@ async function runGapRepairs(deps3, options) { const fail = (reason3) => { options.emit?.(`gap ${item.gapId} (${item.itemId}): ${reason3}`); result.failed.push({ gapId: item.gapId, reason: reason3 }); - recordGapEvent(deps3, options.jobId, item, false, reason3); + recordGapEvent(deps4, options.jobId, item, false, reason3); }; const worktree = await createWorkerWorktree({ - workspace: deps3.workspace, + workspace: deps4.workspace, jobId: options.jobId, workUnitId: `gap-${item.gapId}`.slice(0, 40), attempt: 1 @@ -108189,13 +108295,13 @@ async function runGapRepairs(deps3, options) { ].join("\n"); options.emit?.(`gap ${item.gapId} (${item.itemId}): repair builder started`); const built = await runLargeObjectiveRole({ - workspace: deps3.workspace, - config: deps3.config, - runnerProfile: deps3.config.defaultRunner, + workspace: deps4.workspace, + config: deps4.config, + runnerProfile: deps4.config.defaultRunner, role: "BUILDER", packet, cwd: worktree.dir, - scratchDir: autonomyPath(deps3.workspace, "closure", options.jobId, "scratch", item.gapId), + scratchDir: autonomyPath(deps4.workspace, "closure", options.jobId, "scratch", item.gapId), timeoutMs: policy.builderTimeoutMs, ...options.signal !== void 0 ? { signal: options.signal } : {} }); @@ -108222,7 +108328,7 @@ async function runGapRepairs(deps3, options) { continue; } const patchFile = import_path89.default.join( - autonomyPath(deps3.workspace, "closure", options.jobId, "scratch", item.gapId), + autonomyPath(deps4.workspace, "closure", options.jobId, "scratch", item.gapId), "repair.patch" ); (0, import_fs80.mkdirSync)(import_path89.default.dirname(patchFile), { recursive: true }); @@ -108230,7 +108336,7 @@ async function runGapRepairs(deps3, options) { const applied = await runSafeProcess({ executable: "git", argv: ["apply", "--3way", patchFile], - cwd: deps3.workspace.rootDir, + cwd: deps4.workspace.rootDir, timeoutMs: 3e5, maxStdoutBytes: 64 * 1024, maxStderrBytes: 64 * 1024 @@ -108239,7 +108345,7 @@ async function runGapRepairs(deps3, options) { fail(`the verified repair no longer applies to the canonical tree: ${applied.stderr.split("\n")[0] ?? applied.status}`); continue; } - registerClosureEvidence(deps3, { + registerClosureEvidence(deps4, { jobId: options.jobId, itemIds: [item.itemId], kind: "TRUSTED_VERIFICATION", @@ -108247,7 +108353,7 @@ async function runGapRepairs(deps3, options) { passed: true, detail: `Gap repair (${item.gapKind}) verified by the full trusted suite in an isolated worktree.` }); - advanceClosurePhase(deps3, { + advanceClosurePhase(deps4, { jobId: options.jobId, phase: "GAP_IMPLEMENTATION", releaseQualificationPassed: false, @@ -108255,16 +108361,16 @@ async function runGapRepairs(deps3, options) { }); result.repaired.push(item.gapId); options.emit?.(`gap ${item.gapId} (${item.itemId}): repaired, verified, and integrated`); - recordGapEvent(deps3, options.jobId, item, true, `${collected.changedFiles.length} file(s) changed`); + recordGapEvent(deps4, options.jobId, item, true, `${collected.changedFiles.length} file(s) changed`); } finally { - await removeWorkerWorktree(deps3.workspace, options.jobId, worktree); + await removeWorkerWorktree(deps4.workspace, options.jobId, worktree); } } return result; } -function recordGapEvent(deps3, jobId, item, ok2, detail) { +function recordGapEvent(deps4, jobId, item, ok2, detail) { try { - recordJobEvent(jobDepsOf(deps3), jobId, "gap_repair_completed", { + recordJobEvent(jobDepsOf(deps4), jobId, "gap_repair_completed", { gapId: item.gapId, itemId: item.itemId, gapKind: item.gapKind, @@ -108359,10 +108465,10 @@ var INTERVENTION_EVENTS = Object.freeze({ // needs a person; only the event name differed. budget_exhausted: "the job stopped on an exhausted budget, needing an explicit user action" }); -function computeAutonomyTelemetry(deps3, input) { - const read = readJobState(deps3.workspace, input.jobId); +function deriveAutonomyTelemetry(deps4, input) { + const read = readJobState(deps4.workspace, input.jobId); const job = read.kind === "ok" ? read.job : void 0; - const events = safeEvents(deps3.workspace, input.jobId); + const events = safeEvents(deps4.workspace, input.jobId); const counters = job?.autonomyCounters; const interventions = []; let providerFailovers = 0; @@ -108371,8 +108477,8 @@ function computeAutonomyTelemetry(deps3, input) { let contextRollovers = 0; let supervisorWakeups = 0; let escalationsAfterBoundary = 0; - const bindingForBoundary = readSealBinding(deps3.workspace, input.jobId); - const boundary = bindingForBoundary !== void 0 ? readSealedAt(deps3, bindingForBoundary.sealId) : void 0; + const bindingForBoundary = readSealBinding(deps4.workspace, input.jobId); + const boundary = bindingForBoundary !== void 0 ? readSealedAt(deps4, bindingForBoundary.sealId) : void 0; const boundaryMs = boundary !== void 0 ? Date.parse(boundary) : Number.NaN; const afterBoundary = (at) => { if (!Number.isFinite(boundaryMs)) return true; @@ -108397,7 +108503,7 @@ function computeAutonomyTelemetry(deps3, input) { if (type === "context_rollover" || type === "fresh_context_selected") contextRollovers += 1; if (type === "driver_restarted" || type === "supervisor_attached") supervisorWakeups += 1; } - const supervisionLog = readSupervisionLog(deps3.workspace, 2e3); + const supervisionLog = readSupervisionLog(deps4.workspace, 2e3); supervisorWakeups += supervisionLog.filter( (entry2) => entry2.action === "WOKEN_ON_SCHEDULE" || entry2.action === "WOKEN_ON_RESOURCE_RETURN" ).length; @@ -108408,21 +108514,21 @@ function computeAutonomyTelemetry(deps3, input) { detail: job.blocker?.message ?? `the job is ${job.status} and cannot proceed without a person` }); } - const ledger = readClosureLedger(deps3.workspace, input.jobId); + const ledger = readClosureLedger(deps4.workspace, input.jobId); const totals = ledger !== void 0 ? summarizeClosure(ledger.entries) : void 0; - const toolsmith = listToolsmithRequests(deps3.workspace, input.jobId); - const browserResults = listBrowserResults(deps3.workspace).filter( + const toolsmith = listToolsmithRequests(deps4.workspace, input.jobId); + const browserResults = listBrowserResults(deps4.workspace).filter( (result) => result.jobId === input.jobId ); - const critiques = listCritiques(deps3.workspace).filter( + const critiques = listCritiques(deps4.workspace).filter( (critique) => critique.jobId === input.jobId ); - const binding = readSealBinding(deps3.workspace, input.jobId); + const binding = readSealBinding(deps4.workspace, input.jobId); const telemetry = autonomyTelemetrySchema.parse({ schemaVersion: TELEMETRY_SCHEMA_VERSION, jobId: input.jobId, ...binding !== void 0 ? { sealId: binding.sealId, missionId: binding.missionId } : {}, - recordedAt: nowIso5(deps3), + recordedAt: nowIso5(deps4), jobStatus: job?.status ?? "UNKNOWN", humanInterventionsAfterSeal: interventions.length, humanAuthorityEscalations: counters?.authorityEscalations ?? 0, @@ -108434,7 +108540,7 @@ function computeAutonomyTelemetry(deps3, input) { quotaWaits: Math.max(quotaWaits, counters?.resourceWaits ?? 0), contextRollovers: Math.max(contextRollovers, counters?.contextRollovers ?? 0), toolsmithActions: toolsmith.length, - selfCreatedTools: countSelfCreatedTools(deps3.workspace, input.jobId), + selfCreatedTools: countSelfCreatedTools(deps4.workspace, input.jobId), toolchainRepairs: counters?.toolchainRepairs ?? 0, environmentRepairs: counters?.environmentRepairs ?? 0, controlPlaneRepairs: counters?.controlPlaneRepairs ?? 0, @@ -108461,7 +108567,11 @@ function computeAutonomyTelemetry(deps3, input) { } : {}, interventions: interventions.slice(0, 200) }); - writeJsonRecord(telemetryFile(deps3.workspace, input.jobId), telemetry); + return telemetry; +} +function computeAutonomyTelemetry(deps4, input) { + const telemetry = deriveAutonomyTelemetry(deps4, input); + writeJsonRecord(telemetryFile(deps4.workspace, input.jobId), telemetry); return telemetry; } function elapsedFromJob(job) { @@ -108471,9 +108581,9 @@ function elapsedFromJob(job) { if (!Number.isFinite(created) || !Number.isFinite(updated)) return null; return Math.max(0, updated - created); } -function readSealedAt(deps3, sealId) { +function readSealedAt(deps4, sealId) { try { - return readSeal(deps3.workspace, sealId)?.sealedAt; + return readSeal(deps4.workspace, sealId)?.sealedAt; } catch { return void 0; } @@ -108500,13 +108610,1353 @@ function formatMeasurement(value, unit) { return String(value); } } -var shortText122 = external_exports.string().max(200); +var EXECUTION_TELEMETRY_REPORT_SCHEMA_VERSION = "1.0.0"; +var count3 = external_exports.number().int().min(0); +var shortText122 = external_exports.string().max(512); +var boundedText6 = external_exports.string().max(2e3); +var ratio3 = external_exports.number().min(0).max(1).nullable(); +var countMap = external_exports.record(external_exports.string(), count3); +var fractionMetricSchema = external_exports.object({ + numerator: count3.nullable(), + denominator: count3.nullable(), + value: ratio3 +}).strict(); +var tokenCoverageSchema = external_exports.object({ + attempts: count3, + withAny: count3, + withInput: count3, + withOutput: count3, + ratio: ratio3, + complete: external_exports.boolean() +}).strict(); +var tokenTelemetrySchema = external_exports.object({ + /** Sum of every reported input-token field; null when none reported. */ + inputTokens: count3.nullable(), + /** Sum of every reported output-token field; null when none reported. */ + outputTokens: count3.nullable(), + /** Sum of known components, even when coverage is partial. */ + knownTokens: count3.nullable(), + /** Total only when every attempt reported both components. */ + completeTokens: count3.nullable(), + coverage: tokenCoverageSchema +}).strict(); +var workAccountingSchema = external_exports.enum([ + "completed", + "failed", + "cancelled", + "waiting", + "not-ready", + "human-authority-pending", + "research-pending", + "context-pending" +]); +var diagnosticSchema = external_exports.object({ + code: shortText122, + severity: external_exports.enum(["info", "warning", "error"]), + message: boundedText6, + evidenceRefs: external_exports.array(shortText122).max(20).default([]) +}).strict(); +var phaseResearchSchema = external_exports.object({ + considered: count3, + avoided: count3, + reused: count3, + newCalls: count3, + quick: count3, + deep: count3, + failed: count3 +}).strict(); +var executionTelemetryReportSchema = external_exports.object({ + schemaVersion: external_exports.literal(EXECUTION_TELEMETRY_REPORT_SCHEMA_VERSION), + jobId: shortText122, + missionId: shortText122.nullable(), + generatedAt: shortText122, + period: external_exports.object({ + startedAt: shortText122, + endedAt: shortText122.nullable(), + durationMs: count3.nullable(), + activeExecutionMs: count3.nullable() + }).strict(), + provenance: external_exports.object({ + sourceJobId: shortText122, + jobGraphRevision: count3, + objectiveGraphRevisions: countMap, + executionLedgerWatermark: external_exports.string().regex(/^[a-f0-9]{64}$/), + eventWatermark: count3, + specbridgeVersion: shortText122.nullable(), + sealId: shortText122.nullable(), + sealedAuthorityDigest: shortText122.nullable(), + runtimePolicyChanged: external_exports.boolean().nullable(), + configuration: external_exports.object({ + secondaryBuildStrategy: shortText122, + researchStrategy: shortText122, + runnerProfiles: external_exports.array(shortText122).max(50) + }).strict() + }).strict(), + outcome: external_exports.object({ + status: external_exports.enum(["COMPLETED", "FAILED", "CANCELLED", "BLOCKED", "WAITING"]), + authoritativeJobStatus: shortText122, + finalOutcome: boundedText6.nullable(), + verification: external_exports.enum(["PASS", "FAIL", "UNAVAILABLE"]), + closure: external_exports.enum(["PASS", "FAIL", "UNAVAILABLE"]) + }).strict(), + work: external_exports.object({ + total: count3, + byKind: countMap, + accounting: external_exports.record(workAccountingSchema, count3), + completedImplementation: count3, + objectives: external_exports.array(external_exports.object({ + objectiveNodeId: shortText122, + graphRevision: count3.nullable(), + total: count3, + accounting: external_exports.record(workAccountingSchema, count3), + implementationAttempts: count3, + secondaryAttempts: count3, + strongBuilderAttempts: count3 + }).strict()).max(200), + units: external_exports.array(external_exports.object({ + workUnitId: shortText122, + objectiveNodeId: shortText122, + kind: shortText122, + status: shortText122, + accounting: workAccountingSchema, + builderPath: external_exports.enum(["SECONDARY", "SECONDARY_REPAIR", "STRONG", "STRONG_FALLBACK", "NONE", "UNKNOWN"]), + implementationAttempts: count3, + verification: external_exports.enum(["PASS", "FAIL", "PENDING", "UNAVAILABLE"]), + integration: external_exports.enum(["INTEGRATED", "NOT_INTEGRATED"]) + }).strict()).max(500), + omittedUnits: count3 + }).strict(), + secondary: external_exports.object({ + eligibility: external_exports.object({ + eligible: count3, + ineligible: count3, + strongRequired: count3, + needsResearch: count3, + needsAuthority: count3, + needsContext: count3, + notReady: count3, + unavailable: count3 + }).strict(), + selection: external_exports.object({ + secondarySelected: count3, + strongSelectedDespiteEligibility: count3, + noBuilderNeeded: count3, + waitingForResource: count3 + }).strict(), + funnel: external_exports.object({ + initialAttempts: count3, + initialPass: count3, + repairAttempted: count3, + repairPass: count3, + toStrongFallback: count3, + unavailableFallback: count3 + }).strict(), + initialSuccessRate: fractionMetricSchema, + repairRecoveryRate: fractionMetricSchema, + toStrongFallbackRate: fractionMetricSchema, + fallbackReasons: countMap, + builderTokens: tokenTelemetrySchema + }).strict(), + strong: external_exports.object({ + builderAttempts: count3, + evaluatorAttempts: count3, + selection: external_exports.object({ + requiredDirect: count3, + byStrategyOff: count3, + byAutoPolicy: count3, + becauseSecondaryUnavailable: count3, + fallbackAfterSecondary: count3 + }).strict(), + implementationTokens: tokenTelemetrySchema, + evaluatorTokens: tokenTelemetrySchema + }).strict(), + research: external_exports.object({ + scope: external_exports.enum(["JOB", "WORKSPACE", "NONE"]), + considered: count3.nullable(), + decisions: countMap, + providerCalls: count3, + successful: count3, + inconclusive: count3, + failed: count3, + priorResearchReused: count3, + newQuick: count3, + newDeep: count3, + avoidanceRatio: fractionMetricSchema, + reuseRate: fractionMetricSchema, + byPhase: external_exports.record(external_exports.string(), phaseResearchSchema), + usage: external_exports.object({ + inputTokens: count3.nullable(), + outputTokens: count3.nullable(), + durationMs: count3.nullable(), + providerReportedCost: external_exports.number().min(0).nullable(), + subagentCount: count3.nullable(), + recordsWithUsage: count3, + providerCalls: count3, + coverage: ratio3 + }).strict() + }).strict(), + cooldown: external_exports.object({ + episodes: count3, + observations: count3, + totalDurationMs: count3.nullable(), + usefulWorkDuringSubscriptionCooldown: count3, + secondaryImplementationWorkDuringCooldown: count3, + researchWorkDuringCooldown: count3, + strongRequiredWaiting: count3, + avoidableIdlePeriods: count3, + intervals: external_exports.array(external_exports.object({ + objectiveNodeId: shortText122, + status: external_exports.enum(["ACTIVE", "RECOVERED"]), + startedAt: shortText122, + endedAt: shortText122.nullable(), + durationMs: count3.nullable(), + completedWorkUnits: count3 + }).strict()).max(200), + timeline: external_exports.array(external_exports.object({ + at: shortText122, + type: shortText122, + objectiveNodeId: shortText122.nullable(), + detail: boundedText6 + }).strict()).max(200) + }).strict(), + attempts: external_exports.object({ + uniqueImplementationAttempts: count3, + meanPerCompletedWorkUnit: external_exports.number().min(0).nullable(), + medianPerCompletedWorkUnit: external_exports.number().min(0).nullable(), + maxPerWorkUnit: count3, + workUnitsWithMultipleAttempts: count3, + byKind: countMap, + completedWorkUnitsPerImplementationAttempt: external_exports.number().min(0).nullable(), + completedWorkUnitsPerStrongBuilderCall: external_exports.number().min(0).nullable(), + completedEligibleWorkUnitsPerSecondaryAttempt: external_exports.number().min(0).nullable() + }).strict(), + verification: external_exports.object({ + attempts: count3, + passes: count3, + failures: count3, + otherVerdicts: count3, + failuresByBuilderBackend: countMap, + failuresRecoveredByRepair: count3, + failuresRecoveredByStrongFallback: count3 + }).strict(), + closure: external_exports.object({ + available: external_exports.boolean(), + items: count3, + earned: count3, + waived: count3, + unresolved: count3, + completionGateOutcome: external_exports.enum(["PASS", "FAIL", "UNAVAILABLE"]), + ratio: ratio3 + }).strict(), + human: external_exports.object({ + decisionsBeforeSeal: count3.nullable(), + approvals: count3, + authorityEscalationsAfterSeal: count3.nullable(), + interventionsAfterSeal: count3, + unexpectedBlockersAfterSeal: count3, + zeroTouchAfterSeal: external_exports.boolean(), + byKind: countMap + }).strict(), + reliability: external_exports.object({ + failureSources: countMap, + recoveryActions: countMap, + noProgressDetections: count3, + repeatedProblemFingerprints: count3, + legitimateResourceWaitsExcluded: count3, + processRestarts: count3, + supervisorRestarts: count3, + candidatesPersisted: count3, + candidatesReusedAfterRestart: count3, + candidateRebuildsAfterRestart: count3, + candidatesLostOrUnreadable: count3, + candidateReadyResumes: count3, + integrationRetries: count3, + completedWorkRedoCount: count3, + completedWorkReusedAfterRestart: count3, + attemptsIncorrectlyRepeated: count3, + unexpectedBlocks: count3, + unrecoveredDriverDeaths: count3 + }).strict(), + efficiency: external_exports.object({ + strongBuilderAvoidanceRatio: fractionMetricSchema, + strongBuilderCallsAvoided: count3, + completedWorkUnitsPerImplementationAttempt: external_exports.number().min(0).nullable(), + baseline: external_exports.object({ + kind: external_exports.enum(["OBSERVED", "QUALIFICATION_FIXTURE"]), + reportId: shortText122, + strongBuilderAttempts: count3, + sameVerificationOutcome: external_exports.boolean(), + sameClosureOutcome: external_exports.boolean() + }).strict().nullable() + }).strict(), + qualificationSummary: external_exports.object({ + strongBuilderAvoidanceRatio: ratio3, + secondaryInitialSuccessRate: ratio3, + secondaryRepairRecoveryRate: ratio3, + secondaryToStrongFallback: count3, + strongImplementationTokens: count3.nullable(), + researchAvoidanceRatio: ratio3, + newResearchCalls: count3, + researchReuse: count3, + usefulWorkDuringSubscriptionCooldown: count3, + humanInterventionsAfterSeal: count3, + completedWorkRedoCount: count3, + unexpectedBlocks: count3, + unrecoveredDriverDeaths: count3 + }).strict(), + diagnostics: external_exports.array(diagnosticSchema).max(200) +}).strict(); +var SECRET_PATTERNS2 = [ + /-----BEGIN (?:RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----/gi, + /\b(?:bearer|basic)\s+[A-Za-z0-9+/=_-]{12,}/gi, + /\b(?:sk|ghp|github_pat|xox[baprs])[_-][A-Za-z0-9_-]{12,}\b/gi, + /\b(?:api[-_ ]?key|auth[-_ ]?token|access[-_ ]?token|password|secret)\s*[:=]\s*\S{8,}/gi +]; +function redactTelemetryText(value) { + let redacted = value; + for (const pattern of SECRET_PATTERNS2) redacted = redacted.replace(pattern, "[REDACTED]"); + return redacted.slice(0, 2e3); +} +function increment2(record5, key, by = 1) { + record5[key] = (record5[key] ?? 0) + by; +} +function metric(numerator, denominator) { + return { + numerator, + denominator, + value: numerator === null || denominator === null || denominator === 0 ? null : numerator / denominator + }; +} +function tokenTelemetry(attempts, usage) { + let input = 0; + let output = 0; + let withInput = 0; + let withOutput = 0; + let withAny = 0; + for (const attempt of attempts) { + const reported = usage(attempt); + const hasInput = reported.input !== null && reported.input !== void 0; + const hasOutput = reported.output !== null && reported.output !== void 0; + if (hasInput) { + input += reported.input ?? 0; + withInput += 1; + } + if (hasOutput) { + output += reported.output ?? 0; + withOutput += 1; + } + if (hasInput || hasOutput) withAny += 1; + } + const attemptCount = attempts.length; + const complete = attemptCount > 0 && withInput === attemptCount && withOutput === attemptCount; + return { + inputTokens: withInput > 0 ? input : null, + outputTokens: withOutput > 0 ? output : null, + knownTokens: withAny > 0 ? input + output : null, + completeTokens: complete ? input + output : null, + coverage: { + attempts: attemptCount, + withAny, + withInput, + withOutput, + ratio: attemptCount === 0 ? null : withAny / attemptCount, + complete + } + }; +} +function timestampMs(value) { + if (value === null || value === void 0) return void 0; + const parsed = Date.parse(value); + return Number.isFinite(parsed) ? parsed : void 0; +} +function outcomeStatus(status) { + if (status === "COMPLETED") return "COMPLETED"; + if (status === "FAILED") return "FAILED"; + if (status === "CANCELLED") return "CANCELLED"; + if (status === "BLOCKED" || status === "NEEDS_AUTHORITY" || status === "NEEDS_CLARIFICATION") { + return "BLOCKED"; + } + return "WAITING"; +} +function verificationOutcome(job, events) { + const status = job.latestEvidence?.evidenceStatus; + if (status === "verified" || status === "manually-accepted") return "PASS"; + const lastFailure = [...events].reverse().find((event) => event.type === "verification_failed"); + if (lastFailure !== void 0 && job.latestEvidence === void 0) return "FAIL"; + return "UNAVAILABLE"; +} +function currentRoutingStates(objectives) { + const current = /* @__PURE__ */ new Map(); + for (const objective of objectives) { + for (const state of objective.routingStates) { + const key = `${objective.objectiveNodeId}\0${state.workUnitId}`; + const prior = current.get(key); + if (prior === void 0 || state.updatedAt.localeCompare(prior.updatedAt, "en") > 0 || state.updatedAt === prior.updatedAt && state.contentHash.localeCompare(prior.contentHash, "en") > 0) { + current.set(key, state); + } + } + } + return current; +} +function uniqueBuilderAttempts(objectives) { + const seen = /* @__PURE__ */ new Map(); + let duplicateIds = 0; + for (const objective of objectives) { + for (const state of objective.routingStates) { + for (const attempt of state.attempts) { + const key = `${objective.objectiveNodeId}\0${state.workUnitId}\0${attempt.attemptId}`; + if (seen.has(key)) { + duplicateIds += 1; + continue; + } + seen.set(key, { ...attempt, objectiveNodeId: objective.objectiveNodeId, workUnitId: state.workUnitId }); + } + } + } + return { + attempts: [...seen.values()].sort( + (left, right) => left.startedAt.localeCompare(right.startedAt, "en") || left.objectiveNodeId.localeCompare(right.objectiveNodeId, "en") || left.workUnitId.localeCompare(right.workUnitId, "en") || left.sequence - right.sequence + ), + duplicateIds + }; +} +function latestUnits(objectives) { + const units = []; + for (const objective of objectives) { + for (const unit of objective.graph?.units ?? []) { + units.push({ objectiveNodeId: objective.objectiveNodeId, unit }); + } + } + return units.sort( + (left, right) => left.objectiveNodeId.localeCompare(right.objectiveNodeId, "en") || left.unit.workUnitId.localeCompare(right.unit.workUnitId, "en") + ); +} +function workAccounting(unit, routing) { + if (unit.status === "INTEGRATED") return "completed"; + if (unit.status === "FAILED") return "failed"; + if (unit.status === "SUPERSEDED") return "cancelled"; + const eligibility = routing?.initialEligibility; + if (eligibility === "NEEDS_AUTHORITY") return "human-authority-pending"; + if (eligibility === "NEEDS_RESEARCH") return "research-pending"; + if (eligibility === "NEEDS_CONTEXT") return "context-pending"; + if (eligibility === "NOT_READY" || unit.status === "PLANNED") return "not-ready"; + return "waiting"; +} +function builderPath(attempts) { + if (attempts.some((attempt) => attempt.kind === "STRONG_FALLBACK")) return "STRONG_FALLBACK"; + if (attempts.some((attempt) => attempt.kind === "STRONG")) return "STRONG"; + if (attempts.some((attempt) => attempt.kind === "SECONDARY_REPAIR")) return "SECONDARY_REPAIR"; + if (attempts.some((attempt) => attempt.kind === "SECONDARY")) return "SECONDARY"; + return attempts.length === 0 ? "NONE" : "UNKNOWN"; +} +function verificationFor(evaluations) { + if (evaluations.some((entry2) => entry2.verdict === "FAIL")) return "FAIL"; + if (evaluations.some((entry2) => entry2.verdict === "PASS")) return "PASS"; + if (evaluations.length > 0) return "PENDING"; + return "UNAVAILABLE"; +} +function fallbackReason(attempts) { + const preceding = [...attempts].reverse().find((attempt) => attempt.kind === "SECONDARY" || attempt.kind === "SECONDARY_REPAIR"); + if (preceding === void 0) return "other"; + if (preceding.noProgress) return "no-progress"; + switch (preceding.outcome) { + case "FAILED_VERIFICATION": + return "verification-failure"; + case "FAILED_OUTPUT": + return "malformed-model-result"; + case "FAILED_RESOURCE": + return "capability-failure"; + case "FAILED_IMPLEMENTATION": + return /context|stale source|insufficient/i.test(preceding.failureSummary ?? "") ? "context-insufficiency" : "implementation-failure"; + default: + return "other"; + } +} +function median4(values) { + if (values.length === 0) return null; + const sorted = [...values].sort((left, right) => left - right); + const middle = Math.floor(sorted.length / 2); + if (sorted.length % 2 === 1) return sorted[middle] ?? null; + return ((sorted[middle - 1] ?? 0) + (sorted[middle] ?? 0)) / 2; +} +function deriveExecutionTelemetryReport(facts) { + const diagnostics = []; + const generatedMs = timestampMs(facts.generatedAt) ?? 0; + const eventTypes = (type) => facts.events.filter((event) => event.type === type); + const currentRouting = currentRoutingStates(facts.objectives); + const { attempts: implementationAttempts, duplicateIds } = uniqueBuilderAttempts(facts.objectives); + const units = latestUnits(facts.objectives); + const evaluations = facts.objectives.flatMap((objective) => objective.evaluations).filter((entry2, index, values) => values.findIndex((other) => other.evaluationId === entry2.evaluationId) === index).sort((left, right) => left.createdAt.localeCompare(right.createdAt, "en")); + if (facts.eventTotal > facts.events.length) { + diagnostics.push({ + code: "EVENT_WINDOW_BOUNDED", + severity: "info", + message: `The report used the newest ${facts.events.length} of ${facts.eventTotal} job events; ledgers and current state remain authoritative for aggregates.`, + evidenceRefs: [] + }); + } + if (facts.objectives.length === 0) { + diagnostics.push({ + code: "OBJECTIVE_TELEMETRY_UNAVAILABLE", + severity: "info", + message: "No objective-runtime records exist; Phase 7/8 metrics are unavailable for this older or direct-execution job.", + evidenceRefs: [] + }); + } + if (facts.autonomy.boundaryStartedAt === null) { + diagnostics.push({ + code: "ZERO_TOUCH_BOUNDARY_UNAVAILABLE", + severity: "info", + message: "No durable seal boundary exists; intervention counting conservatively includes the whole recorded Job history.", + evidenceRefs: [] + }); + } + if (duplicateIds > 0) { + diagnostics.push({ + code: "ATTEMPT_REPLAY_DEDUPLICATED", + severity: "info", + message: `${duplicateIds} replayed builder-attempt record${duplicateIds === 1 ? "" : "s"} were ignored by durable attempt id.`, + evidenceRefs: [] + }); + } + if (facts.researchTelemetryDiagnostic !== void 0) { + diagnostics.push({ + code: "RESEARCH_TELEMETRY_UNREADABLE", + severity: "warning", + message: redactTelemetryText(facts.researchTelemetryDiagnostic), + evidenceRefs: [] + }); + } + for (const diagnostic of facts.researchRecordDiagnostics ?? []) { + diagnostics.push({ + code: diagnostic.code.slice(0, 512), + severity: "warning", + message: redactTelemetryText(diagnostic.message), + evidenceRefs: [] + }); + } + const attemptsByUnit = /* @__PURE__ */ new Map(); + for (const attempt of implementationAttempts) { + const key = `${attempt.objectiveNodeId}\0${attempt.workUnitId}`; + const list = attemptsByUnit.get(key) ?? []; + list.push(attempt); + attemptsByUnit.set(key, list); + } + const evaluationsByUnit = /* @__PURE__ */ new Map(); + for (const evaluation of evaluations) { + const key = `${evaluation.objectiveNodeId}\0${evaluation.workUnitId}`; + const list = evaluationsByUnit.get(key) ?? []; + list.push(evaluation); + evaluationsByUnit.set(key, list); + } + const workAccountingCounts = { + completed: 0, + failed: 0, + cancelled: 0, + waiting: 0, + "not-ready": 0, + "human-authority-pending": 0, + "research-pending": 0, + "context-pending": 0 + }; + const workByKind = {}; + const unitSummaries = []; + for (const entry2 of units) { + const key = `${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`; + const routing = currentRouting.get(key); + const unitAttempts = attemptsByUnit.get(key) ?? []; + const unitEvaluations = evaluationsByUnit.get(key) ?? []; + const accounting = workAccounting(entry2.unit, routing); + workAccountingCounts[accounting] += 1; + increment2(workByKind, entry2.unit.kind); + if (unitSummaries.length < 500) { + unitSummaries.push({ + workUnitId: entry2.unit.workUnitId, + objectiveNodeId: entry2.objectiveNodeId, + kind: entry2.unit.kind, + status: entry2.unit.status, + accounting, + builderPath: builderPath(unitAttempts), + implementationAttempts: unitAttempts.length, + verification: verificationFor(unitEvaluations), + integration: entry2.unit.status === "INTEGRATED" ? "INTEGRATED" : "NOT_INTEGRATED" + }); + } + } + const eligibility = { + eligible: 0, + ineligible: 0, + strongRequired: 0, + needsResearch: 0, + needsAuthority: 0, + needsContext: 0, + notReady: 0, + unavailable: units.filter((entry2) => entry2.unit.kind === "build" && !currentRouting.has(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`)).length + }; + const selection = { + secondarySelected: 0, + strongSelectedDespiteEligibility: 0, + noBuilderNeeded: 0, + waitingForResource: 0 + }; + const strongSelection = { + requiredDirect: 0, + byStrategyOff: 0, + byAutoPolicy: 0, + becauseSecondaryUnavailable: 0, + fallbackAfterSecondary: 0 + }; + const fallbackReasons = {}; + for (const entry2 of units) { + if (entry2.unit.kind !== "build") { + selection.noBuilderNeeded += 1; + continue; + } + const key = `${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`; + const state = currentRouting.get(key); + if (state === void 0) continue; + switch (state.initialEligibility) { + case "ELIGIBLE": + eligibility.eligible += 1; + break; + case "STRONG_REQUIRED": + eligibility.strongRequired += 1; + break; + case "NEEDS_RESEARCH": + eligibility.needsResearch += 1; + break; + case "NEEDS_AUTHORITY": + eligibility.needsAuthority += 1; + break; + case "NEEDS_CONTEXT": + eligibility.needsContext += 1; + break; + case "NOT_READY": + eligibility.notReady += 1; + break; + default: + break; + } + const decisions = state.decisions; + const unitAttempts = attemptsByUnit.get(key) ?? []; + if (entry2.unit.resourceWait !== void 0) selection.waitingForResource += 1; + if (state.initialEligibility === "ELIGIBLE") { + if (decisions.some((decision) => decision.selectedBackend === "SECONDARY")) { + selection.secondarySelected += 1; + } else if (decisions.some((decision) => decision.selectedBackend === "STRONG")) { + selection.strongSelectedDespiteEligibility += 1; + } + } + const directStrong = decisions.find((decision) => decision.selectedBackend === "STRONG"); + if (directStrong !== void 0 && !unitAttempts.some((attempt) => attempt.kind === "STRONG_FALLBACK")) { + if (state.initialEligibility === "STRONG_REQUIRED") strongSelection.requiredDirect += 1; + else if (directStrong.reasons.some((reason3) => reason3.code === "STRATEGY_OFF")) strongSelection.byStrategyOff += 1; + else if (directStrong.reasons.some((reason3) => reason3.code === "SECONDARY_UNAVAILABLE")) { + strongSelection.becauseSecondaryUnavailable += 1; + } else if (directStrong.reasons.some((reason3) => reason3.code === "SUBSCRIPTION_HARVEST" || reason3.code === "SECONDARY_AUTO_POLICY" || reason3.code === "CRITICAL_WORK_PREFERS_STRONG")) { + strongSelection.byAutoPolicy += 1; + } + } + if (unitAttempts.some((attempt) => attempt.kind === "STRONG_FALLBACK")) { + strongSelection.fallbackAfterSecondary += 1; + increment2(fallbackReasons, fallbackReason(unitAttempts)); + } + } + eligibility.ineligible = eligibility.strongRequired + eligibility.needsResearch + eligibility.needsAuthority + eligibility.needsContext + eligibility.notReady; + const eligibleUnits = units.filter((entry2) => { + const state = currentRouting.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`); + return entry2.unit.kind === "build" && state?.initialEligibility === "ELIGIBLE"; + }); + const eligibleCompleted = eligibleUnits.filter((entry2) => entry2.unit.status === "INTEGRATED"); + const eligibleCompletedWithoutStrong = eligibleCompleted.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return !attempts.some((attempt) => attempt.kind === "STRONG" || attempt.kind === "STRONG_FALLBACK"); + }); + const secondaryAttemptedUnits = eligibleUnits.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => (attempt.kind === "SECONDARY" || attempt.kind === "SECONDARY_REPAIR") && attempt.outcome !== "FAILED_RESOURCE" && attempt.outcome !== "CANCELLED"); + }); + const initialAttemptedUnits = eligibleUnits.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => attempt.kind === "SECONDARY" && attempt.outcome !== "FAILED_RESOURCE" && attempt.outcome !== "CANCELLED"); + }); + const initialPassUnits = initialAttemptedUnits.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => attempt.kind === "SECONDARY" && attempt.outcome === "SUCCEEDED"); + }); + const repairAttemptedUnits = eligibleUnits.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => attempt.kind === "SECONDARY_REPAIR" && attempt.outcome !== "FAILED_RESOURCE" && attempt.outcome !== "CANCELLED"); + }); + const repairPassUnits = repairAttemptedUnits.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => attempt.kind === "SECONDARY_REPAIR" && attempt.outcome === "SUCCEEDED"); + }); + const fallbackUnits = eligibleUnits.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => attempt.kind === "STRONG_FALLBACK"); + }); + const unavailableFallbackUnits = eligibleUnits.filter((entry2) => { + const state = currentRouting.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`); + return state?.decisions.some((decision) => decision.selectedBackend === "STRONG" && decision.reasons.some((reason3) => reason3.code === "SECONDARY_UNAVAILABLE")) === true; + }); + const secondaryAttempts = implementationAttempts.filter((attempt) => attempt.kind === "SECONDARY" || attempt.kind === "SECONDARY_REPAIR"); + const strongAttempts = implementationAttempts.filter((attempt) => attempt.kind === "STRONG" || attempt.kind === "STRONG_FALLBACK"); + const strongEvaluatorAttempts = facts.ledger.filter((entry2) => entry2.role === "EVALUATOR" && entry2.lane !== "LOCAL"); + const secondaryTokens = tokenTelemetry(secondaryAttempts, (attempt) => ({ + input: attempt.inputTokens, + output: attempt.outputTokens + })); + const strongTokens = tokenTelemetry(strongAttempts, (attempt) => ({ + input: attempt.inputTokens, + output: attempt.outputTokens + })); + const evaluatorTokens = tokenTelemetry(strongEvaluatorAttempts, (attempt) => ({ + input: attempt.metrics.inputTokens, + output: attempt.metrics.outputTokens + })); + const jobResearchRecords = facts.researchRecords.filter((record5) => record5.scope?.jobId === facts.job.jobId); + const jobResearchIds = new Set(jobResearchRecords.map((record5) => record5.researchId)); + const jobResearchUses = facts.researchUses.filter((use) => jobResearchIds.has(use.researchId)); + const hasJobResearch = jobResearchRecords.length > 0 || jobResearchUses.length > 0; + const hasWorkspaceResearch = (facts.researchTelemetry?.gateConsidered ?? 0) > 0 || facts.researchRecords.length > 0 || facts.researchUses.length > 0; + const researchScope = hasJobResearch ? "JOB" : hasWorkspaceResearch ? "WORKSPACE" : "NONE"; + const reportResearchRecords = hasJobResearch ? jobResearchRecords : facts.researchRecords; + const reportResearchUses = hasJobResearch ? jobResearchUses : facts.researchUses; + const useIds = new Set(reportResearchUses.map((use) => use.useId)); + const uniqueUses = reportResearchUses.filter((use) => { + if (!useIds.has(use.useId)) return false; + useIds.delete(use.useId); + return true; + }); + const providerRecords = reportResearchRecords.filter((record5) => record5.status !== "PENDING"); + const workspaceResearch = researchScope === "WORKSPACE"; + const providerCallCount = workspaceResearch ? facts.researchTelemetry?.providerCalls ?? providerRecords.length : providerRecords.length; + const successfulResearch = workspaceResearch ? facts.researchTelemetry?.successfulResearch ?? providerRecords.filter((record5) => record5.status === "COMPLETED").length : providerRecords.filter((record5) => record5.status === "COMPLETED").length; + const inconclusiveResearch = workspaceResearch ? facts.researchTelemetry?.inconclusiveResearch ?? providerRecords.filter((record5) => record5.status === "INCONCLUSIVE").length : providerRecords.filter((record5) => record5.status === "INCONCLUSIVE").length; + const failedResearch = workspaceResearch ? facts.researchTelemetry?.failedResearch ?? providerRecords.filter((record5) => record5.status === "FAILED").length : providerRecords.filter((record5) => record5.status === "FAILED").length; + const reuseCount = workspaceResearch ? facts.researchTelemetry?.reusedReports ?? uniqueUses.filter((use) => use.useKind === "REUSED").length : uniqueUses.filter((use) => use.useKind === "REUSED").length; + const newQuick = workspaceResearch ? facts.researchTelemetry?.newQuick ?? providerRecords.filter((record5) => record5.depth === "QUICK").length : providerRecords.filter((record5) => record5.depth === "QUICK").length; + const newDeep = workspaceResearch ? facts.researchTelemetry?.newDeep ?? providerRecords.filter((record5) => record5.depth === "DEEP").length : providerRecords.filter((record5) => record5.depth === "DEEP").length; + const researchConsidered = researchScope === "WORKSPACE" ? facts.researchTelemetry?.gateConsidered ?? null : null; + const researchAvoided = researchScope === "WORKSPACE" ? facts.researchTelemetry?.researchAvoided ?? null : null; + const researchDecisions = researchScope === "WORKSPACE" ? { ...facts.researchTelemetry?.decisions ?? {} } : {}; + const byPhase = {}; + for (const phase of ["CONVERSATION", "SPEC_DRAFT", "INTAKE_DECISION", "RUNTIME_INVESTIGATION"]) { + const aggregate = researchScope === "WORKSPACE" ? facts.researchTelemetry?.byPhase[phase] : void 0; + const phaseRecords = providerRecords.filter((record5) => record5.lifecycle?.phase === phase); + const phaseUses = uniqueUses.filter((use) => use.phase === phase); + byPhase[phase] = { + considered: aggregate?.considered ?? 0, + avoided: aggregate?.avoided ?? 0, + reused: researchScope === "WORKSPACE" ? aggregate?.reused ?? phaseUses.filter((use) => use.useKind === "REUSED").length : phaseUses.filter((use) => use.useKind === "REUSED").length, + newCalls: researchScope === "WORKSPACE" ? (aggregate?.newQuick ?? 0) + (aggregate?.newDeep ?? 0) : phaseRecords.length, + quick: researchScope === "WORKSPACE" ? aggregate?.newQuick ?? phaseRecords.filter((record5) => record5.depth === "QUICK").length : phaseRecords.filter((record5) => record5.depth === "QUICK").length, + deep: researchScope === "WORKSPACE" ? aggregate?.newDeep ?? phaseRecords.filter((record5) => record5.depth === "DEEP").length : phaseRecords.filter((record5) => record5.depth === "DEEP").length, + failed: phaseRecords.filter((record5) => record5.status === "FAILED").length + }; + } + let researchInputTokens = 0; + let researchOutputTokens = 0; + let researchDurationMs = 0; + let researchCost = 0; + let researchSubagents = 0; + let researchInputObserved = false; + let researchOutputObserved = false; + let researchDurationObserved = false; + let researchCostObserved = false; + let researchSubagentsObserved = false; + let recordsWithUsage = 0; + for (const record5 of providerRecords) { + const usage = record5.usage ?? record5.report?.usage; + if (usage === void 0) continue; + recordsWithUsage += 1; + if (usage.inputTokens !== void 0) { + researchInputObserved = true; + researchInputTokens += usage.inputTokens; + } + if (usage.outputTokens !== void 0) { + researchOutputObserved = true; + researchOutputTokens += usage.outputTokens; + } + if (usage.durationMs !== void 0) { + researchDurationObserved = true; + researchDurationMs += usage.durationMs; + } + if (usage.providerReportedCost !== void 0) { + researchCostObserved = true; + researchCost += usage.providerReportedCost; + } + if (usage.subagentCount !== void 0) { + researchSubagentsObserved = true; + researchSubagents += usage.subagentCount; + } + } + if (researchScope === "WORKSPACE" && providerRecords.length === 0 && facts.researchTelemetry !== void 0) { + const reported = facts.researchTelemetry.reportedUsage; + if (reported.reports > 0) { + recordsWithUsage = reported.reports; + if (reported.inputTokens > 0) { + researchInputObserved = true; + researchInputTokens = reported.inputTokens; + } + if (reported.outputTokens > 0) { + researchOutputObserved = true; + researchOutputTokens = reported.outputTokens; + } + if (reported.providerReportedCost > 0) { + researchCostObserved = true; + researchCost = reported.providerReportedCost; + } + if (reported.subagentCount > 0) { + researchSubagentsObserved = true; + researchSubagents = reported.subagentCount; + } + } + if (facts.researchTelemetry.totalDurationMs > 0) { + researchDurationObserved = true; + researchDurationMs = facts.researchTelemetry.totalDurationMs; + } + } + const cooldownStates = facts.objectives.map((objective) => objective.cooldown).filter((state) => state !== void 0); + const cooldownIntervals = []; + let cooldownDurationMs = 0; + let cooldownDurationKnown = cooldownStates.length > 0; + let cooldownEpisodes = 0; + for (const state of cooldownStates) { + cooldownEpisodes += state.episodes; + const startedAt = state.currentStartedAt ?? state.firstStartedAt; + const endedAt = state.status === "RECOVERED" ? state.lastEndedAt ?? null : null; + const startMs = timestampMs(startedAt); + const endMs = state.status === "ACTIVE" ? generatedMs : timestampMs(endedAt); + const durationMs = startMs !== void 0 && endMs !== void 0 && endMs >= startMs ? endMs - startMs : null; + if (state.episodes !== 1) cooldownDurationKnown = false; + if (durationMs === null) cooldownDurationKnown = false; + else cooldownDurationMs += durationMs; + cooldownIntervals.push({ + objectiveNodeId: state.objectiveNodeId, + status: state.status, + startedAt, + endedAt, + durationMs, + completedWorkUnits: state.completedDuringCooldown.length + }); + if (state.episodes > 1) { + diagnostics.push({ + code: "COOLDOWN_DURATION_PARTIAL", + severity: "info", + message: `Objective ${state.objectiveNodeId} records ${state.episodes} cooldown episodes but retains only bounded interval endpoints; total duration is unavailable.`, + evidenceRefs: [state.objectiveNodeId] + }); + } + } + const cooldownCompletedKeys = /* @__PURE__ */ new Set(); + const cooldownWaitingKeys = /* @__PURE__ */ new Set(); + for (const state of cooldownStates) { + for (const workUnitId of state.completedDuringCooldown) { + cooldownCompletedKeys.add(`${state.objectiveNodeId}\0${workUnitId}`); + } + for (const workUnitId of state.waitingWorkUnitIds) { + cooldownWaitingKeys.add(`${state.objectiveNodeId}\0${workUnitId}`); + } + } + let secondaryImplementationDuringCooldown = 0; + for (const entry2 of units) { + const key = `${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`; + if (!cooldownCompletedKeys.has(key) || entry2.unit.kind !== "build") continue; + const unitAttempts = attemptsByUnit.get(key) ?? []; + if (unitAttempts.some((attempt) => attempt.kind === "SECONDARY" || attempt.kind === "SECONDARY_REPAIR") && !unitAttempts.some((attempt) => attempt.kind === "STRONG" || attempt.kind === "STRONG_FALLBACK")) { + secondaryImplementationDuringCooldown += 1; + } + } + const withinCooldown = (at) => { + const atMs = timestampMs(at); + if (atMs === void 0) return false; + return cooldownIntervals.some((interval) => { + const start = timestampMs(interval.startedAt); + const end = timestampMs(interval.endedAt) ?? generatedMs; + return start !== void 0 && atMs >= start && atMs <= end; + }); + }; + const researchDuringCooldown = providerRecords.filter((record5) => (record5.status === "COMPLETED" || record5.status === "INCONCLUSIVE") && withinCooldown(record5.report?.completedAt ?? record5.updatedAt)).length; + let avoidableIdlePeriods = 0; + for (const objective of facts.objectives) { + if (objective.cooldown?.status !== "ACTIVE" || objective.graph === void 0) continue; + for (const unit of objective.graph.units) { + if (unit.kind !== "build" || unit.status !== "READY" || unit.resourceWait !== void 0) continue; + const key = `${objective.objectiveNodeId}\0${unit.workUnitId}`; + const state = currentRouting.get(key); + if (state?.initialEligibility !== "ELIGIBLE" || state.strategy === "OFF") continue; + const startMs = timestampMs(objective.cooldown.currentStartedAt); + const dispatched = (attemptsByUnit.get(key) ?? []).some((attempt) => { + const attemptMs = timestampMs(attempt.startedAt); + return (attempt.kind === "SECONDARY" || attempt.kind === "SECONDARY_REPAIR") && attemptMs !== void 0 && (startMs === void 0 || attemptMs >= startMs); + }); + if (!dispatched) avoidableIdlePeriods += 1; + } + } + if (avoidableIdlePeriods > 0) { + diagnostics.push({ + code: "AVOIDABLE_IDLE_DURING_COOLDOWN", + severity: "warning", + message: `${avoidableIdlePeriods} runnable Secondary work period(s) had no durable Secondary dispatch during an active Strong cooldown.`, + evidenceRefs: [] + }); + } + const cooldownEventTypes = /* @__PURE__ */ new Set([ + "resource_cooldown_started", + "resource_cooldown_observed", + "work_unit_resource_wait_started", + "work_unit_resource_wait_ended", + "resource_wait_entered", + "useful_work_during_cooldown", + "resource_recovered" + ]); + const cooldownTimeline = facts.events.filter((event) => cooldownEventTypes.has(event.type)).slice(-200).map((event) => ({ + at: String(event.at ?? ""), + type: event.type, + objectiveNodeId: typeof event["nodeId"] === "string" ? event["nodeId"].slice(0, 512) : null, + detail: cooldownEventDetail(event) + })); + const evaluationFailures = evaluations.filter((entry2) => entry2.verdict === "FAIL"); + const evaluationPasses = evaluations.filter((entry2) => entry2.verdict === "PASS"); + const failuresByBackend = {}; + let failuresRecoveredByRepair = 0; + let failuresRecoveredByStrongFallback = 0; + const failedUnitKeys = /* @__PURE__ */ new Set(); + for (const evaluation of evaluationFailures) { + const key = `${evaluation.objectiveNodeId}\0${evaluation.workUnitId}`; + failedUnitKeys.add(key); + const unitAttempts = attemptsByUnit.get(key) ?? []; + const matching = [...unitAttempts].reverse().find((attempt) => attempt.workUnitAttempt === evaluation.attempt); + increment2(failuresByBackend, matching?.kind ?? "UNKNOWN"); + } + for (const key of failedUnitKeys) { + const unitAttempts = attemptsByUnit.get(key) ?? []; + if (unitAttempts.some((attempt) => attempt.kind === "SECONDARY_REPAIR" && attempt.outcome === "SUCCEEDED")) { + failuresRecoveredByRepair += 1; + } + if (unitAttempts.some((attempt) => attempt.kind === "STRONG_FALLBACK" && attempt.outcome === "SUCCEEDED")) { + failuresRecoveredByStrongFallback += 1; + } + } + const failureSources = {}; + const recoveryActions = {}; + for (const entry2 of facts.ledger) { + if (entry2.failureSource !== null) increment2(failureSources, entry2.failureSource); + else if (!entry2.success && entry2.failureReason !== null) increment2(failureSources, "UNCLASSIFIED"); + if (entry2.recoveryAction !== null) increment2(recoveryActions, entry2.recoveryAction); + } + const repairAttempts = implementationAttempts.filter((attempt) => attempt.kind === "SECONDARY_REPAIR").length; + const strongFallbackAttempts = implementationAttempts.filter((attempt) => attempt.kind === "STRONG_FALLBACK").length; + if (repairAttempts > 0) increment2(recoveryActions, "repair", repairAttempts); + if (strongFallbackAttempts > 0) increment2(recoveryActions, "strong-fallback", strongFallbackAttempts); + const resourceWaitEvents = eventTypes("resource_wait_started").length + eventTypes("resource_wait_entered").length + eventTypes("work_unit_resource_wait_started").length; + if (resourceWaitEvents > 0) increment2(recoveryActions, "resource-wait", resourceWaitEvents); + const restartEvents = eventTypes("job_resumed").length + eventTypes("driver_restarted").length; + if (restartEvents > 0) increment2(recoveryActions, "restart-resume", restartEvents); + const noProgressDetections = implementationAttempts.filter((attempt) => attempt.noProgress).length; + const fingerprintCounts = /* @__PURE__ */ new Map(); + for (const attempt of implementationAttempts) { + if (attempt.problemFingerprint !== void 0) { + fingerprintCounts.set( + attempt.problemFingerprint, + (fingerprintCounts.get(attempt.problemFingerprint) ?? 0) + 1 + ); + } + } + const repeatedProblemFingerprints = [...fingerprintCounts.values()].filter((value) => value > 1).length; + const candidatesPersisted = new Set( + implementationAttempts.map((attempt) => attempt.candidateRef).filter((ref) => ref !== void 0) + ).size; + const candidateRebuilds = eventTypes("candidate_resume_missing").length; + const candidatesReused = cooldownStates.reduce( + (sum, state) => sum + state.candidateReuseAfterRestart, + 0 + ); + const integrationRetries = eventTypes("integration_failed").length; + let completedWorkRedoCount = 0; + for (const entry2 of units) { + if (entry2.unit.integratedAt === void 0) continue; + const integratedMs = timestampMs(entry2.unit.integratedAt); + if (integratedMs === void 0) continue; + const attemptsAfterIntegration = (attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []).filter((attempt) => (timestampMs(attempt.startedAt) ?? 0) > integratedMs); + if (attemptsAfterIntegration.length > 0) completedWorkRedoCount += 1; + } + const lastRestartMs = Math.max( + 0, + ...facts.events.filter((event) => event.type === "job_resumed" || event.type === "driver_restarted").map((event) => timestampMs(event.at) ?? 0) + ); + const completedWorkReusedAfterRestart = lastRestartMs === 0 ? 0 : units.filter((entry2) => { + if (entry2.unit.status !== "INTEGRATED") return false; + const unitAttempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return unitAttempts.length > 0 && unitAttempts.every((attempt) => (timestampMs(attempt.completedAt) ?? Number.MAX_SAFE_INTEGER) <= lastRestartMs); + }).length; + const unresolvedInterrupted = facts.ledger.filter((entry2) => { + if (entry2.status !== "INTERRUPTED") return false; + return !facts.ledger.some((candidate) => candidate.taskId === entry2.taskId && candidate.attemptNumber > entry2.attemptNumber && candidate.status === "COMPLETED"); + }).length; + const unrecoveredDriverDeaths = ["COMPLETED", "FAILED", "CANCELLED"].includes(facts.job.status) ? unresolvedInterrupted : 0; + const unexpectedBlocks = facts.autonomy.interventions.filter((intervention) => intervention.kind === "job_blocked" || intervention.kind === "budget_exhausted" || intervention.kind.startsWith("status:")).length; + if (completedWorkRedoCount > 0) { + diagnostics.push({ + code: "COMPLETED_WORK_REDONE", + severity: "error", + message: `${completedWorkRedoCount} authoritatively integrated WorkUnit(s) have a later implementation attempt without recorded invalidation.`, + evidenceRefs: [] + }); + } + const completedImplementation = units.filter((entry2) => entry2.unit.kind === "build" && entry2.unit.status === "INTEGRATED").length; + const attemptCountsForCompleted = units.filter((entry2) => entry2.unit.status === "INTEGRATED" && entry2.unit.kind === "build").map((entry2) => (attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []).length); + const totalAttemptsForCompleted = attemptCountsForCompleted.reduce((sum, value) => sum + value, 0); + const meanAttempts = attemptCountsForCompleted.length === 0 ? null : totalAttemptsForCompleted / attemptCountsForCompleted.length; + const completedPerAttempt = implementationAttempts.length === 0 ? null : completedImplementation / implementationAttempts.length; + const completedPerStrong = strongAttempts.length === 0 ? null : completedImplementation / strongAttempts.length; + const completedEligiblePerSecondary = secondaryAttempts.length === 0 ? null : eligibleCompleted.length / secondaryAttempts.length; + const closureTotals = facts.closure === void 0 ? void 0 : summarizeClosure(facts.closure.entries); + const closureGate = facts.closure === void 0 ? void 0 : missionMayComplete(facts.closure, facts.closurePolicy); + const closureOutcome = facts.closure === void 0 ? "UNAVAILABLE" : closureGate?.mayComplete === true ? "PASS" : "FAIL"; + const overallVerification = verificationOutcome(facts.job, facts.events); + const boundaryMs = timestampMs(facts.autonomy.boundaryStartedAt); + const decisionsBeforeSeal = boundaryMs === void 0 ? null : facts.events.filter((event) => (event.type === "clarification_resolved" || event.type === "authority_resolved") && (timestampMs(event.at) ?? Number.MAX_SAFE_INTEGER) < boundaryMs).length; + const humanByKind = {}; + for (const intervention of facts.autonomy.interventions) increment2(humanByKind, intervention.kind); + const objectiveRevisions = {}; + for (const objective of facts.objectives) { + if (objective.graph !== void 0) objectiveRevisions[objective.objectiveNodeId] = objective.graph.revision; + } + const ledgerWatermark = sha256Hex(JSON.stringify( + facts.ledger.map((entry2) => [entry2.attemptId, entry2.status, entry2.completedAt]) + )); + const currentPolicyFingerprint = autonomyPolicyFingerprint(facts.currentAutonomyPolicy); + const runtimePolicyChanged = facts.binding === void 0 ? null : currentPolicyFingerprint !== facts.binding.boundPolicyFingerprint; + const strongAvoidance = metric(eligibleCompletedWithoutStrong.length, eligibleCompleted.length); + const secondaryInitial = metric(initialPassUnits.length, initialAttemptedUnits.length); + const secondaryRepair = metric(repairPassUnits.length, repairAttemptedUnits.length); + const secondaryFallback = metric(fallbackUnits.length, secondaryAttemptedUnits.length); + const researchAvoidance = metric(researchAvoided, researchConsidered); + const researchReuse = metric( + reuseCount, + reuseCount + providerCallCount + ); + const implementationByKind = {}; + for (const attempt of implementationAttempts) increment2(implementationByKind, attempt.kind); + const objectiveSummaries = facts.objectives.slice(0, 200).map((objective) => { + const accounting = { + completed: 0, + failed: 0, + cancelled: 0, + waiting: 0, + "not-ready": 0, + "human-authority-pending": 0, + "research-pending": 0, + "context-pending": 0 + }; + for (const unit of objective.graph?.units ?? []) { + const key = `${objective.objectiveNodeId}\0${unit.workUnitId}`; + accounting[workAccounting(unit, currentRouting.get(key))] += 1; + } + const attempts = implementationAttempts.filter((entry2) => entry2.objectiveNodeId === objective.objectiveNodeId); + return { + objectiveNodeId: objective.objectiveNodeId, + graphRevision: objective.graph?.revision ?? null, + total: objective.graph?.units.length ?? 0, + accounting, + implementationAttempts: attempts.length, + secondaryAttempts: attempts.filter((entry2) => entry2.kind === "SECONDARY" || entry2.kind === "SECONDARY_REPAIR").length, + strongBuilderAttempts: attempts.filter((entry2) => entry2.kind === "STRONG" || entry2.kind === "STRONG_FALLBACK").length + }; + }); + const report = executionTelemetryReportSchema.parse({ + schemaVersion: EXECUTION_TELEMETRY_REPORT_SCHEMA_VERSION, + jobId: facts.job.jobId, + missionId: facts.binding?.missionId ?? facts.seal?.missionId ?? null, + generatedAt: facts.generatedAt, + period: { + startedAt: facts.job.createdAt, + endedAt: facts.job.finalizedAt ?? null, + durationMs: timestampMs(facts.job.createdAt) === void 0 ? null : Math.max( + 0, + (timestampMs(facts.job.finalizedAt ?? facts.generatedAt) ?? generatedMs) - (timestampMs(facts.job.createdAt) ?? generatedMs) + ), + activeExecutionMs: timestampMs(facts.job.createdAt) === void 0 ? null : workedMsOf(facts.job, timestampMs(facts.job.finalizedAt ?? facts.generatedAt) ?? generatedMs) + }, + provenance: { + sourceJobId: facts.job.jobId, + jobGraphRevision: facts.job.graphRevision, + objectiveGraphRevisions: objectiveRevisions, + executionLedgerWatermark: ledgerWatermark, + eventWatermark: facts.eventTotal, + specbridgeVersion: facts.specbridgeVersion ?? null, + sealId: facts.binding?.sealId ?? null, + sealedAuthorityDigest: facts.seal?.authorityDigest ?? null, + runtimePolicyChanged, + configuration: { + secondaryBuildStrategy: facts.secondaryBuildStrategy, + researchStrategy: facts.researchStrategy, + runnerProfiles: [...facts.runnerProfiles].sort().slice(0, 50) + } + }, + outcome: { + status: outcomeStatus(facts.job.status), + authoritativeJobStatus: facts.job.status, + finalOutcome: facts.job.finalOutcome === void 0 ? null : redactTelemetryText(facts.job.finalOutcome).slice(0, 2e3), + verification: overallVerification, + closure: closureOutcome + }, + work: { + total: units.length, + byKind: workByKind, + accounting: workAccountingCounts, + completedImplementation, + objectives: objectiveSummaries, + units: unitSummaries, + omittedUnits: Math.max(0, units.length - unitSummaries.length) + }, + secondary: { + eligibility, + selection, + funnel: { + initialAttempts: initialAttemptedUnits.length, + initialPass: initialPassUnits.length, + repairAttempted: repairAttemptedUnits.length, + repairPass: repairPassUnits.length, + toStrongFallback: fallbackUnits.length, + unavailableFallback: unavailableFallbackUnits.length + }, + initialSuccessRate: secondaryInitial, + repairRecoveryRate: secondaryRepair, + toStrongFallbackRate: secondaryFallback, + fallbackReasons, + builderTokens: secondaryTokens + }, + strong: { + builderAttempts: strongAttempts.length, + evaluatorAttempts: strongEvaluatorAttempts.length, + selection: strongSelection, + implementationTokens: strongTokens, + evaluatorTokens + }, + research: { + scope: researchScope, + considered: researchConsidered, + decisions: researchDecisions, + providerCalls: providerCallCount, + successful: successfulResearch, + inconclusive: inconclusiveResearch, + failed: failedResearch, + priorResearchReused: reuseCount, + newQuick, + newDeep, + avoidanceRatio: researchAvoidance, + reuseRate: researchReuse, + byPhase, + usage: { + inputTokens: researchInputObserved ? researchInputTokens : null, + outputTokens: researchOutputObserved ? researchOutputTokens : null, + durationMs: researchDurationObserved ? researchDurationMs : null, + providerReportedCost: researchCostObserved ? researchCost : null, + subagentCount: researchSubagentsObserved ? researchSubagents : null, + recordsWithUsage, + providerCalls: providerCallCount, + coverage: providerCallCount === 0 ? null : Math.min(1, recordsWithUsage / providerCallCount) + } + }, + cooldown: { + episodes: cooldownEpisodes, + observations: eventTypes("resource_cooldown_observed").length, + totalDurationMs: cooldownDurationKnown ? cooldownDurationMs : null, + usefulWorkDuringSubscriptionCooldown: cooldownCompletedKeys.size, + secondaryImplementationWorkDuringCooldown: secondaryImplementationDuringCooldown, + researchWorkDuringCooldown: researchDuringCooldown, + strongRequiredWaiting: cooldownWaitingKeys.size, + avoidableIdlePeriods, + intervals: cooldownIntervals.sort((left, right) => left.startedAt.localeCompare(right.startedAt, "en") || left.objectiveNodeId.localeCompare(right.objectiveNodeId, "en")), + timeline: cooldownTimeline + }, + attempts: { + uniqueImplementationAttempts: implementationAttempts.length, + meanPerCompletedWorkUnit: meanAttempts, + medianPerCompletedWorkUnit: median4(attemptCountsForCompleted), + maxPerWorkUnit: attemptCountsForCompleted.length === 0 ? 0 : Math.max(...attemptCountsForCompleted), + workUnitsWithMultipleAttempts: attemptCountsForCompleted.filter((value) => value > 1).length, + byKind: implementationByKind, + completedWorkUnitsPerImplementationAttempt: completedPerAttempt, + completedWorkUnitsPerStrongBuilderCall: completedPerStrong, + completedEligibleWorkUnitsPerSecondaryAttempt: completedEligiblePerSecondary + }, + verification: { + attempts: evaluations.length, + passes: evaluationPasses.length, + failures: evaluationFailures.length, + otherVerdicts: evaluations.length - evaluationPasses.length - evaluationFailures.length, + failuresByBuilderBackend: failuresByBackend, + failuresRecoveredByRepair, + failuresRecoveredByStrongFallback + }, + closure: { + available: closureTotals !== void 0, + items: closureTotals?.total ?? 0, + earned: closureTotals?.verified ?? 0, + waived: closureTotals?.waived ?? 0, + unresolved: closureTotals === void 0 ? 0 : closureTotals.total - closureTotals.verified - closureTotals.waived - closureTotals.notApplicable, + completionGateOutcome: closureOutcome, + ratio: closureTotals === void 0 ? null : closureRatio(closureTotals) + }, + human: { + decisionsBeforeSeal, + approvals: facts.seal?.sealedAt === void 0 ? 0 : 1, + authorityEscalationsAfterSeal: facts.autonomy.humanAuthorityEscalationsAfterSeal, + interventionsAfterSeal: facts.autonomy.humanInterventionsAfterSeal, + unexpectedBlockersAfterSeal: unexpectedBlocks, + zeroTouchAfterSeal: facts.autonomy.humanInterventionsAfterSeal === 0, + byKind: humanByKind + }, + reliability: { + failureSources, + recoveryActions, + noProgressDetections, + repeatedProblemFingerprints, + legitimateResourceWaitsExcluded: resourceWaitEvents, + processRestarts: eventTypes("job_resumed").length, + supervisorRestarts: eventTypes("driver_restarted").length + eventTypes("supervisor_lease_reclaimed").length, + candidatesPersisted, + candidatesReusedAfterRestart: candidatesReused, + candidateRebuildsAfterRestart: candidateRebuilds, + candidatesLostOrUnreadable: candidateRebuilds, + candidateReadyResumes: candidatesReused, + integrationRetries, + completedWorkRedoCount, + completedWorkReusedAfterRestart, + attemptsIncorrectlyRepeated: completedWorkRedoCount, + unexpectedBlocks, + unrecoveredDriverDeaths + }, + efficiency: { + strongBuilderAvoidanceRatio: strongAvoidance, + strongBuilderCallsAvoided: eligibleCompletedWithoutStrong.length, + completedWorkUnitsPerImplementationAttempt: completedPerAttempt, + baseline: facts.baseline === void 0 ? null : { + kind: facts.baseline.kind, + reportId: facts.baseline.reportId, + strongBuilderAttempts: facts.baseline.strongBuilderAttempts, + sameVerificationOutcome: facts.baseline.verificationOutcome === overallVerification, + sameClosureOutcome: facts.baseline.closureOutcome === closureOutcome + } + }, + qualificationSummary: { + strongBuilderAvoidanceRatio: strongAvoidance.value, + secondaryInitialSuccessRate: secondaryInitial.value, + secondaryRepairRecoveryRate: secondaryRepair.value, + secondaryToStrongFallback: fallbackUnits.length, + strongImplementationTokens: strongTokens.completeTokens, + researchAvoidanceRatio: researchAvoidance.value, + newResearchCalls: providerCallCount, + researchReuse: reuseCount, + usefulWorkDuringSubscriptionCooldown: cooldownCompletedKeys.size, + humanInterventionsAfterSeal: facts.autonomy.humanInterventionsAfterSeal, + completedWorkRedoCount, + unexpectedBlocks, + unrecoveredDriverDeaths + }, + diagnostics: diagnostics.slice(0, 200) + }); + return report; +} +function cooldownEventDetail(event) { + switch (event.type) { + case "resource_cooldown_started": + return `Strong resource cooldown started (${String(event["availability"] ?? "availability unknown")}).`; + case "resource_cooldown_observed": + return "Strong resource cooldown was observed again; this is not a new episode."; + case "work_unit_resource_wait_started": + return `WorkUnit ${String(event["workUnitId"] ?? "(unknown)")} entered a Strong resource wait.`; + case "work_unit_resource_wait_ended": + return `WorkUnit ${String(event["workUnitId"] ?? "(unknown)")} left its Strong resource wait.`; + case "resource_wait_entered": + return "The job entered a global resource wait because no permitted work remained runnable."; + case "useful_work_during_cooldown": + return `${Number(event["newlyCompleted"] ?? 0)} additional WorkUnit(s) completed during cooldown.`; + case "resource_recovered": + return "The Strong resource recovered and waiting work was released."; + default: + return event.type; + } +} +function collectExecutionTelemetryFacts(deps4, jobId, options = {}) { + const job = requireJobState(deps4.workspace, jobId); + const eventPage = readJobEvents(deps4.workspace, jobId, { limit: 500 }); + const objectives = listObjectiveNodes(deps4.workspace, jobId).map( + (objectiveNodeId) => ({ + objectiveNodeId, + graph: readLatestWorkGraph(deps4.workspace, jobId, objectiveNodeId), + routingStates: readBuilderRoutingStates(deps4.workspace, jobId, objectiveNodeId), + cooldown: readObjectiveCooldownState(deps4.workspace, jobId, objectiveNodeId), + evaluations: readEvaluations(deps4.workspace, jobId, objectiveNodeId) + }) + ); + const researchTelemetryRead = readResearchTelemetry(deps4.workspace); + const researchRecords = listResearchRecords(deps4.workspace); + const binding = readSealBinding(deps4.workspace, jobId); + const seal = readJobSeal(deps4.workspace, jobId); + return { + job, + events: eventPage.events, + eventTotal: eventPage.total, + ledger: readExecutionLedger(deps4.workspace, jobId), + objectives, + researchTelemetry: researchTelemetryRead.telemetry, + ...researchTelemetryRead.diagnostic !== void 0 ? { researchTelemetryDiagnostic: researchTelemetryRead.diagnostic } : {}, + researchRecords: researchRecords.records, + researchRecordDiagnostics: researchRecords.diagnostics.map((diagnostic) => ({ + code: diagnostic.code, + message: diagnostic.message + })), + researchUses: listResearchUseRecords(deps4.workspace), + autonomy: deriveAutonomyTelemetry(deps4, { jobId }), + closure: readClosureLedger(deps4.workspace, jobId), + ...binding !== void 0 ? { binding } : {}, + ...seal !== void 0 ? { seal } : {}, + generatedAt: nowIso5(deps4), + ...options.specbridgeVersion !== void 0 ? { specbridgeVersion: options.specbridgeVersion } : {}, + secondaryBuildStrategy: deps4.config.orchestration.jobs.objectives.secondaryBuilder.strategy, + researchStrategy: deps4.config.research.strategy, + runnerProfiles: Object.keys(deps4.config.runnerProfiles), + currentAutonomyPolicy: deps4.config.autonomy, + closurePolicy: deps4.config.autonomy.closure + }; +} +function executionTelemetryReportFile(workspace, jobId) { + if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(jobId)) { + throw new Error(`Invalid job id "${jobId}".`); + } + return assertInsideWorkspace( + workspace.rootDir, + import_path90.default.join(workspace.sidecarDir, "reports", `job-${jobId}-telemetry.json`) + ); +} +function persistExecutionTelemetryReport(workspace, report) { + const validated = executionTelemetryReportSchema.parse(report); + const file = executionTelemetryReportFile(workspace, validated.jobId); + (0, import_fs81.mkdirSync)(import_path90.default.dirname(file), { recursive: true }); + writeFileAtomic(file, `${JSON.stringify(validated, null, 2)} +`); + return file; +} +function computeExecutionTelemetryReport(deps4, jobId, options = {}) { + const report = deriveExecutionTelemetryReport( + collectExecutionTelemetryFacts(deps4, jobId, options) + ); + if (options.persist === true) persistExecutionTelemetryReport(deps4.workspace, report); + return report; +} +var shortText132 = external_exports.string().max(200); var text12 = external_exports.string().max(4e3); var controlPlaneRepairSchema = external_exports.object({ schemaVersion: external_exports.string().regex(/^\d+\.\d+\.\d+$/), - repairId: shortText122, + repairId: shortText132, /** The product job that hit the defect and is suspended for this. */ - productJobId: shortText122, + productJobId: shortText132, defectKind: external_exports.enum(CONTROL_PLANE_DEFECT_KINDS), /** What was observed, in one line. Never a stack trace with paths. */ symptom: text12, @@ -108515,22 +109965,22 @@ var controlPlaneRepairSchema = external_exports.object({ status: external_exports.enum(CONTROL_PLANE_REPAIR_STATUSES), /** Stages completed, in order. The gate is that this is a prefix. */ stagesCompleted: external_exports.array(external_exports.enum(CONTROL_PLANE_REPAIR_STAGES)).max(20).default([]), - createdAt: shortText122, - updatedAt: shortText122, - finishedAt: shortText122.optional(), + createdAt: shortText132, + updatedAt: shortText132, + finishedAt: shortText132.optional(), /** Isolated working copy the patch was developed in. */ - isolationPath: shortText122.optional(), + isolationPath: shortText132.optional(), /** Where the verified build was staged. Never the running installation. */ - artifactPath: shortText122.optional(), + artifactPath: shortText132.optional(), /** Files the patch touched, workspace-relative to the SpecBridge source. */ - changedFiles: external_exports.array(shortText122).max(200).default([]), + changedFiles: external_exports.array(shortText132).max(200).default([]), /** The regression test added, which is mandatory. */ - regressionTestPath: shortText122.optional(), + regressionTestPath: shortText132.optional(), /** Invariants the screen found the patch touching. Non-empty means reject. */ invariantViolations: external_exports.array( external_exports.object({ invariant: external_exports.enum(PROTECTED_CONTROL_PLANE_INVARIANTS), - file: shortText122, + file: shortText132, evidence: text12 }).passthrough() ).max(50).default([]), @@ -108642,8 +110092,8 @@ function classifyFailure2(observation2) { humanRequired: false }; } -async function runUnattendedMission(deps3, options) { - const policy = autonomyPolicyOf(deps3); +async function runUnattendedMission(deps4, options) { + const policy = autonomyPolicyOf(deps4); if (!isUnattendedMode(policy.mode)) { throw new AutonomyError( "SBA001", @@ -108652,11 +110102,11 @@ async function runUnattendedMission(deps3, options) { ); } const seal = requireExecutableSeal( - readJobSeal(deps3.workspace, options.jobId) ?? latestExecutableSeal(deps3.workspace, options.missionId), + readJobSeal(deps4.workspace, options.jobId) ?? latestExecutableSeal(deps4.workspace, options.missionId), policy ); const surfaces = requiredSurfacesFor(seal); - const report = options.preflightReport ?? await runOvernightPreflight(deps3, { + const report = options.preflightReport ?? await runOvernightPreflight(deps4, { subject: options.missionId, missionId: options.missionId, sealId: seal.sealId, @@ -108665,9 +110115,9 @@ async function runUnattendedMission(deps3, options) { }); assertOvernightReady(report); const emit22 = (kind, message2) => options.onEvent?.({ kind, message: message2 }); - if (readJobSeal(deps3.workspace, options.jobId) === void 0) { - bindSealToJob(deps3, options.jobId, seal.sealId); - recordJobEvent(jobDepsOf(deps3), options.jobId, "autonomy_seal_bound", { + if (readJobSeal(deps4.workspace, options.jobId) === void 0) { + bindSealToJob(deps4, options.jobId, seal.sealId); + recordJobEvent(jobDepsOf(deps4), options.jobId, "autonomy_seal_bound", { sealId: seal.sealId, missionId: seal.missionId, mode: policy.mode, @@ -108675,18 +110125,18 @@ async function runUnattendedMission(deps3, options) { criteria: seal.acceptanceCriteria.length }); } - if (readClosureLedger(deps3.workspace, options.jobId) === void 0) { - const ledger = buildClosureLedger(deps3, { jobId: options.jobId, seal }); + if (readClosureLedger(deps4.workspace, options.jobId) === void 0) { + const ledger = buildClosureLedger(deps4, { jobId: options.jobId, seal }); emit22("closure", `closure ledger built with ${ledger.entries.length} sealed item(s)`); } const supervisedDeps = { - ...deps3, - ...shouldDelegateAuthority(policy) ? { authorityResolver: createAuthorityResolver({ workspace: deps3.workspace, policy }) } : {}, - completionGate: createClosureCompletionGate(deps3.workspace, policy.closure) + ...deps4, + ...shouldDelegateAuthority(policy) ? { authorityResolver: createAuthorityResolver({ workspace: deps4.workspace, policy }) } : {}, + completionGate: createClosureCompletionGate(deps4.workspace, policy.closure) }; const host = typeof options.host === "function" ? options.host(supervisedDeps) : options.host; - const sessionStartedAt = nowIso5(deps3); - const startedMs = now5(deps3).getTime(); + const sessionStartedAt = nowIso5(deps4); + const startedMs = now5(deps4).getTime(); const recoveries = []; const audits = []; const maxCycles = options.maxCycles ?? 100; @@ -108735,11 +110185,11 @@ async function runUnattendedMission(deps3, options) { } const telemetry = computeAutonomyTelemetry(supervisedDeps, { jobId: options.jobId, - elapsedWallTimeMs: now5(deps3).getTime() - startedMs + elapsedWallTimeMs: now5(deps4).getTime() - startedMs }); return { stop: stop ?? { kind: "cycles-exhausted" }, - job: requireJobState(deps3.workspace, options.jobId), + job: requireJobState(deps4.workspace, options.jobId), seal, telemetry, audits, @@ -108747,7 +110197,7 @@ async function runUnattendedMission(deps3, options) { cycles }; } -async function resolveSupervisionStop(deps3, input) { +async function resolveSupervisionStop(deps4, input) { switch (input.stop.kind) { case "completed": return { stop: { kind: "completed", rationale: "the job reached a terminal COMPLETED status" } }; @@ -108759,7 +110209,7 @@ async function resolveSupervisionStop(deps3, input) { case "gave-up": return { stop: { kind: "gave-up", reason: input.stop.reason } }; case "needs-human": { - const job = requireJobState(deps3.workspace, input.jobId); + const job = requireJobState(deps4.workspace, input.jobId); if (input.stop.status === "NEEDS_AUTHORITY") { return { stop: { @@ -108775,9 +110225,9 @@ async function resolveSupervisionStop(deps3, input) { case "released": case "cycles-exhausted": default: { - const job = requireJobState(deps3.workspace, input.jobId); + const job = requireJobState(deps4.workspace, input.jobId); if (job.status === "BLOCKED" && job.blocker !== void 0) { - const recovery = applyRecovery(deps3, { + const recovery = applyRecovery(deps4, { jobId: input.jobId, observation: { kind: "blocked", detail: job.blocker.message }, emit: input.emit @@ -108788,10 +110238,10 @@ async function resolveSupervisionStop(deps3, input) { } } } -function applyRecovery(deps3, input) { +function applyRecovery(deps4, input) { const classification = classifyFailure2(input.observation); input.emit?.("recovery", `${classification.status}: ${classification.detail}`); - const jobDeps2 = jobDepsOf(deps3); + const jobDeps2 = jobDepsOf(deps4); const payload = { kind: classification.waitKind, detail: classification.detail, @@ -108829,19 +110279,19 @@ function applyRecovery(deps3, input) { } return classification; } -async function runClosureCycle(deps3, input) { - const job = requireJobState(deps3.workspace, input.jobId); - const graph = safeGraph(deps3, job); +async function runClosureCycle(deps4, input) { + const job = requireJobState(deps4.workspace, input.jobId); + const graph = safeGraph(deps4, job); const completedNodeIds = graph.filter((node) => node.status === "COMPLETED").map((node) => node.nodeId); const implementationComplete = graph.length > 0 && graph.every((node) => node.status === "COMPLETED" || node.status === "SUPERSEDED"); - const swept = attributeCompletedWork(deps3, { + const swept = attributeCompletedWork(deps4, { jobId: input.jobId, missionId: input.missionId }); if (swept.attributed > 0) { input.emit("closure", `attributed completed work to ${swept.attributed} sealed item reference(s)`); } - const { audit } = runClosureAudit(deps3, { + const { audit } = runClosureAudit(deps4, { jobId: input.jobId, completedNodeIds, implementationComplete @@ -108855,7 +110305,7 @@ async function runClosureCycle(deps3, input) { case "NEEDS_AUTHORITY": return { audit, stop: { kind: "needs-authority", question: audit.rationale } }; case "GENERATE_GAP_WORK": { - const generated = generateGapWork(deps3, { jobId: input.jobId, audit }); + const generated = generateGapWork(deps4, { jobId: input.jobId, audit }); input.emit("closure", `generated ${generated.length} gap work item(s)`); if (generated.length === 0) { return { @@ -108866,7 +110316,7 @@ async function runClosureCycle(deps3, input) { } }; } - const repairs = await runGapRepairs(deps3, { + const repairs = await runGapRepairs(deps4, { jobId: input.jobId, items: generated, ...input.signal !== void 0 ? { signal: input.signal } : {}, @@ -108876,15 +110326,15 @@ async function runClosureCycle(deps3, input) { "closure", `gap repairs: ${repairs.repaired.length} integrated, ${repairs.failed.length} failed` ); - clearOperationalStateIfNeeded(deps3, input.jobId); + clearOperationalStateIfNeeded(deps4, input.jobId); return { audit }; } case "RUN_SYSTEM_SCENARIOS": { - enterQualifying(jobDepsOf(deps3), input.jobId, { + enterQualifying(jobDepsOf(deps4), input.jobId, { phase: "SYSTEM_SCENARIO_QUALIFICATION", detail: audit.rationale }); - const scenarios = await runSystemScenarioPhase(deps3, { + const scenarios = await runSystemScenarioPhase(deps4, { jobId: input.jobId, ...input.environmentRuntime !== void 0 ? { runtime: input.environmentRuntime } : {}, ...input.probeExecutor !== void 0 ? { probeExecutor: input.probeExecutor } : {}, @@ -108897,49 +110347,49 @@ async function runClosureCycle(deps3, input) { "closure", `system scenarios: ${scenarios.passed}/${scenarios.executed} passed` + (scenarios.environmentUnavailable > 0 ? `, ${scenarios.environmentUnavailable} environment-unavailable` : "") + (scenarios.uncovered.length > 0 ? `, ${scenarios.uncovered.length} item(s) uncovered` : "") ); - clearOperationalStateIfNeeded(deps3, input.jobId); + clearOperationalStateIfNeeded(deps4, input.jobId); return { audit }; } case "RUN_RELEASE_QUALIFICATION": { - enterQualifying(jobDepsOf(deps3), input.jobId, { phase: "RELEASE_QUALIFICATION" }); - await runReleaseQualificationPhase(deps3, { + enterQualifying(jobDepsOf(deps4), input.jobId, { phase: "RELEASE_QUALIFICATION" }); + await runReleaseQualificationPhase(deps4, { jobId: input.jobId, ...input.signal !== void 0 ? { signal: input.signal } : {}, emit: (message2) => input.emit("closure", message2) }); - clearOperationalStateIfNeeded(deps3, input.jobId); + clearOperationalStateIfNeeded(deps4, input.jobId); return { audit }; } case "RUN_REPRODUCIBILITY": { - enterQualifying(jobDepsOf(deps3), input.jobId, { phase: "REPRODUCIBILITY" }); - await runReproducibilityPhase(deps3, { + enterQualifying(jobDepsOf(deps4), input.jobId, { phase: "REPRODUCIBILITY" }); + await runReproducibilityPhase(deps4, { jobId: input.jobId, ...input.signal !== void 0 ? { signal: input.signal } : {}, emit: (message2) => input.emit("closure", message2) }); - clearOperationalStateIfNeeded(deps3, input.jobId); + clearOperationalStateIfNeeded(deps4, input.jobId); return { audit }; } case "CONTINUE_IMPLEMENTATION": default: - clearOperationalStateIfNeeded(deps3, input.jobId); + clearOperationalStateIfNeeded(deps4, input.jobId); return { audit }; } } -function clearOperationalStateIfNeeded(deps3, jobId) { - const job = requireJobState(deps3.workspace, jobId); +function clearOperationalStateIfNeeded(deps4, jobId) { + const job = requireJobState(deps4.workspace, jobId); if (job.status === "QUALIFYING" || job.operationalWait !== void 0) { try { - clearOperationalState(jobDepsOf(deps3), jobId, { + clearOperationalState(jobDepsOf(deps4), jobId, { resolution: "the closure audit returned work to implementation" }); } catch { } } } -function safeGraph(deps3, job) { +function safeGraph(deps4, job) { try { - const graph = readGraphRevision(deps3.workspace, job.jobId, job.graphRevision); + const graph = readGraphRevision(deps4.workspace, job.jobId, job.graphRevision); return graph?.nodes.map((node) => ({ nodeId: node.nodeId, status: node.status })) ?? []; } catch { return []; @@ -109091,10 +110541,10 @@ var CERTIFICATION_MATRIX = Object.freeze([ expectedBehaviour: "the job stops in NEEDS_AUTHORITY with the question recorded, and the sealed contract is NOT modified" } ]); -var shortText132 = external_exports.string().max(200); +var shortText142 = external_exports.string().max(200); var text13 = external_exports.string().max(4e3); var certificationScenarioResultSchema = external_exports.object({ - scenarioId: shortText132, + scenarioId: shortText142, fault: external_exports.enum(ZERO_TOUCH_FAULTS), expectation: external_exports.enum(ZERO_TOUCH_EXPECTATIONS), outcome: external_exports.enum(ZERO_TOUCH_OUTCOMES), @@ -109105,21 +110555,21 @@ var certificationScenarioResultSchema = external_exports.object({ /** What the runtime actually did, in one or two lines. */ observed: text13, /** The job status the scenario ended in. */ - finalStatus: shortText132.optional(), + finalStatus: shortText142.optional(), /** Operational statuses the job passed through, in order. */ - recoveryPath: external_exports.array(shortText132).max(30).default([]), + recoveryPath: external_exports.array(shortText142).max(30).default([]), /** Present when the scenario could not run here. Never a pass. */ skipReason: text13.optional(), - startedAt: shortText132, - finishedAt: shortText132.optional(), + startedAt: shortText142, + finishedAt: shortText142.optional(), durationMs: external_exports.number().int().min(0).nullable().default(null) }).passthrough(); var certificationRunSchema = external_exports.object({ schemaVersion: external_exports.string().regex(/^\d+\.\d+\.\d+$/), - runId: shortText132, - createdAt: shortText132, - finishedAt: shortText132.optional(), - host: shortText132, + runId: shortText142, + createdAt: shortText142, + finishedAt: shortText142.optional(), + host: shortText142, verdict: external_exports.enum(CERTIFICATION_VERDICTS), results: external_exports.array(certificationScenarioResultSchema).max(100).default([]), /** Totals, hoisted so the headline needs no arithmetic. */ @@ -109142,7 +110592,7 @@ var certificationRunSchema = external_exports.object({ /** Why the verdict is what it is, in one or two lines. */ rationale: text13, /** Scenarios that failed, with what happened, for the report. */ - failures: external_exports.array(external_exports.object({ scenarioId: shortText132, outcome: shortText132, observed: text13 }).passthrough()).max(100).default([]) + failures: external_exports.array(external_exports.object({ scenarioId: shortText142, outcome: shortText142, observed: text13 }).passthrough()).max(100).default([]) }).passthrough(); function listCertificationRuns(workspace) { return listJsonRecords( @@ -109152,8 +110602,6 @@ function listCertificationRuns(workspace) { } // ../../packages/intake/dist/index.js -var import_fs83 = require("fs"); -var import_path92 = __toESM(require("path"), 1); var import_fs84 = require("fs"); var import_path93 = __toESM(require("path"), 1); var import_fs85 = require("fs"); @@ -109164,6 +110612,8 @@ var import_fs87 = require("fs"); var import_path96 = __toESM(require("path"), 1); var import_fs88 = require("fs"); var import_path97 = __toESM(require("path"), 1); +var import_fs89 = require("fs"); +var import_path98 = __toESM(require("path"), 1); var INTAKE_STATUSES = [ /** The source specification is ingested; discovery has not run. */ "INGESTED", @@ -109438,31 +110888,31 @@ var IntakeError = class extends Error { this.retryable = options.retryable ?? false; } }; -function autonomyDepsOf(deps3) { - return deps3; +function autonomyDepsOf(deps4) { + return deps4; } -function missionDepsOf(deps3) { +function missionDepsOf(deps4) { return { - workspace: deps3.workspace, - clock: deps3.clock, - idFactory: deps3.idFactory, - host: deps3.host + workspace: deps4.workspace, + clock: deps4.clock, + idFactory: deps4.idFactory, + host: deps4.host }; } -function now6(deps3) { - return (deps3.clock ?? (() => /* @__PURE__ */ new Date()))(); +function now6(deps4) { + return (deps4.clock ?? (() => /* @__PURE__ */ new Date()))(); } -function nowIso6(deps3) { - return now6(deps3).toISOString(); +function nowIso6(deps4) { + return now6(deps4).toISOString(); } -function hostOf2(deps3) { - return deps3.host ?? "cli"; +function hostOf2(deps4) { + return deps4.host ?? "cli"; } -function newId6(deps3) { - return (deps3.idFactory ?? import_crypto30.randomUUID)(); +function newId6(deps4) { + return (deps4.idFactory ?? import_crypto30.randomUUID)(); } -function newRecordId2(deps3, prefix) { - const raw = newId6(deps3).replace(/[^A-Za-z0-9._-]/g, "").slice(0, 40); +function newRecordId2(deps4, prefix) { + const raw = newId6(deps4).replace(/[^A-Za-z0-9._-]/g, "").slice(0, 40); return `${prefix}-${raw.length > 0 ? raw : "x"}`; } var INTAKE_STATE_SCHEMA_VERSION = "1.0.0"; @@ -109888,41 +111338,41 @@ function assertIntakeId(id) { function intakeRootDir(workspace) { return assertInsideWorkspace( workspace.rootDir, - import_path90.default.join(workspace.rootDir, ".specbridge", INTAKE_DIR_NAME) + import_path91.default.join(workspace.rootDir, ".specbridge", INTAKE_DIR_NAME) ); } function intakeDir(workspace, intakeId) { assertIntakeId(intakeId); - return assertInsideWorkspace(workspace.rootDir, import_path90.default.join(intakeRootDir(workspace), intakeId)); + return assertInsideWorkspace(workspace.rootDir, import_path91.default.join(intakeRootDir(workspace), intakeId)); } function intakePath(workspace, intakeId, ...segments) { return assertInsideWorkspace( workspace.rootDir, - import_path90.default.join(intakeDir(workspace, intakeId), ...segments) + import_path91.default.join(intakeDir(workspace, intakeId), ...segments) ); } function writeJson(file, value) { - (0, import_fs81.mkdirSync)(import_path90.default.dirname(file), { recursive: true }); + (0, import_fs82.mkdirSync)(import_path91.default.dirname(file), { recursive: true }); writeFileAtomic(file, `${JSON.stringify(value, null, 2)} `); } function readJson2(file, parse3) { - if (!(0, import_fs81.existsSync)(file)) return void 0; + if (!(0, import_fs82.existsSync)(file)) return void 0; try { - return parse3(JSON.parse((0, import_fs81.readFileSync)(file, "utf8"))); + return parse3(JSON.parse((0, import_fs82.readFileSync)(file, "utf8"))); } catch { return void 0; } } function appendJsonl3(file, value) { - (0, import_fs81.mkdirSync)(import_path90.default.dirname(file), { recursive: true }); - (0, import_fs81.appendFileSync)(file, `${JSON.stringify(value)} + (0, import_fs82.mkdirSync)(import_path91.default.dirname(file), { recursive: true }); + (0, import_fs82.appendFileSync)(file, `${JSON.stringify(value)} `, "utf8"); } function readFolded(file, key, parse3) { - if (!(0, import_fs81.existsSync)(file)) return []; + if (!(0, import_fs82.existsSync)(file)) return []; const folded = /* @__PURE__ */ new Map(); - for (const line of (0, import_fs81.readFileSync)(file, "utf8").split("\n")) { + for (const line of (0, import_fs82.readFileSync)(file, "utf8").split("\n")) { if (line.trim().length === 0) continue; try { const value = parse3(JSON.parse(line)); @@ -109955,16 +111405,16 @@ function writeIntakeState(workspace, state) { } function listIntakes(workspace) { const root = intakeRootDir(workspace); - if (!(0, import_fs81.existsSync)(root)) return { intakes: [], diagnostics: [] }; + if (!(0, import_fs82.existsSync)(root)) return { intakes: [], diagnostics: [] }; const intakes = []; const diagnostics = []; - for (const entry2 of (0, import_fs81.readdirSync)(root, { withFileTypes: true })) { + for (const entry2 of (0, import_fs82.readdirSync)(root, { withFileTypes: true })) { if (!entry2.isDirectory()) continue; if (!ID_PATTERN11.test(entry2.name)) continue; - const file = import_path90.default.join(root, entry2.name, "intake.json"); - if (!(0, import_fs81.existsSync)(file)) continue; + const file = import_path91.default.join(root, entry2.name, "intake.json"); + if (!(0, import_fs82.existsSync)(file)) continue; try { - intakes.push(specIntakeStateSchema.parse(JSON.parse((0, import_fs81.readFileSync)(file, "utf8")))); + intakes.push(specIntakeStateSchema.parse(JSON.parse((0, import_fs82.readFileSync)(file, "utf8")))); } catch (cause) { diagnostics.push({ intakeId: entry2.name, @@ -109994,8 +111444,8 @@ function sourceFile(workspace, intakeId, contentHash) { } function storeSourceText(workspace, intakeId, contentHash, content) { const file = sourceFile(workspace, intakeId, contentHash); - if (!(0, import_fs81.existsSync)(file)) { - (0, import_fs81.mkdirSync)(import_path90.default.dirname(file), { recursive: true }); + if (!(0, import_fs82.existsSync)(file)) { + (0, import_fs82.mkdirSync)(import_path91.default.dirname(file), { recursive: true }); writeFileAtomic(file, content); } return file; @@ -110080,7 +111530,7 @@ function approvalFile2(workspace, intakeId) { function writeApproval(workspace, approval) { const validated = intakeApprovalSchema.parse(approval); const file = approvalFile2(workspace, validated.intakeId); - if ((0, import_fs81.existsSync)(file)) { + if ((0, import_fs82.existsSync)(file)) { throw new IntakeError( "SBI017", `Spec intake "${validated.intakeId}" is already approved; an approval is immutable.`, @@ -110139,7 +111589,7 @@ function appendIntakeEvent(workspace, intakeId, event) { function baselineFile(workspace) { return assertInsideWorkspace( workspace.rootDir, - import_path90.default.join(intakeRootDir(workspace), "baseline.json") + import_path91.default.join(intakeRootDir(workspace), "baseline.json") ); } function readProductBaseline(workspace) { @@ -110754,7 +112204,7 @@ var BUILD_MARKERS = [ ]; function detectBuildSystem(rootDir) { for (const marker of BUILD_MARKERS) { - if ((0, import_fs82.existsSync)(import_path91.default.join(rootDir, marker.file))) return marker.system; + if ((0, import_fs83.existsSync)(import_path92.default.join(rootDir, marker.file))) return marker.system; } return null; } @@ -110791,33 +112241,33 @@ var PUBLIC_INTERFACE_PATTERNS = [ var TEST_DIR_PATTERN = /^(tests?|spec|specs|__tests__|it|integration-tests?|e2e)$/i; function readGitHead(rootDir) { try { - const dotGit = import_path91.default.join(rootDir, ".git"); - if (!(0, import_fs82.existsSync)(dotGit)) return null; + const dotGit = import_path92.default.join(rootDir, ".git"); + if (!(0, import_fs83.existsSync)(dotGit)) return null; let gitDir = dotGit; - if ((0, import_fs82.statSync)(dotGit).isFile()) { - const pointer = (0, import_fs82.readFileSync)(dotGit, "utf8").trim(); + if ((0, import_fs83.statSync)(dotGit).isFile()) { + const pointer = (0, import_fs83.readFileSync)(dotGit, "utf8").trim(); const match = /^gitdir:\s*(.+)$/.exec(pointer); if (match === null) return null; const target = match[1] ?? ""; - gitDir = import_path91.default.isAbsolute(target) ? target : import_path91.default.resolve(rootDir, target); + gitDir = import_path92.default.isAbsolute(target) ? target : import_path92.default.resolve(rootDir, target); } - const headFile = import_path91.default.join(gitDir, "HEAD"); - if (!(0, import_fs82.existsSync)(headFile)) return null; - const head = (0, import_fs82.readFileSync)(headFile, "utf8").trim(); + const headFile = import_path92.default.join(gitDir, "HEAD"); + if (!(0, import_fs83.existsSync)(headFile)) return null; + const head = (0, import_fs83.readFileSync)(headFile, "utf8").trim(); if (/^[0-9a-f]{40}$/i.test(head)) return head.toLowerCase(); const refMatch = /^ref:\s*(.+)$/.exec(head); if (refMatch === null) return null; const ref = (refMatch[1] ?? "").trim(); for (const dir of refDirsFor(gitDir)) { - const refFile = import_path91.default.join(dir, ...ref.split("/")); - if (!(0, import_fs82.existsSync)(refFile)) continue; - const sha = (0, import_fs82.readFileSync)(refFile, "utf8").trim(); + const refFile = import_path92.default.join(dir, ...ref.split("/")); + if (!(0, import_fs83.existsSync)(refFile)) continue; + const sha = (0, import_fs83.readFileSync)(refFile, "utf8").trim(); if (/^[0-9a-f]{40}$/i.test(sha)) return sha.toLowerCase(); } for (const dir of refDirsFor(gitDir)) { - const packed = import_path91.default.join(dir, "packed-refs"); - if (!(0, import_fs82.existsSync)(packed)) continue; - for (const line of (0, import_fs82.readFileSync)(packed, "utf8").split("\n")) { + const packed = import_path92.default.join(dir, "packed-refs"); + if (!(0, import_fs83.existsSync)(packed)) continue; + for (const line of (0, import_fs83.readFileSync)(packed, "utf8").split("\n")) { const entry2 = /^([0-9a-f]{40})\s+(.+)$/.exec(line.trim()); if (entry2 !== null && entry2[2] === ref) return (entry2[1] ?? "").toLowerCase(); } @@ -110829,20 +112279,20 @@ function readGitHead(rootDir) { } function refDirsFor(gitDir) { const dirs = [gitDir]; - const commonFile = import_path91.default.join(gitDir, "commondir"); - if ((0, import_fs82.existsSync)(commonFile)) { + const commonFile = import_path92.default.join(gitDir, "commondir"); + if ((0, import_fs83.existsSync)(commonFile)) { try { - const target = (0, import_fs82.readFileSync)(commonFile, "utf8").trim(); + const target = (0, import_fs83.readFileSync)(commonFile, "utf8").trim(); if (target.length > 0) { - dirs.push(import_path91.default.isAbsolute(target) ? target : import_path91.default.resolve(gitDir, target)); + dirs.push(import_path92.default.isAbsolute(target) ? target : import_path92.default.resolve(gitDir, target)); } } catch { } } return dirs; } -function groundInRepository(deps3, request) { - const workspace = deps3.workspace; +function groundInRepository(deps4, request) { + const workspace = deps4.workspace; const exclude = new Set(request.excludeMissionIds ?? []); const evidence = []; const notes = []; @@ -110886,7 +112336,7 @@ function groundInRepository(deps3, request) { summary: `existing Kiro spec with ${folder.files.length} document(s)`, authoritative: false, topics: [], - path: import_path91.default.posix.join(".kiro", "specs", folder.name) + path: import_path92.default.posix.join(".kiro", "specs", folder.name) }); } for (const steering of safeSteering(workspace, notes)) { @@ -110897,7 +112347,7 @@ function groundInRepository(deps3, request) { summary: `steering document (${steering.inclusion})`, authoritative: false, topics: [], - path: import_path91.default.posix.join(".kiro", "steering", steering.fileName) + path: import_path92.default.posix.join(".kiro", "steering", steering.fileName) }); } const buildSystem = detectBuildSystem(workspace.rootDir); @@ -110941,7 +112391,7 @@ function groundInRepository(deps3, request) { }); } for (const container of modules.slice(0, 40)) { - const dir = import_path91.default.join(workspace.rootDir, container); + const dir = import_path92.default.join(workspace.rootDir, container); for (const entry2 of safeReaddir(dir, notes)) { if (!entry2.isDirectory()) continue; if (MODULE_DENYLIST.has(entry2.name) || entry2.name.startsWith(".")) continue; @@ -110991,7 +112441,7 @@ function groundInRepository(deps3, request) { return { schemaVersion: INTAKE_GROUNDING_SCHEMA_VERSION, intakeId: request.intakeId, - groundedAt: nowIso6(deps3), + groundedAt: nowIso6(deps4), baselineCommit: readGitHead(workspace.rootDir), existingProduct, evidence: evidence.slice(0, INTAKE_LIMITS.maxEvidence), @@ -111093,7 +112543,7 @@ function safeSteering(workspace, notes) { } function safeReaddir(dir, notes) { try { - return (0, import_fs82.readdirSync)(dir, { withFileTypes: true }); + return (0, import_fs83.readdirSync)(dir, { withFileTypes: true }); } catch (cause) { notes.push(`Directory ${dir} could not be listed: ${message(cause)}.`); return []; @@ -111133,14 +112583,14 @@ function analyzeDeltaAuthority(request) { if (items.length >= INTAKE_LIMITS.maxItems) break; const statement = statementOf(chunk); if (statement.length === 0) continue; - const tokens = tokenSet(statement); + const tokens2 = tokenSet(statement); const surfaces = surfacesFor(chunk, statement); const publicSurface = surfaces.length > 0; const item = classifyStatement({ itemId: `D-${String(++sequence).padStart(3, "0")}`, statement, chunkId: chunk.chunkId, - tokens, + tokens: tokens2, surfaces: surfaces.map((match) => match.surface), topics: topicsFor(chunk, statement), publicSurface, @@ -111195,10 +112645,10 @@ function analyzeDeltaAuthority(request) { ); } for (const cls of AUTHORITY_SENSITIVE_DELTA_CLASSES) { - const count3 = counts[cls] ?? 0; - if (count3 === 0) continue; + const count4 = counts[cls] ?? 0; + if (count4 === 0) continue; reasons.push( - `${count3} statement(s) classified ${cls} and need a product decision before this specification can be approved.` + `${count4} statement(s) classified ${cls} and need a product decision before this specification can be approved.` ); } const complete = items.length > 0 && authoritySensitive.length === 0; @@ -111905,14 +113355,14 @@ function emptyProjectionMap() { function mapFile(workspace, intakeId) { return assertInsideWorkspace( workspace.rootDir, - import_path92.default.join(workspace.rootDir, ".specbridge", "intake", intakeId, "mission-map.json") + import_path93.default.join(workspace.rootDir, ".specbridge", "intake", intakeId, "mission-map.json") ); } function readProjectionMap(workspace, intakeId) { const file = mapFile(workspace, intakeId); - if (!(0, import_fs83.existsSync)(file)) return emptyProjectionMap(); + if (!(0, import_fs84.existsSync)(file)) return emptyProjectionMap(); try { - const raw = JSON.parse((0, import_fs83.readFileSync)(file, "utf8")); + const raw = JSON.parse((0, import_fs84.readFileSync)(file, "utf8")); return { itemContracts: raw.itemContracts ?? {}, itemDecisions: raw.itemDecisions ?? {}, @@ -111927,7 +113377,7 @@ function readProjectionMap(workspace, intakeId) { } function writeProjectionMap(workspace, intakeId, map) { const file = mapFile(workspace, intakeId); - (0, import_fs83.mkdirSync)(import_path92.default.dirname(file), { recursive: true }); + (0, import_fs84.mkdirSync)(import_path93.default.dirname(file), { recursive: true }); writeFileAtomic(file, `${JSON.stringify(map, null, 2)} `); } @@ -112003,7 +113453,7 @@ var BEHAVIOUR_CONTRACT = { var BEHAVIOUR_SURFACE_KEY = "__behaviour__"; var TOPIC_DECISION_RESERVE = 12; var FACT_BUDGET = 120; -function compileMissionTruth(deps3, intakeDeps3, request) { +function compileMissionTruth(deps4, intakeDeps3, request) { const map = readProjectionMap(intakeDeps3.workspace, request.intakeId); const missionBefore = requireMissionState(intakeDeps3.workspace, request.missionId); const missionGoal = missionBefore.goal; @@ -112023,7 +113473,7 @@ function compileMissionTruth(deps3, intakeDeps3, request) { ); const overflowItemIds = []; if (map.sourceTurnId === void 0) { - const { turn } = recordTurn(deps3, request.missionId, { + const { turn } = recordTurn(deps4, request.missionId, { speaker: "user", kind: "statement", text: sourceTurnText(request.source) @@ -112094,7 +113544,7 @@ function compileMissionTruth(deps3, intakeDeps3, request) { resolvedTopics.push(topic); topicDecisionInputs.push(resolution); } - const decisionAssessment = recordAssessment(deps3, request.missionId, { + const decisionAssessment = recordAssessment(deps4, request.missionId, { ...facts.length > 0 ? { facts } : {}, ...decisions.length > 0 || topicDecisionInputs.length > 0 ? { decisions: [...decisions, ...topicDecisionInputs] } : {}, ...map.fieldsWritten !== true ? { missionUpdates: missionFieldsFrom(request) } : {} @@ -112160,7 +113610,7 @@ function compileMissionTruth(deps3, intakeDeps3, request) { let mission = decisionAssessment.mission; let contractIds = []; if (contracts.length > 0) { - const contractAssessment = recordAssessment(deps3, request.missionId, { contracts }); + const contractAssessment = recordAssessment(deps4, request.missionId, { contracts }); mission = contractAssessment.mission; contractIds = contractAssessment.contractIds; submitted.forEach((bucket, index) => { @@ -112334,9 +113784,9 @@ function reconcileCoverage(input) { out.push(existing); continue; } - const tokens = tokenSet(chunk.text); + const tokens2 = tokenSet(chunk.text); const match = authoritative.find( - (evidence) => containment(tokens, tokenSet(evidence.summary)) >= ALREADY_TRUE_CONTAINMENT + (evidence) => containment(tokens2, tokenSet(evidence.summary)) >= ALREADY_TRUE_CONTAINMENT ); if (match !== void 0) { out.push({ chunkId: chunk.chunkId, state: "ALREADY_TRUE", carriedBy: [match.evidenceId] }); @@ -112579,8 +114029,8 @@ function checkProjectionEquivalence(request) { let checked = 0; let traced = 0; for (const stage of stages) { - const file = import_path93.default.join(folder.dir, `${stage}.md`); - if (!(0, import_fs84.existsSync)(file)) { + const file = import_path94.default.join(folder.dir, `${stage}.md`); + if (!(0, import_fs85.existsSync)(file)) { divergences.push({ kind: "UNRELATED_ARTIFACT", stage, @@ -112588,17 +114038,17 @@ function checkProjectionEquivalence(request) { }); continue; } - const content = (0, import_fs84.readFileSync)(file, "utf8"); + const content = (0, import_fs85.readFileSync)(file, "utf8"); artifactHashes[stage] = sha256Hex(content); for (const statement of extractNormativeStatements(stage, content)) { checked += 1; - const tokens = tokenSet(statement.statement); - if (tokens.size === 0) { + const tokens2 = tokenSet(statement.statement); + if (tokens2.size === 0) { traced += 1; continue; } const match = approvedTokens.find( - (element) => containment(tokens, element.tokens) >= TRACE_CONTAINMENT || jaccard(tokens, element.tokens) >= TRACE_JACCARD + (element) => containment(tokens2, element.tokens) >= TRACE_CONTAINMENT || jaccard(tokens2, element.tokens) >= TRACE_JACCARD ); if (match === void 0) { divergences.push({ @@ -112714,8 +114164,8 @@ function recordDerivedApprovals(request) { } return { approved, results }; } -function emptyLedger(deps3, approval) { - const at = nowIso6(deps3); +function emptyLedger(deps4, approval) { + const at = nowIso6(deps4); return { schemaVersion: INTAKE_LIFECYCLE_SCHEMA_VERSION, intakeId: approval.intakeId, @@ -112743,11 +114193,11 @@ function withStep(ledger, step2, patch) { const steps = ledger.steps.some((record5) => record5.step === step2) ? ledger.steps.map((record5) => record5.step === step2 ? merged : record5) : [...ledger.steps, merged]; return { ...ledger, steps }; } -async function runSealAndBuild(deps3, options) { - const approval = requireApproval(deps3.workspace, options.intakeId); - let ledger = readLifecycle(deps3.workspace, options.intakeId) ?? emptyLedger(deps3, approval); +async function runSealAndBuild(deps4, options) { + const approval = requireApproval(deps4.workspace, options.intakeId); + let ledger = readLifecycle(deps4.workspace, options.intakeId) ?? emptyLedger(deps4, approval); const emit3 = (kind, message2) => options.onEvent?.({ kind, message: message2 }); - const autonomy = autonomyDepsOf(deps3); + const autonomy = autonomyDepsOf(deps4); let preflight; let unattended; const outcome = ledger.outcome; @@ -112759,18 +114209,18 @@ async function runSealAndBuild(deps3, options) { }; } if (outcome !== void 0) { - ledger = writeLifecycle(deps3.workspace, { + ledger = writeLifecycle(deps4.workspace, { ...ledger, outcome: void 0, finishedAt: void 0, humanPrerequisites: [], - updatedAt: nowIso6(deps3) + updatedAt: nowIso6(deps4) }); } const persist4 = (next) => { - const written = writeLifecycle(deps3.workspace, { + const written = writeLifecycle(deps4.workspace, { ...next, - updatedAt: nowIso6(deps3) + updatedAt: nowIso6(deps4) }); ledger = written; return written; @@ -112780,12 +114230,12 @@ async function runSealAndBuild(deps3, options) { persist4( withStep(ledger, step2, { status: "RUNNING", - startedAt: nowIso6(deps3), + startedAt: nowIso6(deps4), attempts: record5.attempts + 1 }) ); - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "build_step_started", step: step2 }); @@ -112795,13 +114245,13 @@ async function runSealAndBuild(deps3, options) { persist4( withStep(ledger, step2, { status, - settledAt: nowIso6(deps3), + settledAt: nowIso6(deps4), detail: detail.slice(0, INTAKE_LIMITS.maxTextChars), ...result !== void 0 ? { result } : {} }) ); - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "build_step_completed", step: step2, status, @@ -112813,12 +114263,12 @@ async function runSealAndBuild(deps3, options) { persist4( withStep(ledger, step2, { status: "FAILED", - settledAt: nowIso6(deps3), + settledAt: nowIso6(deps4), detail: detail.slice(0, INTAKE_LIMITS.maxTextChars) }) ); - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "build_step_failed", step: step2, detail: detail.slice(0, 600) @@ -112826,23 +114276,23 @@ async function runSealAndBuild(deps3, options) { emit3("lifecycle", `${step2} FAILED: ${detail}`); }; if (!isStepSettled(stepOf(ledger, "CONTRACT_READY").status)) { - const mission = requireMissionState(deps3.workspace, approval.missionId); + const mission = requireMissionState(deps4.workspace, approval.missionId); if (mission.status !== "IDEA" && mission.status !== "DISCOVERING" && mission.status !== "NEEDS_DECISION") { settle("CONTRACT_READY", "RECONCILED", `the mission is already ${mission.status}`); } else { begin("CONTRACT_READY"); try { - const { mission: ready } = markContractReady(missionDepsOf(deps3), approval.missionId); + const { mission: ready } = markContractReady(missionDepsOf(deps4), approval.missionId); settle("CONTRACT_READY", "COMPLETED", `the mission is ${ready.status}`); } catch (cause) { fail("CONTRACT_READY", messageOf(cause)); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } } } let specName = ledger.specName; if (!isStepSettled(stepOf(ledger, "SYNTHESIZE").status)) { - const mission = requireMissionState(deps3.workspace, approval.missionId); + const mission = requireMissionState(deps4.workspace, approval.missionId); if (mission.specName !== void 0) { specName = mission.specName; ledger = persist4({ ...ledger, specName }); @@ -112850,8 +114300,8 @@ async function runSealAndBuild(deps3, options) { } else { begin("SYNTHESIZE"); try { - const intake = requireIntakeState(deps3.workspace, options.intakeId); - const result = synthesizeMissionSpec(missionDepsOf(deps3), approval.missionId, { + const intake = requireIntakeState(deps4.workspace, options.intakeId); + const result = synthesizeMissionSpec(missionDepsOf(deps4), approval.missionId, { specName: intake.specName ?? void 0 }); specName = result.specName; @@ -112864,23 +114314,23 @@ async function runSealAndBuild(deps3, options) { ); } catch (cause) { fail("SYNTHESIZE", messageOf(cause)); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } } } - specName = specName ?? requireMissionState(deps3.workspace, approval.missionId).specName; + specName = specName ?? requireMissionState(deps4.workspace, approval.missionId).specName; if (specName === void 0) { fail("SYNTHESIZE", "no spec name is recorded after synthesis"); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } if (!isStepSettled(stepOf(ledger, "VALIDATE_PROJECTION").status)) { begin("VALIDATE_PROJECTION"); try { - const equivalence = validateProjection(deps3, approval, specName); - writeProjectionEquivalence(deps3.workspace, equivalence); + const equivalence = validateProjection(deps4, approval, specName); + writeProjectionEquivalence(deps4.workspace, equivalence); if (!equivalence.equivalent) { - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "projection_diverged", divergences: equivalence.divergences.length }); @@ -112888,10 +114338,10 @@ async function runSealAndBuild(deps3, options) { "VALIDATE_PROJECTION", `${equivalence.divergences.length} divergence(s): ` + equivalence.divergences.slice(0, 3).map((divergence) => `${divergence.kind} \u2014 ${divergence.detail}`).join(" | ") ); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "projection_validated", checked: equivalence.checkedStatements, traced: equivalence.tracedStatements @@ -112903,27 +114353,27 @@ async function runSealAndBuild(deps3, options) { ); } catch (cause) { fail("VALIDATE_PROJECTION", messageOf(cause)); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } } if (!isStepSettled(stepOf(ledger, "DERIVE_APPROVALS").status)) { - const state = readSpecState(deps3.workspace, specName).state; + const state = readSpecState(deps4.workspace, specName).state; if (state?.status === "READY_FOR_IMPLEMENTATION") { settle("DERIVE_APPROVALS", "RECONCILED", "every stage of the spec is already approved"); } else { begin("DERIVE_APPROVALS"); try { - const equivalence = validateProjection(deps3, approval, specName); + const equivalence = validateProjection(deps4, approval, specName); const derived = recordDerivedApprovals({ - workspace: deps3.workspace, + workspace: deps4.workspace, approval, specName, equivalence, - clock: deps3.clock ?? (() => /* @__PURE__ */ new Date()) + clock: deps4.clock ?? (() => /* @__PURE__ */ new Date()) }); for (const stage of derived.approved) { - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "derived_approval_recorded", stage, approvalId: approval.approvalId, @@ -112937,13 +114387,13 @@ async function runSealAndBuild(deps3, options) { ); } catch (cause) { fail("DERIVE_APPROVALS", messageOf(cause)); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } } } let sealId = ledger.sealId ?? approval.sealId; if (!isStepSettled(stepOf(ledger, "SEAL").status)) { - const existing = latestExecutableSeal(deps3.workspace, approval.missionId); + const existing = latestExecutableSeal(deps4.workspace, approval.missionId); if (approval.sealId !== void 0 && existing?.sealId === approval.sealId) { sealId = existing.sealId; ledger = persist4({ ...ledger, sealId }); @@ -112953,7 +114403,7 @@ async function runSealAndBuild(deps3, options) { try { const draft = draftSeal(autonomy, { missionId: approval.missionId, - sealId: newRecordId2(deps3, "seal"), + sealId: newRecordId2(deps4, "seal"), maxApiSpendUsd: approval.maxApiSpendUsd, allowedLanes: approval.allowedLanes }); @@ -112963,17 +114413,17 @@ async function runSealAndBuild(deps3, options) { "SEAL", `the seal is missing authority required for unattended execution: ${completeness.missing.join(", ")}` ); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } const seal = sealMission(autonomy, { sealId: draft.sealId, via: `intake-approval:${approval.approvalId}` }); sealId = seal.sealId; - bindApprovalSeal(deps3.workspace, options.intakeId, seal.sealId); + bindApprovalSeal(deps4.workspace, options.intakeId, seal.sealId); ledger = persist4({ ...ledger, sealId }); - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "seal_created", sealId: seal.sealId, approvalId: approval.approvalId, @@ -112988,17 +114438,17 @@ async function runSealAndBuild(deps3, options) { ); } catch (cause) { fail("SEAL", messageOf(cause)); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } } } if (!isStepSettled(stepOf(ledger, "PREFLIGHT").status)) { begin("PREFLIGHT"); try { - preflight = await runPreflight2(deps3, options, approval.missionId, sealId); + preflight = await runPreflight2(deps4, options, approval.missionId, sealId); ledger = persist4({ ...ledger, preflightReportId: preflight.reportId }); - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "preflight_completed", reportId: preflight.reportId, verdict: preflight.verdict @@ -113006,38 +114456,38 @@ async function runSealAndBuild(deps3, options) { settle("PREFLIGHT", "COMPLETED", preflight.verdict, preflight.reportId); } catch (cause) { fail("PREFLIGHT", messageOf(cause)); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } } if (!isStepSettled(stepOf(ledger, "RESOLVE_PREREQUISITES").status)) { begin("RESOLVE_PREREQUISITES"); try { if (preflight === void 0) { - preflight = await runPreflight2(deps3, options, approval.missionId, sealId); + preflight = await runPreflight2(deps4, options, approval.missionId, sealId); ledger = persist4( withStep({ ...ledger, preflightReportId: preflight.reportId }, "PREFLIGHT", { detail: preflight.verdict, result: preflight.reportId, - settledAt: nowIso6(deps3) + settledAt: nowIso6(deps4) }) ); - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "preflight_completed", reportId: preflight.reportId, verdict: preflight.verdict, rechecked: true }); } - const resolution = resolvePrerequisites(deps3, options.intakeId, preflight); + const resolution = resolvePrerequisites(deps4, options.intakeId, preflight); ledger = persist4({ ...ledger, resolvedPrerequisites: resolution.resolved.slice(0, INTAKE_LIMITS.maxItems), humanPrerequisites: resolution.human.slice(0, INTAKE_LIMITS.maxItems) }); for (const resolved2 of resolution.resolved) { - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "prerequisite_resolved", detail: resolved2.slice(0, 400) }); @@ -113047,7 +114497,7 @@ async function runSealAndBuild(deps3, options) { "RESOLVE_PREREQUISITES", `${resolution.human.length} prerequisite(s) only a person can satisfy: ` + resolution.human.slice(0, 4).join(" | ") ); - return finish4(deps3, options, ledger, "HUMAN_PREREQUISITE_REQUIRED", { preflight }); + return finish4(deps4, options, ledger, "HUMAN_PREREQUISITE_REQUIRED", { preflight }); } settle( "RESOLVE_PREREQUISITES", @@ -113056,23 +114506,23 @@ async function runSealAndBuild(deps3, options) { ); } catch (cause) { fail("RESOLVE_PREREQUISITES", messageOf(cause)); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } } let jobId = ledger.jobId; if (!isStepSettled(stepOf(ledger, "CREATE_JOB").status)) { - if (jobId !== void 0 && readJobState(deps3.workspace, jobId).kind === "ok") { + if (jobId !== void 0 && readJobState(deps4.workspace, jobId).kind === "ok") { settle("CREATE_JOB", "RECONCILED", `job ${jobId} already exists`, jobId); } else { begin("CREATE_JOB"); try { - const job = createJob(deps3, { specName, goal: approval.goal }); + const job = createJob(deps4, { specName, goal: approval.goal }); jobId = job.jobId; ledger = persist4({ ...ledger, jobId }); - const intake = requireIntakeState(deps3.workspace, options.intakeId); - writeIntakeState(deps3.workspace, { ...intake, jobId, specName, sealId, status: "BUILDING" }); - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + const intake = requireIntakeState(deps4.workspace, options.intakeId); + writeIntakeState(deps4.workspace, { ...intake, jobId, specName, sealId, status: "BUILDING" }); + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "job_created", jobId, specName @@ -113080,23 +114530,23 @@ async function runSealAndBuild(deps3, options) { settle("CREATE_JOB", "COMPLETED", `job created for spec "${specName}"`, jobId); } catch (cause) { fail("CREATE_JOB", messageOf(cause)); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } } } jobId = jobId ?? stepOf(ledger, "CREATE_JOB").result; if (jobId === void 0) { fail("CREATE_JOB", "no job id is recorded after job creation"); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } { - const retry = retryBlockedJob(deps3, jobId, { + const retry = retryBlockedJob(deps4, jobId, { reason: "the operator resumed the intake after fixing the cause" }); if (retry.cleared) { emit3("lifecycle", `job ${jobId} unblocked and returned to the schedulable path`); - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "build_step_started", step: "LAUNCH", unblocked: true @@ -113104,18 +114554,18 @@ async function runSealAndBuild(deps3, options) { } } { - const healed = selfHealOnResume(deps3, jobId); + const healed = selfHealOnResume(deps4, jobId); for (const repair of healed.repairs) { emit3("lifecycle", `self-heal: ${repair.code} \u2014 ${repair.detail.slice(0, 160)}`); } - resetSupervisedJobForExplicitResume(autonomyDepsOf(deps3), hostOf2(deps3), jobId); + resetSupervisedJobForExplicitResume(autonomyDepsOf(deps4), hostOf2(deps4), jobId); } { const ccrs = new Map( - readCcrs(deps3.workspace, approval.missionId).map((ccr) => [ccr.ccrId, ccr.status]) + readCcrs(deps4.workspace, approval.missionId).map((ccr) => [ccr.ccrId, ccr.status]) ); const reconciled = reconcileDecidedCcrs( - deps3, + deps4, jobId, (ccrId) => ccrs.has(ccrId) && ccrs.get(ccrId) !== "NEEDS_HUMAN" ); @@ -113128,38 +114578,38 @@ async function runSealAndBuild(deps3, options) { } if (options.launch === false) { settle("LAUNCH", "SKIPPED", "launch was not requested; the job is ready to run"); - return finish4(deps3, options, ledger, "LAUNCHED", { preflight }); + return finish4(deps4, options, ledger, "LAUNCHED", { preflight }); } begin("LAUNCH"); try { - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "unattended_launched", jobId, sealId: sealId ?? null }); - unattended = await launchUnattended(deps3, options, { + unattended = await launchUnattended(deps4, options, { missionId: approval.missionId, jobId, preflight }); settle("LAUNCH", "COMPLETED", `the unattended run stopped: ${unattended.stop.kind}`, jobId); const finalOutcome = unattended.stop.kind === "completed" ? "COMPLETED" : unattended.stop.kind === "needs-authority" ? "NEEDS_AUTHORITY" : "LAUNCHED"; - return finish4(deps3, options, ledger, finalOutcome, { preflight, unattended }); + return finish4(deps4, options, ledger, finalOutcome, { preflight, unattended }); } catch (cause) { fail("LAUNCH", messageOf(cause)); - return finish4(deps3, options, ledger, "FAILED", { preflight }); + return finish4(deps4, options, ledger, "FAILED", { preflight }); } } -function validateProjection(deps3, approval, specName) { - const mission = requireMissionState(deps3.workspace, approval.missionId); - const contracts = readContractRegistry(deps3.workspace, approval.missionId); - const constitution = readConstitution(deps3.workspace, approval.missionId); - const adrs = readAdrs(deps3.workspace, approval.missionId); - const decisions = readDecisions(deps3.workspace, approval.missionId).filter( +function validateProjection(deps4, approval, specName) { + const mission = requireMissionState(deps4.workspace, approval.missionId); + const contracts = readContractRegistry(deps4.workspace, approval.missionId); + const constitution = readConstitution(deps4.workspace, approval.missionId); + const adrs = readAdrs(deps4.workspace, approval.missionId); + const decisions = readDecisions(deps4.workspace, approval.missionId).filter( (decision) => decision.status === "active" ); - const questions = readQuestions2(deps3.workspace, approval.intakeId); + const questions = readQuestions2(deps4.workspace, approval.intakeId); const currentDigest = computeIntakeAuthorityDigest( canonicalTruthOf({ mission, @@ -113171,10 +114621,10 @@ function validateProjection(deps3, approval, specName) { }) ); return checkProjectionEquivalence({ - workspace: deps3.workspace, + workspace: deps4.workspace, approval, specName, - checkedAt: nowIso6(deps3), + checkedAt: nowIso6(deps4), approvedElements: approvedElements( approval, contracts.map((contract) => ({ @@ -113189,9 +114639,9 @@ function validateProjection(deps3, approval, specName) { currentAuthorityDigest: currentDigest }); } -async function runPreflight2(deps3, options, missionId, sealId) { - const autonomy = autonomyDepsOf(deps3); - const seal = latestExecutableSeal(deps3.workspace, missionId); +async function runPreflight2(deps4, options, missionId, sealId) { + const autonomy = autonomyDepsOf(deps4); + const seal = latestExecutableSeal(deps4.workspace, missionId); const surfaces = requiredSurfacesFor(seal); return runOvernightPreflight(autonomy, { subject: missionId, @@ -113202,10 +114652,10 @@ async function runPreflight2(deps3, options, missionId, sealId) { ...options.probeRunner !== void 0 ? { probeRunner: options.probeRunner } : {} }); } -function resolvePrerequisites(deps3, intakeId, report) { +function resolvePrerequisites(deps4, intakeId, report) { const resolved2 = []; const human = []; - const autonomy = autonomyDepsOf(deps3); + const autonomy = autonomyDepsOf(deps4); for (const check6 of report.checks) { if (check6.outcome === "HUMAN_REQUIRED") { human.push( @@ -113230,7 +114680,7 @@ function resolvePrerequisites(deps3, intakeId, report) { capability, target: check6.capability, purpose: `Overnight preflight classified ${check6.capability} as satisfiable by the runtime; pre-authorizing it before the unattended launch.`, - requestId: newRecordId2(deps3, "ts") + requestId: newRecordId2(deps4, "ts") }); if (decision.request.status === "GRANTED") { resolved2.push(`${check6.capability}: pre-authorized as ${capability}`); @@ -113242,9 +114692,9 @@ function resolvePrerequisites(deps3, intakeId, report) { } return { resolved: resolved2, human }; } -async function launchUnattended(deps3, options, input) { +async function launchUnattended(deps4, options, input) { if (options.runUnattended !== void 0) { - return options.runUnattended(deps3, { missionId: input.missionId, jobId: input.jobId }); + return options.runUnattended(deps4, { missionId: input.missionId, jobId: input.jobId }); } if (options.host === void 0) { throw new IntakeError( @@ -113252,7 +114702,7 @@ async function launchUnattended(deps3, options, input) { "The unattended launch needs a driver host. Pass one, or run with --no-launch and launch with `specbridge overnight run`." ); } - return runUnattendedMission(autonomyDepsOf(deps3), { + return runUnattendedMission(autonomyDepsOf(deps4), { missionId: input.missionId, jobId: input.jobId, host: options.host, @@ -113260,25 +114710,25 @@ async function launchUnattended(deps3, options, input) { ...options.maxCycles !== void 0 ? { maxCycles: options.maxCycles } : {}, ...options.signal !== void 0 ? { signal: options.signal } : {}, ...options.onEvent !== void 0 ? { onEvent: options.onEvent } : {}, - ownerId: hostOf2(deps3) + ownerId: hostOf2(deps4) }); } -function finish4(deps3, options, ledger, outcome, extras) { - const finished7 = writeLifecycle(deps3.workspace, { +function finish4(deps4, options, ledger, outcome, extras) { + const finished7 = writeLifecycle(deps4.workspace, { ...ledger, outcome, - updatedAt: nowIso6(deps3), - finishedAt: nowIso6(deps3) + updatedAt: nowIso6(deps4), + finishedAt: nowIso6(deps4) }); - appendIntakeEvent(deps3.workspace, options.intakeId, { - at: nowIso6(deps3), + appendIntakeEvent(deps4.workspace, options.intakeId, { + at: nowIso6(deps4), type: "build_finished", outcome, ...finished7.jobId !== void 0 ? { jobId: finished7.jobId } : {} }); - const intake = requireIntakeState(deps3.workspace, options.intakeId); + const intake = requireIntakeState(deps4.workspace, options.intakeId); const status = outcome === "COMPLETED" ? "BUILT" : outcome === "LAUNCHED" ? "BUILDING" : outcome === "NEEDS_AUTHORITY" ? "BUILDING" : "BLOCKED"; - writeIntakeState(deps3.workspace, { + writeIntakeState(deps4.workspace, { ...intake, status, ...finished7.jobId !== void 0 ? { jobId: finished7.jobId } : {}, @@ -113296,7 +114746,7 @@ function finish4(deps3, options, ledger, outcome, extras) { function messageOf(cause) { return cause instanceof Error ? cause.message : String(cause); } -function startSpecIntake(deps3, request) { +function startSpecIntake(deps4, request) { const name = request.name.trim(); if (name.length === 0) { throw new IntakeError("SBI005", "A spec intake needs a name.", { @@ -113315,23 +114765,23 @@ function startSpecIntake(deps3, request) { { remediation: ["Split the specification, or submit the part this feature covers."] } ); } - const intakeId = request.intakeId ?? newRecordId2(deps3, "intake"); + const intakeId = request.intakeId ?? newRecordId2(deps4, "intake"); const contentHash = sha256Hex(content); - const storedPath = storeSourceText(deps3.workspace, intakeId, contentHash, content); + const storedPath = storeSourceText(deps4.workspace, intakeId, contentHash, content); const parsed = parseSpecificationDocument(content); - const at = nowIso6(deps3); + const at = nowIso6(deps4); const goal = request.goal?.trim() ?? deriveGoal(parsed.chunks, name); - const mission = beginMission(missionDepsOf(deps3), { name, goal }); - const source = writeSpecSource(deps3.workspace, { + const mission = beginMission(missionDepsOf(deps4), { name, goal }); + const source = writeSpecSource(deps4.workspace, { schemaVersion: INTAKE_SOURCE_SCHEMA_VERSION, intakeId, kind: request.kind, ...request.originPath !== void 0 ? { originPath: clip(request.originPath, 500) } : {}, receivedAt: at, - receivedVia: hostOf2(deps3), + receivedVia: hostOf2(deps4), byteLength, contentHash, - storedAt: import_path94.default.posix.join( + storedAt: import_path95.default.posix.join( ".specbridge", "intake", intakeId, @@ -113342,7 +114792,7 @@ function startSpecIntake(deps3, request) { chunks: parsed.chunks }); void storedPath; - const intake = writeIntakeState(deps3.workspace, { + const intake = writeIntakeState(deps4.workspace, { schemaVersion: INTAKE_STATE_SCHEMA_VERSION, intakeId, name, @@ -113350,9 +114800,9 @@ function startSpecIntake(deps3, request) { missionId: mission.missionId, createdAt: at, updatedAt: at, - host: hostOf2(deps3), + host: hostOf2(deps4), sourceContentHash: contentHash, - baselineCommit: readGitHead(deps3.workspace.rootDir), + baselineCommit: readGitHead(deps4.workspace.rootDir), counters: { sourceChunks: parsed.chunks.length, normativeChunks: parsed.normativeCount, @@ -113369,13 +114819,13 @@ function startSpecIntake(deps3, request) { sequences: { question: 0, refusal: 0, deltaItem: 0, evidence: 0 }, ...request.specName !== void 0 ? { specName: request.specName } : {} }); - appendIntakeEvent(deps3.workspace, intakeId, { + appendIntakeEvent(deps4.workspace, intakeId, { at, type: "intake_created", name, missionId: mission.missionId }); - appendIntakeEvent(deps3.workspace, intakeId, { + appendIntakeEvent(deps4.workspace, intakeId, { at, type: "source_ingested", kind: request.kind, @@ -113386,53 +114836,53 @@ function startSpecIntake(deps3, request) { }); return { intake, source, mission }; } -function startSpecIntakeFromFile(deps3, request) { - const resolved2 = import_path94.default.resolve(request.file); - if (!(0, import_fs85.existsSync)(resolved2)) { +function startSpecIntakeFromFile(deps4, request) { + const resolved2 = import_path95.default.resolve(request.file); + if (!(0, import_fs86.existsSync)(resolved2)) { throw new IntakeError("SBI007", `No specification file at ${request.file}.`, { remediation: ["Check the path, or pass the specification text with --text."] }); } - const size = (0, import_fs85.statSync)(resolved2).size; + const size = (0, import_fs86.statSync)(resolved2).size; if (size > INTAKE_LIMITS.maxSourceBytes) { throw new IntakeError( "SBI006", `${request.file} is ${size} bytes, over the ${INTAKE_LIMITS.maxSourceBytes}-byte bound.` ); } - const content = (0, import_fs85.readFileSync)(resolved2, "utf8"); - return startSpecIntake(deps3, { + const content = (0, import_fs86.readFileSync)(resolved2, "utf8"); + return startSpecIntake(deps4, { ...request, kind: "file", content, originPath: resolved2 }); } -function runIntakeDiscovery(deps3, intakeId, options = {}) { - let intake = requireIntakeState(deps3.workspace, intakeId); +function runIntakeDiscovery(deps4, intakeId, options = {}) { + let intake = requireIntakeState(deps4.workspace, intakeId); if (intake.status === "ABANDONED") { throw new IntakeError("SBI004", `Spec intake ${intakeId} is ABANDONED and read-only.`); } - const source = requireSpecSource(deps3.workspace, intakeId); - const at = nowIso6(deps3); + const source = requireSpecSource(deps4.workspace, intakeId); + const at = nowIso6(deps4); const grounding = writeGrounding( - deps3.workspace, - groundInRepository(deps3, { + deps4.workspace, + groundInRepository(deps4, { intakeId, excludeMissionIds: [intake.missionId] }) ); - appendIntakeEvent(deps3.workspace, intakeId, { + appendIntakeEvent(deps4.workspace, intakeId, { at, type: "grounding_completed", evidence: grounding.evidence.length, priorMissions: grounding.priorMissionIds.length, existingProduct: grounding.existingProduct }); - const existingContracts = activeProductContracts(deps3.workspace, { + const existingContracts = activeProductContracts(deps4.workspace, { excludeMissionIds: [intake.missionId] }); - const constitutionRules = activeConstitutionRules(deps3.workspace, { + const constitutionRules = activeConstitutionRules(deps4.workspace, { excludeMissionIds: [intake.missionId] }); let analysis = analyzeDeltaAuthority({ @@ -113452,7 +114902,7 @@ function runIntakeDiscovery(deps3, intakeId, options = {}) { let questionSequence = intake.sequences.question; let refusalSequence = intake.sequences.refusal; const newQuestions = []; - const admitted = admitAndRecord(deps3, { + const admitted = admitAndRecord(deps4, { intakeId, missionId: intake.missionId, candidates, @@ -113465,7 +114915,7 @@ function runIntakeDiscovery(deps3, intakeId, options = {}) { questionSequence = admitted.nextQuestionSequence; refusalSequence = admitted.nextRefusalSequence; newQuestions.push(...admitted.opened); - let questions = readQuestions2(deps3.workspace, intakeId); + let questions = readQuestions2(deps4.workspace, intakeId); const openByItem = /* @__PURE__ */ new Map(); for (const question of questions) { if (question.status !== "open") continue; @@ -113494,7 +114944,7 @@ function runIntakeDiscovery(deps3, intakeId, options = {}) { const authoritySensitive = raisedItems.filter( (item) => requiresProductAuthority(item.classification) ); - analysis = writeDeltaAnalysis(deps3.workspace, { + analysis = writeDeltaAnalysis(deps4.workspace, { ...analysis, items: raisedItems, counts: countsOf(raisedItems), @@ -113505,7 +114955,7 @@ function runIntakeDiscovery(deps3, intakeId, options = {}) { "The submitted specification contains no statements the classifier recognised as material." ] : [] }); - appendIntakeEvent(deps3.workspace, intakeId, { + appendIntakeEvent(deps4.workspace, intakeId, { at, type: "delta_analysis_completed", items: analysis.items.length, @@ -113516,7 +114966,7 @@ function runIntakeDiscovery(deps3, intakeId, options = {}) { const blockedItemIds = analysis.items.filter( (item) => item.classification === "UNKNOWN_PRODUCT_AUTHORITY" || item.classification === "CONTRADICTION" || item.classification === "EXISTING_SEALED_CONTRACT_CHANGE" ).map((item) => item.itemId); - const compiled = compileMissionTruth(missionDepsOf(deps3), deps3, { + const compiled = compileMissionTruth(missionDepsOf(deps4), deps4, { intakeId, missionId: intake.missionId, source, @@ -113531,11 +114981,11 @@ function runIntakeDiscovery(deps3, intakeId, options = {}) { ...question.deltaItemId !== void 0 ? { deltaItemId: question.deltaItemId } : {} })) }); - let mission = requireMissionState(deps3.workspace, intake.missionId); - let missionCoverage = refreshCoverage(missionDepsOf(deps3), mission); + let mission = requireMissionState(deps4.workspace, intake.missionId); + let missionCoverage = refreshCoverage(missionDepsOf(deps4), mission); const unknownRequired = missionCoverage.topics.filter((topic) => topic.required && topic.status === "unknown").map((topic) => topic.topicId); if (unknownRequired.length > 0) { - const topicAdmission = admitAndRecord(deps3, { + const topicAdmission = admitAndRecord(deps4, { intakeId, missionId: intake.missionId, candidates: generateRequiredTopicCandidates(unknownRequired), @@ -113548,9 +114998,9 @@ function runIntakeDiscovery(deps3, intakeId, options = {}) { questionSequence = topicAdmission.nextQuestionSequence; refusalSequence = topicAdmission.nextRefusalSequence; newQuestions.push(...topicAdmission.opened); - questions = readQuestions2(deps3.workspace, intakeId); - mission = requireMissionState(deps3.workspace, intake.missionId); - missionCoverage = refreshCoverage(missionDepsOf(deps3), mission); + questions = readQuestions2(deps4.workspace, intakeId); + mission = requireMissionState(deps4.workspace, intake.missionId); + missionCoverage = refreshCoverage(missionDepsOf(deps4), mission); } const coverage = reconcileCoverage({ chunks: source.chunks, @@ -113559,7 +115009,7 @@ function runIntakeDiscovery(deps3, intakeId, options = {}) { evidence: grounding.evidence, overflowItemIds: compiled.overflowItemIds }); - appendIntakeEvent(deps3.workspace, intakeId, { + appendIntakeEvent(deps4.workspace, intakeId, { at, type: "coverage_reconciled", unaccounted: coverage.filter((entry2) => entry2.state === "UNACCOUNTED").length, @@ -113571,29 +115021,29 @@ function runIntakeDiscovery(deps3, intakeId, options = {}) { questions, missionCoverage, overflowed: compiled.overflowItemIds.length > 0, - productContractCount: readContractRegistry(deps3.workspace, intake.missionId).filter( + productContractCount: readContractRegistry(deps4.workspace, intake.missionId).filter( (contract) => contract.status !== "superseded" ).length }); const openCount = questions.filter((question) => question.status === "open").length; const status = readiness.ready ? "READY_FOR_APPROVAL" : openCount > 0 ? "AWAITING_PRODUCT_ANSWERS" : "DISCOVERING"; if (status !== intake.status && intake.status !== "APPROVED" && intake.status !== "BUILDING") { - appendIntakeEvent(deps3.workspace, intakeId, { + appendIntakeEvent(deps4.workspace, intakeId, { at, type: "status_changed", from: intake.status, to: status }); if (status === "READY_FOR_APPROVAL") { - appendIntakeEvent(deps3.workspace, intakeId, { + appendIntakeEvent(deps4.workspace, intakeId, { at, type: "ready_for_approval", - contracts: readContractRegistry(deps3.workspace, intake.missionId).length, + contracts: readContractRegistry(deps4.workspace, intake.missionId).length, criteria: mission.successCriteria.length }); } } - intake = writeIntakeState(deps3.workspace, { + intake = writeIntakeState(deps4.workspace, { ...intake, status: intake.status === "APPROVED" || intake.status === "BUILDING" || intake.status === "BUILT" ? intake.status : status, counters: { @@ -113602,7 +115052,7 @@ function runIntakeDiscovery(deps3, intakeId, options = {}) { deltaItems: analysis.items.length, questionsAsked: questions.length, questionsAnswered: questions.filter((question) => question.status === "answered").length, - questionsRefused: readRefusals(deps3.workspace, intakeId).length, + questionsRefused: readRefusals(deps4.workspace, intakeId).length, groundingPasses: intake.counters.groundingPasses + 1 }, sequences: { @@ -113619,14 +115069,14 @@ function runIntakeDiscovery(deps3, intakeId, options = {}) { analysis, questions, newQuestions, - refusals: readRefusals(deps3.workspace, intakeId), + refusals: readRefusals(deps4.workspace, intakeId), coverage, readiness, missionCoverage }; } -function answerIntakeQuestion(deps3, intakeId, request, options = {}) { - const intake = requireIntakeState(deps3.workspace, intakeId); +function answerIntakeQuestion(deps4, intakeId, request, options = {}) { + const intake = requireIntakeState(deps4.workspace, intakeId); if (intake.status === "APPROVED" || intake.status === "BUILDING" || intake.status === "BUILT") { throw new IntakeError( "SBI003", @@ -113638,7 +115088,7 @@ function answerIntakeQuestion(deps3, intakeId, request, options = {}) { } ); } - const questions = readQuestions2(deps3.workspace, intakeId); + const questions = readQuestions2(deps4.workspace, intakeId); const question = questions.find((candidate) => candidate.questionId === request.questionId); if (question === void 0) { throw new IntakeError("SBI005", `No product question "${request.questionId}" on this intake.`, { @@ -113658,8 +115108,8 @@ function answerIntakeQuestion(deps3, intakeId, request, options = {}) { `Question ${request.questionId} was never mirrored into the mission and cannot record a governed answer.` ); } - const at = nowIso6(deps3); - const result = answerQuestion(missionDepsOf(deps3), intake.missionId, { + const at = nowIso6(deps4); + const result = answerQuestion(missionDepsOf(deps4), intake.missionId, { questionId: question.missionQuestionId, answer }); @@ -113670,14 +115120,14 @@ function answerIntakeQuestion(deps3, intakeId, request, options = {}) { answeredAt: at, decisionId: result.decision.decisionId }; - appendQuestion2(deps3.workspace, intakeId, answered); - appendIntakeEvent(deps3.workspace, intakeId, { + appendQuestion2(deps4.workspace, intakeId, answered); + appendIntakeEvent(deps4.workspace, intakeId, { at, type: "question_answered", questionId: answered.questionId, decisionId: result.decision.decisionId }); - writeIntakeState(deps3.workspace, { + writeIntakeState(deps4.workspace, { ...intake, counters: { ...intake.counters, @@ -113685,23 +115135,23 @@ function answerIntakeQuestion(deps3, intakeId, request, options = {}) { questionsAnswered: intake.counters.questionsAnswered + 1 } }); - const discovery = runIntakeDiscovery(deps3, intakeId, options); + const discovery = runIntakeDiscovery(deps4, intakeId, options); return { question: answered, intake: discovery.intake, discovery }; } -function approveIntake(deps3, request) { - const intake = requireIntakeState(deps3.workspace, request.intakeId); +function approveIntake(deps4, request) { + const intake = requireIntakeState(deps4.workspace, request.intakeId); if (intake.status === "ABANDONED") { throw new IntakeError("SBI004", `Spec intake ${request.intakeId} is ABANDONED.`); } - const existing = readApproval(deps3.workspace, request.intakeId); + const existing = readApproval(deps4.workspace, request.intakeId); if (existing !== void 0) { return { approval: existing, intake, - summary: summaryOf(deps3, intake) + summary: summaryOf(deps4, intake) }; } - const discovery = runIntakeDiscovery(deps3, request.intakeId); + const discovery = runIntakeDiscovery(deps4, request.intakeId); if (!discovery.readiness.ready) { throw new IntakeError( "SBI010", @@ -113722,23 +115172,23 @@ function approveIntake(deps3, request) { } ); } - const mission = requireMissionState(deps3.workspace, intake.missionId); - const contracts = readContractRegistry(deps3.workspace, intake.missionId); - const constitution = readConstitution(deps3.workspace, intake.missionId); - const adrs = readAdrs(deps3.workspace, intake.missionId); - const decisions = readDecisions(deps3.workspace, intake.missionId).filter( + const mission = requireMissionState(deps4.workspace, intake.missionId); + const contracts = readContractRegistry(deps4.workspace, intake.missionId); + const constitution = readConstitution(deps4.workspace, intake.missionId); + const adrs = readAdrs(deps4.workspace, intake.missionId); + const decisions = readDecisions(deps4.workspace, intake.missionId).filter( (decision) => decision.status === "active" ); - const source = requireSpecSource(deps3.workspace, request.intakeId); - const at = nowIso6(deps3); + const source = requireSpecSource(deps4.workspace, request.intakeId); + const at = nowIso6(deps4); const approval = writeApproval( - deps3.workspace, + deps4.workspace, buildIntakeApproval({ - approvalId: request.approvalId ?? newRecordId2(deps3, "approval"), + approvalId: request.approvalId ?? newRecordId2(deps4, "approval"), intakeId: request.intakeId, missionId: intake.missionId, approvedAt: at, - approvedVia: request.via ?? hostOf2(deps3), + approvedVia: request.via ?? hostOf2(deps4), source, mission, contracts, @@ -113751,7 +115201,7 @@ function approveIntake(deps3, request) { allowedLanes: request.allowedLanes ?? ["LOCAL", "SUBSCRIPTION"] }) ); - appendIntakeEvent(deps3.workspace, request.intakeId, { + appendIntakeEvent(deps4.workspace, request.intakeId, { at, type: "intake_approved", approvalId: approval.approvalId, @@ -113761,13 +115211,13 @@ function approveIntake(deps3, request) { criteria: approval.acceptanceCriteria.length, answeredQuestions: approval.resolvedQuestions.length }); - appendIntakeEvent(deps3.workspace, request.intakeId, { + appendIntakeEvent(deps4.workspace, request.intakeId, { at, type: "status_changed", from: intake.status, to: "APPROVED" }); - const approved = writeIntakeState(deps3.workspace, { + const approved = writeIntakeState(deps4.workspace, { ...intake, status: "APPROVED", approvalId: approval.approvalId, @@ -113777,7 +115227,7 @@ function approveIntake(deps3, request) { authorityApprovalCount: intake.counters.authorityApprovalCount + 1 } }); - recordBaselineEntry(deps3, approved, approval, discovery.analysis); + recordBaselineEntry(deps4, approved, approval, discovery.analysis); return { approval, intake: approved, @@ -113789,25 +115239,25 @@ function approveIntake(deps3, request) { }) }; } -function describeIntake(deps3, intakeId) { - const intake = requireIntakeState(deps3.workspace, intakeId); - const contracts = readContractRegistry(deps3.workspace, intake.missionId); +function describeIntake(deps4, intakeId) { + const intake = requireIntakeState(deps4.workspace, intakeId); + const contracts = readContractRegistry(deps4.workspace, intake.missionId); return { intake, - source: readSpecSource(deps3.workspace, intakeId), - grounding: readGrounding(deps3.workspace, intakeId), - analysis: readDeltaAnalysis(deps3.workspace, intakeId), - questions: readQuestions2(deps3.workspace, intakeId), - refusals: readRefusals(deps3.workspace, intakeId), - approval: readApproval(deps3.workspace, intakeId), - lifecycle: readLifecycle(deps3.workspace, intakeId), - summary: summaryOf(deps3, intake), - missionCoverage: readCoverage(deps3.workspace, intake.missionId), + source: readSpecSource(deps4.workspace, intakeId), + grounding: readGrounding(deps4.workspace, intakeId), + analysis: readDeltaAnalysis(deps4.workspace, intakeId), + questions: readQuestions2(deps4.workspace, intakeId), + refusals: readRefusals(deps4.workspace, intakeId), + approval: readApproval(deps4.workspace, intakeId), + lifecycle: readLifecycle(deps4.workspace, intakeId), + summary: summaryOf(deps4, intake), + missionCoverage: readCoverage(deps4.workspace, intake.missionId), contracts }; } -function requireIntakeFor(deps3, subject) { - const found = findIntake(deps3.workspace, subject); +function requireIntakeFor(deps4, subject) { + const found = findIntake(deps4.workspace, subject); if (found === void 0) { throw new IntakeError("SBI001", `No spec intake matches "${subject}".`, { remediation: [ @@ -113818,39 +115268,39 @@ function requireIntakeFor(deps3, subject) { } return found; } -function abandonIntake(deps3, intakeId, reason3) { - const intake = requireIntakeState(deps3.workspace, intakeId); +function abandonIntake(deps4, intakeId, reason3) { + const intake = requireIntakeState(deps4.workspace, intakeId); if (intake.status === "ABANDONED") return intake; - const at = nowIso6(deps3); - appendIntakeEvent(deps3.workspace, intakeId, { + const at = nowIso6(deps4); + appendIntakeEvent(deps4.workspace, intakeId, { at, type: "intake_abandoned", reason: clip(reason3, 500) }); - return writeIntakeState(deps3.workspace, { + return writeIntakeState(deps4.workspace, { ...intake, status: "ABANDONED", abandonedAt: at, abandonReason: clip(reason3, INTAKE_LIMITS.maxTextChars) }); } -function summaryOf(deps3, intake) { - const analysis = readDeltaAnalysis(deps3.workspace, intake.intakeId); +function summaryOf(deps4, intake) { + const analysis = readDeltaAnalysis(deps4.workspace, intake.intakeId); if (analysis === void 0) return void 0; return buildApprovalSummary({ - mission: requireMissionState(deps3.workspace, intake.missionId), - contracts: readContractRegistry(deps3.workspace, intake.missionId), + mission: requireMissionState(deps4.workspace, intake.missionId), + contracts: readContractRegistry(deps4.workspace, intake.missionId), analysis, - questions: readQuestions2(deps3.workspace, intake.intakeId) + questions: readQuestions2(deps4.workspace, intake.intakeId) }); } -function admitAndRecord(deps3, input) { +function admitAndRecord(deps4, input) { const admission = admitQuestions({ candidates: input.candidates, context: { chunks: input.chunks, evidence: input.evidence, - existing: readQuestions2(deps3.workspace, input.intakeId) + existing: readQuestions2(deps4.workspace, input.intakeId) }, at: input.at, questionSequence: input.questionSequence, @@ -113858,7 +115308,7 @@ function admitAndRecord(deps3, input) { }); const opened = []; if (admission.questions.length > 0) { - const assessment = recordAssessment(missionDepsOf(deps3), input.missionId, { + const assessment = recordAssessment(missionDepsOf(deps4), input.missionId, { questions: admission.questions.map((question) => ({ question: question.question, whyItMatters: question.whyItMatters, @@ -113874,9 +115324,9 @@ function admitAndRecord(deps3, input) { ...question, ...missionQuestionId !== void 0 ? { missionQuestionId } : {} }; - appendQuestion2(deps3.workspace, input.intakeId, stored); + appendQuestion2(deps4.workspace, input.intakeId, stored); opened.push(stored); - appendIntakeEvent(deps3.workspace, input.intakeId, { + appendIntakeEvent(deps4.workspace, input.intakeId, { at: input.at, type: "question_opened", questionId: stored.questionId, @@ -113887,8 +115337,8 @@ function admitAndRecord(deps3, input) { }); } for (const refusal of admission.refusals) { - appendRefusal(deps3.workspace, input.intakeId, refusal); - appendIntakeEvent(deps3.workspace, input.intakeId, { + appendRefusal(deps4.workspace, input.intakeId, refusal); + appendIntakeEvent(deps4.workspace, input.intakeId, { at: input.at, type: "question_refused", refusalId: refusal.refusalId, @@ -113915,8 +115365,8 @@ function deriveGoal(chunks, name) { const derived = opening !== void 0 ? firstSentence(opening.text, 600) : ""; return derived.length >= 12 ? derived : `Deliver the ${name} feature as specified.`; } -function recordBaselineEntry(deps3, intake, approval, analysis) { - const baseline = readProductBaseline(deps3.workspace); +function recordBaselineEntry(deps4, intake, approval, analysis) { + const baseline = readProductBaseline(deps4.workspace); const predecessorSealIds = baseline.features.filter((feature) => feature.sealId !== void 0 && feature.intakeId !== intake.intakeId).map((feature) => feature.sealId); const entry2 = { intakeId: intake.intakeId, @@ -113931,19 +115381,19 @@ function recordBaselineEntry(deps3, intake, approval, analysis) { implementationCommits: [] }; const features = baseline.features.filter((feature) => feature.intakeId !== intake.intakeId); - writeProductBaseline(deps3.workspace, { + writeProductBaseline(deps4.workspace, { ...baseline, updatedAt: approval.approvedAt, features: [...features, entry2].slice(-INTAKE_LIMITS.maxItems) }); - appendIntakeEvent(deps3.workspace, intake.intakeId, { + appendIntakeEvent(deps4.workspace, intake.intakeId, { at: approval.approvedAt, type: "baseline_recorded", predecessors: predecessorSealIds.length }); } -function recordFeatureOutcome(deps3, intakeId, outcome) { - const baseline = readProductBaseline(deps3.workspace); +function recordFeatureOutcome(deps4, intakeId, outcome) { + const baseline = readProductBaseline(deps4.workspace); const index = baseline.features.findIndex((feature) => feature.intakeId === intakeId); if (index < 0) return; const existing = baseline.features[index]; @@ -113959,29 +115409,29 @@ function recordFeatureOutcome(deps3, intakeId, outcome) { }; const features = [...baseline.features]; features[index] = updated; - writeProductBaseline(deps3.workspace, { + writeProductBaseline(deps4.workspace, { ...baseline, - updatedAt: nowIso6(deps3), + updatedAt: nowIso6(deps4), features }); } -function listSpecIntakes(deps3) { - return listIntakes(deps3.workspace); +function listSpecIntakes(deps4) { + return listIntakes(deps4.workspace); } var INTAKE_TELEMETRY_SCHEMA_VERSION = "1.0.0"; -function computeIntakeTelemetry(deps3, intakeId) { - const intake = requireIntakeState(deps3.workspace, intakeId); - const approval = readApproval(deps3.workspace, intakeId); - const questions = readQuestions2(deps3.workspace, intakeId); - const refusals = readRefusals(deps3.workspace, intakeId); +function computeIntakeTelemetry(deps4, intakeId) { + const intake = requireIntakeState(deps4.workspace, intakeId); + const approval = readApproval(deps4.workspace, intakeId); + const questions = readQuestions2(deps4.workspace, intakeId); + const refusals = readRefusals(deps4.workspace, intakeId); let autonomy; if (intake.jobId !== void 0) { - autonomy = readAutonomyTelemetry(deps3.workspace, intake.jobId) ?? safeCompute(deps3, intake.jobId); + autonomy = readAutonomyTelemetry(deps4.workspace, intake.jobId) ?? safeCompute(deps4, intake.jobId); } return intakeTelemetrySchema.parse({ schemaVersion: INTAKE_TELEMETRY_SCHEMA_VERSION, intakeId, - recordedAt: nowIso6(deps3), + recordedAt: nowIso6(deps4), status: intake.status, discoveryHumanTurns: intake.counters.discoveryHumanTurns, productQuestionsAsked: questions.length, @@ -113994,9 +115444,9 @@ function computeIntakeTelemetry(deps3, intakeId) { ...intake.sealId !== void 0 ? { sealId: intake.sealId } : {} }); } -function safeCompute(deps3, jobId) { +function safeCompute(deps4, jobId) { try { - return computeAutonomyTelemetry(autonomyDepsOf(deps3), { jobId }); + return computeAutonomyTelemetry(autonomyDepsOf(deps4), { jobId }); } catch { return void 0; } @@ -114125,7 +115575,7 @@ var repositoryManifestSchema = external_exports.object({ function repositoryManifestFile(workspace) { return assertInsideWorkspace( workspace.rootDir, - import_path95.default.join(workspace.sidecarDir, "repositories.json") + import_path96.default.join(workspace.sidecarDir, "repositories.json") ); } var DETECTION_DENYLIST = /* @__PURE__ */ new Set([ @@ -114142,10 +115592,10 @@ var DETECTION_DENYLIST = /* @__PURE__ */ new Set([ ]); function readRepositoryManifest(workspace) { const file = repositoryManifestFile(workspace); - if (!(0, import_fs86.existsSync)(file)) return void 0; + if (!(0, import_fs87.existsSync)(file)) return void 0; let raw; try { - raw = JSON.parse((0, import_fs86.readFileSync)(file, "utf8")); + raw = JSON.parse((0, import_fs87.readFileSync)(file, "utf8")); } catch (cause) { throw new IntakeError("SBI018", `The repository manifest at ${file} is not valid JSON.`, { remediation: ["Fix or delete .specbridge/repositories.json; without it the workspace root is the repository."], @@ -114165,7 +115615,7 @@ function resolveRepositories(workspace) { } seen.add(entry2.id); const absDir = assertInsideWorkspace(workspace.rootDir, entry2.path); - if (!(0, import_fs86.existsSync)(absDir) || !(0, import_fs86.statSync)(absDir).isDirectory()) { + if (!(0, import_fs87.existsSync)(absDir) || !(0, import_fs87.statSync)(absDir).isDirectory()) { throw new IntakeError( "SBI018", `The repository manifest names "${entry2.id}" at ${entry2.path}, which is not a directory.`, @@ -114182,11 +115632,11 @@ function resolveRepositories(workspace) { } const children = []; try { - for (const entry2 of (0, import_fs86.readdirSync)(workspace.rootDir, { withFileTypes: true })) { + for (const entry2 of (0, import_fs87.readdirSync)(workspace.rootDir, { withFileTypes: true })) { if (!entry2.isDirectory()) continue; if (DETECTION_DENYLIST.has(entry2.name) || entry2.name.startsWith(".")) continue; - const absDir = import_path95.default.join(workspace.rootDir, entry2.name); - if (!(0, import_fs86.existsSync)(import_path95.default.join(absDir, ".git"))) continue; + const absDir = import_path96.default.join(workspace.rootDir, entry2.name); + if (!(0, import_fs87.existsSync)(import_path96.default.join(absDir, ".git"))) continue; if (children.length >= BOOTSTRAP_LIMITS.maxRepositories) { notes.push("More child repositories exist than the bootstrap bound; declare a manifest to choose."); break; @@ -114197,7 +115647,7 @@ function resolveRepositories(workspace) { notes.push(`The workspace root could not be listed: ${cause instanceof Error ? cause.message : String(cause)}.`); } if (children.length > 0) { - const rootIsRepo = (0, import_fs86.existsSync)(import_path95.default.join(workspace.rootDir, ".git")); + const rootIsRepo = (0, import_fs87.existsSync)(import_path96.default.join(workspace.rootDir, ".git")); const repositories = rootIsRepo ? [resolved(workspace, rootRepositoryId(workspace), workspace.rootDir, void 0), ...children] : children; return { repositories: repositories.slice(0, BOOTSTRAP_LIMITS.maxRepositories), @@ -114212,18 +115662,18 @@ function resolveRepositories(workspace) { }; } function rootRepositoryId(workspace) { - const base = import_path95.default.basename(workspace.rootDir).replace(/[^A-Za-z0-9._-]/g, "-").replace(/^[^A-Za-z0-9]+/, ""); + const base = import_path96.default.basename(workspace.rootDir).replace(/[^A-Za-z0-9._-]/g, "-").replace(/^[^A-Za-z0-9]+/, ""); return base.length > 0 ? base.slice(0, 64) : "workspace"; } function resolved(workspace, repositoryId, absDir, role) { - const relPath2 = import_path95.default.relative(workspace.rootDir, absDir).replace(/\\/g, "/"); + const relPath2 = import_path96.default.relative(workspace.rootDir, absDir).replace(/\\/g, "/"); return { repositoryId, relPath: relPath2, ...role !== void 0 ? { role } : {}, absDir, gitHead: readGitHead(absDir), - isGitRepository: (0, import_fs86.existsSync)(import_path95.default.join(absDir, ".git")) + isGitRepository: (0, import_fs87.existsSync)(import_path96.default.join(absDir, ".git")) }; } function repositoryOfPath(repositories, workspaceRelativePath) { @@ -114416,7 +115866,7 @@ function synthesizeSystemFindings(input) { }); } const manifestEntries = entries.filter( - (entry2) => MANIFEST_BASENAMES.has(import_path96.default.posix.basename(entry2.path).toLowerCase()) + (entry2) => MANIFEST_BASENAMES.has(import_path97.default.posix.basename(entry2.path).toLowerCase()) ); const architectureLabels = /* @__PURE__ */ new Map(); for (const entry2 of manifestEntries.slice(0, 40)) { @@ -114461,7 +115911,7 @@ function synthesizeSystemFindings(input) { architecture.push({ findingId: ids("arc"), class: "OBSERVED_IMPLEMENTATION", - statement: clip3(`${label} (declared by ${import_path96.default.posix.basename(entry2.path)}).`), + statement: clip3(`${label} (declared by ${import_path97.default.posix.basename(entry2.path)}).`), evidence: [fileRef(entry2)] }); } @@ -114606,7 +116056,7 @@ function synthesizeSystemFindings(input) { findingId: ids("con"), class: "OBSERVED_IMPLEMENTATION", statement: clip3( - `Repository "${repo.repositoryId}" builds with ${import_path96.default.posix.basename(marker.path)}.` + `Repository "${repo.repositoryId}" builds with ${import_path97.default.posix.basename(marker.path)}.` ), evidence: [fileRef(marker)] }); @@ -114678,9 +116128,9 @@ function clip3(value) { } function boundedRead(workspace, relPath2) { try { - const abs = import_path96.default.join(workspace.rootDir, relPath2); - if (!(0, import_fs87.existsSync)(abs)) return void 0; - const body = (0, import_fs87.readFileSync)(abs, "utf8"); + const abs = import_path97.default.join(workspace.rootDir, relPath2); + if (!(0, import_fs88.existsSync)(abs)) return void 0; + const body = (0, import_fs88.readFileSync)(abs, "utf8"); return body.length > MAX_MANIFEST_READ_BYTES ? body.slice(0, MAX_MANIFEST_READ_BYTES) : body; } catch { return void 0; @@ -114721,25 +116171,25 @@ function safeSeals(workspace) { } } function bootstrapDir(workspace) { - return assertInsideWorkspace(workspace.rootDir, import_path97.default.join(workspace.sidecarDir, "bootstrap")); + return assertInsideWorkspace(workspace.rootDir, import_path98.default.join(workspace.sidecarDir, "bootstrap")); } function snapshotFile(workspace) { return assertInsideWorkspace( workspace.rootDir, - import_path97.default.join(bootstrapDir(workspace), "current-system-snapshot.json") + import_path98.default.join(bootstrapDir(workspace), "current-system-snapshot.json") ); } function readCurrentSystemSnapshot(workspace) { const file = snapshotFile(workspace); - if (!(0, import_fs88.existsSync)(file)) return void 0; + if (!(0, import_fs89.existsSync)(file)) return void 0; try { - return currentSystemSnapshotSchema.parse(JSON.parse((0, import_fs88.readFileSync)(file, "utf8"))); + return currentSystemSnapshotSchema.parse(JSON.parse((0, import_fs89.readFileSync)(file, "utf8"))); } catch { return void 0; } } function persistSnapshot(workspace, snapshot2) { - (0, import_fs88.mkdirSync)(bootstrapDir(workspace), { recursive: true }); + (0, import_fs89.mkdirSync)(bootstrapDir(workspace), { recursive: true }); writeFileAtomic(snapshotFile(workspace), `${JSON.stringify(snapshot2, null, 2)} `); } @@ -114781,13 +116231,13 @@ function assessSnapshotFreshness2(workspace, snapshot2) { } return reasons.length === 0 ? { status: "FRESH", reasons: [] } : { status: "STALE", reasons }; } -function bootstrapWorkspace(deps3, options = {}) { - const workspace = deps3.workspace; +function bootstrapWorkspace(deps4, options = {}) { + const workspace = deps4.workspace; const resolution = resolveRepositories(workspace); const ensured = ensureRepositoryIndex({ workspace, - config: deps3.config, - now: nowIso6(deps3), + config: deps4.config, + now: nowIso6(deps4), // Bootstrap has no Git snapshot to name additions, so the refresh walks // for them: a snapshot that missed a brand-new capability file would // claim currency over a repository it has not actually seen. @@ -114837,12 +116287,12 @@ function bootstrapWorkspace(deps3, options = {}) { schemaVersion: BOOTSTRAP_SCHEMA_VERSION, snapshotId: `snap-${contentHash.slice(0, 12)}`, workspaceKey: workspaceKeyFor(workspace.rootDir), - createdAt: nowIso6(deps3), + createdAt: nowIso6(deps4), ...material, indexStats: { entries: ensured.state.entries.length, truncated: ensured.state.truncated, - skipped: Object.values(ensured.state.skippedCounts).reduce((sum, count3) => sum + count3, 0) + skipped: Object.values(ensured.state.skippedCounts).reduce((sum, count4) => sum + count4, 0) }, contentHash }); @@ -114855,32 +116305,32 @@ function bootstrapWorkspace(deps3, options = {}) { }; } function countIndexed(index, repositories, repo) { - let count3 = 0; + let count4 = 0; for (const entry2 of index.entries) { - if (repositoryOfPath(repositories, entry2.path)?.repositoryId === repo.repositoryId) count3 += 1; + if (repositoryOfPath(repositories, entry2.path)?.repositoryId === repo.repositoryId) count4 += 1; } - return count3; + return count4; } function readWorkspaceSnapshot(workspace) { const snapshot2 = readCurrentSystemSnapshot(workspace); return { snapshot: snapshot2, freshness: assessSnapshotFreshness2(workspace, snapshot2) }; } -function inspectWorkspace(deps3, options) { +function inspectWorkspace(deps4, options) { const question = options.question.trim(); if (question.length === 0 || question.length > 2e3) { throw new IntakeError("SBI018", "An inspection question must be 1\u20132000 characters."); } - const policy = deps3.config.orchestration.jobs.context.efficiency; + const policy = deps4.config.orchestration.jobs.context.efficiency; const maxSections = Math.min( Math.max(1, options.maxSections ?? 5), policy.maxSelectedItems ); - const workspace = deps3.workspace; + const workspace = deps4.workspace; const resolution = resolveRepositories(workspace); const ensured = ensureRepositoryIndex({ workspace, - config: deps3.config, - now: nowIso6(deps3) + config: deps4.config, + now: nowIso6(deps4) }); const query = buildRetrievalQuery({ taskId: "workspace-inspect", @@ -114912,7 +116362,7 @@ function inspectWorkspace(deps3, options) { } let body; try { - body = (0, import_fs88.readFileSync)( + body = (0, import_fs89.readFileSync)( assertInsideWorkspace(workspace.rootDir, entry2.path), "utf8" ); @@ -115221,20 +116671,20 @@ Examples: "Pass exactly one of --file, --text, or --stdin." ); } - const deps3 = intakeDeps(runtime); - const started = options.file !== void 0 ? startSpecIntakeFromFile(deps3, { + const deps4 = intakeDeps(runtime); + const started = options.file !== void 0 ? startSpecIntakeFromFile(deps4, { name, file: options.file, ...options.goal !== void 0 ? { goal: options.goal } : {}, ...options.specName !== void 0 ? { specName: options.specName } : {} - }) : startSpecIntake(deps3, { + }) : startSpecIntake(deps4, { name, kind: options.stdin === true ? "stdin" : "text", content: options.stdin === true ? readStdin() : options.text ?? "", ...options.goal !== void 0 ? { goal: options.goal } : {}, ...options.specName !== void 0 ? { specName: options.specName } : {} }); - const discovery = runIntakeDiscovery(deps3, started.intake.intakeId); + const discovery = runIntakeDiscovery(deps4, started.intake.intakeId); if (options.json === true) { jsonOut(runtime, "spec-intake-start/v1", { intake: intakeSummary(discovery.intake), @@ -115277,9 +116727,9 @@ Examples: } ); spec.command("discover ").description("Re-run repository-grounded discovery and show the open product questions").option("--json", "machine-readable output").action((name, options) => { - const deps3 = intakeDeps(runtime); - const intake = requireIntakeFor(deps3, name); - const discovery = runIntakeDiscovery(deps3, intake.intakeId); + const deps4 = intakeDeps(runtime); + const intake = requireIntakeFor(deps4, name); + const discovery = runIntakeDiscovery(deps4, intake.intakeId); if (options.json === true) { jsonOut(runtime, "spec-intake-discover/v1", { intake: intakeSummary(discovery.intake), @@ -115311,7 +116761,7 @@ Examples: renderDiscovery(runtime, discovery); runtime.out(""); if (discovery.readiness.ready) { - const overview = describeIntake(deps3, intake.intakeId); + const overview = describeIntake(deps4, intake.intakeId); if (overview.summary !== void 0) renderSummary(runtime, overview.summary); runtime.out(""); runtime.out(okLine("Specification ready.")); @@ -115323,9 +116773,9 @@ Examples: }); spec.command("answer ").description("Record your answer to one open product question").option("--json", "machine-readable output").action( (name, questionId, answerWords, options) => { - const deps3 = intakeDeps(runtime); - const intake = requireIntakeFor(deps3, name); - const result = answerIntakeQuestion(deps3, intake.intakeId, { + const deps4 = intakeDeps(runtime); + const intake = requireIntakeFor(deps4, name); + const result = answerIntakeQuestion(deps4, intake.intakeId, { questionId, answer: answerWords.join(" ") }); @@ -115347,7 +116797,7 @@ Examples: } if (result.discovery.readiness.ready) { runtime.out(""); - const overview = describeIntake(deps3, intake.intakeId); + const overview = describeIntake(deps4, intake.intakeId); if (overview.summary !== void 0) renderSummary(runtime, overview.summary); runtime.out(""); runtime.out(okLine("Specification ready.")); @@ -115359,9 +116809,9 @@ Examples: ); spec.command("intake [name]").description("Inspect spec intakes; with --resume, continue an interrupted build").option("--resume", "continue the seal-and-build lifecycle idempotently").option("--no-launch", "with --resume, stop after creating the job").option("--json", "machine-readable output").action( async (name, options) => { - const deps3 = intakeDeps(runtime); + const deps4 = intakeDeps(runtime); if (name === void 0) { - const listed = listSpecIntakes(deps3); + const listed = listSpecIntakes(deps4); if (options.json === true) { jsonOut(runtime, "spec-intake-list/v1", { intakes: listed.intakes.map(intakeSummary), @@ -115385,17 +116835,17 @@ Examples: for (const diagnostic of listed.diagnostics) runtime.out(warnLine(diagnostic.message)); return; } - const intake = requireIntakeFor(deps3, name); + const intake = requireIntakeFor(deps4, name); if (options.resume === true) { - await runBuild(runtime, deps3, intake.intakeId, { + await runBuild(runtime, deps4, intake.intakeId, { launch: options.launch !== false, json: options.json === true, subject: name }); return; } - const overview = describeIntake(deps3, intake.intakeId); - const telemetry = computeIntakeTelemetry(deps3, intake.intakeId); + const overview = describeIntake(deps4, intake.intakeId); + const telemetry = computeIntakeTelemetry(deps4, intake.intakeId); if (options.json === true) { jsonOut(runtime, "spec-intake-show/v1", { ...overviewJson(overview), @@ -115434,19 +116884,19 @@ Examples: } ); spec.command("abandon-intake ").description("Abandon a spec intake (final; the record stays readable)").requiredOption("--reason ").action((name, options) => { - const deps3 = intakeDeps(runtime); - const intake = requireIntakeFor(deps3, name); - const abandoned = abandonIntake(deps3, intake.intakeId, options.reason); + const deps4 = intakeDeps(runtime); + const intake = requireIntakeFor(deps4, name); + const abandoned = abandonIntake(deps4, intake.intakeId, options.reason); runtime.out(okLine(`Spec intake ${abandoned.intakeId} is ${abandoned.status}.`)); }); } async function runApproveAndBuild(runtime, name, options) { - const deps3 = intakeDeps(runtime); - const intake = requireIntakeFor(deps3, name); + const deps4 = intakeDeps(runtime); + const intake = requireIntakeFor(deps4, name); const lanes = (options.lanes ?? "LOCAL,SUBSCRIPTION").split(",").map((lane) => lane.trim().toUpperCase()).filter( (lane) => lane === "LOCAL" || lane === "SUBSCRIPTION" || lane === "API" ); - const approved = approveIntake(deps3, { + const approved = approveIntake(deps4, { intakeId: intake.intakeId, via: "cli", maxApiSpendUsd: options.maxSpend !== void 0 ? Number(options.maxSpend) : null, @@ -115462,16 +116912,16 @@ async function runApproveAndBuild(runtime, name, options) { runtime.out(dim2("Everything from here is unattended.")); runtime.out(""); } - await runBuild(runtime, deps3, intake.intakeId, { + await runBuild(runtime, deps4, intake.intakeId, { launch: options.launch, json: options.json === true, subject: name, ...options.maxCycles !== void 0 ? { maxCycles: Number(options.maxCycles) } : {} }); } -async function runBuild(runtime, deps3, intakeId, options) { +async function runBuild(runtime, deps4, intakeId, options) { const context = loadExecutionContext(runtime); - const result = await runSealAndBuild(deps3, { + const result = await runSealAndBuild(deps4, { intakeId, launch: options.launch, // A FACTORY, because the deps the driver runs under are not known until @@ -115487,13 +116937,13 @@ async function runBuild(runtime, deps3, intakeId, options) { if (!options.json) runtime.out(dim2(` ${event.kind}: ${event.message}`)); } }); - recordFeatureOutcome(deps3, intakeId, { + recordFeatureOutcome(deps4, intakeId, { ...result.lifecycle.sealId !== void 0 ? { sealId: result.lifecycle.sealId } : {}, ...result.lifecycle.specName !== void 0 ? { specName: result.lifecycle.specName } : {}, ...result.lifecycle.jobId !== void 0 ? { jobId: result.lifecycle.jobId } : {}, outcome: result.outcome }); - const telemetry = computeIntakeTelemetry(deps3, intakeId); + const telemetry = computeIntakeTelemetry(deps4, intakeId); if (options.json) { jsonOut(runtime, "spec-intake-build/v1", { intakeId, @@ -116147,7 +117597,7 @@ Examples: throw new SpecBridgeError("INVALID_ARGUMENT", "--dry-run plans a single task; combine it with --task or --next."); } const context = loadExecutionContext(runtime); - const deps3 = { + const deps4 = { workspace: context.workspace, config: context.config, registry: context.registry, @@ -116167,7 +117617,7 @@ Examples: ...options.verify === false ? { noVerify: true } : {} }; if (options.all === true) { - const summary = await runAllOpenTasks(deps3, shared); + const summary = await runAllOpenTasks(deps4, shared); runtime.exitCode = summary.exitCode; if (options.json === true) { runtime.outRaw( @@ -116197,7 +117647,7 @@ Examples: } return; } - const outcome = await runApprovedTask(deps3, { + const outcome = await runApprovedTask(deps4, { ...shared, ...options.task !== void 0 ? { taskId: options.task } : { next: true }, ...options.dryRun === true ? { dryRun: true } : {} @@ -118737,8 +120187,8 @@ function selectedFamilies(options) { function countsByStatus(findings2) { const counts = {}; for (const status of STATUS_ORDER) { - const count3 = findings2.filter((candidate) => candidate.status === status).length; - if (count3 > 0) counts[status] = count3; + const count4 = findings2.filter((candidate) => candidate.status === status).length; + if (count4 > 0) counts[status] = count4; } return counts; } @@ -118824,8 +120274,8 @@ Examples: } printFindings(runtime, findings2); runtime.out(sectionTitle("Summary")); - for (const [status, count3] of Object.entries(counts)) { - runtime.out(statusLine(status)(`${status}: ${count3}`)); + for (const [status, count4] of Object.entries(counts)) { + runtime.out(statusLine(status)(`${status}: ${count4}`)); } runtime.out(); if (healthy) { @@ -119550,12 +121000,12 @@ Examples: }); } -// ../../packages/mcp-server/dist/chunk-U6N2BU4S.js +// ../../packages/mcp-server/dist/chunk-XJ3HVTHJ.js var import_buffer7 = require("buffer"); -var import_fs89 = require("fs"); -var import_path98 = __toESM(require("path"), 1); -var import_crypto31 = require("crypto"); +var import_fs90 = require("fs"); var import_path99 = __toESM(require("path"), 1); +var import_crypto31 = require("crypto"); +var import_path100 = __toESM(require("path"), 1); // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v4/core/core.js var NEVER2 = Object.freeze({ @@ -120271,7 +121721,7 @@ var ulid = /^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$/; var xid = /^[0-9a-vA-V]{20}$/; var ksuid = /^[A-Za-z0-9]{27}$/; var nanoid = /^[a-zA-Z0-9_-]{21}$/; -var duration = /^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/; +var duration2 = /^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/; var guid = /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/; var uuid = (version2) => { if (!version2) @@ -120980,7 +122430,7 @@ var $ZodISOTime = /* @__PURE__ */ $constructor("$ZodISOTime", (inst, def) => { $ZodStringFormat.init(inst, def); }); var $ZodISODuration = /* @__PURE__ */ $constructor("$ZodISODuration", (inst, def) => { - def.pattern ?? (def.pattern = duration); + def.pattern ?? (def.pattern = duration2); $ZodStringFormat.init(inst, def); }); var $ZodIPv4 = /* @__PURE__ */ $constructor("$ZodIPv4", (inst, def) => { @@ -123559,7 +125009,7 @@ __export(iso_exports2, { ZodISOTime: () => ZodISOTime, date: () => date2, datetime: () => datetime2, - duration: () => duration2, + duration: () => duration3, time: () => time2 }); var ZodISODateTime = /* @__PURE__ */ $constructor("ZodISODateTime", (inst, def) => { @@ -123587,7 +125037,7 @@ var ZodISODuration = /* @__PURE__ */ $constructor("ZodISODuration", (inst, def) $ZodISODuration.init(inst, def); ZodStringFormat.init(inst, def); }); -function duration2(params) { +function duration3(params) { return _isoDuration(ZodISODuration, params); } @@ -123749,7 +125199,7 @@ var ZodString2 = /* @__PURE__ */ $constructor("ZodString", (inst, def) => { inst.datetime = (params) => inst.check(datetime2(params)); inst.date = (params) => inst.check(date2(params)); inst.time = (params) => inst.check(time2(params)); - inst.duration = (params) => inst.check(duration2(params)); + inst.duration = (params) => inst.check(duration3(params)); }); function string2(params) { return _string(ZodString2, params); @@ -129882,13 +131332,13 @@ var EMPTY_COMPLETION_RESULT = { } }; -// ../../packages/mcp-server/dist/chunk-U6N2BU4S.js -var import_fs90 = require("fs"); +// ../../packages/mcp-server/dist/chunk-XJ3HVTHJ.js var import_fs91 = require("fs"); -var import_path100 = __toESM(require("path"), 1); var import_fs92 = require("fs"); -var import_os3 = __toESM(require("os"), 1); var import_path101 = __toESM(require("path"), 1); +var import_fs93 = require("fs"); +var import_os3 = __toESM(require("os"), 1); +var import_path102 = __toESM(require("path"), 1); // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js var import_node_process11 = __toESM(require("process"), 1); @@ -129982,7 +131432,7 @@ var StdioServerTransport = class { } }; -// ../../packages/mcp-server/dist/chunk-U6N2BU4S.js +// ../../packages/mcp-server/dist/chunk-XJ3HVTHJ.js var MCP_SERVER_NAME = "specbridge"; var MCP_SERVER_VERSION = "1.1.0"; var MCP_SERVER_TITLE = "SpecBridge"; @@ -130347,10 +131797,10 @@ function validateProjectRoot(value, source, cwd) { remediation: ["Pass a plain filesystem path as --project-root."] }; } - const resolved2 = import_path98.default.resolve(cwd, value); + const resolved2 = import_path99.default.resolve(cwd, value); let canonical; try { - canonical = (0, import_fs89.realpathSync)(resolved2); + canonical = (0, import_fs90.realpathSync)(resolved2); } catch { return { ok: false, @@ -130363,7 +131813,7 @@ function validateProjectRoot(value, source, cwd) { } let stats; try { - stats = (0, import_fs89.statSync)(canonical); + stats = (0, import_fs90.statSync)(canonical); } catch { return { ok: false, @@ -130620,8 +132070,8 @@ var paginationShape = external_exports.object({ nextCursor: external_exports.string().optional() }); function repoRelative2(workspace, target) { - const relative = import_path99.default.isAbsolute(target) ? import_path99.default.relative(workspace.rootDir, target) : target; - const posix = relative.split(import_path99.default.sep).join("/"); + const relative = import_path100.default.isAbsolute(target) ? import_path100.default.relative(workspace.rootDir, target) : target; + const posix = relative.split(import_path100.default.sep).join("/"); return posix === "" ? "." : posix; } function toDiagnosticView(workspace, diagnostic) { @@ -131121,7 +132571,7 @@ function registerRunResources(server, context) { throw resourceNotFound(`Run "${runId}"`, "List runs with the run_list tool."); } const directory = runDir(workspace, record5.runId); - const artifactNames = (0, import_fs90.existsSync)(directory) ? (0, import_fs90.readdirSync)(directory).filter((name) => !REDACTED_ARTIFACTS.has(name)).sort((a2, b) => a2.localeCompare(b, "en")) : []; + const artifactNames = (0, import_fs91.existsSync)(directory) ? (0, import_fs91.readdirSync)(directory).filter((name) => !REDACTED_ARTIFACTS.has(name)).sort((a2, b) => a2.localeCompare(b, "en")) : []; return jsonContents(context, uri.href, buildRunDetail(workspace, record5, artifactNames)); } ); @@ -132731,8 +134181,8 @@ function registerTaskCompleteTool(server, context) { handler: async (args, extras) => context.withWriteLock(async () => { assertInputSize("summary", args.summary, LIMITS.maximumShortTextChars); const workspace = context.requireWorkspace(); - const deps3 = { ...interactiveDeps(context, workspace), signal: extras.signal }; - const outcome = await completeInteractiveTask(deps3, { + const deps4 = { ...interactiveDeps(context, workspace), signal: extras.signal }; + const outcome = await completeInteractiveTask(deps4, { runId: args.runId, summary: args.summary, ...args.runVerification !== void 0 ? { runVerification: args.runVerification } : {}, @@ -132937,7 +134387,7 @@ function registerRunReadTool(server, context) { }); } const directory = runDir(workspace, record5.runId); - const artifactNames = (0, import_fs91.existsSync)(directory) ? (0, import_fs91.readdirSync)(directory).filter((name) => !REDACTED_ARTIFACTS2.has(name)).sort((a2, b) => a2.localeCompare(b, "en")) : []; + const artifactNames = (0, import_fs92.existsSync)(directory) ? (0, import_fs92.readdirSync)(directory).filter((name) => !REDACTED_ARTIFACTS2.has(name)).sort((a2, b) => a2.localeCompare(b, "en")) : []; const detail = buildRunDetail(workspace, record5, artifactNames); const lines = [ `Run ${detail.summary.runId} \u2014 ${detail.summary.runType} for spec "${detail.summary.specName}"${detail.summary.taskId !== void 0 ? `, task ${detail.summary.taskId}` : ""}.`, @@ -133297,7 +134747,7 @@ function registerSpecRunVerificationTool(server, context) { durationMs: command.durationMs, timedOut: command.timedOut })); - const reportPath = result.artifactsDir !== void 0 ? import_path100.default.relative(workspace.rootDir, result.artifactsDir).split(import_path100.default.sep).join("/") : void 0; + const reportPath = result.artifactsDir !== void 0 ? import_path101.default.relative(workspace.rootDir, result.artifactsDir).split(import_path101.default.sep).join("/") : void 0; const commandLines = commands.map( (command) => `- ${command.name}: ${command.disposition}${command.disposition === "executed" ? command.passed ? " (passed)" : ` (FAILED, exit ${command.exitCode ?? "none"})` : ""}` ); @@ -133416,18 +134866,18 @@ var conformanceSummaryShape = external_exports.object({ note: external_exports.string() }); async function invocationFreeConformanceSummary(profile) { - const scratch = (0, import_fs92.mkdtempSync)(import_path101.default.join(import_os3.default.tmpdir(), "specbridge-mcp-conformance-")); + const scratch = (0, import_fs93.mkdtempSync)(import_path102.default.join(import_os3.default.tmpdir(), "specbridge-mcp-conformance-")); let result; try { result = await runRunnerConformance({ profile, workspaceRoot: scratch, - runDir: import_path101.default.join(scratch, ".specbridge-conformance-runs"), + runDir: import_path102.default.join(scratch, ".specbridge-conformance-runs"), invocationsAllowed: false, timeoutMs: RUNNER_PROBE_TIMEOUT_MS }); } finally { - (0, import_fs92.rmSync)(scratch, { recursive: true, force: true }); + (0, import_fs93.rmSync)(scratch, { recursive: true, force: true }); } return { passed: result.passed, @@ -134483,7 +135933,7 @@ function orchestrationDeps(context, workspace) { }; } var orchestrationIdArg = external_exports.string().min(1).max(64).describe("Orchestration run id returned by orchestration_begin"); -var boundedText6 = (max) => external_exports.string().min(1).max(max); +var boundedText7 = (max) => external_exports.string().min(1).max(max); var stateSummaryShape = { orchestrationId: external_exports.string(), specName: external_exports.string(), @@ -134569,7 +136019,7 @@ function registerOrchestrationStatusTool(server, context) { }, handler: async (args) => { const workspace = context.requireWorkspace(); - const deps3 = orchestrationDeps(context, workspace); + const deps4 = orchestrationDeps(context, workspace); if (args.orchestrationId === void 0) { const listed = listOrchestrationRuns(workspace); const latest = listed.runs[0]; @@ -134604,7 +136054,7 @@ function registerOrchestrationStatusTool(server, context) { } }; } - const report = await resumeOrchestration(deps3, args.orchestrationId); + const report = await resumeOrchestration(deps4, args.orchestrationId); const detail = describeOrchestration(workspace, report.state, { eventLimit: args.eventLimit ?? 20 }); @@ -134654,7 +136104,7 @@ function registerOrchestrationBeginTool(server, context) { }, inputSchema: { specName: specNameArg, - goal: boundedText6(4e3).describe( + goal: boundedText7(4e3).describe( "The user's stated goal, verbatim. Recorded as data, never executed as instructions." ), taskId: external_exports.string().max(64).optional().describe("Target task, when the user named one") @@ -134667,8 +136117,8 @@ function registerOrchestrationBeginTool(server, context) { }, handler: async (args) => context.withWriteLock(async () => { const workspace = context.requireWorkspace(); - const deps3 = orchestrationDeps(context, workspace); - const state = beginOrchestration(deps3, { + const deps4 = orchestrationDeps(context, workspace); + const state = beginOrchestration(deps4, { specName: args.specName, goal: args.goal, ...args.taskId !== void 0 ? { taskId: args.taskId } : {} @@ -134717,11 +136167,11 @@ function registerOrchestrationAssessIntentTool(server, context) { inputSchema: { orchestrationId: orchestrationIdArg, outcome: external_exports.enum(INTENT_OUTCOMES).describe("Your assessment; SpecBridge may override it"), - summary: boundedText6(2e3).describe("One-line restatement of the user's request"), - reasons: external_exports.array(boundedText6(2e3)).max(20).optional(), + summary: boundedText7(2e3).describe("One-line restatement of the user's request"), + reasons: external_exports.array(boundedText7(2e3)).max(20).optional(), provenance: external_exports.array( external_exports.object({ - fact: boundedText6(2e3), + fact: boundedText7(2e3), source: external_exports.enum(PROVENANCE_KINDS), reference: external_exports.string().max(512).optional() }) @@ -134739,8 +136189,8 @@ function registerOrchestrationAssessIntentTool(server, context) { }, handler: async (args) => context.withWriteLock(async () => { const workspace = context.requireWorkspace(); - const deps3 = orchestrationDeps(context, workspace); - const result = assessIntent(deps3, args.orchestrationId, { + const deps4 = orchestrationDeps(context, workspace); + const result = assessIntent(deps4, args.orchestrationId, { outcome: args.outcome, summary: args.summary, ...args.reasons !== void 0 ? { reasons: args.reasons } : {}, @@ -134784,11 +136234,11 @@ function registerOrchestrationClarifyTool(server, context) { orchestrationId: orchestrationIdArg, questions: external_exports.array( external_exports.object({ - question: boundedText6(1024), - whyItMatters: boundedText6(1024).describe( + question: boundedText7(1024), + whyItMatters: boundedText7(1024).describe( "What the answer changes about the implementation. Required." ), - options: external_exports.array(boundedText6(512)).max(10).optional(), + options: external_exports.array(boundedText7(512)).max(10).optional(), relatedTaskId: external_exports.string().max(64).optional() }) ).min(1).max(20) @@ -134800,9 +136250,9 @@ function registerOrchestrationClarifyTool(server, context) { }, handler: async (args) => context.withWriteLock(async () => { const workspace = context.requireWorkspace(); - const deps3 = orchestrationDeps(context, workspace); + const deps4 = orchestrationDeps(context, workspace); const state = requestClarification( - deps3, + deps4, args.orchestrationId, args.questions.map((question) => ({ question: question.question, @@ -134845,9 +136295,9 @@ function registerOrchestrationResolveClarificationTool(server, context) { decisions: external_exports.array( external_exports.object({ questionId: external_exports.string().min(1).max(64), - answer: boundedText6(4096), + answer: boundedText7(4096), source: external_exports.enum(PROVENANCE_KINDS).describe("Use known-from-user for a direct answer from the user"), - impact: boundedText6(2e3).optional().describe("What this changes about the build"), + impact: boundedText7(2e3).optional().describe("What this changes about the build"), supersedes: external_exports.string().max(64).optional() }) ).min(1).max(20) @@ -134860,9 +136310,9 @@ function registerOrchestrationResolveClarificationTool(server, context) { }, handler: async (args) => context.withWriteLock(async () => { const workspace = context.requireWorkspace(); - const deps3 = orchestrationDeps(context, workspace); + const deps4 = orchestrationDeps(context, workspace); const result = resolveClarification( - deps3, + deps4, args.orchestrationId, args.decisions.map((decision) => ({ questionId: decision.questionId, @@ -134908,26 +136358,26 @@ function registerOrchestrationSubmitPlanTool(server, context) { inputSchema: { orchestrationId: orchestrationIdArg, taskId: external_exports.string().min(1).max(64).describe("The approved task this plan implements"), - goal: boundedText6(2e3), + goal: boundedText7(2e3), steps: external_exports.array( external_exports.object({ id: external_exports.string().max(64).optional(), - description: boundedText6(2e3), + description: boundedText7(2e3), expectedAreas: external_exports.array(external_exports.string().max(512)).max(20).optional(), - expectedEvidence: boundedText6(2e3).optional() + expectedEvidence: boundedText7(2e3).optional() }) ).min(1).max(200), - testStrategy: boundedText6(2e3), - verificationStrategy: boundedText6(2e3), - nonGoals: external_exports.array(boundedText6(2e3)).max(50).optional(), - constraints: external_exports.array(boundedText6(2e3)).max(50).optional(), - relevantEvidence: external_exports.array(boundedText6(2e3)).max(50).optional(), - assumptions: external_exports.array(boundedText6(2e3)).max(50).optional().describe("Labelled assumptions. Planning information, never presented as facts."), - openQuestions: external_exports.array(boundedText6(2e3)).max(50).optional(), + testStrategy: boundedText7(2e3), + verificationStrategy: boundedText7(2e3), + nonGoals: external_exports.array(boundedText7(2e3)).max(50).optional(), + constraints: external_exports.array(boundedText7(2e3)).max(50).optional(), + relevantEvidence: external_exports.array(boundedText7(2e3)).max(50).optional(), + assumptions: external_exports.array(boundedText7(2e3)).max(50).optional().describe("Labelled assumptions. Planning information, never presented as facts."), + openQuestions: external_exports.array(boundedText7(2e3)).max(50).optional(), expectedAreas: external_exports.array(external_exports.string().max(512)).max(50).optional().describe("Expected implementation areas. Planning information, not a prediction of fact."), - rollbackConsiderations: boundedText6(2e3).optional(), - replanTriggers: external_exports.array(boundedText6(2e3)).max(50).optional(), - replanReason: boundedText6(2e3).optional().describe("Required in spirit when replacing a plan") + rollbackConsiderations: boundedText7(2e3).optional(), + replanTriggers: external_exports.array(boundedText7(2e3)).max(50).optional(), + replanReason: boundedText7(2e3).optional().describe("Required in spirit when replacing a plan") }, outputSchema: { ...stateSummaryShape, @@ -134941,8 +136391,8 @@ function registerOrchestrationSubmitPlanTool(server, context) { }, handler: async (args) => context.withWriteLock(async () => { const workspace = context.requireWorkspace(); - const deps3 = orchestrationDeps(context, workspace); - const result = await submitPlan(deps3, args.orchestrationId, { + const deps4 = orchestrationDeps(context, workspace); + const result = await submitPlan(deps4, args.orchestrationId, { taskId: args.taskId, goal: args.goal, steps: args.steps.map((step2) => ({ @@ -135017,13 +136467,13 @@ function registerOrchestrationReviewPlanTool(server, context) { orchestrationId: orchestrationIdArg, planHash: external_exports.string().min(1).max(64).describe("Exact planHash from orchestration_submit_plan"), decision: external_exports.enum(["approved", "rejected"]).describe("The user's decision, not yours"), - note: boundedText6(2e3).optional() + note: boundedText7(2e3).optional() }, outputSchema: { ...stateSummaryShape, decision: external_exports.string(), planRevision: external_exports.number().int() }, handler: async (args) => context.withWriteLock(async () => { const workspace = context.requireWorkspace(); - const deps3 = orchestrationDeps(context, workspace); - const state = reviewPlan(deps3, args.orchestrationId, { + const deps4 = orchestrationDeps(context, workspace); + const state = reviewPlan(deps4, args.orchestrationId, { planHash: args.planHash, decision: args.decision, ...args.note !== void 0 ? { note: args.note } : {}, @@ -135054,15 +136504,15 @@ function registerOrchestrationRecordActionTool(server, context) { inputSchema: { orchestrationId: orchestrationIdArg, action: external_exports.enum(ACTION_CATEGORIES), - target: boundedText6(512).describe("What the action targeted: a path, a verifier, a step"), + target: boundedText7(512).describe("What the action targeted: a path, a verifier, a step"), result: external_exports.enum(OBSERVATION_RESULTS), planStepId: external_exports.string().max(64).optional(), - expectedEvidence: boundedText6(2e3).optional(), + expectedEvidence: boundedText7(2e3).optional(), changedFiles: external_exports.array(external_exports.object({ path: external_exports.string().max(1024), contentHash: external_exports.string().max(128).optional() })).max(500).optional().describe("Observed changes. Claims: the completion gate re-derives them from Git."), failure: external_exports.object({ category: external_exports.enum(FAILURE_CATEGORIES), - message: boundedText6(2e3), - source: boundedText6(512).describe("Verifier name, tool, or step that failed"), + message: boundedText7(2e3), + source: boundedText7(512).describe("Verifier name, tool, or step that failed"), exitCode: external_exports.number().int().optional(), output: external_exports.string().max(16384).optional().describe("Normalized before fingerprinting") }).optional(), @@ -135083,8 +136533,8 @@ function registerOrchestrationRecordActionTool(server, context) { }, handler: async (args) => context.withWriteLock(async () => { const workspace = context.requireWorkspace(); - const deps3 = orchestrationDeps(context, workspace); - const result = await recordActionChecked(deps3, args.orchestrationId, { + const deps4 = orchestrationDeps(context, workspace); + const result = await recordActionChecked(deps4, args.orchestrationId, { action: args.action, target: args.target, result: args.result, @@ -135132,9 +136582,9 @@ function registerOrchestrationCheckpointTool(server, context) { }, inputSchema: { orchestrationId: orchestrationIdArg, - nextAction: boundedText6(2e3).describe("The exact next safe action, in one line"), - observations: external_exports.array(boundedText6(2e3)).max(50).optional(), - latestVerifier: boundedText6(2e3).optional() + nextAction: boundedText7(2e3).describe("The exact next safe action, in one line"), + observations: external_exports.array(boundedText7(2e3)).max(50).optional(), + latestVerifier: boundedText7(2e3).optional() }, outputSchema: { orchestrationId: external_exports.string(), @@ -135147,8 +136597,8 @@ function registerOrchestrationCheckpointTool(server, context) { }, handler: async (args) => context.withWriteLock(async () => { const workspace = context.requireWorkspace(); - const deps3 = orchestrationDeps(context, workspace); - const checkpoint = createCheckpoint(deps3, args.orchestrationId, { + const deps4 = orchestrationDeps(context, workspace); + const checkpoint = createCheckpoint(deps4, args.orchestrationId, { nextAction: args.nextAction, ...args.observations !== void 0 ? { observations: args.observations } : {}, ...args.latestVerifier !== void 0 ? { latestVerifier: args.latestVerifier } : {} @@ -135182,15 +136632,15 @@ function registerOrchestrationFinalizeTool(server, context) { inputSchema: { orchestrationId: orchestrationIdArg, outcome: external_exports.enum(["completed", "aborted", "cancelled"]), - reason: boundedText6(2e3), + reason: boundedText7(2e3), evidenceStatus: external_exports.string().max(64).optional().describe("The evidenceStatus task_complete actually returned. Required for completion."), interactiveRunId: external_exports.string().max(64).optional() }, outputSchema: { ...stateSummaryShape, finalOutcome: external_exports.string(), finalizedAt: external_exports.string().optional() }, handler: async (args) => context.withWriteLock(async () => { const workspace = context.requireWorkspace(); - const deps3 = orchestrationDeps(context, workspace); - const state = finalizeOrchestration(deps3, args.orchestrationId, { + const deps4 = orchestrationDeps(context, workspace); + const state = finalizeOrchestration(deps4, args.orchestrationId, { outcome: args.outcome, reason: args.reason, ...args.evidenceStatus !== void 0 ? { evidenceStatus: args.evidenceStatus } : {}, @@ -135408,6 +136858,56 @@ function registerJobCancelTool(server, context) { } }); } +function percent2(value) { + return value === null ? "n/a" : `${(value * 100).toFixed(1)}%`; +} +function registerJobReportTool(server, context) { + registerDefinedTool(server, context, { + name: "job_report", + title: "Read a Job execution report", + description: "Derive versioned operational and token-conservation telemetry from durable Job, WorkUnit, attempt, research, cooldown, verification, and closure records. Read-only; metrics never grant completion or authority.", + annotations: { + readOnlyHint: true, + destructiveHint: false, + idempotentHint: true, + openWorldHint: false + }, + inputSchema: { + jobId: external_exports.string().min(1).max(64).describe("Job id (job-\u2026) from job_list") + }, + outputSchema: { + report: executionTelemetryReportSchema + }, + handler: async (args) => { + const workspace = context.requireWorkspace(); + const deps4 = { + workspace, + config: requireAgentConfig(workspace), + clock: context.clock, + idFactory: context.idFactory, + host: "mcp" + }; + const report = computeExecutionTelemetryReport(deps4, args.jobId, { + persist: false, + specbridgeVersion: MCP_SERVER_VERSION + }); + const summary = report.qualificationSummary; + return { + text: [ + `Job ${report.jobId}: ${report.outcome.status} (${report.outcome.authoritativeJobStatus})`, + `StrongBuilderAvoidanceRatio: ${percent2(summary.strongBuilderAvoidanceRatio)}`, + `Secondary initial/repair: ${percent2(summary.secondaryInitialSuccessRate)} / ${percent2(summary.secondaryRepairRecoveryRate)}`, + `ResearchAvoidanceRatio: ${percent2(summary.researchAvoidanceRatio)}`, + `UsefulWorkDuringSubscriptionCooldown: ${summary.usefulWorkDuringSubscriptionCooldown}`, + `humanInterventionsAfterSeal: ${summary.humanInterventionsAfterSeal}`, + `CompletedWorkRedoCount: ${summary.completedWorkRedoCount}`, + `Verification / closure: ${report.outcome.verification} / ${report.outcome.closure}` + ].join("\n"), + structured: { report } + }; + } + }); +} function missionDeps(context, workspace) { return { workspace, @@ -135499,14 +136999,14 @@ function registerMissionReadTool(server, context) { }, handler: async (args) => { const workspace = context.requireWorkspace(); - const deps3 = missionDeps(context, workspace); - observeSpecApproval(deps3, args.missionId); + const deps4 = missionDeps(context, workspace); + observeSpecApproval(deps4, args.missionId); const view = args.view ?? "overview"; const limit = args.limit ?? 50; let records = []; switch (view) { case "overview": { - const overview = describeMission(deps3, args.missionId); + const overview = describeMission(deps4, args.missionId); records = [ { goal: overview.mission.goal, @@ -135818,9 +137318,9 @@ function registerMissionSynthesizeTool(server, context) { }, handler: async (args) => { const workspace = context.requireWorkspace(); - const deps3 = missionDeps(context, workspace); - markContractReady(deps3, args.missionId); - const result = synthesizeMissionSpec(deps3, args.missionId, { specName: args.specName }); + const deps4 = missionDeps(context, workspace); + markContractReady(deps4, args.missionId); + const result = synthesizeMissionSpec(deps4, args.missionId, { specName: args.specName }); return { text: `Synthesized spec "${result.specName}" with ${result.objectiveCount} objective(s). The user approves it with: specbridge spec approve ${result.specName} --stage requirements|design|tasks.`, structured: { @@ -136029,14 +137529,14 @@ function registerSpecIntakeStartTool(server, context) { }, handler: async (args) => { const workspace = context.requireWorkspace(); - const deps3 = intakeDeps2(context, workspace); - const started = startSpecIntake(deps3, { + const deps4 = intakeDeps2(context, workspace); + const started = startSpecIntake(deps4, { name: args.name, kind: "text", content: args.specification, ...args.goal !== void 0 ? { goal: args.goal } : {} }); - const discovery = runIntakeDiscovery(deps3, started.intake.intakeId); + const discovery = runIntakeDiscovery(deps4, started.intake.intakeId); const open = discovery.questions.filter((question) => question.status === "open"); return { text: `Spec intake ${started.intake.intakeId} created for "${args.name}". ${started.source.chunks.length} section(s) ingested. ` + (discovery.readiness.ready ? `No product question is open; the specification is ready for the human approval (\`specbridge spec approve ${args.name} --build\`).` : `${open.length} product question(s) need the user's decision.`), @@ -136089,9 +137589,9 @@ function registerSpecIntakeReadTool(server, context) { }, handler: async (args) => { const workspace = context.requireWorkspace(); - const deps3 = intakeDeps2(context, workspace); + const deps4 = intakeDeps2(context, workspace); if (args.subject === void 0) { - const listed = listSpecIntakes(deps3); + const listed = listSpecIntakes(deps4); const all = { intakes: listed.intakes.map((intake) => summarize22(workspace, context, intake.intakeId)) }; @@ -136100,8 +137600,8 @@ function registerSpecIntakeReadTool(server, context) { structured: all }; } - const resolved2 = requireIntakeFor(deps3, args.subject); - const overview = describeIntake(deps3, resolved2.intakeId); + const resolved2 = requireIntakeFor(deps4, args.subject); + const overview = describeIntake(deps4, resolved2.intakeId); const structured = { intake: summarize22(workspace, context, resolved2.intakeId) }; @@ -136180,9 +137680,9 @@ function registerSpecIntakeAnswerTool(server, context) { }, handler: async (args) => { const workspace = context.requireWorkspace(); - const deps3 = intakeDeps2(context, workspace); - const resolved2 = requireIntakeFor(deps3, args.subject); - const result = answerIntakeQuestion(deps3, resolved2.intakeId, { + const deps4 = intakeDeps2(context, workspace); + const resolved2 = requireIntakeFor(deps4, args.subject); + const result = answerIntakeQuestion(deps4, resolved2.intakeId, { questionId: args.questionId, answer: args.answer }); @@ -136924,9 +138424,9 @@ function registerResearchProviderStatusTool(server, context) { health: researchProviderHealthSchema }, handler: async (_args, extras) => { - const deps3 = serviceDeps(context); - const health = await getResearchProviderHealth(deps3, extras.signal); - const policy = deps3.config.research; + const deps4 = serviceDeps(context); + const health = await getResearchProviderHealth(deps4, extras.signal); + const policy = deps4.config.research; const providerEnabled2 = policy.provider === "deerflow" && policy.providers.deerflow.enabled; return { text: `Research ${policy.enabled ? "enabled" : "disabled"}; ${health.provider} health: ${health.status}.`, @@ -136985,6 +138485,7 @@ var TOOL_CATALOG = [ { name: "orchestration_finalize", readOnly: false, summary: "Close a run (completion needs verified evidence)" }, { name: "job_list", readOnly: true, summary: "List long-running orchestration jobs" }, { name: "job_read", readOnly: true, summary: "One job in depth: graph, attempts, questions, checkpoint" }, + { name: "job_report", readOnly: true, summary: "Durable Job operational and token-conservation report" }, { name: "job_cancel", readOnly: false, summary: "Cancel a job (final, idempotent, evidence preserved)" }, { name: "mission_begin", readOnly: false, summary: "Begin Mission Discovery from a product direction" }, { name: "mission_status", readOnly: true, summary: "List missions with lifecycle status and readiness" }, @@ -137071,6 +138572,7 @@ function registerAllTools(server, context) { registerOrchestrationFinalizeTool(server, context); registerJobListTool(server, context); registerJobReadTool(server, context); + registerJobReportTool(server, context); registerJobCancelTool(server, context); registerMissionBeginTool(server, context); registerMissionStatusTool(server, context); @@ -137262,8 +138764,8 @@ async function runMcpServe(argv2, io = { } // ../../packages/mcp-server/dist/index.js -var import_fs93 = require("fs"); -var import_path102 = __toESM(require("path"), 1); +var import_fs94 = require("fs"); +var import_path103 = __toESM(require("path"), 1); async function runMcpDoctor(options = {}) { const checks = []; const env = options.env ?? process.env; @@ -137356,7 +138858,7 @@ async function runMcpDoctor(options = {}) { const pluginRoot = env["CLAUDE_PLUGIN_ROOT"]; if (pluginRoot !== void 0 && pluginRoot.length > 0) { const missing = ["dist/mcp-server.cjs", "dist/cli.cjs"].filter( - (relative) => !(0, import_fs93.existsSync)(import_path102.default.join(pluginRoot, relative)) + (relative) => !(0, import_fs94.existsSync)(import_path103.default.join(pluginRoot, relative)) ); checks.push( missing.length === 0 ? { name: "plugin-bundle", status: "ok", detail: `Bundled executables present under ${pluginRoot}` } : { @@ -138428,7 +139930,7 @@ function registerOrchestrateJobCommands(orchestrate, runtime) { orchestrate.command("run").description("Run the long-running job orchestrator for one approved spec (foreground, resumable)").argument("", "spec name under .kiro/specs/").option("--goal ", "stated goal recorded on the job (default: implement the approved plan)").option("--resume ", "resume an existing job instead of creating one").option("--dry-run", "validate and show what would run, without creating or advancing anything").option("--json", "output a machine-readable JSON report of the final state").action( async (specName, options) => { const context = loadExecutionContext(runtime); - const deps3 = { + const deps4 = { workspace: context.workspace, config: context.config, registry: context.registry, @@ -138497,7 +139999,7 @@ function registerOrchestrateJobCommands(orchestrate, runtime) { `Job ${active.jobId} is already active (${active.status}) for "${specName}". Resume it with --resume ${active.jobId}, or cancel it with \`${CLI_BIN} orchestrate cancel-job ${active.jobId}\`.` ); } - const job = createJob(deps3, { + const job = createJob(deps4, { specName, goal: options.goal ?? `Implement the approved task plan of "${specName}".` }); @@ -138511,7 +140013,7 @@ function registerOrchestrateJobCommands(orchestrate, runtime) { }; process.once("SIGINT", onSigint); try { - const result = await driveJob(deps3, jobId, { + const result = await driveJob(deps4, jobId, { signal: controller.signal, onEvent: (event) => { if (event.kind === "decision") runtime.out(dim2(` \u2192 ${event.message}`)); @@ -138704,8 +140206,8 @@ function registerOrchestrateJobCommands(orchestrate, runtime) { throw new SpecBridgeError("INVALID_ARGUMENT", "Pass exactly one of --approve or --reject."); } const context = loadExecutionContext(runtime); - const deps3 = { workspace: context.workspace, config: context.config, host: "cli" }; - reviewNodePlan(deps3, jobId, { + const deps4 = { workspace: context.workspace, config: context.config, host: "cli" }; + reviewNodePlan(deps4, jobId, { nodeId, decision: options.approve === true ? "approved" : "rejected", note: options.note @@ -138718,8 +140220,8 @@ function registerOrchestrateJobCommands(orchestrate, runtime) { }); orchestrate.command("answer").description("Answer an open clarification question (human decision)").argument("").argument("").argument("").action((jobId, questionId, answerWords) => { const context = loadExecutionContext(runtime); - const deps3 = { workspace: context.workspace, config: context.config, host: "cli" }; - const job = answerClarification(deps3, jobId, [ + const deps4 = { workspace: context.workspace, config: context.config, host: "cli" }; + const job = answerClarification(deps4, jobId, [ { questionId, answer: answerWords.join(" ") } ]); runtime.out(okLine(`Recorded the decision. ${job.openQuestions.length} question(s) remain open.`)); @@ -138729,8 +140231,8 @@ function registerOrchestrateJobCommands(orchestrate, runtime) { }); orchestrate.command("cancel-job").description("Cancel a job (final; never auto-restarted)").argument("").option("--reason ", "reason recorded on the cancellation", "cancelled from the CLI").action((jobId, options) => { const context = loadExecutionContext(runtime); - const deps3 = { workspace: context.workspace, config: context.config, host: "cli" }; - const job = cancelJob(deps3, jobId, options.reason); + const deps4 = { workspace: context.workspace, config: context.config, host: "cli" }; + const job = cancelJob(deps4, jobId, options.reason); runtime.out(okLine(`Job ${jobId} is ${job.status}.`)); }); orchestrate.command("objective").description("One objective in depth: work graph, unit statuses, workers, conflicts, evaluations").argument("").argument("").option("--json", "output a machine-readable JSON report").action((jobId, nodeId, options) => { @@ -138842,16 +140344,16 @@ function registerOrchestrateJobCommands(orchestrate, runtime) { return; } runtime.out(reportTitle("Subscription quota")); - const percent = (ratio3) => ratio3 === null ? "unknown" : `${(ratio3 * 100).toFixed(1)}%`; + const percent3 = (ratio4) => ratio4 === null ? "unknown" : `${(ratio4 * 100).toFixed(1)}%`; const untilText = (ms) => ms === null ? "unknown" : `${Math.round(ms / 6e4)}m`; runtime.out( infoLine( - ` five-hour: ${percent(forecast.fiveHourRemainingRatio)} remaining, reset in ${untilText(forecast.timeToFiveHourResetMs)}` + ` five-hour: ${percent3(forecast.fiveHourRemainingRatio)} remaining, reset in ${untilText(forecast.timeToFiveHourResetMs)}` ) ); runtime.out( infoLine( - ` weekly: ${percent(forecast.weeklyRemainingRatio)} remaining, reset in ${untilText(forecast.timeToWeeklyResetMs)}` + ` weekly: ${percent3(forecast.weeklyRemainingRatio)} remaining, reset in ${untilText(forecast.timeToWeeklyResetMs)}` ) ); runtime.out(infoLine(` scheduler mode: ${forecast.schedulerMode} (telemetry ${forecast.telemetryFreshness})`)); @@ -139117,7 +140619,7 @@ function registerOrchestrateJobCommands(orchestrate, runtime) { if (!policy.enabled) runtime.out(warnLine(" lane scheduling is disabled by configuration.")); runtime.out( infoLine( - ` attempt lanes: ${Object.entries(laneCounts).map(([laneName, count3]) => `${laneName}=${count3}`).join(", ") || "(none yet)"}` + ` attempt lanes: ${Object.entries(laneCounts).map(([laneName, count4]) => `${laneName}=${count4}`).join(", ") || "(none yet)"}` ) ); runtime.out(reportTitle("Local execution (vNext.4)")); @@ -139213,8 +140715,8 @@ function registerOrchestrateJobCommands(orchestrate, runtime) { ` mode ${adaptiveSummary.mode}; ${adaptiveSummary.profileCount} profile(s) from ${adaptiveSummary.observations} observation(s); ${adaptiveSummary.decisions} recent decision(s), ${adaptiveSummary.applied} applied, ${adaptiveSummary.disagreements} disagreement(s)` ) ); - for (const [reason3, count3] of Object.entries(adaptiveSummary.fallbackReasons)) { - runtime.out(dim2(` fell back ${count3}x: ${reason3}`)); + for (const [reason3, count4] of Object.entries(adaptiveSummary.fallbackReasons)) { + runtime.out(dim2(` fell back ${count4}x: ${reason3}`)); } runtime.out(dim2(` detail: ${CLI_BIN} orchestrate adaptive ${jobId}`)); runtime.out(reportTitle("Ready tasks")); @@ -139698,7 +141200,7 @@ function registerOrchestrateJobCommands(orchestrate, runtime) { (fingerprintCounts.get(entry2.failureFingerprint) ?? 0) + 1 ); } - const repeating = [...fingerprintCounts.entries()].filter(([, count3]) => count3 > 1).sort((left, right) => right[1] - left[1]); + const repeating = [...fingerprintCounts.entries()].filter(([, count4]) => count4 > 1).sort((left, right) => right[1] - left[1]); const failedChecks = (latestEvaluation?.deterministicChecks ?? []).filter( (check6) => check6.required && check6.outcome !== "PASSED" ); @@ -139717,7 +141219,7 @@ function registerOrchestrateJobCommands(orchestrate, runtime) { failedChecks, assessment: latestAssessment ?? null, recovery: latestDecision ?? null, - repeatingFingerprints: repeating.map(([fingerprint, count3]) => ({ fingerprint, count: count3 })), + repeatingFingerprints: repeating.map(([fingerprint, count4]) => ({ fingerprint, count: count4 })), remaining, counters: { stagnationEvents: reliability?.stagnationEvents ?? 0, @@ -139764,8 +141266,8 @@ function registerOrchestrateJobCommands(orchestrate, runtime) { if (repeating.length > 0) { runtime.out(""); runtime.out(reportTitle("What keeps happening?")); - for (const [fingerprint, count3] of repeating.slice(0, 5)) { - runtime.out(warnLine(` failure ${fingerprint} recurred ${count3} time(s)`)); + for (const [fingerprint, count4] of repeating.slice(0, 5)) { + runtime.out(warnLine(` failure ${fingerprint} recurred ${count4} time(s)`)); } } if (latestAssessment !== void 0) { @@ -140079,7 +141581,7 @@ function registerOrchestrateQualifyCommands(orchestrate, runtime) { } } let sequence = 0; - const deps3 = { + const deps4 = { workspace: context.workspace, config: context.config, clock: () => runtime.now(), @@ -140088,7 +141590,7 @@ function registerOrchestrateQualifyCommands(orchestrate, runtime) { return `${Date.now().toString(36)}${String(sequence).padStart(3, "0")}`; } }; - const run = options.runId === void 0 ? startQualificationRun(deps3, { + const run = options.runId === void 0 ? startQualificationRun(deps4, { profile, target: resolveTarget(options), missionDirection: options.direction ?? null, @@ -140115,7 +141617,7 @@ function registerOrchestrateQualifyCommands(orchestrate, runtime) { } } const result = executeQualificationRun({ - deps: deps3, + deps: deps4, run, executor: "cli", ...options.scenario === void 0 ? {} : { only: options.scenario }, @@ -140259,9 +141761,9 @@ function registerOrchestrateQualifyCommands(orchestrate, runtime) { ) ); runtime.out(sectionTitle("Zero-tolerance conditions")); - for (const [condition, count3] of Object.entries(report.zeroTolerance)) { - const line = ` ${condition}: ${String(count3)}`; - runtime.out(count3 === 0 ? dim2(line) : failLine(line)); + for (const [condition, count4] of Object.entries(report.zeroTolerance)) { + const line = ` ${condition}: ${String(count4)}`; + runtime.out(count4 === 0 ? dim2(line) : failLine(line)); } if (report.blockers.length > 0) { runtime.out(sectionTitle("Release blockers")); @@ -140730,9 +142232,9 @@ function registerMissionCommands(program2, runtime) { for (const diagnostic of listed.diagnostics) runtime.out(warnLine(diagnostic.message)); }); mission.command("show").description("One mission in depth: status, coverage, open questions, artifacts").argument("").option("--json", "output a machine-readable JSON report").action((missionId, options) => { - const deps3 = missionDeps2(runtime); - observeSpecApproval(deps3, missionId); - const overview = describeMission(deps3, missionId); + const deps4 = missionDeps2(runtime); + observeSpecApproval(deps4, missionId); + const overview = describeMission(deps4, missionId); if (options.json === true) { jsonOut7(runtime, "mission-show", { mission: missionSummary(overview.mission), @@ -141044,8 +142546,8 @@ function registerSetup(autonomy, runtime) { } function registerPolicy(autonomy, runtime) { autonomy.command("policy").description("Print the resolved autonomy policy and the authority boundary").option("--json", "machine-readable output").action((options) => { - const deps3 = autonomyDeps(runtime); - const policy = deps3.config.autonomy; + const deps4 = autonomyDeps(runtime); + const policy = deps4.config.autonomy; if (options.json === true) { jsonOut8(runtime, "autonomy-policy/v1", { policy, @@ -141070,18 +142572,18 @@ function registerPolicy(autonomy, runtime) { function registerSeal(autonomy, runtime) { autonomy.command("seal ").description("Draft, and with --confirm authorize, the delegated intent seal").option("--confirm", "authorize the seal (this is the human authorization)").option("--max-spend ", "monetary ceiling this seal authorizes").option("--lanes ", "comma-separated lanes: LOCAL,SUBSCRIPTION,API", "LOCAL,SUBSCRIPTION").option("--json", "machine-readable output").action( (subject, options) => { - const deps3 = autonomyDeps(runtime); + const deps4 = autonomyDeps(runtime); const missionId = resolveMissionId(runtime, subject); const lanes = options.lanes.split(",").map((lane) => lane.trim().toUpperCase()).filter( (lane) => lane === "LOCAL" || lane === "SUBSCRIPTION" || lane === "API" ); - const draft = draftSeal(deps3, { + const draft = draftSeal(deps4, { missionId, maxApiSpendUsd: options.maxSpend !== void 0 ? Number(options.maxSpend) : null, allowedLanes: lanes.length > 0 ? lanes : ["LOCAL"] }); const completeness = assessSealCompleteness(draft); - const seal = options.confirm === true && completeness.complete ? sealMission(deps3, { sealId: draft.sealId, via: "cli" }) : draft; + const seal = options.confirm === true && completeness.complete ? sealMission(deps4, { sealId: draft.sealId, via: "cli" }) : draft; if (options.json === true) { jsonOut8(runtime, "autonomy-seal/v1", { sealId: seal.sealId, @@ -141149,8 +142651,8 @@ function registerSeal(autonomy, runtime) { } }); autonomy.command("revoke ").description("Withdraw a seal; delegated execution stops immediately").requiredOption("--reason ", "why the authorization is withdrawn").action((sealId, options) => { - const deps3 = autonomyDeps(runtime); - const seal = revokeSeal(deps3, sealId, options.reason); + const deps4 = autonomyDeps(runtime); + const seal = revokeSeal(deps4, sealId, options.reason); runtime.out(okLine(`Seal ${seal.sealId} is ${seal.status}.`)); }); } @@ -141187,11 +142689,11 @@ function renderPreflight(runtime, report) { function registerOvernight(program2, runtime) { const overnight = program2.command("overnight").description("Prepare and launch an unattended mission build"); overnight.command("preflight ").description("Find the human-only prerequisites before you leave the machine").option("--json", "machine-readable output").action(async (subject, options) => { - const deps3 = autonomyDeps(runtime); + const deps4 = autonomyDeps(runtime); const missionId = resolveMissionId(runtime, subject); - const seal = latestExecutableSeal(deps3.workspace, missionId); + const seal = latestExecutableSeal(deps4.workspace, missionId); const surfaces = requiredSurfacesFor(seal); - const report = await runOvernightPreflight(deps3, { + const report = await runOvernightPreflight(deps4, { subject: missionId, missionId, ...seal !== void 0 ? { sealId: seal.sealId } : {}, @@ -141218,14 +142720,14 @@ function registerOvernight(program2, runtime) { overnight.command("run ").description("Launch the unattended build. Progress needs nobody after this").option("--job ", "continue an existing job").option("--goal ", "goal recorded on a newly created job").option("--max-cycles ", "bound on supervise/close cycles (diagnostics)").option("--json", "machine-readable output").action( async (subject, options) => { const context = loadExecutionContext(runtime); - const deps3 = { + const deps4 = { workspace: context.workspace, config: context.config, clock: () => runtime.now(), host: "cli" }; const missionId = resolveMissionId(runtime, subject); - const seal = latestExecutableSeal(deps3.workspace, missionId); + const seal = latestExecutableSeal(deps4.workspace, missionId); if (seal === void 0) { throw new SpecBridgeError( "INVALID_STATE", @@ -141239,11 +142741,11 @@ function registerOvernight(program2, runtime) { `Mission ${missionId} has synthesized no spec yet; there is nothing to build.` ); } - const jobId = options.job ?? createJob(deps3, { + const jobId = options.job ?? createJob(deps4, { specName, goal: options.goal ?? seal.goal }).jobId; - const result = await runUnattendedMission(deps3, { + const result = await runUnattendedMission(deps4, { missionId, jobId, // A factory: the runtime hands back deps carrying the authority @@ -141357,10 +142859,10 @@ function registerInspection(autonomy, runtime) { } }); autonomy.command("report ").description("The autonomy report for one job (read-only)").option("--json", "machine-readable output").action((jobId, options) => { - const deps3 = autonomyDeps(runtime); - const telemetry = computeAutonomyTelemetry(deps3, { jobId }); - const ledger = readClosureLedger(deps3.workspace, jobId); - const job = requireJobState(deps3.workspace, jobId); + const deps4 = autonomyDeps(runtime); + const telemetry = computeAutonomyTelemetry(deps4, { jobId }); + const ledger = readClosureLedger(deps4.workspace, jobId); + const job = requireJobState(deps4.workspace, jobId); if (options.json === true) { jsonOut8(runtime, "autonomy-report/v1", { jobId, @@ -141494,8 +142996,8 @@ function registerClosure(autonomy, runtime) { closure.command("waive ").description( "Waive one sealed closure item with YOUR authority (human decision). A waiver is an attestation, not a shortcut: name the evidence you inspected." ).requiredOption("--reason ", "why this item is satisfied or does not apply \u2014 name the evidence").option("--by ", "who attests", "operator").action((jobId, itemId, options) => { - const deps3 = autonomyDeps(runtime); - const ledger = waiveClosureItem(deps3, { + const deps4 = autonomyDeps(runtime); + const ledger = waiveClosureItem(deps4, { jobId, itemId, reason: options.reason, @@ -141789,6 +143291,37 @@ function registerResearchCommands(program2, runtime) { }); } +// ../../packages/cli/src/commands/report.ts +function deps3(runtime) { + const context = loadExecutionContext(runtime); + return { + workspace: context.workspace, + config: context.config, + clock: () => runtime.now(), + host: "cli" + }; +} +function registerReportCommands(program2, runtime) { + const report = program2.command("report").description("Derived execution telemetry (never completion authority)"); + report.command("job ").description("Report one Job from durable execution facts").option("--json", "emit the versioned machine-readable report").option("--verbose", "include bounded WorkUnit accounting and cooldown timeline").option("--no-persist", "derive without writing .specbridge/reports").action((jobId, options) => { + const reportingDeps = deps3(runtime); + const result = computeExecutionTelemetryReport(reportingDeps, jobId, { + persist: options.persist !== false, + specbridgeVersion: VERSION + }); + if (options.json === true) { + runtime.outRaw(serializeJsonReport(result)); + return; + } + runtime.outRaw(renderExecutionTelemetryReport(result, { verbose: options.verbose === true })); + if (options.persist !== false) { + runtime.out( + `Report: ${relPath(reportingDeps.workspace, executionTelemetryReportFile(reportingDeps.workspace, jobId))}` + ); + } + }); +} + // ../../packages/cli/src/cli.ts function buildProgram(runtime) { const program2 = new Command(); @@ -141851,6 +143384,7 @@ honest error; nothing pretends to work before it does.` registerAutonomyCommands(program2, runtime); registerWorkspaceCommands(program2, runtime); registerResearchCommands(program2, runtime); + registerReportCommands(program2, runtime); return program2; } async function runCli(argv2, ioOverrides) { diff --git a/integrations/codex-plugin/specbridge/dist/mcp-server.cjs b/integrations/codex-plugin/specbridge/dist/mcp-server.cjs index 85b5e4f..f6b99b6 100644 --- a/integrations/codex-plugin/specbridge/dist/mcp-server.cjs +++ b/integrations/codex-plugin/specbridge/dist/mcp-server.cjs @@ -597,8 +597,8 @@ var require_Node = __commonJS({ }; const res = toJS.toJS(this, "", ctx); if (typeof onAnchor === "function") - for (const { count: count3, res: res2 } of ctx.anchors.values()) - onAnchor(res2, count3); + for (const { count: count4, res: res2 } of ctx.anchors.values()) + onAnchor(res2, count4); return typeof reviver === "function" ? applyReviver.applyReviver(reviver, { "": res }, "", res) : res; } }; @@ -704,13 +704,13 @@ var require_Alias = __commonJS({ const anchor = anchors2 && source && anchors2.get(source); return anchor ? anchor.count * anchor.aliasCount : 0; } else if (identity3.isCollection(node)) { - let count3 = 0; + let count4 = 0; for (const item of node.items) { const c3 = getAliasCount(doc, item, anchors2); - if (c3 > count3) - count3 = c3; + if (c3 > count4) + count4 = c3; } - return count3; + return count4; } else if (identity3.isPair(node)) { const kc = getAliasCount(doc, node.key, anchors2); const vc = getAliasCount(doc, node.value, anchors2); @@ -3663,8 +3663,8 @@ var require_Document = __commonJS({ }; const res = toJS.toJS(this.contents, jsonArg ?? "", ctx); if (typeof onAnchor === "function") - for (const { count: count3, res: res2 } of ctx.anchors.values()) - onAnchor(res2, count3); + for (const { count: count4, res: res2 } of ctx.anchors.values()) + onAnchor(res2, count4); return typeof reviver === "function" ? applyReviver.applyReviver(reviver, { "": res }, "", res) : res; } /** @@ -3741,12 +3741,12 @@ var require_errors = __commonJS({ lineStr = prev + lineStr; } if (/[^ ]/.test(lineStr)) { - let count3 = 1; + let count4 = 1; const end = error2.linePos[1]; if (end?.line === line && end.col > col) { - count3 = Math.max(1, Math.min(end.col - col, 80 - ci)); + count4 = Math.max(1, Math.min(end.col - col, 80 - ci)); } - const pointer = " ".repeat(ci) + "^".repeat(count3); + const pointer = " ".repeat(ci) + "^".repeat(count4); error2.message += `: ${lineStr} @@ -10044,20 +10044,20 @@ var require_resolve = __commonJS({ return false; } function countKeys(schema) { - let count3 = 0; + let count4 = 0; for (const key in schema) { if (key === "$ref") return Infinity; - count3++; + count4++; if (SIMPLE_INLINED.has(key)) continue; if (typeof schema[key] == "object") { - (0, util_1.eachItem)(schema[key], (sch) => count3 += countKeys(sch)); + (0, util_1.eachItem)(schema[key], (sch) => count4 += countKeys(sch)); } - if (count3 === Infinity) + if (count4 === Infinity) return Infinity; } - return count3; + return count4; } function getFullPath(resolver, id = "", normalize3) { if (normalize3 !== false) @@ -13229,8 +13229,8 @@ var require_contains = __commonJS({ cxt.result(valid, () => cxt.reset()); function validateItemsWithCount() { const schValid = gen.name("_valid"); - const count3 = gen.let("count", 0); - validateItems(schValid, () => gen.if(schValid, () => checkLimits(count3))); + const count4 = gen.let("count", 0); + validateItems(schValid, () => gen.if(schValid, () => checkLimits(count4))); } function validateItems(_valid, block) { gen.forRange("i", 0, len, (i2) => { @@ -13243,16 +13243,16 @@ var require_contains = __commonJS({ block(); }); } - function checkLimits(count3) { - gen.code((0, codegen_1._)`${count3}++`); + function checkLimits(count4) { + gen.code((0, codegen_1._)`${count4}++`); if (max === void 0) { - gen.if((0, codegen_1._)`${count3} >= ${min}`, () => gen.assign(valid, true).break()); + gen.if((0, codegen_1._)`${count4} >= ${min}`, () => gen.assign(valid, true).break()); } else { - gen.if((0, codegen_1._)`${count3} > ${max}`, () => gen.assign(valid, false).break()); + gen.if((0, codegen_1._)`${count4} > ${max}`, () => gen.assign(valid, false).break()); if (min === 1) gen.assign(valid, true); else - gen.if((0, codegen_1._)`${count3} >= ${min}`, () => gen.assign(valid, true)); + gen.if((0, codegen_1._)`${count4} >= ${min}`, () => gen.assign(valid, true)); } } } @@ -15641,20 +15641,20 @@ var require_parse2 = __commonJS({ consume(token.value); }; const negate = () => { - let count3 = 1; + let count4 = 1; while (peek() === "!" && (peek(2) !== "(" || peek(3) === "?")) { advance(); state.start++; - count3++; + count4++; } - if (count3 % 2 === 0) { + if (count4 % 2 === 0) { return false; } state.negated = true; state.start++; return true; }; - const increment2 = (type) => { + const increment3 = (type) => { state[type]++; stack.push(type); }; @@ -15695,7 +15695,7 @@ var require_parse2 = __commonJS({ token.startIndex = state.index; token.tokensIndex = tokens.length; const output = (opts.capture ? "(" : "") + token.open; - increment2("parens"); + increment3("parens"); push2({ type, value: value2, output: state.output ? "" : ONE_CHAR }); push2({ type: "paren", extglob: true, value: advance(), output }); extglobs.push(token); @@ -15871,7 +15871,7 @@ var require_parse2 = __commonJS({ continue; } if (value === "(") { - increment2("parens"); + increment3("parens"); push2({ type: "paren", value }); continue; } @@ -15895,7 +15895,7 @@ var require_parse2 = __commonJS({ } value = `\\${value}`; } else { - increment2("brackets"); + increment3("brackets"); } push2({ type: "bracket", value }); continue; @@ -15934,7 +15934,7 @@ var require_parse2 = __commonJS({ continue; } if (value === "{" && opts.nobrace !== true) { - increment2("braces"); + increment3("braces"); const open = { type: "brace", value, @@ -28454,6 +28454,54 @@ var autonomyPolicySchema = external_exports.object({ closure: closurePolicySchema.default({}), controlPlaneRepair: controlPlaneRepairPolicySchema.default({}) }).passthrough(); +function autonomyPolicyFingerprint(policy) { + const canonical = { + mode: policy.mode, + humanGate: policy.humanGate, + decisions: { + implementation: policy.decisions.implementation, + internalArchitecture: policy.decisions.internalArchitecture, + dependencySelection: policy.decisions.dependencySelection, + toolingCreation: policy.decisions.toolingCreation, + testInfrastructure: policy.decisions.testInfrastructure, + environmentProvisioning: policy.decisions.environmentProvisioning, + browserVerification: policy.decisions.browserVerification, + workDecomposition: policy.decisions.workDecomposition + }, + recovery: { + provider: policy.recovery.provider, + process: policy.recovery.process, + toolchain: policy.recovery.toolchain, + implementation: policy.recovery.implementation, + context: policy.recovery.context, + environment: policy.recovery.environment, + controlPlane: policy.recovery.controlPlane + }, + supervisor: { enabled: policy.supervisor.enabled, maxRestarts: policy.supervisor.maxRestarts }, + toolsmith: { + enabled: policy.toolsmith.enabled, + capabilities: [...policy.toolsmith.capabilities].sort(), + maxGrantsPerJob: policy.toolsmith.maxGrantsPerJob + }, + environments: { enabled: policy.environments.enabled }, + browser: { enabled: policy.browser.enabled }, + critic: { mode: policy.critic.mode }, + closure: { + enabled: policy.closure.enabled, + maxGapClosureCycles: policy.closure.maxGapClosureCycles, + requireSystemScenarios: policy.closure.requireSystemScenarios, + requireReleaseQualification: policy.closure.requireReleaseQualification, + requireReproducibility: policy.closure.requireReproducibility + }, + controlPlaneRepair: { + enabled: policy.controlPlaneRepair.enabled, + maxRepairsPerJob: policy.controlPlaneRepair.maxRepairsPerJob, + requireFullQualification: policy.controlPlaneRepair.requireFullQualification, + requireCanary: policy.controlPlaneRepair.requireCanary + } + }; + return JSON.stringify(canonical); +} var RUNNER_CONFIG_SCHEMA_VERSION = "2.0.0"; var BUILT_IN_PROFILE_NAMES = { "claude-code": "claude-code", @@ -31903,7 +31951,7 @@ function analyzeSpecWorkflow(spec, evaluation, stages) { function buildInitialState(specName, specType, mode, origin, clock) { const shape = workflowShape(specType, mode); const stages = initialStages(shape, specName); - const now5 = isoNow(clock); + const now6 = isoNow(clock); return { schemaVersion: SPEC_STATE_SCHEMA_VERSION, specName, @@ -31911,8 +31959,8 @@ function buildInitialState(specName, specType, mode, origin, clock) { workflowMode: mode, origin, status: deriveWorkflowStatus(shape, stages), - createdAt: now5, - updatedAt: now5, + createdAt: now6, + updatedAt: now6, stages }; } @@ -37377,7 +37425,7 @@ function parseMilliseconds(milliseconds) { // ../../node_modules/.pnpm/pretty-ms@9.3.0/node_modules/pretty-ms/index.js var isZero = (value) => value === 0 || value === 0n; -var pluralize = (word, count3) => count3 === 1 || count3 === 1n ? word : `${word}s`; +var pluralize = (word, count4) => count4 === 1 || count4 === 1n ? word : `${word}s`; var SECOND_ROUNDING_EPSILON = 1e-7; var ONE_DAY_IN_MILLISECONDS = 24n * 60n * 60n * 1000n; function prettyMilliseconds(milliseconds, options) { @@ -39381,10 +39429,10 @@ var errorStream = (stream, error2) => { }; var noop2 = () => { }; -var updateMaxListeners = (passThroughStream, increment2) => { +var updateMaxListeners = (passThroughStream, increment3) => { const maxListeners = passThroughStream.getMaxListeners(); if (maxListeners !== 0 && maxListeners !== Number.POSITIVE_INFINITY) { - passThroughStream.setMaxListeners(maxListeners + increment2); + passThroughStream.setMaxListeners(maxListeners + increment3); } }; var PASSTHROUGH_LISTENERS_COUNT = 2; @@ -39608,12 +39656,12 @@ var SignalExit = class extends SignalExitBase { for (const sig of signals) { this.#sigListeners[sig] = () => { const listeners = this.#process.listeners(sig); - let { count: count3 } = this.#emitter; + let { count: count4 } = this.#emitter; const p = process11; if (typeof p.__signal_exit_emitter__ === "object" && typeof p.__signal_exit_emitter__.count === "number") { - count3 += p.__signal_exit_emitter__.count; + count4 += p.__signal_exit_emitter__.count; } - if (listeners.length === count3) { + if (listeners.length === count4) { this.unload(); const ret = this.#emitter.emit("exit", null, sig); const s = sig === "SIGHUP" ? this.#hupSig : sig; @@ -49318,7 +49366,7 @@ function hashProtectedTree(workspaceRoot, relativeDir, into) { } } async function captureGitSnapshot(workspaceRoot, options = {}) { - const now5 = options.clock?.() ?? /* @__PURE__ */ new Date(); + const now6 = options.clock?.() ?? /* @__PURE__ */ new Date(); const diagnostics = []; const excludedPrefixes = [ ...SNAPSHOT_EXCLUDED_PREFIXES, @@ -49333,7 +49381,7 @@ async function captureGitSnapshot(workspaceRoot, options = {}) { }); return { schemaVersion: GIT_SNAPSHOT_SCHEMA_VERSION, - capturedAt: now5.toISOString(), + capturedAt: now6.toISOString(), gitAvailable: false, detached: false, clean: false, @@ -49407,7 +49455,7 @@ async function captureGitSnapshot(workspaceRoot, options = {}) { hashProtectedTree(workspaceRoot, import_path15.default.join(".specbridge", "state"), protectedHashes); return { schemaVersion: GIT_SNAPSHOT_SCHEMA_VERSION, - capturedAt: now5.toISOString(), + capturedAt: now6.toISOString(), gitAvailable: statusResult.ok, ...head !== void 0 ? { head } : {}, ...branch !== void 0 ? { branch } : {}, @@ -49757,10 +49805,10 @@ function evaluateEvidence(input) { if (!input.taskStillExists) { violations.push("the selected task no longer exists in tasks.md with its recorded text"); } - const outcomeStatus = statusForFailedOutcome(input.runnerOutcome); - if (outcomeStatus !== void 0) { + const outcomeStatus2 = statusForFailedOutcome(input.runnerOutcome); + if (outcomeStatus2 !== void 0) { reasons.push(`the runner outcome was "${input.runnerOutcome}"`); - return { status: outcomeStatus, violations, warnings, reasons }; + return { status: outcomeStatus2, violations, warnings, reasons }; } const agentChanges = agentChangedFiles(input.comparison).filter( (file) => !input.comparison.ambiguousPaths.includes(file.path) @@ -51002,15 +51050,15 @@ function readInteractiveLock(workspace) { } function acquireInteractiveLock(workspace, details) { const lockPath = interactiveLockPath(workspace); - const now5 = (details.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); + const now6 = (details.clock ?? (() => /* @__PURE__ */ new Date()))().toISOString(); const lock = { schemaVersion: INTERACTIVE_LOCK_SCHEMA_VERSION, runId: details.runId, specName: details.specName, taskId: details.taskId, pid: details.pid ?? process.pid, - createdAt: now5, - heartbeatAt: now5 + createdAt: now6, + heartbeatAt: now6 }; (0, import_fs20.mkdirSync)(import_path21.default.dirname(lockPath), { recursive: true }); try { @@ -51493,8 +51541,8 @@ async function abortInteractiveTask(deps, request) { ...report !== void 0 ? { outcome: classifyInteractiveOutcome(report) } : {} }; } - const now5 = await captureGitSnapshot(workspace.rootDir, { clock: () => clock() }); - const remaining = now5.gitAvailable ? agentChangedFiles(compareSnapshots(state.before, now5)).map((file) => file.path) : []; + const now6 = await captureGitSnapshot(workspace.rootDir, { clock: () => clock() }); + const remaining = now6.gitAvailable ? agentChangedFiles(compareSnapshots(state.before, now6)).map((file) => file.path) : []; const abortedAt = clock().toISOString(); writeRunArtifact( workspace, @@ -52630,14 +52678,14 @@ function refreshRepositoryIndex(previous, options) { function normalize(value) { return value.replace(/\\/g, "/").replace(/^\.\//, ""); } -function safeBuildEntry(rootDir, relativePath, now5, maxFileBytes) { +function safeBuildEntry(rootDir, relativePath, now6, maxFileBytes) { const limit = maxFileBytes ?? REPOSITORY_INDEX_LIMITS.maxFileBytes; try { if ((0, import_fs22.statSync)(import_path24.default.join(rootDir, relativePath)).size > limit) return void 0; } catch { return void 0; } - return buildEntry(rootDir, relativePath, now5); + return buildEntry(rootDir, relativePath, now6); } var RepositoryContextIndex = class { /** @@ -53544,12 +53592,16 @@ var contextEfficiencyMetricsSchema = external_exports.object({ // ../../packages/orchestration/dist/index.js var import_fs26 = require("fs"); var import_path28 = __toESM(require("path"), 1); -var import_crypto13 = require("crypto"); var import_fs27 = require("fs"); var import_path29 = __toESM(require("path"), 1); -var import_crypto14 = require("crypto"); var import_fs28 = require("fs"); var import_path30 = __toESM(require("path"), 1); +var import_crypto13 = require("crypto"); +var import_fs29 = require("fs"); +var import_path31 = __toESM(require("path"), 1); +var import_crypto14 = require("crypto"); +var import_fs30 = require("fs"); +var import_path32 = __toESM(require("path"), 1); var ORCHESTRATION_PHASES = [ /** The run exists; no intent has been assessed yet. */ "CREATED", @@ -56744,6 +56796,10 @@ var jobCheckpointSchema = external_exports.object({ /** The exact next legal action, in one line. */ nextAction: text22 }).passthrough(); +function workedMsOf(job, nowMs) { + const waited = (job.counters.humanWaitMs ?? 0) + (job.counters.deadIdleMs ?? 0) + (job.humanWaitSince === void 0 ? 0 : Math.max(0, nowMs - Date.parse(job.humanWaitSince))); + return Math.max(0, nowMs - Date.parse(job.createdAt) - waited); +} var RECOVERY_TARGETS = [ "WAITING_RESOURCE", "RECOVERING_PROVIDER", @@ -58562,6 +58618,29 @@ function readCandidate(workspace, jobId, nodeId, workUnitId, attempt) { } ); } +function readBuilderRoutingStates(workspace, jobId, nodeId) { + const dir = artifactPath3(workspace, jobId, nodeId, "routing"); + if (!(0, import_fs25.existsSync)(dir)) return []; + const states = []; + for (const name of (0, import_fs25.readdirSync)(dir).sort()) { + if (!name.endsWith(".json") || name === "telemetry.json") continue; + const state = readJson(import_path27.default.join(dir, name), (raw) => { + const result = builderRoutingStateSchema.safeParse(raw); + return result.success ? result.data : void 0; + }); + if (state !== void 0) states.push(state); + } + return states; +} +function readObjectiveCooldownState(workspace, jobId, nodeId) { + return readJson( + artifactPath3(workspace, jobId, nodeId, "resources", "strong-subscription.json"), + (raw) => { + const result = objectiveCooldownStateSchema.safeParse(raw); + return result.success ? result.data : void 0; + } + ); +} function readEvaluations(workspace, jobId, nodeId, workUnitId) { const dir = artifactPath3(workspace, jobId, nodeId, "evaluations"); if (!(0, import_fs25.existsSync)(dir)) return []; @@ -58606,6 +58685,11 @@ function readWorkerRecords(workspace, jobId, nodeId) { } return records; } +function listObjectiveNodes(workspace, jobId) { + const dir = import_path27.default.join(jobDir(workspace, jobId), "objectives"); + if (!(0, import_fs25.existsSync)(dir)) return []; + return (0, import_fs25.readdirSync)(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && ID_PATTERN3.test(entry.name)).map((entry) => entry.name).sort(); +} var EVALUATION_STATUSES = ["PASS", "FAIL", "INCONCLUSIVE"]; var EVALUATION_CHECK_LEVELS = [ "EXECUTION_INTEGRITY", @@ -59033,6 +59117,48 @@ var taskReliabilityStateSchema = external_exports.object({ pendingDecisionId: shortText8.optional(), updatedAt: shortText8 }).passthrough(); +function reliabilityDir(workspace, jobId) { + return assertInsideWorkspace(workspace.rootDir, import_path28.default.join(jobDir(workspace, jobId), "reliability")); +} +function recordDir(workspace, jobId, kind) { + return assertInsideWorkspace(workspace.rootDir, import_path28.default.join(reliabilityDir(workspace, jobId), kind)); +} +function readRecord(file, parse3) { + if (!(0, import_fs26.existsSync)(file)) return void 0; + try { + return parse3(JSON.parse((0, import_fs26.readFileSync)(file, "utf8"))); + } catch { + return void 0; + } +} +function listRecords(workspace, jobId, kind, parse3) { + const dir = recordDir(workspace, jobId, kind); + if (!(0, import_fs26.existsSync)(dir)) return []; + const records = []; + for (const entry of (0, import_fs26.readdirSync)(dir).sort()) { + if (!entry.endsWith(".json")) continue; + const record32 = readRecord(import_path28.default.join(dir, entry), parse3); + if (record32 !== void 0) records.push(record32); + } + return records; +} +function listEvaluationResults(workspace, jobId, filter = {}) { + const all = listRecords(workspace, jobId, "evaluations", (raw) => evaluationResultSchema.parse(raw)); + return filter.nodeId === void 0 ? all : all.filter((entry) => entry.nodeId === filter.nodeId); +} +function listFailureAssessments(workspace, jobId, filter = {}) { + const all = listRecords( + workspace, + jobId, + "assessments", + (raw) => failureAssessmentSchema.parse(raw) + ); + return filter.nodeId === void 0 ? all : all.filter((entry) => entry.nodeId === filter.nodeId); +} +function listRecoveryDecisions(workspace, jobId, filter = {}) { + const all = listRecords(workspace, jobId, "decisions", (raw) => recoveryDecisionSchema.parse(raw)); + return filter.nodeId === void 0 ? all : all.filter((entry) => entry.nodeId === filter.nodeId); +} var TASK_ATTEMPT_STATUSES = [ /** The dispatch is (or was, before a crash) in flight. */ "RUNNING", @@ -59357,6 +59483,102 @@ var executionLedgerEntrySchema = external_exports.object({ runnerVersion: shortText9.nullable().default(null), metrics: attemptMetricsSchema }).passthrough(); +function taskAttemptsDir(workspace, jobId) { + return assertInsideWorkspace( + workspace.rootDir, + import_path29.default.join(jobDir(workspace, jobId), "task-attempts") + ); +} +function listTaskAttempts(workspace, jobId, options = {}) { + const dir = taskAttemptsDir(workspace, jobId); + if (!(0, import_fs27.existsSync)(dir)) return []; + const attempts = []; + for (const entry of (0, import_fs27.readdirSync)(dir, { withFileTypes: true })) { + if (!entry.isFile() || !entry.name.endsWith(".json")) continue; + try { + const parsed = taskAttemptSchema.safeParse( + JSON.parse((0, import_fs27.readFileSync)(import_path29.default.join(dir, entry.name), "utf8")) + ); + if (!parsed.success) continue; + if (options.nodeId !== void 0 && parsed.data.nodeId !== options.nodeId) continue; + if (options.status !== void 0 && parsed.data.status !== options.status) continue; + attempts.push(parsed.data); + } catch { + } + } + attempts.sort( + (a2, b) => a2.startedAt.localeCompare(b.startedAt, "en") || a2.attemptId.localeCompare(b.attemptId, "en") + ); + return attempts; +} +function readExecutionLedger(workspace, jobId, options = {}) { + const attempts = listTaskAttempts(workspace, jobId, { nodeId: options.nodeId }); + const evaluations = new Map( + listEvaluationResults(workspace, jobId, { + ...options.nodeId !== void 0 ? { nodeId: options.nodeId } : {} + }).map((entry) => [entry.attemptId, entry]) + ); + const assessments = new Map( + listFailureAssessments(workspace, jobId, { + ...options.nodeId !== void 0 ? { nodeId: options.nodeId } : {} + }).map((entry) => [entry.attemptId, entry]) + ); + const decisions = new Map( + listRecoveryDecisions(workspace, jobId, { + ...options.nodeId !== void 0 ? { nodeId: options.nodeId } : {} + }).map((entry) => [entry.attemptId, entry]) + ); + return attempts.map((attempt) => { + const evaluation = evaluations.get(attempt.attemptId); + const assessment = assessments.get(attempt.attemptId); + const decision = decisions.get(attempt.attemptId); + return executionLedgerEntrySchema.parse({ + attemptId: attempt.attemptId, + jobId: attempt.jobId, + nodeId: attempt.nodeId, + taskId: attempt.taskId, + role: attempt.role, + provider: attempt.provider, + model: attempt.model, + lane: attempt.lane ?? null, + status: attempt.status, + attemptNumber: attempt.attemptNumber, + startedAt: attempt.startedAt, + completedAt: attempt.completedAt ?? null, + success: attempt.status === "COMPLETED", + failureReason: attempt.failure?.category ?? attempt.interruptedReason ?? null, + localSuitability: attempt.localSuitability ?? null, + taskComplexity: attempt.taskComplexity ?? null, + taskCategory: attempt.taskCategory ?? null, + schedulingDecisionId: attempt.schedulingDecisionId ?? null, + executionMode: attempt.executionMode ?? null, + executionShape: attempt.executionShape ?? null, + computeLocality: attempt.computeLocality ?? null, + apiSpendMode: attempt.apiSpendMode ?? null, + gapReason: attempt.gapReason ?? null, + subscriptionAvailableAt: attempt.subscriptionAvailableAt ?? null, + estimatedGapDurationMs: attempt.estimatedGapDurationMs ?? null, + costSource: attempt.costSource ?? null, + pricingProfile: attempt.pricingProfile ?? null, + apiBudgetReservationId: attempt.apiBudgetReservationId ?? null, + apiApprovalId: attempt.apiApprovalId ?? null, + delaySensitivity: attempt.delaySensitivity ?? null, + evaluationStatus: evaluation?.status ?? null, + evaluationId: evaluation?.evaluationId ?? null, + failureSource: assessment?.source ?? null, + failureFingerprint: assessment?.fingerprint ?? null, + executionHealth: assessment?.health ?? null, + recoveryAction: decision?.action ?? null, + recoveryReasonCode: decision?.reasonCode ?? null, + recoveryDecisionId: decision?.decisionId ?? null, + strategyChange: decision?.strategyChange ?? null, + taskSignature: attempt.taskSignature ?? null, + contextStrategy: attempt.contextStrategy ?? null, + runnerVersion: attempt.runnerVersion ?? null, + metrics: attempt.metrics + }); + }); +} var shortText10 = external_exports.string().min(1).max(200); var apiBudgetReservationSchema = external_exports.object({ reservationId: shortText10, @@ -59484,19 +59706,19 @@ function assessApiBudget(input) { }; } function contextCacheDir(workspace) { - return assertInsideWorkspace(workspace.rootDir, import_path28.default.join(workspace.sidecarDir, "cache")); + return assertInsideWorkspace(workspace.rootDir, import_path30.default.join(workspace.sidecarDir, "cache")); } function repositoryIndexFile(workspace) { return assertInsideWorkspace( workspace.rootDir, - import_path28.default.join(contextCacheDir(workspace), "context-index.json") + import_path30.default.join(contextCacheDir(workspace), "context-index.json") ); } function readRepositoryIndexCache(workspace) { const file = repositoryIndexFile(workspace); - if (!(0, import_fs26.existsSync)(file)) return void 0; + if (!(0, import_fs28.existsSync)(file)) return void 0; try { - const parsed = repositoryContextIndexSchema.safeParse(JSON.parse((0, import_fs26.readFileSync)(file, "utf8"))); + const parsed = repositoryContextIndexSchema.safeParse(JSON.parse((0, import_fs28.readFileSync)(file, "utf8"))); return parsed.success ? parsed.data : void 0; } catch { return void 0; @@ -59505,7 +59727,7 @@ function readRepositoryIndexCache(workspace) { function writeRepositoryIndexCache(workspace, state) { const validated = repositoryContextIndexSchema.parse(state); const file = repositoryIndexFile(workspace); - (0, import_fs26.mkdirSync)(import_path28.default.dirname(file), { recursive: true }); + (0, import_fs28.mkdirSync)(import_path30.default.dirname(file), { recursive: true }); writeFileAtomic(file, `${JSON.stringify(validated)} `); } @@ -61838,13 +62060,13 @@ function findResearchReuse(records, request) { var RESEARCH_DIR_NAME = "research"; var ID_PATTERN7 = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/; function researchRootDir(workspace) { - return assertInsideWorkspace(workspace.rootDir, import_path29.default.join(workspace.sidecarDir, RESEARCH_DIR_NAME)); + return assertInsideWorkspace(workspace.rootDir, import_path31.default.join(workspace.sidecarDir, RESEARCH_DIR_NAME)); } function researchRecordsDir(workspace) { - return assertInsideWorkspace(workspace.rootDir, import_path29.default.join(researchRootDir(workspace), "records")); + return assertInsideWorkspace(workspace.rootDir, import_path31.default.join(researchRootDir(workspace), "records")); } function researchUsesDir(workspace) { - return assertInsideWorkspace(workspace.rootDir, import_path29.default.join(researchRootDir(workspace), "uses")); + return assertInsideWorkspace(workspace.rootDir, import_path31.default.join(researchRootDir(workspace), "uses")); } function assertResearchId(researchId) { if (!ID_PATTERN7.test(researchId)) throw new Error(`Invalid research id "${researchId}".`); @@ -61854,7 +62076,7 @@ function researchRecordFile(workspace, researchId) { assertResearchId(researchId); return assertInsideWorkspace( workspace.rootDir, - import_path29.default.join(researchRecordsDir(workspace), `${researchId}.json`) + import_path31.default.join(researchRecordsDir(workspace), `${researchId}.json`) ); } function majorOf3(value) { @@ -61862,10 +62084,10 @@ function majorOf3(value) { } function readResearchRecord(workspace, researchId) { const file = researchRecordFile(workspace, researchId); - if (!(0, import_fs27.existsSync)(file)) return { kind: "missing" }; + if (!(0, import_fs29.existsSync)(file)) return { kind: "missing" }; let value; try { - value = JSON.parse((0, import_fs27.readFileSync)(file, "utf8")); + value = JSON.parse((0, import_fs29.readFileSync)(file, "utf8")); } catch (cause) { return { kind: "corrupt", problem: cause instanceof Error ? cause.message : String(cause), file }; } @@ -61887,29 +62109,46 @@ function readResearchRecord(workspace, researchId) { function writeResearchRecord(workspace, value) { const record32 = researchRecordSchema.parse(value); const file = researchRecordFile(workspace, record32.researchId); - (0, import_fs27.mkdirSync)(import_path29.default.dirname(file), { recursive: true }); + (0, import_fs29.mkdirSync)(import_path31.default.dirname(file), { recursive: true }); writeFileAtomic(file, `${JSON.stringify(record32, null, 2)} `); return record32; } function researchUseFile(workspace, useId) { - return assertInsideWorkspace(workspace.rootDir, import_path29.default.join(researchUsesDir(workspace), `${useId}.json`)); + return assertInsideWorkspace(workspace.rootDir, import_path31.default.join(researchUsesDir(workspace), `${useId}.json`)); } function writeResearchUseRecord(workspace, value) { const record32 = researchUseRecordSchema.parse(value); const file = researchUseFile(workspace, record32.useId); - if ((0, import_fs27.existsSync)(file)) throw new Error(`research use id ${record32.useId} already exists`); - (0, import_fs27.mkdirSync)(import_path29.default.dirname(file), { recursive: true }); + if ((0, import_fs29.existsSync)(file)) throw new Error(`research use id ${record32.useId} already exists`); + (0, import_fs29.mkdirSync)(import_path31.default.dirname(file), { recursive: true }); writeFileAtomic(file, `${JSON.stringify(record32, null, 2)} `); return record32; } +function listResearchUseRecords(workspace) { + const dir = researchUsesDir(workspace); + if (!(0, import_fs29.existsSync)(dir)) return []; + const records = []; + for (const entry of (0, import_fs29.readdirSync)(dir, { withFileTypes: true })) { + if (!entry.isFile() || !entry.name.endsWith(".json")) continue; + try { + const value = JSON.parse((0, import_fs29.readFileSync)(import_path31.default.join(dir, entry.name), "utf8")); + const version2 = value !== null && typeof value === "object" && typeof value.schemaVersion === "string" ? value.schemaVersion : ""; + if (majorOf3(version2) !== majorOf3(RESEARCH_USE_SCHEMA_VERSION)) continue; + const parsed = researchUseRecordSchema.safeParse(value); + if (parsed.success) records.push(parsed.data); + } catch { + } + } + return records.sort((a2, b) => a2.createdAt.localeCompare(b.createdAt)); +} function listResearchRecords(workspace) { const dir = researchRecordsDir(workspace); - if (!(0, import_fs27.existsSync)(dir)) return { records: [], diagnostics: [] }; + if (!(0, import_fs29.existsSync)(dir)) return { records: [], diagnostics: [] }; const records = []; const diagnostics = []; - for (const entry of (0, import_fs27.readdirSync)(dir, { withFileTypes: true })) { + for (const entry of (0, import_fs29.readdirSync)(dir, { withFileTypes: true })) { if (!entry.isFile() || !entry.name.endsWith(".json")) continue; const researchId = entry.name.slice(0, -5); if (!ID_PATTERN7.test(researchId)) continue; @@ -62477,7 +62716,7 @@ function zeroPhaseCounts() { function avoidanceRatio(avoided, considered) { return considered === 0 ? 0 : avoided / considered; } -function emptyResearchTelemetry(now5) { +function emptyResearchTelemetry(now52) { return { schemaVersion: RESEARCH_TELEMETRY_SCHEMA_VERSION, gateConsidered: 0, @@ -62504,32 +62743,32 @@ function emptyResearchTelemetry(now5) { reports: 0 }, totalDurationMs: 0, - updatedAt: now5.toISOString() + updatedAt: now52.toISOString() }; } function researchTelemetryFile(workspace) { - return assertInsideWorkspace(workspace.rootDir, import_path30.default.join(researchRootDir(workspace), "telemetry.json")); + return assertInsideWorkspace(workspace.rootDir, import_path32.default.join(researchRootDir(workspace), "telemetry.json")); } -function readResearchTelemetry(workspace, now5 = /* @__PURE__ */ new Date()) { +function readResearchTelemetry(workspace, now52 = /* @__PURE__ */ new Date()) { const file = researchTelemetryFile(workspace); - if (!(0, import_fs28.existsSync)(file)) return { telemetry: emptyResearchTelemetry(now5) }; + if (!(0, import_fs30.existsSync)(file)) return { telemetry: emptyResearchTelemetry(now52) }; try { - const parsed = researchTelemetrySchema.safeParse(JSON.parse((0, import_fs28.readFileSync)(file, "utf8"))); - return parsed.success ? { telemetry: parsed.data } : { telemetry: emptyResearchTelemetry(now5), diagnostic: "research telemetry is schema-invalid" }; + const parsed = researchTelemetrySchema.safeParse(JSON.parse((0, import_fs30.readFileSync)(file, "utf8"))); + return parsed.success ? { telemetry: parsed.data } : { telemetry: emptyResearchTelemetry(now52), diagnostic: "research telemetry is schema-invalid" }; } catch { - return { telemetry: emptyResearchTelemetry(now5), diagnostic: "research telemetry is unreadable" }; + return { telemetry: emptyResearchTelemetry(now52), diagnostic: "research telemetry is unreadable" }; } } function writeTelemetry(workspace, value) { const telemetry = researchTelemetrySchema.parse(value); const file = researchTelemetryFile(workspace); - (0, import_fs28.mkdirSync)(import_path30.default.dirname(file), { recursive: true }); + (0, import_fs30.mkdirSync)(import_path32.default.dirname(file), { recursive: true }); writeFileAtomic(file, `${JSON.stringify(telemetry, null, 2)} `); return telemetry; } -function recordResearchGateTelemetry(workspace, decision, now5, phase) { - const current = readResearchTelemetry(workspace, now5).telemetry; +function recordResearchGateTelemetry(workspace, decision, now52, phase) { + const current = readResearchTelemetry(workspace, now52).telemetry; const avoided = decision !== "RESEARCH_QUICK" && decision !== "RESEARCH_DEEP"; const researchAvoided = current.researchAvoided + (avoided ? 1 : 0); const gateConsidered = current.gateConsidered + 1; @@ -62549,7 +62788,7 @@ function recordResearchGateTelemetry(workspace, decision, now5, phase) { } } } : {}, - updatedAt: now5.toISOString() + updatedAt: now52.toISOString() }); } function addUsage(current, usage) { @@ -62563,8 +62802,8 @@ function addUsage(current, usage) { reports: current.reportedUsage.reports + 1 }; } -function recordResearchReuseTelemetry(workspace, now5, phase) { - const current = readResearchTelemetry(workspace, now5).telemetry; +function recordResearchReuseTelemetry(workspace, now52, phase) { + const current = readResearchTelemetry(workspace, now52).telemetry; return writeTelemetry(workspace, { ...current, reusedReports: current.reusedReports + 1, @@ -62574,19 +62813,19 @@ function recordResearchReuseTelemetry(workspace, now5, phase) { [phase]: { ...current.byPhase[phase], reused: current.byPhase[phase].reused + 1 } } } : {}, - updatedAt: now5.toISOString() + updatedAt: now52.toISOString() }); } -function recordResearchBudgetRefusalTelemetry(workspace, now5) { - const current = readResearchTelemetry(workspace, now5).telemetry; +function recordResearchBudgetRefusalTelemetry(workspace, now52) { + const current = readResearchTelemetry(workspace, now52).telemetry; return writeTelemetry(workspace, { ...current, budgetRefusals: current.budgetRefusals + 1, - updatedAt: now5.toISOString() + updatedAt: now52.toISOString() }); } -function recordResearchProviderTelemetry(workspace, result, durationMs, now5, depth, phase) { - const current = readResearchTelemetry(workspace, now5).telemetry; +function recordResearchProviderTelemetry(workspace, result, durationMs, now52, depth, phase) { + const current = readResearchTelemetry(workspace, now52).telemetry; const report = result.ok ? result.report : void 0; return writeTelemetry(workspace, { ...current, @@ -62608,15 +62847,15 @@ function recordResearchProviderTelemetry(workspace, result, durationMs, now5, de } : {}, reportedUsage: addUsage(current, report?.usage), totalDurationMs: current.totalDurationMs + Math.max(0, Math.trunc(durationMs)), - updatedAt: now5.toISOString() + updatedAt: now52.toISOString() }); } -function recordResearchDecisionPreparedTelemetry(workspace, now5) { - const current = readResearchTelemetry(workspace, now5).telemetry; +function recordResearchDecisionPreparedTelemetry(workspace, now52) { + const current = readResearchTelemetry(workspace, now52).telemetry; return writeTelemetry(workspace, { ...current, decisionsPreparedWithResearch: current.decisionsPreparedWithResearch + 1, - updatedAt: now5.toISOString() + updatedAt: now52.toISOString() }); } function nowOf(deps) { @@ -62691,13 +62930,13 @@ function evaluateAndRecordResearchGate(deps, input, phase) { return result; } async function getResearchProviderHealth(deps, signal) { - const now5 = nowOf(deps).toISOString(); + const now52 = nowOf(deps).toISOString(); const policy = deps.config.research; if (!policy.enabled) { return { provider: policy.provider, status: "UNKNOWN", - checkedAt: now5, + checkedAt: now52, detail: "research is disabled; no provider health request was made" }; } @@ -62705,7 +62944,7 @@ async function getResearchProviderHealth(deps, signal) { return { provider: policy.provider, status: "UNKNOWN", - checkedAt: now5, + checkedAt: now52, detail: "the selected research provider is disabled; no health request was made" }; } @@ -62714,7 +62953,7 @@ async function getResearchProviderHealth(deps, signal) { return { provider: policy.provider, status: "UNKNOWN", - checkedAt: now5, + checkedAt: now52, detail: `no ResearchBridge is registered for provider ${policy.provider}` }; } @@ -63325,11 +63564,11 @@ var quotaForecastSchema = external_exports.object({ /** The forecast's own clock reading. */ forecastAt: isoText }).passthrough(); -function timeToResetMs(resetAt, now5) { +function timeToResetMs(resetAt, now52) { if (resetAt === null) return null; const parsed = Date.parse(resetAt); if (Number.isNaN(parsed)) return null; - return Math.max(0, parsed - now5.getTime()); + return Math.max(0, parsed - now52.getTime()); } var shortText15 = external_exports.string().min(1).max(200); var schedulingDecisionSchema = external_exports.object({ @@ -63480,11 +63719,11 @@ var apiSpendApprovalSchema = external_exports.object({ /** The attempt that consumed this approval, when one did. */ consumedByAttemptId: shortText16.nullable().default(null) }).passthrough(); -function assessSnapshotFreshness(snapshot2, now5, staleMs) { +function assessSnapshotFreshness(snapshot2, now52, staleMs) { if (snapshot2 === null || snapshot2.remainingRatio === null) return "UNKNOWN"; const observed = Date.parse(snapshot2.observedAt); if (Number.isNaN(observed)) return "UNKNOWN"; - return now5.getTime() - observed > staleMs ? "STALE" : "FRESH"; + return now52.getTime() - observed > staleMs ? "STALE" : "FRESH"; } function combineFreshness(fiveHour, weekly) { if (fiveHour === "UNKNOWN" && weekly === "UNKNOWN") return "UNKNOWN"; @@ -63510,14 +63749,14 @@ function deriveSchedulerMode(input) { return "NORMAL"; } function buildQuotaForecast(input) { - const { now: now5, policy } = input; - const fiveHourFreshness = assessSnapshotFreshness(input.fiveHour, now5, policy.telemetryStaleMs); - const weeklyFreshness = assessSnapshotFreshness(input.weekly, now5, policy.telemetryStaleMs); + const { now: now52, policy } = input; + const fiveHourFreshness = assessSnapshotFreshness(input.fiveHour, now52, policy.telemetryStaleMs); + const weeklyFreshness = assessSnapshotFreshness(input.weekly, now52, policy.telemetryStaleMs); const freshness = combineFreshness(fiveHourFreshness, weeklyFreshness); const fiveHourRemaining = input.fiveHour?.remainingRatio ?? null; const weeklyRemaining = input.weekly?.remainingRatio ?? null; - const timeToFiveHour = timeToResetMs(input.fiveHour?.resetAt ?? null, now5); - const timeToWeekly = timeToResetMs(input.weekly?.resetAt ?? null, now5); + const timeToFiveHour = timeToResetMs(input.fiveHour?.resetAt ?? null, now52); + const timeToWeekly = timeToResetMs(input.weekly?.resetAt ?? null, now52); const burnRate = input.observedFiveHourBurnRatePerMinute ?? null; const projected = burnRate !== null && timeToFiveHour !== null ? Math.min(1, burnRate * (timeToFiveHour / 6e4)) : null; const schedulerMode = deriveSchedulerMode({ @@ -63540,7 +63779,7 @@ function buildQuotaForecast(input) { schedulerMode, telemetryFreshness: freshness, observedAt: observedTimes[0] ?? null, - forecastAt: now5.toISOString() + forecastAt: now52.toISOString() }); } function formatDuration(ms) { @@ -72701,20 +72940,20 @@ function registerRunResources(server, context) { } // ../../packages/drift/dist/index.js -var import_fs29 = require("fs"); -var import_path31 = __toESM(require("path"), 1); -var import_picomatch = __toESM(require_picomatch2(), 1); -var import_fs30 = require("fs"); -var import_path32 = __toESM(require("path"), 1); var import_fs31 = require("fs"); var import_path33 = __toESM(require("path"), 1); +var import_picomatch = __toESM(require_picomatch2(), 1); var import_fs32 = require("fs"); var import_path34 = __toESM(require("path"), 1); var import_fs33 = require("fs"); var import_path35 = __toESM(require("path"), 1); var import_fs34 = require("fs"); -var import_crypto15 = require("crypto"); var import_path36 = __toESM(require("path"), 1); +var import_fs35 = require("fs"); +var import_path37 = __toESM(require("path"), 1); +var import_fs36 = require("fs"); +var import_crypto15 = require("crypto"); +var import_path38 = __toESM(require("path"), 1); var taskEvidenceSchema = external_exports.object({ taskId: external_exports.string().min(1), status: external_exports.enum(["recorded", "verified", "rejected"]), @@ -72815,24 +73054,24 @@ var verificationPolicySchema = external_exports.object({ } }); function policyDir(workspace) { - return import_path31.default.join(workspace.sidecarDir, "policies"); + return import_path33.default.join(workspace.sidecarDir, "policies"); } function policyPath(workspace, specName) { - const resolved2 = import_path31.default.resolve(policyDir(workspace), `${specName}.json`); - const relative = import_path31.default.relative(workspace.rootDir, resolved2); - if (relative.startsWith("..") || import_path31.default.isAbsolute(relative)) { - return import_path31.default.join(policyDir(workspace), "invalid-spec-name.json"); + const resolved2 = import_path33.default.resolve(policyDir(workspace), `${specName}.json`); + const relative = import_path33.default.relative(workspace.rootDir, resolved2); + if (relative.startsWith("..") || import_path33.default.isAbsolute(relative)) { + return import_path33.default.join(policyDir(workspace), "invalid-spec-name.json"); } return resolved2; } function readVerificationPolicy(workspace, specName, explicitPath) { - const filePath = explicitPath !== void 0 ? import_path31.default.resolve(workspace.rootDir, explicitPath) : policyPath(workspace, specName); - if (!(0, import_fs29.existsSync)(filePath)) { + const filePath = explicitPath !== void 0 ? import_path33.default.resolve(workspace.rootDir, explicitPath) : policyPath(workspace, specName); + if (!(0, import_fs31.existsSync)(filePath)) { return { path: filePath, exists: false, diagnostics: [] }; } let parsed; try { - parsed = JSON.parse((0, import_fs29.readFileSync)(filePath, "utf8")); + parsed = JSON.parse((0, import_fs31.readFileSync)(filePath, "utf8")); } catch (cause) { return { path: filePath, @@ -72895,7 +73134,7 @@ function resolveEffectivePolicy(workspace, specName, options = {}) { const storedMode = policy?.mode ?? "advisory"; const strictFromCli = options.strict === true && storedMode !== "strict"; const mode = options.strict === true ? "strict" : storedMode; - const workspaceRelativePolicyPath = import_path31.default.relative(workspace.rootDir, read.path).split(import_path31.default.sep).join("/"); + const workspaceRelativePolicyPath = import_path33.default.relative(workspace.rootDir, read.path).split(import_path33.default.sep).join("/"); return { specName, mode, @@ -73039,33 +73278,33 @@ function mergeNumstat(files, stats) { function sniffBinary(absolutePath) { let fd; try { - fd = (0, import_fs30.openSync)(absolutePath, "r"); + fd = (0, import_fs32.openSync)(absolutePath, "r"); const buffer = Buffer.alloc(8e3); - const bytesRead = (0, import_fs30.readSync)(fd, buffer, 0, buffer.length, 0); + const bytesRead = (0, import_fs32.readSync)(fd, buffer, 0, buffer.length, 0); return buffer.subarray(0, bytesRead).includes(0); } catch { return false; } finally { - if (fd !== void 0) (0, import_fs30.closeSync)(fd); + if (fd !== void 0) (0, import_fs32.closeSync)(fd); } } function flagSymlinkEscapes(repoRoot, files) { const resolvedRoot = (() => { try { - return (0, import_fs30.realpathSync)(repoRoot); + return (0, import_fs32.realpathSync)(repoRoot); } catch { - return import_path32.default.resolve(repoRoot); + return import_path34.default.resolve(repoRoot); } })(); for (const file of files) { if (file.changeType === "deleted") continue; - const absolute = import_path32.default.join(repoRoot, file.path.split("/").join(import_path32.default.sep)); + const absolute = import_path34.default.join(repoRoot, file.path.split("/").join(import_path34.default.sep)); try { - const stats = (0, import_fs30.lstatSync)(absolute); + const stats = (0, import_fs32.lstatSync)(absolute); if (!stats.isSymbolicLink()) continue; - const target = (0, import_fs30.realpathSync)(absolute); - const relative = import_path32.default.relative(resolvedRoot, target); - if (relative.startsWith("..") || import_path32.default.isAbsolute(relative)) { + const target = (0, import_fs32.realpathSync)(absolute); + const relative = import_path34.default.relative(resolvedRoot, target); + if (relative.startsWith("..") || import_path34.default.isAbsolute(relative)) { file.symlinkOutsideRepository = true; } } catch { @@ -73193,7 +73432,7 @@ async function resolveComparison(repoRoot, request, options = {}) { const known = new Set(files.map((file) => file.path)); for (const token of untracked.stdout.split("\0")) { if (token.length === 0 || known.has(token)) continue; - const absolute = import_path32.default.join(repoRoot, token.split("/").join(import_path32.default.sep)); + const absolute = import_path34.default.join(repoRoot, token.split("/").join(import_path34.default.sep)); files.push({ path: token, changeType: "untracked", @@ -73273,9 +73512,9 @@ function specMatchReasons(specName, policy, validEvidencePaths, designPathRefere function readSpecEvidenceRecords(workspace, specName) { const byTask = /* @__PURE__ */ new Map(); let invalidRecordCount = 0; - const specDir = import_path33.default.join(workspace.sidecarDir, "evidence", specName); - if ((0, import_fs31.existsSync)(specDir)) { - const taskDirs = (0, import_fs31.readdirSync)(specDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort((a2, b) => a2.localeCompare(b, "en")); + const specDir = import_path35.default.join(workspace.sidecarDir, "evidence", specName); + if ((0, import_fs33.existsSync)(specDir)) { + const taskDirs = (0, import_fs33.readdirSync)(specDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort((a2, b) => a2.localeCompare(b, "en")); for (const taskDir of taskDirs) { const { records, diagnostics } = listTaskEvidence(workspace, specName, taskDir); invalidRecordCount += diagnostics.length; @@ -73289,7 +73528,7 @@ function readSpecEvidenceRecords(workspace, specName) { return { byTask, invalidRecordCount }; } async function buildSpecVerificationContext(options) { - const { workspace, folder, comparison, caches, now: now5 } = options; + const { workspace, folder, comparison, caches, now: now6 } = options; const spec = analyzeSpec(workspace, folder); const evaluation = spec.state !== void 0 ? evaluateWorkflow(workspace, spec.state) : void 0; const policy = resolveEffectivePolicy(workspace, folder.name, { @@ -73322,7 +73561,7 @@ async function buildSpecVerificationContext(options) { } if (effective("tasks") && tasksStage !== void 0) { const planHash2 = typeof tasksStage.approvedPlanHash === "string" ? tasksStage.approvedPlanHash : tryTaskPlanHashOfFile( - import_path33.default.join(workspace.rootDir, tasksStage.file.split("/").join(import_path33.default.sep)) + import_path35.default.join(workspace.rootDir, tasksStage.file.split("/").join(import_path35.default.sep)) ); if (planHash2 !== void 0) approved.tasksPlanHash = planHash2; } @@ -73344,7 +73583,7 @@ async function buildSpecVerificationContext(options) { approved, approvedAt, tasks: currentTasks, - now: now5 + now: now6 }; const recordedShas = /* @__PURE__ */ new Set(); for (const records of rawEvidence.byTask.values()) { @@ -73396,7 +73635,7 @@ async function buildSpecVerificationContext(options) { freshness, matchedBy: options.matchedBy ?? [], readBaseContent: makeBaseContentReader(workspace, comparison, caches, options.signal), - now: now5 + now: now6 }; } async function orchestrateVerificationCommands(options) { @@ -73544,7 +73783,7 @@ async function evaluateGlobalRules(rules, context) { return { diagnostics, disabledRules }; } function repoRelative2(workspace, absolutePath) { - return import_path34.default.relative(workspace.rootDir, absolutePath).split(import_path34.default.sep).join("/"); + return import_path36.default.relative(workspace.rootDir, absolutePath).split(import_path36.default.sep).join("/"); } function isSpecInfraPath(candidate) { return candidate === ".git" || candidate.startsWith(".git/") || candidate.startsWith(".kiro/") || candidate.startsWith(".specbridge/"); @@ -74225,14 +74464,14 @@ var sbv018 = { if (designDocument === void 0) return []; const designFile = designDocument.filePath; const designRepoPath = designFile !== void 0 ? repoRelative2(context.workspace, designFile) : void 0; - const specDir = import_path34.default.join(context.workspace.rootDir, ".kiro", "specs", context.specName); + const specDir = import_path36.default.join(context.workspace.rootDir, ".kiro", "specs", context.specName); return context.traceability.designPathReferences.filter((reference) => !reference.isGlob).filter((reference) => { - const fromRoot = import_path34.default.join( + const fromRoot = import_path36.default.join( context.workspace.rootDir, - reference.path.split("/").join(import_path34.default.sep) + reference.path.split("/").join(import_path36.default.sep) ); - const fromSpecDir = import_path34.default.join(specDir, reference.path.split("/").join(import_path34.default.sep)); - return !(0, import_fs32.existsSync)(fromRoot) && !(0, import_fs32.existsSync)(fromSpecDir); + const fromSpecDir = import_path36.default.join(specDir, reference.path.split("/").join(import_path36.default.sep)); + return !(0, import_fs34.existsSync)(fromRoot) && !(0, import_fs34.existsSync)(fromSpecDir); }).map( (reference) => makeDiagnostic({ rule: this, @@ -74476,9 +74715,9 @@ function loadSpecMatchingInfo(workspace, folder, options) { } } const evidencePaths = /* @__PURE__ */ new Set(); - const evidenceDir2 = import_path35.default.join(workspace.sidecarDir, "evidence", folder.name); - if ((0, import_fs33.existsSync)(evidenceDir2)) { - for (const entry of (0, import_fs34.readdirSync)(evidenceDir2, { withFileTypes: true })) { + const evidenceDir2 = import_path37.default.join(workspace.sidecarDir, "evidence", folder.name); + if ((0, import_fs35.existsSync)(evidenceDir2)) { + for (const entry of (0, import_fs36.readdirSync)(evidenceDir2, { withFileTypes: true })) { if (!entry.isDirectory()) continue; const { records } = listTaskEvidence(workspace, folder.name, entry.name); for (const record4 of records) { @@ -74535,7 +74774,7 @@ var VERIFY_EXIT_CODES = { commandTimeout: 5 }; async function verifySpecs(request) { - const now5 = (request.clock ?? (() => /* @__PURE__ */ new Date()))(); + const now6 = (request.clock ?? (() => /* @__PURE__ */ new Date()))(); const verificationId = (request.idFactory ?? import_crypto15.randomUUID)(); const workspace = request.workspace; const configRead = readAgentConfig(workspace); @@ -74577,7 +74816,7 @@ async function verifySpecs(request) { ...request.strict !== void 0 ? { strict: request.strict } : {}, ...request.explicitPolicyPath !== void 0 ? { explicitPolicyPath: request.explicitPolicyPath } : {}, ...matchedBy !== void 0 ? { matchedBy: dedupe(matchedBy) } : {}, - now: now5, + now: now6, ...request.signal !== void 0 ? { signal: request.signal } : {} }) ); @@ -74587,8 +74826,8 @@ async function verifySpecs(request) { let artifactsDir; const ensureArtifactsDir = () => { if (artifactsDir === void 0) { - const base = request.reportsDir ?? import_path36.default.join(workspace.sidecarDir, "reports"); - artifactsDir = import_path36.default.join(base, verificationId); + const base = request.reportsDir ?? import_path38.default.join(workspace.sidecarDir, "reports"); + artifactsDir = import_path38.default.join(base, verificationId); } return artifactsDir; }; @@ -74611,8 +74850,8 @@ async function verifySpecs(request) { onCommandFinished: (result, stdout, stderr) => { const dir = ensureArtifactsDir(); const safeName = result.name.replace(/[^A-Za-z0-9._-]+/g, "-"); - writeFileAtomic(import_path36.default.join(dir, "commands", `${safeName}.stdout.log`), stdout); - writeFileAtomic(import_path36.default.join(dir, "commands", `${safeName}.stderr.log`), stderr); + writeFileAtomic(import_path38.default.join(dir, "commands", `${safeName}.stdout.log`), stdout); + writeFileAtomic(import_path38.default.join(dir, "commands", `${safeName}.stderr.log`), stderr); } } : {} }) : { mode: "none", commands: [], missingRequired: [] }; @@ -74630,7 +74869,7 @@ async function verifySpecs(request) { unmappedFiles: affectedResult.unmapped, ambiguousFiles: affectedResult.ambiguous, commands, - now: now5 + now: now6 }; const globalResult = await evaluateGlobalRules(rules, globalContext); const selectedNames = new Set(specContexts.map((context) => context.specName)); @@ -74742,7 +74981,7 @@ async function verifySpecs(request) { schemaVersion: VERIFICATION_REPORT_SCHEMA_VERSION, tool: { name: "specbridge", version: request.toolVersion }, verificationId, - createdAt: now5.toISOString(), + createdAt: now6.toISOString(), comparison: comparison.descriptor, selection: { mode: selectionMode, @@ -74763,7 +75002,7 @@ async function verifySpecs(request) { verificationReportSchema.parse(report); if (persistArtifacts && artifactsDir !== void 0) { writeFileAtomic( - import_path36.default.join(artifactsDir, "report.json"), + import_path38.default.join(artifactsDir, "report.json"), `${JSON.stringify(report, null, 2)} ` ); @@ -77987,17 +78226,17 @@ var TEMPLATE_PROVIDER_TEMPLATES_DIR = "templates"; var MAX_TEMPLATE_PROVIDER_PACKS = 20; // ../../packages/extensions/dist/index.js -var import_fs38 = require("fs"); -var import_path41 = __toESM(require("path"), 1); +var import_fs40 = require("fs"); +var import_path43 = __toESM(require("path"), 1); // ../../packages/templates/dist/index.js -var import_fs35 = require("fs"); -var import_path37 = __toESM(require("path"), 1); -var import_fs36 = require("fs"); -var import_path38 = __toESM(require("path"), 1); var import_fs37 = require("fs"); var import_path39 = __toESM(require("path"), 1); +var import_fs38 = require("fs"); var import_path40 = __toESM(require("path"), 1); +var import_fs39 = require("fs"); +var import_path41 = __toESM(require("path"), 1); +var import_path42 = __toESM(require("path"), 1); var SPECBRIDGE_VERSION = "1.0.0"; var TEMPLATE_ERROR_CODES = { SBT001: "template not found", @@ -78826,11 +79065,11 @@ function readTemplatePackDirectory(dir) { { path: currentDir } ); } - const entries = (0, import_fs35.readdirSync)(currentDir, { withFileTypes: true }).sort( + const entries = (0, import_fs37.readdirSync)(currentDir, { withFileTypes: true }).sort( (a2, b) => a2.name.localeCompare(b.name, "en") ); for (const entry of entries) { - const entryPath = import_path37.default.join(currentDir, entry.name); + const entryPath = import_path39.default.join(currentDir, entry.name); const entryRelative = relative === "" ? entry.name : `${relative}/${entry.name}`; const stat = statNoFollow(entryPath); if (stat.isSymbolicLink()) { @@ -78882,7 +79121,7 @@ function readTemplatePackDirectory(dir) { { path: dir } ); } - const buffer = (0, import_fs35.readFileSync)(entryPath); + const buffer = (0, import_fs37.readFileSync)(entryPath); const text15 = buffer.toString("utf8"); if (!Buffer.from(text15, "utf8").equals(buffer)) { throw new TemplateError( @@ -78908,7 +79147,7 @@ function readTemplatePackDirectory(dir) { } function statNoFollow(target) { try { - return (0, import_fs35.lstatSync)(target); + return (0, import_fs37.lstatSync)(target); } catch (cause) { throw new TemplateError( "SBT007", @@ -79186,7 +79425,7 @@ var BUILTIN_TEMPLATE_PACKS = [ } ]; function projectTemplatesDir(workspace) { - return import_path38.default.join(workspace.sidecarDir, "templates"); + return import_path40.default.join(workspace.sidecarDir, "templates"); } function builtinEntries(options) { const entries = []; @@ -79211,11 +79450,11 @@ function builtinEntries(options) { function projectEntries(workspace, options, diagnostics) { if (workspace === void 0) return []; const dir = projectTemplatesDir(workspace); - if (!(0, import_fs36.existsSync)(dir)) return []; + if (!(0, import_fs38.existsSync)(dir)) return []; const entries = []; let names; try { - names = (0, import_fs36.readdirSync)(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.isSymbolicLink()).map((entry) => entry.name).sort((a2, b) => a2.localeCompare(b, "en")); + names = (0, import_fs38.readdirSync)(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.isSymbolicLink()).map((entry) => entry.name).sort((a2, b) => a2.localeCompare(b, "en")); } catch (cause) { diagnostics.push({ severity: "warning", @@ -79225,7 +79464,7 @@ function projectEntries(workspace, options, diagnostics) { return []; } for (const name of names) { - const packDir = import_path38.default.join(dir, name); + const packDir = import_path40.default.join(dir, name); let pack; try { const data = readTemplatePackDirectory(packDir); @@ -79468,7 +79707,7 @@ var templateRecordSchema = external_exports.discriminatedUnion("type", [ templateScaffoldRecordSchema ]); function templateRecordsPath(workspace) { - return import_path39.default.join(workspace.sidecarDir, TEMPLATE_RECORDS_FILE_NAME); + return import_path41.default.join(workspace.sidecarDir, TEMPLATE_RECORDS_FILE_NAME); } var recordCounter = 0; function newTemplateRecordId(clock = systemClock) { @@ -79479,8 +79718,8 @@ function appendTemplateRecord(workspace, record4) { const validated = templateRecordSchema.parse(record4); const filePath = templateRecordsPath(workspace); try { - (0, import_fs37.mkdirSync)(workspace.sidecarDir, { recursive: true }); - (0, import_fs37.appendFileSync)(filePath, `${JSON.stringify(validated)} + (0, import_fs39.mkdirSync)(workspace.sidecarDir, { recursive: true }); + (0, import_fs39.appendFileSync)(filePath, `${JSON.stringify(validated)} `, "utf8"); } catch (cause) { throw ioError("append template record to", filePath, cause); @@ -79647,7 +79886,7 @@ function planTemplateApplication(workspace, catalog, request, clock = systemCloc }; } function toPosix2(relative) { - return relative.split(import_path40.default.sep).join("/"); + return relative.split(import_path42.default.sep).join("/"); } function executeTemplateApplication(workspace, plan, clock = systemClock, recordId) { let creation; @@ -79677,8 +79916,8 @@ function executeTemplateApplication(workspace, plan, clock = systemClock, record })), variableNames: plan.variableNames, createdPaths: [ - ...creation.writtenFiles.map((file) => toPosix2(import_path40.default.relative(workspace.rootDir, file))), - toPosix2(import_path40.default.relative(workspace.rootDir, creation.statePath)) + ...creation.writtenFiles.map((file) => toPosix2(import_path42.default.relative(workspace.rootDir, file))), + toPosix2(import_path42.default.relative(workspace.rootDir, creation.statePath)) ] }; appendTemplateRecord(workspace, record4); @@ -79687,13 +79926,13 @@ function executeTemplateApplication(workspace, plan, clock = systemClock, record // ../../packages/extensions/dist/index.js var import_crypto17 = require("crypto"); -var import_fs39 = require("fs"); -var import_path42 = __toESM(require("path"), 1); -var import_child_process = require("child_process"); -var import_fs40 = require("fs"); -var import_path43 = __toESM(require("path"), 1); var import_fs41 = require("fs"); var import_path44 = __toESM(require("path"), 1); +var import_child_process = require("child_process"); +var import_fs42 = require("fs"); +var import_path45 = __toESM(require("path"), 1); +var import_fs43 = require("fs"); +var import_path46 = __toESM(require("path"), 1); var ExtensionError = class extends SpecBridgeError { extensionCode; /** Actionable next step, always present. */ @@ -79937,7 +80176,7 @@ var FORBIDDEN_LIFECYCLE_SCRIPTS = [ "postuninstall" ]; function readExtensionPackageDirectory(dir) { - const rootStat = (0, import_fs38.lstatSync)(dir, { throwIfNoEntry: false }); + const rootStat = (0, import_fs40.lstatSync)(dir, { throwIfNoEntry: false }); if (rootStat === void 0 || !rootStat.isDirectory()) { throw new ExtensionError( "SBE008", @@ -79962,7 +80201,7 @@ function readExtensionPackageDirectory(dir) { "Flatten the package layout." ); } - for (const entry of (0, import_fs38.readdirSync)(currentDir, { withFileTypes: true })) { + for (const entry of (0, import_fs40.readdirSync)(currentDir, { withFileTypes: true })) { const relativePath = relativePrefix === "" ? entry.name : `${relativePrefix}/${entry.name}`; if (entry.isSymbolicLink()) { throw new ExtensionError( @@ -79988,7 +80227,7 @@ function readExtensionPackageDirectory(dir) { "Remove the directory before validating or packaging." ); } - walk(import_path41.default.join(currentDir, entry.name), relativePath, depth + 1); + walk(import_path43.default.join(currentDir, entry.name), relativePath, depth + 1); continue; } if (!entry.isFile()) { @@ -80005,7 +80244,7 @@ function readExtensionPackageDirectory(dir) { "Reduce the package contents." ); } - const content = (0, import_fs38.readFileSync)(import_path41.default.join(currentDir, entry.name)); + const content = (0, import_fs40.readFileSync)(import_path43.default.join(currentDir, entry.name)); totalBytes += content.length; if (totalBytes > EXTENSION_LIMITS.maxExtractedTotalBytes) { throw new ExtensionError( @@ -80278,10 +80517,10 @@ var EXTENSION_STATE_FILE_NAME = "state.json"; var EXTENSION_GRANTS_FILE_NAME = "grants.json"; var EXTENSION_STATE_SCHEMA_VERSION = "1.0.0"; function extensionsDir(workspace) { - return import_path42.default.join(workspace.sidecarDir, EXTENSIONS_DIR_NAME); + return import_path44.default.join(workspace.sidecarDir, EXTENSIONS_DIR_NAME); } function installedRootDir(workspace) { - return import_path42.default.join(extensionsDir(workspace), "installed"); + return import_path44.default.join(extensionsDir(workspace), "installed"); } function installedVersionDir(workspace, id, version2) { if (!validateExtensionId(id).valid || parseSemver(version2) === void 0) { @@ -80291,7 +80530,7 @@ function installedVersionDir(workspace, id, version2) { "Use a valid extension ID and X.Y.Z version." ); } - const dir = import_path42.default.join(installedRootDir(workspace), id, version2); + const dir = import_path44.default.join(installedRootDir(workspace), id, version2); assertInsideWorkspace(workspace.rootDir, dir); return dir; } @@ -80335,12 +80574,12 @@ function emptyPermissionGrants() { return { schemaVersion: EXTENSION_STATE_SCHEMA_VERSION, grants: {} }; } function readValidatedJson(filePath, schema, empty, label) { - if (!(0, import_fs39.existsSync)(filePath)) { + if (!(0, import_fs41.existsSync)(filePath)) { return { value: empty, diagnostics: [], exists: false }; } let text15; try { - text15 = (0, import_fs39.readFileSync)(filePath, "utf8"); + text15 = (0, import_fs41.readFileSync)(filePath, "utf8"); } catch (cause) { return { value: empty, @@ -80390,10 +80629,10 @@ function readValidatedJson(filePath, schema, empty, label) { return { value: result.data, diagnostics: [], exists: true }; } function extensionStatePath(workspace) { - return import_path42.default.join(extensionsDir(workspace), EXTENSION_STATE_FILE_NAME); + return import_path44.default.join(extensionsDir(workspace), EXTENSION_STATE_FILE_NAME); } function permissionGrantsPath(workspace) { - return import_path42.default.join(extensionsDir(workspace), EXTENSION_GRANTS_FILE_NAME); + return import_path44.default.join(extensionsDir(workspace), EXTENSION_GRANTS_FILE_NAME); } function readExtensionState(workspace) { const { value, diagnostics, exists } = readValidatedJson( @@ -80574,9 +80813,9 @@ function resolveEntrypoint(installedDir, entrypoint) { if (problem !== void 0) { throw new ExtensionError("SBE012", `entrypoint "${entrypoint}": ${problem}.`, "Fix the extension manifest."); } - const resolved2 = import_path43.default.join(installedDir, ...entrypoint.split("/")); - const relative = import_path43.default.relative(installedDir, resolved2); - if (relative.startsWith("..") || import_path43.default.isAbsolute(relative)) { + const resolved2 = import_path45.default.join(installedDir, ...entrypoint.split("/")); + const relative = import_path45.default.relative(installedDir, resolved2); + if (relative.startsWith("..") || import_path45.default.isAbsolute(relative)) { throw new ExtensionError( "SBE012", `entrypoint "${entrypoint}" escapes the installed extension directory.`, @@ -80584,9 +80823,9 @@ function resolveEntrypoint(installedDir, entrypoint) { ); } let current = installedDir; - for (const segment of relative.split(import_path43.default.sep)) { - current = import_path43.default.join(current, segment); - const stat = (0, import_fs40.lstatSync)(current, { throwIfNoEntry: false }); + for (const segment of relative.split(import_path45.default.sep)) { + current = import_path45.default.join(current, segment); + const stat = (0, import_fs42.lstatSync)(current, { throwIfNoEntry: false }); if (stat === void 0) { throw new ExtensionError( "SBE012", @@ -80602,7 +80841,7 @@ function resolveEntrypoint(installedDir, entrypoint) { ); } } - const finalStat = (0, import_fs40.lstatSync)(resolved2, { throwIfNoEntry: false }); + const finalStat = (0, import_fs42.lstatSync)(resolved2, { throwIfNoEntry: false }); if (finalStat === void 0 || !finalStat.isFile()) { throw new ExtensionError( "SBE012", @@ -81133,14 +81372,14 @@ async function probeExtensionHandshake(enabled, options = {}) { } function compatibilityOf(workspace, record4, specbridgeVersion) { try { - const manifestPath = import_path44.default.join( + const manifestPath = import_path46.default.join( installedVersionDir(workspace, record4.id, record4.version), EXTENSION_MANIFEST_FILE_NAME ); - if (!(0, import_fs41.existsSync)(manifestPath)) { + if (!(0, import_fs43.existsSync)(manifestPath)) { return { compatibility: "unknown", deprecated: false }; } - const parsed = parseExtensionManifest((0, import_fs41.readFileSync)(manifestPath, "utf8")); + const parsed = parseExtensionManifest((0, import_fs43.readFileSync)(manifestPath, "utf8")); if (parsed.manifest === void 0) { return { compatibility: "unknown", deprecated: false }; } @@ -82518,10 +82757,10 @@ function registerTemplateApplyTool(server, context) { } // ../../packages/registry/dist/index.js -var import_fs42 = require("fs"); -var import_path45 = __toESM(require("path"), 1); -var import_fs43 = require("fs"); -var import_path46 = __toESM(require("path"), 1); +var import_fs44 = require("fs"); +var import_path47 = __toESM(require("path"), 1); +var import_fs45 = require("fs"); +var import_path48 = __toESM(require("path"), 1); var BUILTIN_REGISTRY_INDEX_JSON = '{\n "schemaVersion": "1.0.0",\n "name": "specbridge-examples",\n "updatedAt": "2026-01-01T00:00:00.000Z",\n "extensions": [\n {\n "id": "example-analyzer",\n "displayName": "example-analyzer",\n "description": "Deterministic spec diagnostics contributed by the example-analyzer analyzer extension.",\n "kind": "analyzer",\n "latestVersion": "1.0.0",\n "versions": [\n {\n "version": "1.0.0",\n "archiveUrl": "https://example.invalid/specbridge-extensions/example-analyzer-1.0.0.specbridge-extension.zip",\n "sha256": "e6e0948a315b09e53bd18997dce21888af9adbb3997fbf82955399dcf3252a19",\n "manifest": {\n "protocolVersion": "1.0.0",\n "compatibility": {\n "specbridge": ">=0.7.1 <2.0.0"\n },\n "permissions": {\n "specRead": true,\n "repositoryRead": false,\n "repositoryWrite": false,\n "network": false,\n "childProcess": false,\n "environmentVariables": []\n }\n }\n }\n ],\n "repository": "https://github.com/HelloThisWorld/specbridge",\n "license": "MIT",\n "keywords": [\n "analyzer",\n "specbridge-extension"\n ]\n },\n {\n "id": "example-exporter",\n "displayName": "example-exporter",\n "description": "Candidate export files produced by the example-exporter exporter extension.",\n "kind": "exporter",\n "latestVersion": "1.0.0",\n "versions": [\n {\n "version": "1.0.0",\n "archiveUrl": "https://example.invalid/specbridge-extensions/example-exporter-1.0.0.specbridge-extension.zip",\n "sha256": "68f42755a4e56d0e318012ec8c0e3b093e44429182ca93b02d9fb4ce2ec308a3",\n "manifest": {\n "protocolVersion": "1.0.0",\n "compatibility": {\n "specbridge": ">=0.7.1 <2.0.0"\n },\n "permissions": {\n "specRead": true,\n "repositoryRead": false,\n "repositoryWrite": false,\n "network": false,\n "childProcess": false,\n "environmentVariables": []\n }\n }\n }\n ],\n "repository": "https://github.com/HelloThisWorld/specbridge",\n "license": "MIT",\n "keywords": [\n "exporter",\n "specbridge-extension"\n ]\n },\n {\n "id": "example-runner",\n "displayName": "example-runner",\n "description": "An out-of-process runner adapter provided by the example-runner extension.",\n "kind": "runner",\n "latestVersion": "1.0.0",\n "versions": [\n {\n "version": "1.0.0",\n "archiveUrl": "https://example.invalid/specbridge-extensions/example-runner-1.0.0.specbridge-extension.zip",\n "sha256": "5ef3db937d872bfe09495695e9ecb0a3cf3beaf9e006fabdc2972ef55ace80ef",\n "manifest": {\n "protocolVersion": "1.0.0",\n "compatibility": {\n "specbridge": ">=0.7.1 <2.0.0"\n },\n "permissions": {\n "specRead": true,\n "repositoryRead": true,\n "repositoryWrite": true,\n "network": false,\n "childProcess": false,\n "environmentVariables": []\n }\n }\n }\n ],\n "repository": "https://github.com/HelloThisWorld/specbridge",\n "license": "MIT",\n "keywords": [\n "runner",\n "specbridge-extension"\n ]\n },\n {\n "id": "example-template-provider",\n "displayName": "example-template-provider",\n "description": "Spec template packs contributed by the example-template-provider template-provider extension.",\n "kind": "template-provider",\n "latestVersion": "1.0.0",\n "versions": [\n {\n "version": "1.0.0",\n "archiveUrl": "https://example.invalid/specbridge-extensions/example-template-provider-1.0.0.specbridge-extension.zip",\n "sha256": "f7caa11a13473f0891cc8d237ec4f9f2962a2dd1bd2baba4e9d01570de29044b",\n "manifest": {\n "protocolVersion": "1.0.0",\n "compatibility": {\n "specbridge": ">=0.7.1 <2.0.0"\n },\n "permissions": {\n "specRead": false,\n "repositoryRead": false,\n "repositoryWrite": false,\n "network": false,\n "childProcess": false,\n "environmentVariables": []\n }\n }\n }\n ],\n "repository": "https://github.com/HelloThisWorld/specbridge",\n "license": "MIT",\n "keywords": [\n "template-provider",\n "specbridge-extension"\n ]\n },\n {\n "id": "example-verifier",\n "displayName": "example-verifier",\n "description": "Verification diagnostics contributed by the example-verifier verifier extension.",\n "kind": "verifier",\n "latestVersion": "1.0.0",\n "versions": [\n {\n "version": "1.0.0",\n "archiveUrl": "https://example.invalid/specbridge-extensions/example-verifier-1.0.0.specbridge-extension.zip",\n "sha256": "d531c9078fcbeef6573a95773eefafd409d798bac1223c83748e0229ae0225bf",\n "manifest": {\n "protocolVersion": "1.0.0",\n "compatibility": {\n "specbridge": ">=0.7.1 <2.0.0"\n },\n "permissions": {\n "specRead": true,\n "repositoryRead": false,\n "repositoryWrite": false,\n "network": false,\n "childProcess": false,\n "environmentVariables": []\n }\n }\n }\n ],\n "repository": "https://github.com/HelloThisWorld/specbridge",\n "license": "MIT",\n "keywords": [\n "verifier",\n "specbridge-extension"\n ]\n }\n ]\n}\n'; var REGISTRY_ERROR_CODES = { SBR001: "registry not found", @@ -82677,20 +82916,20 @@ var cachedRegistrySchema = external_exports.object({ index: registryIndexSchema }).passthrough(); function registryCacheDir(workspace) { - return import_path45.default.join(workspace.sidecarDir, REGISTRY_CACHE_DIR_NAME); + return import_path47.default.join(workspace.sidecarDir, REGISTRY_CACHE_DIR_NAME); } function registryCachePath(workspace, name) { - const target = import_path45.default.join(registryCacheDir(workspace), `${name}.json`); + const target = import_path47.default.join(registryCacheDir(workspace), `${name}.json`); assertInsideWorkspace(workspace.rootDir, target); return target; } function readRegistryCache(workspace, name) { const filePath = registryCachePath(workspace, name); - if (!(0, import_fs42.existsSync)(filePath)) { + if (!(0, import_fs44.existsSync)(filePath)) { return { diagnostics: [] }; } try { - const parsed = cachedRegistrySchema.safeParse(JSON.parse((0, import_fs42.readFileSync)(filePath, "utf8"))); + const parsed = cachedRegistrySchema.safeParse(JSON.parse((0, import_fs44.readFileSync)(filePath, "utf8"))); if (!parsed.success) { return { diagnostics: [ @@ -82730,9 +82969,9 @@ function resolveRegistryIndex(workspace, source) { return { sourceName: source.name, index: parsed.index, origin: "builtin", diagnostics: [] }; } if (source.type === "local-file") { - const filePath = import_path45.default.resolve(workspace.rootDir, source.file); + const filePath = import_path47.default.resolve(workspace.rootDir, source.file); assertInsideWorkspace(workspace.rootDir, filePath); - if (!(0, import_fs42.existsSync)(filePath)) { + if (!(0, import_fs44.existsSync)(filePath)) { return { sourceName: source.name, index: { schemaVersion: "1.0.0", name: source.name, updatedAt: "unknown", extensions: [] }, @@ -82747,7 +82986,7 @@ function resolveRegistryIndex(workspace, source) { ] }; } - const text15 = (0, import_fs42.readFileSync)(filePath, "utf8"); + const text15 = (0, import_fs44.readFileSync)(filePath, "utf8"); const parsed = parseRegistryIndex(text15); if (parsed.index === void 0) { throw new RegistryError( @@ -82843,7 +83082,7 @@ var registriesConfigSchema = external_exports.object({ registries: external_exports.array(registrySourceSchema).max(20) }).passthrough(); function registriesConfigPath(workspace) { - return import_path46.default.join(workspace.sidecarDir, REGISTRIES_FILE_NAME); + return import_path48.default.join(workspace.sidecarDir, REGISTRIES_FILE_NAME); } function defaultRegistriesConfig() { return { @@ -82853,12 +83092,12 @@ function defaultRegistriesConfig() { } function readRegistriesConfig(workspace) { const filePath = registriesConfigPath(workspace); - if (!(0, import_fs43.existsSync)(filePath)) { + if (!(0, import_fs45.existsSync)(filePath)) { return { config: defaultRegistriesConfig(), diagnostics: [], exists: false }; } let parsed; try { - parsed = JSON.parse((0, import_fs43.readFileSync)(filePath, "utf8")); + parsed = JSON.parse((0, import_fs45.readFileSync)(filePath, "utf8")); } catch (cause) { return { config: defaultRegistriesConfig(), @@ -84230,826 +84469,290 @@ function registerJobCancelTool(server, context) { }); } -// ../../packages/mcp-server/src/tools/mission-tools.ts -function missionDeps(context, workspace) { - return { - workspace, - clock: context.clock, - idFactory: context.idFactory, - host: "mcp" - }; -} -var missionIdArg = external_exports.string().min(1).max(64).describe("Mission id (m-\u2026) from mission_begin or mission_status"); -var missionSummaryShape = { - missionId: external_exports.string(), - name: external_exports.string(), - status: external_exports.string(), - specName: external_exports.string().optional(), - openQuestions: external_exports.number().int(), - decisions: external_exports.number().int(), - contracts: external_exports.number().int(), - contractReady: external_exports.boolean().optional() -}; -function summarize3(context, workspace, missionId) { - const mission = requireMissionState(workspace, missionId); - const coverage = readCoverage(workspace, missionId); - return { - missionId: mission.missionId, - name: mission.name, - status: mission.status, - ...mission.specName !== void 0 ? { specName: mission.specName } : {}, - openQuestions: mission.counters.openQuestions, - decisions: mission.counters.decisions, - contracts: mission.counters.contracts, - ...coverage !== void 0 ? { contractReady: coverage.contractReady } : {} - }; -} -function registerMissionBeginTool(server, context) { - registerDefinedTool(server, context, { - name: "mission_begin", - title: "Begin a mission", - description: "Begin Mission Discovery from a high-level product direction. Creates the durable mission record under .specbridge/missions/. Discovery itself is a conversation: record every material visible exchange with mission_record_turn and its structured meaning with mission_assess.", - annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }, - inputSchema: { - name: external_exports.string().min(1).max(120).describe("Short mission name (also the default spec name)"), - goal: external_exports.string().min(1).max(4e3).describe("The user's product direction, verbatim") - }, - outputSchema: { mission: external_exports.object(missionSummaryShape) }, - handler: async (args) => { - const workspace = context.requireWorkspace(); - const mission = beginMission(missionDeps(context, workspace), { name: args.name, goal: args.goal }); - return { - text: `Mission ${mission.missionId} (${mission.name}) created in status ${mission.status}. Record the user's direction as the first turn.`, - structured: { mission: summarize3(context, workspace, mission.missionId) } - }; - } - }); -} -function registerMissionStatusTool(server, context) { - registerDefinedTool(server, context, { - name: "mission_status", - title: "List missions", - description: "List missions (newest first) with lifecycle status, counters, and readiness. Read-only.", - annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, - inputSchema: {}, - outputSchema: { missions: external_exports.array(external_exports.object(missionSummaryShape)) }, - handler: async () => { - const workspace = context.requireWorkspace(); - const listed = listMissions(workspace); - const missions = listed.missions.slice(0, 50).map((mission) => summarize3(context, workspace, mission.missionId)); - return { - text: missions.length === 0 ? "No missions exist. Begin one with mission_begin." : missions.map((mission) => `- ${mission.missionId} ${mission.status} (${mission.name})`).join("\n"), - structured: { missions } - }; - } - }); +// ../../packages/autonomy/dist/index.js +var import_fs46 = require("fs"); +var import_path49 = __toESM(require("path"), 1); +var import_fs47 = require("fs"); +var import_path50 = __toESM(require("path"), 1); +var SEAL_STATUSES = [ + /** Drafted from mission state; not yet authorized by a human. */ + "DRAFT", + /** A human authorized it. The only status delegated execution may use. */ + "SEALED", + /** A later seal replaced it. Historical, still readable, never executable. */ + "SUPERSEDED", + /** Explicitly withdrawn by a human. Delegated execution stops immediately. */ + "REVOKED" +]; +var SEALED_AUTHORITY_KINDS = [ + /** The product goal, verbatim. */ + "GOAL", + /** What the product explicitly will not do. */ + "NON_GOALS", + /** Recorded human decisions with provenance. */ + "DECISIONS", + /** Constitution rules: the invariants the product is built under. */ + "CONSTITUTION", + /** Architecture decision records. */ + "ADRS", + /** Product engineering contracts and their revisions. */ + "CONTRACTS", + /** Individual requirements inside those contracts. */ + "REQUIREMENTS", + /** How the product is judged done. */ + "ACCEPTANCE_CRITERIA", + /** The spending ceiling and resource policy the run may consume. */ + "RESOURCE_POLICY", + /** The autonomy/delegation policy in force at seal time. */ + "AUTONOMY_POLICY" +]; +var SUPERVISION_STATUSES = [ + /** Registered for supervision; no driver has been started yet. */ + "REGISTERED", + /** A driver holds a live lease and is executing. */ + "ACTIVE", + /** Waiting on a resource, a backoff, or a scheduled wake time. */ + "SLEEPING", + /** The previous driver died; a replacement is being started. */ + "RESTARTING", + /** Final: the job reached a terminal status. */ + "RELEASED" +]; +var SUPERVISION_ACTIONS = [ + "LEASE_ACQUIRED", + "LEASE_RENEWED", + "LEASE_EXPIRED_RECLAIMED", + "DRIVER_STARTED", + "DRIVER_EXITED_CLEANLY", + "DRIVER_DIED", + /** A person explicitly resumed; the give-up ledger starts fresh. */ + "RESET_ON_EXPLICIT_RESUME", + /** Planned work exhausted with the closure gate unsatisfied; the closure lifecycle takes over. */ + "CLOSURE_HANDOFF", + "DRIVER_RESTARTED", + "ATTEMPT_RECONCILED", + "WAKE_SCHEDULED", + "WOKEN_ON_SCHEDULE", + "WOKEN_ON_RESOURCE_RETURN", + "PROVIDER_HEALTH_RECHECKED", + "LOCAL_RUNTIME_RESTARTED", + "STALE_PROCESS_REAPED", + "RESTART_BUDGET_EXHAUSTED", + "SESSION_BUDGET_REACHED", + "INDEFINITE_WAIT_CLASSIFIED", + "RELEASED_ON_TERMINAL_STATUS", + "RELEASED_ON_AUTHORITY_STOP" +]; +var PREFLIGHT_CAPABILITIES = [ + "WORKSPACE_WRITABLE", + "REPOSITORY_CLEAN_ENOUGH", + "GIT_AVAILABLE", + "DISK_SPACE", + "PROTECTED_PATHS_CONFIGURED", + "SEAL_PRESENT", + "SEAL_COMPLETE", + "AUTONOMY_POLICY_COMPLETE", + "SUPERVISOR_CAPABLE", + "STRONG_WORKER_AVAILABLE", + "LOCAL_MODEL_STARTABLE", + "API_FALLBACK_AUTHORIZED", + "SPEND_CEILING_DECLARED", + "TRUSTED_VERIFICATION_CONFIGURED", + "PACKAGE_MANAGER_AVAILABLE", + "PACKAGE_REGISTRY_REACHABLE", + "BUILD_TOOLCHAIN_AVAILABLE", + "CONTAINER_RUNTIME", + "CONTAINER_COMPOSE", + "BROWSER_RUNTIME", + "TOOLSMITH_POLICY_SUFFICIENT", + "ENVIRONMENT_POLICY_SUFFICIENT", + "KNOWN_CREDENTIALS_PRESENT", + "CONTROL_PLANE_REPAIR_CONFIGURED" +]; +var PREFLIGHT_OUTCOMES = [ + /** Observed present and usable right now. */ + "READY", + /** Absent now, and the runtime is authorized and able to provide it. */ + "SATISFIABLE_AUTONOMOUSLY", + /** Absent, and only a human can supply it. Blocks an unattended launch. */ + "HUMAN_REQUIRED", + /** Not needed for this mission's declared surfaces. */ + "NOT_APPLICABLE", + /** The probe itself could not reach a conclusion. Never a pass. */ + "UNKNOWN" +]; +var PREFLIGHT_VERDICTS = [ + /** Every required capability is READY or autonomously satisfiable. */ + "OVERNIGHT_READY", + /** At least one capability needs a person before launch. */ + "HUMAN_ACTION_REQUIRED", + /** A probe could not decide something required. Never launch on this. */ + "INDETERMINATE" +]; +var TOOLSMITH_REQUEST_STATUSES = [ + "REQUESTED", + "GRANTED", + "DENIED", + "APPLIED", + "FAILED" +]; +var TOOLSMITH_DENIAL_REASONS = [ + "CAPABILITY_NOT_ENABLED", + "TOOLSMITH_DISABLED", + "GRANT_BUDGET_EXHAUSTED", + "TARGET_OUTSIDE_WORKSPACE", + "TARGET_PROTECTED_PATH", + "REGISTRY_NOT_ALLOWED", + "REQUIRES_ADMIN_PRIVILEGE", + "WOULD_CREATE_AUTHORITY", + "DOWNLOAD_TOO_LARGE", + "PORTABLE_ALTERNATIVE_REQUIRED" +]; +var TOOL_INSTALL_SCOPES = [ + "PROJECT_LOCAL", + "PORTABLE", + "CONTAINERIZED", + "USER_LOCAL" +]; +var SERVICE_KINDS = [ + "CONTAINER", + "COMPOSE_PROJECT", + "PROCESS", + "DATABASE", + "MESSAGE_BROKER", + "CACHE", + "APPLICATION_SERVER", + "FRONTEND_SERVER", + "WORKER" +]; +var READINESS_PROBE_KINDS = [ + /** The process/container exists and has not exited. Weakest evidence. */ + "PROCESS_ALIVE", + /** A TCP connection is accepted. */ + "TCP_CONNECT", + /** An HTTP request returns an expected status. */ + "HTTP_STATUS", + /** An HTTP body matches an expected pattern. */ + "HTTP_BODY", + /** A command exits zero inside or against the service. */ + "COMMAND_EXIT", + /** A protocol-level handshake succeeded (SQL ping, broker metadata, …). */ + "PROTOCOL_HANDSHAKE", + /** The container runtime reports its own healthcheck as healthy. */ + "CONTAINER_HEALTHCHECK" +]; +var ENVIRONMENT_STATUSES = [ + "PLANNED", + "PROVISIONING", + "WAITING_READY", + "READY", + "DEGRADED", + "REPAIRING", + "FAILED", + "STOPPED" +]; +var SERVICE_STATUSES = [ + "PENDING", + "STARTING", + "WAITING_READY", + "READY", + "UNHEALTHY", + "RESTARTING", + "FAILED", + "STOPPED" +]; +var ENVIRONMENT_FAILURE_KINDS = [ + "RUNTIME_UNAVAILABLE", + "IMAGE_PULL_FAILED", + "PORT_CONFLICT", + "READINESS_TIMEOUT", + "SERVICE_CRASHED", + "DEPENDENCY_UNREADY", + "CONFIGURATION_INVALID", + "RESOURCE_EXHAUSTED", + "UNKNOWN" +]; +var BROWSER_STEP_KINDS = [ + "NAVIGATE", + "CLICK", + "TYPE", + "FILL_FORM", + "SUBMIT", + "WAIT_FOR_SELECTOR", + "WAIT_FOR_TEXT", + "EXPECT_SELECTOR", + "EXPECT_TEXT", + "EXPECT_ABSENT", + "EXPECT_URL", + "EXPECT_NO_CONSOLE_ERRORS", + "EXPECT_NO_FAILED_REQUESTS", + "SCREENSHOT", + "SET_VIEWPORT", + "RELOAD", + "SWITCH_CONTEXT" +]; +var BROWSER_ASSERTION_STEPS = [ + "EXPECT_SELECTOR", + "EXPECT_TEXT", + "EXPECT_ABSENT", + "EXPECT_URL", + "EXPECT_NO_CONSOLE_ERRORS", + "EXPECT_NO_FAILED_REQUESTS" +]; +var BROWSER_SCENARIO_STATUSES = [ + "PASSED", + "FAILED", + "ERRORED", + "SKIPPED_NO_RUNTIME", + "NOT_RUN" +]; +var BROWSER_EVIDENCE_KINDS = [ + "SCREENSHOT", + "DOM_SNAPSHOT", + "CONSOLE_LOG", + "NETWORK_FAILURES", + "STEP_TRACE", + "VIEWPORT_MATRIX" +]; +var UX_FINDING_KINDS = [ + "OVERLAPPING_ELEMENTS", + "CLIPPED_CONTENT", + "UNREADABLE_LAYOUT", + "BROKEN_RESPONSIVE", + "DEAD_INTERACTION", + "MISSING_LOADING_STATE", + "MISSING_ERROR_STATE", + "MISSING_EMPTY_STATE", + "INCONSISTENT_UX", + "UNUSABLE_CONTROL", + "VISUAL_REGRESSION", + "AESTHETIC_PREFERENCE" +]; +var UX_FINDING_SEVERITIES = ["MATERIAL", "MINOR", "COSMETIC"]; +var UX_CRITIQUE_VERDICTS = [ + "NO_MATERIAL_FINDINGS", + "MATERIAL_FINDINGS", + "NOT_RUN", + "INSUFFICIENT_EVIDENCE" +]; +var CLOSURE_STATUSES = [ + /** Nothing claims to implement this item. */ + "NOT_STARTED", + /** Work exists and is in flight. */ + "IN_PROGRESS", + /** Implementation exists and is attributed, but nothing has proven it. */ + "IMPLEMENTED", + /** Trusted evidence demonstrates the item holds. The only closing state. */ + "VERIFIED", + /** A human explicitly waived it, with a recorded reason. */ + "WAIVED", + /** Explicitly out of scope for this seal, by recorded decision. */ + "NOT_APPLICABLE" +]; +var CLOSING_STATUSES = ["VERIFIED", "WAIVED", "NOT_APPLICABLE"]; +function isClosingStatus(status) { + return CLOSING_STATUSES.includes(status); } -function registerMissionReadTool(server, context) { - registerDefinedTool(server, context, { - name: "mission_read", - title: "Read one mission", - description: "Read one mission in depth. `view` selects the record family: overview (default), facts, decisions, questions, conversation, coverage, constitution, adrs, or ccrs. Bounded; read-only.", - annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, - inputSchema: { - missionId: missionIdArg, - view: external_exports.enum(["overview", "facts", "decisions", "questions", "conversation", "coverage", "constitution", "adrs", "ccrs"]).optional().describe("Which record family to read (default overview)"), - limit: external_exports.number().int().min(1).max(200).optional().describe("Bounded page size for list views") - }, - outputSchema: { - mission: external_exports.object(missionSummaryShape), - view: external_exports.string(), - records: external_exports.array(external_exports.record(external_exports.unknown())) - }, - handler: async (args) => { - const workspace = context.requireWorkspace(); - const deps = missionDeps(context, workspace); - observeSpecApproval(deps, args.missionId); - const view = args.view ?? "overview"; - const limit = args.limit ?? 50; - let records = []; - switch (view) { - case "overview": { - const overview = describeMission(deps, args.missionId); - records = [ - { - goal: overview.mission.goal, - nonGoals: overview.mission.nonGoals, - targetUsers: overview.mission.targetUsers, - constraints: overview.mission.constraints, - successCriteria: overview.mission.successCriteria, - assumptions: overview.mission.assumptions, - constitutionVersion: overview.constitutionVersion, - activeConstitutionRules: overview.activeConstitutionRules, - contractCount: overview.contractCount, - adrCount: overview.adrCount, - blockingQuestions: overview.blockingQuestions, - openCcrs: overview.openCcrs - } - ]; - break; - } - case "facts": - records = readFacts(workspace, args.missionId).slice(-limit); - break; - case "decisions": - records = readDecisions(workspace, args.missionId).slice(-limit); - break; - case "questions": - records = readQuestions(workspace, args.missionId).slice(-limit); - break; - case "conversation": - records = readTurns(workspace, args.missionId, { limit }).turns; - break; - case "coverage": { - const coverage = readCoverage(workspace, args.missionId); - records = coverage !== void 0 ? [coverage] : []; - break; - } - case "constitution": { - const constitution = readConstitution(workspace, args.missionId); - records = constitution !== void 0 ? [constitution] : []; - break; - } - case "adrs": - records = readAdrs(workspace, args.missionId).slice(-limit); - break; - case "ccrs": - records = readCcrs(workspace, args.missionId).slice(-limit); - break; - } - return { - text: `${view}: ${records.length} record(s).`, - structured: { mission: summarize3(context, workspace, args.missionId), view, records } - }; - } - }); -} -function registerMissionRecordTurnTool(server, context) { - registerDefinedTool(server, context, { - name: "mission_record_turn", - title: "Record a visible discovery turn", - description: "Persist one USER-VISIBLE discovery exchange verbatim: what the user said, or what the agent visibly asked, interpreted, or presented. Turns are the provenance roots every decision traces back to. Never record hidden reasoning \u2014 only what both sides could see.", - annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }, - inputSchema: { - missionId: missionIdArg, - speaker: external_exports.enum(TURN_SPEAKERS).describe("Who produced the visible text"), - kind: external_exports.enum(TURN_KINDS).describe("What kind of exchange this is"), - text: external_exports.string().min(1).max(8e3).describe("The visible text, verbatim"), - inReplyTo: external_exports.string().max(64).optional().describe("Turn id this replies to"), - refs: external_exports.array(external_exports.string().max(64)).max(30).optional().describe("Record ids this turn addresses") - }, - outputSchema: { turnId: external_exports.string(), missionStatus: external_exports.string() }, - handler: async (args) => { - const workspace = context.requireWorkspace(); - const result = recordTurn(missionDeps(context, workspace), args.missionId, { - speaker: args.speaker, - kind: args.kind, - text: args.text, - inReplyTo: args.inReplyTo, - refs: args.refs - }); - return { - text: `Recorded ${result.turn.turnId} (${args.speaker} ${args.kind}). Mission is ${result.mission.status}.`, - structured: { turnId: result.turn.turnId, missionStatus: result.mission.status } - }; - } - }); -} -var factInput = external_exports.object({ - statement: external_exports.string().min(1).max(4e3), - provenance: external_exports.enum(MISSION_PROVENANCE_KINDS), - sourceTurnId: external_exports.string().max(64).optional(), - topics: external_exports.array(external_exports.enum(DISCOVERY_TOPICS)).max(10).optional(), - supersedesFactId: external_exports.string().max(64).optional() -}); -var questionInput = external_exports.object({ - question: external_exports.string().min(1).max(4e3), - whyItMatters: external_exports.string().min(1).max(4e3), - topics: external_exports.array(external_exports.enum(DISCOVERY_TOPICS)).max(10).optional(), - affectedSurfaces: external_exports.array(external_exports.enum(IRREVERSIBLE_SURFACES)).max(10).optional(), - materiality: external_exports.enum(MATERIALITY_LEVELS).optional(), - options: external_exports.array(external_exports.string().max(2e3)).max(10).optional(), - sourceTurnId: external_exports.string().max(64).optional() -}); -var decisionInput = external_exports.object({ - decision: external_exports.string().min(1).max(4e3), - rationale: external_exports.string().max(4e3).optional(), - provenance: external_exports.enum(MISSION_PROVENANCE_KINDS), - sourceTurnId: external_exports.string().max(64).optional(), - questionId: external_exports.string().max(64).optional(), - topics: external_exports.array(external_exports.enum(DISCOVERY_TOPICS)).max(10).optional(), - marksNotApplicable: external_exports.array(external_exports.enum(DISCOVERY_TOPICS)).max(10).optional(), - supersedesDecisionId: external_exports.string().max(64).optional() -}); -var constitutionRuleInput = external_exports.object({ - statement: external_exports.string().min(1).max(4e3), - rationale: external_exports.string().max(4e3).optional(), - decisionIds: external_exports.array(external_exports.string().max(64)).min(1).max(30), - affectedContractIds: external_exports.array(external_exports.string().max(64)).max(30).optional(), - guardPatterns: external_exports.array(external_exports.string().min(1).max(200)).max(10).optional(), - supersedesRuleId: external_exports.string().max(64).optional() -}); -var adrInput = external_exports.object({ - title: external_exports.string().min(1).max(512), - context: external_exports.string().min(1).max(4e3), - decision: external_exports.string().min(1).max(4e3), - alternatives: external_exports.array(external_exports.string().max(4e3)).max(20).optional(), - rationale: external_exports.string().min(1).max(4e3), - consequences: external_exports.array(external_exports.string().max(4e3)).max(20).optional(), - revisitConditions: external_exports.array(external_exports.string().max(4e3)).max(20).optional(), - decisionIds: external_exports.array(external_exports.string().max(64)).max(30).optional(), - turnIds: external_exports.array(external_exports.string().max(64)).max(30).optional(), - supersedesAdrId: external_exports.string().max(64).optional() -}); -var contractInput = external_exports.object({ - title: external_exports.string().min(1).max(512), - summary: external_exports.string().min(1).max(4e3), - classification: external_exports.enum(["public", "internal"]), - compatibilityPolicy: external_exports.enum(["frozen", "additive-only", "evolving", "internal"]), - dependsOn: external_exports.array(external_exports.string().max(64)).max(30).optional(), - requirements: external_exports.array(external_exports.object({ statement: external_exports.string().min(1).max(4e3), decisionIds: external_exports.array(external_exports.string().max(64)).max(30).optional() })).min(1).max(60), - invariants: external_exports.array( - external_exports.object({ - statement: external_exports.string().min(1).max(4e3), - constitutionRuleIds: external_exports.array(external_exports.string().max(64)).max(30).optional(), - guardPatterns: external_exports.array(external_exports.string().min(1).max(200)).max(10).optional() - }) - ).max(60).optional(), - decisionIds: external_exports.array(external_exports.string().max(64)).min(1).max(30), - turnIds: external_exports.array(external_exports.string().max(64)).max(30).optional() -}); -function registerMissionAssessTool(server, context) { - registerDefinedTool(server, context, { - name: "mission_assess", - title: "Record a structured discovery assessment", - description: "Submit the STRUCTURED meaning of the discovery conversation: facts, questions, decisions, constitution rules, ADRs, contracts, and mission field updates. SpecBridge governs every record: decisions need safe provenance (a user-provenance decision must cite a USER turn), question materiality passes the deterministic irreversibility screen (it can only be RAISED), durable artifacts must trace to recorded decisions, and coverage recomputes deterministically. Blocking questions prevent CONTRACT_READY; implementation-detail questions never do.", - annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }, - inputSchema: { - missionId: missionIdArg, - facts: external_exports.array(factInput).max(20).optional(), - questions: external_exports.array(questionInput).max(20).optional(), - decisions: external_exports.array(decisionInput).max(20).optional(), - constitutionRules: external_exports.array(constitutionRuleInput).max(10).optional(), - adrs: external_exports.array(adrInput).max(10).optional(), - contracts: external_exports.array(contractInput).max(10).optional(), - missionUpdates: external_exports.object({ - nonGoals: external_exports.array(external_exports.string().max(4e3)).max(50).optional(), - targetUsers: external_exports.array(external_exports.string().max(4e3)).max(50).optional(), - constraints: external_exports.array(external_exports.string().max(4e3)).max(50).optional(), - successCriteria: external_exports.array(external_exports.string().max(4e3)).max(50).optional(), - assumptions: external_exports.array( - external_exports.object({ - statement: external_exports.string().min(1).max(4e3), - topics: external_exports.array(external_exports.enum(DISCOVERY_TOPICS)).max(10).optional(), - questionId: external_exports.string().max(64).optional() - }) - ).max(50).optional() - }).optional() - }, - outputSchema: { - missionStatus: external_exports.string(), - contractReady: external_exports.boolean(), - factIds: external_exports.array(external_exports.string()), - questionIds: external_exports.array(external_exports.string()), - decisionIds: external_exports.array(external_exports.string()), - constitutionRuleIds: external_exports.array(external_exports.string()), - adrIds: external_exports.array(external_exports.string()), - contractIds: external_exports.array(external_exports.string()), - materialityRaised: external_exports.array( - external_exports.object({ questionId: external_exports.string(), from: external_exports.string(), to: external_exports.string() }) - ), - blockingQuestionIds: external_exports.array(external_exports.string()), - unresolvedRequiredTopics: external_exports.array(external_exports.string()) - }, - handler: async (args) => { - const workspace = context.requireWorkspace(); - const result = recordAssessment(missionDeps(context, workspace), args.missionId, { - facts: args.facts, - questions: args.questions, - decisions: args.decisions, - constitutionRules: args.constitutionRules, - adrs: args.adrs, - contracts: args.contracts, - missionUpdates: args.missionUpdates - }); - const raised = result.materialityRaised.map((entry) => `${entry.questionId} raised ${entry.from} \u2192 ${entry.to}`).join("; "); - return { - text: `Recorded ${result.factIds.length} fact(s), ${result.questionIds.length} question(s), ${result.decisionIds.length} decision(s), ${result.constitutionRuleIds.length} rule(s), ${result.adrIds.length} ADR(s), ${result.contractIds.length} contract(s). Mission is ${result.mission.status}; contract-ready: ${result.coverage.contractReady}.` + (raised.length > 0 ? ` Materiality screen: ${raised}.` : ""), - structured: { - missionStatus: result.mission.status, - contractReady: result.coverage.contractReady, - factIds: result.factIds, - questionIds: result.questionIds, - decisionIds: result.decisionIds, - constitutionRuleIds: result.constitutionRuleIds, - adrIds: result.adrIds, - contractIds: result.contractIds, - materialityRaised: result.materialityRaised, - blockingQuestionIds: result.coverage.blockingQuestionIds, - unresolvedRequiredTopics: result.coverage.unresolvedRequiredTopics - } - }; - } - }); -} -function registerMissionQuestionsTool(server, context) { - registerDefinedTool(server, context, { - name: "mission_questions", - title: "Open discovery questions", - description: "The open questions with materiality and why each matters. Blocking questions gate CONTRACT_READY. Read-only.", - annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, - inputSchema: { missionId: missionIdArg }, - outputSchema: { - questions: external_exports.array( - external_exports.object({ - questionId: external_exports.string(), - question: external_exports.string(), - whyItMatters: external_exports.string(), - materiality: external_exports.string(), - topics: external_exports.array(external_exports.string()), - options: external_exports.array(external_exports.string()) - }) - ) - }, - handler: async (args) => { - const workspace = context.requireWorkspace(); - requireMissionState(workspace, args.missionId); - const questions = readQuestions(workspace, args.missionId).filter((question) => question.status === "open").map((question) => ({ - questionId: question.questionId, - question: question.question, - whyItMatters: question.whyItMatters, - materiality: question.materiality, - topics: [...question.topics], - options: [...question.options] - })); - return { - text: questions.length === 0 ? "No open questions." : questions.map((question) => `- ${question.questionId} [${question.materiality}] ${question.question}`).join("\n"), - structured: { questions } - }; - } - }); -} -function registerMissionAnswerTool(server, context) { - registerDefinedTool(server, context, { - name: "mission_answer", - title: "Record the user\u2019s answer to a question", - description: "Record the USER'S answer to one open discovery question: an answering user turn plus a known-from-user decision bound to it. Relay their words; never answer on their behalf.", - annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }, - inputSchema: { - missionId: missionIdArg, - questionId: external_exports.string().min(1).max(64), - answer: external_exports.string().min(1).max(4e3).describe("The user's answer, verbatim"), - marksNotApplicable: external_exports.array(external_exports.enum(DISCOVERY_TOPICS)).max(10).optional() - }, - outputSchema: { - decisionId: external_exports.string(), - missionStatus: external_exports.string(), - contractReady: external_exports.boolean() - }, - handler: async (args) => { - const workspace = context.requireWorkspace(); - const result = answerQuestion(missionDeps(context, workspace), args.missionId, { - questionId: args.questionId, - answer: args.answer, - marksNotApplicable: args.marksNotApplicable - }); - return { - text: `Recorded ${result.decision.decisionId}. Mission is ${result.mission.status}; contract-ready: ${result.coverage.contractReady}.`, - structured: { - decisionId: result.decision.decisionId, - missionStatus: result.mission.status, - contractReady: result.coverage.contractReady - } - }; - } - }); -} -function registerMissionSynthesizeTool(server, context) { - registerDefinedTool(server, context, { - name: "mission_synthesize", - title: "Synthesize the Kiro spec", - description: "Move a coverage-complete mission to CONTRACT_READY and compile its contract set into Kiro spec candidates: requirements.md, design.md, and OBJECTIVE-oriented tasks.md \u2014 through the existing creation machinery. Approval stays entirely human (`specbridge spec approve \u2026`); nothing here or anywhere on MCP can approve a stage. Fails closed when blocking questions or required topics remain.", - annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }, - inputSchema: { - missionId: missionIdArg, - specName: external_exports.string().max(64).optional().describe("Spec name (default: the mission name)") - }, - outputSchema: { - specName: external_exports.string(), - objectiveCount: external_exports.number().int(), - files: external_exports.array(external_exports.object({ fileName: external_exports.string(), bytes: external_exports.number().int() })) - }, - handler: async (args) => { - const workspace = context.requireWorkspace(); - const deps = missionDeps(context, workspace); - markContractReady(deps, args.missionId); - const result = synthesizeMissionSpec(deps, args.missionId, { specName: args.specName }); - return { - text: `Synthesized spec "${result.specName}" with ${result.objectiveCount} objective(s). The user approves it with: specbridge spec approve ${result.specName} --stage requirements|design|tasks.`, - structured: { - specName: result.specName, - objectiveCount: result.objectiveCount, - files: result.files - } - }; - } - }); -} -function registerContractListTool(server, context) { - registerDefinedTool(server, context, { - name: "contract_list", - title: "List product contracts", - description: "The mission\u2019s product contract registry (current revisions) plus the Architecture Constitution. Read-only.", - annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, - inputSchema: { missionId: missionIdArg }, - outputSchema: { - constitutionVersion: external_exports.number().int(), - rules: external_exports.array(external_exports.object({ ruleId: external_exports.string(), statement: external_exports.string(), status: external_exports.string() })), - contracts: external_exports.array( - external_exports.object({ - contractId: external_exports.string(), - revision: external_exports.number().int(), - title: external_exports.string(), - classification: external_exports.string(), - compatibilityPolicy: external_exports.string() - }) - ) - }, - handler: async (args) => { - const workspace = context.requireWorkspace(); - requireMissionState(workspace, args.missionId); - const constitution = readConstitution(workspace, args.missionId); - const contracts = readContractRegistry(workspace, args.missionId).map((contract) => ({ - contractId: contract.contractId, - revision: contract.revision, - title: contract.title, - classification: contract.classification, - compatibilityPolicy: contract.compatibilityPolicy - })); - return { - text: contracts.map((contract) => `- ${contract.contractId} r${contract.revision} ${contract.title}`).join("\n") || "No contracts recorded.", - structured: { - constitutionVersion: constitution?.version ?? 0, - rules: (constitution?.rules ?? []).map((rule) => ({ - ruleId: rule.ruleId, - statement: rule.statement, - status: rule.status - })), - contracts - } - }; - } - }); -} -function registerContractReadTool(server, context) { - registerDefinedTool(server, context, { - name: "contract_read", - title: "Read one product contract", - description: "One contract in depth: requirements, invariants, dependencies, provenance, revision lineage. Read-only.", - annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, - inputSchema: { - missionId: missionIdArg, - contractId: external_exports.string().min(1).max(64), - revision: external_exports.number().int().min(1).optional().describe("A specific revision (default: current)") - }, - outputSchema: { contract: external_exports.record(external_exports.unknown()) }, - handler: async (args) => { - const workspace = context.requireWorkspace(); - requireMissionState(workspace, args.missionId); - const contract = readContract(workspace, args.missionId, args.contractId, args.revision); - if (contract === void 0) { - return { - text: `Contract ${args.contractId}${args.revision !== void 0 ? ` r${args.revision}` : ""} does not exist.`, - structured: { contract: {} } - }; - } - return { - text: `${contract.contractId} r${contract.revision}: ${contract.title} \u2014 ${contract.requirements.length} requirement(s), ${contract.invariants.length} invariant(s).`, - structured: { contract } - }; - } - }); -} -function registerContractChangeRequestTool(server, context) { - registerDefinedTool(server, context, { - name: "contract_change_request", - title: "Create a contract change request", - description: "Create a durable ContractChangeRequest against a product contract. Anyone may RAISE one; only the human decides it (CLI: `specbridge mission ccr --approve|--reject`). A material request (public contract, frozen/additive policy, or irreversible surface) lands NEEDS_HUMAN and stops affected execution. This tool can never approve anything.", - annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }, - inputSchema: { - missionId: missionIdArg, - contractId: external_exports.string().min(1).max(64), - problem: external_exports.string().min(1).max(4e3).describe("What the current contract cannot express"), - proposal: external_exports.string().min(1).max(4e3).describe("The proposed change"), - affected: external_exports.array(external_exports.string().max(2e3)).max(30).optional().describe("Areas the change would touch") - }, - outputSchema: { - ccrId: external_exports.string(), - status: external_exports.string(), - material: external_exports.boolean() - }, - handler: async (args) => { - const workspace = context.requireWorkspace(); - const result = createContractChangeRequest(missionDeps(context, workspace), args.missionId, { - contractId: args.contractId, - problem: args.problem, - proposal: args.proposal, - affected: args.affected, - raisedBy: "mcp" - }); - return { - text: `${result.ccr.ccrId} created (${result.ccr.status}). ` + (result.material ? "It is material: the human decides it with `specbridge mission ccr \u2026 --approve|--reject`." : "It is recorded for the next contract review."), - structured: { ccrId: result.ccr.ccrId, status: result.ccr.status, material: result.material } - }; - } - }); -} - -// ../../packages/intake/dist/index.js -var import_crypto18 = require("crypto"); -var import_fs45 = require("fs"); -var import_path48 = __toESM(require("path"), 1); -var import_fs46 = require("fs"); -var import_path49 = __toESM(require("path"), 1); - -// ../../packages/autonomy/dist/index.js -var import_fs44 = require("fs"); -var import_path47 = __toESM(require("path"), 1); -var SEAL_STATUSES = [ - /** Drafted from mission state; not yet authorized by a human. */ - "DRAFT", - /** A human authorized it. The only status delegated execution may use. */ - "SEALED", - /** A later seal replaced it. Historical, still readable, never executable. */ - "SUPERSEDED", - /** Explicitly withdrawn by a human. Delegated execution stops immediately. */ - "REVOKED" -]; -var SEALED_AUTHORITY_KINDS = [ - /** The product goal, verbatim. */ - "GOAL", - /** What the product explicitly will not do. */ - "NON_GOALS", - /** Recorded human decisions with provenance. */ - "DECISIONS", - /** Constitution rules: the invariants the product is built under. */ - "CONSTITUTION", - /** Architecture decision records. */ - "ADRS", - /** Product engineering contracts and their revisions. */ - "CONTRACTS", - /** Individual requirements inside those contracts. */ - "REQUIREMENTS", - /** How the product is judged done. */ - "ACCEPTANCE_CRITERIA", - /** The spending ceiling and resource policy the run may consume. */ - "RESOURCE_POLICY", - /** The autonomy/delegation policy in force at seal time. */ - "AUTONOMY_POLICY" -]; -var SUPERVISION_STATUSES = [ - /** Registered for supervision; no driver has been started yet. */ - "REGISTERED", - /** A driver holds a live lease and is executing. */ - "ACTIVE", - /** Waiting on a resource, a backoff, or a scheduled wake time. */ - "SLEEPING", - /** The previous driver died; a replacement is being started. */ - "RESTARTING", - /** Final: the job reached a terminal status. */ - "RELEASED" -]; -var SUPERVISION_ACTIONS = [ - "LEASE_ACQUIRED", - "LEASE_RENEWED", - "LEASE_EXPIRED_RECLAIMED", - "DRIVER_STARTED", - "DRIVER_EXITED_CLEANLY", - "DRIVER_DIED", - /** A person explicitly resumed; the give-up ledger starts fresh. */ - "RESET_ON_EXPLICIT_RESUME", - /** Planned work exhausted with the closure gate unsatisfied; the closure lifecycle takes over. */ - "CLOSURE_HANDOFF", - "DRIVER_RESTARTED", - "ATTEMPT_RECONCILED", - "WAKE_SCHEDULED", - "WOKEN_ON_SCHEDULE", - "WOKEN_ON_RESOURCE_RETURN", - "PROVIDER_HEALTH_RECHECKED", - "LOCAL_RUNTIME_RESTARTED", - "STALE_PROCESS_REAPED", - "RESTART_BUDGET_EXHAUSTED", - "SESSION_BUDGET_REACHED", - "INDEFINITE_WAIT_CLASSIFIED", - "RELEASED_ON_TERMINAL_STATUS", - "RELEASED_ON_AUTHORITY_STOP" -]; -var PREFLIGHT_CAPABILITIES = [ - "WORKSPACE_WRITABLE", - "REPOSITORY_CLEAN_ENOUGH", - "GIT_AVAILABLE", - "DISK_SPACE", - "PROTECTED_PATHS_CONFIGURED", - "SEAL_PRESENT", - "SEAL_COMPLETE", - "AUTONOMY_POLICY_COMPLETE", - "SUPERVISOR_CAPABLE", - "STRONG_WORKER_AVAILABLE", - "LOCAL_MODEL_STARTABLE", - "API_FALLBACK_AUTHORIZED", - "SPEND_CEILING_DECLARED", - "TRUSTED_VERIFICATION_CONFIGURED", - "PACKAGE_MANAGER_AVAILABLE", - "PACKAGE_REGISTRY_REACHABLE", - "BUILD_TOOLCHAIN_AVAILABLE", - "CONTAINER_RUNTIME", - "CONTAINER_COMPOSE", - "BROWSER_RUNTIME", - "TOOLSMITH_POLICY_SUFFICIENT", - "ENVIRONMENT_POLICY_SUFFICIENT", - "KNOWN_CREDENTIALS_PRESENT", - "CONTROL_PLANE_REPAIR_CONFIGURED" -]; -var PREFLIGHT_OUTCOMES = [ - /** Observed present and usable right now. */ - "READY", - /** Absent now, and the runtime is authorized and able to provide it. */ - "SATISFIABLE_AUTONOMOUSLY", - /** Absent, and only a human can supply it. Blocks an unattended launch. */ - "HUMAN_REQUIRED", - /** Not needed for this mission's declared surfaces. */ - "NOT_APPLICABLE", - /** The probe itself could not reach a conclusion. Never a pass. */ - "UNKNOWN" -]; -var PREFLIGHT_VERDICTS = [ - /** Every required capability is READY or autonomously satisfiable. */ - "OVERNIGHT_READY", - /** At least one capability needs a person before launch. */ - "HUMAN_ACTION_REQUIRED", - /** A probe could not decide something required. Never launch on this. */ - "INDETERMINATE" -]; -var TOOLSMITH_REQUEST_STATUSES = [ - "REQUESTED", - "GRANTED", - "DENIED", - "APPLIED", - "FAILED" -]; -var TOOLSMITH_DENIAL_REASONS = [ - "CAPABILITY_NOT_ENABLED", - "TOOLSMITH_DISABLED", - "GRANT_BUDGET_EXHAUSTED", - "TARGET_OUTSIDE_WORKSPACE", - "TARGET_PROTECTED_PATH", - "REGISTRY_NOT_ALLOWED", - "REQUIRES_ADMIN_PRIVILEGE", - "WOULD_CREATE_AUTHORITY", - "DOWNLOAD_TOO_LARGE", - "PORTABLE_ALTERNATIVE_REQUIRED" -]; -var TOOL_INSTALL_SCOPES = [ - "PROJECT_LOCAL", - "PORTABLE", - "CONTAINERIZED", - "USER_LOCAL" -]; -var SERVICE_KINDS = [ - "CONTAINER", - "COMPOSE_PROJECT", - "PROCESS", - "DATABASE", - "MESSAGE_BROKER", - "CACHE", - "APPLICATION_SERVER", - "FRONTEND_SERVER", - "WORKER" -]; -var READINESS_PROBE_KINDS = [ - /** The process/container exists and has not exited. Weakest evidence. */ - "PROCESS_ALIVE", - /** A TCP connection is accepted. */ - "TCP_CONNECT", - /** An HTTP request returns an expected status. */ - "HTTP_STATUS", - /** An HTTP body matches an expected pattern. */ - "HTTP_BODY", - /** A command exits zero inside or against the service. */ - "COMMAND_EXIT", - /** A protocol-level handshake succeeded (SQL ping, broker metadata, …). */ - "PROTOCOL_HANDSHAKE", - /** The container runtime reports its own healthcheck as healthy. */ - "CONTAINER_HEALTHCHECK" -]; -var ENVIRONMENT_STATUSES = [ - "PLANNED", - "PROVISIONING", - "WAITING_READY", - "READY", - "DEGRADED", - "REPAIRING", - "FAILED", - "STOPPED" -]; -var SERVICE_STATUSES = [ - "PENDING", - "STARTING", - "WAITING_READY", - "READY", - "UNHEALTHY", - "RESTARTING", - "FAILED", - "STOPPED" -]; -var ENVIRONMENT_FAILURE_KINDS = [ - "RUNTIME_UNAVAILABLE", - "IMAGE_PULL_FAILED", - "PORT_CONFLICT", - "READINESS_TIMEOUT", - "SERVICE_CRASHED", - "DEPENDENCY_UNREADY", - "CONFIGURATION_INVALID", - "RESOURCE_EXHAUSTED", - "UNKNOWN" -]; -var BROWSER_STEP_KINDS = [ - "NAVIGATE", - "CLICK", - "TYPE", - "FILL_FORM", - "SUBMIT", - "WAIT_FOR_SELECTOR", - "WAIT_FOR_TEXT", - "EXPECT_SELECTOR", - "EXPECT_TEXT", - "EXPECT_ABSENT", - "EXPECT_URL", - "EXPECT_NO_CONSOLE_ERRORS", - "EXPECT_NO_FAILED_REQUESTS", - "SCREENSHOT", - "SET_VIEWPORT", - "RELOAD", - "SWITCH_CONTEXT" -]; -var BROWSER_ASSERTION_STEPS = [ - "EXPECT_SELECTOR", - "EXPECT_TEXT", - "EXPECT_ABSENT", - "EXPECT_URL", - "EXPECT_NO_CONSOLE_ERRORS", - "EXPECT_NO_FAILED_REQUESTS" -]; -var BROWSER_SCENARIO_STATUSES = [ - "PASSED", - "FAILED", - "ERRORED", - "SKIPPED_NO_RUNTIME", - "NOT_RUN" -]; -var BROWSER_EVIDENCE_KINDS = [ - "SCREENSHOT", - "DOM_SNAPSHOT", - "CONSOLE_LOG", - "NETWORK_FAILURES", - "STEP_TRACE", - "VIEWPORT_MATRIX" -]; -var UX_FINDING_KINDS = [ - "OVERLAPPING_ELEMENTS", - "CLIPPED_CONTENT", - "UNREADABLE_LAYOUT", - "BROKEN_RESPONSIVE", - "DEAD_INTERACTION", - "MISSING_LOADING_STATE", - "MISSING_ERROR_STATE", - "MISSING_EMPTY_STATE", - "INCONSISTENT_UX", - "UNUSABLE_CONTROL", - "VISUAL_REGRESSION", - "AESTHETIC_PREFERENCE" -]; -var UX_FINDING_SEVERITIES = ["MATERIAL", "MINOR", "COSMETIC"]; -var UX_CRITIQUE_VERDICTS = [ - "NO_MATERIAL_FINDINGS", - "MATERIAL_FINDINGS", - "NOT_RUN", - "INSUFFICIENT_EVIDENCE" -]; -var CLOSURE_STATUSES = [ - /** Nothing claims to implement this item. */ - "NOT_STARTED", - /** Work exists and is in flight. */ - "IN_PROGRESS", - /** Implementation exists and is attributed, but nothing has proven it. */ - "IMPLEMENTED", - /** Trusted evidence demonstrates the item holds. The only closing state. */ - "VERIFIED", - /** A human explicitly waived it, with a recorded reason. */ - "WAIVED", - /** Explicitly out of scope for this seal, by recorded decision. */ - "NOT_APPLICABLE" -]; var CLOSURE_EVIDENCE_KINDS = [ "TRUSTED_VERIFICATION", "UNIT_TEST", @@ -85178,33 +84881,107 @@ var ZERO_TOUCH_OUTCOMES = [ "NOT_RUN" ]; var CERTIFICATION_VERDICTS = ["CERTIFIED", "NOT_CERTIFIED", "INCOMPLETE"]; +var SBA_CODES = { + SBA001: "autonomy disabled by policy", + SBA002: "mission seal not found", + SBA003: "mission seal invalid", + SBA004: "mission seal not executable", + SBA005: "mission seal incomplete", + SBA006: "autonomy policy drift since seal", + SBA007: "product authority required", + SBA008: "supervisor lease held by another owner", + SBA009: "supervisor state invalid", + SBA010: "supervisor restart budget exhausted", + SBA011: "overnight preflight refused launch", + SBA012: "toolsmith capability denied", + SBA013: "toolsmith grant budget exhausted", + SBA014: "environment plan invalid", + SBA015: "environment provisioning failed", + SBA016: "environment runtime unavailable", + SBA017: "browser scenario invalid", + SBA018: "browser runtime unavailable", + SBA019: "ux critique rejected", + SBA020: "contract closure incomplete", + SBA021: "closure budget exhausted", + SBA022: "control plane repair refused", + SBA023: "control plane repair would weaken an invariant", + SBA024: "autonomy record invalid", + SBA025: "certification run invalid" +}; +var AutonomyError = class extends Error { + code; + category; + remediation; + details; + retryable; + constructor(code, message2, options = {}) { + super(message2); + this.name = "AutonomyError"; + this.code = code; + this.category = SBA_CODES[code]; + this.remediation = options.remediation ?? []; + this.details = options.details ?? {}; + this.retryable = options.retryable ?? false; + } +}; +function now3(deps) { + return (deps.clock ?? (() => /* @__PURE__ */ new Date()))(); +} +function nowIso2(deps) { + return now3(deps).toISOString(); +} +var ID_PATTERN4 = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/; +function assertAutonomyId(kind, id) { + if (!ID_PATTERN4.test(id)) { + throw new AutonomyError("SBA024", `Invalid ${kind} id "${id}".`, { + remediation: ["Ids are generated by SpecBridge; pass one returned by an autonomy operation."], + details: { kind, id } + }); + } + return id; +} function autonomyDir(workspace) { return assertInsideWorkspace( workspace.rootDir, - import_path47.default.join(workspace.rootDir, ".specbridge", "autonomy") + import_path49.default.join(workspace.rootDir, ".specbridge", "autonomy") ); } function autonomyPath(workspace, ...segments) { - return assertInsideWorkspace(workspace.rootDir, import_path47.default.join(autonomyDir(workspace), ...segments)); + return assertInsideWorkspace(workspace.rootDir, import_path49.default.join(autonomyDir(workspace), ...segments)); } function readJsonRecord(file, parse3) { - if (!(0, import_fs44.existsSync)(file)) return void 0; + if (!(0, import_fs46.existsSync)(file)) return void 0; try { - return parse3(JSON.parse((0, import_fs44.readFileSync)(file, "utf8"))); + return parse3(JSON.parse((0, import_fs46.readFileSync)(file, "utf8"))); } catch { return void 0; } } function listJsonRecords(dir, parse3) { - if (!(0, import_fs44.existsSync)(dir)) return []; + if (!(0, import_fs46.existsSync)(dir)) return []; const out = []; - for (const entry2 of (0, import_fs44.readdirSync)(dir).sort()) { + for (const entry2 of (0, import_fs46.readdirSync)(dir).sort()) { if (!entry2.endsWith(".json")) continue; - const value = readJsonRecord(import_path47.default.join(dir, entry2), parse3); + const value = readJsonRecord(import_path49.default.join(dir, entry2), parse3); if (value !== void 0) out.push(value); } return out; } +function readJsonl2(file, parse3, limit = 5e3) { + if (!(0, import_fs46.existsSync)(file)) return { entries: [], skipped: 0 }; + const lines = (0, import_fs46.readFileSync)(file, "utf8").split("\n").filter((line) => line.trim().length > 0); + const slice = lines.slice(-limit); + const entries = []; + let skipped = 0; + for (const line of slice) { + try { + entries.push(parse3(JSON.parse(line))); + } catch { + skipped += 1; + } + } + return { entries, skipped }; +} var SEAL_LIMITS = { maxShortTextChars: 200, maxTextChars: 4e3, @@ -85310,11 +85087,30 @@ var sealBindingSchema = external_exports.object({ function sealsDir(workspace) { return autonomyPath(workspace, "seals"); } +function sealFile(workspace, sealId) { + assertAutonomyId("seal", sealId); + return autonomyPath(workspace, "seals", `${sealId}.json`); +} +function bindingFile(workspace, jobId) { + assertAutonomyId("job", jobId); + return autonomyPath(workspace, "bindings", `${jobId}.json`); +} +function readSeal(workspace, sealId) { + return readJsonRecord(sealFile(workspace, sealId), (raw) => missionSealSchema.parse(raw)); +} function listSeals(workspace, missionId) { const seals = listJsonRecords(sealsDir(workspace), (raw) => missionSealSchema.parse(raw)); const filtered = missionId === void 0 ? seals : seals.filter((s) => s.missionId === missionId); return filtered.sort((a2, b) => a2.createdAt.localeCompare(b.createdAt)); } +function readSealBinding(workspace, jobId) { + return readJsonRecord(bindingFile(workspace, jobId), (raw) => sealBindingSchema.parse(raw)); +} +function readJobSeal(workspace, jobId) { + const binding = readSealBinding(workspace, jobId); + if (binding === void 0) return void 0; + return readSeal(workspace, binding.sealId); +} var DELEGATED_SURFACES = Object.freeze({ "implementation-structure": "implementation", "internal-architecture": "internalArchitecture", @@ -85427,6 +85223,16 @@ var supervisionLogEntrySchema = external_exports.object({ detail: text23.optional(), generation: external_exports.number().int().min(0).optional() }).passthrough(); +function supervisionLogFile(workspace) { + return autonomyPath(workspace, "supervisor", "log.jsonl"); +} +function readSupervisionLog(workspace, limit = 500) { + return readJsonl2( + supervisionLogFile(workspace), + (raw) => supervisionLogEntrySchema.parse(raw), + limit + ).entries; +} var shortText33 = external_exports.string().max(200); var text32 = external_exports.string().max(4e3); var capabilityCheckSchema = external_exports.object({ @@ -85528,6 +85334,24 @@ var CANONICAL_SCOPE = Object.freeze({ USER_LOCAL_CLI: "USER_LOCAL", BROWSER_RUNTIME: "USER_LOCAL" }); +function toolsmithDir(workspace, jobId) { + assertAutonomyId("job", jobId); + return autonomyPath(workspace, "toolsmith", jobId); +} +function listToolsmithRequests(workspace, jobId) { + return listJsonRecords( + toolsmithDir(workspace, jobId), + (raw) => toolsmithRequestSchema.parse(raw) + ).sort((a2, b) => a2.requestedAt.localeCompare(b.requestedAt)); +} +function writesFileDirectly(capability) { + return capability === "PROJECT_LOCAL_SCRIPT" || capability === "CODE_GENERATION"; +} +function countSelfCreatedTools(workspace, jobId) { + return listToolsmithRequests(workspace, jobId).filter( + (request) => request.status === "APPLIED" && writesFileDirectly(request.capability) + ).length; +} var PACKAGE_MANAGER_INSTALL_ARGV = Object.freeze({ pnpm: ["install", "--frozen-lockfile=false"], npm: ["install"], @@ -85766,6 +85590,12 @@ var browserScenarioResultSchema = external_exports.object({ /** The first failing step's detail, hoisted for the report. */ failureDetail: text62.optional() }).passthrough(); +function listBrowserResults(workspace) { + return listJsonRecords( + autonomyPath(workspace, "browser", "results"), + (raw) => browserScenarioResultSchema.parse(raw) + ).sort((a2, b) => a2.startedAt.localeCompare(b.startedAt)); +} var shortText72 = external_exports.string().max(200); var text72 = external_exports.string().max(4e3); var uxFindingSchema = external_exports.object({ @@ -85803,6 +85633,9 @@ var uxCritiqueSchema = external_exports.object({ /** True when the critique was recorded but may not create work. */ advisoryOnly: external_exports.boolean().default(false) }).passthrough(); +function listCritiques(workspace) { + return listJsonRecords(autonomyPath(workspace, "critic"), (raw) => uxCritiqueSchema.parse(raw)); +} var shortText82 = external_exports.string().max(200); var text82 = external_exports.string().max(4e3); var closureEvidenceRefSchema = external_exports.object({ @@ -85913,6 +85746,92 @@ var gapWorkItemSchema = external_exports.object({ /** The audit that generated it. */ auditId: shortText82 }).passthrough(); +function summarizeClosure(entries) { + const totals = { + total: entries.length, + verified: 0, + implemented: 0, + inProgress: 0, + notStarted: 0, + waived: 0, + notApplicable: 0 + }; + for (const entry2 of entries) { + switch (entry2.status) { + case "VERIFIED": + totals.verified += 1; + break; + case "IMPLEMENTED": + totals.implemented += 1; + break; + case "IN_PROGRESS": + totals.inProgress += 1; + break; + case "NOT_STARTED": + totals.notStarted += 1; + break; + case "WAIVED": + totals.waived += 1; + break; + case "NOT_APPLICABLE": + totals.notApplicable += 1; + break; + default: + break; + } + } + return totals; +} +function closureRatio(totals) { + if (totals.total === 0) return null; + return (totals.verified + totals.waived + totals.notApplicable) / totals.total; +} +function missionMayComplete(ledger, policy) { + const unclosed = ledger.entries.filter((entry2) => !isClosingStatus(entry2.status)); + if (ledger.entries.length === 0) { + return { + mayComplete: false, + reason: "the closure ledger is empty: a seal with no auditable contract items cannot be shown to be complete", + unclosedIds: [] + }; + } + if (unclosed.length > 0) { + return { + mayComplete: false, + reason: `${unclosed.length} sealed contract item(s) are not closed on trusted evidence`, + unclosedIds: unclosed.map((entry2) => entry2.itemId).slice(0, 100) + }; + } + if (policy.requireReleaseQualification && !ledger.releaseQualificationPassed) { + return { + mayComplete: false, + reason: "every item closes, but the release qualification has not passed against the integrated tree", + unclosedIds: [] + }; + } + if (policy.requireReproducibility && !ledger.reproducibilityPassed) { + return { + mayComplete: false, + reason: "every item closes, but reproducibility has not been demonstrated from a clean environment", + unclosedIds: [] + }; + } + return { + mayComplete: true, + reason: `all ${ledger.entries.length} sealed contract item(s) are closed`, + unclosedIds: [] + }; +} +function closureLedgerFile(workspace, jobId) { + assertAutonomyId("job", jobId); + return autonomyPath(workspace, "closure", jobId, "ledger.json"); +} +function readClosureLedger(workspace, jobId) { + return readJsonRecord( + closureLedgerFile(workspace, jobId), + (raw) => closureLedgerSchema.parse(raw) + ); +} var shortText92 = external_exports.string().max(200); var text92 = external_exports.string().max(4e3); var systemStepSchema = external_exports.object({ @@ -86021,6 +85940,7 @@ var reproducibilityResultSchema = external_exports.object({ inconclusiveReason: text10.optional(), failureDetail: text10.optional() }).passthrough(); +var TELEMETRY_SCHEMA_VERSION = "1.0.0"; var shortText112 = external_exports.string().max(200); var text11 = external_exports.string().max(4e3); var autonomyTelemetrySchema = external_exports.object({ @@ -86095,13 +86015,1478 @@ var INTERVENTION_EVENTS = Object.freeze({ // needs a person; only the event name differed. budget_exhausted: "the job stopped on an exhausted budget, needing an explicit user action" }); -var shortText122 = external_exports.string().max(200); +function deriveAutonomyTelemetry(deps, input) { + const read = readJobState(deps.workspace, input.jobId); + const job = read.kind === "ok" ? read.job : void 0; + const events = safeEvents(deps.workspace, input.jobId); + const counters = job?.autonomyCounters; + const interventions = []; + let providerFailovers = 0; + let providerFailures = 0; + let quotaWaits = 0; + let contextRollovers = 0; + let supervisorWakeups = 0; + let escalationsAfterBoundary = 0; + const bindingForBoundary = readSealBinding(deps.workspace, input.jobId); + const boundary = bindingForBoundary !== void 0 ? readSealedAt(deps, bindingForBoundary.sealId) : void 0; + const boundaryMs = boundary !== void 0 ? Date.parse(boundary) : Number.NaN; + const afterBoundary = (at) => { + if (!Number.isFinite(boundaryMs)) return true; + const eventMs = Date.parse(at); + return !Number.isFinite(eventMs) || eventMs >= boundaryMs; + }; + for (const event of events) { + const type = String(event["type"] ?? ""); + const at = String(event["at"] ?? ""); + const explanation = INTERVENTION_EVENTS[type]; + if (explanation !== void 0 && afterBoundary(at)) { + interventions.push({ at, kind: type, detail: explanation }); + } + if (type === "authority_escalated" && afterBoundary(at)) escalationsAfterBoundary += 1; + if (type === "worker_escalated" || type === "local_harness_to_subscription_escalated") { + providerFailovers += 1; + } + if (type === "local_model_stopped" || type === "local_harness_unavailable") providerFailures += 1; + if (type === "quota_exhausted" || type === "task_deferred" || type === "resource_wait_started") { + quotaWaits += 1; + } + if (type === "context_rollover" || type === "fresh_context_selected") contextRollovers += 1; + if (type === "driver_restarted" || type === "supervisor_attached") supervisorWakeups += 1; + } + const supervisionLog = readSupervisionLog(deps.workspace, 2e3); + supervisorWakeups += supervisionLog.filter( + (entry2) => entry2.action === "WOKEN_ON_SCHEDULE" || entry2.action === "WOKEN_ON_RESOURCE_RETURN" + ).length; + if (job !== void 0 && requiresHumanAttention(job.status) && job.status !== "NEEDS_AUTHORITY" && interventions.length === 0) { + interventions.push({ + at: job.updatedAt, + kind: `status:${job.status}`, + detail: job.blocker?.message ?? `the job is ${job.status} and cannot proceed without a person` + }); + } + const ledger = readClosureLedger(deps.workspace, input.jobId); + const totals = ledger !== void 0 ? summarizeClosure(ledger.entries) : void 0; + const toolsmith = listToolsmithRequests(deps.workspace, input.jobId); + const browserResults = listBrowserResults(deps.workspace).filter( + (result) => result.jobId === input.jobId + ); + const critiques = listCritiques(deps.workspace).filter( + (critique) => critique.jobId === input.jobId + ); + const binding = readSealBinding(deps.workspace, input.jobId); + const telemetry = autonomyTelemetrySchema.parse({ + schemaVersion: TELEMETRY_SCHEMA_VERSION, + jobId: input.jobId, + ...binding !== void 0 ? { sealId: binding.sealId, missionId: binding.missionId } : {}, + recordedAt: nowIso2(deps), + jobStatus: job?.status ?? "UNKNOWN", + humanInterventionsAfterSeal: interventions.length, + humanAuthorityEscalations: counters?.authorityEscalations ?? 0, + humanAuthorityEscalationsAfterSeal: boundary === void 0 ? null : escalationsAfterBoundary, + boundaryStartedAt: boundary ?? null, + autonomousRecoveryCount: counters?.autonomousRecoveries ?? 0, + providerFailovers, + providerFailures, + quotaWaits: Math.max(quotaWaits, counters?.resourceWaits ?? 0), + contextRollovers: Math.max(contextRollovers, counters?.contextRollovers ?? 0), + toolsmithActions: toolsmith.length, + selfCreatedTools: countSelfCreatedTools(deps.workspace, input.jobId), + toolchainRepairs: counters?.toolchainRepairs ?? 0, + environmentRepairs: counters?.environmentRepairs ?? 0, + controlPlaneRepairs: counters?.controlPlaneRepairs ?? 0, + gapClosureCycles: ledger?.gapCycles ?? counters?.gapClosureCycles ?? 0, + systemQualificationCycles: ledger?.systemCycles ?? counters?.systemQualificationCycles ?? 0, + browserScenariosRun: browserResults.length, + uxCritiquesRun: critiques.length, + driverRestarts: counters?.driverRestarts ?? 0, + supervisorWakeups, + elapsedWallTimeMs: input.elapsedWallTimeMs ?? elapsedFromJob(job), + // Provider-reported only. `null` when nothing reported, which is a + // different fact from "it was free". + reportedTokens: job?.counters.reportedTokens ?? null, + reportedCostUsd: job?.counters.reportedCostUsd ?? null, + contractClosureRatio: totals !== void 0 ? closureRatio(totals) : null, + ...totals !== void 0 ? { + closure: { + total: totals.total, + verified: totals.verified, + implemented: totals.implemented, + notStarted: totals.notStarted, + waived: totals.waived + } + } : {}, + interventions: interventions.slice(0, 200) + }); + return telemetry; +} +function elapsedFromJob(job) { + if (job === void 0) return null; + const created = Date.parse(job.createdAt); + const updated = Date.parse(job.finalizedAt ?? job.updatedAt); + if (!Number.isFinite(created) || !Number.isFinite(updated)) return null; + return Math.max(0, updated - created); +} +function readSealedAt(deps, sealId) { + try { + return readSeal(deps.workspace, sealId)?.sealedAt; + } catch { + return void 0; + } +} +function safeEvents(workspace, jobId) { + try { + return readJobEvents(workspace, jobId, { limit: 1e4 }).events; + } catch { + return []; + } +} +var EXECUTION_TELEMETRY_REPORT_SCHEMA_VERSION = "1.0.0"; +var count3 = external_exports.number().int().min(0); +var shortText122 = external_exports.string().max(512); +var boundedText7 = external_exports.string().max(2e3); +var ratio2 = external_exports.number().min(0).max(1).nullable(); +var countMap = external_exports.record(external_exports.string(), count3); +var fractionMetricSchema = external_exports.object({ + numerator: count3.nullable(), + denominator: count3.nullable(), + value: ratio2 +}).strict(); +var tokenCoverageSchema = external_exports.object({ + attempts: count3, + withAny: count3, + withInput: count3, + withOutput: count3, + ratio: ratio2, + complete: external_exports.boolean() +}).strict(); +var tokenTelemetrySchema = external_exports.object({ + /** Sum of every reported input-token field; null when none reported. */ + inputTokens: count3.nullable(), + /** Sum of every reported output-token field; null when none reported. */ + outputTokens: count3.nullable(), + /** Sum of known components, even when coverage is partial. */ + knownTokens: count3.nullable(), + /** Total only when every attempt reported both components. */ + completeTokens: count3.nullable(), + coverage: tokenCoverageSchema +}).strict(); +var workAccountingSchema = external_exports.enum([ + "completed", + "failed", + "cancelled", + "waiting", + "not-ready", + "human-authority-pending", + "research-pending", + "context-pending" +]); +var diagnosticSchema = external_exports.object({ + code: shortText122, + severity: external_exports.enum(["info", "warning", "error"]), + message: boundedText7, + evidenceRefs: external_exports.array(shortText122).max(20).default([]) +}).strict(); +var phaseResearchSchema = external_exports.object({ + considered: count3, + avoided: count3, + reused: count3, + newCalls: count3, + quick: count3, + deep: count3, + failed: count3 +}).strict(); +var executionTelemetryReportSchema = external_exports.object({ + schemaVersion: external_exports.literal(EXECUTION_TELEMETRY_REPORT_SCHEMA_VERSION), + jobId: shortText122, + missionId: shortText122.nullable(), + generatedAt: shortText122, + period: external_exports.object({ + startedAt: shortText122, + endedAt: shortText122.nullable(), + durationMs: count3.nullable(), + activeExecutionMs: count3.nullable() + }).strict(), + provenance: external_exports.object({ + sourceJobId: shortText122, + jobGraphRevision: count3, + objectiveGraphRevisions: countMap, + executionLedgerWatermark: external_exports.string().regex(/^[a-f0-9]{64}$/), + eventWatermark: count3, + specbridgeVersion: shortText122.nullable(), + sealId: shortText122.nullable(), + sealedAuthorityDigest: shortText122.nullable(), + runtimePolicyChanged: external_exports.boolean().nullable(), + configuration: external_exports.object({ + secondaryBuildStrategy: shortText122, + researchStrategy: shortText122, + runnerProfiles: external_exports.array(shortText122).max(50) + }).strict() + }).strict(), + outcome: external_exports.object({ + status: external_exports.enum(["COMPLETED", "FAILED", "CANCELLED", "BLOCKED", "WAITING"]), + authoritativeJobStatus: shortText122, + finalOutcome: boundedText7.nullable(), + verification: external_exports.enum(["PASS", "FAIL", "UNAVAILABLE"]), + closure: external_exports.enum(["PASS", "FAIL", "UNAVAILABLE"]) + }).strict(), + work: external_exports.object({ + total: count3, + byKind: countMap, + accounting: external_exports.record(workAccountingSchema, count3), + completedImplementation: count3, + objectives: external_exports.array(external_exports.object({ + objectiveNodeId: shortText122, + graphRevision: count3.nullable(), + total: count3, + accounting: external_exports.record(workAccountingSchema, count3), + implementationAttempts: count3, + secondaryAttempts: count3, + strongBuilderAttempts: count3 + }).strict()).max(200), + units: external_exports.array(external_exports.object({ + workUnitId: shortText122, + objectiveNodeId: shortText122, + kind: shortText122, + status: shortText122, + accounting: workAccountingSchema, + builderPath: external_exports.enum(["SECONDARY", "SECONDARY_REPAIR", "STRONG", "STRONG_FALLBACK", "NONE", "UNKNOWN"]), + implementationAttempts: count3, + verification: external_exports.enum(["PASS", "FAIL", "PENDING", "UNAVAILABLE"]), + integration: external_exports.enum(["INTEGRATED", "NOT_INTEGRATED"]) + }).strict()).max(500), + omittedUnits: count3 + }).strict(), + secondary: external_exports.object({ + eligibility: external_exports.object({ + eligible: count3, + ineligible: count3, + strongRequired: count3, + needsResearch: count3, + needsAuthority: count3, + needsContext: count3, + notReady: count3, + unavailable: count3 + }).strict(), + selection: external_exports.object({ + secondarySelected: count3, + strongSelectedDespiteEligibility: count3, + noBuilderNeeded: count3, + waitingForResource: count3 + }).strict(), + funnel: external_exports.object({ + initialAttempts: count3, + initialPass: count3, + repairAttempted: count3, + repairPass: count3, + toStrongFallback: count3, + unavailableFallback: count3 + }).strict(), + initialSuccessRate: fractionMetricSchema, + repairRecoveryRate: fractionMetricSchema, + toStrongFallbackRate: fractionMetricSchema, + fallbackReasons: countMap, + builderTokens: tokenTelemetrySchema + }).strict(), + strong: external_exports.object({ + builderAttempts: count3, + evaluatorAttempts: count3, + selection: external_exports.object({ + requiredDirect: count3, + byStrategyOff: count3, + byAutoPolicy: count3, + becauseSecondaryUnavailable: count3, + fallbackAfterSecondary: count3 + }).strict(), + implementationTokens: tokenTelemetrySchema, + evaluatorTokens: tokenTelemetrySchema + }).strict(), + research: external_exports.object({ + scope: external_exports.enum(["JOB", "WORKSPACE", "NONE"]), + considered: count3.nullable(), + decisions: countMap, + providerCalls: count3, + successful: count3, + inconclusive: count3, + failed: count3, + priorResearchReused: count3, + newQuick: count3, + newDeep: count3, + avoidanceRatio: fractionMetricSchema, + reuseRate: fractionMetricSchema, + byPhase: external_exports.record(external_exports.string(), phaseResearchSchema), + usage: external_exports.object({ + inputTokens: count3.nullable(), + outputTokens: count3.nullable(), + durationMs: count3.nullable(), + providerReportedCost: external_exports.number().min(0).nullable(), + subagentCount: count3.nullable(), + recordsWithUsage: count3, + providerCalls: count3, + coverage: ratio2 + }).strict() + }).strict(), + cooldown: external_exports.object({ + episodes: count3, + observations: count3, + totalDurationMs: count3.nullable(), + usefulWorkDuringSubscriptionCooldown: count3, + secondaryImplementationWorkDuringCooldown: count3, + researchWorkDuringCooldown: count3, + strongRequiredWaiting: count3, + avoidableIdlePeriods: count3, + intervals: external_exports.array(external_exports.object({ + objectiveNodeId: shortText122, + status: external_exports.enum(["ACTIVE", "RECOVERED"]), + startedAt: shortText122, + endedAt: shortText122.nullable(), + durationMs: count3.nullable(), + completedWorkUnits: count3 + }).strict()).max(200), + timeline: external_exports.array(external_exports.object({ + at: shortText122, + type: shortText122, + objectiveNodeId: shortText122.nullable(), + detail: boundedText7 + }).strict()).max(200) + }).strict(), + attempts: external_exports.object({ + uniqueImplementationAttempts: count3, + meanPerCompletedWorkUnit: external_exports.number().min(0).nullable(), + medianPerCompletedWorkUnit: external_exports.number().min(0).nullable(), + maxPerWorkUnit: count3, + workUnitsWithMultipleAttempts: count3, + byKind: countMap, + completedWorkUnitsPerImplementationAttempt: external_exports.number().min(0).nullable(), + completedWorkUnitsPerStrongBuilderCall: external_exports.number().min(0).nullable(), + completedEligibleWorkUnitsPerSecondaryAttempt: external_exports.number().min(0).nullable() + }).strict(), + verification: external_exports.object({ + attempts: count3, + passes: count3, + failures: count3, + otherVerdicts: count3, + failuresByBuilderBackend: countMap, + failuresRecoveredByRepair: count3, + failuresRecoveredByStrongFallback: count3 + }).strict(), + closure: external_exports.object({ + available: external_exports.boolean(), + items: count3, + earned: count3, + waived: count3, + unresolved: count3, + completionGateOutcome: external_exports.enum(["PASS", "FAIL", "UNAVAILABLE"]), + ratio: ratio2 + }).strict(), + human: external_exports.object({ + decisionsBeforeSeal: count3.nullable(), + approvals: count3, + authorityEscalationsAfterSeal: count3.nullable(), + interventionsAfterSeal: count3, + unexpectedBlockersAfterSeal: count3, + zeroTouchAfterSeal: external_exports.boolean(), + byKind: countMap + }).strict(), + reliability: external_exports.object({ + failureSources: countMap, + recoveryActions: countMap, + noProgressDetections: count3, + repeatedProblemFingerprints: count3, + legitimateResourceWaitsExcluded: count3, + processRestarts: count3, + supervisorRestarts: count3, + candidatesPersisted: count3, + candidatesReusedAfterRestart: count3, + candidateRebuildsAfterRestart: count3, + candidatesLostOrUnreadable: count3, + candidateReadyResumes: count3, + integrationRetries: count3, + completedWorkRedoCount: count3, + completedWorkReusedAfterRestart: count3, + attemptsIncorrectlyRepeated: count3, + unexpectedBlocks: count3, + unrecoveredDriverDeaths: count3 + }).strict(), + efficiency: external_exports.object({ + strongBuilderAvoidanceRatio: fractionMetricSchema, + strongBuilderCallsAvoided: count3, + completedWorkUnitsPerImplementationAttempt: external_exports.number().min(0).nullable(), + baseline: external_exports.object({ + kind: external_exports.enum(["OBSERVED", "QUALIFICATION_FIXTURE"]), + reportId: shortText122, + strongBuilderAttempts: count3, + sameVerificationOutcome: external_exports.boolean(), + sameClosureOutcome: external_exports.boolean() + }).strict().nullable() + }).strict(), + qualificationSummary: external_exports.object({ + strongBuilderAvoidanceRatio: ratio2, + secondaryInitialSuccessRate: ratio2, + secondaryRepairRecoveryRate: ratio2, + secondaryToStrongFallback: count3, + strongImplementationTokens: count3.nullable(), + researchAvoidanceRatio: ratio2, + newResearchCalls: count3, + researchReuse: count3, + usefulWorkDuringSubscriptionCooldown: count3, + humanInterventionsAfterSeal: count3, + completedWorkRedoCount: count3, + unexpectedBlocks: count3, + unrecoveredDriverDeaths: count3 + }).strict(), + diagnostics: external_exports.array(diagnosticSchema).max(200) +}).strict(); +var SECRET_PATTERNS2 = [ + /-----BEGIN (?:RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----/gi, + /\b(?:bearer|basic)\s+[A-Za-z0-9+/=_-]{12,}/gi, + /\b(?:sk|ghp|github_pat|xox[baprs])[_-][A-Za-z0-9_-]{12,}\b/gi, + /\b(?:api[-_ ]?key|auth[-_ ]?token|access[-_ ]?token|password|secret)\s*[:=]\s*\S{8,}/gi +]; +function redactTelemetryText(value) { + let redacted = value; + for (const pattern of SECRET_PATTERNS2) redacted = redacted.replace(pattern, "[REDACTED]"); + return redacted.slice(0, 2e3); +} +function increment2(record4, key, by = 1) { + record4[key] = (record4[key] ?? 0) + by; +} +function metric(numerator, denominator) { + return { + numerator, + denominator, + value: numerator === null || denominator === null || denominator === 0 ? null : numerator / denominator + }; +} +function tokenTelemetry(attempts, usage) { + let input = 0; + let output = 0; + let withInput = 0; + let withOutput = 0; + let withAny = 0; + for (const attempt of attempts) { + const reported = usage(attempt); + const hasInput = reported.input !== null && reported.input !== void 0; + const hasOutput = reported.output !== null && reported.output !== void 0; + if (hasInput) { + input += reported.input ?? 0; + withInput += 1; + } + if (hasOutput) { + output += reported.output ?? 0; + withOutput += 1; + } + if (hasInput || hasOutput) withAny += 1; + } + const attemptCount = attempts.length; + const complete = attemptCount > 0 && withInput === attemptCount && withOutput === attemptCount; + return { + inputTokens: withInput > 0 ? input : null, + outputTokens: withOutput > 0 ? output : null, + knownTokens: withAny > 0 ? input + output : null, + completeTokens: complete ? input + output : null, + coverage: { + attempts: attemptCount, + withAny, + withInput, + withOutput, + ratio: attemptCount === 0 ? null : withAny / attemptCount, + complete + } + }; +} +function timestampMs(value) { + if (value === null || value === void 0) return void 0; + const parsed = Date.parse(value); + return Number.isFinite(parsed) ? parsed : void 0; +} +function outcomeStatus(status) { + if (status === "COMPLETED") return "COMPLETED"; + if (status === "FAILED") return "FAILED"; + if (status === "CANCELLED") return "CANCELLED"; + if (status === "BLOCKED" || status === "NEEDS_AUTHORITY" || status === "NEEDS_CLARIFICATION") { + return "BLOCKED"; + } + return "WAITING"; +} +function verificationOutcome(job, events) { + const status = job.latestEvidence?.evidenceStatus; + if (status === "verified" || status === "manually-accepted") return "PASS"; + const lastFailure = [...events].reverse().find((event) => event.type === "verification_failed"); + if (lastFailure !== void 0 && job.latestEvidence === void 0) return "FAIL"; + return "UNAVAILABLE"; +} +function currentRoutingStates(objectives) { + const current = /* @__PURE__ */ new Map(); + for (const objective of objectives) { + for (const state of objective.routingStates) { + const key = `${objective.objectiveNodeId}\0${state.workUnitId}`; + const prior = current.get(key); + if (prior === void 0 || state.updatedAt.localeCompare(prior.updatedAt, "en") > 0 || state.updatedAt === prior.updatedAt && state.contentHash.localeCompare(prior.contentHash, "en") > 0) { + current.set(key, state); + } + } + } + return current; +} +function uniqueBuilderAttempts(objectives) { + const seen = /* @__PURE__ */ new Map(); + let duplicateIds = 0; + for (const objective of objectives) { + for (const state of objective.routingStates) { + for (const attempt of state.attempts) { + const key = `${objective.objectiveNodeId}\0${state.workUnitId}\0${attempt.attemptId}`; + if (seen.has(key)) { + duplicateIds += 1; + continue; + } + seen.set(key, { ...attempt, objectiveNodeId: objective.objectiveNodeId, workUnitId: state.workUnitId }); + } + } + } + return { + attempts: [...seen.values()].sort( + (left, right) => left.startedAt.localeCompare(right.startedAt, "en") || left.objectiveNodeId.localeCompare(right.objectiveNodeId, "en") || left.workUnitId.localeCompare(right.workUnitId, "en") || left.sequence - right.sequence + ), + duplicateIds + }; +} +function latestUnits(objectives) { + const units = []; + for (const objective of objectives) { + for (const unit of objective.graph?.units ?? []) { + units.push({ objectiveNodeId: objective.objectiveNodeId, unit }); + } + } + return units.sort( + (left, right) => left.objectiveNodeId.localeCompare(right.objectiveNodeId, "en") || left.unit.workUnitId.localeCompare(right.unit.workUnitId, "en") + ); +} +function workAccounting(unit, routing) { + if (unit.status === "INTEGRATED") return "completed"; + if (unit.status === "FAILED") return "failed"; + if (unit.status === "SUPERSEDED") return "cancelled"; + const eligibility = routing?.initialEligibility; + if (eligibility === "NEEDS_AUTHORITY") return "human-authority-pending"; + if (eligibility === "NEEDS_RESEARCH") return "research-pending"; + if (eligibility === "NEEDS_CONTEXT") return "context-pending"; + if (eligibility === "NOT_READY" || unit.status === "PLANNED") return "not-ready"; + return "waiting"; +} +function builderPath(attempts) { + if (attempts.some((attempt) => attempt.kind === "STRONG_FALLBACK")) return "STRONG_FALLBACK"; + if (attempts.some((attempt) => attempt.kind === "STRONG")) return "STRONG"; + if (attempts.some((attempt) => attempt.kind === "SECONDARY_REPAIR")) return "SECONDARY_REPAIR"; + if (attempts.some((attempt) => attempt.kind === "SECONDARY")) return "SECONDARY"; + return attempts.length === 0 ? "NONE" : "UNKNOWN"; +} +function verificationFor(evaluations) { + if (evaluations.some((entry2) => entry2.verdict === "FAIL")) return "FAIL"; + if (evaluations.some((entry2) => entry2.verdict === "PASS")) return "PASS"; + if (evaluations.length > 0) return "PENDING"; + return "UNAVAILABLE"; +} +function fallbackReason(attempts) { + const preceding = [...attempts].reverse().find((attempt) => attempt.kind === "SECONDARY" || attempt.kind === "SECONDARY_REPAIR"); + if (preceding === void 0) return "other"; + if (preceding.noProgress) return "no-progress"; + switch (preceding.outcome) { + case "FAILED_VERIFICATION": + return "verification-failure"; + case "FAILED_OUTPUT": + return "malformed-model-result"; + case "FAILED_RESOURCE": + return "capability-failure"; + case "FAILED_IMPLEMENTATION": + return /context|stale source|insufficient/i.test(preceding.failureSummary ?? "") ? "context-insufficiency" : "implementation-failure"; + default: + return "other"; + } +} +function median(values) { + if (values.length === 0) return null; + const sorted = [...values].sort((left, right) => left - right); + const middle = Math.floor(sorted.length / 2); + if (sorted.length % 2 === 1) return sorted[middle] ?? null; + return ((sorted[middle - 1] ?? 0) + (sorted[middle] ?? 0)) / 2; +} +function deriveExecutionTelemetryReport(facts) { + const diagnostics = []; + const generatedMs = timestampMs(facts.generatedAt) ?? 0; + const eventTypes = (type) => facts.events.filter((event) => event.type === type); + const currentRouting = currentRoutingStates(facts.objectives); + const { attempts: implementationAttempts, duplicateIds } = uniqueBuilderAttempts(facts.objectives); + const units = latestUnits(facts.objectives); + const evaluations = facts.objectives.flatMap((objective) => objective.evaluations).filter((entry2, index, values) => values.findIndex((other) => other.evaluationId === entry2.evaluationId) === index).sort((left, right) => left.createdAt.localeCompare(right.createdAt, "en")); + if (facts.eventTotal > facts.events.length) { + diagnostics.push({ + code: "EVENT_WINDOW_BOUNDED", + severity: "info", + message: `The report used the newest ${facts.events.length} of ${facts.eventTotal} job events; ledgers and current state remain authoritative for aggregates.`, + evidenceRefs: [] + }); + } + if (facts.objectives.length === 0) { + diagnostics.push({ + code: "OBJECTIVE_TELEMETRY_UNAVAILABLE", + severity: "info", + message: "No objective-runtime records exist; Phase 7/8 metrics are unavailable for this older or direct-execution job.", + evidenceRefs: [] + }); + } + if (facts.autonomy.boundaryStartedAt === null) { + diagnostics.push({ + code: "ZERO_TOUCH_BOUNDARY_UNAVAILABLE", + severity: "info", + message: "No durable seal boundary exists; intervention counting conservatively includes the whole recorded Job history.", + evidenceRefs: [] + }); + } + if (duplicateIds > 0) { + diagnostics.push({ + code: "ATTEMPT_REPLAY_DEDUPLICATED", + severity: "info", + message: `${duplicateIds} replayed builder-attempt record${duplicateIds === 1 ? "" : "s"} were ignored by durable attempt id.`, + evidenceRefs: [] + }); + } + if (facts.researchTelemetryDiagnostic !== void 0) { + diagnostics.push({ + code: "RESEARCH_TELEMETRY_UNREADABLE", + severity: "warning", + message: redactTelemetryText(facts.researchTelemetryDiagnostic), + evidenceRefs: [] + }); + } + for (const diagnostic of facts.researchRecordDiagnostics ?? []) { + diagnostics.push({ + code: diagnostic.code.slice(0, 512), + severity: "warning", + message: redactTelemetryText(diagnostic.message), + evidenceRefs: [] + }); + } + const attemptsByUnit = /* @__PURE__ */ new Map(); + for (const attempt of implementationAttempts) { + const key = `${attempt.objectiveNodeId}\0${attempt.workUnitId}`; + const list = attemptsByUnit.get(key) ?? []; + list.push(attempt); + attemptsByUnit.set(key, list); + } + const evaluationsByUnit = /* @__PURE__ */ new Map(); + for (const evaluation of evaluations) { + const key = `${evaluation.objectiveNodeId}\0${evaluation.workUnitId}`; + const list = evaluationsByUnit.get(key) ?? []; + list.push(evaluation); + evaluationsByUnit.set(key, list); + } + const workAccountingCounts = { + completed: 0, + failed: 0, + cancelled: 0, + waiting: 0, + "not-ready": 0, + "human-authority-pending": 0, + "research-pending": 0, + "context-pending": 0 + }; + const workByKind = {}; + const unitSummaries = []; + for (const entry2 of units) { + const key = `${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`; + const routing = currentRouting.get(key); + const unitAttempts = attemptsByUnit.get(key) ?? []; + const unitEvaluations = evaluationsByUnit.get(key) ?? []; + const accounting = workAccounting(entry2.unit, routing); + workAccountingCounts[accounting] += 1; + increment2(workByKind, entry2.unit.kind); + if (unitSummaries.length < 500) { + unitSummaries.push({ + workUnitId: entry2.unit.workUnitId, + objectiveNodeId: entry2.objectiveNodeId, + kind: entry2.unit.kind, + status: entry2.unit.status, + accounting, + builderPath: builderPath(unitAttempts), + implementationAttempts: unitAttempts.length, + verification: verificationFor(unitEvaluations), + integration: entry2.unit.status === "INTEGRATED" ? "INTEGRATED" : "NOT_INTEGRATED" + }); + } + } + const eligibility = { + eligible: 0, + ineligible: 0, + strongRequired: 0, + needsResearch: 0, + needsAuthority: 0, + needsContext: 0, + notReady: 0, + unavailable: units.filter((entry2) => entry2.unit.kind === "build" && !currentRouting.has(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`)).length + }; + const selection = { + secondarySelected: 0, + strongSelectedDespiteEligibility: 0, + noBuilderNeeded: 0, + waitingForResource: 0 + }; + const strongSelection = { + requiredDirect: 0, + byStrategyOff: 0, + byAutoPolicy: 0, + becauseSecondaryUnavailable: 0, + fallbackAfterSecondary: 0 + }; + const fallbackReasons = {}; + for (const entry2 of units) { + if (entry2.unit.kind !== "build") { + selection.noBuilderNeeded += 1; + continue; + } + const key = `${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`; + const state = currentRouting.get(key); + if (state === void 0) continue; + switch (state.initialEligibility) { + case "ELIGIBLE": + eligibility.eligible += 1; + break; + case "STRONG_REQUIRED": + eligibility.strongRequired += 1; + break; + case "NEEDS_RESEARCH": + eligibility.needsResearch += 1; + break; + case "NEEDS_AUTHORITY": + eligibility.needsAuthority += 1; + break; + case "NEEDS_CONTEXT": + eligibility.needsContext += 1; + break; + case "NOT_READY": + eligibility.notReady += 1; + break; + default: + break; + } + const decisions = state.decisions; + const unitAttempts = attemptsByUnit.get(key) ?? []; + if (entry2.unit.resourceWait !== void 0) selection.waitingForResource += 1; + if (state.initialEligibility === "ELIGIBLE") { + if (decisions.some((decision) => decision.selectedBackend === "SECONDARY")) { + selection.secondarySelected += 1; + } else if (decisions.some((decision) => decision.selectedBackend === "STRONG")) { + selection.strongSelectedDespiteEligibility += 1; + } + } + const directStrong = decisions.find((decision) => decision.selectedBackend === "STRONG"); + if (directStrong !== void 0 && !unitAttempts.some((attempt) => attempt.kind === "STRONG_FALLBACK")) { + if (state.initialEligibility === "STRONG_REQUIRED") strongSelection.requiredDirect += 1; + else if (directStrong.reasons.some((reason) => reason.code === "STRATEGY_OFF")) strongSelection.byStrategyOff += 1; + else if (directStrong.reasons.some((reason) => reason.code === "SECONDARY_UNAVAILABLE")) { + strongSelection.becauseSecondaryUnavailable += 1; + } else if (directStrong.reasons.some((reason) => reason.code === "SUBSCRIPTION_HARVEST" || reason.code === "SECONDARY_AUTO_POLICY" || reason.code === "CRITICAL_WORK_PREFERS_STRONG")) { + strongSelection.byAutoPolicy += 1; + } + } + if (unitAttempts.some((attempt) => attempt.kind === "STRONG_FALLBACK")) { + strongSelection.fallbackAfterSecondary += 1; + increment2(fallbackReasons, fallbackReason(unitAttempts)); + } + } + eligibility.ineligible = eligibility.strongRequired + eligibility.needsResearch + eligibility.needsAuthority + eligibility.needsContext + eligibility.notReady; + const eligibleUnits = units.filter((entry2) => { + const state = currentRouting.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`); + return entry2.unit.kind === "build" && state?.initialEligibility === "ELIGIBLE"; + }); + const eligibleCompleted = eligibleUnits.filter((entry2) => entry2.unit.status === "INTEGRATED"); + const eligibleCompletedWithoutStrong = eligibleCompleted.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return !attempts.some((attempt) => attempt.kind === "STRONG" || attempt.kind === "STRONG_FALLBACK"); + }); + const secondaryAttemptedUnits = eligibleUnits.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => (attempt.kind === "SECONDARY" || attempt.kind === "SECONDARY_REPAIR") && attempt.outcome !== "FAILED_RESOURCE" && attempt.outcome !== "CANCELLED"); + }); + const initialAttemptedUnits = eligibleUnits.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => attempt.kind === "SECONDARY" && attempt.outcome !== "FAILED_RESOURCE" && attempt.outcome !== "CANCELLED"); + }); + const initialPassUnits = initialAttemptedUnits.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => attempt.kind === "SECONDARY" && attempt.outcome === "SUCCEEDED"); + }); + const repairAttemptedUnits = eligibleUnits.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => attempt.kind === "SECONDARY_REPAIR" && attempt.outcome !== "FAILED_RESOURCE" && attempt.outcome !== "CANCELLED"); + }); + const repairPassUnits = repairAttemptedUnits.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => attempt.kind === "SECONDARY_REPAIR" && attempt.outcome === "SUCCEEDED"); + }); + const fallbackUnits = eligibleUnits.filter((entry2) => { + const attempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => attempt.kind === "STRONG_FALLBACK"); + }); + const unavailableFallbackUnits = eligibleUnits.filter((entry2) => { + const state = currentRouting.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`); + return state?.decisions.some((decision) => decision.selectedBackend === "STRONG" && decision.reasons.some((reason) => reason.code === "SECONDARY_UNAVAILABLE")) === true; + }); + const secondaryAttempts = implementationAttempts.filter((attempt) => attempt.kind === "SECONDARY" || attempt.kind === "SECONDARY_REPAIR"); + const strongAttempts = implementationAttempts.filter((attempt) => attempt.kind === "STRONG" || attempt.kind === "STRONG_FALLBACK"); + const strongEvaluatorAttempts = facts.ledger.filter((entry2) => entry2.role === "EVALUATOR" && entry2.lane !== "LOCAL"); + const secondaryTokens = tokenTelemetry(secondaryAttempts, (attempt) => ({ + input: attempt.inputTokens, + output: attempt.outputTokens + })); + const strongTokens = tokenTelemetry(strongAttempts, (attempt) => ({ + input: attempt.inputTokens, + output: attempt.outputTokens + })); + const evaluatorTokens = tokenTelemetry(strongEvaluatorAttempts, (attempt) => ({ + input: attempt.metrics.inputTokens, + output: attempt.metrics.outputTokens + })); + const jobResearchRecords = facts.researchRecords.filter((record4) => record4.scope?.jobId === facts.job.jobId); + const jobResearchIds = new Set(jobResearchRecords.map((record4) => record4.researchId)); + const jobResearchUses = facts.researchUses.filter((use) => jobResearchIds.has(use.researchId)); + const hasJobResearch = jobResearchRecords.length > 0 || jobResearchUses.length > 0; + const hasWorkspaceResearch = (facts.researchTelemetry?.gateConsidered ?? 0) > 0 || facts.researchRecords.length > 0 || facts.researchUses.length > 0; + const researchScope = hasJobResearch ? "JOB" : hasWorkspaceResearch ? "WORKSPACE" : "NONE"; + const reportResearchRecords = hasJobResearch ? jobResearchRecords : facts.researchRecords; + const reportResearchUses = hasJobResearch ? jobResearchUses : facts.researchUses; + const useIds = new Set(reportResearchUses.map((use) => use.useId)); + const uniqueUses = reportResearchUses.filter((use) => { + if (!useIds.has(use.useId)) return false; + useIds.delete(use.useId); + return true; + }); + const providerRecords = reportResearchRecords.filter((record4) => record4.status !== "PENDING"); + const workspaceResearch = researchScope === "WORKSPACE"; + const providerCallCount = workspaceResearch ? facts.researchTelemetry?.providerCalls ?? providerRecords.length : providerRecords.length; + const successfulResearch = workspaceResearch ? facts.researchTelemetry?.successfulResearch ?? providerRecords.filter((record4) => record4.status === "COMPLETED").length : providerRecords.filter((record4) => record4.status === "COMPLETED").length; + const inconclusiveResearch = workspaceResearch ? facts.researchTelemetry?.inconclusiveResearch ?? providerRecords.filter((record4) => record4.status === "INCONCLUSIVE").length : providerRecords.filter((record4) => record4.status === "INCONCLUSIVE").length; + const failedResearch = workspaceResearch ? facts.researchTelemetry?.failedResearch ?? providerRecords.filter((record4) => record4.status === "FAILED").length : providerRecords.filter((record4) => record4.status === "FAILED").length; + const reuseCount = workspaceResearch ? facts.researchTelemetry?.reusedReports ?? uniqueUses.filter((use) => use.useKind === "REUSED").length : uniqueUses.filter((use) => use.useKind === "REUSED").length; + const newQuick = workspaceResearch ? facts.researchTelemetry?.newQuick ?? providerRecords.filter((record4) => record4.depth === "QUICK").length : providerRecords.filter((record4) => record4.depth === "QUICK").length; + const newDeep = workspaceResearch ? facts.researchTelemetry?.newDeep ?? providerRecords.filter((record4) => record4.depth === "DEEP").length : providerRecords.filter((record4) => record4.depth === "DEEP").length; + const researchConsidered = researchScope === "WORKSPACE" ? facts.researchTelemetry?.gateConsidered ?? null : null; + const researchAvoided = researchScope === "WORKSPACE" ? facts.researchTelemetry?.researchAvoided ?? null : null; + const researchDecisions = researchScope === "WORKSPACE" ? { ...facts.researchTelemetry?.decisions ?? {} } : {}; + const byPhase = {}; + for (const phase of ["CONVERSATION", "SPEC_DRAFT", "INTAKE_DECISION", "RUNTIME_INVESTIGATION"]) { + const aggregate = researchScope === "WORKSPACE" ? facts.researchTelemetry?.byPhase[phase] : void 0; + const phaseRecords = providerRecords.filter((record4) => record4.lifecycle?.phase === phase); + const phaseUses = uniqueUses.filter((use) => use.phase === phase); + byPhase[phase] = { + considered: aggregate?.considered ?? 0, + avoided: aggregate?.avoided ?? 0, + reused: researchScope === "WORKSPACE" ? aggregate?.reused ?? phaseUses.filter((use) => use.useKind === "REUSED").length : phaseUses.filter((use) => use.useKind === "REUSED").length, + newCalls: researchScope === "WORKSPACE" ? (aggregate?.newQuick ?? 0) + (aggregate?.newDeep ?? 0) : phaseRecords.length, + quick: researchScope === "WORKSPACE" ? aggregate?.newQuick ?? phaseRecords.filter((record4) => record4.depth === "QUICK").length : phaseRecords.filter((record4) => record4.depth === "QUICK").length, + deep: researchScope === "WORKSPACE" ? aggregate?.newDeep ?? phaseRecords.filter((record4) => record4.depth === "DEEP").length : phaseRecords.filter((record4) => record4.depth === "DEEP").length, + failed: phaseRecords.filter((record4) => record4.status === "FAILED").length + }; + } + let researchInputTokens = 0; + let researchOutputTokens = 0; + let researchDurationMs = 0; + let researchCost = 0; + let researchSubagents = 0; + let researchInputObserved = false; + let researchOutputObserved = false; + let researchDurationObserved = false; + let researchCostObserved = false; + let researchSubagentsObserved = false; + let recordsWithUsage = 0; + for (const record4 of providerRecords) { + const usage = record4.usage ?? record4.report?.usage; + if (usage === void 0) continue; + recordsWithUsage += 1; + if (usage.inputTokens !== void 0) { + researchInputObserved = true; + researchInputTokens += usage.inputTokens; + } + if (usage.outputTokens !== void 0) { + researchOutputObserved = true; + researchOutputTokens += usage.outputTokens; + } + if (usage.durationMs !== void 0) { + researchDurationObserved = true; + researchDurationMs += usage.durationMs; + } + if (usage.providerReportedCost !== void 0) { + researchCostObserved = true; + researchCost += usage.providerReportedCost; + } + if (usage.subagentCount !== void 0) { + researchSubagentsObserved = true; + researchSubagents += usage.subagentCount; + } + } + if (researchScope === "WORKSPACE" && providerRecords.length === 0 && facts.researchTelemetry !== void 0) { + const reported = facts.researchTelemetry.reportedUsage; + if (reported.reports > 0) { + recordsWithUsage = reported.reports; + if (reported.inputTokens > 0) { + researchInputObserved = true; + researchInputTokens = reported.inputTokens; + } + if (reported.outputTokens > 0) { + researchOutputObserved = true; + researchOutputTokens = reported.outputTokens; + } + if (reported.providerReportedCost > 0) { + researchCostObserved = true; + researchCost = reported.providerReportedCost; + } + if (reported.subagentCount > 0) { + researchSubagentsObserved = true; + researchSubagents = reported.subagentCount; + } + } + if (facts.researchTelemetry.totalDurationMs > 0) { + researchDurationObserved = true; + researchDurationMs = facts.researchTelemetry.totalDurationMs; + } + } + const cooldownStates = facts.objectives.map((objective) => objective.cooldown).filter((state) => state !== void 0); + const cooldownIntervals = []; + let cooldownDurationMs = 0; + let cooldownDurationKnown = cooldownStates.length > 0; + let cooldownEpisodes = 0; + for (const state of cooldownStates) { + cooldownEpisodes += state.episodes; + const startedAt = state.currentStartedAt ?? state.firstStartedAt; + const endedAt = state.status === "RECOVERED" ? state.lastEndedAt ?? null : null; + const startMs = timestampMs(startedAt); + const endMs = state.status === "ACTIVE" ? generatedMs : timestampMs(endedAt); + const durationMs = startMs !== void 0 && endMs !== void 0 && endMs >= startMs ? endMs - startMs : null; + if (state.episodes !== 1) cooldownDurationKnown = false; + if (durationMs === null) cooldownDurationKnown = false; + else cooldownDurationMs += durationMs; + cooldownIntervals.push({ + objectiveNodeId: state.objectiveNodeId, + status: state.status, + startedAt, + endedAt, + durationMs, + completedWorkUnits: state.completedDuringCooldown.length + }); + if (state.episodes > 1) { + diagnostics.push({ + code: "COOLDOWN_DURATION_PARTIAL", + severity: "info", + message: `Objective ${state.objectiveNodeId} records ${state.episodes} cooldown episodes but retains only bounded interval endpoints; total duration is unavailable.`, + evidenceRefs: [state.objectiveNodeId] + }); + } + } + const cooldownCompletedKeys = /* @__PURE__ */ new Set(); + const cooldownWaitingKeys = /* @__PURE__ */ new Set(); + for (const state of cooldownStates) { + for (const workUnitId of state.completedDuringCooldown) { + cooldownCompletedKeys.add(`${state.objectiveNodeId}\0${workUnitId}`); + } + for (const workUnitId of state.waitingWorkUnitIds) { + cooldownWaitingKeys.add(`${state.objectiveNodeId}\0${workUnitId}`); + } + } + let secondaryImplementationDuringCooldown = 0; + for (const entry2 of units) { + const key = `${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`; + if (!cooldownCompletedKeys.has(key) || entry2.unit.kind !== "build") continue; + const unitAttempts = attemptsByUnit.get(key) ?? []; + if (unitAttempts.some((attempt) => attempt.kind === "SECONDARY" || attempt.kind === "SECONDARY_REPAIR") && !unitAttempts.some((attempt) => attempt.kind === "STRONG" || attempt.kind === "STRONG_FALLBACK")) { + secondaryImplementationDuringCooldown += 1; + } + } + const withinCooldown = (at) => { + const atMs = timestampMs(at); + if (atMs === void 0) return false; + return cooldownIntervals.some((interval) => { + const start = timestampMs(interval.startedAt); + const end = timestampMs(interval.endedAt) ?? generatedMs; + return start !== void 0 && atMs >= start && atMs <= end; + }); + }; + const researchDuringCooldown = providerRecords.filter((record4) => (record4.status === "COMPLETED" || record4.status === "INCONCLUSIVE") && withinCooldown(record4.report?.completedAt ?? record4.updatedAt)).length; + let avoidableIdlePeriods = 0; + for (const objective of facts.objectives) { + if (objective.cooldown?.status !== "ACTIVE" || objective.graph === void 0) continue; + for (const unit of objective.graph.units) { + if (unit.kind !== "build" || unit.status !== "READY" || unit.resourceWait !== void 0) continue; + const key = `${objective.objectiveNodeId}\0${unit.workUnitId}`; + const state = currentRouting.get(key); + if (state?.initialEligibility !== "ELIGIBLE" || state.strategy === "OFF") continue; + const startMs = timestampMs(objective.cooldown.currentStartedAt); + const dispatched = (attemptsByUnit.get(key) ?? []).some((attempt) => { + const attemptMs = timestampMs(attempt.startedAt); + return (attempt.kind === "SECONDARY" || attempt.kind === "SECONDARY_REPAIR") && attemptMs !== void 0 && (startMs === void 0 || attemptMs >= startMs); + }); + if (!dispatched) avoidableIdlePeriods += 1; + } + } + if (avoidableIdlePeriods > 0) { + diagnostics.push({ + code: "AVOIDABLE_IDLE_DURING_COOLDOWN", + severity: "warning", + message: `${avoidableIdlePeriods} runnable Secondary work period(s) had no durable Secondary dispatch during an active Strong cooldown.`, + evidenceRefs: [] + }); + } + const cooldownEventTypes = /* @__PURE__ */ new Set([ + "resource_cooldown_started", + "resource_cooldown_observed", + "work_unit_resource_wait_started", + "work_unit_resource_wait_ended", + "resource_wait_entered", + "useful_work_during_cooldown", + "resource_recovered" + ]); + const cooldownTimeline = facts.events.filter((event) => cooldownEventTypes.has(event.type)).slice(-200).map((event) => ({ + at: String(event.at ?? ""), + type: event.type, + objectiveNodeId: typeof event["nodeId"] === "string" ? event["nodeId"].slice(0, 512) : null, + detail: cooldownEventDetail(event) + })); + const evaluationFailures = evaluations.filter((entry2) => entry2.verdict === "FAIL"); + const evaluationPasses = evaluations.filter((entry2) => entry2.verdict === "PASS"); + const failuresByBackend = {}; + let failuresRecoveredByRepair = 0; + let failuresRecoveredByStrongFallback = 0; + const failedUnitKeys = /* @__PURE__ */ new Set(); + for (const evaluation of evaluationFailures) { + const key = `${evaluation.objectiveNodeId}\0${evaluation.workUnitId}`; + failedUnitKeys.add(key); + const unitAttempts = attemptsByUnit.get(key) ?? []; + const matching = [...unitAttempts].reverse().find((attempt) => attempt.workUnitAttempt === evaluation.attempt); + increment2(failuresByBackend, matching?.kind ?? "UNKNOWN"); + } + for (const key of failedUnitKeys) { + const unitAttempts = attemptsByUnit.get(key) ?? []; + if (unitAttempts.some((attempt) => attempt.kind === "SECONDARY_REPAIR" && attempt.outcome === "SUCCEEDED")) { + failuresRecoveredByRepair += 1; + } + if (unitAttempts.some((attempt) => attempt.kind === "STRONG_FALLBACK" && attempt.outcome === "SUCCEEDED")) { + failuresRecoveredByStrongFallback += 1; + } + } + const failureSources = {}; + const recoveryActions = {}; + for (const entry2 of facts.ledger) { + if (entry2.failureSource !== null) increment2(failureSources, entry2.failureSource); + else if (!entry2.success && entry2.failureReason !== null) increment2(failureSources, "UNCLASSIFIED"); + if (entry2.recoveryAction !== null) increment2(recoveryActions, entry2.recoveryAction); + } + const repairAttempts = implementationAttempts.filter((attempt) => attempt.kind === "SECONDARY_REPAIR").length; + const strongFallbackAttempts = implementationAttempts.filter((attempt) => attempt.kind === "STRONG_FALLBACK").length; + if (repairAttempts > 0) increment2(recoveryActions, "repair", repairAttempts); + if (strongFallbackAttempts > 0) increment2(recoveryActions, "strong-fallback", strongFallbackAttempts); + const resourceWaitEvents = eventTypes("resource_wait_started").length + eventTypes("resource_wait_entered").length + eventTypes("work_unit_resource_wait_started").length; + if (resourceWaitEvents > 0) increment2(recoveryActions, "resource-wait", resourceWaitEvents); + const restartEvents = eventTypes("job_resumed").length + eventTypes("driver_restarted").length; + if (restartEvents > 0) increment2(recoveryActions, "restart-resume", restartEvents); + const noProgressDetections = implementationAttempts.filter((attempt) => attempt.noProgress).length; + const fingerprintCounts = /* @__PURE__ */ new Map(); + for (const attempt of implementationAttempts) { + if (attempt.problemFingerprint !== void 0) { + fingerprintCounts.set( + attempt.problemFingerprint, + (fingerprintCounts.get(attempt.problemFingerprint) ?? 0) + 1 + ); + } + } + const repeatedProblemFingerprints = [...fingerprintCounts.values()].filter((value) => value > 1).length; + const candidatesPersisted = new Set( + implementationAttempts.map((attempt) => attempt.candidateRef).filter((ref) => ref !== void 0) + ).size; + const candidateRebuilds = eventTypes("candidate_resume_missing").length; + const candidatesReused = cooldownStates.reduce( + (sum, state) => sum + state.candidateReuseAfterRestart, + 0 + ); + const integrationRetries = eventTypes("integration_failed").length; + let completedWorkRedoCount = 0; + for (const entry2 of units) { + if (entry2.unit.integratedAt === void 0) continue; + const integratedMs = timestampMs(entry2.unit.integratedAt); + if (integratedMs === void 0) continue; + const attemptsAfterIntegration = (attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []).filter((attempt) => (timestampMs(attempt.startedAt) ?? 0) > integratedMs); + if (attemptsAfterIntegration.length > 0) completedWorkRedoCount += 1; + } + const lastRestartMs = Math.max( + 0, + ...facts.events.filter((event) => event.type === "job_resumed" || event.type === "driver_restarted").map((event) => timestampMs(event.at) ?? 0) + ); + const completedWorkReusedAfterRestart = lastRestartMs === 0 ? 0 : units.filter((entry2) => { + if (entry2.unit.status !== "INTEGRATED") return false; + const unitAttempts = attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []; + return unitAttempts.length > 0 && unitAttempts.every((attempt) => (timestampMs(attempt.completedAt) ?? Number.MAX_SAFE_INTEGER) <= lastRestartMs); + }).length; + const unresolvedInterrupted = facts.ledger.filter((entry2) => { + if (entry2.status !== "INTERRUPTED") return false; + return !facts.ledger.some((candidate) => candidate.taskId === entry2.taskId && candidate.attemptNumber > entry2.attemptNumber && candidate.status === "COMPLETED"); + }).length; + const unrecoveredDriverDeaths = ["COMPLETED", "FAILED", "CANCELLED"].includes(facts.job.status) ? unresolvedInterrupted : 0; + const unexpectedBlocks = facts.autonomy.interventions.filter((intervention) => intervention.kind === "job_blocked" || intervention.kind === "budget_exhausted" || intervention.kind.startsWith("status:")).length; + if (completedWorkRedoCount > 0) { + diagnostics.push({ + code: "COMPLETED_WORK_REDONE", + severity: "error", + message: `${completedWorkRedoCount} authoritatively integrated WorkUnit(s) have a later implementation attempt without recorded invalidation.`, + evidenceRefs: [] + }); + } + const completedImplementation = units.filter((entry2) => entry2.unit.kind === "build" && entry2.unit.status === "INTEGRATED").length; + const attemptCountsForCompleted = units.filter((entry2) => entry2.unit.status === "INTEGRATED" && entry2.unit.kind === "build").map((entry2) => (attemptsByUnit.get(`${entry2.objectiveNodeId}\0${entry2.unit.workUnitId}`) ?? []).length); + const totalAttemptsForCompleted = attemptCountsForCompleted.reduce((sum, value) => sum + value, 0); + const meanAttempts = attemptCountsForCompleted.length === 0 ? null : totalAttemptsForCompleted / attemptCountsForCompleted.length; + const completedPerAttempt = implementationAttempts.length === 0 ? null : completedImplementation / implementationAttempts.length; + const completedPerStrong = strongAttempts.length === 0 ? null : completedImplementation / strongAttempts.length; + const completedEligiblePerSecondary = secondaryAttempts.length === 0 ? null : eligibleCompleted.length / secondaryAttempts.length; + const closureTotals = facts.closure === void 0 ? void 0 : summarizeClosure(facts.closure.entries); + const closureGate = facts.closure === void 0 ? void 0 : missionMayComplete(facts.closure, facts.closurePolicy); + const closureOutcome = facts.closure === void 0 ? "UNAVAILABLE" : closureGate?.mayComplete === true ? "PASS" : "FAIL"; + const overallVerification = verificationOutcome(facts.job, facts.events); + const boundaryMs = timestampMs(facts.autonomy.boundaryStartedAt); + const decisionsBeforeSeal = boundaryMs === void 0 ? null : facts.events.filter((event) => (event.type === "clarification_resolved" || event.type === "authority_resolved") && (timestampMs(event.at) ?? Number.MAX_SAFE_INTEGER) < boundaryMs).length; + const humanByKind = {}; + for (const intervention of facts.autonomy.interventions) increment2(humanByKind, intervention.kind); + const objectiveRevisions = {}; + for (const objective of facts.objectives) { + if (objective.graph !== void 0) objectiveRevisions[objective.objectiveNodeId] = objective.graph.revision; + } + const ledgerWatermark = sha256Hex(JSON.stringify( + facts.ledger.map((entry2) => [entry2.attemptId, entry2.status, entry2.completedAt]) + )); + const currentPolicyFingerprint = autonomyPolicyFingerprint(facts.currentAutonomyPolicy); + const runtimePolicyChanged = facts.binding === void 0 ? null : currentPolicyFingerprint !== facts.binding.boundPolicyFingerprint; + const strongAvoidance = metric(eligibleCompletedWithoutStrong.length, eligibleCompleted.length); + const secondaryInitial = metric(initialPassUnits.length, initialAttemptedUnits.length); + const secondaryRepair = metric(repairPassUnits.length, repairAttemptedUnits.length); + const secondaryFallback = metric(fallbackUnits.length, secondaryAttemptedUnits.length); + const researchAvoidance = metric(researchAvoided, researchConsidered); + const researchReuse = metric( + reuseCount, + reuseCount + providerCallCount + ); + const implementationByKind = {}; + for (const attempt of implementationAttempts) increment2(implementationByKind, attempt.kind); + const objectiveSummaries = facts.objectives.slice(0, 200).map((objective) => { + const accounting = { + completed: 0, + failed: 0, + cancelled: 0, + waiting: 0, + "not-ready": 0, + "human-authority-pending": 0, + "research-pending": 0, + "context-pending": 0 + }; + for (const unit of objective.graph?.units ?? []) { + const key = `${objective.objectiveNodeId}\0${unit.workUnitId}`; + accounting[workAccounting(unit, currentRouting.get(key))] += 1; + } + const attempts = implementationAttempts.filter((entry2) => entry2.objectiveNodeId === objective.objectiveNodeId); + return { + objectiveNodeId: objective.objectiveNodeId, + graphRevision: objective.graph?.revision ?? null, + total: objective.graph?.units.length ?? 0, + accounting, + implementationAttempts: attempts.length, + secondaryAttempts: attempts.filter((entry2) => entry2.kind === "SECONDARY" || entry2.kind === "SECONDARY_REPAIR").length, + strongBuilderAttempts: attempts.filter((entry2) => entry2.kind === "STRONG" || entry2.kind === "STRONG_FALLBACK").length + }; + }); + const report = executionTelemetryReportSchema.parse({ + schemaVersion: EXECUTION_TELEMETRY_REPORT_SCHEMA_VERSION, + jobId: facts.job.jobId, + missionId: facts.binding?.missionId ?? facts.seal?.missionId ?? null, + generatedAt: facts.generatedAt, + period: { + startedAt: facts.job.createdAt, + endedAt: facts.job.finalizedAt ?? null, + durationMs: timestampMs(facts.job.createdAt) === void 0 ? null : Math.max( + 0, + (timestampMs(facts.job.finalizedAt ?? facts.generatedAt) ?? generatedMs) - (timestampMs(facts.job.createdAt) ?? generatedMs) + ), + activeExecutionMs: timestampMs(facts.job.createdAt) === void 0 ? null : workedMsOf(facts.job, timestampMs(facts.job.finalizedAt ?? facts.generatedAt) ?? generatedMs) + }, + provenance: { + sourceJobId: facts.job.jobId, + jobGraphRevision: facts.job.graphRevision, + objectiveGraphRevisions: objectiveRevisions, + executionLedgerWatermark: ledgerWatermark, + eventWatermark: facts.eventTotal, + specbridgeVersion: facts.specbridgeVersion ?? null, + sealId: facts.binding?.sealId ?? null, + sealedAuthorityDigest: facts.seal?.authorityDigest ?? null, + runtimePolicyChanged, + configuration: { + secondaryBuildStrategy: facts.secondaryBuildStrategy, + researchStrategy: facts.researchStrategy, + runnerProfiles: [...facts.runnerProfiles].sort().slice(0, 50) + } + }, + outcome: { + status: outcomeStatus(facts.job.status), + authoritativeJobStatus: facts.job.status, + finalOutcome: facts.job.finalOutcome === void 0 ? null : redactTelemetryText(facts.job.finalOutcome).slice(0, 2e3), + verification: overallVerification, + closure: closureOutcome + }, + work: { + total: units.length, + byKind: workByKind, + accounting: workAccountingCounts, + completedImplementation, + objectives: objectiveSummaries, + units: unitSummaries, + omittedUnits: Math.max(0, units.length - unitSummaries.length) + }, + secondary: { + eligibility, + selection, + funnel: { + initialAttempts: initialAttemptedUnits.length, + initialPass: initialPassUnits.length, + repairAttempted: repairAttemptedUnits.length, + repairPass: repairPassUnits.length, + toStrongFallback: fallbackUnits.length, + unavailableFallback: unavailableFallbackUnits.length + }, + initialSuccessRate: secondaryInitial, + repairRecoveryRate: secondaryRepair, + toStrongFallbackRate: secondaryFallback, + fallbackReasons, + builderTokens: secondaryTokens + }, + strong: { + builderAttempts: strongAttempts.length, + evaluatorAttempts: strongEvaluatorAttempts.length, + selection: strongSelection, + implementationTokens: strongTokens, + evaluatorTokens + }, + research: { + scope: researchScope, + considered: researchConsidered, + decisions: researchDecisions, + providerCalls: providerCallCount, + successful: successfulResearch, + inconclusive: inconclusiveResearch, + failed: failedResearch, + priorResearchReused: reuseCount, + newQuick, + newDeep, + avoidanceRatio: researchAvoidance, + reuseRate: researchReuse, + byPhase, + usage: { + inputTokens: researchInputObserved ? researchInputTokens : null, + outputTokens: researchOutputObserved ? researchOutputTokens : null, + durationMs: researchDurationObserved ? researchDurationMs : null, + providerReportedCost: researchCostObserved ? researchCost : null, + subagentCount: researchSubagentsObserved ? researchSubagents : null, + recordsWithUsage, + providerCalls: providerCallCount, + coverage: providerCallCount === 0 ? null : Math.min(1, recordsWithUsage / providerCallCount) + } + }, + cooldown: { + episodes: cooldownEpisodes, + observations: eventTypes("resource_cooldown_observed").length, + totalDurationMs: cooldownDurationKnown ? cooldownDurationMs : null, + usefulWorkDuringSubscriptionCooldown: cooldownCompletedKeys.size, + secondaryImplementationWorkDuringCooldown: secondaryImplementationDuringCooldown, + researchWorkDuringCooldown: researchDuringCooldown, + strongRequiredWaiting: cooldownWaitingKeys.size, + avoidableIdlePeriods, + intervals: cooldownIntervals.sort((left, right) => left.startedAt.localeCompare(right.startedAt, "en") || left.objectiveNodeId.localeCompare(right.objectiveNodeId, "en")), + timeline: cooldownTimeline + }, + attempts: { + uniqueImplementationAttempts: implementationAttempts.length, + meanPerCompletedWorkUnit: meanAttempts, + medianPerCompletedWorkUnit: median(attemptCountsForCompleted), + maxPerWorkUnit: attemptCountsForCompleted.length === 0 ? 0 : Math.max(...attemptCountsForCompleted), + workUnitsWithMultipleAttempts: attemptCountsForCompleted.filter((value) => value > 1).length, + byKind: implementationByKind, + completedWorkUnitsPerImplementationAttempt: completedPerAttempt, + completedWorkUnitsPerStrongBuilderCall: completedPerStrong, + completedEligibleWorkUnitsPerSecondaryAttempt: completedEligiblePerSecondary + }, + verification: { + attempts: evaluations.length, + passes: evaluationPasses.length, + failures: evaluationFailures.length, + otherVerdicts: evaluations.length - evaluationPasses.length - evaluationFailures.length, + failuresByBuilderBackend: failuresByBackend, + failuresRecoveredByRepair, + failuresRecoveredByStrongFallback + }, + closure: { + available: closureTotals !== void 0, + items: closureTotals?.total ?? 0, + earned: closureTotals?.verified ?? 0, + waived: closureTotals?.waived ?? 0, + unresolved: closureTotals === void 0 ? 0 : closureTotals.total - closureTotals.verified - closureTotals.waived - closureTotals.notApplicable, + completionGateOutcome: closureOutcome, + ratio: closureTotals === void 0 ? null : closureRatio(closureTotals) + }, + human: { + decisionsBeforeSeal, + approvals: facts.seal?.sealedAt === void 0 ? 0 : 1, + authorityEscalationsAfterSeal: facts.autonomy.humanAuthorityEscalationsAfterSeal, + interventionsAfterSeal: facts.autonomy.humanInterventionsAfterSeal, + unexpectedBlockersAfterSeal: unexpectedBlocks, + zeroTouchAfterSeal: facts.autonomy.humanInterventionsAfterSeal === 0, + byKind: humanByKind + }, + reliability: { + failureSources, + recoveryActions, + noProgressDetections, + repeatedProblemFingerprints, + legitimateResourceWaitsExcluded: resourceWaitEvents, + processRestarts: eventTypes("job_resumed").length, + supervisorRestarts: eventTypes("driver_restarted").length + eventTypes("supervisor_lease_reclaimed").length, + candidatesPersisted, + candidatesReusedAfterRestart: candidatesReused, + candidateRebuildsAfterRestart: candidateRebuilds, + candidatesLostOrUnreadable: candidateRebuilds, + candidateReadyResumes: candidatesReused, + integrationRetries, + completedWorkRedoCount, + completedWorkReusedAfterRestart, + attemptsIncorrectlyRepeated: completedWorkRedoCount, + unexpectedBlocks, + unrecoveredDriverDeaths + }, + efficiency: { + strongBuilderAvoidanceRatio: strongAvoidance, + strongBuilderCallsAvoided: eligibleCompletedWithoutStrong.length, + completedWorkUnitsPerImplementationAttempt: completedPerAttempt, + baseline: facts.baseline === void 0 ? null : { + kind: facts.baseline.kind, + reportId: facts.baseline.reportId, + strongBuilderAttempts: facts.baseline.strongBuilderAttempts, + sameVerificationOutcome: facts.baseline.verificationOutcome === overallVerification, + sameClosureOutcome: facts.baseline.closureOutcome === closureOutcome + } + }, + qualificationSummary: { + strongBuilderAvoidanceRatio: strongAvoidance.value, + secondaryInitialSuccessRate: secondaryInitial.value, + secondaryRepairRecoveryRate: secondaryRepair.value, + secondaryToStrongFallback: fallbackUnits.length, + strongImplementationTokens: strongTokens.completeTokens, + researchAvoidanceRatio: researchAvoidance.value, + newResearchCalls: providerCallCount, + researchReuse: reuseCount, + usefulWorkDuringSubscriptionCooldown: cooldownCompletedKeys.size, + humanInterventionsAfterSeal: facts.autonomy.humanInterventionsAfterSeal, + completedWorkRedoCount, + unexpectedBlocks, + unrecoveredDriverDeaths + }, + diagnostics: diagnostics.slice(0, 200) + }); + return report; +} +function cooldownEventDetail(event) { + switch (event.type) { + case "resource_cooldown_started": + return `Strong resource cooldown started (${String(event["availability"] ?? "availability unknown")}).`; + case "resource_cooldown_observed": + return "Strong resource cooldown was observed again; this is not a new episode."; + case "work_unit_resource_wait_started": + return `WorkUnit ${String(event["workUnitId"] ?? "(unknown)")} entered a Strong resource wait.`; + case "work_unit_resource_wait_ended": + return `WorkUnit ${String(event["workUnitId"] ?? "(unknown)")} left its Strong resource wait.`; + case "resource_wait_entered": + return "The job entered a global resource wait because no permitted work remained runnable."; + case "useful_work_during_cooldown": + return `${Number(event["newlyCompleted"] ?? 0)} additional WorkUnit(s) completed during cooldown.`; + case "resource_recovered": + return "The Strong resource recovered and waiting work was released."; + default: + return event.type; + } +} +function collectExecutionTelemetryFacts(deps, jobId, options = {}) { + const job = requireJobState(deps.workspace, jobId); + const eventPage = readJobEvents(deps.workspace, jobId, { limit: 500 }); + const objectives = listObjectiveNodes(deps.workspace, jobId).map( + (objectiveNodeId) => ({ + objectiveNodeId, + graph: readLatestWorkGraph(deps.workspace, jobId, objectiveNodeId), + routingStates: readBuilderRoutingStates(deps.workspace, jobId, objectiveNodeId), + cooldown: readObjectiveCooldownState(deps.workspace, jobId, objectiveNodeId), + evaluations: readEvaluations(deps.workspace, jobId, objectiveNodeId) + }) + ); + const researchTelemetryRead = readResearchTelemetry(deps.workspace); + const researchRecords = listResearchRecords(deps.workspace); + const binding = readSealBinding(deps.workspace, jobId); + const seal = readJobSeal(deps.workspace, jobId); + return { + job, + events: eventPage.events, + eventTotal: eventPage.total, + ledger: readExecutionLedger(deps.workspace, jobId), + objectives, + researchTelemetry: researchTelemetryRead.telemetry, + ...researchTelemetryRead.diagnostic !== void 0 ? { researchTelemetryDiagnostic: researchTelemetryRead.diagnostic } : {}, + researchRecords: researchRecords.records, + researchRecordDiagnostics: researchRecords.diagnostics.map((diagnostic) => ({ + code: diagnostic.code, + message: diagnostic.message + })), + researchUses: listResearchUseRecords(deps.workspace), + autonomy: deriveAutonomyTelemetry(deps, { jobId }), + closure: readClosureLedger(deps.workspace, jobId), + ...binding !== void 0 ? { binding } : {}, + ...seal !== void 0 ? { seal } : {}, + generatedAt: nowIso2(deps), + ...options.specbridgeVersion !== void 0 ? { specbridgeVersion: options.specbridgeVersion } : {}, + secondaryBuildStrategy: deps.config.orchestration.jobs.objectives.secondaryBuilder.strategy, + researchStrategy: deps.config.research.strategy, + runnerProfiles: Object.keys(deps.config.runnerProfiles), + currentAutonomyPolicy: deps.config.autonomy, + closurePolicy: deps.config.autonomy.closure + }; +} +function executionTelemetryReportFile(workspace, jobId) { + if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(jobId)) { + throw new Error(`Invalid job id "${jobId}".`); + } + return assertInsideWorkspace( + workspace.rootDir, + import_path50.default.join(workspace.sidecarDir, "reports", `job-${jobId}-telemetry.json`) + ); +} +function persistExecutionTelemetryReport(workspace, report) { + const validated = executionTelemetryReportSchema.parse(report); + const file = executionTelemetryReportFile(workspace, validated.jobId); + (0, import_fs47.mkdirSync)(import_path50.default.dirname(file), { recursive: true }); + writeFileAtomic(file, `${JSON.stringify(validated, null, 2)} +`); + return file; +} +function computeExecutionTelemetryReport(deps, jobId, options = {}) { + const report = deriveExecutionTelemetryReport( + collectExecutionTelemetryFacts(deps, jobId, options) + ); + if (options.persist === true) persistExecutionTelemetryReport(deps.workspace, report); + return report; +} +var shortText132 = external_exports.string().max(200); var text12 = external_exports.string().max(4e3); var controlPlaneRepairSchema = external_exports.object({ schemaVersion: external_exports.string().regex(/^\d+\.\d+\.\d+$/), - repairId: shortText122, + repairId: shortText132, /** The product job that hit the defect and is suspended for this. */ - productJobId: shortText122, + productJobId: shortText132, defectKind: external_exports.enum(CONTROL_PLANE_DEFECT_KINDS), /** What was observed, in one line. Never a stack trace with paths. */ symptom: text12, @@ -86110,238 +87495,830 @@ var controlPlaneRepairSchema = external_exports.object({ status: external_exports.enum(CONTROL_PLANE_REPAIR_STATUSES), /** Stages completed, in order. The gate is that this is a prefix. */ stagesCompleted: external_exports.array(external_exports.enum(CONTROL_PLANE_REPAIR_STAGES)).max(20).default([]), - createdAt: shortText122, - updatedAt: shortText122, - finishedAt: shortText122.optional(), + createdAt: shortText132, + updatedAt: shortText132, + finishedAt: shortText132.optional(), /** Isolated working copy the patch was developed in. */ - isolationPath: shortText122.optional(), + isolationPath: shortText132.optional(), /** Where the verified build was staged. Never the running installation. */ - artifactPath: shortText122.optional(), + artifactPath: shortText132.optional(), /** Files the patch touched, workspace-relative to the SpecBridge source. */ - changedFiles: external_exports.array(shortText122).max(200).default([]), + changedFiles: external_exports.array(shortText132).max(200).default([]), /** The regression test added, which is mandatory. */ - regressionTestPath: shortText122.optional(), + regressionTestPath: shortText132.optional(), /** Invariants the screen found the patch touching. Non-empty means reject. */ invariantViolations: external_exports.array( external_exports.object({ - invariant: external_exports.enum(PROTECTED_CONTROL_PLANE_INVARIANTS), - file: shortText122, - evidence: text12 - }).passthrough() - ).max(50).default([]), - /** Why the repair ended where it did. */ - outcomeDetail: text12.optional() -}).passthrough(); -var CERTIFICATION_MATRIX = Object.freeze([ - { - id: "ZT-01", - fault: "STRONG_PROVIDER_UNAVAILABLE", - title: "the subscription provider is temporarily down", - situation: "The strong worker returns 529/overloaded for every dispatch.", - injection: "driver host returns a crashed outcome carrying the provider signature", - expectation: "SELF_RECOVERED", - expectedBehaviour: "WAITING_RESOURCE with a provider cooldown, re-checked and resumed without a human" - }, - { - id: "ZT-02", - fault: "STRONG_QUOTA_EXHAUSTED", - title: "the subscription quota is exhausted until a known reset", - situation: "The provider reports no remaining capacity and names a reset time.", - injection: "driver host returns a deferred stop carrying retryAt", - expectation: "SELF_RECOVERED", - expectedBehaviour: "WAITING_RESOURCE with wakeAt set; the supervisor sleeps and wakes itself" - }, - { - id: "ZT-03", - fault: "LOCAL_RUNTIME_CRASH", - title: "the local llama.cpp process crashes", - situation: "The managed local inference server exits mid-dispatch.", - injection: "driver host crashes with a local-model signature", - expectation: "SELF_RECOVERED", - expectedBehaviour: "RECOVERING_PROVIDER, the runtime restarts the local runtime and continues" - }, - { - id: "ZT-04", - fault: "INVALID_STRUCTURED_OUTPUT", - title: "a model returns structured output that does not validate", - situation: "The local model produces JSON the agent contract rejects.", - injection: "driver host crashes with an invalid-output signature", - expectation: "SELF_RECOVERED", - expectedBehaviour: "a bounded retry, then escalation to a stronger tier. Never a question" - }, - { - id: "ZT-05", - fault: "CONTEXT_EXHAUSTION", - title: "the context window is exceeded mid-task", - situation: "A dispatch fails because the prompt exceeds the model context.", - injection: "driver host crashes with a context-length signature", - expectation: "SELF_RECOVERED", - expectedBehaviour: "checkpoint, compact, reconstruct in a fresh session, continue. Task memory is not the context window" - }, - { - id: "ZT-06", - fault: "WORKER_PROCESS_TERMINATED", - title: "a worker process is killed", - situation: "The runner child process is terminated by the OS.", - injection: "driver host crashes with a process-termination signature", - expectation: "SELF_RECOVERED", - expectedBehaviour: "the attempt is reconciled as INTERRUPTED and re-dispatched" - }, - { - id: "ZT-07", - fault: "DRIVER_PROCESS_TERMINATED", - title: "the driver itself dies", - situation: "The orchestrating driver process is killed without cleanup.", - injection: "driver host crashes on its first run and succeeds on the next", - expectation: "SELF_RECOVERED", - expectedBehaviour: "the supervisor observes the dead driver and restarts it under the same lease" - }, - { - id: "ZT-08", - fault: "CONTAINER_SERVICE_CRASH", - title: "a container service crashes", - situation: "A compose service exits during a system scenario.", - injection: "driver host crashes with a container signature", - expectation: "SELF_RECOVERED", - expectedBehaviour: "REPAIRING_ENVIRONMENT; the service is restarted within its budget" - }, - { - id: "ZT-09", - fault: "DELAYED_SERVICE_READINESS", - title: "a service takes far longer than expected to become ready", - situation: "Postgres accepts TCP long before it accepts a connection.", - injection: "readiness probe reports not-ready for several attempts", - expectation: "SELF_RECOVERED", - expectedBehaviour: "the readiness loop waits, restarts within budget, and proceeds when it answers" - }, - { - id: "ZT-10", - fault: "MISSING_PROJECT_DEPENDENCY", - title: "a project dependency is missing", - situation: 'A build fails with "cannot find module".', - injection: "driver host crashes with a missing-module signature", - expectation: "SELF_RECOVERED", - expectedBehaviour: "REPAIRING_TOOLCHAIN; the Toolsmith installs it. A missing package is engineering" - }, - { - id: "ZT-11", - fault: "MISSING_BROWSER_RUNTIME", - title: "no browser runtime is installed", - situation: "A UI acceptance criterion needs a browser and none exists.", - injection: "browser driver reports unavailable", - expectation: "SELF_RECOVERED", - expectedBehaviour: "the scenario records SKIPPED_NO_RUNTIME, the criterion stays unclosed, and the Toolsmith is asked for the runtime" - }, - { - id: "ZT-12", - fault: "FAILING_IMPLEMENTATION_TEST", - title: "the implementation is wrong and the tests say so", - situation: "A trusted verification command fails against the produced code.", - injection: "closure evidence registered as failing", - expectation: "SELF_RECOVERED", - expectedBehaviour: "the item stays unclosed with EVIDENCE_FAILED and gap work repairs it" - }, - { - id: "ZT-13", - fault: "WRONG_STRATEGY_REQUIRES_REPLAN", - title: "the approach is wrong and needs replanning", - situation: "A replan proposes restructuring the internal architecture.", - injection: "the authority resolver is asked about an architecture-flavoured replan", - expectation: "SELF_RECOVERED", - expectedBehaviour: "the replan proceeds under delegated authority. Internal architecture is not a promise" - }, - { - id: "ZT-14", - fault: "TRANSIENT_NETWORK_FAILURE", - title: "a transient network failure", - situation: "A registry or provider connection is refused once.", - injection: "driver host crashes with a network signature, then succeeds", - expectation: "SELF_RECOVERED", - expectedBehaviour: "RECOVERING_PROVIDER and a bounded retry" - }, - { - id: "ZT-15", - fault: "CONTROL_PLANE_RUNNER_DEFECT", - title: "a SpecBridge runner defect", - situation: "The provider CLI rejects an argument SpecBridge passes.", - injection: "driver host crashes with an unknown-option signature", - expectation: "SELF_RECOVERED", - expectedBehaviour: "REPAIRING_CONTROL_PLANE; the governed repair path runs and the operator does not become the SpecBridge maintainer" - }, - { - id: "ZT-16", - fault: "SEALED_CONTRACT_CHANGE_REQUIRED", - title: "completing the work requires changing a sealed public contract", - situation: "The only way to satisfy a requirement is to change the public API the human already approved.", - injection: "the authority resolver is asked about a public-api replan", - expectation: "NEEDS_AUTHORITY", - expectedBehaviour: "the job stops in NEEDS_AUTHORITY with the question recorded, and the sealed contract is NOT modified" - } -]); -var shortText132 = external_exports.string().max(200); -var text13 = external_exports.string().max(4e3); -var certificationScenarioResultSchema = external_exports.object({ - scenarioId: shortText132, - fault: external_exports.enum(ZERO_TOUCH_FAULTS), - expectation: external_exports.enum(ZERO_TOUCH_EXPECTATIONS), - outcome: external_exports.enum(ZERO_TOUCH_OUTCOMES), - /** Human interventions observed. Anything above zero fails the scenario. */ - humanInterventions: external_exports.number().int().min(0), - /** Authority escalations. Expected exactly on the authority scenario. */ - authorityEscalations: external_exports.number().int().min(0), - /** What the runtime actually did, in one or two lines. */ - observed: text13, - /** The job status the scenario ended in. */ - finalStatus: shortText132.optional(), - /** Operational statuses the job passed through, in order. */ - recoveryPath: external_exports.array(shortText132).max(30).default([]), - /** Present when the scenario could not run here. Never a pass. */ - skipReason: text13.optional(), - startedAt: shortText132, - finishedAt: shortText132.optional(), - durationMs: external_exports.number().int().min(0).nullable().default(null) -}).passthrough(); -var certificationRunSchema = external_exports.object({ - schemaVersion: external_exports.string().regex(/^\d+\.\d+\.\d+$/), - runId: shortText132, - createdAt: shortText132, - finishedAt: shortText132.optional(), - host: shortText132, - verdict: external_exports.enum(CERTIFICATION_VERDICTS), - results: external_exports.array(certificationScenarioResultSchema).max(100).default([]), - /** Totals, hoisted so the headline needs no arithmetic. */ - totals: external_exports.object({ - total: external_exports.number().int().min(0), - selfRecovered: external_exports.number().int().min(0), - needsAuthority: external_exports.number().int().min(0), - askedHuman: external_exports.number().int().min(0), - stuck: external_exports.number().int().min(0), - selfAuthorized: external_exports.number().int().min(0), - skipped: external_exports.number().int().min(0), - notRun: external_exports.number().int().min(0) - }).passthrough(), - /** - * Total human interventions across every scenario. The headline number: - * a certified run has zero, and any non-zero value is named here rather - * than buried in a per-scenario field. - */ - humanInterventionsAfterSeal: external_exports.number().int().min(0), - /** Why the verdict is what it is, in one or two lines. */ - rationale: text13, - /** Scenarios that failed, with what happened, for the report. */ - failures: external_exports.array(external_exports.object({ scenarioId: shortText132, outcome: shortText132, observed: text13 }).passthrough()).max(100).default([]) -}).passthrough(); + invariant: external_exports.enum(PROTECTED_CONTROL_PLANE_INVARIANTS), + file: shortText132, + evidence: text12 + }).passthrough() + ).max(50).default([]), + /** Why the repair ended where it did. */ + outcomeDetail: text12.optional() +}).passthrough(); +var CERTIFICATION_MATRIX = Object.freeze([ + { + id: "ZT-01", + fault: "STRONG_PROVIDER_UNAVAILABLE", + title: "the subscription provider is temporarily down", + situation: "The strong worker returns 529/overloaded for every dispatch.", + injection: "driver host returns a crashed outcome carrying the provider signature", + expectation: "SELF_RECOVERED", + expectedBehaviour: "WAITING_RESOURCE with a provider cooldown, re-checked and resumed without a human" + }, + { + id: "ZT-02", + fault: "STRONG_QUOTA_EXHAUSTED", + title: "the subscription quota is exhausted until a known reset", + situation: "The provider reports no remaining capacity and names a reset time.", + injection: "driver host returns a deferred stop carrying retryAt", + expectation: "SELF_RECOVERED", + expectedBehaviour: "WAITING_RESOURCE with wakeAt set; the supervisor sleeps and wakes itself" + }, + { + id: "ZT-03", + fault: "LOCAL_RUNTIME_CRASH", + title: "the local llama.cpp process crashes", + situation: "The managed local inference server exits mid-dispatch.", + injection: "driver host crashes with a local-model signature", + expectation: "SELF_RECOVERED", + expectedBehaviour: "RECOVERING_PROVIDER, the runtime restarts the local runtime and continues" + }, + { + id: "ZT-04", + fault: "INVALID_STRUCTURED_OUTPUT", + title: "a model returns structured output that does not validate", + situation: "The local model produces JSON the agent contract rejects.", + injection: "driver host crashes with an invalid-output signature", + expectation: "SELF_RECOVERED", + expectedBehaviour: "a bounded retry, then escalation to a stronger tier. Never a question" + }, + { + id: "ZT-05", + fault: "CONTEXT_EXHAUSTION", + title: "the context window is exceeded mid-task", + situation: "A dispatch fails because the prompt exceeds the model context.", + injection: "driver host crashes with a context-length signature", + expectation: "SELF_RECOVERED", + expectedBehaviour: "checkpoint, compact, reconstruct in a fresh session, continue. Task memory is not the context window" + }, + { + id: "ZT-06", + fault: "WORKER_PROCESS_TERMINATED", + title: "a worker process is killed", + situation: "The runner child process is terminated by the OS.", + injection: "driver host crashes with a process-termination signature", + expectation: "SELF_RECOVERED", + expectedBehaviour: "the attempt is reconciled as INTERRUPTED and re-dispatched" + }, + { + id: "ZT-07", + fault: "DRIVER_PROCESS_TERMINATED", + title: "the driver itself dies", + situation: "The orchestrating driver process is killed without cleanup.", + injection: "driver host crashes on its first run and succeeds on the next", + expectation: "SELF_RECOVERED", + expectedBehaviour: "the supervisor observes the dead driver and restarts it under the same lease" + }, + { + id: "ZT-08", + fault: "CONTAINER_SERVICE_CRASH", + title: "a container service crashes", + situation: "A compose service exits during a system scenario.", + injection: "driver host crashes with a container signature", + expectation: "SELF_RECOVERED", + expectedBehaviour: "REPAIRING_ENVIRONMENT; the service is restarted within its budget" + }, + { + id: "ZT-09", + fault: "DELAYED_SERVICE_READINESS", + title: "a service takes far longer than expected to become ready", + situation: "Postgres accepts TCP long before it accepts a connection.", + injection: "readiness probe reports not-ready for several attempts", + expectation: "SELF_RECOVERED", + expectedBehaviour: "the readiness loop waits, restarts within budget, and proceeds when it answers" + }, + { + id: "ZT-10", + fault: "MISSING_PROJECT_DEPENDENCY", + title: "a project dependency is missing", + situation: 'A build fails with "cannot find module".', + injection: "driver host crashes with a missing-module signature", + expectation: "SELF_RECOVERED", + expectedBehaviour: "REPAIRING_TOOLCHAIN; the Toolsmith installs it. A missing package is engineering" + }, + { + id: "ZT-11", + fault: "MISSING_BROWSER_RUNTIME", + title: "no browser runtime is installed", + situation: "A UI acceptance criterion needs a browser and none exists.", + injection: "browser driver reports unavailable", + expectation: "SELF_RECOVERED", + expectedBehaviour: "the scenario records SKIPPED_NO_RUNTIME, the criterion stays unclosed, and the Toolsmith is asked for the runtime" + }, + { + id: "ZT-12", + fault: "FAILING_IMPLEMENTATION_TEST", + title: "the implementation is wrong and the tests say so", + situation: "A trusted verification command fails against the produced code.", + injection: "closure evidence registered as failing", + expectation: "SELF_RECOVERED", + expectedBehaviour: "the item stays unclosed with EVIDENCE_FAILED and gap work repairs it" + }, + { + id: "ZT-13", + fault: "WRONG_STRATEGY_REQUIRES_REPLAN", + title: "the approach is wrong and needs replanning", + situation: "A replan proposes restructuring the internal architecture.", + injection: "the authority resolver is asked about an architecture-flavoured replan", + expectation: "SELF_RECOVERED", + expectedBehaviour: "the replan proceeds under delegated authority. Internal architecture is not a promise" + }, + { + id: "ZT-14", + fault: "TRANSIENT_NETWORK_FAILURE", + title: "a transient network failure", + situation: "A registry or provider connection is refused once.", + injection: "driver host crashes with a network signature, then succeeds", + expectation: "SELF_RECOVERED", + expectedBehaviour: "RECOVERING_PROVIDER and a bounded retry" + }, + { + id: "ZT-15", + fault: "CONTROL_PLANE_RUNNER_DEFECT", + title: "a SpecBridge runner defect", + situation: "The provider CLI rejects an argument SpecBridge passes.", + injection: "driver host crashes with an unknown-option signature", + expectation: "SELF_RECOVERED", + expectedBehaviour: "REPAIRING_CONTROL_PLANE; the governed repair path runs and the operator does not become the SpecBridge maintainer" + }, + { + id: "ZT-16", + fault: "SEALED_CONTRACT_CHANGE_REQUIRED", + title: "completing the work requires changing a sealed public contract", + situation: "The only way to satisfy a requirement is to change the public API the human already approved.", + injection: "the authority resolver is asked about a public-api replan", + expectation: "NEEDS_AUTHORITY", + expectedBehaviour: "the job stops in NEEDS_AUTHORITY with the question recorded, and the sealed contract is NOT modified" + } +]); +var shortText142 = external_exports.string().max(200); +var text13 = external_exports.string().max(4e3); +var certificationScenarioResultSchema = external_exports.object({ + scenarioId: shortText142, + fault: external_exports.enum(ZERO_TOUCH_FAULTS), + expectation: external_exports.enum(ZERO_TOUCH_EXPECTATIONS), + outcome: external_exports.enum(ZERO_TOUCH_OUTCOMES), + /** Human interventions observed. Anything above zero fails the scenario. */ + humanInterventions: external_exports.number().int().min(0), + /** Authority escalations. Expected exactly on the authority scenario. */ + authorityEscalations: external_exports.number().int().min(0), + /** What the runtime actually did, in one or two lines. */ + observed: text13, + /** The job status the scenario ended in. */ + finalStatus: shortText142.optional(), + /** Operational statuses the job passed through, in order. */ + recoveryPath: external_exports.array(shortText142).max(30).default([]), + /** Present when the scenario could not run here. Never a pass. */ + skipReason: text13.optional(), + startedAt: shortText142, + finishedAt: shortText142.optional(), + durationMs: external_exports.number().int().min(0).nullable().default(null) +}).passthrough(); +var certificationRunSchema = external_exports.object({ + schemaVersion: external_exports.string().regex(/^\d+\.\d+\.\d+$/), + runId: shortText142, + createdAt: shortText142, + finishedAt: shortText142.optional(), + host: shortText142, + verdict: external_exports.enum(CERTIFICATION_VERDICTS), + results: external_exports.array(certificationScenarioResultSchema).max(100).default([]), + /** Totals, hoisted so the headline needs no arithmetic. */ + totals: external_exports.object({ + total: external_exports.number().int().min(0), + selfRecovered: external_exports.number().int().min(0), + needsAuthority: external_exports.number().int().min(0), + askedHuman: external_exports.number().int().min(0), + stuck: external_exports.number().int().min(0), + selfAuthorized: external_exports.number().int().min(0), + skipped: external_exports.number().int().min(0), + notRun: external_exports.number().int().min(0) + }).passthrough(), + /** + * Total human interventions across every scenario. The headline number: + * a certified run has zero, and any non-zero value is named here rather + * than buried in a per-scenario field. + */ + humanInterventionsAfterSeal: external_exports.number().int().min(0), + /** Why the verdict is what it is, in one or two lines. */ + rationale: text13, + /** Scenarios that failed, with what happened, for the report. */ + failures: external_exports.array(external_exports.object({ scenarioId: shortText142, outcome: shortText142, observed: text13 }).passthrough()).max(100).default([]) +}).passthrough(); + +// ../../packages/mcp-server/src/tools/job-report.ts +function percent(value) { + return value === null ? "n/a" : `${(value * 100).toFixed(1)}%`; +} +function registerJobReportTool(server, context) { + registerDefinedTool(server, context, { + name: "job_report", + title: "Read a Job execution report", + description: "Derive versioned operational and token-conservation telemetry from durable Job, WorkUnit, attempt, research, cooldown, verification, and closure records. Read-only; metrics never grant completion or authority.", + annotations: { + readOnlyHint: true, + destructiveHint: false, + idempotentHint: true, + openWorldHint: false + }, + inputSchema: { + jobId: external_exports.string().min(1).max(64).describe("Job id (job-\u2026) from job_list") + }, + outputSchema: { + report: executionTelemetryReportSchema + }, + handler: async (args) => { + const workspace = context.requireWorkspace(); + const deps = { + workspace, + config: requireAgentConfig(workspace), + clock: context.clock, + idFactory: context.idFactory, + host: "mcp" + }; + const report = computeExecutionTelemetryReport(deps, args.jobId, { + persist: false, + specbridgeVersion: MCP_SERVER_VERSION + }); + const summary = report.qualificationSummary; + return { + text: [ + `Job ${report.jobId}: ${report.outcome.status} (${report.outcome.authoritativeJobStatus})`, + `StrongBuilderAvoidanceRatio: ${percent(summary.strongBuilderAvoidanceRatio)}`, + `Secondary initial/repair: ${percent(summary.secondaryInitialSuccessRate)} / ${percent(summary.secondaryRepairRecoveryRate)}`, + `ResearchAvoidanceRatio: ${percent(summary.researchAvoidanceRatio)}`, + `UsefulWorkDuringSubscriptionCooldown: ${summary.usefulWorkDuringSubscriptionCooldown}`, + `humanInterventionsAfterSeal: ${summary.humanInterventionsAfterSeal}`, + `CompletedWorkRedoCount: ${summary.completedWorkRedoCount}`, + `Verification / closure: ${report.outcome.verification} / ${report.outcome.closure}` + ].join("\n"), + structured: { report } + }; + } + }); +} + +// ../../packages/mcp-server/src/tools/mission-tools.ts +function missionDeps(context, workspace) { + return { + workspace, + clock: context.clock, + idFactory: context.idFactory, + host: "mcp" + }; +} +var missionIdArg = external_exports.string().min(1).max(64).describe("Mission id (m-\u2026) from mission_begin or mission_status"); +var missionSummaryShape = { + missionId: external_exports.string(), + name: external_exports.string(), + status: external_exports.string(), + specName: external_exports.string().optional(), + openQuestions: external_exports.number().int(), + decisions: external_exports.number().int(), + contracts: external_exports.number().int(), + contractReady: external_exports.boolean().optional() +}; +function summarize3(context, workspace, missionId) { + const mission = requireMissionState(workspace, missionId); + const coverage = readCoverage(workspace, missionId); + return { + missionId: mission.missionId, + name: mission.name, + status: mission.status, + ...mission.specName !== void 0 ? { specName: mission.specName } : {}, + openQuestions: mission.counters.openQuestions, + decisions: mission.counters.decisions, + contracts: mission.counters.contracts, + ...coverage !== void 0 ? { contractReady: coverage.contractReady } : {} + }; +} +function registerMissionBeginTool(server, context) { + registerDefinedTool(server, context, { + name: "mission_begin", + title: "Begin a mission", + description: "Begin Mission Discovery from a high-level product direction. Creates the durable mission record under .specbridge/missions/. Discovery itself is a conversation: record every material visible exchange with mission_record_turn and its structured meaning with mission_assess.", + annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }, + inputSchema: { + name: external_exports.string().min(1).max(120).describe("Short mission name (also the default spec name)"), + goal: external_exports.string().min(1).max(4e3).describe("The user's product direction, verbatim") + }, + outputSchema: { mission: external_exports.object(missionSummaryShape) }, + handler: async (args) => { + const workspace = context.requireWorkspace(); + const mission = beginMission(missionDeps(context, workspace), { name: args.name, goal: args.goal }); + return { + text: `Mission ${mission.missionId} (${mission.name}) created in status ${mission.status}. Record the user's direction as the first turn.`, + structured: { mission: summarize3(context, workspace, mission.missionId) } + }; + } + }); +} +function registerMissionStatusTool(server, context) { + registerDefinedTool(server, context, { + name: "mission_status", + title: "List missions", + description: "List missions (newest first) with lifecycle status, counters, and readiness. Read-only.", + annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, + inputSchema: {}, + outputSchema: { missions: external_exports.array(external_exports.object(missionSummaryShape)) }, + handler: async () => { + const workspace = context.requireWorkspace(); + const listed = listMissions(workspace); + const missions = listed.missions.slice(0, 50).map((mission) => summarize3(context, workspace, mission.missionId)); + return { + text: missions.length === 0 ? "No missions exist. Begin one with mission_begin." : missions.map((mission) => `- ${mission.missionId} ${mission.status} (${mission.name})`).join("\n"), + structured: { missions } + }; + } + }); +} +function registerMissionReadTool(server, context) { + registerDefinedTool(server, context, { + name: "mission_read", + title: "Read one mission", + description: "Read one mission in depth. `view` selects the record family: overview (default), facts, decisions, questions, conversation, coverage, constitution, adrs, or ccrs. Bounded; read-only.", + annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, + inputSchema: { + missionId: missionIdArg, + view: external_exports.enum(["overview", "facts", "decisions", "questions", "conversation", "coverage", "constitution", "adrs", "ccrs"]).optional().describe("Which record family to read (default overview)"), + limit: external_exports.number().int().min(1).max(200).optional().describe("Bounded page size for list views") + }, + outputSchema: { + mission: external_exports.object(missionSummaryShape), + view: external_exports.string(), + records: external_exports.array(external_exports.record(external_exports.unknown())) + }, + handler: async (args) => { + const workspace = context.requireWorkspace(); + const deps = missionDeps(context, workspace); + observeSpecApproval(deps, args.missionId); + const view = args.view ?? "overview"; + const limit = args.limit ?? 50; + let records = []; + switch (view) { + case "overview": { + const overview = describeMission(deps, args.missionId); + records = [ + { + goal: overview.mission.goal, + nonGoals: overview.mission.nonGoals, + targetUsers: overview.mission.targetUsers, + constraints: overview.mission.constraints, + successCriteria: overview.mission.successCriteria, + assumptions: overview.mission.assumptions, + constitutionVersion: overview.constitutionVersion, + activeConstitutionRules: overview.activeConstitutionRules, + contractCount: overview.contractCount, + adrCount: overview.adrCount, + blockingQuestions: overview.blockingQuestions, + openCcrs: overview.openCcrs + } + ]; + break; + } + case "facts": + records = readFacts(workspace, args.missionId).slice(-limit); + break; + case "decisions": + records = readDecisions(workspace, args.missionId).slice(-limit); + break; + case "questions": + records = readQuestions(workspace, args.missionId).slice(-limit); + break; + case "conversation": + records = readTurns(workspace, args.missionId, { limit }).turns; + break; + case "coverage": { + const coverage = readCoverage(workspace, args.missionId); + records = coverage !== void 0 ? [coverage] : []; + break; + } + case "constitution": { + const constitution = readConstitution(workspace, args.missionId); + records = constitution !== void 0 ? [constitution] : []; + break; + } + case "adrs": + records = readAdrs(workspace, args.missionId).slice(-limit); + break; + case "ccrs": + records = readCcrs(workspace, args.missionId).slice(-limit); + break; + } + return { + text: `${view}: ${records.length} record(s).`, + structured: { mission: summarize3(context, workspace, args.missionId), view, records } + }; + } + }); +} +function registerMissionRecordTurnTool(server, context) { + registerDefinedTool(server, context, { + name: "mission_record_turn", + title: "Record a visible discovery turn", + description: "Persist one USER-VISIBLE discovery exchange verbatim: what the user said, or what the agent visibly asked, interpreted, or presented. Turns are the provenance roots every decision traces back to. Never record hidden reasoning \u2014 only what both sides could see.", + annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }, + inputSchema: { + missionId: missionIdArg, + speaker: external_exports.enum(TURN_SPEAKERS).describe("Who produced the visible text"), + kind: external_exports.enum(TURN_KINDS).describe("What kind of exchange this is"), + text: external_exports.string().min(1).max(8e3).describe("The visible text, verbatim"), + inReplyTo: external_exports.string().max(64).optional().describe("Turn id this replies to"), + refs: external_exports.array(external_exports.string().max(64)).max(30).optional().describe("Record ids this turn addresses") + }, + outputSchema: { turnId: external_exports.string(), missionStatus: external_exports.string() }, + handler: async (args) => { + const workspace = context.requireWorkspace(); + const result = recordTurn(missionDeps(context, workspace), args.missionId, { + speaker: args.speaker, + kind: args.kind, + text: args.text, + inReplyTo: args.inReplyTo, + refs: args.refs + }); + return { + text: `Recorded ${result.turn.turnId} (${args.speaker} ${args.kind}). Mission is ${result.mission.status}.`, + structured: { turnId: result.turn.turnId, missionStatus: result.mission.status } + }; + } + }); +} +var factInput = external_exports.object({ + statement: external_exports.string().min(1).max(4e3), + provenance: external_exports.enum(MISSION_PROVENANCE_KINDS), + sourceTurnId: external_exports.string().max(64).optional(), + topics: external_exports.array(external_exports.enum(DISCOVERY_TOPICS)).max(10).optional(), + supersedesFactId: external_exports.string().max(64).optional() +}); +var questionInput = external_exports.object({ + question: external_exports.string().min(1).max(4e3), + whyItMatters: external_exports.string().min(1).max(4e3), + topics: external_exports.array(external_exports.enum(DISCOVERY_TOPICS)).max(10).optional(), + affectedSurfaces: external_exports.array(external_exports.enum(IRREVERSIBLE_SURFACES)).max(10).optional(), + materiality: external_exports.enum(MATERIALITY_LEVELS).optional(), + options: external_exports.array(external_exports.string().max(2e3)).max(10).optional(), + sourceTurnId: external_exports.string().max(64).optional() +}); +var decisionInput = external_exports.object({ + decision: external_exports.string().min(1).max(4e3), + rationale: external_exports.string().max(4e3).optional(), + provenance: external_exports.enum(MISSION_PROVENANCE_KINDS), + sourceTurnId: external_exports.string().max(64).optional(), + questionId: external_exports.string().max(64).optional(), + topics: external_exports.array(external_exports.enum(DISCOVERY_TOPICS)).max(10).optional(), + marksNotApplicable: external_exports.array(external_exports.enum(DISCOVERY_TOPICS)).max(10).optional(), + supersedesDecisionId: external_exports.string().max(64).optional() +}); +var constitutionRuleInput = external_exports.object({ + statement: external_exports.string().min(1).max(4e3), + rationale: external_exports.string().max(4e3).optional(), + decisionIds: external_exports.array(external_exports.string().max(64)).min(1).max(30), + affectedContractIds: external_exports.array(external_exports.string().max(64)).max(30).optional(), + guardPatterns: external_exports.array(external_exports.string().min(1).max(200)).max(10).optional(), + supersedesRuleId: external_exports.string().max(64).optional() +}); +var adrInput = external_exports.object({ + title: external_exports.string().min(1).max(512), + context: external_exports.string().min(1).max(4e3), + decision: external_exports.string().min(1).max(4e3), + alternatives: external_exports.array(external_exports.string().max(4e3)).max(20).optional(), + rationale: external_exports.string().min(1).max(4e3), + consequences: external_exports.array(external_exports.string().max(4e3)).max(20).optional(), + revisitConditions: external_exports.array(external_exports.string().max(4e3)).max(20).optional(), + decisionIds: external_exports.array(external_exports.string().max(64)).max(30).optional(), + turnIds: external_exports.array(external_exports.string().max(64)).max(30).optional(), + supersedesAdrId: external_exports.string().max(64).optional() +}); +var contractInput = external_exports.object({ + title: external_exports.string().min(1).max(512), + summary: external_exports.string().min(1).max(4e3), + classification: external_exports.enum(["public", "internal"]), + compatibilityPolicy: external_exports.enum(["frozen", "additive-only", "evolving", "internal"]), + dependsOn: external_exports.array(external_exports.string().max(64)).max(30).optional(), + requirements: external_exports.array(external_exports.object({ statement: external_exports.string().min(1).max(4e3), decisionIds: external_exports.array(external_exports.string().max(64)).max(30).optional() })).min(1).max(60), + invariants: external_exports.array( + external_exports.object({ + statement: external_exports.string().min(1).max(4e3), + constitutionRuleIds: external_exports.array(external_exports.string().max(64)).max(30).optional(), + guardPatterns: external_exports.array(external_exports.string().min(1).max(200)).max(10).optional() + }) + ).max(60).optional(), + decisionIds: external_exports.array(external_exports.string().max(64)).min(1).max(30), + turnIds: external_exports.array(external_exports.string().max(64)).max(30).optional() +}); +function registerMissionAssessTool(server, context) { + registerDefinedTool(server, context, { + name: "mission_assess", + title: "Record a structured discovery assessment", + description: "Submit the STRUCTURED meaning of the discovery conversation: facts, questions, decisions, constitution rules, ADRs, contracts, and mission field updates. SpecBridge governs every record: decisions need safe provenance (a user-provenance decision must cite a USER turn), question materiality passes the deterministic irreversibility screen (it can only be RAISED), durable artifacts must trace to recorded decisions, and coverage recomputes deterministically. Blocking questions prevent CONTRACT_READY; implementation-detail questions never do.", + annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }, + inputSchema: { + missionId: missionIdArg, + facts: external_exports.array(factInput).max(20).optional(), + questions: external_exports.array(questionInput).max(20).optional(), + decisions: external_exports.array(decisionInput).max(20).optional(), + constitutionRules: external_exports.array(constitutionRuleInput).max(10).optional(), + adrs: external_exports.array(adrInput).max(10).optional(), + contracts: external_exports.array(contractInput).max(10).optional(), + missionUpdates: external_exports.object({ + nonGoals: external_exports.array(external_exports.string().max(4e3)).max(50).optional(), + targetUsers: external_exports.array(external_exports.string().max(4e3)).max(50).optional(), + constraints: external_exports.array(external_exports.string().max(4e3)).max(50).optional(), + successCriteria: external_exports.array(external_exports.string().max(4e3)).max(50).optional(), + assumptions: external_exports.array( + external_exports.object({ + statement: external_exports.string().min(1).max(4e3), + topics: external_exports.array(external_exports.enum(DISCOVERY_TOPICS)).max(10).optional(), + questionId: external_exports.string().max(64).optional() + }) + ).max(50).optional() + }).optional() + }, + outputSchema: { + missionStatus: external_exports.string(), + contractReady: external_exports.boolean(), + factIds: external_exports.array(external_exports.string()), + questionIds: external_exports.array(external_exports.string()), + decisionIds: external_exports.array(external_exports.string()), + constitutionRuleIds: external_exports.array(external_exports.string()), + adrIds: external_exports.array(external_exports.string()), + contractIds: external_exports.array(external_exports.string()), + materialityRaised: external_exports.array( + external_exports.object({ questionId: external_exports.string(), from: external_exports.string(), to: external_exports.string() }) + ), + blockingQuestionIds: external_exports.array(external_exports.string()), + unresolvedRequiredTopics: external_exports.array(external_exports.string()) + }, + handler: async (args) => { + const workspace = context.requireWorkspace(); + const result = recordAssessment(missionDeps(context, workspace), args.missionId, { + facts: args.facts, + questions: args.questions, + decisions: args.decisions, + constitutionRules: args.constitutionRules, + adrs: args.adrs, + contracts: args.contracts, + missionUpdates: args.missionUpdates + }); + const raised = result.materialityRaised.map((entry) => `${entry.questionId} raised ${entry.from} \u2192 ${entry.to}`).join("; "); + return { + text: `Recorded ${result.factIds.length} fact(s), ${result.questionIds.length} question(s), ${result.decisionIds.length} decision(s), ${result.constitutionRuleIds.length} rule(s), ${result.adrIds.length} ADR(s), ${result.contractIds.length} contract(s). Mission is ${result.mission.status}; contract-ready: ${result.coverage.contractReady}.` + (raised.length > 0 ? ` Materiality screen: ${raised}.` : ""), + structured: { + missionStatus: result.mission.status, + contractReady: result.coverage.contractReady, + factIds: result.factIds, + questionIds: result.questionIds, + decisionIds: result.decisionIds, + constitutionRuleIds: result.constitutionRuleIds, + adrIds: result.adrIds, + contractIds: result.contractIds, + materialityRaised: result.materialityRaised, + blockingQuestionIds: result.coverage.blockingQuestionIds, + unresolvedRequiredTopics: result.coverage.unresolvedRequiredTopics + } + }; + } + }); +} +function registerMissionQuestionsTool(server, context) { + registerDefinedTool(server, context, { + name: "mission_questions", + title: "Open discovery questions", + description: "The open questions with materiality and why each matters. Blocking questions gate CONTRACT_READY. Read-only.", + annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, + inputSchema: { missionId: missionIdArg }, + outputSchema: { + questions: external_exports.array( + external_exports.object({ + questionId: external_exports.string(), + question: external_exports.string(), + whyItMatters: external_exports.string(), + materiality: external_exports.string(), + topics: external_exports.array(external_exports.string()), + options: external_exports.array(external_exports.string()) + }) + ) + }, + handler: async (args) => { + const workspace = context.requireWorkspace(); + requireMissionState(workspace, args.missionId); + const questions = readQuestions(workspace, args.missionId).filter((question) => question.status === "open").map((question) => ({ + questionId: question.questionId, + question: question.question, + whyItMatters: question.whyItMatters, + materiality: question.materiality, + topics: [...question.topics], + options: [...question.options] + })); + return { + text: questions.length === 0 ? "No open questions." : questions.map((question) => `- ${question.questionId} [${question.materiality}] ${question.question}`).join("\n"), + structured: { questions } + }; + } + }); +} +function registerMissionAnswerTool(server, context) { + registerDefinedTool(server, context, { + name: "mission_answer", + title: "Record the user\u2019s answer to a question", + description: "Record the USER'S answer to one open discovery question: an answering user turn plus a known-from-user decision bound to it. Relay their words; never answer on their behalf.", + annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }, + inputSchema: { + missionId: missionIdArg, + questionId: external_exports.string().min(1).max(64), + answer: external_exports.string().min(1).max(4e3).describe("The user's answer, verbatim"), + marksNotApplicable: external_exports.array(external_exports.enum(DISCOVERY_TOPICS)).max(10).optional() + }, + outputSchema: { + decisionId: external_exports.string(), + missionStatus: external_exports.string(), + contractReady: external_exports.boolean() + }, + handler: async (args) => { + const workspace = context.requireWorkspace(); + const result = answerQuestion(missionDeps(context, workspace), args.missionId, { + questionId: args.questionId, + answer: args.answer, + marksNotApplicable: args.marksNotApplicable + }); + return { + text: `Recorded ${result.decision.decisionId}. Mission is ${result.mission.status}; contract-ready: ${result.coverage.contractReady}.`, + structured: { + decisionId: result.decision.decisionId, + missionStatus: result.mission.status, + contractReady: result.coverage.contractReady + } + }; + } + }); +} +function registerMissionSynthesizeTool(server, context) { + registerDefinedTool(server, context, { + name: "mission_synthesize", + title: "Synthesize the Kiro spec", + description: "Move a coverage-complete mission to CONTRACT_READY and compile its contract set into Kiro spec candidates: requirements.md, design.md, and OBJECTIVE-oriented tasks.md \u2014 through the existing creation machinery. Approval stays entirely human (`specbridge spec approve \u2026`); nothing here or anywhere on MCP can approve a stage. Fails closed when blocking questions or required topics remain.", + annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }, + inputSchema: { + missionId: missionIdArg, + specName: external_exports.string().max(64).optional().describe("Spec name (default: the mission name)") + }, + outputSchema: { + specName: external_exports.string(), + objectiveCount: external_exports.number().int(), + files: external_exports.array(external_exports.object({ fileName: external_exports.string(), bytes: external_exports.number().int() })) + }, + handler: async (args) => { + const workspace = context.requireWorkspace(); + const deps = missionDeps(context, workspace); + markContractReady(deps, args.missionId); + const result = synthesizeMissionSpec(deps, args.missionId, { specName: args.specName }); + return { + text: `Synthesized spec "${result.specName}" with ${result.objectiveCount} objective(s). The user approves it with: specbridge spec approve ${result.specName} --stage requirements|design|tasks.`, + structured: { + specName: result.specName, + objectiveCount: result.objectiveCount, + files: result.files + } + }; + } + }); +} +function registerContractListTool(server, context) { + registerDefinedTool(server, context, { + name: "contract_list", + title: "List product contracts", + description: "The mission\u2019s product contract registry (current revisions) plus the Architecture Constitution. Read-only.", + annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, + inputSchema: { missionId: missionIdArg }, + outputSchema: { + constitutionVersion: external_exports.number().int(), + rules: external_exports.array(external_exports.object({ ruleId: external_exports.string(), statement: external_exports.string(), status: external_exports.string() })), + contracts: external_exports.array( + external_exports.object({ + contractId: external_exports.string(), + revision: external_exports.number().int(), + title: external_exports.string(), + classification: external_exports.string(), + compatibilityPolicy: external_exports.string() + }) + ) + }, + handler: async (args) => { + const workspace = context.requireWorkspace(); + requireMissionState(workspace, args.missionId); + const constitution = readConstitution(workspace, args.missionId); + const contracts = readContractRegistry(workspace, args.missionId).map((contract) => ({ + contractId: contract.contractId, + revision: contract.revision, + title: contract.title, + classification: contract.classification, + compatibilityPolicy: contract.compatibilityPolicy + })); + return { + text: contracts.map((contract) => `- ${contract.contractId} r${contract.revision} ${contract.title}`).join("\n") || "No contracts recorded.", + structured: { + constitutionVersion: constitution?.version ?? 0, + rules: (constitution?.rules ?? []).map((rule) => ({ + ruleId: rule.ruleId, + statement: rule.statement, + status: rule.status + })), + contracts + } + }; + } + }); +} +function registerContractReadTool(server, context) { + registerDefinedTool(server, context, { + name: "contract_read", + title: "Read one product contract", + description: "One contract in depth: requirements, invariants, dependencies, provenance, revision lineage. Read-only.", + annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, + inputSchema: { + missionId: missionIdArg, + contractId: external_exports.string().min(1).max(64), + revision: external_exports.number().int().min(1).optional().describe("A specific revision (default: current)") + }, + outputSchema: { contract: external_exports.record(external_exports.unknown()) }, + handler: async (args) => { + const workspace = context.requireWorkspace(); + requireMissionState(workspace, args.missionId); + const contract = readContract(workspace, args.missionId, args.contractId, args.revision); + if (contract === void 0) { + return { + text: `Contract ${args.contractId}${args.revision !== void 0 ? ` r${args.revision}` : ""} does not exist.`, + structured: { contract: {} } + }; + } + return { + text: `${contract.contractId} r${contract.revision}: ${contract.title} \u2014 ${contract.requirements.length} requirement(s), ${contract.invariants.length} invariant(s).`, + structured: { contract } + }; + } + }); +} +function registerContractChangeRequestTool(server, context) { + registerDefinedTool(server, context, { + name: "contract_change_request", + title: "Create a contract change request", + description: "Create a durable ContractChangeRequest against a product contract. Anyone may RAISE one; only the human decides it (CLI: `specbridge mission ccr --approve|--reject`). A material request (public contract, frozen/additive policy, or irreversible surface) lands NEEDS_HUMAN and stops affected execution. This tool can never approve anything.", + annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false }, + inputSchema: { + missionId: missionIdArg, + contractId: external_exports.string().min(1).max(64), + problem: external_exports.string().min(1).max(4e3).describe("What the current contract cannot express"), + proposal: external_exports.string().min(1).max(4e3).describe("The proposed change"), + affected: external_exports.array(external_exports.string().max(2e3)).max(30).optional().describe("Areas the change would touch") + }, + outputSchema: { + ccrId: external_exports.string(), + status: external_exports.string(), + material: external_exports.boolean() + }, + handler: async (args) => { + const workspace = context.requireWorkspace(); + const result = createContractChangeRequest(missionDeps(context, workspace), args.missionId, { + contractId: args.contractId, + problem: args.problem, + proposal: args.proposal, + affected: args.affected, + raisedBy: "mcp" + }); + return { + text: `${result.ccr.ccrId} created (${result.ccr.status}). ` + (result.material ? "It is material: the human decides it with `specbridge mission ccr \u2026 --approve|--reject`." : "It is recorded for the next contract review."), + structured: { ccrId: result.ccr.ccrId, status: result.ccr.status, material: result.material } + }; + } + }); +} // ../../packages/intake/dist/index.js -var import_fs47 = require("fs"); -var import_path50 = __toESM(require("path"), 1); -var import_path51 = __toESM(require("path"), 1); +var import_crypto18 = require("crypto"); var import_fs48 = require("fs"); -var import_path52 = __toESM(require("path"), 1); +var import_path51 = __toESM(require("path"), 1); var import_fs49 = require("fs"); -var import_path53 = __toESM(require("path"), 1); +var import_path52 = __toESM(require("path"), 1); var import_fs50 = require("fs"); +var import_path53 = __toESM(require("path"), 1); var import_path54 = __toESM(require("path"), 1); +var import_fs51 = require("fs"); +var import_path55 = __toESM(require("path"), 1); +var import_fs52 = require("fs"); +var import_path56 = __toESM(require("path"), 1); +var import_fs53 = require("fs"); +var import_path57 = __toESM(require("path"), 1); var INTAKE_STATUSES = [ /** The source specification is ingested; discovery has not run. */ "INGESTED", @@ -86616,11 +88593,11 @@ function missionDepsOf(deps) { host: deps.host }; } -function now3(deps) { +function now5(deps) { return (deps.clock ?? (() => /* @__PURE__ */ new Date()))(); } -function nowIso2(deps) { - return now3(deps).toISOString(); +function nowIso3(deps) { + return now5(deps).toISOString(); } function hostOf(deps) { return deps.host ?? "cli"; @@ -87039,10 +89016,10 @@ var intakeTelemetrySchema = external_exports.object({ jobId: shortText19.optional(), sealId: shortText19.optional() }).passthrough(); -var ID_PATTERN4 = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/; +var ID_PATTERN5 = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/; var INTAKE_DIR_NAME = "intake"; function assertIntakeId(id) { - if (!ID_PATTERN4.test(id)) { + if (!ID_PATTERN5.test(id)) { throw new IntakeError("SBI005", `Invalid spec intake id "${id}".`, { remediation: ["Ids are generated by SpecBridge; pass one returned by an intake operation."], details: { id } @@ -87053,41 +89030,41 @@ function assertIntakeId(id) { function intakeRootDir(workspace) { return assertInsideWorkspace( workspace.rootDir, - import_path48.default.join(workspace.rootDir, ".specbridge", INTAKE_DIR_NAME) + import_path51.default.join(workspace.rootDir, ".specbridge", INTAKE_DIR_NAME) ); } function intakeDir(workspace, intakeId) { assertIntakeId(intakeId); - return assertInsideWorkspace(workspace.rootDir, import_path48.default.join(intakeRootDir(workspace), intakeId)); + return assertInsideWorkspace(workspace.rootDir, import_path51.default.join(intakeRootDir(workspace), intakeId)); } function intakePath(workspace, intakeId, ...segments) { return assertInsideWorkspace( workspace.rootDir, - import_path48.default.join(intakeDir(workspace, intakeId), ...segments) + import_path51.default.join(intakeDir(workspace, intakeId), ...segments) ); } function writeJson(file, value) { - (0, import_fs45.mkdirSync)(import_path48.default.dirname(file), { recursive: true }); + (0, import_fs48.mkdirSync)(import_path51.default.dirname(file), { recursive: true }); writeFileAtomic(file, `${JSON.stringify(value, null, 2)} `); } function readJson2(file, parse3) { - if (!(0, import_fs45.existsSync)(file)) return void 0; + if (!(0, import_fs48.existsSync)(file)) return void 0; try { - return parse3(JSON.parse((0, import_fs45.readFileSync)(file, "utf8"))); + return parse3(JSON.parse((0, import_fs48.readFileSync)(file, "utf8"))); } catch { return void 0; } } function appendJsonl2(file, value) { - (0, import_fs45.mkdirSync)(import_path48.default.dirname(file), { recursive: true }); - (0, import_fs45.appendFileSync)(file, `${JSON.stringify(value)} + (0, import_fs48.mkdirSync)(import_path51.default.dirname(file), { recursive: true }); + (0, import_fs48.appendFileSync)(file, `${JSON.stringify(value)} `, "utf8"); } function readFolded(file, key, parse3) { - if (!(0, import_fs45.existsSync)(file)) return []; + if (!(0, import_fs48.existsSync)(file)) return []; const folded = /* @__PURE__ */ new Map(); - for (const line of (0, import_fs45.readFileSync)(file, "utf8").split("\n")) { + for (const line of (0, import_fs48.readFileSync)(file, "utf8").split("\n")) { if (line.trim().length === 0) continue; try { const value = parse3(JSON.parse(line)); @@ -87120,16 +89097,16 @@ function writeIntakeState(workspace, state) { } function listIntakes(workspace) { const root = intakeRootDir(workspace); - if (!(0, import_fs45.existsSync)(root)) return { intakes: [], diagnostics: [] }; + if (!(0, import_fs48.existsSync)(root)) return { intakes: [], diagnostics: [] }; const intakes = []; const diagnostics = []; - for (const entry of (0, import_fs45.readdirSync)(root, { withFileTypes: true })) { + for (const entry of (0, import_fs48.readdirSync)(root, { withFileTypes: true })) { if (!entry.isDirectory()) continue; - if (!ID_PATTERN4.test(entry.name)) continue; - const file = import_path48.default.join(root, entry.name, "intake.json"); - if (!(0, import_fs45.existsSync)(file)) continue; + if (!ID_PATTERN5.test(entry.name)) continue; + const file = import_path51.default.join(root, entry.name, "intake.json"); + if (!(0, import_fs48.existsSync)(file)) continue; try { - intakes.push(specIntakeStateSchema.parse(JSON.parse((0, import_fs45.readFileSync)(file, "utf8")))); + intakes.push(specIntakeStateSchema.parse(JSON.parse((0, import_fs48.readFileSync)(file, "utf8")))); } catch (cause) { diagnostics.push({ intakeId: entry.name, @@ -87159,8 +89136,8 @@ function sourceFile(workspace, intakeId, contentHash) { } function storeSourceText(workspace, intakeId, contentHash, content) { const file = sourceFile(workspace, intakeId, contentHash); - if (!(0, import_fs45.existsSync)(file)) { - (0, import_fs45.mkdirSync)(import_path48.default.dirname(file), { recursive: true }); + if (!(0, import_fs48.existsSync)(file)) { + (0, import_fs48.mkdirSync)(import_path51.default.dirname(file), { recursive: true }); writeFileAtomic(file, content); } return file; @@ -87252,7 +89229,7 @@ function appendIntakeEvent(workspace, intakeId, event) { function baselineFile(workspace) { return assertInsideWorkspace( workspace.rootDir, - import_path48.default.join(intakeRootDir(workspace), "baseline.json") + import_path51.default.join(intakeRootDir(workspace), "baseline.json") ); } function readProductBaseline(workspace) { @@ -87862,7 +89839,7 @@ var BUILD_MARKERS = [ ]; function detectBuildSystem(rootDir) { for (const marker of BUILD_MARKERS) { - if ((0, import_fs46.existsSync)(import_path49.default.join(rootDir, marker.file))) return marker.system; + if ((0, import_fs49.existsSync)(import_path52.default.join(rootDir, marker.file))) return marker.system; } return null; } @@ -87899,33 +89876,33 @@ var PUBLIC_INTERFACE_PATTERNS = [ var TEST_DIR_PATTERN = /^(tests?|spec|specs|__tests__|it|integration-tests?|e2e)$/i; function readGitHead(rootDir) { try { - const dotGit = import_path49.default.join(rootDir, ".git"); - if (!(0, import_fs46.existsSync)(dotGit)) return null; + const dotGit = import_path52.default.join(rootDir, ".git"); + if (!(0, import_fs49.existsSync)(dotGit)) return null; let gitDir = dotGit; - if ((0, import_fs46.statSync)(dotGit).isFile()) { - const pointer = (0, import_fs46.readFileSync)(dotGit, "utf8").trim(); + if ((0, import_fs49.statSync)(dotGit).isFile()) { + const pointer = (0, import_fs49.readFileSync)(dotGit, "utf8").trim(); const match = /^gitdir:\s*(.+)$/.exec(pointer); if (match === null) return null; const target = match[1] ?? ""; - gitDir = import_path49.default.isAbsolute(target) ? target : import_path49.default.resolve(rootDir, target); + gitDir = import_path52.default.isAbsolute(target) ? target : import_path52.default.resolve(rootDir, target); } - const headFile = import_path49.default.join(gitDir, "HEAD"); - if (!(0, import_fs46.existsSync)(headFile)) return null; - const head = (0, import_fs46.readFileSync)(headFile, "utf8").trim(); + const headFile = import_path52.default.join(gitDir, "HEAD"); + if (!(0, import_fs49.existsSync)(headFile)) return null; + const head = (0, import_fs49.readFileSync)(headFile, "utf8").trim(); if (/^[0-9a-f]{40}$/i.test(head)) return head.toLowerCase(); const refMatch = /^ref:\s*(.+)$/.exec(head); if (refMatch === null) return null; const ref = (refMatch[1] ?? "").trim(); for (const dir of refDirsFor(gitDir)) { - const refFile = import_path49.default.join(dir, ...ref.split("/")); - if (!(0, import_fs46.existsSync)(refFile)) continue; - const sha = (0, import_fs46.readFileSync)(refFile, "utf8").trim(); + const refFile = import_path52.default.join(dir, ...ref.split("/")); + if (!(0, import_fs49.existsSync)(refFile)) continue; + const sha = (0, import_fs49.readFileSync)(refFile, "utf8").trim(); if (/^[0-9a-f]{40}$/i.test(sha)) return sha.toLowerCase(); } for (const dir of refDirsFor(gitDir)) { - const packed = import_path49.default.join(dir, "packed-refs"); - if (!(0, import_fs46.existsSync)(packed)) continue; - for (const line of (0, import_fs46.readFileSync)(packed, "utf8").split("\n")) { + const packed = import_path52.default.join(dir, "packed-refs"); + if (!(0, import_fs49.existsSync)(packed)) continue; + for (const line of (0, import_fs49.readFileSync)(packed, "utf8").split("\n")) { const entry = /^([0-9a-f]{40})\s+(.+)$/.exec(line.trim()); if (entry !== null && entry[2] === ref) return (entry[1] ?? "").toLowerCase(); } @@ -87937,12 +89914,12 @@ function readGitHead(rootDir) { } function refDirsFor(gitDir) { const dirs = [gitDir]; - const commonFile = import_path49.default.join(gitDir, "commondir"); - if ((0, import_fs46.existsSync)(commonFile)) { + const commonFile = import_path52.default.join(gitDir, "commondir"); + if ((0, import_fs49.existsSync)(commonFile)) { try { - const target = (0, import_fs46.readFileSync)(commonFile, "utf8").trim(); + const target = (0, import_fs49.readFileSync)(commonFile, "utf8").trim(); if (target.length > 0) { - dirs.push(import_path49.default.isAbsolute(target) ? target : import_path49.default.resolve(gitDir, target)); + dirs.push(import_path52.default.isAbsolute(target) ? target : import_path52.default.resolve(gitDir, target)); } } catch { } @@ -87994,7 +89971,7 @@ function groundInRepository(deps, request) { summary: `existing Kiro spec with ${folder.files.length} document(s)`, authoritative: false, topics: [], - path: import_path49.default.posix.join(".kiro", "specs", folder.name) + path: import_path52.default.posix.join(".kiro", "specs", folder.name) }); } for (const steering of safeSteering(workspace, notes)) { @@ -88005,7 +89982,7 @@ function groundInRepository(deps, request) { summary: `steering document (${steering.inclusion})`, authoritative: false, topics: [], - path: import_path49.default.posix.join(".kiro", "steering", steering.fileName) + path: import_path52.default.posix.join(".kiro", "steering", steering.fileName) }); } const buildSystem = detectBuildSystem(workspace.rootDir); @@ -88049,7 +90026,7 @@ function groundInRepository(deps, request) { }); } for (const container of modules.slice(0, 40)) { - const dir = import_path49.default.join(workspace.rootDir, container); + const dir = import_path52.default.join(workspace.rootDir, container); for (const entry of safeReaddir(dir, notes)) { if (!entry.isDirectory()) continue; if (MODULE_DENYLIST.has(entry.name) || entry.name.startsWith(".")) continue; @@ -88099,7 +90076,7 @@ function groundInRepository(deps, request) { return { schemaVersion: INTAKE_GROUNDING_SCHEMA_VERSION, intakeId: request.intakeId, - groundedAt: nowIso2(deps), + groundedAt: nowIso3(deps), baselineCommit: readGitHead(workspace.rootDir), existingProduct, evidence: evidence.slice(0, INTAKE_LIMITS.maxEvidence), @@ -88201,7 +90178,7 @@ function safeSteering(workspace, notes) { } function safeReaddir(dir, notes) { try { - return (0, import_fs46.readdirSync)(dir, { withFileTypes: true }); + return (0, import_fs49.readdirSync)(dir, { withFileTypes: true }); } catch (cause) { notes.push(`Directory ${dir} could not be listed: ${message(cause)}.`); return []; @@ -88303,10 +90280,10 @@ function analyzeDeltaAuthority(request) { ); } for (const cls of AUTHORITY_SENSITIVE_DELTA_CLASSES) { - const count3 = counts[cls] ?? 0; - if (count3 === 0) continue; + const count4 = counts[cls] ?? 0; + if (count4 === 0) continue; reasons.push( - `${count3} statement(s) classified ${cls} and need a product decision before this specification can be approved.` + `${count4} statement(s) classified ${cls} and need a product decision before this specification can be approved.` ); } const complete = items.length > 0 && authoritySensitive.length === 0; @@ -89013,14 +90990,14 @@ function emptyProjectionMap() { function mapFile(workspace, intakeId) { return assertInsideWorkspace( workspace.rootDir, - import_path50.default.join(workspace.rootDir, ".specbridge", "intake", intakeId, "mission-map.json") + import_path53.default.join(workspace.rootDir, ".specbridge", "intake", intakeId, "mission-map.json") ); } function readProjectionMap(workspace, intakeId) { const file = mapFile(workspace, intakeId); - if (!(0, import_fs47.existsSync)(file)) return emptyProjectionMap(); + if (!(0, import_fs50.existsSync)(file)) return emptyProjectionMap(); try { - const raw = JSON.parse((0, import_fs47.readFileSync)(file, "utf8")); + const raw = JSON.parse((0, import_fs50.readFileSync)(file, "utf8")); return { itemContracts: raw.itemContracts ?? {}, itemDecisions: raw.itemDecisions ?? {}, @@ -89035,7 +91012,7 @@ function readProjectionMap(workspace, intakeId) { } function writeProjectionMap(workspace, intakeId, map) { const file = mapFile(workspace, intakeId); - (0, import_fs47.mkdirSync)(import_path50.default.dirname(file), { recursive: true }); + (0, import_fs50.mkdirSync)(import_path53.default.dirname(file), { recursive: true }); writeFileAtomic(file, `${JSON.stringify(map, null, 2)} `); } @@ -89585,7 +91562,7 @@ function startSpecIntake(deps, request) { const contentHash = sha256Hex(content); const storedPath = storeSourceText(deps.workspace, intakeId, contentHash, content); const parsed = parseSpecificationDocument(content); - const at = nowIso2(deps); + const at = nowIso3(deps); const goal = request.goal?.trim() ?? deriveGoal(parsed.chunks, name); const mission = beginMission(missionDepsOf(deps), { name, goal }); const source = writeSpecSource(deps.workspace, { @@ -89597,7 +91574,7 @@ function startSpecIntake(deps, request) { receivedVia: hostOf(deps), byteLength, contentHash, - storedAt: import_path51.default.posix.join( + storedAt: import_path54.default.posix.join( ".specbridge", "intake", intakeId, @@ -89658,7 +91635,7 @@ function runIntakeDiscovery(deps, intakeId, options = {}) { throw new IntakeError("SBI004", `Spec intake ${intakeId} is ABANDONED and read-only.`); } const source = requireSpecSource(deps.workspace, intakeId); - const at = nowIso2(deps); + const at = nowIso3(deps); const grounding = writeGrounding( deps.workspace, groundInRepository(deps, { @@ -89902,7 +91879,7 @@ function answerIntakeQuestion(deps, intakeId, request, options = {}) { `Question ${request.questionId} was never mirrored into the mission and cannot record a governed answer.` ); } - const at = nowIso2(deps); + const at = nowIso3(deps); const result = answerQuestion(missionDepsOf(deps), intake.missionId, { questionId: question.missionQuestionId, answer @@ -90169,7 +92146,7 @@ var repositoryManifestSchema = external_exports.object({ function repositoryManifestFile(workspace) { return assertInsideWorkspace( workspace.rootDir, - import_path52.default.join(workspace.sidecarDir, "repositories.json") + import_path55.default.join(workspace.sidecarDir, "repositories.json") ); } var DETECTION_DENYLIST = /* @__PURE__ */ new Set([ @@ -90186,10 +92163,10 @@ var DETECTION_DENYLIST = /* @__PURE__ */ new Set([ ]); function readRepositoryManifest(workspace) { const file = repositoryManifestFile(workspace); - if (!(0, import_fs48.existsSync)(file)) return void 0; + if (!(0, import_fs51.existsSync)(file)) return void 0; let raw; try { - raw = JSON.parse((0, import_fs48.readFileSync)(file, "utf8")); + raw = JSON.parse((0, import_fs51.readFileSync)(file, "utf8")); } catch (cause) { throw new IntakeError("SBI018", `The repository manifest at ${file} is not valid JSON.`, { remediation: ["Fix or delete .specbridge/repositories.json; without it the workspace root is the repository."], @@ -90209,7 +92186,7 @@ function resolveRepositories(workspace) { } seen.add(entry.id); const absDir = assertInsideWorkspace(workspace.rootDir, entry.path); - if (!(0, import_fs48.existsSync)(absDir) || !(0, import_fs48.statSync)(absDir).isDirectory()) { + if (!(0, import_fs51.existsSync)(absDir) || !(0, import_fs51.statSync)(absDir).isDirectory()) { throw new IntakeError( "SBI018", `The repository manifest names "${entry.id}" at ${entry.path}, which is not a directory.`, @@ -90226,11 +92203,11 @@ function resolveRepositories(workspace) { } const children = []; try { - for (const entry of (0, import_fs48.readdirSync)(workspace.rootDir, { withFileTypes: true })) { + for (const entry of (0, import_fs51.readdirSync)(workspace.rootDir, { withFileTypes: true })) { if (!entry.isDirectory()) continue; if (DETECTION_DENYLIST.has(entry.name) || entry.name.startsWith(".")) continue; - const absDir = import_path52.default.join(workspace.rootDir, entry.name); - if (!(0, import_fs48.existsSync)(import_path52.default.join(absDir, ".git"))) continue; + const absDir = import_path55.default.join(workspace.rootDir, entry.name); + if (!(0, import_fs51.existsSync)(import_path55.default.join(absDir, ".git"))) continue; if (children.length >= BOOTSTRAP_LIMITS.maxRepositories) { notes.push("More child repositories exist than the bootstrap bound; declare a manifest to choose."); break; @@ -90241,7 +92218,7 @@ function resolveRepositories(workspace) { notes.push(`The workspace root could not be listed: ${cause instanceof Error ? cause.message : String(cause)}.`); } if (children.length > 0) { - const rootIsRepo = (0, import_fs48.existsSync)(import_path52.default.join(workspace.rootDir, ".git")); + const rootIsRepo = (0, import_fs51.existsSync)(import_path55.default.join(workspace.rootDir, ".git")); const repositories = rootIsRepo ? [resolved(workspace, rootRepositoryId(workspace), workspace.rootDir, void 0), ...children] : children; return { repositories: repositories.slice(0, BOOTSTRAP_LIMITS.maxRepositories), @@ -90256,18 +92233,18 @@ function resolveRepositories(workspace) { }; } function rootRepositoryId(workspace) { - const base = import_path52.default.basename(workspace.rootDir).replace(/[^A-Za-z0-9._-]/g, "-").replace(/^[^A-Za-z0-9]+/, ""); + const base = import_path55.default.basename(workspace.rootDir).replace(/[^A-Za-z0-9._-]/g, "-").replace(/^[^A-Za-z0-9]+/, ""); return base.length > 0 ? base.slice(0, 64) : "workspace"; } function resolved(workspace, repositoryId, absDir, role) { - const relPath = import_path52.default.relative(workspace.rootDir, absDir).replace(/\\/g, "/"); + const relPath = import_path55.default.relative(workspace.rootDir, absDir).replace(/\\/g, "/"); return { repositoryId, relPath, ...role !== void 0 ? { role } : {}, absDir, gitHead: readGitHead(absDir), - isGitRepository: (0, import_fs48.existsSync)(import_path52.default.join(absDir, ".git")) + isGitRepository: (0, import_fs51.existsSync)(import_path55.default.join(absDir, ".git")) }; } function repositoryOfPath(repositories, workspaceRelativePath) { @@ -90460,7 +92437,7 @@ function synthesizeSystemFindings(input) { }); } const manifestEntries = entries.filter( - (entry) => MANIFEST_BASENAMES.has(import_path53.default.posix.basename(entry.path).toLowerCase()) + (entry) => MANIFEST_BASENAMES.has(import_path56.default.posix.basename(entry.path).toLowerCase()) ); const architectureLabels = /* @__PURE__ */ new Map(); for (const entry of manifestEntries.slice(0, 40)) { @@ -90505,7 +92482,7 @@ function synthesizeSystemFindings(input) { architecture.push({ findingId: ids("arc"), class: "OBSERVED_IMPLEMENTATION", - statement: clip3(`${label} (declared by ${import_path53.default.posix.basename(entry.path)}).`), + statement: clip3(`${label} (declared by ${import_path56.default.posix.basename(entry.path)}).`), evidence: [fileRef(entry)] }); } @@ -90650,7 +92627,7 @@ function synthesizeSystemFindings(input) { findingId: ids("con"), class: "OBSERVED_IMPLEMENTATION", statement: clip3( - `Repository "${repo.repositoryId}" builds with ${import_path53.default.posix.basename(marker.path)}.` + `Repository "${repo.repositoryId}" builds with ${import_path56.default.posix.basename(marker.path)}.` ), evidence: [fileRef(marker)] }); @@ -90722,9 +92699,9 @@ function clip3(value) { } function boundedRead(workspace, relPath) { try { - const abs = import_path53.default.join(workspace.rootDir, relPath); - if (!(0, import_fs49.existsSync)(abs)) return void 0; - const body = (0, import_fs49.readFileSync)(abs, "utf8"); + const abs = import_path56.default.join(workspace.rootDir, relPath); + if (!(0, import_fs52.existsSync)(abs)) return void 0; + const body = (0, import_fs52.readFileSync)(abs, "utf8"); return body.length > MAX_MANIFEST_READ_BYTES ? body.slice(0, MAX_MANIFEST_READ_BYTES) : body; } catch { return void 0; @@ -90765,25 +92742,25 @@ function safeSeals(workspace) { } } function bootstrapDir(workspace) { - return assertInsideWorkspace(workspace.rootDir, import_path54.default.join(workspace.sidecarDir, "bootstrap")); + return assertInsideWorkspace(workspace.rootDir, import_path57.default.join(workspace.sidecarDir, "bootstrap")); } function snapshotFile(workspace) { return assertInsideWorkspace( workspace.rootDir, - import_path54.default.join(bootstrapDir(workspace), "current-system-snapshot.json") + import_path57.default.join(bootstrapDir(workspace), "current-system-snapshot.json") ); } function readCurrentSystemSnapshot(workspace) { const file = snapshotFile(workspace); - if (!(0, import_fs50.existsSync)(file)) return void 0; + if (!(0, import_fs53.existsSync)(file)) return void 0; try { - return currentSystemSnapshotSchema.parse(JSON.parse((0, import_fs50.readFileSync)(file, "utf8"))); + return currentSystemSnapshotSchema.parse(JSON.parse((0, import_fs53.readFileSync)(file, "utf8"))); } catch { return void 0; } } function persistSnapshot(workspace, snapshot2) { - (0, import_fs50.mkdirSync)(bootstrapDir(workspace), { recursive: true }); + (0, import_fs53.mkdirSync)(bootstrapDir(workspace), { recursive: true }); writeFileAtomic(snapshotFile(workspace), `${JSON.stringify(snapshot2, null, 2)} `); } @@ -90831,7 +92808,7 @@ function bootstrapWorkspace(deps, options = {}) { const ensured = ensureRepositoryIndex({ workspace, config: deps.config, - now: nowIso2(deps), + now: nowIso3(deps), // Bootstrap has no Git snapshot to name additions, so the refresh walks // for them: a snapshot that missed a brand-new capability file would // claim currency over a repository it has not actually seen. @@ -90881,12 +92858,12 @@ function bootstrapWorkspace(deps, options = {}) { schemaVersion: BOOTSTRAP_SCHEMA_VERSION, snapshotId: `snap-${contentHash.slice(0, 12)}`, workspaceKey: workspaceKeyFor(workspace.rootDir), - createdAt: nowIso2(deps), + createdAt: nowIso3(deps), ...material, indexStats: { entries: ensured.state.entries.length, truncated: ensured.state.truncated, - skipped: Object.values(ensured.state.skippedCounts).reduce((sum, count3) => sum + count3, 0) + skipped: Object.values(ensured.state.skippedCounts).reduce((sum, count4) => sum + count4, 0) }, contentHash }); @@ -90899,11 +92876,11 @@ function bootstrapWorkspace(deps, options = {}) { }; } function countIndexed(index, repositories, repo) { - let count3 = 0; + let count4 = 0; for (const entry of index.entries) { - if (repositoryOfPath(repositories, entry.path)?.repositoryId === repo.repositoryId) count3 += 1; + if (repositoryOfPath(repositories, entry.path)?.repositoryId === repo.repositoryId) count4 += 1; } - return count3; + return count4; } function readWorkspaceSnapshot(workspace) { const snapshot2 = readCurrentSystemSnapshot(workspace); @@ -90924,7 +92901,7 @@ function inspectWorkspace(deps, options) { const ensured = ensureRepositoryIndex({ workspace, config: deps.config, - now: nowIso2(deps) + now: nowIso3(deps) }); const query = buildRetrievalQuery({ taskId: "workspace-inspect", @@ -90956,7 +92933,7 @@ function inspectWorkspace(deps, options) { } let body; try { - body = (0, import_fs50.readFileSync)( + body = (0, import_fs53.readFileSync)( assertInsideWorkspace(workspace.rootDir, entry.path), "utf8" ); @@ -92039,6 +94016,7 @@ function registerAllTools(server, context) { registerOrchestrationFinalizeTool(server, context); registerJobListTool(server, context); registerJobReadTool(server, context); + registerJobReportTool(server, context); registerJobCancelTool(server, context); registerMissionBeginTool(server, context); registerMissionStatusTool(server, context); diff --git a/packages/autonomy/src/telemetry/execution-report.ts b/packages/autonomy/src/telemetry/execution-report.ts new file mode 100644 index 0000000..f6e372d --- /dev/null +++ b/packages/autonomy/src/telemetry/execution-report.ts @@ -0,0 +1,1745 @@ +import { mkdirSync, readFileSync } from 'node:fs'; +import path from 'node:path'; +import { + assertInsideWorkspace, + autonomyPolicyFingerprint, + sha256Hex, + writeFileAtomic, + type AutonomyPolicy, + type ClosurePolicy, + type WorkspaceInfo, +} from '@specbridge/core'; +import { + listObjectiveNodes, + listResearchRecords, + listResearchUseRecords, + readBuilderRoutingStates, + readEvaluations, + readExecutionLedger, + readJobEvents, + readLatestWorkGraph, + readObjectiveCooldownState, + readResearchTelemetry, + requireJobState, + workedMsOf, + type BuilderRoutingAttempt, + type BuilderRoutingState, + type EvaluationRecord, + type ExecutionLedgerEntry, + type JobEvent, + type JobState, + type ObjectiveCooldownState, + type ResearchRecord, + type ResearchTelemetry, + type ResearchUseRecord, + type WorkGraph, + type WorkUnit, +} from '@specbridge/orchestration'; +import { z } from 'zod'; +import type { AutonomyDeps } from '../deps.js'; +import { nowIso } from '../deps.js'; +import { closureRatio, missionMayComplete, summarizeClosure } from '../closure/oracle.js'; +import type { ClosureLedger } from '../closure/state.js'; +import { readClosureLedger } from '../closure/service.js'; +import type { MissionSeal, SealBinding } from '../seal/state.js'; +import { readJobSeal, readSealBinding } from '../seal/service.js'; +import { + deriveAutonomyTelemetry, + type AutonomyTelemetry, +} from './telemetry.js'; + +/** Stable public-ish contract consumed by CLI, MCP, and Phase 10 qualification. */ +export const EXECUTION_TELEMETRY_REPORT_SCHEMA_VERSION = '1.0.0'; + +const count = z.number().int().min(0); +const shortText = z.string().max(512); +const boundedText = z.string().max(2_000); +const ratio = z.number().min(0).max(1).nullable(); +const countMap = z.record(z.string(), count); + +export const fractionMetricSchema = z.object({ + numerator: count.nullable(), + denominator: count.nullable(), + value: ratio, +}).strict(); +export type FractionMetric = z.infer; + +export const tokenCoverageSchema = z.object({ + attempts: count, + withAny: count, + withInput: count, + withOutput: count, + ratio, + complete: z.boolean(), +}).strict(); + +export const tokenTelemetrySchema = z.object({ + /** Sum of every reported input-token field; null when none reported. */ + inputTokens: count.nullable(), + /** Sum of every reported output-token field; null when none reported. */ + outputTokens: count.nullable(), + /** Sum of known components, even when coverage is partial. */ + knownTokens: count.nullable(), + /** Total only when every attempt reported both components. */ + completeTokens: count.nullable(), + coverage: tokenCoverageSchema, +}).strict(); +export type TokenTelemetry = z.infer; + +const workAccountingSchema = z.enum([ + 'completed', + 'failed', + 'cancelled', + 'waiting', + 'not-ready', + 'human-authority-pending', + 'research-pending', + 'context-pending', +]); + +const diagnosticSchema = z.object({ + code: shortText, + severity: z.enum(['info', 'warning', 'error']), + message: boundedText, + evidenceRefs: z.array(shortText).max(20).default([]), +}).strict(); + +const phaseResearchSchema = z.object({ + considered: count, + avoided: count, + reused: count, + newCalls: count, + quick: count, + deep: count, + failed: count, +}).strict(); + +export const executionTelemetryReportSchema = z.object({ + schemaVersion: z.literal(EXECUTION_TELEMETRY_REPORT_SCHEMA_VERSION), + jobId: shortText, + missionId: shortText.nullable(), + generatedAt: shortText, + period: z.object({ + startedAt: shortText, + endedAt: shortText.nullable(), + durationMs: count.nullable(), + activeExecutionMs: count.nullable(), + }).strict(), + provenance: z.object({ + sourceJobId: shortText, + jobGraphRevision: count, + objectiveGraphRevisions: countMap, + executionLedgerWatermark: z.string().regex(/^[a-f0-9]{64}$/), + eventWatermark: count, + specbridgeVersion: shortText.nullable(), + sealId: shortText.nullable(), + sealedAuthorityDigest: shortText.nullable(), + runtimePolicyChanged: z.boolean().nullable(), + configuration: z.object({ + secondaryBuildStrategy: shortText, + researchStrategy: shortText, + runnerProfiles: z.array(shortText).max(50), + }).strict(), + }).strict(), + outcome: z.object({ + status: z.enum(['COMPLETED', 'FAILED', 'CANCELLED', 'BLOCKED', 'WAITING']), + authoritativeJobStatus: shortText, + finalOutcome: boundedText.nullable(), + verification: z.enum(['PASS', 'FAIL', 'UNAVAILABLE']), + closure: z.enum(['PASS', 'FAIL', 'UNAVAILABLE']), + }).strict(), + work: z.object({ + total: count, + byKind: countMap, + accounting: z.record(workAccountingSchema, count), + completedImplementation: count, + objectives: z.array(z.object({ + objectiveNodeId: shortText, + graphRevision: count.nullable(), + total: count, + accounting: z.record(workAccountingSchema, count), + implementationAttempts: count, + secondaryAttempts: count, + strongBuilderAttempts: count, + }).strict()).max(200), + units: z.array(z.object({ + workUnitId: shortText, + objectiveNodeId: shortText, + kind: shortText, + status: shortText, + accounting: workAccountingSchema, + builderPath: z.enum(['SECONDARY', 'SECONDARY_REPAIR', 'STRONG', 'STRONG_FALLBACK', 'NONE', 'UNKNOWN']), + implementationAttempts: count, + verification: z.enum(['PASS', 'FAIL', 'PENDING', 'UNAVAILABLE']), + integration: z.enum(['INTEGRATED', 'NOT_INTEGRATED']), + }).strict()).max(500), + omittedUnits: count, + }).strict(), + secondary: z.object({ + eligibility: z.object({ + eligible: count, + ineligible: count, + strongRequired: count, + needsResearch: count, + needsAuthority: count, + needsContext: count, + notReady: count, + unavailable: count, + }).strict(), + selection: z.object({ + secondarySelected: count, + strongSelectedDespiteEligibility: count, + noBuilderNeeded: count, + waitingForResource: count, + }).strict(), + funnel: z.object({ + initialAttempts: count, + initialPass: count, + repairAttempted: count, + repairPass: count, + toStrongFallback: count, + unavailableFallback: count, + }).strict(), + initialSuccessRate: fractionMetricSchema, + repairRecoveryRate: fractionMetricSchema, + toStrongFallbackRate: fractionMetricSchema, + fallbackReasons: countMap, + builderTokens: tokenTelemetrySchema, + }).strict(), + strong: z.object({ + builderAttempts: count, + evaluatorAttempts: count, + selection: z.object({ + requiredDirect: count, + byStrategyOff: count, + byAutoPolicy: count, + becauseSecondaryUnavailable: count, + fallbackAfterSecondary: count, + }).strict(), + implementationTokens: tokenTelemetrySchema, + evaluatorTokens: tokenTelemetrySchema, + }).strict(), + research: z.object({ + scope: z.enum(['JOB', 'WORKSPACE', 'NONE']), + considered: count.nullable(), + decisions: countMap, + providerCalls: count, + successful: count, + inconclusive: count, + failed: count, + priorResearchReused: count, + newQuick: count, + newDeep: count, + avoidanceRatio: fractionMetricSchema, + reuseRate: fractionMetricSchema, + byPhase: z.record(z.string(), phaseResearchSchema), + usage: z.object({ + inputTokens: count.nullable(), + outputTokens: count.nullable(), + durationMs: count.nullable(), + providerReportedCost: z.number().min(0).nullable(), + subagentCount: count.nullable(), + recordsWithUsage: count, + providerCalls: count, + coverage: ratio, + }).strict(), + }).strict(), + cooldown: z.object({ + episodes: count, + observations: count, + totalDurationMs: count.nullable(), + usefulWorkDuringSubscriptionCooldown: count, + secondaryImplementationWorkDuringCooldown: count, + researchWorkDuringCooldown: count, + strongRequiredWaiting: count, + avoidableIdlePeriods: count, + intervals: z.array(z.object({ + objectiveNodeId: shortText, + status: z.enum(['ACTIVE', 'RECOVERED']), + startedAt: shortText, + endedAt: shortText.nullable(), + durationMs: count.nullable(), + completedWorkUnits: count, + }).strict()).max(200), + timeline: z.array(z.object({ + at: shortText, + type: shortText, + objectiveNodeId: shortText.nullable(), + detail: boundedText, + }).strict()).max(200), + }).strict(), + attempts: z.object({ + uniqueImplementationAttempts: count, + meanPerCompletedWorkUnit: z.number().min(0).nullable(), + medianPerCompletedWorkUnit: z.number().min(0).nullable(), + maxPerWorkUnit: count, + workUnitsWithMultipleAttempts: count, + byKind: countMap, + completedWorkUnitsPerImplementationAttempt: z.number().min(0).nullable(), + completedWorkUnitsPerStrongBuilderCall: z.number().min(0).nullable(), + completedEligibleWorkUnitsPerSecondaryAttempt: z.number().min(0).nullable(), + }).strict(), + verification: z.object({ + attempts: count, + passes: count, + failures: count, + otherVerdicts: count, + failuresByBuilderBackend: countMap, + failuresRecoveredByRepair: count, + failuresRecoveredByStrongFallback: count, + }).strict(), + closure: z.object({ + available: z.boolean(), + items: count, + earned: count, + waived: count, + unresolved: count, + completionGateOutcome: z.enum(['PASS', 'FAIL', 'UNAVAILABLE']), + ratio, + }).strict(), + human: z.object({ + decisionsBeforeSeal: count.nullable(), + approvals: count, + authorityEscalationsAfterSeal: count.nullable(), + interventionsAfterSeal: count, + unexpectedBlockersAfterSeal: count, + zeroTouchAfterSeal: z.boolean(), + byKind: countMap, + }).strict(), + reliability: z.object({ + failureSources: countMap, + recoveryActions: countMap, + noProgressDetections: count, + repeatedProblemFingerprints: count, + legitimateResourceWaitsExcluded: count, + processRestarts: count, + supervisorRestarts: count, + candidatesPersisted: count, + candidatesReusedAfterRestart: count, + candidateRebuildsAfterRestart: count, + candidatesLostOrUnreadable: count, + candidateReadyResumes: count, + integrationRetries: count, + completedWorkRedoCount: count, + completedWorkReusedAfterRestart: count, + attemptsIncorrectlyRepeated: count, + unexpectedBlocks: count, + unrecoveredDriverDeaths: count, + }).strict(), + efficiency: z.object({ + strongBuilderAvoidanceRatio: fractionMetricSchema, + strongBuilderCallsAvoided: count, + completedWorkUnitsPerImplementationAttempt: z.number().min(0).nullable(), + baseline: z.object({ + kind: z.enum(['OBSERVED', 'QUALIFICATION_FIXTURE']), + reportId: shortText, + strongBuilderAttempts: count, + sameVerificationOutcome: z.boolean(), + sameClosureOutcome: z.boolean(), + }).strict().nullable(), + }).strict(), + qualificationSummary: z.object({ + strongBuilderAvoidanceRatio: ratio, + secondaryInitialSuccessRate: ratio, + secondaryRepairRecoveryRate: ratio, + secondaryToStrongFallback: count, + strongImplementationTokens: count.nullable(), + researchAvoidanceRatio: ratio, + newResearchCalls: count, + researchReuse: count, + usefulWorkDuringSubscriptionCooldown: count, + humanInterventionsAfterSeal: count, + completedWorkRedoCount: count, + unexpectedBlocks: count, + unrecoveredDriverDeaths: count, + }).strict(), + diagnostics: z.array(diagnosticSchema).max(200), +}).strict(); + +export type ExecutionTelemetryReport = z.infer; + +export interface ObjectiveTelemetryFacts { + objectiveNodeId: string; + graph?: WorkGraph | undefined; + routingStates: readonly BuilderRoutingState[]; + cooldown?: ObjectiveCooldownState | undefined; + evaluations: readonly EvaluationRecord[]; +} + +/** + * Normalized durable inputs. The derivation below is pure: callers can load + * these facts from disk, an archive, or a future query store without changing + * metric semantics. + */ +export interface ExecutionTelemetryFacts { + job: JobState; + events: readonly JobEvent[]; + eventTotal: number; + ledger: readonly ExecutionLedgerEntry[]; + objectives: readonly ObjectiveTelemetryFacts[]; + researchTelemetry?: ResearchTelemetry | undefined; + researchTelemetryDiagnostic?: string | undefined; + researchRecords: readonly ResearchRecord[]; + researchRecordDiagnostics?: readonly { code: string; message: string }[] | undefined; + researchUses: readonly ResearchUseRecord[]; + autonomy: AutonomyTelemetry; + closure?: ClosureLedger | undefined; + binding?: SealBinding | undefined; + seal?: MissionSeal | undefined; + generatedAt: string; + specbridgeVersion?: string | undefined; + secondaryBuildStrategy: string; + researchStrategy: string; + runnerProfiles: readonly string[]; + currentAutonomyPolicy: AutonomyPolicy; + closurePolicy: ClosurePolicy; + baseline?: { + kind: 'OBSERVED' | 'QUALIFICATION_FIXTURE'; + reportId: string; + strongBuilderAttempts: number; + verificationOutcome: 'PASS' | 'FAIL' | 'UNAVAILABLE'; + closureOutcome: 'PASS' | 'FAIL' | 'UNAVAILABLE'; + } | undefined; +} + +export interface ComputeExecutionTelemetryOptions { + persist?: boolean | undefined; + specbridgeVersion?: string | undefined; +} + +const SECRET_PATTERNS: readonly RegExp[] = [ + /-----BEGIN (?:RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----/gi, + /\b(?:bearer|basic)\s+[A-Za-z0-9+/=_-]{12,}/gi, + /\b(?:sk|ghp|github_pat|xox[baprs])[_-][A-Za-z0-9_-]{12,}\b/gi, + /\b(?:api[-_ ]?key|auth[-_ ]?token|access[-_ ]?token|password|secret)\s*[:=]\s*\S{8,}/gi, +]; + +/** Redact bounded diagnostic text before it can enter a high-level report. */ +export function redactTelemetryText(value: string): string { + let redacted = value; + for (const pattern of SECRET_PATTERNS) redacted = redacted.replace(pattern, '[REDACTED]'); + return redacted.slice(0, 2_000); +} + +function increment(record: Record, key: string, by = 1): void { + record[key] = (record[key] ?? 0) + by; +} + +function metric(numerator: number | null, denominator: number | null): FractionMetric { + return { + numerator, + denominator, + value: + numerator === null || denominator === null || denominator === 0 + ? null + : numerator / denominator, + }; +} + +function tokenTelemetry( + attempts: readonly T[], + usage: (attempt: T) => { input: number | null | undefined; output: number | null | undefined }, +): TokenTelemetry { + let input = 0; + let output = 0; + let withInput = 0; + let withOutput = 0; + let withAny = 0; + for (const attempt of attempts) { + const reported = usage(attempt); + const hasInput = reported.input !== null && reported.input !== undefined; + const hasOutput = reported.output !== null && reported.output !== undefined; + if (hasInput) { + input += reported.input ?? 0; + withInput += 1; + } + if (hasOutput) { + output += reported.output ?? 0; + withOutput += 1; + } + if (hasInput || hasOutput) withAny += 1; + } + const attemptCount = attempts.length; + const complete = attemptCount > 0 && withInput === attemptCount && withOutput === attemptCount; + return { + inputTokens: withInput > 0 ? input : null, + outputTokens: withOutput > 0 ? output : null, + knownTokens: withAny > 0 ? input + output : null, + completeTokens: complete ? input + output : null, + coverage: { + attempts: attemptCount, + withAny, + withInput, + withOutput, + ratio: attemptCount === 0 ? null : withAny / attemptCount, + complete, + }, + }; +} + +function timestampMs(value: string | null | undefined): number | undefined { + if (value === null || value === undefined) return undefined; + const parsed = Date.parse(value); + return Number.isFinite(parsed) ? parsed : undefined; +} + +function outcomeStatus(status: string): ExecutionTelemetryReport['outcome']['status'] { + if (status === 'COMPLETED') return 'COMPLETED'; + if (status === 'FAILED') return 'FAILED'; + if (status === 'CANCELLED') return 'CANCELLED'; + if (status === 'BLOCKED' || status === 'NEEDS_AUTHORITY' || status === 'NEEDS_CLARIFICATION') { + return 'BLOCKED'; + } + return 'WAITING'; +} + +function verificationOutcome(job: JobState, events: readonly JobEvent[]): 'PASS' | 'FAIL' | 'UNAVAILABLE' { + const status = job.latestEvidence?.evidenceStatus; + if (status === 'verified' || status === 'manually-accepted') return 'PASS'; + const lastFailure = [...events].reverse().find((event) => event.type === 'verification_failed'); + if (lastFailure !== undefined && job.latestEvidence === undefined) return 'FAIL'; + return 'UNAVAILABLE'; +} + +function currentRoutingStates(objectives: readonly ObjectiveTelemetryFacts[]): Map { + const current = new Map(); + for (const objective of objectives) { + for (const state of objective.routingStates) { + const key = `${objective.objectiveNodeId}\u0000${state.workUnitId}`; + const prior = current.get(key); + if ( + prior === undefined + || state.updatedAt.localeCompare(prior.updatedAt, 'en') > 0 + || (state.updatedAt === prior.updatedAt && state.contentHash.localeCompare(prior.contentHash, 'en') > 0) + ) { + current.set(key, state); + } + } + } + return current; +} + +interface UniqueBuilderAttempt extends BuilderRoutingAttempt { + objectiveNodeId: string; + workUnitId: string; +} + +function uniqueBuilderAttempts(objectives: readonly ObjectiveTelemetryFacts[]): { + attempts: UniqueBuilderAttempt[]; + duplicateIds: number; +} { + const seen = new Map(); + let duplicateIds = 0; + for (const objective of objectives) { + for (const state of objective.routingStates) { + for (const attempt of state.attempts) { + const key = `${objective.objectiveNodeId}\u0000${state.workUnitId}\u0000${attempt.attemptId}`; + if (seen.has(key)) { + duplicateIds += 1; + continue; + } + seen.set(key, { ...attempt, objectiveNodeId: objective.objectiveNodeId, workUnitId: state.workUnitId }); + } + } + } + return { + attempts: [...seen.values()].sort( + (left, right) => + left.startedAt.localeCompare(right.startedAt, 'en') + || left.objectiveNodeId.localeCompare(right.objectiveNodeId, 'en') + || left.workUnitId.localeCompare(right.workUnitId, 'en') + || left.sequence - right.sequence, + ), + duplicateIds, + }; +} + +function latestUnits(objectives: readonly ObjectiveTelemetryFacts[]): Array<{ + objectiveNodeId: string; + unit: WorkUnit; +}> { + const units: Array<{ objectiveNodeId: string; unit: WorkUnit }> = []; + for (const objective of objectives) { + for (const unit of objective.graph?.units ?? []) { + units.push({ objectiveNodeId: objective.objectiveNodeId, unit }); + } + } + return units.sort( + (left, right) => + left.objectiveNodeId.localeCompare(right.objectiveNodeId, 'en') + || left.unit.workUnitId.localeCompare(right.unit.workUnitId, 'en'), + ); +} + +function workAccounting( + unit: WorkUnit, + routing: BuilderRoutingState | undefined, +): z.infer { + if (unit.status === 'INTEGRATED') return 'completed'; + if (unit.status === 'FAILED') return 'failed'; + if (unit.status === 'SUPERSEDED') return 'cancelled'; + const eligibility = routing?.initialEligibility; + if (eligibility === 'NEEDS_AUTHORITY') return 'human-authority-pending'; + if (eligibility === 'NEEDS_RESEARCH') return 'research-pending'; + if (eligibility === 'NEEDS_CONTEXT') return 'context-pending'; + if (eligibility === 'NOT_READY' || unit.status === 'PLANNED') return 'not-ready'; + return 'waiting'; +} + +function builderPath(attempts: readonly UniqueBuilderAttempt[]): ExecutionTelemetryReport['work']['units'][number]['builderPath'] { + if (attempts.some((attempt) => attempt.kind === 'STRONG_FALLBACK')) return 'STRONG_FALLBACK'; + if (attempts.some((attempt) => attempt.kind === 'STRONG')) return 'STRONG'; + if (attempts.some((attempt) => attempt.kind === 'SECONDARY_REPAIR')) return 'SECONDARY_REPAIR'; + if (attempts.some((attempt) => attempt.kind === 'SECONDARY')) return 'SECONDARY'; + return attempts.length === 0 ? 'NONE' : 'UNKNOWN'; +} + +function verificationFor( + evaluations: readonly EvaluationRecord[], +): ExecutionTelemetryReport['work']['units'][number]['verification'] { + if (evaluations.some((entry) => entry.verdict === 'FAIL')) return 'FAIL'; + if (evaluations.some((entry) => entry.verdict === 'PASS')) return 'PASS'; + if (evaluations.length > 0) return 'PENDING'; + return 'UNAVAILABLE'; +} + +function fallbackReason(attempts: readonly UniqueBuilderAttempt[]): string { + const preceding = [...attempts] + .reverse() + .find((attempt) => attempt.kind === 'SECONDARY' || attempt.kind === 'SECONDARY_REPAIR'); + if (preceding === undefined) return 'other'; + if (preceding.noProgress) return 'no-progress'; + switch (preceding.outcome) { + case 'FAILED_VERIFICATION': return 'verification-failure'; + case 'FAILED_OUTPUT': return 'malformed-model-result'; + case 'FAILED_RESOURCE': return 'capability-failure'; + case 'FAILED_IMPLEMENTATION': + return /context|stale source|insufficient/i.test(preceding.failureSummary ?? '') + ? 'context-insufficiency' + : 'implementation-failure'; + default: return 'other'; + } +} + +function median(values: readonly number[]): number | null { + if (values.length === 0) return null; + const sorted = [...values].sort((left, right) => left - right); + const middle = Math.floor(sorted.length / 2); + if (sorted.length % 2 === 1) return sorted[middle] ?? null; + return ((sorted[middle - 1] ?? 0) + (sorted[middle] ?? 0)) / 2; +} + +/** Pure derivation from durable facts. No counter is incremented or persisted. */ +export function deriveExecutionTelemetryReport( + facts: ExecutionTelemetryFacts, +): ExecutionTelemetryReport { + const diagnostics: ExecutionTelemetryReport['diagnostics'] = []; + const generatedMs = timestampMs(facts.generatedAt) ?? 0; + const eventTypes = (type: string): JobEvent[] => facts.events.filter((event) => event.type === type); + const currentRouting = currentRoutingStates(facts.objectives); + const { attempts: implementationAttempts, duplicateIds } = uniqueBuilderAttempts(facts.objectives); + const units = latestUnits(facts.objectives); + const evaluations = facts.objectives + .flatMap((objective) => objective.evaluations) + .filter((entry, index, values) => values.findIndex((other) => other.evaluationId === entry.evaluationId) === index) + .sort((left, right) => left.createdAt.localeCompare(right.createdAt, 'en')); + + if (facts.eventTotal > facts.events.length) { + diagnostics.push({ + code: 'EVENT_WINDOW_BOUNDED', + severity: 'info', + message: `The report used the newest ${facts.events.length} of ${facts.eventTotal} job events; ledgers and current state remain authoritative for aggregates.`, + evidenceRefs: [], + }); + } + if (facts.objectives.length === 0) { + diagnostics.push({ + code: 'OBJECTIVE_TELEMETRY_UNAVAILABLE', + severity: 'info', + message: 'No objective-runtime records exist; Phase 7/8 metrics are unavailable for this older or direct-execution job.', + evidenceRefs: [], + }); + } + if (facts.autonomy.boundaryStartedAt === null) { + diagnostics.push({ + code: 'ZERO_TOUCH_BOUNDARY_UNAVAILABLE', + severity: 'info', + message: 'No durable seal boundary exists; intervention counting conservatively includes the whole recorded Job history.', + evidenceRefs: [], + }); + } + if (duplicateIds > 0) { + diagnostics.push({ + code: 'ATTEMPT_REPLAY_DEDUPLICATED', + severity: 'info', + message: `${duplicateIds} replayed builder-attempt record${duplicateIds === 1 ? '' : 's'} were ignored by durable attempt id.`, + evidenceRefs: [], + }); + } + if (facts.researchTelemetryDiagnostic !== undefined) { + diagnostics.push({ + code: 'RESEARCH_TELEMETRY_UNREADABLE', + severity: 'warning', + message: redactTelemetryText(facts.researchTelemetryDiagnostic), + evidenceRefs: [], + }); + } + for (const diagnostic of facts.researchRecordDiagnostics ?? []) { + diagnostics.push({ + code: diagnostic.code.slice(0, 512), + severity: 'warning', + message: redactTelemetryText(diagnostic.message), + evidenceRefs: [], + }); + } + + const attemptsByUnit = new Map(); + for (const attempt of implementationAttempts) { + const key = `${attempt.objectiveNodeId}\u0000${attempt.workUnitId}`; + const list = attemptsByUnit.get(key) ?? []; + list.push(attempt); + attemptsByUnit.set(key, list); + } + const evaluationsByUnit = new Map(); + for (const evaluation of evaluations) { + const key = `${evaluation.objectiveNodeId}\u0000${evaluation.workUnitId}`; + const list = evaluationsByUnit.get(key) ?? []; + list.push(evaluation); + evaluationsByUnit.set(key, list); + } + + const workAccountingCounts: Record, number> = { + completed: 0, + failed: 0, + cancelled: 0, + waiting: 0, + 'not-ready': 0, + 'human-authority-pending': 0, + 'research-pending': 0, + 'context-pending': 0, + }; + const workByKind: Record = {}; + const unitSummaries: ExecutionTelemetryReport['work']['units'] = []; + for (const entry of units) { + const key = `${entry.objectiveNodeId}\u0000${entry.unit.workUnitId}`; + const routing = currentRouting.get(key); + const unitAttempts = attemptsByUnit.get(key) ?? []; + const unitEvaluations = evaluationsByUnit.get(key) ?? []; + const accounting = workAccounting(entry.unit, routing); + workAccountingCounts[accounting] += 1; + increment(workByKind, entry.unit.kind); + if (unitSummaries.length < 500) { + unitSummaries.push({ + workUnitId: entry.unit.workUnitId, + objectiveNodeId: entry.objectiveNodeId, + kind: entry.unit.kind, + status: entry.unit.status, + accounting, + builderPath: builderPath(unitAttempts), + implementationAttempts: unitAttempts.length, + verification: verificationFor(unitEvaluations), + integration: entry.unit.status === 'INTEGRATED' ? 'INTEGRATED' : 'NOT_INTEGRATED', + }); + } + } + + const eligibility = { + eligible: 0, + ineligible: 0, + strongRequired: 0, + needsResearch: 0, + needsAuthority: 0, + needsContext: 0, + notReady: 0, + unavailable: units.filter((entry) => + entry.unit.kind === 'build' + && !currentRouting.has(`${entry.objectiveNodeId}\u0000${entry.unit.workUnitId}`)).length, + }; + const selection = { + secondarySelected: 0, + strongSelectedDespiteEligibility: 0, + noBuilderNeeded: 0, + waitingForResource: 0, + }; + const strongSelection = { + requiredDirect: 0, + byStrategyOff: 0, + byAutoPolicy: 0, + becauseSecondaryUnavailable: 0, + fallbackAfterSecondary: 0, + }; + const fallbackReasons: Record = {}; + + for (const entry of units) { + if (entry.unit.kind !== 'build') { + selection.noBuilderNeeded += 1; + continue; + } + const key = `${entry.objectiveNodeId}\u0000${entry.unit.workUnitId}`; + const state = currentRouting.get(key); + if (state === undefined) continue; + switch (state.initialEligibility) { + case 'ELIGIBLE': eligibility.eligible += 1; break; + case 'STRONG_REQUIRED': eligibility.strongRequired += 1; break; + case 'NEEDS_RESEARCH': eligibility.needsResearch += 1; break; + case 'NEEDS_AUTHORITY': eligibility.needsAuthority += 1; break; + case 'NEEDS_CONTEXT': eligibility.needsContext += 1; break; + case 'NOT_READY': eligibility.notReady += 1; break; + default: break; + } + const decisions = state.decisions; + const unitAttempts = attemptsByUnit.get(key) ?? []; + if (entry.unit.resourceWait !== undefined) selection.waitingForResource += 1; + if (state.initialEligibility === 'ELIGIBLE') { + if (decisions.some((decision) => decision.selectedBackend === 'SECONDARY')) { + selection.secondarySelected += 1; + } else if (decisions.some((decision) => decision.selectedBackend === 'STRONG')) { + selection.strongSelectedDespiteEligibility += 1; + } + } + const directStrong = decisions.find((decision) => decision.selectedBackend === 'STRONG'); + if (directStrong !== undefined && !unitAttempts.some((attempt) => attempt.kind === 'STRONG_FALLBACK')) { + if (state.initialEligibility === 'STRONG_REQUIRED') strongSelection.requiredDirect += 1; + else if (directStrong.reasons.some((reason) => reason.code === 'STRATEGY_OFF')) strongSelection.byStrategyOff += 1; + else if (directStrong.reasons.some((reason) => reason.code === 'SECONDARY_UNAVAILABLE')) { + strongSelection.becauseSecondaryUnavailable += 1; + } else if ( + directStrong.reasons.some((reason) => + reason.code === 'SUBSCRIPTION_HARVEST' + || reason.code === 'SECONDARY_AUTO_POLICY' + || reason.code === 'CRITICAL_WORK_PREFERS_STRONG') + ) { + strongSelection.byAutoPolicy += 1; + } + } + if (unitAttempts.some((attempt) => attempt.kind === 'STRONG_FALLBACK')) { + strongSelection.fallbackAfterSecondary += 1; + increment(fallbackReasons, fallbackReason(unitAttempts)); + } + } + eligibility.ineligible = + eligibility.strongRequired + + eligibility.needsResearch + + eligibility.needsAuthority + + eligibility.needsContext + + eligibility.notReady; + + const eligibleUnits = units.filter((entry) => { + const state = currentRouting.get(`${entry.objectiveNodeId}\u0000${entry.unit.workUnitId}`); + return entry.unit.kind === 'build' && state?.initialEligibility === 'ELIGIBLE'; + }); + const eligibleCompleted = eligibleUnits.filter((entry) => entry.unit.status === 'INTEGRATED'); + const eligibleCompletedWithoutStrong = eligibleCompleted.filter((entry) => { + const attempts = attemptsByUnit.get(`${entry.objectiveNodeId}\u0000${entry.unit.workUnitId}`) ?? []; + return !attempts.some((attempt) => attempt.kind === 'STRONG' || attempt.kind === 'STRONG_FALLBACK'); + }); + const secondaryAttemptedUnits = eligibleUnits.filter((entry) => { + const attempts = attemptsByUnit.get(`${entry.objectiveNodeId}\u0000${entry.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => + (attempt.kind === 'SECONDARY' || attempt.kind === 'SECONDARY_REPAIR') + && attempt.outcome !== 'FAILED_RESOURCE' + && attempt.outcome !== 'CANCELLED'); + }); + const initialAttemptedUnits = eligibleUnits.filter((entry) => { + const attempts = attemptsByUnit.get(`${entry.objectiveNodeId}\u0000${entry.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => + attempt.kind === 'SECONDARY' + && attempt.outcome !== 'FAILED_RESOURCE' + && attempt.outcome !== 'CANCELLED'); + }); + const initialPassUnits = initialAttemptedUnits.filter((entry) => { + const attempts = attemptsByUnit.get(`${entry.objectiveNodeId}\u0000${entry.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => attempt.kind === 'SECONDARY' && attempt.outcome === 'SUCCEEDED'); + }); + const repairAttemptedUnits = eligibleUnits.filter((entry) => { + const attempts = attemptsByUnit.get(`${entry.objectiveNodeId}\u0000${entry.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => + attempt.kind === 'SECONDARY_REPAIR' + && attempt.outcome !== 'FAILED_RESOURCE' + && attempt.outcome !== 'CANCELLED'); + }); + const repairPassUnits = repairAttemptedUnits.filter((entry) => { + const attempts = attemptsByUnit.get(`${entry.objectiveNodeId}\u0000${entry.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => attempt.kind === 'SECONDARY_REPAIR' && attempt.outcome === 'SUCCEEDED'); + }); + const fallbackUnits = eligibleUnits.filter((entry) => { + const attempts = attemptsByUnit.get(`${entry.objectiveNodeId}\u0000${entry.unit.workUnitId}`) ?? []; + return attempts.some((attempt) => attempt.kind === 'STRONG_FALLBACK'); + }); + const unavailableFallbackUnits = eligibleUnits.filter((entry) => { + const state = currentRouting.get(`${entry.objectiveNodeId}\u0000${entry.unit.workUnitId}`); + return state?.decisions.some((decision) => + decision.selectedBackend === 'STRONG' + && decision.reasons.some((reason) => reason.code === 'SECONDARY_UNAVAILABLE')) === true; + }); + + const secondaryAttempts = implementationAttempts.filter((attempt) => + attempt.kind === 'SECONDARY' || attempt.kind === 'SECONDARY_REPAIR'); + const strongAttempts = implementationAttempts.filter((attempt) => + attempt.kind === 'STRONG' || attempt.kind === 'STRONG_FALLBACK'); + const strongEvaluatorAttempts = facts.ledger.filter((entry) => + entry.role === 'EVALUATOR' && entry.lane !== 'LOCAL'); + const secondaryTokens = tokenTelemetry(secondaryAttempts, (attempt) => ({ + input: attempt.inputTokens, + output: attempt.outputTokens, + })); + const strongTokens = tokenTelemetry(strongAttempts, (attempt) => ({ + input: attempt.inputTokens, + output: attempt.outputTokens, + })); + const evaluatorTokens = tokenTelemetry(strongEvaluatorAttempts, (attempt) => ({ + input: attempt.metrics.inputTokens, + output: attempt.metrics.outputTokens, + })); + + // Research records carry provider executions and usage. Gate telemetry is + // currently workspace-scoped, so a job report labels that scope instead of + // pretending the aggregate belongs exclusively to this job. + const jobResearchRecords = facts.researchRecords.filter((record) => record.scope?.jobId === facts.job.jobId); + const jobResearchIds = new Set(jobResearchRecords.map((record) => record.researchId)); + const jobResearchUses = facts.researchUses.filter((use) => jobResearchIds.has(use.researchId)); + const hasJobResearch = jobResearchRecords.length > 0 || jobResearchUses.length > 0; + const hasWorkspaceResearch = + (facts.researchTelemetry?.gateConsidered ?? 0) > 0 + || facts.researchRecords.length > 0 + || facts.researchUses.length > 0; + const researchScope: ExecutionTelemetryReport['research']['scope'] = hasJobResearch + ? 'JOB' + : hasWorkspaceResearch + ? 'WORKSPACE' + : 'NONE'; + const reportResearchRecords = hasJobResearch ? jobResearchRecords : facts.researchRecords; + const reportResearchUses = hasJobResearch ? jobResearchUses : facts.researchUses; + const useIds = new Set(reportResearchUses.map((use) => use.useId)); + const uniqueUses = reportResearchUses.filter((use) => { + if (!useIds.has(use.useId)) return false; + useIds.delete(use.useId); + return true; + }); + const providerRecords = reportResearchRecords.filter((record) => record.status !== 'PENDING'); + const workspaceResearch = researchScope === 'WORKSPACE'; + const providerCallCount = workspaceResearch + ? facts.researchTelemetry?.providerCalls ?? providerRecords.length + : providerRecords.length; + const successfulResearch = workspaceResearch + ? facts.researchTelemetry?.successfulResearch ?? providerRecords.filter((record) => record.status === 'COMPLETED').length + : providerRecords.filter((record) => record.status === 'COMPLETED').length; + const inconclusiveResearch = workspaceResearch + ? facts.researchTelemetry?.inconclusiveResearch ?? providerRecords.filter((record) => record.status === 'INCONCLUSIVE').length + : providerRecords.filter((record) => record.status === 'INCONCLUSIVE').length; + const failedResearch = workspaceResearch + ? facts.researchTelemetry?.failedResearch ?? providerRecords.filter((record) => record.status === 'FAILED').length + : providerRecords.filter((record) => record.status === 'FAILED').length; + const reuseCount = workspaceResearch + ? facts.researchTelemetry?.reusedReports ?? uniqueUses.filter((use) => use.useKind === 'REUSED').length + : uniqueUses.filter((use) => use.useKind === 'REUSED').length; + const newQuick = workspaceResearch + ? facts.researchTelemetry?.newQuick ?? providerRecords.filter((record) => record.depth === 'QUICK').length + : providerRecords.filter((record) => record.depth === 'QUICK').length; + const newDeep = workspaceResearch + ? facts.researchTelemetry?.newDeep ?? providerRecords.filter((record) => record.depth === 'DEEP').length + : providerRecords.filter((record) => record.depth === 'DEEP').length; + const researchConsidered = researchScope === 'WORKSPACE' + ? facts.researchTelemetry?.gateConsidered ?? null + : null; + const researchAvoided = researchScope === 'WORKSPACE' + ? facts.researchTelemetry?.researchAvoided ?? null + : null; + const researchDecisions = researchScope === 'WORKSPACE' + ? { ...(facts.researchTelemetry?.decisions ?? {}) } + : {}; + const byPhase: Record> = {}; + for (const phase of ['CONVERSATION', 'SPEC_DRAFT', 'INTAKE_DECISION', 'RUNTIME_INVESTIGATION']) { + const aggregate = researchScope === 'WORKSPACE' ? facts.researchTelemetry?.byPhase[phase as keyof ResearchTelemetry['byPhase']] : undefined; + const phaseRecords = providerRecords.filter((record) => record.lifecycle?.phase === phase); + const phaseUses = uniqueUses.filter((use) => use.phase === phase); + byPhase[phase] = { + considered: aggregate?.considered ?? 0, + avoided: aggregate?.avoided ?? 0, + reused: researchScope === 'WORKSPACE' ? aggregate?.reused ?? phaseUses.filter((use) => use.useKind === 'REUSED').length : phaseUses.filter((use) => use.useKind === 'REUSED').length, + newCalls: researchScope === 'WORKSPACE' ? (aggregate?.newQuick ?? 0) + (aggregate?.newDeep ?? 0) : phaseRecords.length, + quick: researchScope === 'WORKSPACE' ? aggregate?.newQuick ?? phaseRecords.filter((record) => record.depth === 'QUICK').length : phaseRecords.filter((record) => record.depth === 'QUICK').length, + deep: researchScope === 'WORKSPACE' ? aggregate?.newDeep ?? phaseRecords.filter((record) => record.depth === 'DEEP').length : phaseRecords.filter((record) => record.depth === 'DEEP').length, + failed: phaseRecords.filter((record) => record.status === 'FAILED').length, + }; + } + let researchInputTokens = 0; + let researchOutputTokens = 0; + let researchDurationMs = 0; + let researchCost = 0; + let researchSubagents = 0; + let researchInputObserved = false; + let researchOutputObserved = false; + let researchDurationObserved = false; + let researchCostObserved = false; + let researchSubagentsObserved = false; + let recordsWithUsage = 0; + for (const record of providerRecords) { + const usage = record.usage ?? record.report?.usage; + if (usage === undefined) continue; + recordsWithUsage += 1; + if (usage.inputTokens !== undefined) { + researchInputObserved = true; + researchInputTokens += usage.inputTokens; + } + if (usage.outputTokens !== undefined) { + researchOutputObserved = true; + researchOutputTokens += usage.outputTokens; + } + if (usage.durationMs !== undefined) { + researchDurationObserved = true; + researchDurationMs += usage.durationMs; + } + if (usage.providerReportedCost !== undefined) { + researchCostObserved = true; + researchCost += usage.providerReportedCost; + } + if (usage.subagentCount !== undefined) { + researchSubagentsObserved = true; + researchSubagents += usage.subagentCount; + } + } + if (researchScope === 'WORKSPACE' && providerRecords.length === 0 && facts.researchTelemetry !== undefined) { + const reported = facts.researchTelemetry.reportedUsage; + if (reported.reports > 0) { + recordsWithUsage = reported.reports; + // Legacy aggregate telemetry did not preserve per-field coverage. A + // positive aggregate is safe evidence that the provider reported that + // field; zero remains ambiguous and therefore stays null. + if (reported.inputTokens > 0) { + researchInputObserved = true; + researchInputTokens = reported.inputTokens; + } + if (reported.outputTokens > 0) { + researchOutputObserved = true; + researchOutputTokens = reported.outputTokens; + } + if (reported.providerReportedCost > 0) { + researchCostObserved = true; + researchCost = reported.providerReportedCost; + } + if (reported.subagentCount > 0) { + researchSubagentsObserved = true; + researchSubagents = reported.subagentCount; + } + } + if (facts.researchTelemetry.totalDurationMs > 0) { + researchDurationObserved = true; + researchDurationMs = facts.researchTelemetry.totalDurationMs; + } + } + + const cooldownStates = facts.objectives + .map((objective) => objective.cooldown) + .filter((state): state is ObjectiveCooldownState => state !== undefined); + const cooldownIntervals: ExecutionTelemetryReport['cooldown']['intervals'] = []; + let cooldownDurationMs = 0; + let cooldownDurationKnown = cooldownStates.length > 0; + let cooldownEpisodes = 0; + for (const state of cooldownStates) { + cooldownEpisodes += state.episodes; + const startedAt = state.currentStartedAt ?? state.firstStartedAt; + const endedAt = state.status === 'RECOVERED' ? state.lastEndedAt ?? null : null; + const startMs = timestampMs(startedAt); + const endMs = state.status === 'ACTIVE' ? generatedMs : timestampMs(endedAt); + const durationMs = startMs !== undefined && endMs !== undefined && endMs >= startMs + ? endMs - startMs + : null; + if (state.episodes !== 1) cooldownDurationKnown = false; + if (durationMs === null) cooldownDurationKnown = false; + else cooldownDurationMs += durationMs; + cooldownIntervals.push({ + objectiveNodeId: state.objectiveNodeId, + status: state.status, + startedAt, + endedAt, + durationMs, + completedWorkUnits: state.completedDuringCooldown.length, + }); + if (state.episodes > 1) { + diagnostics.push({ + code: 'COOLDOWN_DURATION_PARTIAL', + severity: 'info', + message: `Objective ${state.objectiveNodeId} records ${state.episodes} cooldown episodes but retains only bounded interval endpoints; total duration is unavailable.`, + evidenceRefs: [state.objectiveNodeId], + }); + } + } + const cooldownCompletedKeys = new Set(); + const cooldownWaitingKeys = new Set(); + for (const state of cooldownStates) { + for (const workUnitId of state.completedDuringCooldown) { + cooldownCompletedKeys.add(`${state.objectiveNodeId}\u0000${workUnitId}`); + } + for (const workUnitId of state.waitingWorkUnitIds) { + cooldownWaitingKeys.add(`${state.objectiveNodeId}\u0000${workUnitId}`); + } + } + let secondaryImplementationDuringCooldown = 0; + for (const entry of units) { + const key = `${entry.objectiveNodeId}\u0000${entry.unit.workUnitId}`; + if (!cooldownCompletedKeys.has(key) || entry.unit.kind !== 'build') continue; + const unitAttempts = attemptsByUnit.get(key) ?? []; + if ( + unitAttempts.some((attempt) => attempt.kind === 'SECONDARY' || attempt.kind === 'SECONDARY_REPAIR') + && !unitAttempts.some((attempt) => attempt.kind === 'STRONG' || attempt.kind === 'STRONG_FALLBACK') + ) { + secondaryImplementationDuringCooldown += 1; + } + } + const withinCooldown = (at: string): boolean => { + const atMs = timestampMs(at); + if (atMs === undefined) return false; + return cooldownIntervals.some((interval) => { + const start = timestampMs(interval.startedAt); + const end = timestampMs(interval.endedAt) ?? generatedMs; + return start !== undefined && atMs >= start && atMs <= end; + }); + }; + const researchDuringCooldown = providerRecords.filter((record) => + (record.status === 'COMPLETED' || record.status === 'INCONCLUSIVE') + && withinCooldown(record.report?.completedAt ?? record.updatedAt)).length; + let avoidableIdlePeriods = 0; + for (const objective of facts.objectives) { + if (objective.cooldown?.status !== 'ACTIVE' || objective.graph === undefined) continue; + for (const unit of objective.graph.units) { + if (unit.kind !== 'build' || unit.status !== 'READY' || unit.resourceWait !== undefined) continue; + const key = `${objective.objectiveNodeId}\u0000${unit.workUnitId}`; + const state = currentRouting.get(key); + if (state?.initialEligibility !== 'ELIGIBLE' || state.strategy === 'OFF') continue; + const startMs = timestampMs(objective.cooldown.currentStartedAt); + const dispatched = (attemptsByUnit.get(key) ?? []).some((attempt) => { + const attemptMs = timestampMs(attempt.startedAt); + return (attempt.kind === 'SECONDARY' || attempt.kind === 'SECONDARY_REPAIR') + && attemptMs !== undefined + && (startMs === undefined || attemptMs >= startMs); + }); + if (!dispatched) avoidableIdlePeriods += 1; + } + } + if (avoidableIdlePeriods > 0) { + diagnostics.push({ + code: 'AVOIDABLE_IDLE_DURING_COOLDOWN', + severity: 'warning', + message: `${avoidableIdlePeriods} runnable Secondary work period(s) had no durable Secondary dispatch during an active Strong cooldown.`, + evidenceRefs: [], + }); + } + const cooldownEventTypes = new Set([ + 'resource_cooldown_started', + 'resource_cooldown_observed', + 'work_unit_resource_wait_started', + 'work_unit_resource_wait_ended', + 'resource_wait_entered', + 'useful_work_during_cooldown', + 'resource_recovered', + ]); + const cooldownTimeline = facts.events + .filter((event) => cooldownEventTypes.has(event.type)) + .slice(-200) + .map((event) => ({ + at: String(event.at ?? ''), + type: event.type, + objectiveNodeId: typeof event['nodeId'] === 'string' ? event['nodeId'].slice(0, 512) : null, + detail: cooldownEventDetail(event), + })); + + const evaluationFailures = evaluations.filter((entry) => entry.verdict === 'FAIL'); + const evaluationPasses = evaluations.filter((entry) => entry.verdict === 'PASS'); + const failuresByBackend: Record = {}; + let failuresRecoveredByRepair = 0; + let failuresRecoveredByStrongFallback = 0; + const failedUnitKeys = new Set(); + for (const evaluation of evaluationFailures) { + const key = `${evaluation.objectiveNodeId}\u0000${evaluation.workUnitId}`; + failedUnitKeys.add(key); + const unitAttempts = attemptsByUnit.get(key) ?? []; + const matching = [...unitAttempts] + .reverse() + .find((attempt) => attempt.workUnitAttempt === evaluation.attempt); + increment(failuresByBackend, matching?.kind ?? 'UNKNOWN'); + } + for (const key of failedUnitKeys) { + const unitAttempts = attemptsByUnit.get(key) ?? []; + if (unitAttempts.some((attempt) => attempt.kind === 'SECONDARY_REPAIR' && attempt.outcome === 'SUCCEEDED')) { + failuresRecoveredByRepair += 1; + } + if (unitAttempts.some((attempt) => attempt.kind === 'STRONG_FALLBACK' && attempt.outcome === 'SUCCEEDED')) { + failuresRecoveredByStrongFallback += 1; + } + } + + const failureSources: Record = {}; + const recoveryActions: Record = {}; + for (const entry of facts.ledger) { + if (entry.failureSource !== null) increment(failureSources, entry.failureSource); + else if (!entry.success && entry.failureReason !== null) increment(failureSources, 'UNCLASSIFIED'); + if (entry.recoveryAction !== null) increment(recoveryActions, entry.recoveryAction); + } + const repairAttempts = implementationAttempts.filter((attempt) => attempt.kind === 'SECONDARY_REPAIR').length; + const strongFallbackAttempts = implementationAttempts.filter((attempt) => attempt.kind === 'STRONG_FALLBACK').length; + if (repairAttempts > 0) increment(recoveryActions, 'repair', repairAttempts); + if (strongFallbackAttempts > 0) increment(recoveryActions, 'strong-fallback', strongFallbackAttempts); + const resourceWaitEvents = eventTypes('resource_wait_started').length + + eventTypes('resource_wait_entered').length + + eventTypes('work_unit_resource_wait_started').length; + if (resourceWaitEvents > 0) increment(recoveryActions, 'resource-wait', resourceWaitEvents); + const restartEvents = eventTypes('job_resumed').length + eventTypes('driver_restarted').length; + if (restartEvents > 0) increment(recoveryActions, 'restart-resume', restartEvents); + + const noProgressDetections = implementationAttempts.filter((attempt) => attempt.noProgress).length; + const fingerprintCounts = new Map(); + for (const attempt of implementationAttempts) { + if (attempt.problemFingerprint !== undefined) { + fingerprintCounts.set( + attempt.problemFingerprint, + (fingerprintCounts.get(attempt.problemFingerprint) ?? 0) + 1, + ); + } + } + const repeatedProblemFingerprints = [...fingerprintCounts.values()].filter((value) => value > 1).length; + const candidatesPersisted = new Set( + implementationAttempts + .map((attempt) => attempt.candidateRef) + .filter((ref): ref is string => ref !== undefined), + ).size; + const candidateRebuilds = eventTypes('candidate_resume_missing').length; + const candidatesReused = cooldownStates.reduce( + (sum, state) => sum + state.candidateReuseAfterRestart, + 0, + ); + const integrationRetries = eventTypes('integration_failed').length; + let completedWorkRedoCount = 0; + for (const entry of units) { + if (entry.unit.integratedAt === undefined) continue; + const integratedMs = timestampMs(entry.unit.integratedAt); + if (integratedMs === undefined) continue; + const attemptsAfterIntegration = (attemptsByUnit.get(`${entry.objectiveNodeId}\u0000${entry.unit.workUnitId}`) ?? []) + .filter((attempt) => (timestampMs(attempt.startedAt) ?? 0) > integratedMs); + if (attemptsAfterIntegration.length > 0) completedWorkRedoCount += 1; + } + const lastRestartMs = Math.max( + 0, + ...facts.events + .filter((event) => event.type === 'job_resumed' || event.type === 'driver_restarted') + .map((event) => timestampMs(event.at) ?? 0), + ); + const completedWorkReusedAfterRestart = lastRestartMs === 0 + ? 0 + : units.filter((entry) => { + if (entry.unit.status !== 'INTEGRATED') return false; + const unitAttempts = attemptsByUnit.get(`${entry.objectiveNodeId}\u0000${entry.unit.workUnitId}`) ?? []; + return unitAttempts.length > 0 + && unitAttempts.every((attempt) => (timestampMs(attempt.completedAt) ?? Number.MAX_SAFE_INTEGER) <= lastRestartMs); + }).length; + const unresolvedInterrupted = facts.ledger.filter((entry) => { + if (entry.status !== 'INTERRUPTED') return false; + return !facts.ledger.some((candidate) => + candidate.taskId === entry.taskId + && candidate.attemptNumber > entry.attemptNumber + && candidate.status === 'COMPLETED'); + }).length; + const unrecoveredDriverDeaths = ['COMPLETED', 'FAILED', 'CANCELLED'].includes(facts.job.status) + ? unresolvedInterrupted + : 0; + const unexpectedBlocks = facts.autonomy.interventions.filter((intervention) => + intervention.kind === 'job_blocked' + || intervention.kind === 'budget_exhausted' + || intervention.kind.startsWith('status:')).length; + if (completedWorkRedoCount > 0) { + diagnostics.push({ + code: 'COMPLETED_WORK_REDONE', + severity: 'error', + message: `${completedWorkRedoCount} authoritatively integrated WorkUnit(s) have a later implementation attempt without recorded invalidation.`, + evidenceRefs: [], + }); + } + + const completedImplementation = units.filter((entry) => + entry.unit.kind === 'build' && entry.unit.status === 'INTEGRATED').length; + const attemptCountsForCompleted = units + .filter((entry) => entry.unit.status === 'INTEGRATED' && entry.unit.kind === 'build') + .map((entry) => + (attemptsByUnit.get(`${entry.objectiveNodeId}\u0000${entry.unit.workUnitId}`) ?? []).length); + const totalAttemptsForCompleted = attemptCountsForCompleted.reduce((sum, value) => sum + value, 0); + const meanAttempts = attemptCountsForCompleted.length === 0 + ? null + : totalAttemptsForCompleted / attemptCountsForCompleted.length; + const completedPerAttempt = implementationAttempts.length === 0 + ? null + : completedImplementation / implementationAttempts.length; + const completedPerStrong = strongAttempts.length === 0 + ? null + : completedImplementation / strongAttempts.length; + const completedEligiblePerSecondary = secondaryAttempts.length === 0 + ? null + : eligibleCompleted.length / secondaryAttempts.length; + + const closureTotals = facts.closure === undefined ? undefined : summarizeClosure(facts.closure.entries); + const closureGate = facts.closure === undefined + ? undefined + : missionMayComplete(facts.closure, facts.closurePolicy); + const closureOutcome: 'PASS' | 'FAIL' | 'UNAVAILABLE' = facts.closure === undefined + ? 'UNAVAILABLE' + : closureGate?.mayComplete === true + ? 'PASS' + : 'FAIL'; + const overallVerification = verificationOutcome(facts.job, facts.events); + const boundaryMs = timestampMs(facts.autonomy.boundaryStartedAt); + const decisionsBeforeSeal = boundaryMs === undefined + ? null + : facts.events.filter((event) => + (event.type === 'clarification_resolved' || event.type === 'authority_resolved') + && (timestampMs(event.at) ?? Number.MAX_SAFE_INTEGER) < boundaryMs).length; + const humanByKind: Record = {}; + for (const intervention of facts.autonomy.interventions) increment(humanByKind, intervention.kind); + + const objectiveRevisions: Record = {}; + for (const objective of facts.objectives) { + if (objective.graph !== undefined) objectiveRevisions[objective.objectiveNodeId] = objective.graph.revision; + } + const ledgerWatermark = sha256Hex(JSON.stringify( + facts.ledger.map((entry) => [entry.attemptId, entry.status, entry.completedAt]), + )); + const currentPolicyFingerprint = autonomyPolicyFingerprint(facts.currentAutonomyPolicy); + const runtimePolicyChanged = facts.binding === undefined + ? null + : currentPolicyFingerprint !== facts.binding.boundPolicyFingerprint; + + const strongAvoidance = metric(eligibleCompletedWithoutStrong.length, eligibleCompleted.length); + const secondaryInitial = metric(initialPassUnits.length, initialAttemptedUnits.length); + const secondaryRepair = metric(repairPassUnits.length, repairAttemptedUnits.length); + const secondaryFallback = metric(fallbackUnits.length, secondaryAttemptedUnits.length); + const researchAvoidance = metric(researchAvoided, researchConsidered); + const researchReuse = metric( + reuseCount, + reuseCount + providerCallCount, + ); + const implementationByKind: Record = {}; + for (const attempt of implementationAttempts) increment(implementationByKind, attempt.kind); + const objectiveSummaries: ExecutionTelemetryReport['work']['objectives'] = facts.objectives + .slice(0, 200) + .map((objective) => { + const accounting: Record, number> = { + completed: 0, + failed: 0, + cancelled: 0, + waiting: 0, + 'not-ready': 0, + 'human-authority-pending': 0, + 'research-pending': 0, + 'context-pending': 0, + }; + for (const unit of objective.graph?.units ?? []) { + const key = `${objective.objectiveNodeId}\u0000${unit.workUnitId}`; + accounting[workAccounting(unit, currentRouting.get(key))] += 1; + } + const attempts = implementationAttempts.filter((entry) => + entry.objectiveNodeId === objective.objectiveNodeId); + return { + objectiveNodeId: objective.objectiveNodeId, + graphRevision: objective.graph?.revision ?? null, + total: objective.graph?.units.length ?? 0, + accounting, + implementationAttempts: attempts.length, + secondaryAttempts: attempts.filter((entry) => + entry.kind === 'SECONDARY' || entry.kind === 'SECONDARY_REPAIR').length, + strongBuilderAttempts: attempts.filter((entry) => + entry.kind === 'STRONG' || entry.kind === 'STRONG_FALLBACK').length, + }; + }); + + const report = executionTelemetryReportSchema.parse({ + schemaVersion: EXECUTION_TELEMETRY_REPORT_SCHEMA_VERSION, + jobId: facts.job.jobId, + missionId: facts.binding?.missionId ?? facts.seal?.missionId ?? null, + generatedAt: facts.generatedAt, + period: { + startedAt: facts.job.createdAt, + endedAt: facts.job.finalizedAt ?? null, + durationMs: + timestampMs(facts.job.createdAt) === undefined + ? null + : Math.max( + 0, + (timestampMs(facts.job.finalizedAt ?? facts.generatedAt) ?? generatedMs) + - (timestampMs(facts.job.createdAt) ?? generatedMs), + ), + activeExecutionMs: + timestampMs(facts.job.createdAt) === undefined + ? null + : workedMsOf(facts.job, timestampMs(facts.job.finalizedAt ?? facts.generatedAt) ?? generatedMs), + }, + provenance: { + sourceJobId: facts.job.jobId, + jobGraphRevision: facts.job.graphRevision, + objectiveGraphRevisions: objectiveRevisions, + executionLedgerWatermark: ledgerWatermark, + eventWatermark: facts.eventTotal, + specbridgeVersion: facts.specbridgeVersion ?? null, + sealId: facts.binding?.sealId ?? null, + sealedAuthorityDigest: facts.seal?.authorityDigest ?? null, + runtimePolicyChanged, + configuration: { + secondaryBuildStrategy: facts.secondaryBuildStrategy, + researchStrategy: facts.researchStrategy, + runnerProfiles: [...facts.runnerProfiles].sort().slice(0, 50), + }, + }, + outcome: { + status: outcomeStatus(facts.job.status), + authoritativeJobStatus: facts.job.status, + finalOutcome: + facts.job.finalOutcome === undefined + ? null + : redactTelemetryText(facts.job.finalOutcome).slice(0, 2_000), + verification: overallVerification, + closure: closureOutcome, + }, + work: { + total: units.length, + byKind: workByKind, + accounting: workAccountingCounts, + completedImplementation, + objectives: objectiveSummaries, + units: unitSummaries, + omittedUnits: Math.max(0, units.length - unitSummaries.length), + }, + secondary: { + eligibility, + selection, + funnel: { + initialAttempts: initialAttemptedUnits.length, + initialPass: initialPassUnits.length, + repairAttempted: repairAttemptedUnits.length, + repairPass: repairPassUnits.length, + toStrongFallback: fallbackUnits.length, + unavailableFallback: unavailableFallbackUnits.length, + }, + initialSuccessRate: secondaryInitial, + repairRecoveryRate: secondaryRepair, + toStrongFallbackRate: secondaryFallback, + fallbackReasons, + builderTokens: secondaryTokens, + }, + strong: { + builderAttempts: strongAttempts.length, + evaluatorAttempts: strongEvaluatorAttempts.length, + selection: strongSelection, + implementationTokens: strongTokens, + evaluatorTokens, + }, + research: { + scope: researchScope, + considered: researchConsidered, + decisions: researchDecisions, + providerCalls: providerCallCount, + successful: successfulResearch, + inconclusive: inconclusiveResearch, + failed: failedResearch, + priorResearchReused: reuseCount, + newQuick, + newDeep, + avoidanceRatio: researchAvoidance, + reuseRate: researchReuse, + byPhase, + usage: { + inputTokens: researchInputObserved ? researchInputTokens : null, + outputTokens: researchOutputObserved ? researchOutputTokens : null, + durationMs: researchDurationObserved ? researchDurationMs : null, + providerReportedCost: researchCostObserved ? researchCost : null, + subagentCount: researchSubagentsObserved ? researchSubagents : null, + recordsWithUsage, + providerCalls: providerCallCount, + coverage: providerCallCount === 0 ? null : Math.min(1, recordsWithUsage / providerCallCount), + }, + }, + cooldown: { + episodes: cooldownEpisodes, + observations: eventTypes('resource_cooldown_observed').length, + totalDurationMs: cooldownDurationKnown ? cooldownDurationMs : null, + usefulWorkDuringSubscriptionCooldown: cooldownCompletedKeys.size, + secondaryImplementationWorkDuringCooldown: secondaryImplementationDuringCooldown, + researchWorkDuringCooldown: researchDuringCooldown, + strongRequiredWaiting: cooldownWaitingKeys.size, + avoidableIdlePeriods, + intervals: cooldownIntervals.sort((left, right) => + left.startedAt.localeCompare(right.startedAt, 'en') + || left.objectiveNodeId.localeCompare(right.objectiveNodeId, 'en')), + timeline: cooldownTimeline, + }, + attempts: { + uniqueImplementationAttempts: implementationAttempts.length, + meanPerCompletedWorkUnit: meanAttempts, + medianPerCompletedWorkUnit: median(attemptCountsForCompleted), + maxPerWorkUnit: attemptCountsForCompleted.length === 0 ? 0 : Math.max(...attemptCountsForCompleted), + workUnitsWithMultipleAttempts: attemptCountsForCompleted.filter((value) => value > 1).length, + byKind: implementationByKind, + completedWorkUnitsPerImplementationAttempt: completedPerAttempt, + completedWorkUnitsPerStrongBuilderCall: completedPerStrong, + completedEligibleWorkUnitsPerSecondaryAttempt: completedEligiblePerSecondary, + }, + verification: { + attempts: evaluations.length, + passes: evaluationPasses.length, + failures: evaluationFailures.length, + otherVerdicts: evaluations.length - evaluationPasses.length - evaluationFailures.length, + failuresByBuilderBackend: failuresByBackend, + failuresRecoveredByRepair, + failuresRecoveredByStrongFallback, + }, + closure: { + available: closureTotals !== undefined, + items: closureTotals?.total ?? 0, + earned: closureTotals?.verified ?? 0, + waived: closureTotals?.waived ?? 0, + unresolved: + closureTotals === undefined + ? 0 + : closureTotals.total - closureTotals.verified - closureTotals.waived - closureTotals.notApplicable, + completionGateOutcome: closureOutcome, + ratio: closureTotals === undefined ? null : closureRatio(closureTotals), + }, + human: { + decisionsBeforeSeal, + approvals: facts.seal?.sealedAt === undefined ? 0 : 1, + authorityEscalationsAfterSeal: facts.autonomy.humanAuthorityEscalationsAfterSeal, + interventionsAfterSeal: facts.autonomy.humanInterventionsAfterSeal, + unexpectedBlockersAfterSeal: unexpectedBlocks, + zeroTouchAfterSeal: facts.autonomy.humanInterventionsAfterSeal === 0, + byKind: humanByKind, + }, + reliability: { + failureSources, + recoveryActions, + noProgressDetections, + repeatedProblemFingerprints, + legitimateResourceWaitsExcluded: resourceWaitEvents, + processRestarts: eventTypes('job_resumed').length, + supervisorRestarts: eventTypes('driver_restarted').length + eventTypes('supervisor_lease_reclaimed').length, + candidatesPersisted, + candidatesReusedAfterRestart: candidatesReused, + candidateRebuildsAfterRestart: candidateRebuilds, + candidatesLostOrUnreadable: candidateRebuilds, + candidateReadyResumes: candidatesReused, + integrationRetries, + completedWorkRedoCount, + completedWorkReusedAfterRestart, + attemptsIncorrectlyRepeated: completedWorkRedoCount, + unexpectedBlocks, + unrecoveredDriverDeaths, + }, + efficiency: { + strongBuilderAvoidanceRatio: strongAvoidance, + strongBuilderCallsAvoided: eligibleCompletedWithoutStrong.length, + completedWorkUnitsPerImplementationAttempt: completedPerAttempt, + baseline: facts.baseline === undefined + ? null + : { + kind: facts.baseline.kind, + reportId: facts.baseline.reportId, + strongBuilderAttempts: facts.baseline.strongBuilderAttempts, + sameVerificationOutcome: facts.baseline.verificationOutcome === overallVerification, + sameClosureOutcome: facts.baseline.closureOutcome === closureOutcome, + }, + }, + qualificationSummary: { + strongBuilderAvoidanceRatio: strongAvoidance.value, + secondaryInitialSuccessRate: secondaryInitial.value, + secondaryRepairRecoveryRate: secondaryRepair.value, + secondaryToStrongFallback: fallbackUnits.length, + strongImplementationTokens: strongTokens.completeTokens, + researchAvoidanceRatio: researchAvoidance.value, + newResearchCalls: providerCallCount, + researchReuse: reuseCount, + usefulWorkDuringSubscriptionCooldown: cooldownCompletedKeys.size, + humanInterventionsAfterSeal: facts.autonomy.humanInterventionsAfterSeal, + completedWorkRedoCount, + unexpectedBlocks, + unrecoveredDriverDeaths, + }, + diagnostics: diagnostics.slice(0, 200), + }); + return report; +} + +function cooldownEventDetail(event: JobEvent): string { + switch (event.type) { + case 'resource_cooldown_started': + return `Strong resource cooldown started (${String(event['availability'] ?? 'availability unknown')}).`; + case 'resource_cooldown_observed': + return 'Strong resource cooldown was observed again; this is not a new episode.'; + case 'work_unit_resource_wait_started': + return `WorkUnit ${String(event['workUnitId'] ?? '(unknown)')} entered a Strong resource wait.`; + case 'work_unit_resource_wait_ended': + return `WorkUnit ${String(event['workUnitId'] ?? '(unknown)')} left its Strong resource wait.`; + case 'resource_wait_entered': + return 'The job entered a global resource wait because no permitted work remained runnable.'; + case 'useful_work_during_cooldown': + return `${Number(event['newlyCompleted'] ?? 0)} additional WorkUnit(s) completed during cooldown.`; + case 'resource_recovered': + return 'The Strong resource recovered and waiting work was released.'; + default: + return event.type; + } +} + +/** Load the current job's durable facts through existing package read APIs. */ +export function collectExecutionTelemetryFacts( + deps: AutonomyDeps, + jobId: string, + options: ComputeExecutionTelemetryOptions = {}, +): ExecutionTelemetryFacts { + const job = requireJobState(deps.workspace, jobId); + const eventPage = readJobEvents(deps.workspace, jobId, { limit: 500 }); + const objectives: ObjectiveTelemetryFacts[] = listObjectiveNodes(deps.workspace, jobId).map( + (objectiveNodeId) => ({ + objectiveNodeId, + graph: readLatestWorkGraph(deps.workspace, jobId, objectiveNodeId), + routingStates: readBuilderRoutingStates(deps.workspace, jobId, objectiveNodeId), + cooldown: readObjectiveCooldownState(deps.workspace, jobId, objectiveNodeId), + evaluations: readEvaluations(deps.workspace, jobId, objectiveNodeId), + }), + ); + const researchTelemetryRead = readResearchTelemetry(deps.workspace); + const researchRecords = listResearchRecords(deps.workspace); + const binding = readSealBinding(deps.workspace, jobId); + const seal = readJobSeal(deps.workspace, jobId); + return { + job, + events: eventPage.events, + eventTotal: eventPage.total, + ledger: readExecutionLedger(deps.workspace, jobId), + objectives, + researchTelemetry: researchTelemetryRead.telemetry, + ...(researchTelemetryRead.diagnostic !== undefined + ? { researchTelemetryDiagnostic: researchTelemetryRead.diagnostic } + : {}), + researchRecords: researchRecords.records, + researchRecordDiagnostics: researchRecords.diagnostics.map((diagnostic) => ({ + code: diagnostic.code, + message: diagnostic.message, + })), + researchUses: listResearchUseRecords(deps.workspace), + autonomy: deriveAutonomyTelemetry(deps, { jobId }), + closure: readClosureLedger(deps.workspace, jobId), + ...(binding !== undefined ? { binding } : {}), + ...(seal !== undefined ? { seal } : {}), + generatedAt: nowIso(deps), + ...(options.specbridgeVersion !== undefined ? { specbridgeVersion: options.specbridgeVersion } : {}), + secondaryBuildStrategy: deps.config.orchestration.jobs.objectives.secondaryBuilder.strategy, + researchStrategy: deps.config.research.strategy, + runnerProfiles: Object.keys(deps.config.runnerProfiles), + currentAutonomyPolicy: deps.config.autonomy, + closurePolicy: deps.config.autonomy.closure, + }; +} + +export function executionTelemetryReportFile(workspace: WorkspaceInfo, jobId: string): string { + if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(jobId)) { + throw new Error(`Invalid job id "${jobId}".`); + } + return assertInsideWorkspace( + workspace.rootDir, + path.join(workspace.sidecarDir, 'reports', `job-${jobId}-telemetry.json`), + ); +} + +export function persistExecutionTelemetryReport( + workspace: WorkspaceInfo, + report: ExecutionTelemetryReport, +): string { + const validated = executionTelemetryReportSchema.parse(report); + const file = executionTelemetryReportFile(workspace, validated.jobId); + mkdirSync(path.dirname(file), { recursive: true }); + writeFileAtomic(file, `${JSON.stringify(validated, null, 2)}\n`); + return file; +} + +export type ExecutionTelemetryReportReadResult = + | { kind: 'ok'; report: ExecutionTelemetryReport } + | { kind: 'missing' } + | { kind: 'invalid'; problem: string }; + +export function readExecutionTelemetryReport( + workspace: WorkspaceInfo, + jobId: string, +): ExecutionTelemetryReportReadResult { + const file = executionTelemetryReportFile(workspace, jobId); + try { + const parsed = executionTelemetryReportSchema.safeParse(JSON.parse(readFileSync(file, 'utf8'))); + return parsed.success + ? { kind: 'ok', report: parsed.data } + : { kind: 'invalid', problem: 'stored execution telemetry report is schema-invalid' }; + } catch (cause) { + const error = cause as NodeJS.ErrnoException; + if (error.code === 'ENOENT') return { kind: 'missing' }; + return { kind: 'invalid', problem: 'stored execution telemetry report is unreadable' }; + } +} + +/** Derive a fresh report; persistence is explicit and never required by MCP reads. */ +export function computeExecutionTelemetryReport( + deps: AutonomyDeps, + jobId: string, + options: ComputeExecutionTelemetryOptions = {}, +): ExecutionTelemetryReport { + const report = deriveExecutionTelemetryReport( + collectExecutionTelemetryFacts(deps, jobId, options), + ); + if (options.persist === true) persistExecutionTelemetryReport(deps.workspace, report); + return report; +} + +export interface ExecutionTelemetryComparison { + strongOnlyJobId: string; + mixedJobId: string; + strongBuilderAttempts: { strongOnly: number; mixed: number; avoided: number }; + secondaryBuilderAttempts: { strongOnly: number; mixed: number }; + implementationAttempts: { strongOnly: number; mixed: number }; + acceptanceEqual: boolean; + verificationEqual: boolean; + closureEqual: boolean; + evidenceAvailable: boolean; + correctnessEqual: boolean; + /** Engineering evidence only; no statistical claim is made. */ + qualificationOnly: true; +} + +/** Bounded Strong-only vs mixed-compute qualification comparison. */ +export function compareExecutionTelemetryReports( + strongOnly: ExecutionTelemetryReport, + mixed: ExecutionTelemetryReport, +): ExecutionTelemetryComparison { + const verificationEqual = strongOnly.outcome.verification === mixed.outcome.verification; + const closureEqual = strongOnly.outcome.closure === mixed.outcome.closure; + const acceptanceEqual = strongOnly.outcome.status === mixed.outcome.status; + const evidenceAvailable = + strongOnly.outcome.verification !== 'UNAVAILABLE' + && mixed.outcome.verification !== 'UNAVAILABLE' + && strongOnly.outcome.closure !== 'UNAVAILABLE' + && mixed.outcome.closure !== 'UNAVAILABLE'; + return { + strongOnlyJobId: strongOnly.jobId, + mixedJobId: mixed.jobId, + strongBuilderAttempts: { + strongOnly: strongOnly.strong.builderAttempts, + mixed: mixed.strong.builderAttempts, + avoided: Math.max(0, strongOnly.strong.builderAttempts - mixed.strong.builderAttempts), + }, + secondaryBuilderAttempts: { + strongOnly: strongOnly.attempts.byKind['SECONDARY'] ?? 0, + mixed: mixed.attempts.byKind['SECONDARY'] ?? 0, + }, + implementationAttempts: { + strongOnly: strongOnly.attempts.uniqueImplementationAttempts, + mixed: mixed.attempts.uniqueImplementationAttempts, + }, + acceptanceEqual, + verificationEqual, + closureEqual, + evidenceAvailable, + correctnessEqual: acceptanceEqual && verificationEqual && closureEqual && evidenceAvailable, + qualificationOnly: true, + }; +} diff --git a/packages/autonomy/src/telemetry/index.ts b/packages/autonomy/src/telemetry/index.ts index f84f46b..bf1046f 100644 --- a/packages/autonomy/src/telemetry/index.ts +++ b/packages/autonomy/src/telemetry/index.ts @@ -1 +1,2 @@ export * from './telemetry.js'; +export * from './execution-report.js'; diff --git a/packages/autonomy/src/telemetry/telemetry.ts b/packages/autonomy/src/telemetry/telemetry.ts index 914de69..a3b489a 100644 --- a/packages/autonomy/src/telemetry/telemetry.ts +++ b/packages/autonomy/src/telemetry/telemetry.ts @@ -163,7 +163,7 @@ export interface ComputeTelemetryInput { * would be wrong after the first process restart, and process restarts are * the normal case here. */ -export function computeAutonomyTelemetry( +export function deriveAutonomyTelemetry( deps: AutonomyDeps, input: ComputeTelemetryInput, ): AutonomyTelemetry { @@ -306,6 +306,22 @@ export function computeAutonomyTelemetry( interventions: interventions.slice(0, 200), }); + return telemetry; +} + +/** + * Compute and persist the legacy autonomy telemetry snapshot. + * + * New read-only reporting surfaces use `deriveAutonomyTelemetry` so a report + * request cannot mutate runtime state. This wrapper preserves the existing + * command/runtime behaviour for callers that intentionally materialize the + * snapshot under `.specbridge/autonomy/telemetry/`. + */ +export function computeAutonomyTelemetry( + deps: AutonomyDeps, + input: ComputeTelemetryInput, +): AutonomyTelemetry { + const telemetry = deriveAutonomyTelemetry(deps, input); writeJsonRecord(telemetryFile(deps.workspace, input.jobId), telemetry); return telemetry; } diff --git a/packages/cli/README.md b/packages/cli/README.md index 3a96915..820427c 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -40,6 +40,17 @@ specbridge spec show specbridge compat check # proves byte-identical .kiro round-trips ``` +Inspect a durable Job's operational and token-conservation telemetry: + +```bash +specbridge report job +specbridge report job --verbose +specbridge report job --json +``` + +The report is observational and never grants authority or completion. JSON +output preserves unknown usage as `null` and includes coverage metadata. + Full documentation, examples, templates, the extension SDK, and the Claude Code plugin live in the repository: diff --git a/packages/cli/src/cli.ts b/packages/cli/src/cli.ts index 306e87d..b941f27 100644 --- a/packages/cli/src/cli.ts +++ b/packages/cli/src/cli.ts @@ -43,6 +43,7 @@ import { registerMissionCommands } from './commands/mission.js'; import { registerAutonomyCommands } from './commands/autonomy.js'; import { registerWorkspaceCommands } from './commands/workspace.js'; import { registerResearchCommands } from './commands/research.js'; +import { registerReportCommands } from './commands/report.js'; function buildProgram(runtime: CliRuntime): Command { const program = new Command(); @@ -115,6 +116,7 @@ honest error; nothing pretends to work before it does.`, registerAutonomyCommands(program, runtime); registerWorkspaceCommands(program, runtime); registerResearchCommands(program, runtime); + registerReportCommands(program, runtime); return program; } diff --git a/packages/cli/src/commands/report.ts b/packages/cli/src/commands/report.ts new file mode 100644 index 0000000..b87f75f --- /dev/null +++ b/packages/cli/src/commands/report.ts @@ -0,0 +1,55 @@ +import type { Command } from 'commander'; +import type { AutonomyDeps } from '@specbridge/autonomy'; +import { + computeExecutionTelemetryReport, + executionTelemetryReportFile, +} from '@specbridge/autonomy'; +import { + renderExecutionTelemetryReport, + serializeJsonReport, +} from '@specbridge/reporting'; +import type { CliRuntime } from '../context.js'; +import { relPath } from '../context.js'; +import { loadExecutionContext } from '../execution-context.js'; +import { VERSION } from '../version.js'; + +function deps(runtime: CliRuntime): AutonomyDeps { + const context = loadExecutionContext(runtime); + return { + workspace: context.workspace, + config: context.config, + clock: () => runtime.now(), + host: 'cli', + }; +} + +/** Phase 9 durable operational/economic reports. */ +export function registerReportCommands(program: Command, runtime: CliRuntime): void { + const report = program + .command('report') + .description('Derived execution telemetry (never completion authority)'); + + report + .command('job ') + .description('Report one Job from durable execution facts') + .option('--json', 'emit the versioned machine-readable report') + .option('--verbose', 'include bounded WorkUnit accounting and cooldown timeline') + .option('--no-persist', 'derive without writing .specbridge/reports') + .action((jobId: string, options: { json?: boolean; verbose?: boolean; persist?: boolean }) => { + const reportingDeps = deps(runtime); + const result = computeExecutionTelemetryReport(reportingDeps, jobId, { + persist: options.persist !== false, + specbridgeVersion: VERSION, + }); + if (options.json === true) { + runtime.outRaw(serializeJsonReport(result)); + return; + } + runtime.outRaw(renderExecutionTelemetryReport(result, { verbose: options.verbose === true })); + if (options.persist !== false) { + runtime.out( + `Report: ${relPath(reportingDeps.workspace, executionTelemetryReportFile(reportingDeps.workspace, jobId))}`, + ); + } + }); +} diff --git a/packages/mcp-server/package.json b/packages/mcp-server/package.json index 15e182c..2ae9ed3 100644 --- a/packages/mcp-server/package.json +++ b/packages/mcp-server/package.json @@ -32,6 +32,7 @@ }, "dependencies": { "@modelcontextprotocol/sdk": "1.29.0", + "@specbridge/autonomy": "workspace:*", "@specbridge/compat-kiro": "workspace:*", "@specbridge/core": "workspace:*", "@specbridge/drift": "workspace:*", diff --git a/packages/mcp-server/src/tools/job-report.ts b/packages/mcp-server/src/tools/job-report.ts new file mode 100644 index 0000000..47366bb --- /dev/null +++ b/packages/mcp-server/src/tools/job-report.ts @@ -0,0 +1,66 @@ +import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; +import type { AutonomyDeps } from '@specbridge/autonomy'; +import { + computeExecutionTelemetryReport, + executionTelemetryReportSchema, +} from '@specbridge/autonomy'; +import { z } from 'zod'; +import type { ServerContext } from '../context.js'; +import { MCP_SERVER_VERSION } from '../version.js'; +import { registerDefinedTool } from './helpers.js'; +import { requireAgentConfig } from './interactive-shared.js'; + +function percent(value: number | null): string { + return value === null ? 'n/a' : `${(value * 100).toFixed(1)}%`; +} + +export function registerJobReportTool(server: McpServer, context: ServerContext): void { + registerDefinedTool(server, context, { + name: 'job_report', + title: 'Read a Job execution report', + description: + 'Derive versioned operational and token-conservation telemetry from durable Job, WorkUnit, ' + + 'attempt, research, cooldown, verification, and closure records. Read-only; metrics never ' + + 'grant completion or authority.', + annotations: { + readOnlyHint: true, + destructiveHint: false, + idempotentHint: true, + openWorldHint: false, + }, + inputSchema: { + jobId: z.string().min(1).max(64).describe('Job id (job-…) from job_list'), + }, + outputSchema: { + report: executionTelemetryReportSchema, + }, + handler: async (args) => { + const workspace = context.requireWorkspace(); + const deps: AutonomyDeps = { + workspace, + config: requireAgentConfig(workspace), + clock: context.clock, + idFactory: context.idFactory, + host: 'mcp', + }; + const report = computeExecutionTelemetryReport(deps, args.jobId, { + persist: false, + specbridgeVersion: MCP_SERVER_VERSION, + }); + const summary = report.qualificationSummary; + return { + text: [ + `Job ${report.jobId}: ${report.outcome.status} (${report.outcome.authoritativeJobStatus})`, + `StrongBuilderAvoidanceRatio: ${percent(summary.strongBuilderAvoidanceRatio)}`, + `Secondary initial/repair: ${percent(summary.secondaryInitialSuccessRate)} / ${percent(summary.secondaryRepairRecoveryRate)}`, + `ResearchAvoidanceRatio: ${percent(summary.researchAvoidanceRatio)}`, + `UsefulWorkDuringSubscriptionCooldown: ${summary.usefulWorkDuringSubscriptionCooldown}`, + `humanInterventionsAfterSeal: ${summary.humanInterventionsAfterSeal}`, + `CompletedWorkRedoCount: ${summary.completedWorkRedoCount}`, + `Verification / closure: ${report.outcome.verification} / ${report.outcome.closure}`, + ].join('\n'), + structured: { report }, + }; + }, + }); +} diff --git a/packages/mcp-server/src/tools/registry.ts b/packages/mcp-server/src/tools/registry.ts index 70a5053..8e7a74e 100644 --- a/packages/mcp-server/src/tools/registry.ts +++ b/packages/mcp-server/src/tools/registry.ts @@ -54,6 +54,7 @@ import { registerOrchestrationSubmitPlanTool, } from './orchestration-tools.js'; import { registerJobCancelTool, registerJobListTool, registerJobReadTool } from './job-tools.js'; +import { registerJobReportTool } from './job-report.js'; import { registerContractChangeRequestTool, registerContractListTool, @@ -159,6 +160,7 @@ export const TOOL_CATALOG: readonly ToolRegistryEntry[] = [ { name: 'orchestration_finalize', readOnly: false, summary: 'Close a run (completion needs verified evidence)' }, { name: 'job_list', readOnly: true, summary: 'List long-running orchestration jobs' }, { name: 'job_read', readOnly: true, summary: 'One job in depth: graph, attempts, questions, checkpoint' }, + { name: 'job_report', readOnly: true, summary: 'Durable Job operational and token-conservation report' }, { name: 'job_cancel', readOnly: false, summary: 'Cancel a job (final, idempotent, evidence preserved)' }, { name: 'mission_begin', readOnly: false, summary: 'Begin Mission Discovery from a product direction' }, { name: 'mission_status', readOnly: true, summary: 'List missions with lifecycle status and readiness' }, @@ -246,6 +248,7 @@ export function registerAllTools(server: McpServer, context: ServerContext): voi registerOrchestrationFinalizeTool(server, context); registerJobListTool(server, context); registerJobReadTool(server, context); + registerJobReportTool(server, context); registerJobCancelTool(server, context); registerMissionBeginTool(server, context); registerMissionStatusTool(server, context); diff --git a/packages/reporting/src/execution-telemetry.ts b/packages/reporting/src/execution-telemetry.ts new file mode 100644 index 0000000..fb4c332 --- /dev/null +++ b/packages/reporting/src/execution-telemetry.ts @@ -0,0 +1,253 @@ +import { failLine, infoLine, okLine, reportTitle, sectionTitle, warnLine } from './terminal-report.js'; + +interface FractionMetric { + numerator: number | null; + denominator: number | null; + value: number | null; +} + +interface TokenTelemetry { + knownTokens: number | null; + coverage: { ratio: number | null; complete: boolean }; +} + +/** Structural view keeps the renderer independent from the runtime collector. */ +export interface ExecutionTelemetryReportView { + jobId: string; + outcome: { + status: string; + authoritativeJobStatus: string; + verification: 'PASS' | 'FAIL' | 'UNAVAILABLE'; + closure: 'PASS' | 'FAIL' | 'UNAVAILABLE'; + }; + period: { durationMs: number | null; activeExecutionMs: number | null }; + human: { + zeroTouchAfterSeal: boolean; + interventionsAfterSeal: number; + decisionsBeforeSeal: number | null; + approvals: number; + authorityEscalationsAfterSeal: number | null; + }; + work: { + total: number; + completedImplementation: number; + accounting: Record; + objectives: Array<{ + objectiveNodeId: string; + graphRevision: number | null; + total: number; + implementationAttempts: number; + secondaryAttempts: number; + strongBuilderAttempts: number; + }>; + units: Array<{ + objectiveNodeId: string; + workUnitId: string; + accounting: string; + builderPath: string; + implementationAttempts: number; + verification: string; + }>; + }; + attempts: { uniqueImplementationAttempts: number }; + secondary: { + eligibility: { eligible: number }; + selection: { secondarySelected: number }; + funnel: { initialPass: number; repairPass: number }; + initialSuccessRate: FractionMetric; + repairRecoveryRate: FractionMetric; + toStrongFallbackRate: FractionMetric; + builderTokens: TokenTelemetry; + }; + strong: { + builderAttempts: number; + evaluatorAttempts: number; + implementationTokens: TokenTelemetry; + evaluatorTokens: TokenTelemetry; + }; + research: { + scope: string; + considered: number | null; + providerCalls: number; + priorResearchReused: number; + avoidanceRatio: FractionMetric; + reuseRate: FractionMetric; + newQuick: number; + newDeep: number; + }; + cooldown: { + episodes: number; + totalDurationMs: number | null; + usefulWorkDuringSubscriptionCooldown: number; + avoidableIdlePeriods: number; + timeline: Array<{ at: string; type: string; detail: string }>; + }; + reliability: { + processRestarts: number; + supervisorRestarts: number; + candidatesReusedAfterRestart: number; + candidateRebuildsAfterRestart: number; + completedWorkRedoCount: number; + }; + verification: { passes: number; attempts: number; failures: number }; + closure: { earned: number; waived: number; unresolved: number }; + efficiency: { strongBuilderAvoidanceRatio: FractionMetric }; + qualificationSummary: { + secondaryToStrongFallback: number; + usefulWorkDuringSubscriptionCooldown: number; + humanInterventionsAfterSeal: number; + completedWorkRedoCount: number; + }; + diagnostics: Array<{ severity: 'info' | 'warning' | 'error'; code: string; message: string }>; +} + +export interface RenderExecutionTelemetryOptions { + verbose?: boolean | undefined; +} + +function percent(metric: FractionMetric): string { + return metric.value === null ? 'n/a' : `${(metric.value * 100).toFixed(1)}%`; +} + +function tokens(metric: TokenTelemetry): string { + if (metric.knownTokens === null) return 'n/a (provider did not report usage)'; + const coverage = metric.coverage.ratio === null + ? 'n/a' + : `${Math.round(metric.coverage.ratio * 100)}%`; + return `${metric.knownTokens.toLocaleString('en-US')} known (${coverage} attempt coverage${metric.coverage.complete ? ', complete' : ', partial'})`; +} + +function duration(value: number | null): string { + if (value === null) return 'n/a'; + if (value >= 3_600_000) return `${(value / 3_600_000).toFixed(1)}h`; + if (value >= 60_000) return `${(value / 60_000).toFixed(1)}m`; + return `${(value / 1_000).toFixed(1)}s`; +} + +/** + * Compact operator report. It renders normalized aggregates and bounded + * references, never prompts, raw source, model output, or verification logs. + */ +export function renderExecutionTelemetryReport( + report: ExecutionTelemetryReportView, + options: RenderExecutionTelemetryOptions = {}, +): string { + const lines: string[] = [reportTitle(`Job ${report.jobId} — ${report.outcome.status}`)]; + lines.push(infoLine(`authoritative state: ${report.outcome.authoritativeJobStatus}`)); + lines.push(infoLine(`elapsed ${duration(report.period.durationMs)} · active ${duration(report.period.activeExecutionMs)}`)); + + lines.push('', sectionTitle('Zero-touch status')); + lines.push( + report.human.zeroTouchAfterSeal + ? okLine('ZeroTouchAfterSeal: true (0 human interventions)') + : failLine(`ZeroTouchAfterSeal: false (${report.human.interventionsAfterSeal} intervention(s))`), + ); + lines.push(infoLine(`pre-seal decisions ${report.human.decisionsBeforeSeal ?? 'n/a'} · approvals ${report.human.approvals} · post-seal authority stops ${report.human.authorityEscalationsAfterSeal ?? 'n/a'}`)); + + lines.push('', sectionTitle('Work summary')); + lines.push(infoLine(`${report.work.total} WorkUnit(s) · ${report.work.accounting.completed} completed · ${report.work.accounting.failed} failed · ${report.work.accounting.waiting} waiting`)); + lines.push(infoLine(`${report.work.completedImplementation} implementation WorkUnit(s) integrated · ${report.attempts.uniqueImplementationAttempts} unique implementation attempt(s)`)); + + lines.push('', sectionTitle('Secondary Builder efficiency')); + lines.push(infoLine(`${report.secondary.eligibility.eligible} eligible · ${report.secondary.selection.secondarySelected} selected · ${report.secondary.funnel.initialPass} initial pass · ${report.secondary.funnel.repairPass} repair pass`)); + lines.push(infoLine(`StrongBuilderAvoidanceRatio ${percent(report.efficiency.strongBuilderAvoidanceRatio)} (${report.efficiency.strongBuilderAvoidanceRatio.numerator ?? 'n/a'}/${report.efficiency.strongBuilderAvoidanceRatio.denominator ?? 'n/a'})`)); + lines.push(infoLine(`SecondaryInitialSuccessRate ${percent(report.secondary.initialSuccessRate)} · SecondaryRepairRecoveryRate ${percent(report.secondary.repairRecoveryRate)} · fallback ${percent(report.secondary.toStrongFallbackRate)}`)); + lines.push(infoLine(`Secondary builder tokens: ${tokens(report.secondary.builderTokens)}`)); + + lines.push('', sectionTitle('Strong usage')); + lines.push(infoLine(`${report.strong.builderAttempts} Strong Builder attempt(s) · ${report.strong.evaluatorAttempts} Strong Evaluator attempt(s)`)); + lines.push(infoLine(`Strong implementation tokens: ${tokens(report.strong.implementationTokens)}`)); + lines.push(infoLine(`Strong evaluator tokens: ${tokens(report.strong.evaluatorTokens)}`)); + + lines.push('', sectionTitle('Research efficiency')); + lines.push(infoLine(`scope ${report.research.scope} · considered ${report.research.considered ?? 'n/a'} · new calls ${report.research.providerCalls} · reused ${report.research.priorResearchReused}`)); + lines.push(infoLine(`ResearchAvoidanceRatio ${percent(report.research.avoidanceRatio)} · reuse rate ${percent(report.research.reuseRate)} · QUICK ${report.research.newQuick} · DEEP ${report.research.newDeep}`)); + + lines.push('', sectionTitle('Subscription cooldown')); + lines.push(infoLine(`${report.cooldown.episodes} episode(s) · ${duration(report.cooldown.totalDurationMs)} known duration · ${report.cooldown.usefulWorkDuringSubscriptionCooldown} useful WorkUnit(s)`)); + lines.push( + report.cooldown.avoidableIdlePeriods === 0 + ? okLine('AvoidableIdleDuringCooldown: 0') + : warnLine(`AvoidableIdleDuringCooldown: ${report.cooldown.avoidableIdlePeriods}`), + ); + + lines.push('', sectionTitle('Reliability / resume')); + lines.push(infoLine(`restarts ${report.reliability.processRestarts + report.reliability.supervisorRestarts} · candidates reused ${report.reliability.candidatesReusedAfterRestart} · candidate rebuilds ${report.reliability.candidateRebuildsAfterRestart}`)); + lines.push( + report.reliability.completedWorkRedoCount === 0 + ? okLine('CompletedWorkRedoCount: 0') + : failLine(`CompletedWorkRedoCount: ${report.reliability.completedWorkRedoCount}`), + ); + + lines.push('', sectionTitle('Verification & closure')); + lines.push( + report.outcome.verification === 'PASS' + ? okLine(`verification PASS (${report.verification.passes}/${report.verification.attempts} WorkUnit evaluation passes)`) + : report.outcome.verification === 'FAIL' + ? failLine(`verification FAIL (${report.verification.failures} WorkUnit evaluation failure(s))`) + : warnLine(`verification n/a (${report.verification.passes} WorkUnit evaluation pass(es), authoritative job evidence unavailable)`), + ); + lines.push( + report.outcome.closure === 'PASS' + ? okLine(`closure PASS (${report.closure.earned} earned, ${report.closure.waived} waived)`) + : report.outcome.closure === 'FAIL' + ? failLine(`closure FAIL (${report.closure.unresolved} unresolved)`) + : warnLine('closure n/a (no closure ledger)'), + ); + + if (report.diagnostics.length > 0) { + lines.push('', sectionTitle('Diagnostics')); + for (const diagnostic of report.diagnostics.slice(0, options.verbose === true ? 200 : 10)) { + lines.push( + diagnostic.severity === 'error' + ? failLine(`${diagnostic.code}: ${diagnostic.message}`) + : diagnostic.severity === 'warning' + ? warnLine(`${diagnostic.code}: ${diagnostic.message}`) + : infoLine(`${diagnostic.code}: ${diagnostic.message}`), + ); + } + } + + if (options.verbose === true) { + lines.push('', sectionTitle('Objective accounting')); + for (const objective of report.work.objectives) { + lines.push(infoLine(`${objective.objectiveNodeId} · revision ${objective.graphRevision ?? 'n/a'} · ${objective.total} WorkUnit(s) · ${objective.implementationAttempts} implementation attempt(s) (${objective.secondaryAttempts} Secondary, ${objective.strongBuilderAttempts} Strong)`)); + } + lines.push('', sectionTitle('WorkUnit accounting')); + for (const unit of report.work.units) { + lines.push(infoLine(`${unit.objectiveNodeId}/${unit.workUnitId} · ${unit.accounting} · ${unit.builderPath} · ${unit.implementationAttempts} attempt(s) · verification ${unit.verification}`)); + } + if (report.cooldown.timeline.length > 0) { + lines.push('', sectionTitle('Cooldown timeline')); + for (const entry of report.cooldown.timeline) { + lines.push(infoLine(`${entry.at} · ${entry.type} · ${entry.detail}`)); + } + } + } + + return `${lines.join('\n')}\n`; +} + +/** Markdown form for persisted engineering/Phase-10 evidence. */ +export function renderExecutionTelemetryMarkdown(report: ExecutionTelemetryReportView): string { + const summary = report.qualificationSummary; + return [ + `# Job ${report.jobId} execution report`, + '', + `- Outcome: **${report.outcome.status}** (authoritative state: ${report.outcome.authoritativeJobStatus})`, + `- ZeroTouchAfterSeal: **${report.human.zeroTouchAfterSeal}**`, + `- StrongBuilderAvoidanceRatio: **${percent(report.efficiency.strongBuilderAvoidanceRatio)}**`, + `- SecondaryInitialSuccessRate: **${percent(report.secondary.initialSuccessRate)}**`, + `- SecondaryRepairRecoveryRate: **${percent(report.secondary.repairRecoveryRate)}**`, + `- SecondaryToStrongFallback: **${summary.secondaryToStrongFallback}**`, + `- ResearchAvoidanceRatio: **${percent(report.research.avoidanceRatio)}**`, + `- UsefulWorkDuringSubscriptionCooldown: **${summary.usefulWorkDuringSubscriptionCooldown}**`, + `- humanInterventionsAfterSeal: **${summary.humanInterventionsAfterSeal}**`, + `- CompletedWorkRedoCount: **${summary.completedWorkRedoCount}**`, + `- Verification: **${report.outcome.verification}**`, + `- Closure: **${report.outcome.closure}**`, + '', + 'Metrics are derived evidence. They do not grant completion, verification, or product authority.', + '', + ].join('\n'); +} diff --git a/packages/reporting/src/index.ts b/packages/reporting/src/index.ts index a6305e7..bdbd05d 100644 --- a/packages/reporting/src/index.ts +++ b/packages/reporting/src/index.ts @@ -4,3 +4,4 @@ export * from './html-report.js'; export * from './verification-terminal.js'; export * from './verification-markdown.js'; export * from './verification-html.js'; +export * from './execution-telemetry.js'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0005b50..89ed0c3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -392,6 +392,9 @@ importers: '@modelcontextprotocol/sdk': specifier: 1.29.0 version: 1.29.0(zod@3.25.76) + '@specbridge/autonomy': + specifier: workspace:* + version: link:../autonomy '@specbridge/compat-kiro': specifier: workspace:* version: link:../compat-kiro diff --git a/scripts/smoke.mjs b/scripts/smoke.mjs index 32d46b5..2e06083 100644 --- a/scripts/smoke.mjs +++ b/scripts/smoke.mjs @@ -333,7 +333,7 @@ run('mcp manifest reports identity and protocol baseline', { cwd: kiroProject, args: ['mcp', 'manifest'], expectCode: 0, - expectStdout: ['specbridge', '2025-11-25', 'stdio', '77 tools'], + expectStdout: ['specbridge', '2025-11-25', 'stdio', '78 tools'], }); run('mcp tools lists the registry and the approval boundary', { diff --git a/tests/autonomy/execution-telemetry.test.ts b/tests/autonomy/execution-telemetry.test.ts new file mode 100644 index 0000000..eaa9264 --- /dev/null +++ b/tests/autonomy/execution-telemetry.test.ts @@ -0,0 +1,544 @@ +import { describe, expect, it } from 'vitest'; +import { defaultResolvedAgentConfig, sha256Hex } from '@specbridge/core'; +import { + builderRoutingStateSchema, + emptyResearchTelemetry, + executionLedgerEntrySchema, + jobStateSchema, + objectiveCooldownStateSchema, + workGraphSchema, + workUnitSchema, + type BuilderAttemptKind, + type BuilderRoutingAttempt, + type BuilderRoutingState, + type SecondaryEligibilityStatus, + type WorkUnit, +} from '@specbridge/orchestration'; +import { + autonomyTelemetrySchema, + closureLedgerSchema, + compareExecutionTelemetryReports, + deriveExecutionTelemetryReport, + executionTelemetryReportSchema, + type ExecutionTelemetryFacts, +} from '@specbridge/autonomy'; + +const CREATED = '2026-08-30T00:00:00.000Z'; +const FINISHED = '2026-08-30T03:00:00.000Z'; +const config = defaultResolvedAgentConfig(); + +function unit(index: number): WorkUnit { + return workUnitSchema.parse({ + workUnitId: `wu-${index}`, + objectiveNodeId: 'node-1', + parentTaskId: '1', + kind: 'build', + title: `Implement unit ${index}`, + goal: `Complete deterministic fixture unit ${index}`, + status: 'INTEGRATED', + attempt: 1, + integratedAt: '2026-08-30T02:00:00.000Z', + }); +} + +function attempt( + workUnitId: string, + sequence: number, + kind: BuilderAttemptKind, + outcome: BuilderRoutingAttempt['outcome'], + tokens?: { input: number | null; output: number | null }, +): BuilderRoutingAttempt { + return { + attemptId: `${workUnitId}-${kind.toLowerCase()}-${sequence}`, + sequence, + workUnitAttempt: sequence, + kind, + outcome, + changedFiles: [`src/${workUnitId}.ts`], + verificationSummary: outcome === 'FAILED_VERIFICATION' ? ['unit: failed'] : [], + noProgress: false, + inputTokens: tokens?.input ?? null, + outputTokens: tokens?.output ?? null, + startedAt: `2026-08-30T00:${String(sequence).padStart(2, '0')}:00.000Z`, + completedAt: `2026-08-30T00:${String(sequence + 1).padStart(2, '0')}:00.000Z`, + }; +} + +function routing( + index: number, + eligibility: SecondaryEligibilityStatus, + chain: readonly [BuilderAttemptKind, BuilderRoutingAttempt['outcome']][], +): BuilderRoutingState { + const attempts = chain.map(([kind, outcome], attemptIndex) => + attempt(`wu-${index}`, attemptIndex + 1, kind, outcome)); + const last = attempts.at(-1); + return builderRoutingStateSchema.parse({ + schemaVersion: '1.0.0', + jobId: 'job-phase-9', + objectiveNodeId: 'node-1', + workUnitId: `wu-${index}`, + workIdentity: sha256Hex(`work-${index}`), + strategy: 'PREFER', + initialEligibility: eligibility, + decisions: [], + attempts, + repairAttemptsUsed: attempts.filter((entry) => entry.kind === 'SECONDARY_REPAIR').length, + maxRepairAttempts: 1, + escalationStatus: last?.outcome === 'SUCCEEDED' ? 'COMPLETE' : 'FAILED', + finalBackend: + last?.kind === 'SECONDARY' || last?.kind === 'SECONDARY_REPAIR' ? 'SECONDARY' : 'STRONG', + createdAt: CREATED, + updatedAt: FINISHED, + contentHash: sha256Hex(`routing-${index}`), + }); +} + +function mixedFacts(): ExecutionTelemetryFacts { + const units = Array.from({ length: 20 }, (_, index) => unit(index + 1)); + const states: BuilderRoutingState[] = []; + for (let index = 1; index <= 8; index += 1) { + states.push(routing(index, 'ELIGIBLE', [['SECONDARY', 'SUCCEEDED']])); + } + for (let index = 9; index <= 10; index += 1) { + states.push(routing(index, 'ELIGIBLE', [ + ['SECONDARY', 'FAILED_VERIFICATION'], + ['SECONDARY_REPAIR', 'SUCCEEDED'], + ])); + } + for (let index = 11; index <= 12; index += 1) { + states.push(routing(index, 'ELIGIBLE', [ + ['SECONDARY', 'FAILED_VERIFICATION'], + ['SECONDARY_REPAIR', 'FAILED_VERIFICATION'], + ['STRONG_FALLBACK', 'SUCCEEDED'], + ])); + } + for (let index = 13; index <= 20; index += 1) { + states.push(routing(index, 'STRONG_REQUIRED', [['STRONG', 'SUCCEEDED']])); + } + + const research = emptyResearchTelemetry(new Date(FINISHED)); + research.gateConsidered = 10; + research.researchAvoided = 8; + research.researchAvoidanceRatio = 0.8; + research.decisions.ANSWER_DIRECTLY = 4; + research.decisions.ENGINEERING_DECISION = 2; + research.decisions.REUSE_EXISTING = 2; + research.decisions.RESEARCH_QUICK = 1; + research.decisions.RESEARCH_DEEP = 1; + research.providerCalls = 2; + research.successfulResearch = 2; + research.reusedReports = 3; + research.newQuick = 1; + research.newDeep = 1; + research.byPhase.RUNTIME_INVESTIGATION = { + considered: 10, + avoided: 8, + reused: 3, + newQuick: 1, + newDeep: 1, + }; + + return { + job: jobStateSchema.parse({ + schemaVersion: '1.0.0', + jobId: 'job-phase-9', + specName: 'phase-9', + status: 'COMPLETED', + goal: 'Qualify Phase 9 telemetry', + createdAt: CREATED, + updatedAt: FINISHED, + finalizedAt: FINISHED, + finalOutcome: 'completed', + latestEvidence: { + taskId: '1', + runId: 'run-qualified', + evidenceStatus: 'verified', + at: FINISHED, + }, + host: 'test', + policyFingerprint: 'fixture-policy', + budgets: { + maxAgentRuns: 100, + maxTaskAttempts: 10, + maxRepairCyclesPerTask: 2, + maxReplansPerTask: 2, + maxJobReplans: 2, + maxNoProgressCycles: 2, + maxTransientRetries: 2, + maxWallClockMs: 86_400_000, + maxLocalInferenceCalls: 100, + maxEvents: 1_000, + }, + graphRevision: 1, + }), + events: [], + eventTotal: 0, + ledger: [executionLedgerEntrySchema.parse({ + attemptId: 'strong-evaluator-1', + jobId: 'job-phase-9', + nodeId: 'node-1', + taskId: '1', + role: 'EVALUATOR', + provider: 'strong-provider', + model: 'strong-model', + lane: 'SUBSCRIPTION', + status: 'COMPLETED', + attemptNumber: 1, + startedAt: CREATED, + completedAt: FINISHED, + success: true, + failureReason: null, + metrics: { inputTokens: 100, outputTokens: 20 }, + })], + objectives: [{ + objectiveNodeId: 'node-1', + graph: workGraphSchema.parse({ + schemaVersion: '1.0.0', + jobId: 'job-phase-9', + objectiveNodeId: 'node-1', + parentTaskId: '1', + objectiveFingerprint: sha256Hex('objective'), + revision: 1, + createdAt: CREATED, + proposedBy: 'fixture', + units, + }), + // Replaying the first state models a resume reading overlapping durable + // history. Attempt IDs, not array position, define uniqueness. + routingStates: [...states, states[0]!], + cooldown: objectiveCooldownStateSchema.parse({ + schemaVersion: '1.0.0', + jobId: 'job-phase-9', + objectiveNodeId: 'node-1', + resourceClass: 'STRONG_SUBSCRIPTION', + resourceIdentity: 'subscription:strong', + status: 'RECOVERED', + episodes: 1, + firstStartedAt: '2026-08-30T00:30:00.000Z', + lastEndedAt: '2026-08-30T01:30:00.000Z', + lastAvailability: 'AVAILABLE', + lastObservedAt: '2026-08-30T01:30:00.000Z', + completedBeforeCurrentCooldown: [], + completedDuringCooldown: ['wu-1', 'wu-2', 'wu-3', 'wu-4', 'wu-5', 'wu-6'], + waitingWorkUnitIds: [], + updatedAt: FINISHED, + contentHash: sha256Hex('cooldown'), + }), + evaluations: [], + }], + researchTelemetry: research, + researchRecords: [], + researchUses: [], + autonomy: autonomyTelemetrySchema.parse({ + schemaVersion: '1.0.0', + jobId: 'job-phase-9', + recordedAt: FINISHED, + jobStatus: 'COMPLETED', + humanInterventionsAfterSeal: 0, + humanAuthorityEscalations: 0, + humanAuthorityEscalationsAfterSeal: 0, + boundaryStartedAt: CREATED, + autonomousRecoveryCount: 0, + providerFailovers: 0, + providerFailures: 0, + quotaWaits: 1, + contextRollovers: 0, + toolsmithActions: 0, + selfCreatedTools: 0, + toolchainRepairs: 0, + environmentRepairs: 0, + controlPlaneRepairs: 0, + gapClosureCycles: 0, + systemQualificationCycles: 0, + browserScenariosRun: 0, + uxCritiquesRun: 0, + driverRestarts: 0, + supervisorWakeups: 1, + elapsedWallTimeMs: 10_800_000, + reportedTokens: null, + reportedCostUsd: null, + contractClosureRatio: null, + }), + closure: closureLedgerSchema.parse({ + schemaVersion: '1.0.0', + jobId: 'job-phase-9', + sealId: 'seal-phase-9', + missionId: 'mission-phase-9', + createdAt: CREATED, + updatedAt: FINISHED, + phase: 'COMPLETE', + entries: [{ + itemId: 'CTR-001/R1', + kind: 'requirement', + statement: 'The qualification fixture completes correctly.', + status: 'VERIFIED', + evidence: [{ + kind: 'TRUSTED_VERIFICATION', + ref: 'run-qualified', + passed: true, + recordedAt: FINISHED, + }], + updatedAt: FINISHED, + }], + reproducibilityPassed: true, + releaseQualificationPassed: true, + }), + generatedAt: FINISHED, + secondaryBuildStrategy: 'PREFER', + researchStrategy: 'AUTO', + runnerProfiles: ['mock'], + currentAutonomyPolicy: config.autonomy, + closurePolicy: config.autonomy.closure, + }; +} + +describe('Phase 9 execution telemetry qualification', () => { + it('derives the exact mixed-route ratios and excludes Strong evaluators from builder calls', () => { + const report = deriveExecutionTelemetryReport(mixedFacts()); + + expect(executionTelemetryReportSchema.parse(report)).toEqual(report); + expect(report.work.total).toBe(20); + expect(Object.values(report.work.accounting).reduce((sum, value) => sum + value, 0)).toBe(20); + expect(report.work.objectives).toEqual([expect.objectContaining({ + objectiveNodeId: 'node-1', + total: 20, + implementationAttempts: 26, + secondaryAttempts: 16, + strongBuilderAttempts: 10, + })]); + expect(report.secondary.eligibility).toMatchObject({ eligible: 12, ineligible: 8, strongRequired: 8 }); + expect(report.efficiency.strongBuilderAvoidanceRatio).toEqual({ + numerator: 10, + denominator: 12, + value: 10 / 12, + }); + expect(report.secondary.initialSuccessRate.value).toBe(8 / 12); + expect(report.secondary.repairRecoveryRate.value).toBe(2 / 4); + expect(report.secondary.toStrongFallbackRate.value).toBe(2 / 12); + expect(report.strong.builderAttempts).toBe(10); + expect(report.strong.evaluatorAttempts).toBe(1); + expect(report.attempts.uniqueImplementationAttempts).toBe(26); + expect(report.diagnostics.map((entry) => entry.code)).toContain('ATTEMPT_REPLAY_DEDUPLICATED'); + }); + + it('preserves unknown token usage while reporting evaluator coverage separately', () => { + const report = deriveExecutionTelemetryReport(mixedFacts()); + + expect(report.secondary.builderTokens.completeTokens).toBeNull(); + expect(report.secondary.builderTokens.knownTokens).toBeNull(); + expect(report.secondary.builderTokens.coverage.ratio).toBe(0); + expect(report.strong.implementationTokens.completeTokens).toBeNull(); + expect(report.strong.evaluatorTokens).toMatchObject({ + inputTokens: 100, + outputTokens: 20, + completeTokens: 120, + coverage: { ratio: 1, complete: true }, + }); + }); + + it('reports partial provider usage as known components without inventing a complete total', () => { + const facts = mixedFacts(); + const objective = facts.objectives[0]!; + const first = objective.routingStates[0]!; + objective.routingStates = [ + builderRoutingStateSchema.parse({ + ...first, + attempts: [{ ...first.attempts[0]!, inputTokens: 321, outputTokens: null }], + contentHash: sha256Hex('routing-partial-token-coverage'), + }), + ...objective.routingStates.slice(1), + ]; + const report = deriveExecutionTelemetryReport(facts); + + expect(report.secondary.builderTokens).toMatchObject({ + inputTokens: 321, + outputTokens: null, + knownTokens: 321, + completeTokens: null, + coverage: { attempts: 16, withAny: 1, withInput: 1, withOutput: 0, complete: false }, + }); + expect(report.secondary.builderTokens.coverage.ratio).toBe(1 / 16); + }); + + it('uses labeled workspace research aggregates and records cooldown productivity', () => { + const report = deriveExecutionTelemetryReport(mixedFacts()); + + expect(report.research).toMatchObject({ + scope: 'WORKSPACE', + considered: 10, + providerCalls: 2, + successful: 2, + priorResearchReused: 3, + newQuick: 1, + newDeep: 1, + avoidanceRatio: { numerator: 8, denominator: 10, value: 0.8 }, + reuseRate: { numerator: 3, denominator: 5, value: 0.6 }, + usage: { inputTokens: null, outputTokens: null, coverage: 0 }, + }); + expect(report.cooldown.usefulWorkDuringSubscriptionCooldown).toBe(6); + expect(report.research.decisions).toMatchObject({ + ANSWER_DIRECTLY: 4, + ENGINEERING_DECISION: 2, + REUSE_EXISTING: 2, + RESEARCH_QUICK: 1, + RESEARCH_DEEP: 1, + }); + expect(report.qualificationSummary.newResearchCalls).toBe(2); + }); + + it('compares a deterministic Strong-only replay without claiming statistical significance', () => { + const mixed = deriveExecutionTelemetryReport(mixedFacts()); + const strongFacts = mixedFacts(); + const objective = strongFacts.objectives[0]!; + objective.routingStates = Array.from({ length: 20 }, (_, index) => + routing( + index + 1, + index < 12 ? 'ELIGIBLE' : 'STRONG_REQUIRED', + [['STRONG', 'SUCCEEDED']], + )); + const strongOnly = deriveExecutionTelemetryReport(strongFacts); + const comparison = compareExecutionTelemetryReports(strongOnly, mixed); + + expect(comparison).toMatchObject({ + strongBuilderAttempts: { strongOnly: 20, mixed: 10, avoided: 10 }, + secondaryBuilderAttempts: { strongOnly: 0, mixed: 12 }, + acceptanceEqual: true, + verificationEqual: true, + closureEqual: true, + evidenceAvailable: true, + correctnessEqual: true, + qualificationOnly: true, + }); + }); + + it('detects avoidable idle when eligible READY work is ignored during an active cooldown', () => { + const facts = mixedFacts(); + const objective = facts.objectives[0]!; + const firstUnit = objective.graph!.units[0]!; + objective.graph = workGraphSchema.parse({ + ...objective.graph, + units: [ + workUnitSchema.parse({ ...firstUnit, status: 'READY', integratedAt: undefined }), + ...objective.graph!.units.slice(1), + ], + }); + const priorRouting = objective.routingStates.find((entry) => entry.workUnitId === 'wu-1')!; + const idleRouting = builderRoutingStateSchema.parse({ + ...priorRouting, + attempts: [], + repairAttemptsUsed: 0, + escalationStatus: 'NONE', + finalBackend: undefined, + contentHash: sha256Hex('idle-routing'), + }); + objective.routingStates = [ + idleRouting, + ...objective.routingStates.filter((entry) => entry.workUnitId !== 'wu-1'), + ]; + objective.cooldown = objectiveCooldownStateSchema.parse({ + ...objective.cooldown, + status: 'ACTIVE', + currentStartedAt: '2026-08-30T00:30:00.000Z', + lastAvailability: 'COOLDOWN', + completedDuringCooldown: ['wu-2', 'wu-3', 'wu-4', 'wu-5', 'wu-6'], + contentHash: sha256Hex('active-cooldown'), + }); + + const report = deriveExecutionTelemetryReport(facts); + expect(report.cooldown.episodes).toBe(1); + expect(report.cooldown.avoidableIdlePeriods).toBe(1); + expect(report.diagnostics).toContainEqual(expect.objectContaining({ + code: 'AVOIDABLE_IDLE_DURING_COOLDOWN', + severity: 'warning', + })); + }); + + it('separates legitimate authority from a post-seal operational intervention', () => { + const facts = mixedFacts(); + facts.autonomy = autonomyTelemetrySchema.parse({ + ...facts.autonomy, + humanInterventionsAfterSeal: 1, + humanAuthorityEscalations: 1, + humanAuthorityEscalationsAfterSeal: 1, + interventions: [{ + at: '2026-08-30T01:00:00.000Z', + kind: 'job_blocked', + detail: 'manual resume was required', + }], + }); + + const report = deriveExecutionTelemetryReport(facts); + expect(report.human).toMatchObject({ + authorityEscalationsAfterSeal: 1, + interventionsAfterSeal: 1, + zeroTouchAfterSeal: false, + }); + expect(report.reliability.unexpectedBlocks).toBe(1); + }); + + it('reports completed-work redo regressions and candidate reuse independently', () => { + const facts = mixedFacts(); + const objective = facts.objectives[0]!; + objective.graph = workGraphSchema.parse({ + ...objective.graph, + units: objective.graph!.units.map((entry) => + entry.workUnitId === 'wu-1' + ? workUnitSchema.parse({ ...entry, integratedAt: CREATED }) + : entry), + }); + objective.cooldown = objectiveCooldownStateSchema.parse({ + ...objective.cooldown, + candidateReuseAfterRestart: 2, + contentHash: sha256Hex('candidate-reuse'), + }); + + const report = deriveExecutionTelemetryReport(facts); + expect(report.reliability.completedWorkRedoCount).toBe(1); + expect(report.reliability.candidatesReusedAfterRestart).toBe(2); + expect(report.reliability.candidateRebuildsAfterRestart).toBe(0); + expect(report.diagnostics).toContainEqual(expect.objectContaining({ code: 'COMPLETED_WORK_REDONE' })); + }); + + it('keeps quota, environment, verification, and model-output failure sources distinct', () => { + const facts = mixedFacts(); + const template = facts.ledger[0]!; + facts.ledger = ['QUOTA', 'ENVIRONMENT', 'VERIFICATION', 'MODEL_OUTPUT'].map((failureSource, index) => + executionLedgerEntrySchema.parse({ + ...template, + attemptId: `failed-ledger-${index}`, + role: 'EXECUTOR', + status: 'FAILED', + success: false, + failureReason: failureSource.toLowerCase(), + failureSource, + recoveryAction: index === 0 ? 'WAIT_FOR_RESOURCE' : 'RETRY', + })); + + const report = deriveExecutionTelemetryReport(facts); + expect(report.reliability.failureSources).toMatchObject({ + QUOTA: 1, + ENVIRONMENT: 1, + VERIFICATION: 1, + MODEL_OUTPUT: 1, + }); + expect(report.reliability.recoveryActions).toMatchObject({ WAIT_FOR_RESOURCE: 1, RETRY: 3 }); + }); + + it('is deterministic for the same durable facts and emits no credential-shaped content', () => { + const facts = mixedFacts(); + facts.researchTelemetryDiagnostic = + 'provider failed with Authorization: Bearer super-secret-token and api_key=also-secret'; + facts.job.finalOutcome = 'completed after Authorization: Bearer final-outcome-secret'; + const first = deriveExecutionTelemetryReport(facts); + const second = deriveExecutionTelemetryReport(facts); + const serialized = JSON.stringify(first); + + expect(second).toEqual(first); + expect(serialized).not.toContain('super-secret-token'); + expect(serialized).not.toContain('also-secret'); + expect(serialized).not.toContain('final-outcome-secret'); + expect(serialized).toContain('[REDACTED]'); + expect(first.human.zeroTouchAfterSeal).toBe(true); + expect(first.reliability.completedWorkRedoCount).toBe(0); + }); +}); diff --git a/tests/cli/cli-vnext102-reporting.test.ts b/tests/cli/cli-vnext102-reporting.test.ts new file mode 100644 index 0000000..5fa8a72 --- /dev/null +++ b/tests/cli/cli-vnext102-reporting.test.ts @@ -0,0 +1,59 @@ +import { existsSync } from 'node:fs'; +import { describe, expect, it } from 'vitest'; +import { executionTelemetryReportFile } from '@specbridge/autonomy'; +import { createJob } from '@specbridge/orchestration'; +import { runCli } from '../../packages/cli/src/cli'; +import { setupOrchestrationFixture } from '../helpers-orchestration.js'; + +async function cli(cwd: string, ...argv: string[]): Promise<{ + code: number; + stdout: string; + stderr: string; +}> { + const stdout: string[] = []; + const stderr: string[] = []; + const code = await runCli(argv, { + cwd, + out: (line) => stdout.push(`${line}\n`), + outRaw: (value) => stdout.push(value), + err: (line) => stderr.push(`${line}\n`), + }); + return { code, stdout: stdout.join(''), stderr: stderr.join('') }; +} + +describe('specbridge report job', () => { + it('prints versioned JSON without persisting when requested', async () => { + const fixture = setupOrchestrationFixture(); + const job = createJob( + { workspace: fixture.workspace, config: fixture.config, host: 'test' }, + { specName: fixture.specName, goal: 'Inspect telemetry.' }, + ); + const reportFile = executionTelemetryReportFile(fixture.workspace, job.jobId); + + const result = await cli(fixture.root, 'report', 'job', job.jobId, '--json', '--no-persist'); + expect(result.code).toBe(0); + expect(result.stderr).toBe(''); + expect(JSON.parse(result.stdout)).toMatchObject({ + schemaVersion: '1.0.0', + jobId: job.jobId, + outcome: { authoritativeJobStatus: 'CREATED' }, + human: { zeroTouchAfterSeal: true }, + }); + expect(existsSync(reportFile)).toBe(false); + }); + + it('renders a concise report and persists the JSON artifact by default', async () => { + const fixture = setupOrchestrationFixture(); + const job = createJob( + { workspace: fixture.workspace, config: fixture.config, host: 'test' }, + { specName: fixture.specName, goal: 'Persist telemetry.' }, + ); + + const result = await cli(fixture.root, 'report', 'job', job.jobId); + expect(result.code).toBe(0); + expect(result.stdout).toContain(`Job ${job.jobId} — WAITING`); + expect(result.stdout).toContain('StrongBuilderAvoidanceRatio'); + expect(result.stdout).toContain('Report: .specbridge/reports/'); + expect(existsSync(executionTelemetryReportFile(fixture.workspace, job.jobId))).toBe(true); + }); +}); diff --git a/tests/contracts/public-contracts.test.ts b/tests/contracts/public-contracts.test.ts index fe726ec..829dc26 100644 --- a/tests/contracts/public-contracts.test.ts +++ b/tests/contracts/public-contracts.test.ts @@ -166,6 +166,8 @@ describe('public contract snapshots', () => { for (const name of RESEARCH_ADDITIONS) expect(tools).toContain(name); const RESEARCH_LIFECYCLE_ADDITIONS = ['research_consider', 'prepare_intake_decision']; for (const name of RESEARCH_LIFECYCLE_ADDITIONS) expect(tools).toContain(name); + const TELEMETRY_ADDITIONS = ['job_report']; + for (const name of TELEMETRY_ADDITIONS) expect(tools).toContain(name); expect(tools).not.toContain('research_approve'); expect(tools).not.toContain('research_apply_contract'); expect(tools).not.toContain('research_complete_task'); @@ -178,10 +180,11 @@ describe('public contract snapshots', () => { !INTAKE_ADDITIONS.includes(name) && !BOOTSTRAP_ADDITIONS.includes(name) && !RESEARCH_ADDITIONS.includes(name) && - !RESEARCH_LIFECYCLE_ADDITIONS.includes(name), + !RESEARCH_LIFECYCLE_ADDITIONS.includes(name) && + !TELEMETRY_ADDITIONS.includes(name), ), ).toHaveLength(37); - expect(tools).toHaveLength(77); + expect(tools).toHaveLength(78); // No approval tool, no shell, no filesystem, no git — at any version. for (const forbidden of tools) { expect(forbidden).not.toMatch(/^(.*_approve|.*_shell|.*_exec|.*_git|.*_write_file)$/); diff --git a/tests/mcp/mcp-job-tools.test.ts b/tests/mcp/mcp-job-tools.test.ts index 64998ae..46b9c1e 100644 --- a/tests/mcp/mcp-job-tools.test.ts +++ b/tests/mcp/mcp-job-tools.test.ts @@ -1,4 +1,7 @@ +import { existsSync, mkdirSync, writeFileSync } from 'node:fs'; +import path from 'node:path'; import { describe, expect, it } from 'vitest'; +import { executionTelemetryReportFile } from '@specbridge/autonomy'; import { buildJobGraph, createJob, requireJobState } from '@specbridge/orchestration'; import { setupOrchestrationFixture } from '../helpers-orchestration.js'; import type { OrchestrationFixture } from '../helpers-orchestration.js'; @@ -59,6 +62,31 @@ describe('job_list / job_read / job_cancel', () => { } }); + it('derives a versioned job report without persisting or changing job state', async () => { + const fixture = await fixtureWithJob(); + const before = requireJobState(fixture.workspace, fixture.jobId); + const reportFile = executionTelemetryReportFile(fixture.workspace, fixture.jobId); + const researchDir = path.join(fixture.root, '.specbridge', 'research'); + mkdirSync(researchDir, { recursive: true }); + writeFileSync(path.join(researchDir, 'telemetry.json'), '{corrupt', 'utf8'); + const session = await connectMcp(fixture.root); + try { + const result = await callTool(session, 'job_report', { jobId: fixture.jobId }); + expect(result.isError).toBe(false); + expect(result.structured['report']).toMatchObject({ + schemaVersion: '1.0.0', + jobId: fixture.jobId, + outcome: { authoritativeJobStatus: 'READY' }, + }); + expect((result.structured['report'] as { diagnostics: { code: string }[] }).diagnostics) + .toContainEqual(expect.objectContaining({ code: 'RESEARCH_TELEMETRY_UNREADABLE' })); + expect(existsSync(reportFile)).toBe(false); + expect(requireJobState(fixture.workspace, fixture.jobId)).toEqual(before); + } finally { + await session.close(); + } + }); + it('job_cancel finalizes idempotently and reports honestly', async () => { const fixture = await fixtureWithJob(); const session = await connectMcp(fixture.root); @@ -84,7 +112,12 @@ describe('job_list / job_read / job_cancel', () => { try { const tools = await session.client.listTools(); const jobTools = tools.tools.filter((tool) => tool.name.startsWith('job_')); - expect(jobTools.map((tool) => tool.name).sort()).toEqual(['job_cancel', 'job_list', 'job_read']); + expect(jobTools.map((tool) => tool.name).sort()).toEqual([ + 'job_cancel', + 'job_list', + 'job_read', + 'job_report', + ]); // Nothing exposes dispatch, review, approval, or completion for jobs. expect(tools.tools.some((tool) => /job_(run|step|dispatch|approve|review|complete)/.test(tool.name))).toBe( false,