audit-tools 0.42.1 → 0.44.0
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 +229 -140
- package/dispatch/validate-result.mjs +98 -40
- package/dist/audit/cli/conceptualDispatch.d.ts.map +1 -1
- package/dist/audit/cli/conceptualDispatch.js +35 -3
- package/dist/audit/cli/conceptualDispatch.js.map +1 -1
- package/dist/audit/cli/dispatch/hostHandoff.d.ts +9 -1
- package/dist/audit/cli/dispatch/hostHandoff.d.ts.map +1 -1
- package/dist/audit/cli/dispatch/hostHandoff.js +94 -38
- package/dist/audit/cli/dispatch/hostHandoff.js.map +1 -1
- package/dist/audit/cli/laneSubmissions.d.ts +2 -2
- package/dist/audit/cli/laneSubmissions.js +2 -2
- package/dist/audit/cli/nextStepCommand.d.ts +64 -0
- package/dist/audit/cli/nextStepCommand.d.ts.map +1 -1
- package/dist/audit/cli/nextStepCommand.js +877 -783
- package/dist/audit/cli/nextStepCommand.js.map +1 -1
- package/dist/audit/cli/nextStepHelpers.d.ts +12 -36
- package/dist/audit/cli/nextStepHelpers.d.ts.map +1 -1
- package/dist/audit/cli/nextStepHelpers.js +34 -77
- package/dist/audit/cli/nextStepHelpers.js.map +1 -1
- package/dist/audit/cli/steps.d.ts +2 -2
- package/dist/audit/extractors/graph.d.ts +28 -2
- package/dist/audit/extractors/graph.d.ts.map +1 -1
- package/dist/audit/extractors/graph.js +122 -11
- package/dist/audit/extractors/graph.js.map +1 -1
- package/dist/audit/extractors/graphRoutes.d.ts +8 -0
- package/dist/audit/extractors/graphRoutes.d.ts.map +1 -1
- package/dist/audit/extractors/graphRoutes.js +71 -4
- package/dist/audit/extractors/graphRoutes.js.map +1 -1
- package/dist/audit/io/artifacts.d.ts +55 -0
- package/dist/audit/io/artifacts.d.ts.map +1 -1
- package/dist/audit/io/artifacts.js +189 -12
- package/dist/audit/io/artifacts.js.map +1 -1
- package/dist/audit/io/toolingManifest.d.ts +11 -0
- package/dist/audit/io/toolingManifest.d.ts.map +1 -1
- package/dist/audit/io/toolingManifest.js +13 -3
- package/dist/audit/io/toolingManifest.js.map +1 -1
- package/dist/audit/orchestrator/advance.d.ts +64 -0
- package/dist/audit/orchestrator/advance.d.ts.map +1 -1
- package/dist/audit/orchestrator/advance.js +191 -57
- package/dist/audit/orchestrator/advance.js.map +1 -1
- package/dist/audit/orchestrator/charterClarificationExecutor.d.ts.map +1 -1
- package/dist/audit/orchestrator/charterClarificationExecutor.js +55 -21
- package/dist/audit/orchestrator/charterClarificationExecutor.js.map +1 -1
- package/dist/audit/orchestrator/flowCoverage.d.ts.map +1 -1
- package/dist/audit/orchestrator/flowCoverage.js +7 -10
- package/dist/audit/orchestrator/flowCoverage.js.map +1 -1
- package/dist/audit/orchestrator/flowPlanning.d.ts +54 -1
- package/dist/audit/orchestrator/flowPlanning.d.ts.map +1 -1
- package/dist/audit/orchestrator/flowPlanning.js +77 -18
- package/dist/audit/orchestrator/flowPlanning.js.map +1 -1
- package/dist/audit/orchestrator/flowRequeue.d.ts.map +1 -1
- package/dist/audit/orchestrator/flowRequeue.js +6 -10
- package/dist/audit/orchestrator/flowRequeue.js.map +1 -1
- package/dist/audit/orchestrator/requeueFold.d.ts.map +1 -1
- package/dist/audit/orchestrator/requeueFold.js +18 -5
- package/dist/audit/orchestrator/requeueFold.js.map +1 -1
- package/dist/audit/orchestrator/staleness.d.ts +24 -1
- package/dist/audit/orchestrator/staleness.d.ts.map +1 -1
- package/dist/audit/orchestrator/staleness.js +147 -16
- package/dist/audit/orchestrator/staleness.js.map +1 -1
- package/dist/audit/orchestrator/syntaxResolutionExecutor.d.ts +26 -0
- package/dist/audit/orchestrator/syntaxResolutionExecutor.d.ts.map +1 -1
- package/dist/audit/orchestrator/syntaxResolutionExecutor.js +97 -12
- package/dist/audit/orchestrator/syntaxResolutionExecutor.js.map +1 -1
- package/dist/audit/orchestrator/taskBuilder.d.ts.map +1 -1
- package/dist/audit/orchestrator/taskBuilder.js +111 -21
- package/dist/audit/orchestrator/taskBuilder.js.map +1 -1
- package/dist/audit/orchestrator/trivialAudit.d.ts +17 -1
- package/dist/audit/orchestrator/trivialAudit.d.ts.map +1 -1
- package/dist/audit/orchestrator/trivialAudit.js +31 -4
- package/dist/audit/orchestrator/trivialAudit.js.map +1 -1
- package/dist/audit/types/analyzerCapability.d.ts +6 -6
- package/dist/audit/types/charterRegister.d.ts +30 -12
- package/dist/audit/types/charterRegister.d.ts.map +1 -1
- package/dist/audit/types/charterRegister.js +22 -9
- package/dist/audit/types/charterRegister.js.map +1 -1
- package/dist/audit/validation/anchorGrounding.d.ts.map +1 -1
- package/dist/audit/validation/anchorGrounding.js +17 -0
- package/dist/audit/validation/anchorGrounding.js.map +1 -1
- package/dist/audit/validation/auditResults.d.ts +17 -0
- package/dist/audit/validation/auditResults.d.ts.map +1 -1
- package/dist/audit/validation/auditResults.js +50 -17
- package/dist/audit/validation/auditResults.js.map +1 -1
- package/dist/remediate/contractPipeline/cyclicSeamResolution.d.ts +48 -0
- package/dist/remediate/contractPipeline/cyclicSeamResolution.d.ts.map +1 -1
- package/dist/remediate/contractPipeline/cyclicSeamResolution.js +128 -0
- package/dist/remediate/contractPipeline/cyclicSeamResolution.js.map +1 -1
- package/dist/remediate/contractPipeline/derive.d.ts +8 -5
- package/dist/remediate/contractPipeline/derive.d.ts.map +1 -1
- package/dist/remediate/contractPipeline/derive.js +8 -16
- package/dist/remediate/contractPipeline/derive.js.map +1 -1
- package/dist/remediate/index.d.ts.map +1 -1
- package/dist/remediate/index.js +43 -2
- package/dist/remediate/index.js.map +1 -1
- package/dist/remediate/intent/intentOrdering.d.ts +13 -5
- package/dist/remediate/intent/intentOrdering.d.ts.map +1 -1
- package/dist/remediate/intent/intentOrdering.js +56 -25
- package/dist/remediate/intent/intentOrdering.js.map +1 -1
- package/dist/remediate/phases/close.d.ts +57 -2
- package/dist/remediate/phases/close.d.ts.map +1 -1
- package/dist/remediate/phases/close.js +260 -36
- package/dist/remediate/phases/close.js.map +1 -1
- package/dist/remediate/phases/triage.d.ts.map +1 -1
- package/dist/remediate/phases/triage.js +14 -2
- package/dist/remediate/phases/triage.js.map +1 -1
- package/dist/remediate/state/disposition.d.ts +26 -4
- package/dist/remediate/state/disposition.d.ts.map +1 -1
- package/dist/remediate/state/itemStatus.d.ts +33 -6
- package/dist/remediate/state/itemStatus.d.ts.map +1 -1
- package/dist/remediate/state/itemStatus.js +154 -39
- package/dist/remediate/state/itemStatus.js.map +1 -1
- package/dist/remediate/state/types.d.ts +41 -2
- package/dist/remediate/state/types.d.ts.map +1 -1
- package/dist/remediate/state/types.js.map +1 -1
- package/dist/remediate/steps/contractPipeline.d.ts +296 -15
- package/dist/remediate/steps/contractPipeline.d.ts.map +1 -1
- package/dist/remediate/steps/contractPipeline.js +1783 -1001
- package/dist/remediate/steps/contractPipeline.js.map +1 -1
- package/dist/remediate/steps/dispatch/hostHandoff.d.ts +137 -2
- package/dist/remediate/steps/dispatch/hostHandoff.d.ts.map +1 -1
- package/dist/remediate/steps/dispatch/hostHandoff.js +657 -59
- package/dist/remediate/steps/dispatch/hostHandoff.js.map +1 -1
- package/dist/remediate/steps/finalGate.d.ts +136 -37
- package/dist/remediate/steps/finalGate.d.ts.map +1 -1
- package/dist/remediate/steps/finalGate.js +120 -86
- package/dist/remediate/steps/finalGate.js.map +1 -1
- package/dist/remediate/steps/gateCommands.d.ts +8 -0
- package/dist/remediate/steps/gateCommands.d.ts.map +1 -1
- package/dist/remediate/steps/gateCommands.js +40 -11
- package/dist/remediate/steps/gateCommands.js.map +1 -1
- package/dist/remediate/steps/nextStep.d.ts +96 -5
- package/dist/remediate/steps/nextStep.d.ts.map +1 -1
- package/dist/remediate/steps/nextStep.js +668 -147
- package/dist/remediate/steps/nextStep.js.map +1 -1
- package/dist/remediate/steps/types.d.ts +4 -3
- package/dist/remediate/steps/types.d.ts.map +1 -1
- package/dist/remediate/steps/types.js +10 -2
- package/dist/remediate/steps/types.js.map +1 -1
- package/dist/remediate/validation/artifacts.d.ts +20 -2
- package/dist/remediate/validation/artifacts.d.ts.map +1 -1
- package/dist/remediate/validation/artifacts.js +224 -130
- package/dist/remediate/validation/artifacts.js.map +1 -1
- package/dist/remediate/validation/contractPipelineGates.d.ts +58 -0
- package/dist/remediate/validation/contractPipelineGates.d.ts.map +1 -1
- package/dist/remediate/validation/contractPipelineGates.js +143 -27
- package/dist/remediate/validation/contractPipelineGates.js.map +1 -1
- package/dist/shared/analyzers/acquisitionEngine.d.ts +72 -25
- package/dist/shared/analyzers/acquisitionEngine.d.ts.map +1 -1
- package/dist/shared/analyzers/acquisitionEngine.js +149 -15
- package/dist/shared/analyzers/acquisitionEngine.js.map +1 -1
- package/dist/shared/analyzers/binaryAcquisition.d.ts +27 -2
- package/dist/shared/analyzers/binaryAcquisition.d.ts.map +1 -1
- package/dist/shared/analyzers/binaryAcquisition.js +149 -43
- package/dist/shared/analyzers/binaryAcquisition.js.map +1 -1
- package/dist/shared/analyzers/candidates.d.ts +9 -8
- package/dist/shared/analyzers/candidates.d.ts.map +1 -1
- package/dist/shared/analyzers/candidates.js +96 -64
- package/dist/shared/analyzers/candidates.js.map +1 -1
- package/dist/shared/analyzers/normalizeExternal.d.ts +40 -12
- package/dist/shared/analyzers/normalizeExternal.d.ts.map +1 -1
- package/dist/shared/analyzers/normalizeExternal.js +74 -18
- package/dist/shared/analyzers/normalizeExternal.js.map +1 -1
- package/dist/shared/analyzers/rubocop.d.ts +14 -13
- package/dist/shared/analyzers/rubocop.d.ts.map +1 -1
- package/dist/shared/analyzers/rubocop.js +29 -6
- package/dist/shared/analyzers/rubocop.js.map +1 -1
- package/dist/shared/analyzers/types.d.ts +196 -13
- package/dist/shared/analyzers/types.d.ts.map +1 -1
- package/dist/shared/analyzers/types.js +122 -9
- package/dist/shared/analyzers/types.js.map +1 -1
- package/dist/shared/decompose/charterClarification.d.ts +12 -1
- package/dist/shared/decompose/charterClarification.d.ts.map +1 -1
- package/dist/shared/decompose/charterClarification.js +11 -4
- package/dist/shared/decompose/charterClarification.js.map +1 -1
- package/dist/shared/decompose/charterExtraction.d.ts +20 -10
- package/dist/shared/decompose/charterExtraction.d.ts.map +1 -1
- package/dist/shared/decompose/charterExtraction.js +52 -23
- package/dist/shared/decompose/charterExtraction.js.map +1 -1
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/index.js +5 -0
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/intent/freeFormIntentInterpreter.d.ts +12 -2
- package/dist/shared/intent/freeFormIntentInterpreter.d.ts.map +1 -1
- package/dist/shared/intent/freeFormIntentInterpreter.js +27 -22
- package/dist/shared/intent/freeFormIntentInterpreter.js.map +1 -1
- package/dist/shared/intent/pathScope.d.ts +12 -1
- package/dist/shared/intent/pathScope.d.ts.map +1 -1
- package/dist/shared/intent/pathScope.js +56 -19
- package/dist/shared/intent/pathScope.js.map +1 -1
- package/dist/shared/intent/sharedIntentData.d.ts +19 -1
- package/dist/shared/intent/sharedIntentData.d.ts.map +1 -1
- package/dist/shared/intent/sharedIntentData.js +33 -8
- package/dist/shared/intent/sharedIntentData.js.map +1 -1
- package/dist/shared/io/fileLock.d.ts +12 -0
- package/dist/shared/io/fileLock.d.ts.map +1 -1
- package/dist/shared/io/fileLock.js +48 -5
- package/dist/shared/io/fileLock.js.map +1 -1
- package/dist/shared/io/json.d.ts +13 -0
- package/dist/shared/io/json.d.ts.map +1 -1
- package/dist/shared/io/json.js +19 -1
- package/dist/shared/io/json.js.map +1 -1
- package/dist/shared/steps/stepEmissionScaffold.d.ts +69 -0
- package/dist/shared/steps/stepEmissionScaffold.d.ts.map +1 -0
- package/dist/shared/steps/stepEmissionScaffold.js +83 -0
- package/dist/shared/steps/stepEmissionScaffold.js.map +1 -0
- package/dist/shared/submission/handRecovery.d.ts.map +1 -1
- package/dist/shared/submission/handRecovery.js +69 -4
- package/dist/shared/submission/handRecovery.js.map +1 -1
- package/dist/shared/submission/submissionIdentity.d.ts +10 -1
- package/dist/shared/submission/submissionIdentity.d.ts.map +1 -1
- package/dist/shared/submission/submissionIdentity.js +12 -3
- package/dist/shared/submission/submissionIdentity.js.map +1 -1
- package/dist/shared/submission/submissionLedger.d.ts +43 -2
- package/dist/shared/submission/submissionLedger.d.ts.map +1 -1
- package/dist/shared/submission/submissionLedger.js +50 -7
- package/dist/shared/submission/submissionLedger.js.map +1 -1
- package/dist/shared/tooling/allowlistedExec.d.ts +9 -0
- package/dist/shared/tooling/allowlistedExec.d.ts.map +1 -1
- package/dist/shared/tooling/allowlistedExec.js +19 -2
- package/dist/shared/tooling/allowlistedExec.js.map +1 -1
- package/dist/shared/tooling/commandShape.d.ts +21 -0
- package/dist/shared/tooling/commandShape.d.ts.map +1 -0
- package/dist/shared/tooling/commandShape.js +120 -0
- package/dist/shared/tooling/commandShape.js.map +1 -0
- package/dist/shared/types/charter.d.ts +24 -0
- package/dist/shared/types/charter.d.ts.map +1 -1
- package/dist/shared/types/charter.js +9 -0
- package/dist/shared/types/charter.js.map +1 -1
- package/dist/shared/types/remediationOutcome.d.ts +282 -9
- package/dist/shared/types/remediationOutcome.d.ts.map +1 -1
- package/dist/shared/types/remediationOutcome.js +174 -1
- package/dist/shared/types/remediationOutcome.js.map +1 -1
- package/package.json +2 -1
- package/remediate-code.mjs +15 -0
- package/wrapper/remediate-code-wrapper-install-hosts.mjs +45 -4
- package/wrapper/remediate-code-wrapper-install-renderers.mjs +12 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intentOrdering.js","sourceRoot":"","sources":["../../../src/remediate/intent/intentOrdering.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;
|
|
1
|
+
{"version":3,"file":"intentOrdering.js","sourceRoot":"","sources":["../../../src/remediate/intent/intentOrdering.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,19 @@ import { OrchestratorOptions } from "../types/options.js";
|
|
|
3
3
|
import type { RemediationOutcomesReport, RunLogger, VerificationReport } from "audit-tools/shared";
|
|
4
4
|
import type { ClosingAction } from "../state/closingActions.js";
|
|
5
5
|
import type { OutcomeCoverageLedger } from "../state/types.js";
|
|
6
|
-
|
|
6
|
+
import { type FinalGateReport } from "../../shared/types/remediationOutcome.js";
|
|
7
|
+
/**
|
|
8
|
+
* Read the run's tool-owned gate outcome for the report.
|
|
9
|
+
*
|
|
10
|
+
* The gate WRITES `final-gate-outcome.json` on every evaluation; until this
|
|
11
|
+
* reader existed, nothing consumed it — so a scoped-out or suppressed run
|
|
12
|
+
* produced a completion report byte-identical to one written after a green
|
|
13
|
+
* floor, which is the whole defect the record was added to close. A record that
|
|
14
|
+
* is missing, unreadable, or fails its schema degrades to
|
|
15
|
+
* {@link ABSENT_FINAL_GATE_REPORT}: stated as absent, never as green.
|
|
16
|
+
*/
|
|
17
|
+
export declare function readFinalGateReport(artifactsDir: string): Promise<FinalGateReport>;
|
|
18
|
+
export declare function buildRemediationOutcomesReport(state: RemediationState, closingResult: ClosingResult, finalGate?: FinalGateReport): RemediationOutcomesReport;
|
|
7
19
|
/**
|
|
8
20
|
* Build the outcomes file's coverage-ledger section: the plan's coverage ledger
|
|
9
21
|
* with every never-planned entry (cross-lens-deduped, checkpoint-dropped,
|
|
@@ -97,17 +109,60 @@ export interface StagingSelection {
|
|
|
97
109
|
export declare function collectStagingFiles(root: string, manifest: string[], deliverables?: string[]): StagingSelection;
|
|
98
110
|
export declare function executeClosingAction(state: RemediationState, options: OrchestratorOptions): ClosingResult;
|
|
99
111
|
export interface CombinedTestResult {
|
|
112
|
+
/**
|
|
113
|
+
* Whether a suite actually ran. `false` means `plan.test_command` was never
|
|
114
|
+
* configured — a NEVER-RAN outcome, structurally distinct from `passed`, so
|
|
115
|
+
* a caller can no longer mistake "nothing ran" for "a real pass" (the
|
|
116
|
+
* vacuous-pass defect: previously `passed:true` alone claimed a real result
|
|
117
|
+
* even for an unrun, unconfigured suite).
|
|
118
|
+
*/
|
|
119
|
+
ran: boolean;
|
|
100
120
|
passed: boolean;
|
|
101
121
|
duration_ms: number;
|
|
102
122
|
suite_name?: string;
|
|
103
123
|
/** Tail of combined stdout/stderr captured on failure (empty on pass). */
|
|
104
124
|
output: string;
|
|
105
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* Run the plan's combined test suite over the fully merged post-remediation
|
|
128
|
+
* state. Returns pass/fail plus the failure-output tail. No test_command =>
|
|
129
|
+
* `ran:false` (never-ran, distinct from a real pass) — `passed` still reports
|
|
130
|
+
* `true` so existing gates that fold `combinedTest.passed` into `fullyGreen`
|
|
131
|
+
* keep their vacuously-green behavior for a run with no configured suite;
|
|
132
|
+
* `ran` is what lets a caller (buildVerificationReport's trace) tell the two
|
|
133
|
+
* apart rather than rendering "combined test suite passed" for a suite that
|
|
134
|
+
* never executed.
|
|
135
|
+
*/
|
|
136
|
+
export declare function runCombinedTestSuite(state: RemediationState, options: OrchestratorOptions): CombinedTestResult;
|
|
137
|
+
/**
|
|
138
|
+
* On a combined-test failure, selectively re-block items whose touched_files
|
|
139
|
+
* overlap with the failing tests' implicated paths. When attribution is
|
|
140
|
+
* ambiguous (no overlap found), falls back to re-blocking all resolved items.
|
|
141
|
+
* Returns whether any item was blocked — the caller transitions back to triage.
|
|
142
|
+
*/
|
|
143
|
+
export declare function blockResolvedItemsOnCombinedFailure(state: RemediationState, testOutput: string): boolean;
|
|
106
144
|
export interface E2eTestResult {
|
|
107
145
|
ran: boolean;
|
|
108
146
|
passed: boolean;
|
|
109
147
|
output: string;
|
|
110
148
|
}
|
|
149
|
+
/**
|
|
150
|
+
* {@link cleanupTempBranchesAndArtifacts}'s result — lets a caller observe a
|
|
151
|
+
* cleanup residue programmatically rather than only through console/log
|
|
152
|
+
* output. Absent (`{}`) on a clean removal, a not-fully-green close (nothing
|
|
153
|
+
* was attempted), or a final-state-persist failure alone.
|
|
154
|
+
*/
|
|
155
|
+
export interface CleanupResult {
|
|
156
|
+
/**
|
|
157
|
+
* Set to the artifacts directory path when its recursive removal failed
|
|
158
|
+
* after an otherwise fully-green close — the caller must remove it
|
|
159
|
+
* manually. The same fact is also written to the durable structured run log
|
|
160
|
+
* (`runLogger`) and to the console; this field is what surfaces it in the
|
|
161
|
+
* function's OWN returned result too, so a caller does not have to parse
|
|
162
|
+
* log/console output to detect the residue.
|
|
163
|
+
*/
|
|
164
|
+
artifacts_residue?: string;
|
|
165
|
+
}
|
|
111
166
|
/**
|
|
112
167
|
* Persist the completed state and clean up the artifact directory.
|
|
113
168
|
*
|
|
@@ -118,7 +173,7 @@ export interface E2eTestResult {
|
|
|
118
173
|
* closing action failed OR was skipped without completing — the artifacts
|
|
119
174
|
* directory is preserved for diagnosis.
|
|
120
175
|
*/
|
|
121
|
-
export declare function cleanupTempBranchesAndArtifacts(options: OrchestratorOptions, completeState: RemediationState, combinedTest: CombinedTestResult, e2eResult: E2eTestResult, closingResult: ClosingResult, runLogger?: RunLogger): Promise<
|
|
176
|
+
export declare function cleanupTempBranchesAndArtifacts(options: OrchestratorOptions, completeState: RemediationState, combinedTest: CombinedTestResult, e2eResult: E2eTestResult, closingResult: ClosingResult, runLogger?: RunLogger): Promise<CleanupResult>;
|
|
122
177
|
/**
|
|
123
178
|
* Build a VerificationReport from the post-remediation state. One
|
|
124
179
|
* FindingVerificationTrace per terminal finding, with trace entries for:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"close.d.ts","sourceRoot":"","sources":["../../../src/remediate/phases/close.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAiB1D,OAAO,KAAK,EAIV,yBAAyB,EACzB,SAAS,EACT,kBAAkB,EAGnB,MAAM,oBAAoB,CAAC;AAK5B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EAOV,qBAAqB,EAItB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"close.d.ts","sourceRoot":"","sources":["../../../src/remediate/phases/close.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,19 +8,40 @@ import { FAILURE_OUTPUT_TAIL_CHARS } from "./constants.js";
|
|
|
8
8
|
import { verifyAnalyzerLeads } from "./closeVerifyAnalyzerLeads.js";
|
|
9
9
|
import { intakePaths } from "../intake.js";
|
|
10
10
|
import { isAuditFindingsReport } from "./plan.js";
|
|
11
|
-
import { dispositionToOutcomeStatus,
|
|
11
|
+
import { dispositionToOutcomeStatus, isSkipStatus, isTerminalStatus, isUnsuccessfulEndStatus, isVerifiedCompleteStatus, requiresVerificationEvidence, resolveDisposition, } from "../state/itemStatus.js";
|
|
12
|
+
// Brand-new exports of `src/shared/types/remediationOutcome.ts` (CDC-25/
|
|
13
|
+
// CDC-28), not yet re-exported through the `audit-tools/shared` barrel
|
|
14
|
+
// (outside this module's file_scope and this work item's allowed_files) — see
|
|
15
|
+
// the identical note in `src/remediate/state/types.ts`.
|
|
16
|
+
import { ABSENT_FINAL_GATE_REPORT, FinalGateReportSchema, isCompleteEvidence, mechanismContradictsOutcome, missingEvidenceParts, } from "../../shared/types/remediationOutcome.js";
|
|
17
|
+
// The gate record's PATH is single-sourced by the module that writes it. Leaf
|
|
18
|
+
// import (finalGate.ts imports only gateCommands.ts + shared), so this adds no
|
|
19
|
+
// cycle — and the alternative, a second `"final-gate-outcome.json"` literal
|
|
20
|
+
// here, is exactly the drift the layout registry exists to prevent.
|
|
21
|
+
import { finalGateOutcomePath } from "../steps/finalGate.js";
|
|
12
22
|
// Derived from the single source so the key list can never drift from the
|
|
13
23
|
// RemediationOutcomeStatus contract (A6).
|
|
14
24
|
const OUTCOME_KEYS = [
|
|
15
25
|
...RemediationOutcomeStatusSchema.options,
|
|
16
26
|
];
|
|
17
|
-
/**
|
|
27
|
+
/**
|
|
28
|
+
* Retry-oriented final status per outcome (see RemediationOutcomeFinalStatus).
|
|
29
|
+
* `verified_already_fixed` (CDC-25) joins `resolved`/`verified_no_change`
|
|
30
|
+
* under `fixed` — the code was already correct at HEAD, requiring no diff, the
|
|
31
|
+
* same shape as a no-change fix. `refuted` joins `inappropriate` under
|
|
32
|
+
* `skipped` — investigation determined the finding is not a real problem, so
|
|
33
|
+
* like a deemed-inappropriate finding it needs no retry; the substantive "why"
|
|
34
|
+
* for both new members lives in the outcome's `evidence` triple, not in this
|
|
35
|
+
* coarse four-value retry bucket.
|
|
36
|
+
*/
|
|
18
37
|
const FINAL_STATUS_BY_OUTCOME = {
|
|
19
38
|
resolved: "fixed",
|
|
20
39
|
verified_no_change: "fixed",
|
|
21
40
|
inappropriate: "skipped",
|
|
22
41
|
ignored: "ignored",
|
|
23
42
|
blocked: "failed",
|
|
43
|
+
verified_already_fixed: "fixed",
|
|
44
|
+
refuted: "skipped",
|
|
24
45
|
};
|
|
25
46
|
// Skipped and ignored outcomes must always carry a non-empty reason in the
|
|
26
47
|
// outcomes contract; these defaults cover items whose state lost the rationale.
|
|
@@ -65,24 +86,106 @@ function durationBetweenMs(startedAt, completedAt) {
|
|
|
65
86
|
}
|
|
66
87
|
return completed - started;
|
|
67
88
|
}
|
|
68
|
-
|
|
89
|
+
/**
|
|
90
|
+
* Read the run's tool-owned gate outcome for the report.
|
|
91
|
+
*
|
|
92
|
+
* The gate WRITES `final-gate-outcome.json` on every evaluation; until this
|
|
93
|
+
* reader existed, nothing consumed it — so a scoped-out or suppressed run
|
|
94
|
+
* produced a completion report byte-identical to one written after a green
|
|
95
|
+
* floor, which is the whole defect the record was added to close. A record that
|
|
96
|
+
* is missing, unreadable, or fails its schema degrades to
|
|
97
|
+
* {@link ABSENT_FINAL_GATE_REPORT}: stated as absent, never as green.
|
|
98
|
+
*/
|
|
99
|
+
export async function readFinalGateReport(artifactsDir) {
|
|
100
|
+
const raw = await readOptionalJsonFile(finalGateOutcomePath(artifactsDir)).catch(() => undefined);
|
|
101
|
+
if (raw === undefined || raw === null || typeof raw !== "object") {
|
|
102
|
+
return ABSENT_FINAL_GATE_REPORT;
|
|
103
|
+
}
|
|
104
|
+
// The on-disk record carries its own `schema_version`; the REPORT field does
|
|
105
|
+
// not (the outcomes contract has one of its own). Drop that key and keep the
|
|
106
|
+
// schema `.strict()` for everything else, so an unknown field is still a
|
|
107
|
+
// refusal rather than something that rides silently into the contract.
|
|
108
|
+
const { schema_version: _recordVersion, ...body } = raw;
|
|
109
|
+
const parsed = FinalGateReportSchema.safeParse(body);
|
|
110
|
+
if (!parsed.success) {
|
|
111
|
+
return {
|
|
112
|
+
...ABSENT_FINAL_GATE_REPORT,
|
|
113
|
+
reason: "a gate outcome record exists but does not match the outcome contract; " +
|
|
114
|
+
"treated as no verdict",
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
// Defense in depth against a hand-edited or older record: only an EXECUTED
|
|
118
|
+
// gate may carry a verdict. A not-run kind asserting `passed: true` is
|
|
119
|
+
// normalized away here rather than reprinted into the report.
|
|
120
|
+
return parsed.data.outcome === "executed"
|
|
121
|
+
? parsed.data
|
|
122
|
+
: { ...parsed.data, passed: null, commands_run: 0 };
|
|
123
|
+
}
|
|
124
|
+
export function buildRemediationOutcomesReport(state, closingResult,
|
|
125
|
+
// Defaults to ABSENT so every existing caller keeps compiling AND keeps
|
|
126
|
+
// telling the truth: a caller that supplies no gate outcome is a run with no
|
|
127
|
+
// gate outcome, which the contract now states outright.
|
|
128
|
+
finalGate = ABSENT_FINAL_GATE_REPORT) {
|
|
69
129
|
const findingsById = new Map((state.plan?.findings ?? []).map((finding) => [finding.id, finding]));
|
|
70
130
|
const blocksById = new Map((state.plan?.blocks ?? []).map((block) => [block.block_id, block]));
|
|
71
131
|
const outcomes = [];
|
|
72
132
|
const closeReason = closingStatusReason(closingResult);
|
|
73
133
|
for (const item of Object.values(state.items ?? {})) {
|
|
74
|
-
// Derive the outcome from the single status→disposition→outcome
|
|
75
|
-
//
|
|
76
|
-
//
|
|
77
|
-
//
|
|
134
|
+
// Derive the outcome from the single status→disposition→outcome
|
|
135
|
+
// authority. A non-terminal status — in-progress, `blocked`, or an
|
|
136
|
+
// unanswered `needs_clarification` — means the run was force-closed while
|
|
137
|
+
// the item was still non-terminal: record it as a failed (`blocked`)
|
|
138
|
+
// outcome — never drop it — and preserve the original state so a retry
|
|
139
|
+
// sees where it stood (every non-terminal status, not only the five
|
|
140
|
+
// in-progress ones — needs_clarification included).
|
|
78
141
|
let outcome;
|
|
79
142
|
let originalState;
|
|
80
|
-
|
|
143
|
+
let evidence;
|
|
144
|
+
let recordedByModule;
|
|
145
|
+
let evidenceRefusalReason;
|
|
146
|
+
if (!isTerminalStatus(item.status)) {
|
|
81
147
|
outcome = "blocked";
|
|
82
148
|
originalState = item.status;
|
|
83
149
|
}
|
|
84
150
|
else {
|
|
85
|
-
|
|
151
|
+
const disposition = resolveDisposition(item.status, item.disposition_override);
|
|
152
|
+
if (requiresVerificationEvidence(disposition)) {
|
|
153
|
+
// INV-ISC-EVIDENCE-EMITTED — the writer-side backstop. REFUSE a
|
|
154
|
+
// `verified_already_fixed`/`refuted` terminal disposition whose
|
|
155
|
+
// evidence triple is incomplete, or whose complete triple's mechanism
|
|
156
|
+
// CONTRADICTS the disposition it is meant to establish (RED
|
|
157
|
+
// condition (4)'s mechanism-contradiction leg, the W4 witness) —
|
|
158
|
+
// record a non-terminal `blocked` outcome naming the missing or
|
|
159
|
+
// contradicting part instead of a green close on the audit's
|
|
160
|
+
// assertion alone.
|
|
161
|
+
const missing = missingEvidenceParts(item.evidence);
|
|
162
|
+
if (missing.length > 0 || !isCompleteEvidence(item.evidence)) {
|
|
163
|
+
outcome = "blocked";
|
|
164
|
+
evidenceRefusalReason = `incomplete verification evidence for disposition '${disposition}' (missing: ${missing.join(", ")})`;
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
const candidateOutcome = dispositionToOutcomeStatus(disposition);
|
|
168
|
+
if (mechanismContradictsOutcome(candidateOutcome, item.evidence.mechanism)) {
|
|
169
|
+
outcome = "blocked";
|
|
170
|
+
evidenceRefusalReason = `evidence mechanism '${item.evidence.mechanism}' contradicts disposition '${disposition}'`;
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
outcome = candidateOutcome;
|
|
174
|
+
evidence = item.evidence;
|
|
175
|
+
recordedByModule = item.recorded_by_module;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
outcome = dispositionToOutcomeStatus(disposition);
|
|
181
|
+
// Evidence is optional decoration for the original five dispositions,
|
|
182
|
+
// but when a module DID record it, round-trip it byte-exact (the
|
|
183
|
+
// ATTRIBUTION ROUND-TRIP) rather than silently dropping it.
|
|
184
|
+
if (isCompleteEvidence(item.evidence)) {
|
|
185
|
+
evidence = item.evidence;
|
|
186
|
+
recordedByModule = item.recorded_by_module;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
86
189
|
}
|
|
87
190
|
const finding = findingsById.get(item.finding_id);
|
|
88
191
|
const fileExts = [
|
|
@@ -91,12 +194,18 @@ export function buildRemediationOutcomesReport(state, closingResult) {
|
|
|
91
194
|
.filter((ext) => ext.length > 0)),
|
|
92
195
|
].sort();
|
|
93
196
|
const durationMs = durationBetweenMs(item.started_at, item.completed_at);
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
197
|
+
const isSuccessfulOutcome = outcome === "resolved" ||
|
|
198
|
+
outcome === "verified_no_change" ||
|
|
199
|
+
outcome === "verified_already_fixed" ||
|
|
200
|
+
outcome === "refuted";
|
|
201
|
+
let reason = !isSuccessfulOutcome ? item.failure_reason : undefined;
|
|
202
|
+
if (evidenceRefusalReason) {
|
|
203
|
+
reason = `INV-ISC-EVIDENCE-EMITTED refusal: ${evidenceRefusalReason}.${item.failure_reason ? ` ${item.failure_reason}` : ""}`;
|
|
204
|
+
}
|
|
205
|
+
else if (originalState) {
|
|
97
206
|
reason = `Force-closed while non-terminal (original state '${originalState}').${item.failure_reason ? ` ${item.failure_reason}` : ""}`;
|
|
98
207
|
}
|
|
99
|
-
else if (
|
|
208
|
+
else if (!isSuccessfulOutcome && !reason) {
|
|
100
209
|
reason = DEFAULT_REASON_BY_OUTCOME[outcome];
|
|
101
210
|
}
|
|
102
211
|
const base = {
|
|
@@ -114,6 +223,8 @@ export function buildRemediationOutcomesReport(state, closingResult) {
|
|
|
114
223
|
...(item.mechanical_verification
|
|
115
224
|
? { mechanical_verification: item.mechanical_verification }
|
|
116
225
|
: {}),
|
|
226
|
+
...(evidence ? { evidence } : {}),
|
|
227
|
+
...(recordedByModule ? { recorded_by_module: recordedByModule } : {}),
|
|
117
228
|
};
|
|
118
229
|
if (!finding) {
|
|
119
230
|
// Degenerate (corrupt state): without the plan finding there is no payload
|
|
@@ -185,6 +296,7 @@ export function buildRemediationOutcomesReport(state, closingResult) {
|
|
|
185
296
|
...(aggregateStarted ? { started_at: aggregateStarted.value } : {}),
|
|
186
297
|
...(aggregateCompleted ? { completed_at: aggregateCompleted.value } : {}),
|
|
187
298
|
...(aggregateDuration !== undefined ? { duration_ms: aggregateDuration } : {}),
|
|
299
|
+
final_gate: finalGate,
|
|
188
300
|
outcomes,
|
|
189
301
|
};
|
|
190
302
|
}
|
|
@@ -598,12 +710,17 @@ export function executeClosingAction(state, options) {
|
|
|
598
710
|
/**
|
|
599
711
|
* Run the plan's combined test suite over the fully merged post-remediation
|
|
600
712
|
* state. Returns pass/fail plus the failure-output tail. No test_command =>
|
|
601
|
-
*
|
|
713
|
+
* `ran:false` (never-ran, distinct from a real pass) — `passed` still reports
|
|
714
|
+
* `true` so existing gates that fold `combinedTest.passed` into `fullyGreen`
|
|
715
|
+
* keep their vacuously-green behavior for a run with no configured suite;
|
|
716
|
+
* `ran` is what lets a caller (buildVerificationReport's trace) tell the two
|
|
717
|
+
* apart rather than rendering "combined test suite passed" for a suite that
|
|
718
|
+
* never executed.
|
|
602
719
|
*/
|
|
603
|
-
function runCombinedTestSuite(state, options) {
|
|
720
|
+
export function runCombinedTestSuite(state, options) {
|
|
604
721
|
console.log("Running full test suite on combined post-remediation state...");
|
|
605
722
|
if (!state.plan?.test_command) {
|
|
606
|
-
return { passed: true, duration_ms: 0, output: "" };
|
|
723
|
+
return { ran: false, passed: true, duration_ms: 0, output: "" };
|
|
607
724
|
}
|
|
608
725
|
const suiteName = Array.isArray(state.plan.test_command)
|
|
609
726
|
? state.plan.test_command.join(" ")
|
|
@@ -619,12 +736,12 @@ function runCombinedTestSuite(state, options) {
|
|
|
619
736
|
});
|
|
620
737
|
const durationMs = Date.now() - startedAt;
|
|
621
738
|
if (result.status === 0) {
|
|
622
|
-
return { passed: true, suite_name: suiteName, duration_ms: durationMs, output: "" };
|
|
739
|
+
return { ran: true, passed: true, suite_name: suiteName, duration_ms: durationMs, output: "" };
|
|
623
740
|
}
|
|
624
741
|
const output = ((result.stdout?.toString() ?? "") + (result.stderr?.toString() ?? ""))
|
|
625
742
|
.trim()
|
|
626
743
|
.slice(-FAILURE_OUTPUT_TAIL_CHARS);
|
|
627
|
-
return { passed: false, suite_name: suiteName, duration_ms: durationMs, output };
|
|
744
|
+
return { ran: true, passed: false, suite_name: suiteName, duration_ms: durationMs, output };
|
|
628
745
|
}
|
|
629
746
|
/**
|
|
630
747
|
* Parse test output to extract implicated file paths. Looks for common test
|
|
@@ -649,13 +766,29 @@ function extractImplicatedPaths(testOutput) {
|
|
|
649
766
|
}
|
|
650
767
|
return [...paths];
|
|
651
768
|
}
|
|
769
|
+
/**
|
|
770
|
+
* Whether a touched file `tf` and an implicated path `ip` (extracted from test
|
|
771
|
+
* output, which may be a bare/partial path) refer to the same file: exact
|
|
772
|
+
* match after normalization, or one is a path-SEPARATOR-anchored suffix of the
|
|
773
|
+
* other. Never a bare string-suffix test — `"src/myfoo.ts".endsWith("foo.ts")`
|
|
774
|
+
* is true but the two are unrelated files; anchoring the match to a `/`
|
|
775
|
+
* boundary (via `normalizeRepoPath`, which also folds case/slash direction) is
|
|
776
|
+
* what a real path-key join requires and a substring test does not give.
|
|
777
|
+
*/
|
|
778
|
+
function touchedPathMatchesImplicated(tf, ip) {
|
|
779
|
+
const a = normalizeRepoPath(tf);
|
|
780
|
+
const b = normalizeRepoPath(ip);
|
|
781
|
+
if (a === b)
|
|
782
|
+
return true;
|
|
783
|
+
return a.endsWith(`/${b}`) || b.endsWith(`/${a}`);
|
|
784
|
+
}
|
|
652
785
|
/**
|
|
653
786
|
* On a combined-test failure, selectively re-block items whose touched_files
|
|
654
787
|
* overlap with the failing tests' implicated paths. When attribution is
|
|
655
788
|
* ambiguous (no overlap found), falls back to re-blocking all resolved items.
|
|
656
789
|
* Returns whether any item was blocked — the caller transitions back to triage.
|
|
657
790
|
*/
|
|
658
|
-
function blockResolvedItemsOnCombinedFailure(state, testOutput) {
|
|
791
|
+
export function blockResolvedItemsOnCombinedFailure(state, testOutput) {
|
|
659
792
|
const resolvedItems = Object.values(state.items ?? {}).filter((i) => isVerifiedCompleteStatus(i.status));
|
|
660
793
|
if (resolvedItems.length === 0)
|
|
661
794
|
return false;
|
|
@@ -666,7 +799,7 @@ function blockResolvedItemsOnCombinedFailure(state, testOutput) {
|
|
|
666
799
|
if (implicatedPaths.length > 0) {
|
|
667
800
|
for (const item of resolvedItems) {
|
|
668
801
|
const touchedFiles = item.item_spec?.touched_files ?? [];
|
|
669
|
-
const overlaps = touchedFiles.some((tf) => implicatedPaths.some((ip) =>
|
|
802
|
+
const overlaps = touchedFiles.some((tf) => implicatedPaths.some((ip) => touchedPathMatchesImplicated(tf, ip)));
|
|
670
803
|
if (overlaps)
|
|
671
804
|
attributed.push(item);
|
|
672
805
|
}
|
|
@@ -864,6 +997,25 @@ function buildRemediationReportMarkdown(state, entries, closingResult, e2ePassed
|
|
|
864
997
|
reportContent += `- \`${f}\`\n`;
|
|
865
998
|
}
|
|
866
999
|
}
|
|
1000
|
+
// The tool-owned repository gate, ALWAYS rendered. A run whose gate was
|
|
1001
|
+
// scoped out, suppressed, or never reached used to produce a report identical
|
|
1002
|
+
// to one written after a green floor — "the suite passed" and "no suite ran"
|
|
1003
|
+
// were the same document. Every branch below names which happened.
|
|
1004
|
+
const gate = outcomesReport.final_gate;
|
|
1005
|
+
reportContent += `\n## Repository Gate\n\n`;
|
|
1006
|
+
if (gate.outcome === "executed") {
|
|
1007
|
+
reportContent += `Outcome: executed — the repository build/typecheck/test floor RAN (${gate.commands_run} command(s)) and ${gate.passed ? "PASSED" : "FAILED"}.\n`;
|
|
1008
|
+
}
|
|
1009
|
+
else if (gate.outcome === "absent") {
|
|
1010
|
+
reportContent += `Outcome: absent — NO gate outcome was recorded for this run, so nothing here corroborates it. This is not a pass.\n`;
|
|
1011
|
+
}
|
|
1012
|
+
else {
|
|
1013
|
+
reportContent += `Outcome: ${gate.outcome} — the repository floor did NOT run (0 commands), so nothing here corroborates this run. This is not a pass.\n`;
|
|
1014
|
+
}
|
|
1015
|
+
if (gate.reason)
|
|
1016
|
+
reportContent += `Reason: ${gate.reason}\n`;
|
|
1017
|
+
if (gate.scope)
|
|
1018
|
+
reportContent += `Scope: ${gate.scope}\n`;
|
|
867
1019
|
if (e2ePassed !== undefined) {
|
|
868
1020
|
reportContent += `\n## End-to-End Tests\n\nResult: ${e2ePassed ? "passed" : "failed"}\n`;
|
|
869
1021
|
}
|
|
@@ -938,11 +1090,15 @@ export async function cleanupTempBranchesAndArtifacts(options, completeState, co
|
|
|
938
1090
|
// Only delete artifacts on a fully-green close. When any test or closing
|
|
939
1091
|
// action failed, preserve the directory for diagnosis.
|
|
940
1092
|
//
|
|
941
|
-
//
|
|
942
|
-
//
|
|
943
|
-
//
|
|
944
|
-
//
|
|
945
|
-
//
|
|
1093
|
+
// Force-close guard: a `blocked` or `abandoned` item means the run did NOT
|
|
1094
|
+
// fully succeed. It reaches close that way through triage exhausting an item's
|
|
1095
|
+
// retries, an operator halt, or the force-close backstop converting a
|
|
1096
|
+
// still-non-terminal item — NOT through the tool-owned gate, which no longer
|
|
1097
|
+
// mutates item statuses at all (a red pauses the run instead of re-blocking or
|
|
1098
|
+
// abandoning). The guard is unchanged and still needed; only its causes are.
|
|
1099
|
+
// Such a run must never be "landed green" (artifacts deleted as if complete); a
|
|
1100
|
+
// vacuous/unset plan.test_command (combinedTest vacuously passing) cannot mask
|
|
1101
|
+
// it. Preserve
|
|
946
1102
|
// the artifacts so the partial outcome is diagnosable. The predicate is
|
|
947
1103
|
// single-sourced in itemStatus so this guard cannot drift from the seam that
|
|
948
1104
|
// produces the statuses it defends against.
|
|
@@ -963,7 +1119,7 @@ export async function cleanupTempBranchesAndArtifacts(options, completeState, co
|
|
|
963
1119
|
artifact: options.artifactsDir,
|
|
964
1120
|
note: `Artifacts directory preserved for diagnosis (combinedTest.passed=${combinedTest.passed}, e2e.passed=${e2eResult.passed}, closing=${closingResult.status}, closingAction=${closingResult.action}, anyBlocked=${anyBlocked})`,
|
|
965
1121
|
});
|
|
966
|
-
return;
|
|
1122
|
+
return {};
|
|
967
1123
|
}
|
|
968
1124
|
// Archive the friction close-out record with the promoted deliverables BEFORE
|
|
969
1125
|
// deleting the artifacts dir — same property as the audit side's
|
|
@@ -988,7 +1144,9 @@ export async function cleanupTempBranchesAndArtifacts(options, completeState, co
|
|
|
988
1144
|
artifact: options.artifactsDir,
|
|
989
1145
|
note: `Failed to clean up artifacts directory (manual removal may be needed): ${reason}`,
|
|
990
1146
|
});
|
|
1147
|
+
return { artifacts_residue: options.artifactsDir };
|
|
991
1148
|
}
|
|
1149
|
+
return {};
|
|
992
1150
|
}
|
|
993
1151
|
/**
|
|
994
1152
|
* Build a VerificationReport from the post-remediation state. One
|
|
@@ -1031,16 +1189,25 @@ export function buildVerificationReport(state, options, closingResult, combinedT
|
|
|
1031
1189
|
});
|
|
1032
1190
|
continue;
|
|
1033
1191
|
}
|
|
1034
|
-
// Combined test suite trace.
|
|
1192
|
+
// Combined test suite trace. A never-configured suite (`ran:false`) is
|
|
1193
|
+
// NEVER labelled "passed" here — `combinedTest.passed` stays `true` for
|
|
1194
|
+
// that case only so the pre-existing fullyGreen/itemPassed formulas below
|
|
1195
|
+
// keep their vacuously-green behavior; this trace's own evidence/status is
|
|
1196
|
+
// what tells a reader "nothing ran" apart from "it ran and passed"
|
|
1197
|
+
// (`status` stays the file's established "failed" for any non-affirmative
|
|
1198
|
+
// case — see the identical choice on the skipped-item trace above — the
|
|
1199
|
+
// finding-level verdict is driven by `itemPassed`, not by this one trace).
|
|
1035
1200
|
const suiteLabel = combinedTest.suite_name ?? "combined test suite";
|
|
1036
1201
|
traces.push({
|
|
1037
1202
|
trace_id: `${item.finding_id}:combined-tests`,
|
|
1038
1203
|
kind: "task",
|
|
1039
1204
|
label: suiteLabel,
|
|
1040
|
-
evidence: combinedTest.
|
|
1041
|
-
? [
|
|
1042
|
-
:
|
|
1043
|
-
|
|
1205
|
+
evidence: !combinedTest.ran
|
|
1206
|
+
? ["no combined test suite configured for this run"]
|
|
1207
|
+
: combinedTest.passed
|
|
1208
|
+
? [`${suiteLabel} passed`]
|
|
1209
|
+
: [`${suiteLabel} failed`, ...(combinedTest.output ? [combinedTest.output.slice(-500)] : [])],
|
|
1210
|
+
status: combinedTest.ran && combinedTest.passed ? "passed" : "failed",
|
|
1044
1211
|
});
|
|
1045
1212
|
const contractGoalId = finding?.contract_goal_id ?? state.plan?.goal_id;
|
|
1046
1213
|
if (contractGoalId) {
|
|
@@ -1144,6 +1311,25 @@ export async function runClosePhase(state, options, runLogger) {
|
|
|
1144
1311
|
if (!state.plan || !state.items || !state.closing_plan) {
|
|
1145
1312
|
throw new Error("Cannot run close phase: missing plan, items, or closing_plan from state.");
|
|
1146
1313
|
}
|
|
1314
|
+
// CDC-19 (advisory): a planned finding with no corresponding item in
|
|
1315
|
+
// state.items would be left uncounted by every module's INV-COVERAGE join
|
|
1316
|
+
// — a module that was blocked or never dispatched must not silently vanish
|
|
1317
|
+
// from the coverage set. Diagnostic-only: never throws, and a no-op unless a
|
|
1318
|
+
// runLogger is actually wired, so it changes nothing for a caller that
|
|
1319
|
+
// doesn't ask for it.
|
|
1320
|
+
{
|
|
1321
|
+
const findingIds = new Set((state.plan.findings ?? []).map((f) => f.id));
|
|
1322
|
+
const itemIds = new Set(Object.keys(state.items));
|
|
1323
|
+
const uncounted = [...findingIds].filter((id) => !itemIds.has(id));
|
|
1324
|
+
if (uncounted.length > 0) {
|
|
1325
|
+
runLogger?.event({
|
|
1326
|
+
phase: "close",
|
|
1327
|
+
kind: "error",
|
|
1328
|
+
obligation: "closing",
|
|
1329
|
+
note: `${uncounted.length} planned finding(s) have no corresponding item in state.items and would be left uncounted by every module's coverage join: ${uncounted.slice(0, 10).join(", ")}`,
|
|
1330
|
+
});
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1147
1333
|
// 1. Check whether closing action requires user confirmation (preview).
|
|
1148
1334
|
// When not pre-authorized and action is confirmable, generate the file list +
|
|
1149
1335
|
// commit message, attach them to closing_plan.closing_action_preview, and
|
|
@@ -1151,6 +1337,12 @@ export async function runClosePhase(state, options, runLogger) {
|
|
|
1151
1337
|
// closing_plan.pre_authorized = true before the next next-step call.
|
|
1152
1338
|
const preview = checkClosingPreview(state, options);
|
|
1153
1339
|
if (preview) {
|
|
1340
|
+
runLogger?.event({
|
|
1341
|
+
phase: "close",
|
|
1342
|
+
kind: "state",
|
|
1343
|
+
obligation: "closing",
|
|
1344
|
+
note: `Closing action '${state.closing_plan.action}' requires confirmation before proceeding — preview attached, awaiting pre_authorized.`,
|
|
1345
|
+
});
|
|
1154
1346
|
const updatedClosingPlan = { ...state.closing_plan, closing_action_preview: preview };
|
|
1155
1347
|
return { ...state, closing_plan: updatedClosingPlan };
|
|
1156
1348
|
}
|
|
@@ -1159,6 +1351,12 @@ export async function runClosePhase(state, options, runLogger) {
|
|
|
1159
1351
|
if (!combinedTest.passed) {
|
|
1160
1352
|
console.log("Full test suite failed. Transitioning back to triage.");
|
|
1161
1353
|
if (blockResolvedItemsOnCombinedFailure(state, combinedTest.output)) {
|
|
1354
|
+
runLogger?.event({
|
|
1355
|
+
phase: "close",
|
|
1356
|
+
kind: "state",
|
|
1357
|
+
obligation: "closing",
|
|
1358
|
+
note: "Combined test suite failed — re-blocked resolved item(s), transitioning to triage.",
|
|
1359
|
+
});
|
|
1162
1360
|
return { ...state, status: "triage" };
|
|
1163
1361
|
}
|
|
1164
1362
|
console.warn("Combined test suite failed but no resolved items to re-block — completing with test failure recorded in report.");
|
|
@@ -1194,15 +1392,34 @@ export async function runClosePhase(state, options, runLogger) {
|
|
|
1194
1392
|
if (analyzerVerify.persisting.length > 0) {
|
|
1195
1393
|
console.log(`Analyzer lead re-verify: ${analyzerVerify.persisting.length} lead(s) persist ` +
|
|
1196
1394
|
`(${analyzerVerify.persisting.join(", ")}). Transitioning back to triage.`);
|
|
1395
|
+
runLogger?.event({
|
|
1396
|
+
phase: "close",
|
|
1397
|
+
kind: "state",
|
|
1398
|
+
obligation: "closing",
|
|
1399
|
+
note: `Mechanical re-verify: ${analyzerVerify.persisting.length} analyzer lead(s) persist (${analyzerVerify.persisting.join(", ")}) — transitioning to triage.`,
|
|
1400
|
+
});
|
|
1197
1401
|
return { ...state, status: "triage" };
|
|
1198
1402
|
}
|
|
1199
1403
|
}
|
|
1200
|
-
// 3. Run end-to-end tests on the fully merged post-remediation state.
|
|
1404
|
+
// 3. Run end-to-end tests on the fully merged post-remediation state. Mirrors
|
|
1405
|
+
// the combined-test-failure branch's own guard above: a failure transitions
|
|
1406
|
+
// to triage ONLY when something was actually re-blocked for triage to act
|
|
1407
|
+
// on, never unconditionally (a failure with zero verified-complete items has
|
|
1408
|
+
// nothing to re-block, so an unconditional triage transition would enter a
|
|
1409
|
+
// state with no newly-blocked item to drive it forward).
|
|
1201
1410
|
const e2eResult = runE2eTests(state, options);
|
|
1202
1411
|
if (!e2eResult.passed) {
|
|
1203
1412
|
console.log("End-to-end tests failed. Transitioning back to triage.");
|
|
1204
|
-
blockResolvedItemsOnCombinedFailure(state, e2eResult.output)
|
|
1205
|
-
|
|
1413
|
+
if (blockResolvedItemsOnCombinedFailure(state, e2eResult.output)) {
|
|
1414
|
+
runLogger?.event({
|
|
1415
|
+
phase: "close",
|
|
1416
|
+
kind: "state",
|
|
1417
|
+
obligation: "closing",
|
|
1418
|
+
note: "End-to-end tests failed — re-blocked resolved item(s), transitioning to triage.",
|
|
1419
|
+
});
|
|
1420
|
+
return { ...state, status: "triage" };
|
|
1421
|
+
}
|
|
1422
|
+
console.warn("End-to-end tests failed but no resolved items to re-block — completing with e2e failure recorded in report.");
|
|
1206
1423
|
}
|
|
1207
1424
|
// 4. Execute the closing action and record exact command outcomes before
|
|
1208
1425
|
// reporting success.
|
|
@@ -1211,8 +1428,15 @@ export async function runClosePhase(state, options, runLogger) {
|
|
|
1211
1428
|
await writeJsonFile(join(options.artifactsDir, "remediation-closing-result.json"), closingResult);
|
|
1212
1429
|
// 4. Generate remediation-report.md and remediation-report.json
|
|
1213
1430
|
const entries = collectReportEntries(state, options);
|
|
1214
|
-
// Phase 7B: capture per-finding outcomes (surface only)
|
|
1215
|
-
|
|
1431
|
+
// Phase 7B: capture per-finding outcomes (surface only), carrying the run's
|
|
1432
|
+
// tool-owned gate outcome so the report can say which of executed / scoped-out
|
|
1433
|
+
// / disabled / absent this run actually was.
|
|
1434
|
+
const finalGate = await readFinalGateReport(options.artifactsDir);
|
|
1435
|
+
const outcomesReport = buildRemediationOutcomesReport(state, closingResult, finalGate);
|
|
1436
|
+
// No run-log line for the gate here ON PURPOSE: the gate already records its
|
|
1437
|
+
// own outcome at evaluation time (`recordFinalGateOutcome`), so a second line
|
|
1438
|
+
// at close would be a duplicate — and `kind: "outcome"` at close means "one
|
|
1439
|
+
// per finding", which a run-level line would quietly break.
|
|
1216
1440
|
// One run-log line per outcome, plus a summary line for the artifact write.
|
|
1217
1441
|
for (const outcome of outcomesReport.outcomes) {
|
|
1218
1442
|
runLogger?.event({
|