audit-tools 0.32.45 → 0.32.47
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/dist/audit/cli/dispatch.d.ts +1 -0
- package/dist/audit/cli/dispatch.d.ts.map +1 -1
- package/dist/audit/cli/dispatch.js +39 -18
- package/dist/audit/cli/dispatch.js.map +1 -1
- package/dist/audit/cli/mergeAndIngestCommand.d.ts +41 -0
- package/dist/audit/cli/mergeAndIngestCommand.d.ts.map +1 -1
- package/dist/audit/cli/mergeAndIngestCommand.js +105 -18
- package/dist/audit/cli/mergeAndIngestCommand.js.map +1 -1
- package/dist/audit/cli/ownerTokens.d.ts +21 -0
- package/dist/audit/cli/ownerTokens.d.ts.map +1 -0
- package/dist/audit/cli/ownerTokens.js +86 -0
- package/dist/audit/cli/ownerTokens.js.map +1 -0
- package/dist/remediate/phases/close.js +9 -9
- package/dist/remediate/phases/plan.d.ts +2 -30
- package/dist/remediate/phases/plan.d.ts.map +1 -1
- package/dist/remediate/phases/plan.js +5 -494
- package/dist/remediate/phases/plan.js.map +1 -1
- package/dist/remediate/state/store.d.ts +5 -6
- package/dist/remediate/state/store.d.ts.map +1 -1
- package/dist/remediate/state/store.js.map +1 -1
- package/dist/remediate/steps/dispatch/acceptNode.d.ts +27 -0
- package/dist/remediate/steps/dispatch/acceptNode.d.ts.map +1 -1
- package/dist/remediate/steps/dispatch/acceptNode.js +54 -18
- package/dist/remediate/steps/dispatch/acceptNode.js.map +1 -1
- package/dist/remediate/steps/dispatch/worktreeLifecycle.d.ts.map +1 -1
- package/dist/remediate/steps/dispatch/worktreeLifecycle.js +30 -2
- package/dist/remediate/steps/dispatch/worktreeLifecycle.js.map +1 -1
- package/dist/remediate/steps/nextStep.d.ts +12 -0
- package/dist/remediate/steps/nextStep.d.ts.map +1 -1
- package/dist/remediate/steps/nextStep.js +14 -4
- package/dist/remediate/steps/nextStep.js.map +1 -1
- package/dist/remediate/steps/rollingSession.d.ts.map +1 -1
- package/dist/remediate/steps/rollingSession.js +27 -1
- package/dist/remediate/steps/rollingSession.js.map +1 -1
- package/dist/shared/loopCorePaths.d.ts.map +1 -1
- package/dist/shared/loopCorePaths.js +2 -0
- package/dist/shared/loopCorePaths.js.map +1 -1
- package/dist/shared/quota/claimRegistry.d.ts +9 -0
- package/dist/shared/quota/claimRegistry.d.ts.map +1 -1
- package/dist/shared/quota/claimRegistry.js +20 -0
- package/dist/shared/quota/claimRegistry.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// ownerTokens.ts — run-scoped sidecar persisting audit-task claim owner
|
|
2
|
+
// tokens (D-66/67 slice-1, Part A: merge-time ownership gate).
|
|
3
|
+
//
|
|
4
|
+
// `dispatch.ts` captures `ownerTokenByNode` from `ClaimRegistry.claimMany`
|
|
5
|
+
// (task-claims.json) at dispatch time; `mergeAndIngestCommand.ts` reads it
|
|
6
|
+
// back at merge time to `heartbeat()`-verify a terminal task's claim is still
|
|
7
|
+
// ours before folding its result into the ingest and clearing its claim. A
|
|
8
|
+
// task whose lease was reclaimed by a peer (token rotated) fails the
|
|
9
|
+
// heartbeat and is excluded — see the ownership gate in mergeAndIngest.
|
|
10
|
+
//
|
|
11
|
+
// Deliberately RUN-SCOPED (`runs/<runId>/owner-tokens.json`), never parked on
|
|
12
|
+
// `active-dispatch.json`: that file is ONE per artifactsDir (no runId in its
|
|
13
|
+
// path) and is wholly rebuilt by `prepareDispatchArtifacts` every round, so
|
|
14
|
+
// tokens written there would be clobbered by this same run's next dispatch
|
|
15
|
+
// round or a cooperative peer's run — defeating the gate exactly where it
|
|
16
|
+
// matters. This sidecar instead merges ADDITIVELY per task_id, mirroring how
|
|
17
|
+
// `node-claims.json` is run-scoped on the remediate side.
|
|
18
|
+
//
|
|
19
|
+
// Tokens are opaque local strings minted by `ClaimRegistry`, not secrets.
|
|
20
|
+
import { readFile } from "node:fs/promises";
|
|
21
|
+
import { join } from "node:path";
|
|
22
|
+
import { isFileMissingError, withFileLock, writeJsonFile } from "audit-tools/shared";
|
|
23
|
+
/** `<runDir>/owner-tokens.json` — see module doc for why this is run-scoped. */
|
|
24
|
+
export function ownerTokensPath(runDir) {
|
|
25
|
+
return join(runDir, "owner-tokens.json");
|
|
26
|
+
}
|
|
27
|
+
function lockPathFor(path) {
|
|
28
|
+
return `${path}.lock`;
|
|
29
|
+
}
|
|
30
|
+
// Degrades ANY missing/malformed content to `{}` ("no token known for any
|
|
31
|
+
// task") rather than throwing — a corrupt or absent sidecar must never crash
|
|
32
|
+
// dispatch or merge; at worst every task reads as tokenless, which is the
|
|
33
|
+
// gate's documented fail-open case. Mirrors ClaimRegistry's own readClaimMap.
|
|
34
|
+
async function readOwnerTokenMap(path) {
|
|
35
|
+
let raw;
|
|
36
|
+
try {
|
|
37
|
+
raw = await readFile(path, "utf8");
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
if (isFileMissingError(error))
|
|
41
|
+
return {};
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
let parsed;
|
|
45
|
+
try {
|
|
46
|
+
parsed = JSON.parse(raw);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return {};
|
|
50
|
+
}
|
|
51
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed))
|
|
52
|
+
return {};
|
|
53
|
+
const out = {};
|
|
54
|
+
for (const [taskId, token] of Object.entries(parsed)) {
|
|
55
|
+
if (typeof token === "string")
|
|
56
|
+
out[taskId] = token;
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Read the persisted owner-token map for a run. Never throws — see
|
|
62
|
+
* `readOwnerTokenMap`. Absent for a task_id means "no token persisted for it"
|
|
63
|
+
* (fail-open at the ownership gate), not "claim absent".
|
|
64
|
+
*/
|
|
65
|
+
export async function readOwnerTokens(runDir) {
|
|
66
|
+
return readOwnerTokenMap(ownerTokensPath(runDir));
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Merge `tokensByTaskId` additively into the run-scoped sidecar: each task_id
|
|
70
|
+
* in `tokensByTaskId` overwrites (or adds) its own entry — a same-run
|
|
71
|
+
* re-dispatch round's re-grant rotates only that task's token — while every
|
|
72
|
+
* OTHER task's previously-persisted token is preserved untouched. Runs under
|
|
73
|
+
* a file lock so concurrent dispatch rounds (same run re-entry, cooperative
|
|
74
|
+
* peers sharing the run) never race a lost update. No-op when there is
|
|
75
|
+
* nothing to persist.
|
|
76
|
+
*/
|
|
77
|
+
export async function mergeOwnerTokens(runDir, tokensByTaskId) {
|
|
78
|
+
if (Object.keys(tokensByTaskId).length === 0)
|
|
79
|
+
return;
|
|
80
|
+
const path = ownerTokensPath(runDir);
|
|
81
|
+
await withFileLock(lockPathFor(path), async () => {
|
|
82
|
+
const existing = await readOwnerTokenMap(path);
|
|
83
|
+
await writeJsonFile(path, { ...existing, ...tokensByTaskId });
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=ownerTokens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ownerTokens.js","sourceRoot":"","sources":["../../../src/audit/cli/ownerTokens.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,+DAA+D;AAC/D,EAAE;AACF,2EAA2E;AAC3E,2EAA2E;AAC3E,8EAA8E;AAC9E,2EAA2E;AAC3E,qEAAqE;AACrE,wEAAwE;AACxE,EAAE;AACF,8EAA8E;AAC9E,6EAA6E;AAC7E,4EAA4E;AAC5E,2EAA2E;AAC3E,0EAA0E;AAC1E,6EAA6E;AAC7E,0DAA0D;AAC1D,EAAE;AACF,0EAA0E;AAE1E,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAIrF,gFAAgF;AAChF,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,OAAO,IAAI,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAC/B,OAAO,GAAG,IAAI,OAAO,CAAC;AACxB,CAAC;AAED,0EAA0E;AAC1E,6EAA6E;AAC7E,0EAA0E;AAC1E,8EAA8E;AAC9E,KAAK,UAAU,iBAAiB,CAAC,IAAY;IAC3C,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,kBAAkB,CAAC,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QACzC,MAAM,KAAK,CAAC;IACd,CAAC;IACD,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,CAAC;IACtF,MAAM,GAAG,GAAkB,EAAE,CAAC;IAC9B,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAiC,CAAC,EAAE,CAAC;QAChF,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,GAAG,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC;IACrD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAAc;IAClD,OAAO,iBAAiB,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAc,EACd,cAAuC;IAEvC,IAAI,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACrD,MAAM,IAAI,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,EAAE;QAC/C,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,aAAa,CAAC,IAAI,EAAE,EAAE,GAAG,QAAQ,EAAE,GAAG,cAAc,EAAE,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -337,15 +337,15 @@ const AUDIT_TOOLS_EXCLUDE_PATTERN = /^\.audit-tools\//;
|
|
|
337
337
|
* RUN-START-DIRTY GUARD on source (2) ONLY: declared surfaces are plan-time
|
|
338
338
|
* DECLARATIONS (write-access grants) / audit evidence — never verified against
|
|
339
339
|
* an actual diff. A declared file that was ALREADY dirty when the run started
|
|
340
|
-
* (`state.run_start_dirty`, captured
|
|
341
|
-
* edit exists) cannot be the run's edit, so it is excluded here —
|
|
342
|
-
* resolved item declaring a file the run never actually touched
|
|
343
|
-
* pre-existing user WIP into the closing commit (the exact
|
|
344
|
-
* this manifest exists to close). Ground-truth entries
|
|
345
|
-
* NEVER excluded by the snapshot: git proved the run
|
|
346
|
-
* tool-merged edit to a file the user ALSO had dirty
|
|
347
|
-
* tool legitimately owns. A state without
|
|
348
|
-
*
|
|
340
|
+
* (`state.run_start_dirty`, captured at the extracted-plan join site before any
|
|
341
|
+
* remediation edit exists) cannot be the run's edit, so it is excluded here —
|
|
342
|
+
* otherwise a resolved item declaring a file the run never actually touched
|
|
343
|
+
* would sweep pre-existing user WIP into the closing commit (the exact
|
|
344
|
+
* over-inclusion class this manifest exists to close). Ground-truth entries
|
|
345
|
+
* from source (1) are NEVER excluded by the snapshot: git proved the run
|
|
346
|
+
* landed those paths, and a tool-merged edit to a file the user ALSO had dirty
|
|
347
|
+
* at run start is a path the tool legitimately owns. A state without
|
|
348
|
+
* `run_start_dirty` (pre-field) means no exclusions.
|
|
349
349
|
*
|
|
350
350
|
* Both sources empty is legitimate (e.g. a run that only produced
|
|
351
351
|
* `resolved_no_change` / skipped items) and correctly yields an empty
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import { RemediationState } from "../state/store.js";
|
|
2
|
-
import { OrchestratorOptions } from "../types/options.js";
|
|
3
1
|
import { RemediationPlan, Finding, RemediationBlock, RemediationItemState, CoverageLedger } from "../state/types.js";
|
|
4
2
|
import type { AuditFindingsReport, FindingTheme } from "audit-tools/shared";
|
|
5
|
-
import { runTracked } from "audit-tools/shared";
|
|
6
3
|
/**
|
|
7
4
|
* Parse the auditor's canonical `audit-findings.json` (the machine contract) into
|
|
8
5
|
* remediation findings, work blocks, and synthesis themes. The auditor emits this
|
|
@@ -22,21 +19,6 @@ export declare function parseAuditFindingsReport(report: AuditFindingsReport): {
|
|
|
22
19
|
* contract_version is rejected here rather than silently trusted.
|
|
23
20
|
*/
|
|
24
21
|
export declare function isAuditFindingsReport(value: unknown): value is AuditFindingsReport;
|
|
25
|
-
interface PlanPhaseDeps {
|
|
26
|
-
enumerateTestFiles?: (root: string) => string[];
|
|
27
|
-
runCommand?: typeof runTracked;
|
|
28
|
-
now?: () => number;
|
|
29
|
-
/** Test seam: replaces the provider-backed free-form extraction worker. */
|
|
30
|
-
extractFindings?: (content: string, options: OrchestratorOptions) => Promise<{
|
|
31
|
-
findings: Finding[];
|
|
32
|
-
blocks: RemediationBlock[];
|
|
33
|
-
}>;
|
|
34
|
-
/** Test seam: replaces the provider-backed bounded path-repair worker. */
|
|
35
|
-
repairExtractedFindingPaths?: (requests: {
|
|
36
|
-
finding: Finding;
|
|
37
|
-
phantomPaths: string[];
|
|
38
|
-
}[]) => Promise<Map<string, string[]>>;
|
|
39
|
-
}
|
|
40
22
|
export declare function deriveBlocksFromTestGraph(findings: Finding[], testFiles: string[]): {
|
|
41
23
|
blocks: RemediationBlock[];
|
|
42
24
|
useful: boolean;
|
|
@@ -103,21 +85,11 @@ export declare function mergeBlocksSharingFiles(blocks: RemediationBlock[], find
|
|
|
103
85
|
* 2. splitBlocksByContextBudget — keeps each block within the agent context window
|
|
104
86
|
* 3. snapshotAffectedFileHashes — records baseline hashes for integrity checks
|
|
105
87
|
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
* logic and the two paths cannot drift apart.
|
|
88
|
+
* Sole caller is handlePendingExtractedPlan (LLM-extracted plans join site);
|
|
89
|
+
* kept as its own function so the post-dedup logic has one home.
|
|
109
90
|
*/
|
|
110
91
|
export declare function applyPlanPipeline(plan: RemediationPlan, options: {
|
|
111
92
|
root: string;
|
|
112
93
|
artifactsDir?: string;
|
|
113
94
|
}): Promise<RemediationPlan>;
|
|
114
|
-
/**
|
|
115
|
-
* Prune blocks so that every item reference is still in the kept-findings set,
|
|
116
|
-
* and drop blocks whose item list becomes empty after pruning.
|
|
117
|
-
* Used in runPlanPhase wherever a reduction step drops some findings.
|
|
118
|
-
* Extracted to eliminate the three formerly-duplicated inline occurrences of
|
|
119
|
-
* blocks.map(b => ({...b, items: b.items.filter(id => keptIds.has(id))})).filter(...)
|
|
120
|
-
*/
|
|
121
|
-
export declare function pruneBlocksForKeptFindings(blocks: RemediationBlock[], keptFindings: Finding[]): RemediationBlock[];
|
|
122
|
-
export declare function runPlanPhase(state: RemediationState, options: OrchestratorOptions, deps?: PlanPhaseDeps): Promise<RemediationState>;
|
|
123
95
|
//# sourceMappingURL=plan.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/remediate/phases/plan.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/remediate/phases/plan.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,OAAO,EACP,gBAAgB,EAChB,oBAAoB,EACpB,cAAc,EAEf,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAe5E;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,mBAAmB,GAAG;IACrE,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,MAAM,EAAE,YAAY,EAAE,CAAC;CACxB,CAgBA;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,mBAAmB,CAE9B;AAuBD,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,OAAO,EAAE,EACnB,SAAS,EAAE,MAAM,EAAE,GAClB;IAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAiDjD;AAKD,OAAO,EACL,gCAAgC,IAAI,2BAA2B,EAC/D,8BAA8B,IAAI,iCAAiC,GACpE,MAAM,oBAAoB,CAAC;AAoH5B,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAAE,EACpB,QAAQ,EAAE,OAAO,EAAE,EACnB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAMnC,IAAI,CAAC,EAAE,MAAM,GACZ,MAAM,CAeR;AA2BD,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,gBAAgB,EAAE,EAC1B,QAAQ,EAAE,OAAO,EAAE,EACnB,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,MAAM,GACpB,gBAAgB,EAAE,CA+FpB;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,OAAO,EAAE,CAAC;IAC1B,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,iFAAiF;IACjF,mBAAmB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC5C,oEAAoE;IACpE,mBAAmB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC5C;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjE,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;CAC7C,GAAG,cAAc,CAwFjB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,gBAAgB,EAAE,EAC1B,QAAQ,EAAE,OAAO,EAAE,EACnB,IAAI,SAAM,GACT,gBAAgB,EAAE,CA2DpB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,eAAe,EACrB,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/C,OAAO,CAAC,eAAe,CAAC,CAkB1B"}
|