audit-tools 0.32.19 → 0.32.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. package/dist/audit/clarification/blastRadius.d.ts +23 -0
  2. package/dist/audit/clarification/blastRadius.d.ts.map +1 -0
  3. package/dist/audit/clarification/blastRadius.js +65 -0
  4. package/dist/audit/clarification/blastRadius.js.map +1 -0
  5. package/dist/audit/clarification/dials.d.ts +28 -0
  6. package/dist/audit/clarification/dials.d.ts.map +1 -0
  7. package/dist/audit/clarification/dials.js +37 -0
  8. package/dist/audit/clarification/dials.js.map +1 -0
  9. package/dist/audit/clarification/partition.d.ts +25 -0
  10. package/dist/audit/clarification/partition.d.ts.map +1 -0
  11. package/dist/audit/clarification/partition.js +77 -0
  12. package/dist/audit/clarification/partition.js.map +1 -0
  13. package/dist/audit/clarification/riskGate.d.ts +24 -0
  14. package/dist/audit/clarification/riskGate.d.ts.map +1 -0
  15. package/dist/audit/clarification/riskGate.js +38 -0
  16. package/dist/audit/clarification/riskGate.js.map +1 -0
  17. package/dist/audit/clarification/voiQueue.d.ts +17 -0
  18. package/dist/audit/clarification/voiQueue.d.ts.map +1 -0
  19. package/dist/audit/clarification/voiQueue.js +37 -0
  20. package/dist/audit/clarification/voiQueue.js.map +1 -0
  21. package/dist/audit/cli/auditStep.d.ts +2 -0
  22. package/dist/audit/cli/auditStep.d.ts.map +1 -1
  23. package/dist/audit/cli/auditStep.js +9 -1
  24. package/dist/audit/cli/auditStep.js.map +1 -1
  25. package/dist/audit/cli/charterClarificationPrompt.d.ts +19 -0
  26. package/dist/audit/cli/charterClarificationPrompt.d.ts.map +1 -0
  27. package/dist/audit/cli/charterClarificationPrompt.js +60 -0
  28. package/dist/audit/cli/charterClarificationPrompt.js.map +1 -0
  29. package/dist/audit/cli/nextStepCommand.d.ts.map +1 -1
  30. package/dist/audit/cli/nextStepCommand.js +74 -0
  31. package/dist/audit/cli/nextStepCommand.js.map +1 -1
  32. package/dist/audit/cli/nextStepHelpers.d.ts +62 -0
  33. package/dist/audit/cli/nextStepHelpers.d.ts.map +1 -1
  34. package/dist/audit/cli/nextStepHelpers.js +129 -0
  35. package/dist/audit/cli/nextStepHelpers.js.map +1 -1
  36. package/dist/audit/cli/steps.d.ts +4 -4
  37. package/dist/audit/cli/steps.d.ts.map +1 -1
  38. package/dist/audit/cli/steps.js +2 -0
  39. package/dist/audit/cli/steps.js.map +1 -1
  40. package/dist/audit/io/artifacts.d.ts +6 -0
  41. package/dist/audit/io/artifacts.d.ts.map +1 -1
  42. package/dist/audit/io/artifacts.js +2 -0
  43. package/dist/audit/io/artifacts.js.map +1 -1
  44. package/dist/audit/orchestrator/advance.d.ts +23 -0
  45. package/dist/audit/orchestrator/advance.d.ts.map +1 -1
  46. package/dist/audit/orchestrator/advance.js +122 -4
  47. package/dist/audit/orchestrator/advance.js.map +1 -1
  48. package/dist/audit/orchestrator/advanceTypes.d.ts +22 -1
  49. package/dist/audit/orchestrator/advanceTypes.d.ts.map +1 -1
  50. package/dist/audit/orchestrator/charterClarificationExecutor.d.ts +28 -0
  51. package/dist/audit/orchestrator/charterClarificationExecutor.d.ts.map +1 -0
  52. package/dist/audit/orchestrator/charterClarificationExecutor.js +130 -0
  53. package/dist/audit/orchestrator/charterClarificationExecutor.js.map +1 -0
  54. package/dist/audit/orchestrator/dependencyMap.d.ts +2 -0
  55. package/dist/audit/orchestrator/dependencyMap.d.ts.map +1 -1
  56. package/dist/audit/orchestrator/dependencyMap.js +24 -0
  57. package/dist/audit/orchestrator/dependencyMap.js.map +1 -1
  58. package/dist/audit/orchestrator/designReviewPrompt.d.ts +17 -0
  59. package/dist/audit/orchestrator/designReviewPrompt.d.ts.map +1 -1
  60. package/dist/audit/orchestrator/designReviewPrompt.js +50 -0
  61. package/dist/audit/orchestrator/designReviewPrompt.js.map +1 -1
  62. package/dist/audit/orchestrator/executorRunners.d.ts.map +1 -1
  63. package/dist/audit/orchestrator/executorRunners.js +4 -0
  64. package/dist/audit/orchestrator/executorRunners.js.map +1 -1
  65. package/dist/audit/orchestrator/executors.d.ts.map +1 -1
  66. package/dist/audit/orchestrator/executors.js +20 -0
  67. package/dist/audit/orchestrator/executors.js.map +1 -1
  68. package/dist/audit/orchestrator/nextStep.d.ts +11 -1
  69. package/dist/audit/orchestrator/nextStep.d.ts.map +1 -1
  70. package/dist/audit/orchestrator/nextStep.js +6 -2
  71. package/dist/audit/orchestrator/nextStep.js.map +1 -1
  72. package/dist/audit/orchestrator/staleness.d.ts +27 -1
  73. package/dist/audit/orchestrator/staleness.d.ts.map +1 -1
  74. package/dist/audit/orchestrator/staleness.js +33 -16
  75. package/dist/audit/orchestrator/staleness.js.map +1 -1
  76. package/dist/audit/orchestrator/state.d.ts +12 -1
  77. package/dist/audit/orchestrator/state.d.ts.map +1 -1
  78. package/dist/audit/orchestrator/state.js +41 -2
  79. package/dist/audit/orchestrator/state.js.map +1 -1
  80. package/dist/audit/orchestrator/synthesisExecutors.d.ts.map +1 -1
  81. package/dist/audit/orchestrator/synthesisExecutors.js +1 -0
  82. package/dist/audit/orchestrator/synthesisExecutors.js.map +1 -1
  83. package/dist/audit/orchestrator/systemicChallengeExecutor.d.ts +25 -0
  84. package/dist/audit/orchestrator/systemicChallengeExecutor.d.ts.map +1 -0
  85. package/dist/audit/orchestrator/systemicChallengeExecutor.js +107 -0
  86. package/dist/audit/orchestrator/systemicChallengeExecutor.js.map +1 -0
  87. package/dist/audit/reporting/mergeFindings.d.ts +2 -1
  88. package/dist/audit/reporting/mergeFindings.d.ts.map +1 -1
  89. package/dist/audit/reporting/mergeFindings.js +6 -1
  90. package/dist/audit/reporting/mergeFindings.js.map +1 -1
  91. package/dist/audit/reporting/synthesis.d.ts +2 -0
  92. package/dist/audit/reporting/synthesis.d.ts.map +1 -1
  93. package/dist/audit/reporting/synthesis.js +1 -1
  94. package/dist/audit/reporting/synthesis.js.map +1 -1
  95. package/dist/audit/systemic/aggregateMetricsDigest.d.ts +11 -0
  96. package/dist/audit/systemic/aggregateMetricsDigest.d.ts.map +1 -0
  97. package/dist/audit/systemic/aggregateMetricsDigest.js +84 -0
  98. package/dist/audit/systemic/aggregateMetricsDigest.js.map +1 -0
  99. package/dist/audit/systemic/metricsDigestTypes.d.ts +35 -0
  100. package/dist/audit/systemic/metricsDigestTypes.d.ts.map +1 -0
  101. package/dist/audit/systemic/metricsDigestTypes.js +10 -0
  102. package/dist/audit/systemic/metricsDigestTypes.js.map +1 -0
  103. package/dist/audit/systemic/secondOrderAdversaryPrompt.d.ts +16 -0
  104. package/dist/audit/systemic/secondOrderAdversaryPrompt.d.ts.map +1 -0
  105. package/dist/audit/systemic/secondOrderAdversaryPrompt.js +85 -0
  106. package/dist/audit/systemic/secondOrderAdversaryPrompt.js.map +1 -0
  107. package/dist/audit/systemic/systemicChallengeLoop.d.ts +48 -0
  108. package/dist/audit/systemic/systemicChallengeLoop.d.ts.map +1 -0
  109. package/dist/audit/systemic/systemicChallengeLoop.js +107 -0
  110. package/dist/audit/systemic/systemicChallengeLoop.js.map +1 -0
  111. package/dist/audit/types/charterClarification.d.ts +52 -0
  112. package/dist/audit/types/charterClarification.d.ts.map +1 -0
  113. package/dist/audit/types/charterClarification.js +2 -0
  114. package/dist/audit/types/charterClarification.js.map +1 -0
  115. package/dist/audit/types/systemicChallenge.d.ts +69 -0
  116. package/dist/audit/types/systemicChallenge.d.ts.map +1 -0
  117. package/dist/audit/types/systemicChallenge.js +2 -0
  118. package/dist/audit/types/systemicChallenge.js.map +1 -0
  119. package/dist/remediate/phases/triage.d.ts.map +1 -1
  120. package/dist/remediate/phases/triage.js +16 -1
  121. package/dist/remediate/phases/triage.js.map +1 -1
  122. package/dist/remediate/steps/dispatch/acceptNode.d.ts +178 -0
  123. package/dist/remediate/steps/dispatch/acceptNode.d.ts.map +1 -0
  124. package/dist/remediate/steps/dispatch/acceptNode.js +351 -0
  125. package/dist/remediate/steps/dispatch/acceptNode.js.map +1 -0
  126. package/dist/remediate/steps/dispatch/common.d.ts +123 -0
  127. package/dist/remediate/steps/dispatch/common.d.ts.map +1 -0
  128. package/dist/remediate/steps/dispatch/common.js +236 -0
  129. package/dist/remediate/steps/dispatch/common.js.map +1 -0
  130. package/dist/remediate/steps/dispatch/dagNodeFields.d.ts +37 -0
  131. package/dist/remediate/steps/dispatch/dagNodeFields.d.ts.map +1 -0
  132. package/dist/remediate/steps/dispatch/dagNodeFields.js +19 -0
  133. package/dist/remediate/steps/dispatch/dagNodeFields.js.map +1 -0
  134. package/dist/remediate/steps/dispatch/implementPrompt.d.ts +70 -0
  135. package/dist/remediate/steps/dispatch/implementPrompt.d.ts.map +1 -0
  136. package/dist/remediate/steps/dispatch/implementPrompt.js +577 -0
  137. package/dist/remediate/steps/dispatch/implementPrompt.js.map +1 -0
  138. package/dist/remediate/steps/dispatch/marshal.d.ts +32 -0
  139. package/dist/remediate/steps/dispatch/marshal.d.ts.map +1 -0
  140. package/dist/remediate/steps/dispatch/marshal.js +935 -0
  141. package/dist/remediate/steps/dispatch/marshal.js.map +1 -0
  142. package/dist/remediate/steps/dispatch/verifyCommands.d.ts +97 -0
  143. package/dist/remediate/steps/dispatch/verifyCommands.d.ts.map +1 -0
  144. package/dist/remediate/steps/dispatch/verifyCommands.js +204 -0
  145. package/dist/remediate/steps/dispatch/verifyCommands.js.map +1 -0
  146. package/dist/remediate/steps/dispatch/waveScheduling.d.ts +90 -0
  147. package/dist/remediate/steps/dispatch/waveScheduling.d.ts.map +1 -0
  148. package/dist/remediate/steps/dispatch/waveScheduling.js +352 -0
  149. package/dist/remediate/steps/dispatch/waveScheduling.js.map +1 -0
  150. package/dist/remediate/steps/dispatch/worktreeLifecycle.d.ts +189 -0
  151. package/dist/remediate/steps/dispatch/worktreeLifecycle.d.ts.map +1 -0
  152. package/dist/remediate/steps/dispatch/worktreeLifecycle.js +643 -0
  153. package/dist/remediate/steps/dispatch/worktreeLifecycle.js.map +1 -0
  154. package/dist/remediate/steps/dispatch/writeScope.d.ts +151 -0
  155. package/dist/remediate/steps/dispatch/writeScope.d.ts.map +1 -0
  156. package/dist/remediate/steps/dispatch/writeScope.js +376 -0
  157. package/dist/remediate/steps/dispatch/writeScope.js.map +1 -0
  158. package/dist/remediate/steps/dispatch.d.ts +16 -863
  159. package/dist/remediate/steps/dispatch.d.ts.map +1 -1
  160. package/dist/remediate/steps/dispatch.js +18 -3613
  161. package/dist/remediate/steps/dispatch.js.map +1 -1
  162. package/dist/shared/decompose/charterClarification.d.ts +80 -0
  163. package/dist/shared/decompose/charterClarification.d.ts.map +1 -0
  164. package/dist/shared/decompose/charterClarification.js +105 -0
  165. package/dist/shared/decompose/charterClarification.js.map +1 -0
  166. package/dist/shared/decompose/systemicChallenge.d.ts +326 -0
  167. package/dist/shared/decompose/systemicChallenge.d.ts.map +1 -0
  168. package/dist/shared/decompose/systemicChallenge.js +30 -0
  169. package/dist/shared/decompose/systemicChallenge.js.map +1 -0
  170. package/dist/shared/index.d.ts +10 -5
  171. package/dist/shared/index.d.ts.map +1 -1
  172. package/dist/shared/index.js +6 -4
  173. package/dist/shared/index.js.map +1 -1
  174. package/dist/shared/opencodePermissions.d.ts +73 -0
  175. package/dist/shared/opencodePermissions.d.ts.map +1 -1
  176. package/dist/shared/opencodePermissions.js +172 -0
  177. package/dist/shared/opencodePermissions.js.map +1 -1
  178. package/dist/shared/tooling/exec.d.ts +10 -1
  179. package/dist/shared/tooling/exec.d.ts.map +1 -1
  180. package/dist/shared/tooling/exec.js +13 -1
  181. package/dist/shared/tooling/exec.js.map +1 -1
  182. package/dist/shared/types/charter.d.ts +89 -0
  183. package/dist/shared/types/charter.d.ts.map +1 -1
  184. package/dist/shared/types/charter.js +68 -0
  185. package/dist/shared/types/charter.js.map +1 -1
  186. package/dist/shared/types/intentCheckpoint.d.ts +15 -0
  187. package/dist/shared/types/intentCheckpoint.d.ts.map +1 -1
  188. package/dist/shared/types/intentCheckpoint.js +11 -0
  189. package/dist/shared/types/intentCheckpoint.js.map +1 -1
  190. package/dist/shared/validation/charterGate.d.ts +20 -1
  191. package/dist/shared/validation/charterGate.d.ts.map +1 -1
  192. package/dist/shared/validation/charterGate.js +23 -0
  193. package/dist/shared/validation/charterGate.js.map +1 -1
  194. package/docs/audit-pkg/contracts.md +1 -1
  195. package/docs/audit-pkg/development.md +8 -7
  196. package/docs/audit-pkg/product.md +7 -4
  197. package/docs/audit-pkg/release.md +4 -2
  198. package/opencode.json +36 -20
  199. package/package.json +1 -1
  200. package/scripts/postinstall.mjs +2 -1
  201. package/wrapper/audit-code-wrapper-opencode.mjs +38 -12
  202. package/wrapper/remediate-code-wrapper-opencode.mjs +38 -12
