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
@@ -1,864 +1,17 @@
1
- import { type RemediationState } from "../state/store.js";
2
- import { type RemediationBlock } from "../state/types.js";
3
- import type { SessionConfig, HostConcurrencyLimit, WaveSchedule, QuotaStateEntry, ResolvedProviderName, DispatchCapacityPoolSummary, HostModelRosterEntry, CapacityPool, ProviderSlot, RollingDispatchResult } from "audit-tools/shared";
4
- import { HostSessionQuotaSource } from "audit-tools/shared";
5
- import { type DispatchModelHint, type DispatchPhase, type ImplementWorkerResult, type RemediationDispatchPlan, type RemediationDispatchQuota } from "./types.js";
6
- import { resolveHostActiveSubagentLimit } from "../quota/index.js";
7
- export { resolveHostActiveSubagentLimit };
8
- export { detectHostActiveSubagentLimit as detectHostConcurrencyFromEnv, } from "../quota/hostLimits.js";
9
- export type { HostConcurrencyLimit };
10
- export interface ScheduleWaveInput {
11
- hostMaxConcurrent?: number | null;
12
- sessionConfig: SessionConfig | null;
13
- itemCount: number;
14
- estimatedSlotTokens?: number[];
15
- providerName?: ResolvedProviderName;
16
- hostModel?: string | null;
17
- /** Context window the host reports for its dispatch model (handshake). */
18
- hostContextTokens?: number | null;
19
- /** Output cap the host reports for its dispatch model (handshake). */
20
- hostOutputTokens?: number | null;
21
- /**
22
- * Ordered model roster (lowest rank first) from the multi-rank handshake
23
- * (`--host-models`); outranks the scalar pair. One capacity pool is built per
24
- * reported rank, each with its own discovered window.
25
- */
26
- hostModels?: HostModelRosterEntry[] | null;
27
- /**
28
- * Opaque model identity for the quota key when no model name resolves —
29
- * a key segment ONLY (`provider/<id>`), never a window authority.
30
- */
31
- hostModelId?: string | null;
32
- env?: NodeJS.ProcessEnv;
33
- }
34
- export declare function normalizeSlotTokens(tokens: number[] | undefined, count: number): number[];
35
- export interface WaveScheduleResult extends WaveSchedule {
36
- host_concurrency_limit: HostConcurrencyLimit | null;
37
- capacity_pools?: DispatchCapacityPoolSummary[];
38
- }
39
- export declare function resolveHostConcurrencyLimit(options: {
40
- hostMaxConcurrent?: number | null;
41
- sessionConfig: SessionConfig | null;
42
- env?: NodeJS.ProcessEnv;
43
- }): HostConcurrencyLimit | null;
44
- export declare function scheduleWave(input: ScheduleWaveInput): Promise<WaveScheduleResult>;
45
- /**
46
- * Build the confirmed `CapacityPool[]` for a dispatch — one pool per reported
47
- * roster rank (each with its own discovered window + quota key), or a single
48
- * conservative pool for the scalar/absent handshake. This is the same pool shape
49
- * `scheduleWave` constructs internally; it is exposed so the rolling dispatch
50
- * engine (which is fed `confirmedPools` directly) sizes concurrency from the
51
- * identical quota inputs, never from a raw host flag. Reused by
52
- * `driveRollingImplementDispatch`.
53
- */
54
- export declare function buildConfirmedPools(input: {
55
- sessionConfig: SessionConfig | null;
56
- hostMaxConcurrent?: number | null;
57
- hostContextTokens?: number | null;
58
- hostOutputTokens?: number | null;
59
- hostModels?: HostModelRosterEntry[] | null;
60
- hostModelId?: string | null;
61
- env?: NodeJS.ProcessEnv;
62
- /**
63
- * The host-session source the rolling driver RETAINS to feed `recordLimit` and
64
- * read `isPacketEscalated`. Passed in (not constructed anonymously here) so the
65
- * driver threads the SAME instance through pool sizing AND the dispatcher's
66
- * write/read escalation hooks — otherwise the bounded-escalation chain is unfed.
67
- * Omit on the proactive-sizing-only paths; one is constructed internally.
68
- */
69
- hostSession?: HostSessionQuotaSource;
70
- /** Defect-1: demote the primary in-process backend to a source when an attended host drives. */
71
- demotePrimaryInProcess?: boolean;
72
- }): Promise<CapacityPool[]>;
73
- export declare function buildDispatchQuota(runId: string, phase: DispatchPhase, schedule: WaveScheduleResult, admissionPackets: {
74
- id: string;
75
- inputTokens: number;
76
- complexity: number;
77
- }[],
78
- /**
79
- * Whether to LEASE the granted set against the shared reservation ledger. The
80
- * host-subagent path passes `true` (the host dispatches the grant across processes,
81
- * so the tool reserves-before-dispatch and reconciles at accept-node). The
82
- * in-process rolling engine passes `false`: it admits + leases per-packet itself, so
83
- * a host-grant lease here would double-count the same work. Mirrors audit's
84
- * `finalizeDispatchQuota` grantLeases parameterization.
85
- */
86
- grantLeases: boolean, quotaStateEntry?: QuotaStateEntry | null,
87
- /**
88
- * Operator-confirmed cost ordering (rung 1 of costRank; spec/cost-first-routing.md),
89
- * keyed by model id → 0-based confirmed position. Absent ⇒ price then tier.
90
- */
91
- confirmedCostPositions?: Map<string, number> | null): Promise<RemediationDispatchQuota>;
92
- /** Module-level cache: repo root → formatted conventions string. */
93
- export declare const detectRepoConventionsCache: Map<string, string>;
94
- export interface WorktreeVerifyResult {
95
- passed: boolean;
96
- output: string;
97
- }
98
- /**
99
- * The git top-level directory containing `cwd`, or `null` when `cwd` is not
100
- * inside a git working tree (or git is unavailable). `git rev-parse
101
- * --show-toplevel` emits a forward-slash absolute path on every platform.
102
- */
103
- export declare function gitTopLevel(cwd: string): string | null;
104
- /**
105
- * Create an isolated git worktree on a fresh branch at HEAD. Throws on non-zero exit.
106
- *
107
- * Refuses when `root` is not ITSELF a git top-level: a bare `git worktree add`
108
- * with `cwd: root` walks UP to the nearest enclosing repo and silently creates
109
- * the worktree/branch in that ancestor (observed polluting the monorepo with
110
- * leaked `remediate-*` branches during the rolling_engine flip). The resolved
111
- * top-level must equal the target root, or we refuse rather than escape.
112
- */
113
- export declare function createWorktree(root: string, worktreePath: string, branchName: string): void;
114
- /**
115
- * Materialize into a fresh worktree any of the node's declared target paths that
116
- * exist in the main tree but are absent from the worktree — i.e. git-untracked or
117
- * gitignored files that `git worktree add HEAD` does not bring over. Without this
118
- * a node whose scope names an untracked config file (the dogfood hit
119
- * `opencode.json` and an uncommitted `.gemini/commands/*.toml`) cannot see its own
120
- * target, so the edit silently no-ops. The "absent in worktree" test is the
121
- * discriminator: a tracked path is already materialized from HEAD, so only the
122
- * genuinely-missing untracked/ignored declarations are copied — a tracked-but-dirty
123
- * file keeps its clean-from-HEAD worktree content and is never clobbered. Paths are
124
- * repo-relative (the declared scope contract); absolute/escaping paths are skipped.
125
- * Best-effort: a copy failure must not abort the dispatch (logged, not thrown).
126
- */
127
- export declare function seedUntrackedDeclaredPaths(root: string, worktreeRoot: string, declaredPaths: Iterable<string>): void;
128
- /** Remove a git worktree. Best-effort: logs but does not throw on failure. */
129
- export declare function removeWorktree(root: string, worktreePath: string): void;
130
- /**
131
- * Fully reset a node's isolated worktree + branch so a fresh `createWorktree -b`
132
- * can run, even when a prior attempt left either behind. This is the idempotent
133
- * cleanup the in-process driver needs across a `rate_limited` re-queue: the
134
- * engine re-enters the dispatcher for the SAME block while its branch (and maybe
135
- * a stale worktree admin entry) still exist, and `git worktree add -b <branch>`
136
- * would otherwise fail with "branch already exists". Removing the worktree,
137
- * pruning stale admin records, then force-deleting the branch makes every
138
- * (re-)dispatch start clean from HEAD. All steps are best-effort (a missing
139
- * worktree/branch is the expected first-attempt case, not an error). Any partial
140
- * edits from a throttled prior attempt are intentionally discarded — the
141
- * re-dispatch redoes the node from HEAD.
142
- */
143
- export declare function resetNodeWorktreeAndBranch(root: string, worktreePath: string, branchName: string): void;
144
- /**
145
- * Run each targeted command in the worktree directory. Returns pass/fail and
146
- * combined output.
147
- *
148
- * `targeted_commands` are opaque host-authored command *strings* (e.g.
149
- * `npm run build`, `grep -c '/packages/' .gitignore`, anything with pipes,
150
- * quotes, or redirections), NOT pre-tokenized argv. They are run through the
151
- * platform shell (`runShellCommand` → `spawnSync(..., { shell: true })`, the
152
- * same path `close.ts` uses for `test_command`/`e2e_command`) so the shell — not
153
- * a word-split + `spawnSync(shell:false)` — resolves the verb. That is what
154
- * makes this OS-agnostic: on win32 `cmd.exe` natively execs `.cmd` shims (npm,
155
- * npx, …) and resolves PATH commands; on darwin/linux `/bin/sh` does. The prior
156
- * argv path ENOENT'd the *spawn itself* for any verb that wasn't a bare
157
- * executable (e.g. `grep` on Windows), turning a correct fix into a phantom
158
- * contract failure that burned the retry budget.
159
- */
160
- export declare function verifyNodeInWorktree(worktreePath: string, targetedCommands: string[]): WorktreeVerifyResult;
161
- /** Merge the worktree branch into the current HEAD via cherry-pick. On failure, removes the worktree and returns the error. */
162
- export declare function mergeWorktree(root: string, worktreePath: string, branchName: string): {
163
- success: true;
164
- } | {
165
- success: false;
166
- error: string;
167
- };
168
- /**
169
- * Repo-relative tracked paths in the MAIN checkout that have uncommitted changes
170
- * AND collide with a path the node's branch edits. A pre-existing dirty tracked
171
- * file the cherry-pick would touch makes `git cherry-pick` abort with the opaque
172
- * "Your local changes to the following files would be overwritten by merge" — a
173
- * condition the node itself cannot fix and that identically re-fails every
174
- * auto-retry (observed: a docs-only node routed to human triage over unrelated
175
- * uncommitted WIP on the same file). Detected here so `acceptNodeWorktree` can
176
- * surface the actionable cause (which file, commit-or-stash) instead of the raw
177
- * git error. Best-effort: an unavailable diff / status probe returns `[]` (fall
178
- * through to the normal cherry-pick, which reproduces the original behaviour).
179
- */
180
- export declare function dirtyMainTreeCollisions(root: string, branch: string): string[];
181
- /**
182
- * Rebase a node's worktree branch onto the main checkout's current HEAD (the
183
- * remediation branch tip) so a sibling that merged AFTER this worktree was created
184
- * is folded in before this node verifies and merges. Additive edits to a shared
185
- * file merge automatically (git's per-commit 3-way); a true hunk conflict is a
186
- * genuine seam that aborts cleanly so the node routes to triage instead of landing
187
- * a broken merge. The branch is checked out in the worktree, so the rebase runs
188
- * there. A no-op (branch already on HEAD — the common, no-sibling-merged case)
189
- * succeeds. Leaves the branch on its pre-rebase commit on abort (so the failed
190
- * node's work can still be quarantined).
191
- */
192
- export declare function rebaseBranchOntoHead(root: string, worktreePath: string, branch: string): {
193
- ok: true;
194
- } | {
195
- ok: false;
196
- error: string;
197
- };
198
- /** Worktree path for a remediation block. */
199
- export declare function worktreePath(root: string, blockId: string, runId: string): string;
200
- export declare function remediationBranchName(runId: string): string;
201
- /**
202
- * Lock path for the base-mutating accept critical section (INV-2/CE-001), keyed on
203
- * the base repo root + run's remediation branch. DISTINCT from the per-run
204
- * `rolling-session.lock` (`withFileLock` is non-reentrant — an exclusive `wx`
205
- * create — so the base lock MUST be a different path than the session lock
206
- * `advanceHostRolling` already holds, or the nested acquire would self-deadlock).
207
- * Both rolling drivers (host-subagent + in-process) serialize the rebase →
208
- * cherry-pick → cross-package check → reset sequence through this single lock.
209
- */
210
- export declare function baseBranchLockPath(root: string, runId: string): string;
211
- /** Durable ref under which a failed-but-committed node's commit is preserved. */
212
- export declare function quarantineRef(runId: string, blockId: string): string;
213
- /**
214
- * Preserve a failed-but-committed node's work so it can never be lost. A node that
215
- * committed real edits to its worktree branch but then failed verify / the
216
- * write-scope gate / the cherry-pick is about to have its worktree removed and (on
217
- * the next re-dispatch) its branch force-deleted — orphaning the commit. The dogfood
218
- * lost a verified fix exactly this way (the worktree was pruned before recovery).
219
- * Point a durable ref at the branch tip: a ref under refs/remediation-quarantine/
220
- * survives `git branch -D` and `git worktree prune`, so the work stays reachable for
221
- * a manual `git cherry-pick`. Best-effort; returns the ref + commit, or null.
222
- */
223
- export declare function quarantineFailedNodeCommit(root: string, branch: string, runId: string, blockId: string): {
224
- ref: string;
225
- commit: string;
226
- } | null;
227
- /**
228
- * Preserve a failed-but-UNCOMMITTED node's worktree edits before the worktree is
229
- * removed. The verify / scope / merge-fail paths quarantine an already-committed
230
- * branch tip; this is the missing twin for the commit-REFUSAL path: when
231
- * `commitWorktree` fails loudly (e.g. a generated artifact landed under the write
232
- * scope — the genuine CE-003 fail-loud), the worker's real source edits are still
233
- * sitting uncommitted in the worktree and would be destroyed by `removeWorktree`.
234
- * Stage everything and land a preservation commit on the node's ISOLATED branch
235
- * (never cherry-picked into main — it exists only so a durable quarantine ref can
236
- * point at the otherwise-lost work), then quarantine that commit. A guard that
237
- * destroys good work is worse than the bug it guards. Best-effort; returns the
238
- * quarantine ref + commit, or null when there was nothing to preserve / it failed.
239
- */
240
- export declare function quarantineUncommittedWorktreeEdits(root: string, worktreeRoot: string, branch: string, runId: string, blockId: string): {
241
- ref: string;
242
- commit: string;
243
- } | null;
244
- /** Clear a node's quarantine ref (e.g. once a later re-dispatch landed successfully). Best-effort. */
245
- export declare function clearQuarantinedCommit(root: string, runId: string, blockId: string): void;
246
- /** Quarantined failed-node commits still preserved for a run, for recovery surfacing in the report. */
247
- export declare function listQuarantinedCommits(root: string, runId: string): Array<{
248
- block: string;
249
- ref: string;
250
- commit: string;
251
- }>;
252
- /**
253
- * Ensure the main checkout is on the dedicated remediation branch BEFORE any node
254
- * commit is cherry-picked, so accepted work lands there and the user's base branch
255
- * is NEVER modified — the run leaves a feature branch for review (it does not merge
256
- * back). Idempotent across waves: creates the branch from the current HEAD (the base)
257
- * the first time, checks it out on later waves. Best-effort on a non-git root (the
258
- * worktree dispatch flow can't run there anyway): returns null without throwing so
259
- * non-git callers/tests are unaffected. Returns the branch name on success.
260
- */
261
- /** Sidecar recording the base branch the run was launched from (B5). */
262
- export declare function remediationBaseBranchPath(artifactsDir: string): string;
263
- /**
264
- * The base branch this run was launched from, recorded when the remediation
265
- * branch was first created. `null` when unrecorded (e.g. a detached HEAD at
266
- * launch, or a branch created by a prior run) — the opt-in merge-to-base
267
- * closing action degrades to "merge manually" rather than guessing a target.
268
- */
269
- export declare function readRemediationBaseBranch(artifactsDir: string): string | null;
270
- export declare function ensureRemediationBranchCheckedOut(root: string, runId: string, artifactsDir?: string): string | null;
271
- export declare function commitWorktree(worktreeRoot: string, message: string, declaredWritePaths?: string[]): {
272
- committed: boolean;
273
- error?: string;
274
- };
275
- /**
276
- * Make the main checkout's installed `node_modules` available to a worktree. A
277
- * fresh `git worktree add` checks out only tracked files, and `node_modules` is
278
- * gitignored, so per-node verify commands (`npm run check`, focused tests) would
279
- * otherwise fail with missing dependencies. Best-effort junction/symlink to the
280
- * main root's `node_modules`; on failure it logs and the verify step surfaces the
281
- * missing-deps error rather than crashing the dispatch. NOTE: workspace package
282
- * symlinks inside `node_modules/@audit-tools/*` point back into the MAIN checkout,
283
- * so cross-package runtime resolution sees the main tree — the authoritative
284
- * cross-package re-check is the central post-merge build/gate, not this fast
285
- * per-node verify (which gates obvious breakage early).
286
- */
287
- export declare function ensureWorktreeNodeModules(mainRoot: string, worktreeRoot: string): void;
288
- /** Worker transport outcome (mirrors shared `RollingDispatchResult["outcome"]`). */
289
- export type NodeWorkerOutcome = "success" | "error" | "rate_limited" | "timeout";
290
- export interface AcceptNodeWorktreeParams {
291
- root: string;
292
- runId: string;
293
- blockId: string;
294
- /** The node's isolated worktree directory. */
295
- worktreeRoot: string;
296
- /** The node's worktree branch (`worktreeBranchForBlock`). */
297
- branch: string;
298
- /** The worker's transport outcome from the node dispatcher. */
299
- workerOutcome: NodeWorkerOutcome;
300
- /**
301
- * Per-node verify commands. OMIT (leave `undefined`) for the real rolling drivers:
302
- * the gate then DERIVES the verify from the node's actually-touched test files
303
- * post-commit ({@link deriveVerifyCommandsFromBranch}) — correct paths/runner by
304
- * construction, never the whole suite. Pass `[]` to skip the gate (lifecycle unit
305
- * tests on a minimal temp repo), or an explicit list to force specific commands.
306
- */
307
- targetedCommands?: string[];
308
- /**
309
- * The node's own `targeted_commands` (the auditor/finding-specified verification),
310
- * run IN ADDITION to the derived commands — filtered to the build-free subset and
311
- * deduped against the derive. The derive gives correct-paths-by-construction; these
312
- * add the fix-specific regression checks the derive misses when a fix touches no test
313
- * (task_7d35176d). Omit / `[]` → derive-only (the prior behaviour). Ignored when
314
- * `targetedCommands` is an explicit override (the lifecycle unit-test path).
315
- */
316
- additionalVerifyCommands?: string[];
317
- /**
318
- * Accept-time write-scope inputs (OBL-DS-06). The write-scope gate runs HERE —
319
- * after the verify, BEFORE the cherry-pick — so an out-of-scope or seam-conflicting
320
- * edit is PREVENTED from landing in the main tree rather than reported post-hoc once
321
- * it is already merged. REQUIRED (not optional): both rolling drivers always derive
322
- * it from the plan, so a production caller can never silently skip the gate — that
323
- * enforcement is the type, not host discretion (E1). A lifecycle test that does not
324
- * exercise scope passes `{ allBlockScopes: [] }`: an empty registry owns nothing, so
325
- * every edit is unowned-and-granted → the gate is a sound no-op, never a skip.
326
- */
327
- scope: {
328
- /** Every block's declared write scope, for amendment ownership adjudication. */
329
- allBlockScopes: Array<{
330
- block_id: string;
331
- write_paths: string[];
332
- }>;
333
- };
334
- /**
335
- * The block's OWN declared write paths (INV-1). Threaded into `commitWorktree`
336
- * so worker-created new SOURCE files under scope are force-added past
337
- * `.gitignore` and a generated-artifact / out-of-scope new file fails loudly.
338
- * Omit (lifecycle unit tests with no scope) → no new-file inclusion.
339
- */
340
- writePaths?: string[];
341
- /**
342
- * The cross-package check command (argv) run in the MAIN checkout AFTER the
343
- * cherry-pick lands (INV-2): a RED check rolls the base back to its captured HEAD
344
- * OID. When omitted, the command is PINNED — derived from the repo via
345
- * `mergedBaseCheckArgv` (the `check`-layer of the tool-owned gate set), not a
346
- * hardcoded string — and skipped (`null`) on a non-monorepo target. Tests inject a
347
- * deterministic pass/fail argv (a `t.mock.module` seam is unusable under tsx/esm).
348
- * Pass `null` to skip the merged-base check entirely (legacy lifecycle unit tests
349
- * on a minimal repo with no check script).
350
- */
351
- mergedBaseCheckCommand?: string[] | null;
352
- }
353
- export interface AcceptNodeWorktreeResult {
354
- /** The LIFECYCLE outcome (verify/merge applied), distinct from the worker transport outcome. */
355
- outcome: NodeWorkerOutcome;
356
- verifyPassed: boolean;
357
- merged: boolean;
358
- /**
359
- * On a failure outcome, the captured failing command + its output — the verify
360
- * stdout/stderr (`$ <cmd>\n<output>`), or the git commit / cherry-pick error text.
361
- * Persisted into the accept-outcome sidecar so triage can see the root cause
362
- * instead of an `outcome:error` with no captured stderr. Absent on success.
363
- */
364
- diagnostic?: string;
365
- }
366
- /**
367
- * The shared post-worker "accept node" lifecycle, extracted so BOTH rolling
368
- * drivers reuse identical correctness: the in-process provider engine
369
- * (`driveRollingImplementDispatch`) calls it inline once the worker returns; the
370
- * host-subagent driver calls it from the `accept-node` callback once a host
371
- * subagent finishes.
372
- *
373
- * Given a completed worker run in an isolated worktree, this: (1) TOOL-commits
374
- * the worker's edits onto the branch (deterministic, never the worker/host) so
375
- * the branch diff is the write-scope ground truth; (2) runs the per-node verify
376
- * IN the worktree BEFORE accepting; (3) merges via cherry-pick only on a passing
377
- * verify; and (4) drops the worktree on any failure so the main tree is never
378
- * dirtied by an unverified change. It returns the LIFECYCLE outcome (which the
379
- * caller records for the deterministic merge); the caller still returns the
380
- * worker's TRANSPORT outcome to the rolling engine (so a `rate_limited` worker
381
- * re-queues, while a verify-failure is adjudicated by the merge → triage).
382
- *
383
- * SAFETY: the main tree is touched only through `mergeWorktree` (cherry-pick of a
384
- * verified branch, aborts cleanly on conflict). No state mutation here — the
385
- * caller persists via `mergeImplementResults`.
386
- */
387
- export declare function acceptNodeWorktree(params: AcceptNodeWorktreeParams): Promise<AcceptNodeWorktreeResult>;
388
- /**
389
- * Sidecar path for a node's tool-owned accept (verify/merge) outcome. Written by
390
- * BOTH rolling drivers as each node is accepted, read by `mergeImplementResults`.
391
- * Block ids here follow the same filename-safe convention as the per-node result
392
- * files in the same dir.
393
- */
394
- export declare function nodeAcceptOutcomePath(artifactsDir: string, runId: string, blockId: string): string;
395
- /**
396
- * Persist a node's `acceptNodeWorktree` lifecycle outcome so finalization can tell
397
- * a node whose edits actually LANDED (merged) from one that self-reported "resolved"
398
- * but failed tool-owned verify / merge (OBL-DS-06: never trust the worker's self
399
- * report). Both rolling drivers (host-subagent `advanceHostRolling` and in-process
400
- * `driveRollingImplementDispatch`) call this; the interim main-tree path writes none,
401
- * so the merge-state gate is inert there.
402
- */
403
- export declare function recordNodeAcceptOutcome(artifactsDir: string, runId: string, blockId: string, result: AcceptNodeWorktreeResult): Promise<void>;
404
- /** Load a node's recorded accept outcome, or null when none was written. */
405
- export declare function loadNodeAcceptOutcome(artifactsDir: string, runId: string, blockId: string): Promise<AcceptNodeWorktreeResult | null>;
406
- /**
407
- * The per-node worktree worker an in-process driver launches: it edits within the
408
- * node's isolated worktree (cwd-confined), writes its result file, and returns the
409
- * transport outcome. `makeProviderNodeDispatcher` is the live implementation; tests
410
- * inject a stub. Structurally identical to `nextStep`'s `ProgrammaticNodeDispatcher`.
411
- */
412
- export type WorktreeNodeWorker = (args: {
413
- block: RemediationBlock;
414
- slot: ProviderSlot;
415
- worktreeRoot: string;
416
- resultPath: string;
417
- }) => Promise<RollingDispatchResult<{
418
- block_id: string;
419
- }>>;
420
- /** One node's worktree-lifecycle result: the worker transport outcome + the accept lifecycle. */
421
- export interface NodeWorktreeExecution {
422
- /** Worker transport outcome the rolling engine consumes (success/error/rate_limited/timeout). */
423
- result: RollingDispatchResult<{
424
- block_id: string;
425
- }>;
426
- /** Tool-owned accept outcome (commit→verify→merge), already persisted via recordNodeAcceptOutcome. */
427
- accept: AcceptNodeWorktreeResult;
428
- }
429
- /**
430
- * Run ONE node's full in-process lifecycle in an isolated worktree — shared by BOTH
431
- * in-process callers (the reactive `driveRollingImplementDispatch` engine and the
432
- * A-8 hybrid executor) so they create / commit / verify / merge identically:
433
- *
434
- * reset + create the node's worktree → link node_modules → seed declared targets →
435
- * launch the worker (`dispatchNode`) → `acceptNodeWorktree` (tool-commit, rebase,
436
- * verify, write-scope gate, cherry-pick) → persist the accept outcome.
437
- *
438
- * Claim ownership is the CALLER's concern (the reactive engine claims through the
439
- * shared registry; the hybrid executor is handed a coordinator-minted claim), so
440
- * this fn neither claims nor releases — it returns the worker transport result AND
441
- * the accept lifecycle outcome and lets the caller record `nodeOutcomes` / release.
442
- * Any thrown error degrades to a dropped worktree + a persisted `error` accept
443
- * outcome, never an unhandled rejection into the engine.
444
- */
445
- export declare function executeNodeInWorktree(args: {
446
- block: RemediationBlock;
447
- slot: ProviderSlot;
448
- root: string;
449
- artifactsDir: string;
450
- runId: string;
451
- resultPath: string;
452
- /** Untracked declared targets to seed into the worktree (the node's write set or write∪read). */
453
- seedPaths: string[];
454
- /** Every block's declared write scope, for the accept-time write-scope gate (OBL-DS-06). */
455
- allBlockScopes: Array<{
456
- block_id: string;
457
- write_paths: string[];
458
- }>;
459
- /** The node's own targeted_commands, run IN ADDITION to the derived verify (task_7d35176d). */
460
- additionalVerifyCommands?: string[];
461
- dispatchNode: WorktreeNodeWorker;
462
- }): Promise<NodeWorktreeExecution>;
463
- export interface DispatchOptions {
464
- root: string;
465
- artifactsDir: string;
466
- }
467
- /**
468
- * The implementation-DAG node fields `promoteImplementationDagToExtractedPlan`
469
- * writes onto each Finding (one node ↔ one finding ↔ one block in the contract
470
- * pipeline). The shared `Finding` type does not declare these overlay fields, so
471
- * they are read through this structural view rather than added to the shared
472
- * contract. Every field is optional: a finding sourced from a plain
473
- * `audit-findings.json` (not the contract pipeline) carries none of them and the
474
- * seam degrades to the block-level behavior.
475
- */
476
- export interface DagNodeFields {
477
- /** Relative model rank for the node (small | standard | deep). Never a model name. */
478
- model_tier?: "small" | "standard" | "deep";
479
- /** Upstream contracts' declared outputs this node builds on. */
480
- preconditions?: string[];
481
- /** Human-readable description of the concrete changes the node is expected to produce. */
482
- expected_changes?: string;
483
- /** Human-readable verification checks beyond `targeted_commands`. */
484
- verification?: string[];
485
- /**
486
- * Reconciliation expectations carried from seam reconciliation: what an
487
- * upstream/neighbor contract agreed to provide this node, expressed either as
488
- * a list of strings or, when richer, as the precondition list. Read tolerantly
489
- * because the promotion shape can vary across pipeline versions.
490
- */
491
- reconciliation_expectations?: string[];
492
- }
493
- /**
494
- * The host manages the build centrally; a per-node verify command that runs
495
- * `npm run build` (or a `npm test` whose package script prepends a build) races
496
- * the central build's dist/ and is therefore forbidden. A command is build-free
497
- * only when it neither builds nor invokes a build-prepending test script.
498
- *
499
- * Forbidden (return false):
500
- * - `npm run build` / `npm run build -w ...` / `tsc` emit (`tsc -b`, `tsc --build`)
501
- * - bare `npm test` / `npm t` / `npm run test` (the package script prepends build)
502
- *
503
- * Allowed (return true):
504
- * - `npm run check` (no emit)
505
- * - `npx vitest run <path>` / `vitest run <path>`
506
- * - `node --test <path>`
507
- */
508
- export declare function isBuildFreeVerifyCommand(cmd: string): boolean;
509
- /**
510
- * Inject the tsx ESM loader into a bare `node --test <file>` command so the `.mjs`
511
- * node:test suites (which import `audit-tools/shared` via tsconfig `paths`, honored
512
- * only by tsx) resolve in a per-node worktree with no built `dist/`. A host- or
513
- * DAG-authored `node --test tests/audit/x.test.mjs` would otherwise fail module
514
- * resolution; the tool normalizes it so correctness can't depend on the host
515
- * remembering to add the loader. Idempotent: a command already carrying
516
- * `--import tsx/esm` or a `--loader` is left untouched. Mirrors the runner the
517
- * derived verify uses ({@link verifyCommandsForEdits}), so the displayed per-node
518
- * command and the in-process verify match.
519
- */
520
- export declare function normalizeNodeTestCommand(cmd: string): string;
521
- /**
522
- * True when `cmd` is a test-runner invocation whose target is a whole directory
523
- * or the entire suite rather than specific test files — e.g. `npx vitest run
524
- * tests/remediate`, `vitest run` (no path), `node --test tests/audit/`. Such a
525
- * command, run as an *additional* per-node verify alongside the scoped derive,
526
- * re-enters the FULL suite inside a per-node worktree. That is the structural
527
- * deadlock proven 2026-06-30: a source node's whole-suite verify fails on a
528
- * stale test owned by a DIFFERENT node, and concurrent worktrees race shared
529
- * test temp dirs. The derived verify already runs this node's OWN touched
530
- * tests, so a host/DAG-authored whole-suite command adds only risk — the tool
531
- * drops it rather than relying on the author to scope it (enforce-in-tooling,
532
- * never host discretion). A command naming at least one concrete `.test.<ext>`
533
- * file is scoped and kept.
534
- */
535
- export declare function isWholeSuiteTestCommand(cmd: string): boolean;
536
- /**
537
- * Repo-relative path-like tokens in a shell command — tokens containing a `/` and a
538
- * file extension (e.g. `scripts/remediate/verify-hosts.mjs`, `tests/x.test.ts`).
539
- * Used to decide whether a targeted verify command is self-contained.
540
- */
541
- export declare function pathTokensInCommand(cmd: string): string[];
542
- /**
543
- * Keep only the targeted verify commands that are SELF-CONTAINED for this node:
544
- * every path-like token they reference is either one of the node's own paths (its
545
- * declared write set ∪ the files it actually edited on its branch) or already
546
- * present in the tree. A command referencing a path this node doesn't own and that
547
- * isn't in the tree depends on a SIBLING node's not-yet-created deliverable —
548
- * running it in per-node verify is a guaranteed-fail deadlock (proven 2026-07-03: a
549
- * node's `targeted_command` was `node scripts/remediate/verify-hosts.mjs`, another
550
- * node's pending output). Per-node verify must be self-contained; such a cross-node
551
- * command is dropped here and deferred to the integration/close gate. A command with
552
- * no path tokens (e.g. `npm run check`) is always kept.
553
- */
554
- export declare function selfContainedVerifyCommands(commands: string[], ownPaths: Iterable<string>, treeRoot: string): string[];
555
- /**
556
- * Derive a node's per-node verify commands from the test files it ACTUALLY touched
557
- * on its worktree branch (the git ground truth), instead of trusting host-authored
558
- * `targeted_commands` whose paths/runner can drift from where the worker put the
559
- * test. Always typechecks (`npm run check`, no emit), then runs ONLY this node's
560
- * own touched test files with the repo's runners — never the whole suite (which
561
- * would re-enter worktree-spawning tests inside a nested worktree). Build-free: the
562
- * host owns the central build; a node's own test imports the source it changed via
563
- * the tsx loader. Returns `[]` when there is no git ground truth so the caller can
564
- * skip the gate rather than fabricate a command.
565
- */
566
- /** Pure assembly (git-free) of the verify commands for a set of edited paths —
567
- * the testable core of {@link deriveVerifyCommandsFromBranch}. */
568
- export declare function verifyCommandsForEdits(editedFiles: Iterable<string>): string[];
569
- export declare function deriveVerifyCommandsFromBranch(root: string, branch: string): string[];
570
- /**
571
- * A node's own `targeted_commands` for the per-node verify (task_7d35176d) — the union
572
- * of the block's `targeted_commands` and its findings' `targeted_commands` (the
573
- * auditor-specified, fix-specific verification). `acceptNodeWorktree` runs these IN
574
- * ADDITION to the derived touched-test commands (build-free subset, deduped), so a
575
- * fix-specific regression check is honoured even when the fix touches no test file.
576
- */
577
- export declare function targetedCommandsForBlock(state: RemediationState, blockId: string): string[];
578
- /**
579
- * Best-effort: repo-relative test files that reference any of `sourceFiles` (by
580
- * module basename). Pulling them into a block's access lets the worker that
581
- * changes or removes a symbol also fix the tests that assert it, instead of
582
- * leaving orphaned test breakage for a separate central mop-up. Matching is
583
- * deliberately loose (a false positive only grants slightly broader, harmless
584
- * write access; a false negative is the failure mode we want to avoid).
585
- */
586
- export interface TestFileEntry {
587
- rel: string;
588
- content: string;
589
- }
590
- /**
591
- * Walk the repo ONCE and read every test file's content (bounded). Built once per
592
- * dispatch and shared across all blocks so the filesystem walk + reads are not
593
- * repeated per block.
594
- */
595
- export declare function buildTestFileIndex(root: string): TestFileEntry[];
596
- /**
597
- * Collect test files from `index` that reference any of `sourceFiles` by
598
- * module basename. When `packageRoot` is supplied (repo-relative prefix, e.g.
599
- * `packages/foo`), only test files under that package are considered —
600
- * otherwise all test files in the index are matched (existing behavior).
601
- */
602
- export declare function collectReferencingTests(index: TestFileEntry[], sourceFiles: string[], packageRoot?: string): string[];
603
- export declare function buildImplementModelHint(block: RemediationBlock, state: RemediationState): DispatchModelHint;
604
- /**
605
- * Returns true when any path in `writePaths` is one of the live infra modules.
606
- * Paths are normalised to forward-slash form (win32 backslash → `/`) and matched
607
- * by trailing repo-relative segment so absolute/worktree/relative spellings all
608
- * resolve identically. Used to gate the live-surface verification section in the
609
- * implement prompt.
610
- */
611
- export declare function isInfraModifyingBlock(writePaths: string[]): boolean;
612
- export declare function prepareImplementDispatch(options: DispatchOptions, runId: string, onlyBlockId?: string, waveOptions?: {
613
- hostMaxConcurrent?: number;
614
- sessionConfig?: SessionConfig | null;
615
- hostContextTokens?: number | null;
616
- hostOutputTokens?: number | null;
617
- hostModels?: HostModelRosterEntry[] | null;
618
- hostModelId?: string | null;
619
- /**
620
- * Root each node's prompt at its isolated worktree (the deterministic
621
- * `worktreePath(root, block_id, runId)`) rather than the main checkout. Set by
622
- * the rolling engine (`driveRollingImplementDispatch`) so a worker told its
623
- * repository root is the worktree edits there, not the shared main tree.
624
- */
625
- worktreeRootedPrompts?: boolean;
626
- /**
627
- * Lease the granted admitted set against the shared reservation ledger. The
628
- * host-subagent rolling path leaves this unset (defaults true — it dispatches the
629
- * grant across processes and reconciles at accept-node); the in-process rolling
630
- * engine passes `false` (it admits + leases per-packet itself, so a host grant
631
- * here would double-count). Threaded into `buildDispatchQuota`.
632
- */
633
- grantLeases?: boolean;
634
- }): Promise<RemediationDispatchPlan>;
635
- /** Outcome of resolving the worker's ACTUAL edited files from git. */
636
- export type GitEditedFiles = {
637
- available: true;
638
- files: Set<string>;
639
- }
640
- /** git is present but a probe failed against a real repo → fail closed. */
641
- | {
642
- available: false;
643
- reason: "probe_failed";
644
- error: string;
645
- }
646
- /** root is not under version control at all → no ground truth, gate is skipped. */
647
- | {
648
- available: false;
649
- reason: "not_a_repo";
650
- error: string;
651
- };
652
- /**
653
- * Files the worker edited (from git) that fall OUTSIDE the block's declared
654
- * write scope. Result-file artifacts and the agent-feedback file are excluded
655
- * (they are sanctioned side outputs, never source edits). Returns the offending
656
- * repo-relative paths (empty when the edits are fully within scope).
657
- */
658
- export declare function writeScopeViolations(declaredWritePaths: string[], editedFiles: Set<string>, root: string): string[];
659
- /** Branch name a block's isolated worktree is created on (mirrors `worktreePath`). */
660
- export declare function worktreeBranchForBlock(blockId: string, runId: string): string;
661
- /**
662
- * The files a worker's worktree branch changed relative to HEAD — the ground
663
- * truth for write-scope enforcement. Diffs `HEAD...<branch>` (the branch's own
664
- * commits). Fail-closed / not-a-repo semantics mirror `gitEditedFiles`.
665
- */
666
- export declare function gitEditedFilesForBranch(root: string, branch: string): GitEditedFiles;
667
- /** A single edited hunk on the NEW side of a branch diff (repo-relative path). */
668
- export interface GitBranchHunk {
669
- /** Repo-relative forward-slash path the hunk belongs to. */
670
- file: string;
671
- /** 1-based first line of the hunk on the new side. */
672
- startLine: number;
673
- /** Number of new-side lines the hunk spans (a pure deletion has 0). */
674
- lineCount: number;
675
- }
676
- /**
677
- * Outcome of resolving a branch's ACTUAL edited HUNKS from git. Fail-closed like
678
- * {@link gitEditedFilesForBranch}: on a non-repo, a failed probe, or a diff we
679
- * cannot parse, `available` is false and callers MUST treat hunk info as absent
680
- * (conservatively assume same-file blocks overlap — never silently drop a
681
- * collision).
682
- */
683
- export type GitBranchHunks = {
684
- available: true;
685
- hunks: GitBranchHunk[];
686
- } | {
687
- available: false;
688
- reason: "not_a_repo";
689
- error: string;
690
- } | {
691
- available: false;
692
- reason: "probe_failed";
693
- error: string;
694
- };
695
- /**
696
- * Parse `git diff HEAD...<branch>` into per-hunk NEW-side line ranges — the
697
- * ground truth for whether two same-file edits actually touch disjoint regions.
698
- * Mirrors {@link gitEditedFilesForBranch}'s fail-closed / not-a-repo semantics:
699
- * never throws; on a non-repo / failed probe / malformed diff returns a
700
- * discriminated result marking hunks unavailable so the caller can fail closed.
701
- *
702
- * Paths are normalised to repo-relative forward-slash (the same scheme
703
- * {@link gitEditedFilesForBranch} emits) so hunk files compare like-for-like
704
- * with the file set.
705
- */
706
- export declare function gitHunksForBranch(root: string, branch: string): GitBranchHunks;
707
- /**
708
- * Parse a unified-diff body into NEW-side hunk ranges. Extracted for testability
709
- * (no git spawn). Recognises `+++ b/<path>` file headers and
710
- * `@@ -a,b +c,d @@` hunk headers; a header we cannot parse fails the whole probe
711
- * closed (returns `probe_failed`) rather than silently producing partial hunks
712
- * that would let a real overlap slip through.
713
- */
714
- export declare function parseUnifiedDiffHunks(diffText: string): GitBranchHunks;
715
- /** The decision a write-scope gate makes given the resolved edit set. */
716
- export interface WriteScopeDecision {
717
- blocked: boolean;
718
- reason?: string;
719
- }
720
- /**
721
- * Pure write-scope gate decision (OBL-DS-06). Given the block's declared write
722
- * paths and the resolved git edit set:
723
- * - `not_a_repo` → no ground truth (no worktree workflow) → not blocked.
724
- * - `probe_failed` → git is a repo but the diff failed → FAIL CLOSED (blocked).
725
- * - available → block iff any edited file is outside declared scope.
726
- * The worker's self-reported `amended_files` is never an input here.
727
- */
728
- export declare function enforceWriteScope(declaredWritePaths: string[], edited: GitEditedFiles, root: string): WriteScopeDecision;
729
- /** Each block's declared write scope from a dispatch plan — the seed for the
730
- * accept-time write-scope gate's ownership registry (so an amended path owned by
731
- * a sibling block is recognised as a seam conflict, not silently granted). */
732
- export declare function blockScopesFromPlan(plan: RemediationDispatchPlan): Array<{
733
- block_id: string;
734
- write_paths: string[];
735
- }>;
736
- /**
737
- * A block's declared target paths (write ∪ read) from the persisted dispatch plan
738
- * — the single source of the scope the worker actually received (same authority
739
- * the accept-time write-scope gate reads). Used to seed untracked declared targets
740
- * into a fresh worktree (see {@link seedUntrackedDeclaredPaths}).
741
- */
742
- export declare function declaredPathsFromPlan(plan: RemediationDispatchPlan, blockId: string): string[];
743
- /**
744
- * Pure write-scope adjudication (OBL-DS-06) — git-free so it is unit-testable with
745
- * a synthetic edit set. Seeds an ephemeral `OwnershipRegistry` from `allBlockScopes`
746
- * (normalised to repo-relative so ownership compares like-for-like) and routes the
747
- * node's ACTUAL out-of-declared edits — the git ground truth, never a self-report:
748
- * - an edit to a file no sibling block owns is granted and widens this node's
749
- * effective scope (a too-narrow — or empty — declared scope no longer blocks a
750
- * correct fix; this is the sanctioned "extend into unowned files" path);
751
- * - an edit to a file in another block's declared scope is a seam conflict that
752
- * blocks until the seam protocol re-scopes or serialises the nodes.
753
- * Cross-sibling contention on a file two live nodes both touch (neither declared)
754
- * is left to the merge-time lost-update detector (`detectOverlappingEdits`), which
755
- * sees the full set of merged blocks a single accept cannot.
756
- */
757
- export declare function adjudicateWriteScope(allBlockScopes: Array<{
758
- block_id: string;
759
- write_paths: string[];
760
- }>, blockId: string, edited: GitEditedFiles, root: string): WriteScopeDecision;
761
- /**
762
- * Accept-time write-scope gate, run from `acceptNodeWorktree` AFTER the verify and
763
- * BEFORE the cherry-pick so a violation PREVENTS the merge rather than being
764
- * reported once the edit already landed in main. Thin git wrapper around
765
- * {@link adjudicateWriteScope}: resolves the branch's actual edits and adjudicates.
766
- */
767
- export declare function enforceAcceptWriteScope(params: {
768
- root: string;
769
- branch: string;
770
- blockId: string;
771
- allBlockScopes: Array<{
772
- block_id: string;
773
- write_paths: string[];
774
- }>;
775
- }): WriteScopeDecision;
776
- /**
777
- * Build the map from a known obligation/node alias to the finding id that owns
778
- * it, for one block. A worker that mislabels its `finding_id` as an obligation
779
- * id it was assigned (or a CP-BLOCK-prefixed/unprefixed node alias) is remapped
780
- * to the owning node's finding rather than dropped as an orphan — the tolerant
781
- * seam (the host is a variable of any strength). The map only ever points at
782
- * findings that belong to THIS block, so a mislabel can never resolve to an
783
- * unrelated node.
784
- */
785
- export declare function buildBlockAliasMap(block: RemediationBlock, state: RemediationState): Map<string, string>;
786
- /**
787
- * Collapse a worker result's `item_results` to one entry per resolved finding
788
- * id, applying the block alias map first (obligation/node-alias → finding). When
789
- * several entries collapse onto the same finding, a single `blocked` entry wins
790
- * over `resolved` (a node is not complete if any reported facet failed), and the
791
- * union of evidence / first failure_reason is preserved. Entries whose id is
792
- * neither a known finding nor a known alias are returned in `unresolved` so the
793
- * caller can record them as orphans.
794
- */
795
- export declare function collapseItemResults(itemResults: ImplementWorkerResult["item_results"], aliasMap: Map<string, string>, knownFindingIds: Set<string>): {
796
- collapsed: ImplementWorkerResult["item_results"];
797
- unresolved: ImplementWorkerResult["item_results"];
798
- };
799
- export type NodeDispositionStatus = "verified_complete" | "blocked" | "skipped" | "missing_result";
800
- export interface NodeDisposition {
801
- node_id: string;
802
- block_id: string;
803
- disposition: NodeDispositionStatus;
804
- /** The state status the node's finding(s) ended in. */
805
- finding_status: string;
806
- /** Reconciliation expectations the node was responsible for honoring (INV-DS-12). */
807
- reconciliation_expectations: string[];
808
- /** Why the node landed in this disposition (failure_reason / skip reason). */
809
- reason?: string;
810
- }
811
- /**
812
- * Build the per-node disposition for a block (INV-DS-15). A SKIP disposition
813
- * (user-skipped: `ignored` / `deemed_inappropriate`) is NEVER reported as
814
- * `verified_complete`. Each block maps 1:1 to a node, so the disposition keys on
815
- * the block's first finding (the node id).
816
- */
817
- export declare function buildNodeDisposition(block: RemediationBlock, state: RemediationState): NodeDisposition;
818
- /**
819
- * Attribute a post-merge sibling-block failure (INV-DS-14). Given the repo-
820
- * relative paths implicated by a red sibling and the merged blocks' declared
821
- * write scopes, return the exactly-one block whose scope contains an implicated
822
- * file (attributable → route THAT sibling to triage). When zero or more than one
823
- * merged block could own the failure, the red is unattributable and is deferred
824
- * to the rolling-scheduler's coarse backstop (return null).
825
- */
826
- export declare function attributeSiblingRed(implicatedFiles: string[], mergedBlockScopes: Array<{
827
- block_id: string;
828
- write_paths: string[];
829
- }>, root: string): string | null;
830
- /** A merged block's ACTUAL edited file set (resolved from its worktree branch diff). */
831
- export interface BlockEditedFiles {
832
- block_id: string;
833
- /** Repo-relative forward-slash paths the block's worker actually changed. */
834
- files: Set<string>;
835
- /**
836
- * The block's ACTUAL edited hunks (new-side line ranges), when git could
837
- * resolve them. When absent / unavailable, {@link detectOverlappingEdits} MUST
838
- * fail closed and treat any same-file pairing as a potential collision — a
839
- * missing hunk map is never disjointness evidence.
840
- */
841
- hunks?: GitBranchHunks;
842
- }
843
- /** One detected overlap: two merged blocks whose actual edits hit the same file. */
844
- export interface OverlappingEdit {
845
- path: string;
846
- block_ids: string[];
847
- }
848
- /**
849
- * Detect lost-update hazards across concurrently-merged blocks (ARC-f378135d-2 /
850
- * ARC-c1693139). When the rolling engine dispatches multiple nodes in flight and
851
- * each worker edits in its own worktree, two workers can both modify the SAME
852
- * file; cherry-picking both branches silently drops one worker's change to that
853
- * file (lost update). This pure function returns every repo-relative path that
854
- * appears in more than one merged block's ACTUAL edit set, with the owning block
855
- * ids. The caller routes the involved blocks to triage so the conflict is
856
- * reconciled rather than silently losing an edit. Result-file artifacts and the
857
- * agent-feedback file are sanctioned side outputs and are never counted as
858
- * overlaps.
859
- */
860
- export declare function detectOverlappingEdits(editedByBlock: BlockEditedFiles[]): OverlappingEdit[];
861
- export declare function mergeImplementResults(options: DispatchOptions, runId: string): Promise<RemediationState>;
862
- export declare function readExtractedPlanIfPresent(artifactsDir: string): Promise<unknown | undefined>;
863
- export declare function readDispatchPlan(artifactsDir: string, runId: string, phase: "implement"): Promise<RemediationDispatchPlan>;
1
+ export type { DispatchOptions, GitEditedFiles, GitBranchHunk, GitBranchHunks, } from "./dispatch/common.js";
2
+ export { gitTopLevel, worktreeBranchForBlock, gitEditedFilesForBranch, gitHunksForBranch, parseUnifiedDiffHunks, writeScopeViolations, detectRepoConventionsCache, } from "./dispatch/common.js";
3
+ export type { DagNodeFields } from "./dispatch/dagNodeFields.js";
4
+ export type { HostConcurrencyLimit } from "audit-tools/shared";
5
+ export { resolveHostActiveSubagentLimit, detectHostConcurrencyFromEnv, normalizeSlotTokens, resolveHostConcurrencyLimit, scheduleWave, buildConfirmedPools, buildDispatchQuota, } from "./dispatch/waveScheduling.js";
6
+ export type { ScheduleWaveInput, WaveScheduleResult, } from "./dispatch/waveScheduling.js";
7
+ export type { WorktreeVerifyResult } from "./dispatch/worktreeLifecycle.js";
8
+ export { createWorktree, seedUntrackedDeclaredPaths, removeWorktree, resetNodeWorktreeAndBranch, verifyNodeInWorktree, mergeWorktree, dirtyMainTreeCollisions, rebaseBranchOntoHead, worktreePath, remediationBranchName, baseBranchLockPath, quarantineRef, quarantineFailedNodeCommit, quarantineUncommittedWorktreeEdits, clearQuarantinedCommit, listQuarantinedCommits, remediationBaseBranchPath, readRemediationBaseBranch, ensureRemediationBranchCheckedOut, commitWorktree, ensureWorktreeNodeModules, } from "./dispatch/worktreeLifecycle.js";
9
+ export type { NodeWorkerOutcome, AcceptNodeWorktreeParams, AcceptNodeWorktreeResult, WorktreeNodeWorker, NodeWorktreeExecution, } from "./dispatch/acceptNode.js";
10
+ export { acceptNodeWorktree, nodeAcceptOutcomePath, recordNodeAcceptOutcome, loadNodeAcceptOutcome, executeNodeInWorktree, } from "./dispatch/acceptNode.js";
11
+ export { isBuildFreeVerifyCommand, normalizeNodeTestCommand, isWholeSuiteTestCommand, pathTokensInCommand, selfContainedVerifyCommands, verifyCommandsForEdits, deriveVerifyCommandsFromBranch, targetedCommandsForBlock, } from "./dispatch/verifyCommands.js";
12
+ export type { TestFileEntry } from "./dispatch/implementPrompt.js";
13
+ export { buildImplementModelHint, implementResultPath, isInfraModifyingBlock, buildTestFileIndex, collectReferencingTests, } from "./dispatch/implementPrompt.js";
14
+ export type { WriteScopeDecision, NodeDispositionStatus, NodeDisposition, BlockEditedFiles, OverlappingEdit, } from "./dispatch/writeScope.js";
15
+ export { enforceWriteScope, blockScopesFromPlan, declaredPathsFromPlan, adjudicateWriteScope, enforceAcceptWriteScope, buildBlockAliasMap, collapseItemResults, buildNodeDisposition, attributeSiblingRed, detectOverlappingEdits, } from "./dispatch/writeScope.js";
16
+ export { prepareImplementDispatch, mergeImplementResults, readExtractedPlanIfPresent, readDispatchPlan, } from "./dispatch/marshal.js";
864
17
  //# sourceMappingURL=dispatch.d.ts.map