audit-tools 0.30.6 → 0.30.9
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/README.md +229 -0
- package/audit-code.mjs +1 -1
- package/dist/audit/cli/dispatch/packetPrompt.d.ts.map +1 -1
- package/dist/audit/cli/dispatch/packetPrompt.js +1 -0
- package/dist/audit/cli/dispatch/packetPrompt.js.map +1 -1
- package/dist/audit/cli/dispatch.d.ts.map +1 -1
- package/dist/audit/cli/dispatch.js +4 -1
- package/dist/audit/cli/dispatch.js.map +1 -1
- package/dist/audit/cli/mergeAndIngestCommand.d.ts.map +1 -1
- package/dist/audit/cli/mergeAndIngestCommand.js +76 -35
- package/dist/audit/cli/mergeAndIngestCommand.js.map +1 -1
- package/dist/audit/cli/nextStepCommand.d.ts.map +1 -1
- package/dist/audit/cli/nextStepCommand.js +8 -3
- package/dist/audit/cli/nextStepCommand.js.map +1 -1
- package/dist/audit/cli/nextStepHelpers.d.ts +2 -0
- package/dist/audit/cli/nextStepHelpers.d.ts.map +1 -1
- package/dist/audit/cli/nextStepHelpers.js +49 -16
- package/dist/audit/cli/nextStepHelpers.js.map +1 -1
- package/dist/audit/cli/prompts.d.ts +2 -1
- package/dist/audit/cli/prompts.d.ts.map +1 -1
- package/dist/audit/cli/prompts.js +12 -3
- package/dist/audit/cli/prompts.js.map +1 -1
- package/dist/audit/cli/rollingAuditDispatch.d.ts.map +1 -1
- package/dist/audit/cli/rollingAuditDispatch.js +18 -1
- package/dist/audit/cli/rollingAuditDispatch.js.map +1 -1
- package/dist/audit/io/toolingManifest.d.ts +1 -1
- package/dist/audit/io/toolingManifest.d.ts.map +1 -1
- package/dist/audit/io/toolingManifest.js +1 -1
- package/dist/audit/io/toolingManifest.js.map +1 -1
- package/dist/audit/orchestrator/auditTaskUtils.js +1 -1
- package/dist/audit/orchestrator/dependencyMap.js +1 -1
- package/dist/audit/orchestrator/executorRunners.d.ts.map +1 -1
- package/dist/audit/orchestrator/executorRunners.js +6 -9
- package/dist/audit/orchestrator/executorRunners.js.map +1 -1
- package/dist/audit/orchestrator/nextStep.d.ts +5 -9
- package/dist/audit/orchestrator/nextStep.d.ts.map +1 -1
- package/dist/audit/orchestrator/nextStep.js +5 -9
- package/dist/audit/orchestrator/nextStep.js.map +1 -1
- package/dist/audit/orchestrator/planningExecutors.js +2 -2
- package/dist/audit/orchestrator/taskAffinityGraph.js +1 -1
- package/dist/audit/types.d.ts +3 -3
- package/dist/audit/types.js +1 -1
- package/dist/remediate/contractPipeline/derive.d.ts +1 -1
- package/dist/remediate/contractPipeline/derive.js +1 -1
- package/dist/remediate/dispatch/amendmentClaim.d.ts +7 -0
- package/dist/remediate/dispatch/amendmentClaim.d.ts.map +1 -1
- package/dist/remediate/dispatch/amendmentClaim.js +7 -0
- package/dist/remediate/dispatch/amendmentClaim.js.map +1 -1
- package/dist/remediate/dispatch/ownershipRegistry.d.ts +88 -2
- package/dist/remediate/dispatch/ownershipRegistry.d.ts.map +1 -1
- package/dist/remediate/dispatch/ownershipRegistry.js +224 -11
- package/dist/remediate/dispatch/ownershipRegistry.js.map +1 -1
- package/dist/remediate/dispatch/ownershipScheduler.d.ts +48 -0
- package/dist/remediate/dispatch/ownershipScheduler.d.ts.map +1 -0
- package/dist/remediate/dispatch/ownershipScheduler.js +100 -0
- package/dist/remediate/dispatch/ownershipScheduler.js.map +1 -0
- package/dist/remediate/steps/nextStep.d.ts +17 -2
- package/dist/remediate/steps/nextStep.d.ts.map +1 -1
- package/dist/remediate/steps/nextStep.js +76 -70
- package/dist/remediate/steps/nextStep.js.map +1 -1
- package/dist/remediate/steps/providerNodeDispatch.d.ts.map +1 -1
- package/dist/remediate/steps/providerNodeDispatch.js +16 -1
- package/dist/remediate/steps/providerNodeDispatch.js.map +1 -1
- package/dist/remediate/validation/contractPipelineGates.js +1 -1
- package/dist/shared/engine/obligationEngine.d.ts +1 -1
- package/dist/shared/engine/obligationEngine.js +1 -1
- package/dist/shared/friction/triage.d.ts +50 -20
- package/dist/shared/friction/triage.d.ts.map +1 -1
- package/dist/shared/friction/triage.js +70 -23
- package/dist/shared/friction/triage.js.map +1 -1
- package/dist/shared/index.d.ts +2 -2
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/index.js +1 -1
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/quota/scheduler.d.ts +1 -1
- package/dist/shared/repair/brokeredDispatch.d.ts +1 -1
- package/dist/shared/types/rollingDispatch.d.ts +1 -1
- package/package.json +4 -3
- package/{audit-code-wrapper-build.mjs → wrapper/audit-code-wrapper-build.mjs} +1 -1
- package/{audit-code-wrapper-install-hosts.mjs → wrapper/audit-code-wrapper-install-hosts.mjs} +1 -1
- package/{audit-code-wrapper-lib.mjs → wrapper/audit-code-wrapper-lib.mjs} +1 -1
- package/README.audit.md +0 -222
- package/README.remediate.md +0 -112
- /package/{audit-code-wrapper-install-renderers.mjs → wrapper/audit-code-wrapper-install-renderers.mjs} +0 -0
- /package/{audit-code-wrapper-io.mjs → wrapper/audit-code-wrapper-io.mjs} +0 -0
- /package/{audit-code-wrapper-legacy.mjs → wrapper/audit-code-wrapper-legacy.mjs} +0 -0
- /package/{audit-code-wrapper-opencode.mjs → wrapper/audit-code-wrapper-opencode.mjs} +0 -0
|
@@ -2,7 +2,7 @@ import { existsSync } from "node:fs";
|
|
|
2
2
|
import { mkdir, readFile, rename } from "node:fs/promises";
|
|
3
3
|
import { dirname, join, resolve } from "node:path";
|
|
4
4
|
import { StateStore } from "../state/store.js";
|
|
5
|
-
import { readOptionalJsonFile, writeJsonFile, writeTextFile, buildAuditDeliverablePair, formatValidationIssues, isRecord, withFsRetry, RunLogger, DO_NOT_TOKEN_WRAP_NOTE, DISPATCH_PROMPT_HANDOFF_NOTE, renderQuotaCoverageNudge, coerceJsonObjectArg, createRollingDispatcher, setQuotaStateDir, interpretFreeFormIntent, advance, decideFrictionTriage, planHybridDispatch, readSettledPools, addSettledPool, sourceByPoolId } from "audit-tools/shared";
|
|
5
|
+
import { readOptionalJsonFile, writeJsonFile, writeTextFile, buildAuditDeliverablePair, formatValidationIssues, isRecord, withFsRetry, RunLogger, DO_NOT_TOKEN_WRAP_NOTE, DISPATCH_PROMPT_HANDOFF_NOTE, renderQuotaCoverageNudge, coerceJsonObjectArg, createRollingDispatcher, setQuotaStateDir, interpretFreeFormIntent, advance, decideFrictionTriage, buildFrictionTriageBlock, planHybridDispatch, readSettledPools, addSettledPool, sourceByPoolId } from "audit-tools/shared";
|
|
6
6
|
import { applyPlanPipeline, buildCoverageLedger } from "../phases/plan.js";
|
|
7
7
|
import { groundExtractedFindings } from "../phases/grounding.js";
|
|
8
8
|
import { runTriagePhase } from "../phases/triage.js";
|
|
@@ -10,6 +10,7 @@ import { runClosePhase } from "../phases/close.js";
|
|
|
10
10
|
import { validateRemediationPlan } from "../validation/remediationState.js";
|
|
11
11
|
import { mergeImplementResults, prepareImplementDispatch, readExtractedPlanIfPresent, buildConfirmedPools, executeNodeInWorktree, blockScopesFromPlan, declaredPathsFromPlan, targetedCommandsForBlock, } from "./dispatch.js";
|
|
12
12
|
import { makeProviderNodeDispatcher } from "./providerNodeDispatch.js";
|
|
13
|
+
import { ownershipSubWaves } from "../dispatch/ownershipScheduler.js";
|
|
13
14
|
import { prepareHostRollingDispatch, nodeClaimRegistry, nodeSettledPoolsPath } from "./rollingSession.js";
|
|
14
15
|
import { writeCurrentStep } from "./stepWriter.js";
|
|
15
16
|
import { dependencyVerifiedComplete } from "./stepUtils.js";
|
|
@@ -112,7 +113,10 @@ function resolveArtifactsDir(root, artifactsDir) {
|
|
|
112
113
|
return resolve(artifactsDir ?? join(root, ".audit-tools", "remediation"));
|
|
113
114
|
}
|
|
114
115
|
function stateRunId(state) {
|
|
115
|
-
|
|
116
|
+
// When the plan is absent (fully-green close deleted the state, or complete
|
|
117
|
+
// was persisted without a plan), use the stable fallback "run" so the friction
|
|
118
|
+
// record path is deterministic across multiple next-step calls on the same run.
|
|
119
|
+
return state?.plan?.plan_id ?? "run";
|
|
116
120
|
}
|
|
117
121
|
function defaultInputCandidates(root) {
|
|
118
122
|
// Prefer the canonical machine contract (audit-findings.json) over its
|
|
@@ -245,8 +249,14 @@ function blockedByUnsatisfiedDependency(state) {
|
|
|
245
249
|
* prerequisite is skipped/blocked, not merely pending) is NOT placed in any
|
|
246
250
|
* level — it is dead-ended by `handlePlanning`.
|
|
247
251
|
*
|
|
248
|
-
* Pure and deterministic:
|
|
249
|
-
*
|
|
252
|
+
* Pure and deterministic: level MEMBERSHIP is fixed by the dependency predicate
|
|
253
|
+
* (INV-RS-01) and is independent of node order; the interposed-rebuild boundaries
|
|
254
|
+
* are therefore stable across runs without an in-level numeric sort. In-level
|
|
255
|
+
* admission ORDER is no longer decided here — it is owned by the file-ownership
|
|
256
|
+
* scheduler (`ownershipSubWaves`, INV-SOO-04/08), which applies its own explicit
|
|
257
|
+
* block_id tie-break AFTER the disjointness filter. The numeric
|
|
258
|
+
* `block_id.localeCompare` admission ordering that used to live here was removed
|
|
259
|
+
* atomically with that change (INV-SOO-04).
|
|
250
260
|
*/
|
|
251
261
|
export function rollingDependencyLevels(state) {
|
|
252
262
|
const plan = state.plan;
|
|
@@ -254,9 +264,7 @@ export function rollingDependencyLevels(state) {
|
|
|
254
264
|
if (!plan || !items)
|
|
255
265
|
return [];
|
|
256
266
|
const blockById = new Map(plan.blocks.map((b) => [b.block_id, b]));
|
|
257
|
-
const pendingBlocks = plan.blocks
|
|
258
|
-
.filter((b) => b.items.some((id) => items[id]?.status === "pending"))
|
|
259
|
-
.sort((a, b) => a.block_id.localeCompare(b.block_id));
|
|
267
|
+
const pendingBlocks = plan.blocks.filter((b) => b.items.some((id) => items[id]?.status === "pending"));
|
|
260
268
|
// A dependency edge is "completable" only when the dep node is itself pending
|
|
261
269
|
// (will be satisfied by some level) or already verified-complete. A skipped /
|
|
262
270
|
// blocked dependency makes the dependent permanently ineligible — such nodes
|
|
@@ -340,23 +348,34 @@ export async function driveRollingDispatch(levels, options) {
|
|
|
340
348
|
}
|
|
341
349
|
}
|
|
342
350
|
const blockByPacketId = new Map(level.map((b) => [b.block_id, b]));
|
|
343
|
-
const
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
351
|
+
const scopeForBlock = options.scopeForBlock ?? ((b) => b.touched_files ?? []);
|
|
352
|
+
// File-ownership-disjoint admission (INV-SOO): split the level into ordered
|
|
353
|
+
// sub-waves, each a maximal file-disjoint subset (deterministic block_id
|
|
354
|
+
// tie-break AFTER the disjointness filter, INV-SOO-08). Same-file nodes land
|
|
355
|
+
// in successive sub-waves (serialize, INV-SOO-01/02) and a freed file becomes
|
|
356
|
+
// schedulable for the next sub-wave; different-file nodes share a sub-wave and
|
|
357
|
+
// parallelize up to the quota cap the dispatcher enforces (INV-SOO-03/05).
|
|
358
|
+
const subWaves = ownershipSubWaves(level.map((b) => ({ block_id: b.block_id, write_paths: scopeForBlock(b) })), options.root);
|
|
359
|
+
const levelResults = [];
|
|
360
|
+
for (const wave of subWaves) {
|
|
361
|
+
const packets = wave.map((node) => ({
|
|
362
|
+
id: node.block_id,
|
|
363
|
+
payload: { block_id: node.block_id },
|
|
364
|
+
estimatedTokens: estimateTokens(blockByPacketId.get(node.block_id)),
|
|
365
|
+
complexity: 0.5,
|
|
366
|
+
}));
|
|
367
|
+
const dispatcher = createRollingDispatcher({
|
|
368
|
+
confirmedPools: options.confirmedPools,
|
|
369
|
+
sessionConfig: options.sessionConfig,
|
|
370
|
+
dispatchPacket: async (packet, slot) => {
|
|
371
|
+
const block = blockByPacketId.get(packet.payload.block_id);
|
|
372
|
+
return options.dispatchNode(block, slot);
|
|
373
|
+
},
|
|
374
|
+
});
|
|
375
|
+
dispatcher.enqueue(packets);
|
|
376
|
+
levelResults.push(...(await dispatcher.run()));
|
|
377
|
+
}
|
|
378
|
+
out.levels.push({ blockIds: level.map((b) => b.block_id), results: levelResults });
|
|
360
379
|
}
|
|
361
380
|
return out;
|
|
362
381
|
}
|
|
@@ -543,12 +562,18 @@ export async function driveRollingImplementDispatch(options) {
|
|
|
543
562
|
}
|
|
544
563
|
return result;
|
|
545
564
|
};
|
|
565
|
+
// Declared write-scope per block, from the dispatch plan — the same authority
|
|
566
|
+
// the merge-time write-scope gate reads — for file-ownership-disjoint admission
|
|
567
|
+
// (INV-SOO). A block with no plan scope falls back to its touched_files.
|
|
568
|
+
const writePathsByBlock = new Map(allBlockScopes.map((s) => [s.block_id, s.write_paths]));
|
|
546
569
|
await driveRollingDispatch(levels, {
|
|
547
570
|
confirmedPools,
|
|
548
571
|
sessionConfig: options.sessionConfig ?? {},
|
|
549
572
|
dispatchNode: dispatchNodeWithWorktree,
|
|
550
573
|
rebuildSharedBetweenLevels: options.rebuildSharedBetweenLevels,
|
|
551
574
|
quotaStateDir: artifactsDir,
|
|
575
|
+
root,
|
|
576
|
+
scopeForBlock: (block) => writePathsByBlock.get(block.block_id) ?? block.touched_files ?? [],
|
|
552
577
|
});
|
|
553
578
|
// Deterministic merge: same path the wave flow uses (tolerant remap, write-scope
|
|
554
579
|
// gate against each verified branch, lost-update detection). Worktrees are
|
|
@@ -996,56 +1021,36 @@ async function forceReplanFromExistingIntake(root, artifactsDir, previous, store
|
|
|
996
1021
|
}
|
|
997
1022
|
async function presentReportStep(root, artifactsDir, state) {
|
|
998
1023
|
const reportPath = join(dirname(artifactsDir), "remediation-report.md");
|
|
999
|
-
//
|
|
1000
|
-
//
|
|
1001
|
-
//
|
|
1002
|
-
//
|
|
1003
|
-
//
|
|
1004
|
-
//
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
against its id into the run's friction record at \`${triage.recordPath}\` (append to
|
|
1014
|
-
\`dispositions[]\` as \`{ "target_id": "<id>", "disposition": "keep|discard|annotate",
|
|
1015
|
-
optional "annotation": "..." }\`). This is the run's own record under its artifacts
|
|
1016
|
-
dir — do NOT edit any repository's tracking/backlog doc.
|
|
1017
|
-
|
|
1018
|
-
${triage.pending
|
|
1019
|
-
.map((subject) => `- \`${subject.id}\` (${subject.source}) — ${subject.note}`)
|
|
1020
|
-
.join("\n")}
|
|
1021
|
-
`
|
|
1022
|
-
: `
|
|
1023
|
-
|
|
1024
|
-
## Run friction triage
|
|
1025
|
-
|
|
1026
|
-
No captured friction or agent-feedback reflections required disposition this run
|
|
1027
|
-
(empty set → trivially disposed).
|
|
1028
|
-
`;
|
|
1024
|
+
// Terminal friction-TRIAGE close-out, folded into present_report (single-sourced in
|
|
1025
|
+
// `audit-tools/shared`). MANDATORY + BLOCKING: stays "dispose" until every mechanical
|
|
1026
|
+
// event + reflection is disposed AND ≥1 open observation written. Never trivially
|
|
1027
|
+
// satisfied by an empty event set — the host must actively confirm the friction state.
|
|
1028
|
+
//
|
|
1029
|
+
// When `artifactsDir` was deleted by a fully-green close (close.ts rm -rf on a
|
|
1030
|
+
// green run), there is nowhere to persist the friction record and no mechanical
|
|
1031
|
+
// events to triage — skip the triage entirely and go straight to complete.
|
|
1032
|
+
const artifactsDirExists = existsSync(artifactsDir);
|
|
1033
|
+
const triage = artifactsDirExists
|
|
1034
|
+
? await decideRemediateFrictionCloseout(artifactsDir, state)
|
|
1035
|
+
: null;
|
|
1036
|
+
const frictionBlock = triage ? buildFrictionTriageBlock(triage) : "";
|
|
1037
|
+
const isBlocked = triage?.action === "dispose";
|
|
1029
1038
|
return writeCurrentStep({
|
|
1030
1039
|
stepKind: "present_report",
|
|
1031
|
-
status: "complete",
|
|
1040
|
+
status: isBlocked ? "ready" : "complete",
|
|
1032
1041
|
runId: stateRunId(state),
|
|
1033
1042
|
repoRoot: root,
|
|
1034
1043
|
artifactsDir,
|
|
1035
|
-
prompt:
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
Read \`${reportPath}\` and summarize the remediation outcome for the user.
|
|
1039
|
-
Mention the resolved, ignored, and deemed-inappropriate counts plus the closing action.
|
|
1040
|
-
${pendingBlock}
|
|
1041
|
-
Stop after presenting the summary (and disposing captured friction, if any).
|
|
1042
|
-
`,
|
|
1044
|
+
prompt: isBlocked
|
|
1045
|
+
? `# Remediation Run Friction Triage\n\nComplete friction triage before presenting the report.\n${frictionBlock}`
|
|
1046
|
+
: `# Present Remediation Report\n\nRead \`${reportPath}\` and summarize the remediation outcome.\nMention resolved, ignored, and deemed-inappropriate counts plus the closing action.\n${frictionBlock}`,
|
|
1043
1047
|
allowedCommands: [],
|
|
1044
|
-
stopCondition:
|
|
1048
|
+
stopCondition: isBlocked
|
|
1049
|
+
? "Complete friction triage (write dispositions and open_observations), then call next-step again."
|
|
1050
|
+
: "Present the remediation report summary and stop.",
|
|
1045
1051
|
artifactPaths: {
|
|
1046
1052
|
final_report: reportPath,
|
|
1047
|
-
|
|
1048
|
-
friction_record: triage.recordPath,
|
|
1053
|
+
...(triage ? { friction_record: triage.recordPath } : {}),
|
|
1049
1054
|
},
|
|
1050
1055
|
});
|
|
1051
1056
|
}
|
|
@@ -2363,10 +2368,11 @@ async function handleClosing(root, artifactsDir, state, runLogger, store) {
|
|
|
2363
2368
|
// Close-complete CROSSES the engine boundary: `complete` is a pre-intake
|
|
2364
2369
|
// obligation, unreachable from a main-engine transition. Emit the durable
|
|
2365
2370
|
// report directly, passing exactly what the original recursion reloaded — the
|
|
2366
|
-
// artifact dir is DELETED on a fully-green close (reload → null →
|
|
2367
|
-
// and PRESERVED on a not-green complete (reload → the
|
|
2368
|
-
// its plan_id). `store.loadState()` reproduces both, so
|
|
2369
|
-
// identical to the cascade.
|
|
2371
|
+
// artifact dir is DELETED on a fully-green close (reload → null → stateRunId
|
|
2372
|
+
// falls back to "run") and PRESERVED on a not-green complete (reload → the
|
|
2373
|
+
// saved complete state → its plan_id). `store.loadState()` reproduces both, so
|
|
2374
|
+
// present_report is identical to the cascade.
|
|
2375
|
+
// (Regression-locked in next-step-implement-dispatch.)
|
|
2370
2376
|
return {
|
|
2371
2377
|
kind: "emit",
|
|
2372
2378
|
step: await handleComplete(root, artifactsDir, await store.loadState()),
|