audit-tools 0.55.6 → 0.55.8
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/lineIndex.d.ts.map +1 -1
- package/dist/audit/cli/lineIndex.js +19 -41
- package/dist/audit/cli/lineIndex.js.map +1 -1
- package/dist/audit/cli/nextStepCommand.d.ts.map +1 -1
- package/dist/audit/cli/nextStepCommand.js +5 -2
- package/dist/audit/cli/nextStepCommand.js.map +1 -1
- package/dist/audit/cli/nextStepHelpers.d.ts +6 -6
- package/dist/audit/cli/nextStepHelpers.d.ts.map +1 -1
- package/dist/audit/cli/nextStepHelpers.js +52 -129
- package/dist/audit/cli/nextStepHelpers.js.map +1 -1
- package/dist/audit/extractors/disposition.d.ts.map +1 -1
- package/dist/audit/extractors/disposition.js +14 -38
- package/dist/audit/extractors/disposition.js.map +1 -1
- package/dist/audit/extractors/graphManifestEdges/go.d.ts.map +1 -1
- package/dist/audit/extractors/graphManifestEdges/go.js +4 -10
- package/dist/audit/extractors/graphManifestEdges/go.js.map +1 -1
- package/dist/audit/extractors/graphManifestEdges/maven.d.ts.map +1 -1
- package/dist/audit/extractors/graphManifestEdges/maven.js +4 -10
- package/dist/audit/extractors/graphManifestEdges/maven.js.map +1 -1
- package/dist/audit/extractors/graphManifestEdges/packageJson.d.ts.map +1 -1
- package/dist/audit/extractors/graphManifestEdges/packageJson.js +4 -12
- package/dist/audit/extractors/graphManifestEdges/packageJson.js.map +1 -1
- package/dist/audit/extractors/graphManifestEdges/typescript.d.ts.map +1 -1
- package/dist/audit/extractors/graphManifestEdges/typescript.js +4 -10
- package/dist/audit/extractors/graphManifestEdges/typescript.js.map +1 -1
- package/dist/audit/extractors/graphPathUtils.d.ts +2 -0
- package/dist/audit/extractors/graphPathUtils.d.ts.map +1 -1
- package/dist/audit/extractors/graphPathUtils.js +14 -0
- package/dist/audit/extractors/graphPathUtils.js.map +1 -1
- package/dist/audit/extractors/readFileText.d.ts.map +1 -1
- package/dist/audit/extractors/readFileText.js +34 -5
- package/dist/audit/extractors/readFileText.js.map +1 -1
- package/dist/audit/orchestrator/acquisitionExecutor.d.ts +5 -2
- package/dist/audit/orchestrator/acquisitionExecutor.d.ts.map +1 -1
- package/dist/audit/orchestrator/acquisitionExecutor.js +28 -22
- package/dist/audit/orchestrator/acquisitionExecutor.js.map +1 -1
- package/dist/audit/orchestrator/reviewPacketGraphContext.d.ts +17 -0
- package/dist/audit/orchestrator/reviewPacketGraphContext.d.ts.map +1 -1
- package/dist/audit/orchestrator/reviewPacketGraphContext.js +51 -14
- package/dist/audit/orchestrator/reviewPacketGraphContext.js.map +1 -1
- package/dist/audit/orchestrator/reviewPacketSizing.d.ts +4 -4
- package/dist/audit/orchestrator/reviewPacketSizing.d.ts.map +1 -1
- package/dist/audit/orchestrator/reviewPacketSizing.js +5 -5
- package/dist/audit/orchestrator/reviewPacketSizing.js.map +1 -1
- package/dist/audit/orchestrator/reviewPackets.d.ts +2 -1
- package/dist/audit/orchestrator/reviewPackets.d.ts.map +1 -1
- package/dist/audit/orchestrator/reviewPackets.js +19 -11
- package/dist/audit/orchestrator/reviewPackets.js.map +1 -1
- package/dist/audit/orchestrator/runtimeCommand.d.ts +9 -2
- package/dist/audit/orchestrator/runtimeCommand.d.ts.map +1 -1
- package/dist/audit/orchestrator/runtimeCommand.js +14 -22
- package/dist/audit/orchestrator/runtimeCommand.js.map +1 -1
- package/dist/audit/orchestrator/scope.d.ts.map +1 -1
- package/dist/audit/orchestrator/scope.js +7 -2
- package/dist/audit/orchestrator/scope.js.map +1 -1
- package/dist/audit/orchestrator/scopeIndexBaseline.d.ts.map +1 -1
- package/dist/audit/orchestrator/scopeIndexBaseline.js +7 -29
- package/dist/audit/orchestrator/scopeIndexBaseline.js.map +1 -1
- package/dist/audit/orchestrator/selectiveDeepening/conflict.d.ts +6 -2
- package/dist/audit/orchestrator/selectiveDeepening/conflict.d.ts.map +1 -1
- package/dist/audit/orchestrator/selectiveDeepening/conflict.js +45 -4
- package/dist/audit/orchestrator/selectiveDeepening/conflict.js.map +1 -1
- package/dist/audit/orchestrator/selectiveDeepening/index.d.ts.map +1 -1
- package/dist/audit/orchestrator/selectiveDeepening/index.js +4 -4
- package/dist/audit/orchestrator/selectiveDeepening/index.js.map +1 -1
- package/dist/remediate/phases/close.d.ts.map +1 -1
- package/dist/remediate/phases/close.js +10 -7
- package/dist/remediate/phases/close.js.map +1 -1
- package/dist/remediate/phases/closeAcceptance.d.ts.map +1 -1
- package/dist/remediate/phases/closeAcceptance.js +2 -0
- package/dist/remediate/phases/closeAcceptance.js.map +1 -1
- package/dist/remediate/phases/closeVerifyAnalyzerLeads.d.ts +2 -1
- package/dist/remediate/phases/closeVerifyAnalyzerLeads.d.ts.map +1 -1
- package/dist/remediate/phases/closeVerifyAnalyzerLeads.js +10 -9
- package/dist/remediate/phases/closeVerifyAnalyzerLeads.js.map +1 -1
- package/dist/remediate/state/dirtyBaseline.d.ts +10 -0
- package/dist/remediate/state/dirtyBaseline.d.ts.map +1 -0
- package/dist/remediate/state/dirtyBaseline.js +18 -0
- package/dist/remediate/state/dirtyBaseline.js.map +1 -0
- package/dist/remediate/state/store.d.ts +4 -4
- package/dist/remediate/state/store.d.ts.map +1 -1
- package/dist/remediate/state/store.js +8 -0
- package/dist/remediate/state/store.js.map +1 -1
- package/dist/remediate/steps/dispatch/hostCorroboration.d.ts.map +1 -1
- package/dist/remediate/steps/dispatch/hostCorroboration.js +34 -82
- package/dist/remediate/steps/dispatch/hostCorroboration.js.map +1 -1
- package/dist/remediate/steps/dispatch/hostHandoff.d.ts.map +1 -1
- package/dist/remediate/steps/dispatch/hostHandoff.js +6 -1
- package/dist/remediate/steps/dispatch/hostHandoff.js.map +1 -1
- package/dist/remediate/steps/finalGate.d.ts.map +1 -1
- package/dist/remediate/steps/finalGate.js +11 -5
- package/dist/remediate/steps/finalGate.js.map +1 -1
- package/dist/remediate/steps/gateCommands.d.ts +1 -0
- package/dist/remediate/steps/gateCommands.d.ts.map +1 -1
- package/dist/remediate/steps/gateCommands.js +7 -11
- package/dist/remediate/steps/gateCommands.js.map +1 -1
- package/dist/remediate/steps/nextStep.d.ts +0 -10
- package/dist/remediate/steps/nextStep.d.ts.map +1 -1
- package/dist/remediate/steps/nextStep.js +55 -59
- package/dist/remediate/steps/nextStep.js.map +1 -1
- package/dist/shared/analyzers/acquisitionEngine.d.ts +12 -5
- package/dist/shared/analyzers/acquisitionEngine.d.ts.map +1 -1
- package/dist/shared/analyzers/acquisitionEngine.js +86 -38
- package/dist/shared/analyzers/acquisitionEngine.js.map +1 -1
- package/dist/shared/analyzers/binaryAcquisition.d.ts +17 -41
- package/dist/shared/analyzers/binaryAcquisition.d.ts.map +1 -1
- package/dist/shared/analyzers/binaryAcquisition.js +260 -227
- package/dist/shared/analyzers/binaryAcquisition.js.map +1 -1
- package/dist/shared/analyzers/binaryFetcher.d.ts +4 -0
- package/dist/shared/analyzers/binaryFetcher.d.ts.map +1 -0
- package/dist/shared/analyzers/binaryFetcher.js +79 -0
- package/dist/shared/analyzers/binaryFetcher.js.map +1 -0
- package/dist/shared/analyzers/binaryVersions.d.ts +5 -0
- package/dist/shared/analyzers/binaryVersions.d.ts.map +1 -0
- package/dist/shared/analyzers/binaryVersions.js +31 -0
- package/dist/shared/analyzers/binaryVersions.js.map +1 -0
- package/dist/shared/analyzers/candidates.d.ts +3 -3
- package/dist/shared/analyzers/candidates.d.ts.map +1 -1
- package/dist/shared/analyzers/candidates.js +35 -12
- package/dist/shared/analyzers/candidates.js.map +1 -1
- package/dist/shared/git.d.ts +38 -3
- package/dist/shared/git.d.ts.map +1 -1
- package/dist/shared/git.js +169 -55
- package/dist/shared/git.js.map +1 -1
- package/dist/shared/gitTrackedPaths.d.ts +39 -0
- package/dist/shared/gitTrackedPaths.d.ts.map +1 -0
- package/dist/shared/gitTrackedPaths.js +29 -0
- package/dist/shared/gitTrackedPaths.js.map +1 -0
- package/dist/shared/index.d.ts +4 -2
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/index.js +5 -2
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/io/sourcePath.d.ts +8 -0
- package/dist/shared/io/sourcePath.d.ts.map +1 -0
- package/dist/shared/io/sourcePath.js +38 -0
- package/dist/shared/io/sourcePath.js.map +1 -0
- package/dist/shared/tooling/exec.d.ts +1 -0
- package/dist/shared/tooling/exec.d.ts.map +1 -1
- package/dist/shared/tooling/exec.js +20 -4
- package/dist/shared/tooling/exec.js.map +1 -1
- package/dist/shared/tooling/resolveExecutable.d.ts +10 -0
- package/dist/shared/tooling/resolveExecutable.d.ts.map +1 -0
- package/dist/shared/tooling/resolveExecutable.js +46 -0
- package/dist/shared/tooling/resolveExecutable.js.map +1 -0
- package/dist/shared/validation/citationGrounding.d.ts +1 -1
- package/dist/shared/validation/citationGrounding.d.ts.map +1 -1
- package/dist/shared/validation/citationGrounding.js +24 -11
- package/dist/shared/validation/citationGrounding.js.map +1 -1
- package/dist/shared/validation/findingGrounding.d.ts +1 -1
- package/dist/shared/validation/findingGrounding.d.ts.map +1 -1
- package/dist/shared/validation/findingGrounding.js +11 -23
- package/dist/shared/validation/findingGrounding.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { admitRemediationDirtyBaseline, RemediationDirtyBaselineError } from "../state/dirtyBaseline.js";
|
|
1
2
|
import { readDecisionSnapshot, decisionContextDigest } from "../state/decisionConsumption.js";
|
|
2
3
|
import { RemediationPlanAuthorityError } from "../contractPipeline/runtimePlanAuthority.js";
|
|
3
4
|
import { reopenStaleTriageSuccesses } from "../phases/triageConformance.js";
|
|
@@ -441,13 +442,14 @@ async function saveStateForPlan(artifactsDir, existing, plan, planCoverage) {
|
|
|
441
442
|
return state;
|
|
442
443
|
}
|
|
443
444
|
async function forceReplanFromExistingIntake(root, artifactsDir, previous, runLogger) {
|
|
445
|
+
admitRemediationDirtyBaseline(previous);
|
|
444
446
|
const step = await buildNextContractPipelineStep({ root, artifactsDir, runId: requireStateRunId(previous), forceRevision: false });
|
|
445
447
|
if (step)
|
|
446
448
|
return { kind: "planning_step", step };
|
|
447
449
|
const approved = await readApprovedExecutionPlan(artifactsDir);
|
|
448
450
|
if (!approved)
|
|
449
451
|
return { kind: "blocked", reason: "Revise and independently approve the current executable plan before replanning. Accepted execution history is preserved." };
|
|
450
|
-
const activated = await activateApprovedPlan(root, artifactsDir, previous, approved, runLogger);
|
|
452
|
+
const activated = await activateApprovedPlan(root, artifactsDir, previous, approved, runLogger, "existing_run");
|
|
451
453
|
if (activated.kind === "blocked")
|
|
452
454
|
return activated;
|
|
453
455
|
// Activation already carries unchanged history and applies CURRENT owner
|
|
@@ -708,7 +710,11 @@ async function emitPlanRevisionBlockedStep(root, artifactsDir, blocked) {
|
|
|
708
710
|
prompt: `# Executable plan requires attention\n\n${blocked.reason}\nThe current plan and accepted execution history are preserved. Revise the plan through its tool-issued submission and obtain fresh review before continuing.`,
|
|
709
711
|
allowedCommands: [loaderCommand("next-step")], stopCondition: "Resolve the named plan/review issue before implementation.", artifactPaths: { execution_plan: executionPlanPaths(artifactsDir).canonical } });
|
|
710
712
|
}
|
|
711
|
-
async function activateApprovedPlan(root, artifactsDir, existing, _input, _runLogger) {
|
|
713
|
+
async function activateApprovedPlan(root, artifactsDir, existing, _input, _runLogger, origin) {
|
|
714
|
+
if (origin === "existing_run")
|
|
715
|
+
admitRemediationDirtyBaseline(existing);
|
|
716
|
+
else if ("run_start_dirty" in existing || "run_start_dirty_encoding" in existing)
|
|
717
|
+
throw new RemediationDirtyBaselineError();
|
|
712
718
|
const approved = await readApprovedExecutionPlan(artifactsDir);
|
|
713
719
|
if (!approved)
|
|
714
720
|
return { kind: "blocked", reason: "No current independently approved executable plan exists. Re-run planning; unreviewed projections cannot dispatch." };
|
|
@@ -728,8 +734,9 @@ async function activateApprovedPlan(root, artifactsDir, existing, _input, _runLo
|
|
|
728
734
|
...(facts.commands.e2e ? { e2e_command: renderPromptCommand(facts.commands.e2e), e2e_command_source: "project_facts" } : {}),
|
|
729
735
|
};
|
|
730
736
|
plan = await applyCheckpointIntentOrdering(artifactsDir, plan);
|
|
731
|
-
if (
|
|
732
|
-
existing = { ...existing, run_start_dirty: [...await stagedAndUntracked(root)]
|
|
737
|
+
if (origin === "new_pre_edit_run") {
|
|
738
|
+
existing = { ...existing, run_start_dirty: [...await stagedAndUntracked(root)], run_start_dirty_encoding: "git-z/v1" };
|
|
739
|
+
}
|
|
733
740
|
const filter = await readOptionalJsonFile(reviewFilterDispositionsPath(artifactsDir));
|
|
734
741
|
// Through the schema-checked reader: with zero survivors the review gate never
|
|
735
742
|
// rewrites a stale-schema record, so a raw read let its declines into the
|
|
@@ -1004,11 +1011,11 @@ sourceAuditRead) {
|
|
|
1004
1011
|
`path=${findingsPath}`,
|
|
1005
1012
|
});
|
|
1006
1013
|
}
|
|
1007
|
-
async function handleReadyIntakeContractPipeline(root, artifactsDir, options, runLogger) {
|
|
1014
|
+
async function handleReadyIntakeContractPipeline(root, artifactsDir, options, runLogger, origin) {
|
|
1008
1015
|
// Resume the tool-owned plan without reconstructing completed intake.
|
|
1009
1016
|
const earlyExtractedPlan = await readApprovedExecutionPlan(artifactsDir);
|
|
1010
1017
|
if (earlyExtractedPlan && !existsSync(executionPlanPaths(artifactsDir).submission)) {
|
|
1011
|
-
const outcome = await activateApprovedPlan(root, artifactsDir, { status: "pending" }, earlyExtractedPlan, runLogger);
|
|
1018
|
+
const outcome = await activateApprovedPlan(root, artifactsDir, { status: "pending" }, earlyExtractedPlan, runLogger, origin);
|
|
1012
1019
|
return outcome.kind === "blocked"
|
|
1013
1020
|
? emitPlanRevisionBlockedStep(root, artifactsDir, outcome)
|
|
1014
1021
|
: outcome.state;
|
|
@@ -1022,7 +1029,7 @@ async function handleReadyIntakeContractPipeline(root, artifactsDir, options, ru
|
|
|
1022
1029
|
const approved = await readApprovedExecutionPlan(artifactsDir);
|
|
1023
1030
|
if (!approved)
|
|
1024
1031
|
return null;
|
|
1025
|
-
const outcome = await activateApprovedPlan(root, artifactsDir, { status: "pending" }, approved, runLogger);
|
|
1032
|
+
const outcome = await activateApprovedPlan(root, artifactsDir, { status: "pending" }, approved, runLogger, origin);
|
|
1026
1033
|
return outcome.kind === "blocked"
|
|
1027
1034
|
? emitPlanRevisionBlockedStep(root, artifactsDir, outcome)
|
|
1028
1035
|
: outcome.state;
|
|
@@ -1177,16 +1184,16 @@ async function handleReadyIntakeContractPipeline(root, artifactsDir, options, ru
|
|
|
1177
1184
|
if (!extractedPlan) {
|
|
1178
1185
|
return null;
|
|
1179
1186
|
}
|
|
1180
|
-
const outcome = await activateApprovedPlan(root, artifactsDir, { status: "pending" }, extractedPlan, runLogger);
|
|
1187
|
+
const outcome = await activateApprovedPlan(root, artifactsDir, { status: "pending" }, extractedPlan, runLogger, origin);
|
|
1181
1188
|
return outcome.kind === "blocked"
|
|
1182
1189
|
? emitPlanRevisionBlockedStep(root, artifactsDir, outcome)
|
|
1183
1190
|
: outcome.state;
|
|
1184
1191
|
}
|
|
1185
|
-
async function handlePendingIntake(root, artifactsDir, options, runLogger) {
|
|
1192
|
+
async function handlePendingIntake(root, artifactsDir, options, runLogger, origin) {
|
|
1186
1193
|
// Existing source ownership survives pending review and approval invalidation.
|
|
1187
1194
|
// The earlier confirm_intent obligation still guards this continuation.
|
|
1188
1195
|
if (await readPlanSource(artifactsDir)) {
|
|
1189
|
-
return handleReadyIntakeContractPipeline(root, artifactsDir, options, runLogger);
|
|
1196
|
+
return handleReadyIntakeContractPipeline(root, artifactsDir, options, runLogger, origin);
|
|
1190
1197
|
}
|
|
1191
1198
|
const inputResolution = resolveInputPaths(root, options.input);
|
|
1192
1199
|
const intakeResult = await resolveIntakeStep({
|
|
@@ -1205,7 +1212,7 @@ async function handlePendingIntake(root, artifactsDir, options, runLogger) {
|
|
|
1205
1212
|
return intakeResult.step;
|
|
1206
1213
|
}
|
|
1207
1214
|
// Intake is complete — route both paths through the contract pipeline.
|
|
1208
|
-
return handleReadyIntakeContractPipeline(root, artifactsDir, options, runLogger);
|
|
1215
|
+
return handleReadyIntakeContractPipeline(root, artifactsDir, options, runLogger, origin);
|
|
1209
1216
|
}
|
|
1210
1217
|
async function handleNoState(root, artifactsDir) {
|
|
1211
1218
|
const paths = intakePaths(artifactsDir);
|
|
@@ -1614,6 +1621,7 @@ async function handleImplementing(root, artifactsDir, state, runLogger, store) {
|
|
|
1614
1621
|
*/
|
|
1615
1622
|
async function emitFinalGateRedStep(ctx) {
|
|
1616
1623
|
const { root, artifactsDir, state, scope, gate, runLogger } = ctx;
|
|
1624
|
+
admitRemediationDirtyBaseline(state);
|
|
1617
1625
|
const failed = gate.results.find((r) => !r.passed);
|
|
1618
1626
|
const recordPath = ctx.recordedPath ?? await writeFinalGateRedRecord(artifactsDir, scope, failed, {
|
|
1619
1627
|
root,
|
|
@@ -1736,6 +1744,7 @@ function explicitFinalGateTestCommand(state) {
|
|
|
1736
1744
|
}
|
|
1737
1745
|
async function runPhaseBoundaryGate(ctx) {
|
|
1738
1746
|
const { root, artifactsDir, state, options, runLogger } = ctx;
|
|
1747
|
+
admitRemediationDirtyBaseline(state);
|
|
1739
1748
|
// Whether a gate is DUE is decided BEFORE whether it is suppressed. The old
|
|
1740
1749
|
// order asked the suppression first and returned, so a disabled run could not
|
|
1741
1750
|
// tell "no gate was due this pass" from "a gate was due and skipped" — and the
|
|
@@ -2404,19 +2413,7 @@ function requireState(state) {
|
|
|
2404
2413
|
}
|
|
2405
2414
|
return state;
|
|
2406
2415
|
}
|
|
2407
|
-
|
|
2408
|
-
* Priority order for the pre-intake obligations — mirrors the original cascade's
|
|
2409
|
-
* top-down guard order exactly so selection cannot drift.
|
|
2410
|
-
*/
|
|
2411
|
-
export const PRE_INTAKE_PRIORITY = [
|
|
2412
|
-
"input_conflict",
|
|
2413
|
-
"confirm_resume",
|
|
2414
|
-
"confirm_intent",
|
|
2415
|
-
"interpret_intent",
|
|
2416
|
-
"complete_redelivery",
|
|
2417
|
-
"complete",
|
|
2418
|
-
"pending_intake",
|
|
2419
|
-
];
|
|
2416
|
+
// sites-pinned: tests/remediate/obligation-priority-coverage.test.ts
|
|
2420
2417
|
/**
|
|
2421
2418
|
* The linear pre-intake gates as declarative obligations (A3 slice 1). Built per
|
|
2422
2419
|
* call so each `derive` can close over `ctx` paths + the pre-read `snapshot` and
|
|
@@ -2668,7 +2665,7 @@ Then run:
|
|
|
2668
2665
|
id: "pending_intake",
|
|
2669
2666
|
derive: (state) => (state == null ? "missing" : "satisfied"),
|
|
2670
2667
|
execute: async (_state, c) => {
|
|
2671
|
-
const outcome = await handlePendingIntake(c.root, c.artifactsDir, c.options, c.runLogger);
|
|
2668
|
+
const outcome = await handlePendingIntake(c.root, c.artifactsDir, c.options, c.runLogger, "new_pre_edit_run");
|
|
2672
2669
|
if (outcome && "step_kind" in outcome) {
|
|
2673
2670
|
return { kind: "emit", step: outcome };
|
|
2674
2671
|
}
|
|
@@ -2680,23 +2677,6 @@ Then run:
|
|
|
2680
2677
|
},
|
|
2681
2678
|
];
|
|
2682
2679
|
}
|
|
2683
|
-
/**
|
|
2684
|
-
* Priority order for the main (post-intake) obligations — mirrors the original
|
|
2685
|
-
* cascade tail's guard order exactly so selection cannot drift.
|
|
2686
|
-
*/
|
|
2687
|
-
export const MAIN_PRIORITY = [
|
|
2688
|
-
"operator_plan_only",
|
|
2689
|
-
"waiting_for_clarification",
|
|
2690
|
-
"waiting_for_triage",
|
|
2691
|
-
"planning_documentable",
|
|
2692
|
-
"deferred_clarification",
|
|
2693
|
-
"implementing",
|
|
2694
|
-
"triage",
|
|
2695
|
-
"planning_zero",
|
|
2696
|
-
"all_terminal",
|
|
2697
|
-
"closing",
|
|
2698
|
-
"unhandled",
|
|
2699
|
-
];
|
|
2700
2680
|
/**
|
|
2701
2681
|
* The post-intake cascade tail as declarative obligations (A3 slice 2). Runs on a
|
|
2702
2682
|
* non-null state (pre-intake resolved it). Every phase handler returns a
|
|
@@ -2947,6 +2927,21 @@ async function advanceUnderPhaseLock(deps) {
|
|
|
2947
2927
|
// Loaded FRESH under the mutex: a peer may have advanced and persisted state
|
|
2948
2928
|
// between the entry read and this process winning the lock.
|
|
2949
2929
|
let state = await store.loadState();
|
|
2930
|
+
const reportOnlyRequest = state?.status === "complete" &&
|
|
2931
|
+
options.input === undefined && options.severity === undefined && options.findingIds === undefined &&
|
|
2932
|
+
options.guidanceFile === undefined && options.guidanceText === undefined && options.verificationCommand === undefined &&
|
|
2933
|
+
options.guidanceFileSupplied !== true && options.forceReplan !== true && options.planOnly !== true && options.finalizeClosing !== true;
|
|
2934
|
+
// Only a potential complete/report-only request may inspect plan freshness
|
|
2935
|
+
// before baseline admission. No authority write can precede this fence.
|
|
2936
|
+
if (state && !reportOnlyRequest)
|
|
2937
|
+
admitRemediationDirtyBaseline(state);
|
|
2938
|
+
const currentCanonical = state?.plan ? await readCanonicalPlan(artifactsDir) : undefined;
|
|
2939
|
+
const pendingPlanSubmission = existsSync(executionPlanPaths(artifactsDir).submission);
|
|
2940
|
+
const revisionMismatch = Boolean(currentCanonical && currentCanonical.revision_sha256 !== state?.plan?.review_revision_sha256);
|
|
2941
|
+
if (reportOnlyRequest && !pendingPlanSubmission && !revisionMismatch)
|
|
2942
|
+
return handleComplete(root, artifactsDir, state);
|
|
2943
|
+
if (state && reportOnlyRequest)
|
|
2944
|
+
admitRemediationDirtyBaseline(state);
|
|
2950
2945
|
if (state)
|
|
2951
2946
|
await store.reconcileDecisionApplications(state);
|
|
2952
2947
|
let control = await store.loadOperatorLifecycle();
|
|
@@ -3001,8 +2996,7 @@ async function advanceUnderPhaseLock(deps) {
|
|
|
3001
2996
|
// Preamble — forceReplan re-grounds from existing intake. The whole decide loop
|
|
3002
2997
|
// runs once per host call (the engine folds planning → implementing → … through
|
|
3003
2998
|
// transitions, never a recursive decideNextStepLoop), so this fires at most once.
|
|
3004
|
-
|
|
3005
|
-
if (state != null && (options.forceReplan || existsSync(executionPlanPaths(artifactsDir).submission) || (currentCanonical && currentCanonical.revision_sha256 !== state.plan?.review_revision_sha256))) {
|
|
2999
|
+
if (state != null && (options.forceReplan || pendingPlanSubmission || revisionMismatch)) {
|
|
3006
3000
|
await countStep(state);
|
|
3007
3001
|
const replanOutcome = await forceReplanFromExistingIntake(root, artifactsDir, state, runLogger);
|
|
3008
3002
|
// A discarded plan is REPORTED here, not collapsed into `state = null`. Once
|
|
@@ -3062,7 +3056,7 @@ async function advanceUnderPhaseLock(deps) {
|
|
|
3062
3056
|
// The linear pre-intake gates run as obligations through the shared advance
|
|
3063
3057
|
// loop. An emit returns to the host; a transition re-scans within this call;
|
|
3064
3058
|
// exhausting them (step === null) means the run is past intake and falls
|
|
3065
|
-
// through to the post-intake `advance`
|
|
3059
|
+
// through to the post-intake `advance` below.
|
|
3066
3060
|
const ctx = {
|
|
3067
3061
|
root,
|
|
3068
3062
|
artifactsDir,
|
|
@@ -3072,20 +3066,21 @@ async function advanceUnderPhaseLock(deps) {
|
|
|
3072
3066
|
inputResolution,
|
|
3073
3067
|
countStep,
|
|
3074
3068
|
};
|
|
3069
|
+
const preIntakeObligations = buildPreIntakeObligations(ctx, {
|
|
3070
|
+
existingCheckpoint,
|
|
3071
|
+
rejectedCheckpointFields: checkpointRead?.rejected ?? [],
|
|
3072
|
+
resumeAck,
|
|
3073
|
+
entryState: state,
|
|
3074
|
+
suppliedInputUnchanged,
|
|
3075
|
+
sourceAlreadyBound: boundSource !== undefined,
|
|
3076
|
+
inputSelectionChanged,
|
|
3077
|
+
selectionAlreadyBound: recordedSelection !== undefined,
|
|
3078
|
+
selectedSourceChanged,
|
|
3079
|
+
guidanceFileSupplied: Boolean(options.guidanceFileSupplied || options.guidanceFile || options.guidanceText !== undefined),
|
|
3080
|
+
});
|
|
3075
3081
|
const preIntake = await advance({
|
|
3076
|
-
priority:
|
|
3077
|
-
obligations:
|
|
3078
|
-
existingCheckpoint,
|
|
3079
|
-
rejectedCheckpointFields: checkpointRead?.rejected ?? [],
|
|
3080
|
-
resumeAck,
|
|
3081
|
-
entryState: state,
|
|
3082
|
-
suppliedInputUnchanged,
|
|
3083
|
-
sourceAlreadyBound: boundSource !== undefined,
|
|
3084
|
-
inputSelectionChanged,
|
|
3085
|
-
selectionAlreadyBound: recordedSelection !== undefined,
|
|
3086
|
-
selectedSourceChanged,
|
|
3087
|
-
guidanceFileSupplied: Boolean(options.guidanceFileSupplied || options.guidanceFile || options.guidanceText !== undefined),
|
|
3088
|
-
}),
|
|
3082
|
+
priority: preIntakeObligations.map(def => def.id),
|
|
3083
|
+
obligations: preIntakeObligations,
|
|
3089
3084
|
}, state, ctx);
|
|
3090
3085
|
if (preIntake.step)
|
|
3091
3086
|
return preIntake.step;
|
|
@@ -3113,7 +3108,8 @@ async function advanceUnderPhaseLock(deps) {
|
|
|
3113
3108
|
// store without returning the persisted value, so the main fold reads from disk
|
|
3114
3109
|
// exactly as it did when it owned its own lock acquisition.
|
|
3115
3110
|
const advanceState = (await store.loadState()) ?? state;
|
|
3116
|
-
const
|
|
3111
|
+
const mainObligations = buildMainObligations(ctx);
|
|
3112
|
+
const main = await advance({ priority: mainObligations.map(def => def.id), obligations: mainObligations }, advanceState, ctx);
|
|
3117
3113
|
if (main.step)
|
|
3118
3114
|
return main.step;
|
|
3119
3115
|
// Same contract as the pre-intake fold above: a non-convergent stop must not
|