audit-tools 0.34.14 → 0.34.16
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.
- package/dispatch/merge-results.mjs +84 -24
- package/dispatch/validate.mjs +21 -3
- package/dist/audit/cli/dispatch/packetFilter.d.ts.map +1 -1
- package/dist/audit/cli/dispatch/packetFilter.js +7 -14
- package/dist/audit/cli/dispatch/packetFilter.js.map +1 -1
- package/dist/audit/cli/nextStepCommand.d.ts.map +1 -1
- package/dist/audit/cli/nextStepCommand.js +7 -1
- package/dist/audit/cli/nextStepCommand.js.map +1 -1
- package/dist/audit/cli/scoreAuditCommand.d.ts.map +1 -1
- package/dist/audit/cli/scoreAuditCommand.js +6 -1
- package/dist/audit/cli/scoreAuditCommand.js.map +1 -1
- package/dist/audit/extractors/graphSignals.d.ts +37 -9
- package/dist/audit/extractors/graphSignals.d.ts.map +1 -1
- package/dist/audit/extractors/graphSignals.js +69 -9
- package/dist/audit/extractors/graphSignals.js.map +1 -1
- package/dist/audit/orchestrator/pendingTasks.d.ts +26 -0
- package/dist/audit/orchestrator/pendingTasks.d.ts.map +1 -0
- package/dist/audit/orchestrator/pendingTasks.js +13 -0
- package/dist/audit/orchestrator/pendingTasks.js.map +1 -0
- package/dist/audit/orchestrator/planningExecutors.d.ts +12 -1
- package/dist/audit/orchestrator/planningExecutors.d.ts.map +1 -1
- package/dist/audit/orchestrator/planningExecutors.js +43 -9
- package/dist/audit/orchestrator/planningExecutors.js.map +1 -1
- package/dist/audit/orchestrator/state.d.ts.map +1 -1
- package/dist/audit/orchestrator/state.js +31 -22
- package/dist/audit/orchestrator/state.js.map +1 -1
- package/dist/audit/supervisor/operatorHandoff.d.ts.map +1 -1
- package/dist/audit/supervisor/operatorHandoff.js +19 -16
- package/dist/audit/supervisor/operatorHandoff.js.map +1 -1
- package/dist/remediate/dispatch/ownershipRegistry.d.ts +17 -1
- package/dist/remediate/dispatch/ownershipRegistry.d.ts.map +1 -1
- package/dist/remediate/dispatch/ownershipRegistry.js +21 -3
- package/dist/remediate/dispatch/ownershipRegistry.js.map +1 -1
- package/dist/remediate/phases/close.d.ts +49 -1
- package/dist/remediate/phases/close.d.ts.map +1 -1
- package/dist/remediate/phases/close.js +57 -14
- package/dist/remediate/phases/close.js.map +1 -1
- package/dist/remediate/phases/plan.d.ts.map +1 -1
- package/dist/remediate/phases/plan.js +66 -6
- package/dist/remediate/phases/plan.js.map +1 -1
- package/dist/remediate/phases/triage.d.ts.map +1 -1
- package/dist/remediate/phases/triage.js +52 -5
- package/dist/remediate/phases/triage.js.map +1 -1
- package/dist/remediate/review/reviewGate.d.ts +14 -0
- package/dist/remediate/review/reviewGate.d.ts.map +1 -1
- package/dist/remediate/review/reviewGate.js +22 -0
- package/dist/remediate/review/reviewGate.js.map +1 -1
- package/dist/remediate/state/store.d.ts.map +1 -1
- package/dist/remediate/state/store.js +64 -1
- package/dist/remediate/state/store.js.map +1 -1
- package/dist/remediate/steps/dispatch/acceptNode.d.ts +15 -0
- package/dist/remediate/steps/dispatch/acceptNode.d.ts.map +1 -1
- package/dist/remediate/steps/dispatch/acceptNode.js +98 -26
- package/dist/remediate/steps/dispatch/acceptNode.js.map +1 -1
- package/dist/remediate/steps/dispatch/acceptReconcile.d.ts +66 -0
- package/dist/remediate/steps/dispatch/acceptReconcile.d.ts.map +1 -0
- package/dist/remediate/steps/dispatch/acceptReconcile.js +154 -0
- package/dist/remediate/steps/dispatch/acceptReconcile.js.map +1 -0
- package/dist/remediate/steps/dispatch/verifyCommands.d.ts.map +1 -1
- package/dist/remediate/steps/dispatch/verifyCommands.js +29 -15
- package/dist/remediate/steps/dispatch/verifyCommands.js.map +1 -1
- package/dist/remediate/steps/nextStep.d.ts.map +1 -1
- package/dist/remediate/steps/nextStep.js +59 -23
- package/dist/remediate/steps/nextStep.js.map +1 -1
- package/dist/remediate/steps/rollingSession.d.ts +9 -0
- package/dist/remediate/steps/rollingSession.d.ts.map +1 -1
- package/dist/remediate/steps/rollingSession.js +61 -1
- package/dist/remediate/steps/rollingSession.js.map +1 -1
- package/dist/shared/dispatch/unifiedRolling.d.ts.map +1 -1
- package/dist/shared/dispatch/unifiedRolling.js +21 -0
- package/dist/shared/dispatch/unifiedRolling.js.map +1 -1
- package/dist/shared/findings/dedupe.d.ts +5 -2
- package/dist/shared/findings/dedupe.d.ts.map +1 -1
- package/dist/shared/findings/dedupe.js +56 -21
- package/dist/shared/findings/dedupe.js.map +1 -1
- package/dist/shared/friction/triage.d.ts.map +1 -1
- package/dist/shared/friction/triage.js +10 -3
- package/dist/shared/friction/triage.js.map +1 -1
- package/dist/shared/io/frictionCapture.d.ts +0 -14
- package/dist/shared/io/frictionCapture.d.ts.map +1 -1
- package/dist/shared/io/frictionCapture.js +48 -3
- package/dist/shared/io/frictionCapture.js.map +1 -1
- package/dist/shared/providers/openAiCompatibleProvider.d.ts.map +1 -1
- package/dist/shared/providers/openAiCompatibleProvider.js +51 -16
- package/dist/shared/providers/openAiCompatibleProvider.js.map +1 -1
- package/dist/shared/providers/providerFactory.d.ts +17 -0
- package/dist/shared/providers/providerFactory.d.ts.map +1 -1
- package/dist/shared/providers/providerFactory.js +11 -6
- package/dist/shared/providers/providerFactory.js.map +1 -1
- package/dist/shared/providers/proxyCatalog.d.ts.map +1 -1
- package/dist/shared/providers/proxyCatalog.js +20 -5
- package/dist/shared/providers/proxyCatalog.js.map +1 -1
- package/dist/shared/quota/capacity.d.ts.map +1 -1
- package/dist/shared/quota/capacity.js +13 -0
- package/dist/shared/quota/capacity.js.map +1 -1
- package/dist/shared/quota/fileLock.d.ts +8 -1
- package/dist/shared/quota/fileLock.d.ts.map +1 -1
- package/dist/shared/quota/fileLock.js +39 -1
- package/dist/shared/quota/fileLock.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* inv-8 — accept-outcome reconciliation (CE-201): bind the THREE durable
|
|
3
|
+
* records of a node's landing before any force-close mapping runs.
|
|
4
|
+
*
|
|
5
|
+
* The accept lifecycle has two unavoidable kill windows:
|
|
6
|
+
*
|
|
7
|
+
* window 1 — the process dies BETWEEN `mergeWorktree`'s cherry-pick and
|
|
8
|
+
* `recordNodeAcceptOutcome`: the commit IS on the base branch, but the
|
|
9
|
+
* sidecar on disk is a PRIOR attempt's stale `merged:false` (or absent);
|
|
10
|
+
* window 2 — the process dies BETWEEN `recordNodeAcceptOutcome` and the
|
|
11
|
+
* state merge: the sidecar says `merged:true`, but the item statuses are
|
|
12
|
+
* still in-progress.
|
|
13
|
+
*
|
|
14
|
+
* In both windows the run's durable records DISAGREE about a landed block. A
|
|
15
|
+
* force-close that trusts only the state (invariant 9's blocked mapping) then
|
|
16
|
+
* reports a LANDED fix as blocked and omits its files from the staging
|
|
17
|
+
* manifest. This module reconciles the disagreement from git ground truth:
|
|
18
|
+
*
|
|
19
|
+
* 1. git — the base-reachable tool-owned commits: `commitWorktree` stamps
|
|
20
|
+
* the exact subject `remediate <blockId> (<runId>)`, so a `git log
|
|
21
|
+
* --fixed-strings --grep` over HEAD ancestry, filtered to EXACT-subject
|
|
22
|
+
* matches, is the authoritative landed-evidence probe (a cherry-pick
|
|
23
|
+
* rewrites the OID but preserves the subject — the sidecar's
|
|
24
|
+
* `committed_oid` is the BRANCH tip, never the landed commit, which is
|
|
25
|
+
* why detection is disagreement-keyed rather than OID-equality-keyed,
|
|
26
|
+
* and never keyed on sidecar absence alone);
|
|
27
|
+
* 2. the sidecar (`accept-outcome-<block>.json`) — repaired to
|
|
28
|
+
* `merged:true` with the landed OID + files when git disproves it;
|
|
29
|
+
* 3. the state — in-progress items of a landed block are reconciled to
|
|
30
|
+
* `resolved`, and the landed files are unioned into
|
|
31
|
+
* `applied_edit_surface` (the close phase's staging manifest source).
|
|
32
|
+
*
|
|
33
|
+
* A block with NO landed evidence is left untouched — invariant 9's
|
|
34
|
+
* force-close blocked mapping stays valid exactly when reconciliation ran and
|
|
35
|
+
* found nothing (its precondition, pinned by the no-evidence control test).
|
|
36
|
+
*/
|
|
37
|
+
import { spawnSyncHidden } from "audit-tools/shared";
|
|
38
|
+
import { isInProgressStatus } from "../../state/itemStatus.js";
|
|
39
|
+
import { loadNodeAcceptOutcome, recordNodeAcceptOutcome } from "./acceptNode.js";
|
|
40
|
+
/** The exact tool-owned commit subject `commitWorktree` stamps for a block. */
|
|
41
|
+
function acceptCommitSubject(blockId, runId) {
|
|
42
|
+
return `remediate ${blockId} (${runId})`;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Base-reachable commits whose subject EXACTLY equals the block's tool subject.
|
|
46
|
+
* `--grep` is a substring match even with `--fixed-strings`, so the results are
|
|
47
|
+
* filtered to exact-subject equality — a human commit that merely mentions the
|
|
48
|
+
* subject can never count as landed evidence.
|
|
49
|
+
*/
|
|
50
|
+
function landedCommitsForBlock(root, blockId, runId) {
|
|
51
|
+
const subject = acceptCommitSubject(blockId, runId);
|
|
52
|
+
const log = spawnSyncHidden("git", ["log", "--format=%H%x1f%s", "--fixed-strings", `--grep=${subject}`, "HEAD"], { cwd: root, encoding: "utf8", shell: false });
|
|
53
|
+
if (log.error || log.status !== 0)
|
|
54
|
+
return [];
|
|
55
|
+
const out = [];
|
|
56
|
+
for (const line of (log.stdout ?? "").split("\n")) {
|
|
57
|
+
const [oid, s] = line.split("\x1f");
|
|
58
|
+
if (oid && s === subject)
|
|
59
|
+
out.push({ oid, subject: s });
|
|
60
|
+
}
|
|
61
|
+
return out;
|
|
62
|
+
}
|
|
63
|
+
/** Repo-relative files a commit touched. */
|
|
64
|
+
function filesOfCommit(root, oid) {
|
|
65
|
+
const show = spawnSyncHidden("git", ["diff-tree", "--no-commit-id", "--name-only", "-r", oid], { cwd: root, encoding: "utf8", shell: false });
|
|
66
|
+
if (show.error || show.status !== 0)
|
|
67
|
+
return [];
|
|
68
|
+
return (show.stdout ?? "")
|
|
69
|
+
.split("\n")
|
|
70
|
+
.map((l) => l.trim())
|
|
71
|
+
.filter((l) => l.length > 0);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Reconcile every block's three durable records against git ground truth.
|
|
75
|
+
* MUTATES `state` in place (items + applied_edit_surface) and repairs stale
|
|
76
|
+
* sidecars via {@link recordNodeAcceptOutcome} (whose merged:true guard makes
|
|
77
|
+
* the repair monotonic). Call BEFORE any force-close mapping — the close
|
|
78
|
+
* phase wires it at the top of `runClosePhase`.
|
|
79
|
+
*
|
|
80
|
+
* Never throws: a git failure degrades to "no landed evidence" (the
|
|
81
|
+
* conservative reading — nothing is force-resolved without proof).
|
|
82
|
+
*/
|
|
83
|
+
export async function reconcileAcceptOutcomes(args) {
|
|
84
|
+
const { root, artifactsDir, state } = args;
|
|
85
|
+
const runId = state.plan?.plan_id;
|
|
86
|
+
const blocks = state.plan?.blocks ?? [];
|
|
87
|
+
const result = { changed: false, reconciled: [] };
|
|
88
|
+
if (!runId || blocks.length === 0)
|
|
89
|
+
return result;
|
|
90
|
+
for (const block of blocks) {
|
|
91
|
+
const items = block.items
|
|
92
|
+
.map((id) => state.items?.[id])
|
|
93
|
+
.filter((it) => it !== undefined);
|
|
94
|
+
const sidecar = await loadNodeAcceptOutcome(artifactsDir, runId, block.block_id);
|
|
95
|
+
const anyInProgress = items.some((it) => isInProgressStatus(it.status));
|
|
96
|
+
const sidecarDisagrees = sidecar !== null && sidecar.merged !== true;
|
|
97
|
+
// Only probe git when a record disagrees with "cleanly landed and merged
|
|
98
|
+
// into state": an in-progress item (window 1 or 2) or a merged:false /
|
|
99
|
+
// absent sidecar alongside them. Fully-terminal blocks with a merged:true
|
|
100
|
+
// sidecar have nothing to reconcile.
|
|
101
|
+
if (!anyInProgress && !sidecarDisagrees)
|
|
102
|
+
continue;
|
|
103
|
+
const landed = landedCommitsForBlock(root, block.block_id, runId);
|
|
104
|
+
if (landed.length === 0) {
|
|
105
|
+
// No landed evidence: leave the records as they are — invariant 9's
|
|
106
|
+
// force-close blocked mapping is now justified for this block.
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
const landedFiles = [
|
|
110
|
+
...new Set(landed.flatMap((c) => filesOfCommit(root, c.oid))),
|
|
111
|
+
].sort();
|
|
112
|
+
const landedOids = landed.map((c) => c.oid);
|
|
113
|
+
// Record 2 — repair a stale sidecar to the git truth (monotonic: the
|
|
114
|
+
// recordNodeAcceptOutcome guard never regresses merged:true→false).
|
|
115
|
+
if (sidecar === null || sidecar.merged !== true) {
|
|
116
|
+
await recordNodeAcceptOutcome(artifactsDir, runId, block.block_id, {
|
|
117
|
+
outcome: "success",
|
|
118
|
+
verifyPassed: sidecar?.verifyPassed ?? true,
|
|
119
|
+
merged: true,
|
|
120
|
+
...(sidecar?.committedOid !== undefined
|
|
121
|
+
? { committedOid: sidecar.committedOid }
|
|
122
|
+
: {}),
|
|
123
|
+
landedHeadOid: landedOids[0],
|
|
124
|
+
editedFiles: landedFiles,
|
|
125
|
+
});
|
|
126
|
+
result.changed = true;
|
|
127
|
+
}
|
|
128
|
+
// Record 3 — reconcile in-progress items of the landed block to resolved
|
|
129
|
+
// and union the landed files into the staging manifest.
|
|
130
|
+
for (const item of items) {
|
|
131
|
+
if (!isInProgressStatus(item.status))
|
|
132
|
+
continue;
|
|
133
|
+
const now = new Date().toISOString();
|
|
134
|
+
item.status = "resolved";
|
|
135
|
+
item.started_at ??= now;
|
|
136
|
+
item.completed_at = now;
|
|
137
|
+
item.failure_reason = undefined;
|
|
138
|
+
result.changed = true;
|
|
139
|
+
}
|
|
140
|
+
if (landedFiles.length > 0) {
|
|
141
|
+
state.applied_edit_surface = [
|
|
142
|
+
...new Set([...(state.applied_edit_surface ?? []), ...landedFiles]),
|
|
143
|
+
].sort();
|
|
144
|
+
result.changed = true;
|
|
145
|
+
}
|
|
146
|
+
result.reconciled.push({
|
|
147
|
+
block_id: block.block_id,
|
|
148
|
+
landed_oids: landedOids,
|
|
149
|
+
landed_files: landedFiles,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
return result;
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=acceptReconcile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acceptReconcile.js","sourceRoot":"","sources":["../../../../src/remediate/steps/dispatch/acceptReconcile.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verifyCommands.d.ts","sourceRoot":"","sources":["../../../../src/remediate/steps/dispatch/verifyCommands.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAO7D;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"verifyCommands.d.ts","sourceRoot":"","sources":["../../../../src/remediate/steps/dispatch/verifyCommands.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAO7D;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CA4B7D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAM5D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAU5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,SAAS,GAAG,MAAM,EAAE,CAUhF;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAGzD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,MAAM,EAAE,EAClB,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,EAC1B,QAAQ,EAAE,MAAM,GACf,MAAM,EAAE,CAUV;AAaD;;;;;;;;;;GAUG;AACH;mEACmE;AACnE,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,CAW9E;AAED,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAIrF;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAS3F"}
|
|
@@ -20,24 +20,38 @@ import { gitEditedFilesForBranch } from "./common.js";
|
|
|
20
20
|
* - `node --test <path>`
|
|
21
21
|
*/
|
|
22
22
|
export function isBuildFreeVerifyCommand(cmd) {
|
|
23
|
-
|
|
24
|
-
if (c.length === 0)
|
|
23
|
+
if (cmd.trim().length === 0)
|
|
25
24
|
return false;
|
|
26
|
-
//
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
// INV-RSM-VERIFY-01 (COR-8c497987): judge each shell-chained INVOCATION on its
|
|
26
|
+
// own flags, never the whole string — `tsc --noEmit && tsc -p build` must not
|
|
27
|
+
// pass because a `--noEmit` appears SOMEWHERE in the command. Split on the
|
|
28
|
+
// shell chain separators (&&, ||, ;, |, newline) first, then validate every
|
|
29
|
+
// segment independently; one emitting segment forbids the whole command.
|
|
30
|
+
const segments = cmd
|
|
31
|
+
.replace(/\r\n/g, "\n")
|
|
32
|
+
.split(/&&|\|\||[;|\n]/)
|
|
33
|
+
.map((s) => s.trim().toLowerCase().replace(/\s+/g, " "))
|
|
34
|
+
.filter((s) => s.length > 0);
|
|
35
|
+
if (segments.length === 0)
|
|
33
36
|
return false;
|
|
37
|
+
for (const c of segments) {
|
|
38
|
+
// Any explicit build step is forbidden.
|
|
39
|
+
if (/\bnpm\s+run\s+build\b/.test(c))
|
|
40
|
+
return false;
|
|
41
|
+
if (/\btsc\b.*(-b\b|--build\b)/.test(c))
|
|
42
|
+
return false;
|
|
43
|
+
if (/(^|\s)tsc(\s|$)/.test(c) && !/--noemit\b/.test(c)) {
|
|
44
|
+
// A bare `tsc` (or `tsc -p ...`) emits unless --noEmit is set — judged
|
|
45
|
+
// per invocation, so a sibling segment's --noEmit cannot vouch for it.
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
// A build-prepending `npm test` / `npm t` / `npm run test` is forbidden; the
|
|
49
|
+
// build-free runner (vitest run / node --test) must be invoked directly.
|
|
50
|
+
if (/\bnpm\s+(test|t)\b/.test(c))
|
|
51
|
+
return false;
|
|
52
|
+
if (/\bnpm\s+run\s+test\b/.test(c))
|
|
53
|
+
return false;
|
|
34
54
|
}
|
|
35
|
-
// A build-prepending `npm test` / `npm t` / `npm run test` is forbidden; the
|
|
36
|
-
// build-free runner (vitest run / node --test) must be invoked directly.
|
|
37
|
-
if (/\bnpm\s+(test|t)\b/.test(c))
|
|
38
|
-
return false;
|
|
39
|
-
if (/\bnpm\s+run\s+test\b/.test(c))
|
|
40
|
-
return false;
|
|
41
55
|
return true;
|
|
42
56
|
}
|
|
43
57
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verifyCommands.js","sourceRoot":"","sources":["../../../../src/remediate/steps/dispatch/verifyCommands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAEtD,8EAA8E;AAC9E,8DAA8D;AAC9D,8EAA8E;AAE9E;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,wBAAwB,CAAC,GAAW;IAClD,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"verifyCommands.js","sourceRoot":"","sources":["../../../../src/remediate/steps/dispatch/verifyCommands.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nextStep.d.ts","sourceRoot":"","sources":["../../../src/remediate/steps/nextStep.ts"],"names":[],"mappings":"AAIA,OAAO,EAAc,KAAK,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC7F,OAAO,KAAK,EAGV,gBAAgB,EAGjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAmrB,KAAK,sBAAsB,EAA8C,KAAK,iBAAiB,EAAE,KAAK,aAAa,EAAE,KAAK,oBAAoB,EAAE,KAAK,YAAY,EAAE,KAAK,yBAAyB,EAAE,KAAK,qBAAqB,EAAE,KAAK,YAAY,EAAsN,sBAAsB,EAA+d,KAAK,YAAY,EAAoD,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAmC7uD,OAAO,KAAK,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAE3E,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EAEzB,MAAM,wBAAwB,CAAC;AAOhC,OAAO,EAKL,KAAK,UAAU,EAChB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"nextStep.d.ts","sourceRoot":"","sources":["../../../src/remediate/steps/nextStep.ts"],"names":[],"mappings":"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"}
|
|
@@ -26,7 +26,7 @@ import { resolveIntakeStep } from "./intakeResolver.js";
|
|
|
26
26
|
import { runToolOwnedFinalGate, applyCoarseReblock, readFinalGateSidecar, writeFinalGateSidecar, } from "./finalGate.js";
|
|
27
27
|
import { buildNextContractPipelineStep, shouldEnterContractPipeline, writePathASeedFromFindings, buildLeanExtractedPlan, } from "./contractPipeline.js";
|
|
28
28
|
import { contractArtifactExists, contractPipelineDir, } from "../contractPipeline/artifactStore.js";
|
|
29
|
-
import { buildReviewRequest, applyReviewResolution, } from "../review/reviewGate.js";
|
|
29
|
+
import { buildReviewRequest, applyReviewResolution, isResolutionForRequest, } from "../review/reviewGate.js";
|
|
30
30
|
import { buildAutonomousReviewDecision } from "../review/autonomousGate.js";
|
|
31
31
|
import { runFindingFilterPass } from "../findingFilter.js";
|
|
32
32
|
import { intakePaths, isIntakeReady, readIntakeArtifacts, resolveManifestSources, } from "../intake.js";
|
|
@@ -1945,8 +1945,6 @@ async function handlePendingExtractedPlan(root, artifactsDir, existing, extracte
|
|
|
1945
1945
|
// pipeline. File-driven and pre-state (no RemediationState exists at intake yet),
|
|
1946
1946
|
// mirroring the intake-clarification gate rather than waiting_for_clarification.
|
|
1947
1947
|
const REVIEW_DECISION_SCHEMA_VERSION = "remediate-code-review-decision/v1";
|
|
1948
|
-
/** Stable, informational plan id for the pre-plan review request/decision pair. */
|
|
1949
|
-
const REVIEW_GATE_PLAN_ID = "path-a-review";
|
|
1950
1948
|
function reviewRequestPath(artifactsDir) {
|
|
1951
1949
|
return join(artifactsDir, "review_request.json");
|
|
1952
1950
|
}
|
|
@@ -2016,11 +2014,12 @@ async function runReviewApprovalGate(root, artifactsDir, survivors, autonomous =
|
|
|
2016
2014
|
if (gateOpen && autonomous) {
|
|
2017
2015
|
const auto = buildAutonomousReviewDecision(survivors);
|
|
2018
2016
|
const approvedSet = new Set(auto.approved_ids);
|
|
2019
|
-
// Leftovers stay LIVE: declined is EMPTY (no durable rejection). The
|
|
2020
|
-
//
|
|
2017
|
+
// Leftovers stay LIVE: declined is EMPTY (no durable rejection). The
|
|
2018
|
+
// decision REPLAY keys on approved_ids (COR-227a02ae), so on later calls
|
|
2019
|
+
// exactly the approved subset — never the live leftovers — re-enters.
|
|
2021
2020
|
const record = {
|
|
2022
2021
|
schema_version: REVIEW_DECISION_SCHEMA_VERSION,
|
|
2023
|
-
plan_id:
|
|
2022
|
+
plan_id: randomRunId("path-a-review"),
|
|
2024
2023
|
approved_ids: auto.approved_ids,
|
|
2025
2024
|
declined: [],
|
|
2026
2025
|
created_at: new Date().toISOString(),
|
|
@@ -2042,7 +2041,9 @@ async function runReviewApprovalGate(root, artifactsDir, survivors, autonomous =
|
|
|
2042
2041
|
const requestPath = reviewRequestPath(artifactsDir);
|
|
2043
2042
|
if (!existsSync(resolutionPath)) {
|
|
2044
2043
|
// Halt: present the tiered survivors and wait for the user's decision.
|
|
2045
|
-
|
|
2044
|
+
// The request's plan id is minted RUN-UNIQUE so a stale resolution from
|
|
2045
|
+
// another run can never correlate against it (COR-0b906e37).
|
|
2046
|
+
const request = buildReviewRequest(survivors, randomRunId("path-a-review"));
|
|
2046
2047
|
await writeJsonFile(requestPath, request);
|
|
2047
2048
|
return {
|
|
2048
2049
|
kind: "halt",
|
|
@@ -2051,12 +2052,22 @@ async function runReviewApprovalGate(root, artifactsDir, survivors, autonomous =
|
|
|
2051
2052
|
}
|
|
2052
2053
|
// Consume the resolution into a durable, reasoned decision record.
|
|
2053
2054
|
const request = (await readOptionalJsonFile(requestPath)) ??
|
|
2054
|
-
buildReviewRequest(survivors,
|
|
2055
|
+
buildReviewRequest(survivors, randomRunId("path-a-review"));
|
|
2055
2056
|
const resolution = await readOptionalJsonFile(resolutionPath);
|
|
2057
|
+
if (!isResolutionForRequest(request, resolution)) {
|
|
2058
|
+
// Stale cross-run resolution (plan_id mismatch): archive it and RE-HALT
|
|
2059
|
+
// with the live request rather than applying another run's answer.
|
|
2060
|
+
await withFsRetry(() => rename(resolutionPath, `${resolutionPath}.stale-${Date.now()}`));
|
|
2061
|
+
await writeJsonFile(requestPath, request);
|
|
2062
|
+
return {
|
|
2063
|
+
kind: "halt",
|
|
2064
|
+
step: await handleWaitingForReviewApproval(root, artifactsDir, request),
|
|
2065
|
+
};
|
|
2066
|
+
}
|
|
2056
2067
|
const decision = applyReviewResolution(request, resolution);
|
|
2057
2068
|
const record = {
|
|
2058
2069
|
schema_version: REVIEW_DECISION_SCHEMA_VERSION,
|
|
2059
|
-
plan_id:
|
|
2070
|
+
plan_id: request.plan_id,
|
|
2060
2071
|
approved_ids: decision.approved_ids,
|
|
2061
2072
|
declined: decision.declined,
|
|
2062
2073
|
created_at: new Date().toISOString(),
|
|
@@ -2069,13 +2080,20 @@ async function runReviewApprovalGate(root, artifactsDir, survivors, autonomous =
|
|
|
2069
2080
|
}
|
|
2070
2081
|
}
|
|
2071
2082
|
}
|
|
2072
|
-
// Decision recorded (now or on a prior call): split the survivors.
|
|
2083
|
+
// Decision recorded (now or on a prior call): split the survivors. The
|
|
2084
|
+
// replay honours the recorded approved_ids (COR-227a02ae) — an autonomous
|
|
2085
|
+
// decision approves a SUBSET with declined EMPTY (leftovers live but not
|
|
2086
|
+
// approved), so keying the replay on the declined set alone would silently
|
|
2087
|
+
// re-approve every leftover on the next call.
|
|
2073
2088
|
const decision = await readOptionalJsonFile(decisionPath);
|
|
2074
2089
|
const declined = decision?.declined ?? [];
|
|
2075
2090
|
const declinedIds = new Set(declined.map((d) => d.finding_id));
|
|
2091
|
+
const approvedIds = decision ? new Set(decision.approved_ids ?? []) : undefined;
|
|
2076
2092
|
return {
|
|
2077
2093
|
kind: "proceed",
|
|
2078
|
-
approved:
|
|
2094
|
+
approved: approvedIds !== undefined
|
|
2095
|
+
? survivors.filter((f) => approvedIds.has(f.id))
|
|
2096
|
+
: survivors.filter((f) => !declinedIds.has(f.id)),
|
|
2079
2097
|
declined,
|
|
2080
2098
|
};
|
|
2081
2099
|
}
|
|
@@ -2279,6 +2297,17 @@ async function handleReadyIntakeContractPipeline(root, artifactsDir, options) {
|
|
|
2279
2297
|
if (!pipeline.shouldHandleContractPipeline) {
|
|
2280
2298
|
return null;
|
|
2281
2299
|
}
|
|
2300
|
+
// The effective session config is loaded BEFORE the review gate
|
|
2301
|
+
// (COR-5f8fb354): the gate's attended-vs-autonomous resolution must see the
|
|
2302
|
+
// PERSISTED session-config.json (`autonomous_mode`), not only a programmatic
|
|
2303
|
+
// override — resolving from the bare CLI options meant a nightly unattended
|
|
2304
|
+
// run halted for a human at the review gate. The same loaded config feeds
|
|
2305
|
+
// the dispatch-capability resolution further down (single load).
|
|
2306
|
+
const sessionConfigForDispatch = await loadRemediateSessionConfig({
|
|
2307
|
+
root,
|
|
2308
|
+
override: options?.sessionConfig,
|
|
2309
|
+
artifactsFirst: true,
|
|
2310
|
+
});
|
|
2282
2311
|
// Path A: run the single filter pass over the ORIGINAL findings, present the
|
|
2283
2312
|
// SURVIVORS at the review gate (deduped / evidence-bearing / path-grounded /
|
|
2284
2313
|
// checkpoint-kept, tiered by review-necessity), then seed the pipeline with the
|
|
@@ -2304,7 +2333,10 @@ async function handleReadyIntakeContractPipeline(root, artifactsDir, options) {
|
|
|
2304
2333
|
checkpoint: checkpoint ?? undefined,
|
|
2305
2334
|
evidenceGrounding: true,
|
|
2306
2335
|
});
|
|
2307
|
-
const gate = await runReviewApprovalGate(root, artifactsDir, filter.survivors,
|
|
2336
|
+
const gate = await runReviewApprovalGate(root, artifactsDir, filter.survivors,
|
|
2337
|
+
// Autonomy resolves from the PERSISTED session config (hoisted load
|
|
2338
|
+
// above) → env → attended default, never from the bare CLI options.
|
|
2339
|
+
resolveAutonomousMode({ sessionConfig: sessionConfigForDispatch }));
|
|
2308
2340
|
if (gate.kind === "halt") {
|
|
2309
2341
|
return gate.step;
|
|
2310
2342
|
}
|
|
@@ -2415,12 +2447,8 @@ async function handleReadyIntakeContractPipeline(root, artifactsDir, options) {
|
|
|
2415
2447
|
// (`resolveHostDispatchCapability`) implement dispatch uses — never a manual
|
|
2416
2448
|
// flag. Threaded into the contract pipeline so the adversarial 'critique' /
|
|
2417
2449
|
// 'critic' prompts MANDATE an independent sub-agent reviewer when the host can
|
|
2418
|
-
// dispatch one (fail-safe: mandate by default).
|
|
2419
|
-
|
|
2420
|
-
root,
|
|
2421
|
-
override: options?.sessionConfig,
|
|
2422
|
-
artifactsFirst: true,
|
|
2423
|
-
});
|
|
2450
|
+
// dispatch one (fail-safe: mandate by default). The config itself was loaded
|
|
2451
|
+
// once, above the review gate (COR-5f8fb354).
|
|
2424
2452
|
const hostCanDispatchSubagents = resolveHostDispatchCapability({
|
|
2425
2453
|
hostCanDispatchSubagents: options?.hostCanDispatchSubagents,
|
|
2426
2454
|
sessionConfig: sessionConfigForDispatch,
|
|
@@ -2665,8 +2693,6 @@ async function handleWaitingForTriage(root, artifactsDir, state) {
|
|
|
2665
2693
|
},
|
|
2666
2694
|
});
|
|
2667
2695
|
}
|
|
2668
|
-
/** Stable, informational plan id for the Path-B (planning-point) review pair. */
|
|
2669
|
-
const REVIEW_GATE_PLAN_ID_PATH_B = "path-b-review";
|
|
2670
2696
|
/**
|
|
2671
2697
|
* Path-B (document / conversation) review-necessity gate, fired at the PLANNING
|
|
2672
2698
|
* point over the deduped/grounded node findings. Path A records its review
|
|
@@ -2690,20 +2716,30 @@ async function runPlanningReviewGate(root, artifactsDir, state, store) {
|
|
|
2690
2716
|
const requestPath = reviewRequestPath(artifactsDir);
|
|
2691
2717
|
const resolutionPath = reviewResolutionPath(artifactsDir);
|
|
2692
2718
|
const decisionPath = reviewDecisionPath(artifactsDir);
|
|
2719
|
+
// Path B correlates on the LIVE plan's own id (INV-RSM-RESOLUTION-CORRELATE):
|
|
2720
|
+
// the plan exists at the planning point, so its plan_id is the natural
|
|
2721
|
+
// run-unique key — a stale resolution from an earlier plan can never match.
|
|
2722
|
+
const reviewPlanId = state.plan?.plan_id ?? randomRunId("path-b-review");
|
|
2693
2723
|
if (!existsSync(resolutionPath)) {
|
|
2694
2724
|
// Halt: present the tiered node findings and wait for the user's decision.
|
|
2695
|
-
const request = buildReviewRequest(findings,
|
|
2725
|
+
const request = buildReviewRequest(findings, reviewPlanId);
|
|
2696
2726
|
await writeJsonFile(requestPath, request);
|
|
2697
2727
|
return handleWaitingForReviewApproval(root, artifactsDir, request);
|
|
2698
2728
|
}
|
|
2699
2729
|
// Resolution present: consume it into a durable, reasoned decision record.
|
|
2700
2730
|
const request = (await readOptionalJsonFile(requestPath)) ??
|
|
2701
|
-
buildReviewRequest(findings,
|
|
2731
|
+
buildReviewRequest(findings, reviewPlanId);
|
|
2702
2732
|
const resolution = await readOptionalJsonFile(resolutionPath);
|
|
2733
|
+
if (!isResolutionForRequest(request, resolution)) {
|
|
2734
|
+
// Stale cross-run resolution: archive it and re-halt with the live request.
|
|
2735
|
+
await withFsRetry(() => rename(resolutionPath, `${resolutionPath}.stale-${Date.now()}`));
|
|
2736
|
+
await writeJsonFile(requestPath, request);
|
|
2737
|
+
return handleWaitingForReviewApproval(root, artifactsDir, request);
|
|
2738
|
+
}
|
|
2703
2739
|
const decision = applyReviewResolution(request, resolution);
|
|
2704
2740
|
const record = {
|
|
2705
2741
|
schema_version: REVIEW_DECISION_SCHEMA_VERSION,
|
|
2706
|
-
plan_id:
|
|
2742
|
+
plan_id: request.plan_id,
|
|
2707
2743
|
approved_ids: decision.approved_ids,
|
|
2708
2744
|
declined: decision.declined,
|
|
2709
2745
|
created_at: new Date().toISOString(),
|