@@ -0,0 +1,351 @@
1
+ import { join } from "node:path";
2
+ import { spawnSyncHidden } from "audit-tools/shared";
3
+ import { withFileLock } from "audit-tools/shared";
4
+ import { runCommand } from "../../utils/commands.js";
5
+ import { mergedBaseCheckArgv } from "../gateCommands.js";
6
+ import { writeJsonFile, readOptionalJsonFile } from "audit-tools/shared";
7
+ import { runDir, worktreeBranchForBlock, gitEditedFilesForBranch, } from "./common.js";
8
+ import { removeWorktree, commitWorktree, quarantineUncommittedWorktreeEdits, quarantineFailedNodeCommit, clearQuarantinedCommit, rebaseBranchOntoHead, dirtyMainTreeCollisions, mergeWorktree, baseBranchLockPath, resetNodeWorktreeAndBranch, createWorktree, seedUntrackedDeclaredPaths, worktreePath, verifyNodeInWorktree, } from "./worktreeLifecycle.js";
9
+ import { deriveVerifyCommandsFromBranch, selfContainedVerifyCommands, buildFreeVerifyCommands, } from "./verifyCommands.js";
10
+ import { enforceAcceptWriteScope } from "./writeScope.js";
11
+ /**
12
+ * The shared post-worker "accept node" lifecycle, extracted so BOTH rolling
13
+ * drivers reuse identical correctness: the in-process provider engine
14
+ * (`driveRollingImplementDispatch`) calls it inline once the worker returns; the
15
+ * host-subagent driver calls it from the `accept-node` callback once a host
16
+ * subagent finishes.
17
+ *
18
+ * Given a completed worker run in an isolated worktree, this: (1) TOOL-commits
19
+ * the worker's edits onto the branch (deterministic, never the worker/host) so
20
+ * the branch diff is the write-scope ground truth; (2) runs the per-node verify
21
+ * IN the worktree BEFORE accepting; (3) merges via cherry-pick only on a passing
22
+ * verify; and (4) drops the worktree on any failure so the main tree is never
23
+ * dirtied by an unverified change. It returns the LIFECYCLE outcome (which the
24
+ * caller records for the deterministic merge); the caller still returns the
25
+ * worker's TRANSPORT outcome to the rolling engine (so a `rate_limited` worker
26
+ * re-queues, while a verify-failure is adjudicated by the merge → triage).
27
+ *
28
+ * SAFETY: the main tree is touched only through `mergeWorktree` (cherry-pick of a
29
+ * verified branch, aborts cleanly on conflict). No state mutation here — the
30
+ * caller persists via `mergeImplementResults`.
31
+ */
32
+ export async function acceptNodeWorktree(params) {
33
+ const { root, runId, blockId, worktreeRoot: wt, branch, workerOutcome, targetedCommands, additionalVerifyCommands } = params;
34
+ let verifyPassed = false;
35
+ let merged = false;
36
+ if (workerOutcome === "rate_limited") {
37
+ // Piece D — quota-death worktree preservation: a worker that died on a host
38
+ // session-limit is a RETRYABLE pause, not a failure. Leave its worktree INTACT
39
+ // (do NOT removeWorktree) so nothing is destroyed during the pause; the node
40
+ // redoes clean on resume (the re-entry `resetNodeWorktreeAndBranch` handles the
41
+ // clean redo). Nothing to land now — return the outcome so the rolling engine
42
+ // records the pause + strands the node pending.
43
+ return { outcome: workerOutcome, verifyPassed, merged };
44
+ }
45
+ if (workerOutcome !== "success") {
46
+ // Real worker failure (error / timeout): nothing to land; drop the worktree so
47
+ // the main tree is never dirtied by an unverified change, preserve the outcome.
48
+ removeWorktree(root, wt);
49
+ return { outcome: workerOutcome, verifyPassed, merged };
50
+ }
51
+ const commit = commitWorktree(wt, `remediate ${blockId} (${runId})`, params.writePaths);
52
+ if (commit.error) {
53
+ // Could not commit the worker's edits (e.g. a generated-artifact-under-scope
54
+ // fail-loud) → cannot safely LAND it, but the worker's real source edits are
55
+ // still uncommitted in the worktree. Preserve them under a durable quarantine
56
+ // ref BEFORE removing the worktree (P0 data-loss: a guard must not destroy the
57
+ // good work alongside the offending artifact), mirroring the verify/scope/
58
+ // merge-fail quarantine paths below.
59
+ quarantineUncommittedWorktreeEdits(root, wt, branch, runId, blockId);
60
+ removeWorktree(root, wt);
61
+ return { outcome: "error", verifyPassed, merged, diagnostic: commit.error };
62
+ }
63
+ if (!commit.committed) {
64
+ // Worker reported success but made no tracked edits — nothing to verify or merge.
65
+ // The deterministic merge adjudicates the result file (resolved_no_change needs evidence).
66
+ removeWorktree(root, wt);
67
+ return { outcome: "success", verifyPassed, merged };
68
+ }
69
+ // Base-mutating critical section (INV-2/INV-3/CE-001/CE-002/CE-005) under a DISTINCT
70
+ // base-branch lock — NOT the per-run rolling-session.lock `advanceHostRolling` holds
71
+ // (withFileLock is non-reentrant, so a same-path nested acquire would self-deadlock).
72
+ // Acquired exactly ONCE here so BOTH rolling drivers serialize the rebase →
73
+ // cherry-pick → cross-package check → reset sequence through one lock. The base HEAD
74
+ // OID is captured before the cherry-pick so a RED merged-base check rolls the base
75
+ // back bit-identically. The lock is released on EVERY exit path (success, verify
76
+ // fail, scope fail, check fail, subprocess fail) by withFileLock's finally.
77
+ return withFileLock(baseBranchLockPath(root, runId), async () => {
78
+ // Rebase the node's branch onto the current remediation HEAD BEFORE verify, so a
79
+ // sibling that merged after this worktree was created is folded in. Verify, the
80
+ // write-scope gate, and the cherry-pick then all operate on the FINAL to-be-merged
81
+ // content (green-at-merge; the later cherry-pick can no longer conflict). A true
82
+ // hunk conflict here is a genuine seam — preserve the work and route to triage
83
+ // rather than land a broken merge.
84
+ const rebase = rebaseBranchOntoHead(root, wt, branch);
85
+ if (!rebase.ok) {
86
+ quarantineFailedNodeCommit(root, branch, runId, blockId);
87
+ removeWorktree(root, wt);
88
+ return { outcome: "error", verifyPassed, merged, diagnostic: rebase.error };
89
+ }
90
+ // Pre-flight: a dirty tracked file in the MAIN checkout that collides with a
91
+ // path this node edits makes the later cherry-pick abort with an opaque
92
+ // "local changes would be overwritten by merge" — a condition the node cannot
93
+ // fix and that re-fails identically on every auto-retry. Detect it up front
94
+ // (before the expensive verify) and surface the actionable cause; preserve the
95
+ // committed work under quarantine like every sibling error path so nothing is
96
+ // lost while the host commits/stashes the unrelated WIP.
97
+ const collisions = dirtyMainTreeCollisions(root, branch);
98
+ if (collisions.length > 0) {
99
+ quarantineFailedNodeCommit(root, branch, runId, blockId);
100
+ removeWorktree(root, wt);
101
+ const paths = collisions.map((c) => `\`${c}\``).join(", ");
102
+ const it = collisions.length > 1 ? "them" : "it";
103
+ return {
104
+ outcome: "error",
105
+ verifyPassed,
106
+ merged,
107
+ diagnostic: `main tree has uncommitted changes to ${paths} — commit or stash ${it} ` +
108
+ `before merging this node (the cherry-pick would otherwise abort with ` +
109
+ `"local changes would be overwritten by merge"). This is unrelated to the ` +
110
+ `node's own fix; the node's work is preserved under its quarantine ref.`,
111
+ };
112
+ }
113
+ // Verify commands: when the host omits them (real rolling drivers), DERIVE them
114
+ // from the just-committed branch's touched test files — correct paths/runner by
115
+ // construction, only this node's own tests, never the whole suite. An explicit
116
+ // list (or `[]` to skip) overrides; both used by lifecycle unit tests. task_7d35176d:
117
+ // run the derive AND the node's own build-free `targeted_commands` (deduped) — the
118
+ // auditor's fix-specific regression checks the derive misses when a fix touches no
119
+ // test. `additionalVerifyCommands` is ignored on the explicit-override path.
120
+ const baseCommands = targetedCommands === undefined
121
+ ? deriveVerifyCommandsFromBranch(root, branch)
122
+ : targetedCommands;
123
+ let verifyCommands;
124
+ if (targetedCommands === undefined) {
125
+ // Self-contained per-node verify (2026-07-03): the derived `baseCommands` come
126
+ // from this node's ACTUAL branch edits (self-contained by construction), but the
127
+ // node's host/auditor-authored `additionalVerifyCommands` can reference a sibling
128
+ // node's not-yet-created deliverable → a guaranteed-fail deadlock. Drop any such
129
+ // cross-node command (deferred to the integration/close gate). Own paths = the
130
+ // node's declared write set ∪ the files it actually edited on its branch.
131
+ const edited = gitEditedFilesForBranch(root, branch);
132
+ const ownPaths = [
133
+ ...(params.writePaths ?? []),
134
+ ...(edited.available ? edited.files : []),
135
+ ];
136
+ const additional = selfContainedVerifyCommands(buildFreeVerifyCommands(additionalVerifyCommands), ownPaths, wt);
137
+ verifyCommands = [...new Set([...baseCommands, ...additional])];
138
+ }
139
+ else {
140
+ verifyCommands = baseCommands;
141
+ }
142
+ const verify = verifyCommands.length > 0
143
+ ? verifyNodeInWorktree(wt, verifyCommands)
144
+ : { passed: true, output: "" };
145
+ verifyPassed = verify.passed;
146
+ if (!verify.passed) {
147
+ // Verify failed: do not merge; drop the worktree so the main tree stays clean.
148
+ // The node DID commit real edits, so preserve them under a durable quarantine
149
+ // ref before the worktree/branch go away — a tool-verify false-negative must
150
+ // not destroy a good fix (the dogfood lost one this way). Carry the failing
151
+ // command + output so triage isn't blind on outcome:error.
152
+ quarantineFailedNodeCommit(root, branch, runId, blockId);
153
+ removeWorktree(root, wt);
154
+ return { outcome: "error", verifyPassed, merged, diagnostic: verify.output };
155
+ }
156
+ // Write-scope gate (OBL-DS-06), BEFORE the cherry-pick: an out-of-scope or
157
+ // seam-conflicting edit must never land in the main tree, so it is adjudicated
158
+ // against the branch's git diff (the ground truth) here rather than reported
159
+ // after `mergeWorktree` already merged it. The gate routes the node's ACTUAL
160
+ // out-of-declared edits (git diff, never a self-report): an edit to a file no
161
+ // sibling block owns widens the effective scope, while one owned by another
162
+ // block blocks as a seam conflict.
163
+ const decision = enforceAcceptWriteScope({
164
+ root,
165
+ branch,
166
+ blockId,
167
+ allBlockScopes: params.scope.allBlockScopes,
168
+ });
169
+ if (decision.blocked) {
170
+ // Scope-blocked but the node committed real work — preserve it for recovery.
171
+ quarantineFailedNodeCommit(root, branch, runId, blockId);
172
+ removeWorktree(root, wt);
173
+ return { outcome: "error", verifyPassed, merged: false, diagnostic: decision.reason };
174
+ }
175
+ // Capture the base HEAD OID BEFORE the cherry-pick so a RED merged-base check can
176
+ // roll the base back to a bit-identical state.
177
+ const baseHeadBefore = spawnSyncHidden("git", ["rev-parse", "HEAD"], {
178
+ cwd: root,
179
+ encoding: "utf8",
180
+ shell: false,
181
+ });
182
+ if (baseHeadBefore.error || baseHeadBefore.status !== 0) {
183
+ quarantineFailedNodeCommit(root, branch, runId, blockId);
184
+ removeWorktree(root, wt);
185
+ return {
186
+ outcome: "error",
187
+ verifyPassed,
188
+ merged,
189
+ diagnostic: `could not capture base HEAD before merge: ${(baseHeadBefore.stderr ?? baseHeadBefore.error?.message ?? "").toString().trim()}`,
190
+ };
191
+ }
192
+ const baseOid = baseHeadBefore.stdout.trim();
193
+ // mergeWorktree cherry-picks the verified branch and removes the worktree (on
194
+ // success AND on conflict-abort), so no explicit cleanup is needed afterwards.
195
+ const mergeRes = mergeWorktree(root, wt, branch);
196
+ merged = mergeRes.success;
197
+ if (!mergeRes.success) {
198
+ // Cherry-pick conflict: the committed work would otherwise be orphaned — preserve it.
199
+ quarantineFailedNodeCommit(root, branch, runId, blockId);
200
+ return { outcome: "error", verifyPassed, merged, diagnostic: mergeRes.error };
201
+ }
202
+ // Merged-base-green (INV-2): the cherry-pick landed in the MAIN checkout, where
203
+ // node_modules is faithful (the worktree's @audit-tools junction resolves to main
204
+ // and is unfaithful, so the per-node worktree verify cannot catch a cross-package
205
+ // break). Run the REAL cross-package check in the main tree. On RED, roll the base
206
+ // back to its captured OID bit-identically, scoped-clean the cherry-pick's emitted
207
+ // untracked files, quarantine, and fail — never leave a broken base for the sibling.
208
+ const checkArgv = params.mergedBaseCheckCommand === undefined
209
+ ? mergedBaseCheckArgv(root)
210
+ : params.mergedBaseCheckCommand;
211
+ if (checkArgv !== null) {
212
+ // Paths the just-landed pick touched, so the scoped clean nukes only those
213
+ // (never unrelated untracked state). Resolved BEFORE the check runs.
214
+ const pickedFiles = gitEditedFilesForBranch(root, branch);
215
+ // argv via runCommand → runTracked scrubs CLAUDECODE / CLAUDE_CODE_* and applies
216
+ // the shared Windows `.cmd` wrapping — never `shell: true`.
217
+ const [checkCmd, ...checkArgs] = checkArgv;
218
+ const check = runCommand(checkCmd, checkArgs, { cwd: root, encoding: "utf8" });
219
+ const checkFailed = !!check.error || check.status !== 0;
220
+ if (checkFailed) {
221
+ const detail = check.error
222
+ ? check.error.message
223
+ : [check.stdout ?? "", check.stderr ?? ""].filter(Boolean).join("\n");
224
+ // Roll the base back to its pre-pick OID, bit-identical.
225
+ spawnSyncHidden("git", ["reset", "--hard", baseOid], { cwd: root, shell: false });
226
+ // Scoped clean: remove only the cherry-pick / check-emitted untracked files
227
+ // under the paths the pick touched — never a blanket `git clean` that could
228
+ // nuke unrelated untracked state.
229
+ if (pickedFiles.available && pickedFiles.files.size > 0) {
230
+ spawnSyncHidden("git", ["clean", "-fdq", "--", ...[...pickedFiles.files]], { cwd: root, shell: false });
231
+ }
232
+ quarantineFailedNodeCommit(root, branch, runId, blockId);
233
+ return {
234
+ outcome: "error",
235
+ verifyPassed,
236
+ merged: false,
237
+ diagnostic: `$ ${checkArgv.join(" ")}\n${detail}`,
238
+ };
239
+ }
240
+ }
241
+ // Landed successfully and the merged base is green: clear any quarantine ref left
242
+ // by a prior failed attempt for this node so the recovery report lists only
243
+ // genuinely-unrecovered work.
244
+ clearQuarantinedCommit(root, runId, blockId);
245
+ return { outcome: "success", verifyPassed, merged };
246
+ });
247
+ }
248
+ /**
249
+ * Sidecar path for a node's tool-owned accept (verify/merge) outcome. Written by
250
+ * BOTH rolling drivers as each node is accepted, read by `mergeImplementResults`.
251
+ * Block ids here follow the same filename-safe convention as the per-node result
252
+ * files in the same dir.
253
+ */
254
+ export function nodeAcceptOutcomePath(artifactsDir, runId, blockId) {
255
+ return join(runDir(artifactsDir, runId, "implement"), `accept-outcome-${blockId}.json`);
256
+ }
257
+ /**
258
+ * Persist a node's `acceptNodeWorktree` lifecycle outcome so finalization can tell
259
+ * a node whose edits actually LANDED (merged) from one that self-reported "resolved"
260
+ * but failed tool-owned verify / merge (OBL-DS-06: never trust the worker's self
261
+ * report). Both rolling drivers (host-subagent `advanceHostRolling` and in-process
262
+ * `driveRollingImplementDispatch`) call this; the interim main-tree path writes none,
263
+ * so the merge-state gate is inert there.
264
+ */
265
+ export async function recordNodeAcceptOutcome(artifactsDir, runId, blockId, result) {
266
+ await writeJsonFile(nodeAcceptOutcomePath(artifactsDir, runId, blockId), {
267
+ schema_version: "remediate-code-implement/node-accept-outcome/v1alpha1",
268
+ block_id: blockId,
269
+ outcome: result.outcome,
270
+ verify_passed: result.verifyPassed,
271
+ merged: result.merged,
272
+ // Only present on a failure outcome; gives triage the failing command + output.
273
+ ...(result.diagnostic !== undefined ? { diagnostic: result.diagnostic } : {}),
274
+ });
275
+ }
276
+ /** Load a node's recorded accept outcome, or null when none was written. */
277
+ export async function loadNodeAcceptOutcome(artifactsDir, runId, blockId) {
278
+ const raw = await readOptionalJsonFile(nodeAcceptOutcomePath(artifactsDir, runId, blockId));
279
+ if (!raw)
280
+ return null;
281
+ return {
282
+ outcome: raw.outcome,
283
+ verifyPassed: raw.verify_passed,
284
+ merged: raw.merged,
285
+ ...(raw.diagnostic !== undefined ? { diagnostic: raw.diagnostic } : {}),
286
+ };
287
+ }
288
+ /**
289
+ * Run ONE node's full in-process lifecycle in an isolated worktree — shared by BOTH
290
+ * in-process callers (the reactive `driveRollingImplementDispatch` engine and the
291
+ * A-8 hybrid executor) so they create / commit / verify / merge identically:
292
+ *
293
+ * reset + create the node's worktree → link node_modules → seed declared targets →
294
+ * launch the worker (`dispatchNode`) → `acceptNodeWorktree` (tool-commit, rebase,
295
+ * verify, write-scope gate, cherry-pick) → persist the accept outcome.
296
+ *
297
+ * Claim ownership is the CALLER's concern (the reactive engine claims through the
298
+ * shared registry; the hybrid executor is handed a coordinator-minted claim), so
299
+ * this fn neither claims nor releases — it returns the worker transport result AND
300
+ * the accept lifecycle outcome and lets the caller record `nodeOutcomes` / release.
301
+ * Any thrown error degrades to a dropped worktree + a persisted `error` accept
302
+ * outcome, never an unhandled rejection into the engine.
303
+ */
304
+ export async function executeNodeInWorktree(args) {
305
+ const { block, slot, root, artifactsDir, runId, resultPath, seedPaths, allBlockScopes, additionalVerifyCommands, dispatchNode } = args;
306
+ const branch = worktreeBranchForBlock(block.block_id, runId);
307
+ const wt = worktreePath(root, block.block_id, runId);
308
+ try {
309
+ // Idempotent reset of any worktree dir AND leftover branch from a prior attempt
310
+ // (a `rate_limited` re-queue re-enters for the same block with its branch still
311
+ // present), then create this node's isolated worktree (createWorktree also links
312
+ // the main checkout's node_modules so verify can resolve deps), and seed
313
+ // untracked declared targets a committed-files-only worktree can't see.
314
+ resetNodeWorktreeAndBranch(root, wt, branch);
315
+ createWorktree(root, wt, branch);
316
+ seedUntrackedDeclaredPaths(root, wt, seedPaths);
317
+ const result = await dispatchNode({ block, slot, worktreeRoot: wt, resultPath });
318
+ // Shared post-worker lifecycle. Verify commands are DERIVED from the node's
319
+ // actually-touched tests inside acceptNodeWorktree (post-commit) — omit them so a
320
+ // host-authored path can't mis-verify. The write-scope gate adjudicates the node's
321
+ // ACTUAL git edits against every block's declared scope.
322
+ const accept = await acceptNodeWorktree({
323
+ root,
324
+ runId,
325
+ blockId: block.block_id,
326
+ worktreeRoot: wt,
327
+ branch,
328
+ workerOutcome: result.outcome,
329
+ additionalVerifyCommands,
330
+ scope: { allBlockScopes },
331
+ // The block's OWN declared write paths (INV-1 new-file inclusion).
332
+ writePaths: allBlockScopes.find((b) => b.block_id === block.block_id)?.write_paths ?? [],
333
+ });
334
+ await recordNodeAcceptOutcome(artifactsDir, runId, block.block_id, accept);
335
+ return { result, accept };
336
+ }
337
+ catch (err) {
338
+ removeWorktree(root, wt);
339
+ const accept = { outcome: "error", verifyPassed: false, merged: false };
340
+ await recordNodeAcceptOutcome(artifactsDir, runId, block.block_id, accept);
341
+ return {
342
+ result: {
343
+ packet: { id: block.block_id, payload: { block_id: block.block_id }, estimatedTokens: 0, complexity: 0.5 },
344
+ outcome: "error",
345
+ error: err,
346
+ },
347
+ accept,
348
+ };
349
+ }
350
+ }
351
+ //# sourceMappingURL=acceptNode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acceptNode.js","sourceRoot":"","sources":["../../../../src/remediate/steps/dispatch/acceptNode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,123 @@
1
+ export interface DispatchOptions {
2
+ root: string;
3
+ artifactsDir: string;
4
+ }
5
+ /** Normalize a declared path (absolute, repo-relative, or back-slashed) to a repo-relative forward-slash string. */
6
+ export declare function toRepoRelative(p: string, root: string): string;
7
+ export declare function uniquePaths(paths: string[]): string[];
8
+ export declare function runDir(artifactsDir: string, runId: string, phase: string): string;
9
+ export declare function dispatchPlanPath(artifactsDir: string, runId: string, phase: string): string;
10
+ /**
11
+ * Canonical comparison key for a filesystem path. `realpathSync` resolves
12
+ * symlinks and platform short-names so it matches git's `--show-toplevel`
13
+ * output (macOS TMPDIR `/var`→`/private/var`, Windows 8.3 names); falls back to
14
+ * `resolve` for paths that don't exist on disk (e.g. mocked unit tests).
15
+ */
16
+ export declare function canonicalPathKey(p: string): string;
17
+ /**
18
+ * Deterministic name of the dedicated remediation branch for a run. Derived from
19
+ * the stable run id (= the plan id, constant for the whole remediation) so every
20
+ * wave and the final report resolve the SAME branch without persisting it. Ref-safe:
21
+ * any character outside [A-Za-z0-9._-] collapses to '-'. Distinct from the per-node
22
+ * worktree branches (`remediate-<blockId>-<runId>`) — this uses a `remediation/` ref
23
+ * namespace so the two never collide.
24
+ */
25
+ export declare function refSafeSegment(s: string, fallback: string): string;
26
+ /**
27
+ * The git top-level directory containing `cwd`, or `null` when `cwd` is not
28
+ * inside a git working tree (or git is unavailable). `git rev-parse
29
+ * --show-toplevel` emits a forward-slash absolute path on every platform.
30
+ */
31
+ export declare function gitTopLevel(cwd: string): string | null;
32
+ /** True when `root` is inside a git work tree (the git tool is present and it's a repo). */
33
+ export declare function isGitWorkTree(root: string): boolean;
34
+ /** True when `branch` resolves to a commit in the repo at `root`. */
35
+ export declare function gitBranchExists(root: string, branch: string): boolean;
36
+ /** Branch name a block's isolated worktree is created on (mirrors `worktreePath`). */
37
+ export declare function worktreeBranchForBlock(blockId: string, runId: string): string;
38
+ /** Outcome of resolving the worker's ACTUAL edited files from git. */
39
+ export type GitEditedFiles = {
40
+ available: true;
41
+ files: Set<string>;
42
+ }
43
+ /** git is present but a probe failed against a real repo → fail closed. */
44
+ | {
45
+ available: false;
46
+ reason: "probe_failed";
47
+ error: string;
48
+ }
49
+ /** root is not under version control at all → no ground truth, gate is skipped. */
50
+ | {
51
+ available: false;
52
+ reason: "not_a_repo";
53
+ error: string;
54
+ };
55
+ /**
56
+ * The files a worker's worktree branch changed relative to HEAD — the ground
57
+ * truth for write-scope enforcement. Diffs `HEAD...<branch>` (the branch's own
58
+ * commits). Fail-closed / not-a-repo semantics mirror `gitEditedFiles`.
59
+ */
60
+ export declare function gitEditedFilesForBranch(root: string, branch: string): GitEditedFiles;
61
+ /** A single edited hunk on the NEW side of a branch diff (repo-relative path). */
62
+ export interface GitBranchHunk {
63
+ /** Repo-relative forward-slash path the hunk belongs to. */
64
+ file: string;
65
+ /** 1-based first line of the hunk on the new side. */
66
+ startLine: number;
67
+ /** Number of new-side lines the hunk spans (a pure deletion has 0). */
68
+ lineCount: number;
69
+ }
70
+ /**
71
+ * Outcome of resolving a branch's ACTUAL edited HUNKS from git. Fail-closed like
72
+ * {@link gitEditedFilesForBranch}: on a non-repo, a failed probe, or a diff we
73
+ * cannot parse, `available` is false and callers MUST treat hunk info as absent
74
+ * (conservatively assume same-file blocks overlap — never silently drop a
75
+ * collision).
76
+ */
77
+ export type GitBranchHunks = {
78
+ available: true;
79
+ hunks: GitBranchHunk[];
80
+ } | {
81
+ available: false;
82
+ reason: "not_a_repo";
83
+ error: string;
84
+ } | {
85
+ available: false;
86
+ reason: "probe_failed";
87
+ error: string;
88
+ };
89
+ /**
90
+ * Parse `git diff HEAD...<branch>` into per-hunk NEW-side line ranges — the
91
+ * ground truth for whether two same-file edits actually touch disjoint regions.
92
+ * Mirrors {@link gitEditedFilesForBranch}'s fail-closed / not-a-repo semantics:
93
+ * never throws; on a non-repo / failed probe / malformed diff returns a
94
+ * discriminated result marking hunks unavailable so the caller can fail closed.
95
+ *
96
+ * Paths are normalised to repo-relative forward-slash (the same scheme
97
+ * {@link gitEditedFilesForBranch} emits) so hunk files compare like-for-like
98
+ * with the file set.
99
+ */
100
+ export declare function gitHunksForBranch(root: string, branch: string): GitBranchHunks;
101
+ /**
102
+ * Parse a unified-diff body into NEW-side hunk ranges. Extracted for testability
103
+ * (no git spawn). Recognises `+++ b/<path>` file headers and
104
+ * `@@ -a,b +c,d @@` hunk headers; a header we cannot parse fails the whole probe
105
+ * closed (returns `probe_failed`) rather than silently producing partial hunks
106
+ * that would let a real overlap slip through.
107
+ */
108
+ export declare function parseUnifiedDiffHunks(diffText: string): GitBranchHunks;
109
+ /**
110
+ * Files the worker edited (from git) that fall OUTSIDE the block's declared
111
+ * write scope. Result-file artifacts and the agent-feedback file are excluded
112
+ * (they are sanctioned side outputs, never source edits). Returns the offending
113
+ * repo-relative paths (empty when the edits are fully within scope).
114
+ */
115
+ export declare function writeScopeViolations(declaredWritePaths: string[], editedFiles: Set<string>, root: string): string[];
116
+ /** Fixed prompt overhead per dispatch slot (prompt instructions, JSON schema, etc.). */
117
+ export declare const PROMPT_OVERHEAD_TOKENS = 2000;
118
+ /** Estimate slot tokens for an implement dispatch slot from readFiles byte sizes. */
119
+ export declare function estimateImplementSlotTokens(readFiles: string[], root: string): number;
120
+ /** Module-level cache: repo root → formatted conventions string. */
121
+ export declare const detectRepoConventionsCache: Map<string, string>;
122
+ export declare function getCachedConventions(root: string): string;
123
+ //# sourceMappingURL=common.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../../src/remediate/steps/dispatch/common.ts"],"names":[],"mappings":"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"}