audit-tools 0.50.21 → 0.51.1
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 +1 -1
- package/dist/audit/cli/auditStep.d.ts +1 -1
- package/dist/audit/cli/charterExtractionPrompt.d.ts.map +1 -1
- package/dist/audit/cli/charterExtractionPrompt.js +14 -1
- package/dist/audit/cli/charterExtractionPrompt.js.map +1 -1
- package/dist/audit/cli/cleanup.d.ts +0 -1
- package/dist/audit/cli/cleanup.d.ts.map +1 -1
- package/dist/audit/cli/cleanup.js +32 -20
- package/dist/audit/cli/cleanup.js.map +1 -1
- package/dist/audit/cli/conceptualDispatch.d.ts.map +1 -1
- package/dist/audit/cli/conceptualDispatch.js +30 -5
- package/dist/audit/cli/conceptualDispatch.js.map +1 -1
- package/dist/audit/cli/dispatch/hostHandoff.d.ts +2 -0
- package/dist/audit/cli/dispatch/hostHandoff.d.ts.map +1 -1
- package/dist/audit/cli/dispatch/hostHandoff.js +48 -20
- package/dist/audit/cli/dispatch/hostHandoff.js.map +1 -1
- package/dist/audit/cli/fanoutLanes.d.ts +7 -0
- package/dist/audit/cli/fanoutLanes.d.ts.map +1 -1
- package/dist/audit/cli/fanoutLanes.js +9 -1
- package/dist/audit/cli/fanoutLanes.js.map +1 -1
- package/dist/audit/cli/forceSynthesisCommand.d.ts.map +1 -1
- package/dist/audit/cli/forceSynthesisCommand.js +2 -14
- package/dist/audit/cli/forceSynthesisCommand.js.map +1 -1
- package/dist/audit/cli/intakeCommand.d.ts.map +1 -1
- package/dist/audit/cli/intakeCommand.js +3 -13
- package/dist/audit/cli/intakeCommand.js.map +1 -1
- package/dist/audit/cli/laneSubmissions.d.ts +42 -57
- package/dist/audit/cli/laneSubmissions.d.ts.map +1 -1
- package/dist/audit/cli/laneSubmissions.js +116 -82
- package/dist/audit/cli/laneSubmissions.js.map +1 -1
- package/dist/audit/cli/nextStepCommand.d.ts.map +1 -1
- package/dist/audit/cli/nextStepCommand.js +132 -99
- package/dist/audit/cli/nextStepCommand.js.map +1 -1
- package/dist/audit/cli/nextStepHelpers.d.ts.map +1 -1
- package/dist/audit/cli/nextStepHelpers.js +39 -46
- package/dist/audit/cli/nextStepHelpers.js.map +1 -1
- package/dist/audit/cli/resynthesizeCommand.d.ts.map +1 -1
- package/dist/audit/cli/resynthesizeCommand.js +5 -2
- package/dist/audit/cli/resynthesizeCommand.js.map +1 -1
- package/dist/audit/cli/sampleRunCommand.d.ts +3 -2
- package/dist/audit/cli/sampleRunCommand.d.ts.map +1 -1
- package/dist/audit/cli/stepScaffold.d.ts +21 -0
- package/dist/audit/cli/stepScaffold.d.ts.map +1 -0
- package/dist/audit/cli/stepScaffold.js +50 -0
- package/dist/audit/cli/stepScaffold.js.map +1 -0
- package/dist/audit/cli/steps.d.ts +6 -6
- package/dist/audit/cli/synthesizeCommand.d.ts.map +1 -1
- package/dist/audit/cli/synthesizeCommand.js +2 -14
- package/dist/audit/cli/synthesizeCommand.js.map +1 -1
- package/dist/audit/contracts/workerSchemas.d.ts +8 -8
- package/dist/audit/contracts/workerSchemas.d.ts.map +1 -1
- package/dist/audit/contracts/workerSchemas.js +12 -6
- package/dist/audit/contracts/workerSchemas.js.map +1 -1
- package/dist/audit/contracts/wrapperResponse.d.ts +7 -7
- package/dist/audit/contracts/wrapperResponse.d.ts.map +1 -1
- package/dist/audit/contracts/wrapperResponse.js +9 -1
- package/dist/audit/contracts/wrapperResponse.js.map +1 -1
- package/dist/audit/extractors/analyzers/merge.d.ts.map +1 -1
- package/dist/audit/extractors/analyzers/merge.js +2 -7
- package/dist/audit/extractors/analyzers/merge.js.map +1 -1
- package/dist/audit/extractors/commentDecomposition.d.ts +28 -0
- package/dist/audit/extractors/commentDecomposition.d.ts.map +1 -1
- package/dist/audit/extractors/commentDecomposition.js +151 -22
- package/dist/audit/extractors/commentDecomposition.js.map +1 -1
- package/dist/audit/extractors/graph.d.ts +1 -1
- package/dist/audit/extractors/graph.d.ts.map +1 -1
- package/dist/audit/extractors/graph.js +2 -6
- package/dist/audit/extractors/graph.js.map +1 -1
- package/dist/audit/extractors/graphManifestEdges/cargo.d.ts.map +1 -1
- package/dist/audit/extractors/graphManifestEdges/cargo.js +4 -4
- package/dist/audit/extractors/graphManifestEdges/cargo.js.map +1 -1
- package/dist/audit/extractors/graphManifestEdges/pnpm.d.ts.map +1 -1
- package/dist/audit/extractors/graphManifestEdges/pnpm.js +3 -3
- package/dist/audit/extractors/graphManifestEdges/pnpm.js.map +1 -1
- package/dist/audit/extractors/graphManifestEdges/pyproject.d.ts.map +1 -1
- package/dist/audit/extractors/graphManifestEdges/pyproject.js +3 -2
- package/dist/audit/extractors/graphManifestEdges/pyproject.js.map +1 -1
- package/dist/audit/extractors/graphManifestEdges/toml.d.ts +0 -6
- package/dist/audit/extractors/graphManifestEdges/toml.d.ts.map +1 -1
- package/dist/audit/extractors/graphManifestEdges/toml.js +0 -13
- package/dist/audit/extractors/graphManifestEdges/toml.js.map +1 -1
- package/dist/audit/extractors/graphManifestEdges/workspace.d.ts +9 -0
- package/dist/audit/extractors/graphManifestEdges/workspace.d.ts.map +1 -1
- package/dist/audit/extractors/graphManifestEdges/workspace.js +16 -0
- package/dist/audit/extractors/graphManifestEdges/workspace.js.map +1 -1
- package/dist/audit/extractors/graphManifestEdges/yaml.d.ts +0 -2
- package/dist/audit/extractors/graphManifestEdges/yaml.d.ts.map +1 -1
- package/dist/audit/extractors/graphManifestEdges/yaml.js +0 -9
- package/dist/audit/extractors/graphManifestEdges/yaml.js.map +1 -1
- package/dist/audit/extractors/graphSignals.d.ts.map +1 -1
- package/dist/audit/extractors/graphSignals.js +16 -2
- package/dist/audit/extractors/graphSignals.js.map +1 -1
- package/dist/audit/io/artifacts.d.ts +19 -0
- package/dist/audit/io/artifacts.d.ts.map +1 -1
- package/dist/audit/io/artifacts.js +44 -2
- package/dist/audit/io/artifacts.js.map +1 -1
- package/dist/audit/orchestrator/advance.d.ts +0 -22
- package/dist/audit/orchestrator/advance.d.ts.map +1 -1
- package/dist/audit/orchestrator/advance.js +1 -43
- package/dist/audit/orchestrator/advance.js.map +1 -1
- package/dist/audit/orchestrator/charterDeltaExecutor.d.ts.map +1 -1
- package/dist/audit/orchestrator/charterDeltaExecutor.js +14 -0
- package/dist/audit/orchestrator/charterDeltaExecutor.js.map +1 -1
- package/dist/audit/orchestrator/charterExtractionExecutor.d.ts +16 -6
- package/dist/audit/orchestrator/charterExtractionExecutor.d.ts.map +1 -1
- package/dist/audit/orchestrator/charterExtractionExecutor.js +127 -9
- package/dist/audit/orchestrator/charterExtractionExecutor.js.map +1 -1
- package/dist/audit/orchestrator/charterPacketArchive.d.ts +51 -0
- package/dist/audit/orchestrator/charterPacketArchive.d.ts.map +1 -0
- package/dist/audit/orchestrator/charterPacketArchive.js +173 -0
- package/dist/audit/orchestrator/charterPacketArchive.js.map +1 -0
- package/dist/audit/orchestrator/charterPackets.d.ts +31 -13
- package/dist/audit/orchestrator/charterPackets.d.ts.map +1 -1
- package/dist/audit/orchestrator/charterPackets.js +299 -96
- package/dist/audit/orchestrator/charterPackets.js.map +1 -1
- package/dist/audit/orchestrator/designReviewPrompt.d.ts +20 -4
- package/dist/audit/orchestrator/designReviewPrompt.d.ts.map +1 -1
- package/dist/audit/orchestrator/designReviewPrompt.js +89 -12
- package/dist/audit/orchestrator/designReviewPrompt.js.map +1 -1
- package/dist/audit/orchestrator/edgeReasoning.d.ts.map +1 -1
- package/dist/audit/orchestrator/edgeReasoning.js +4 -9
- package/dist/audit/orchestrator/edgeReasoning.js.map +1 -1
- package/dist/audit/orchestrator/executorRunners.d.ts.map +1 -1
- package/dist/audit/orchestrator/executorRunners.js +17 -1
- package/dist/audit/orchestrator/executorRunners.js.map +1 -1
- package/dist/audit/orchestrator/graphEnrichmentExecutor.d.ts.map +1 -1
- package/dist/audit/orchestrator/graphEnrichmentExecutor.js +8 -1
- package/dist/audit/orchestrator/graphEnrichmentExecutor.js.map +1 -1
- package/dist/audit/orchestrator/intentCheckpointGate.d.ts.map +1 -1
- package/dist/audit/orchestrator/intentCheckpointGate.js +11 -2
- package/dist/audit/orchestrator/intentCheckpointGate.js.map +1 -1
- package/dist/audit/orchestrator/lineCounts.d.ts +44 -0
- package/dist/audit/orchestrator/lineCounts.d.ts.map +1 -0
- package/dist/audit/orchestrator/lineCounts.js +61 -0
- package/dist/audit/orchestrator/lineCounts.js.map +1 -0
- package/dist/audit/orchestrator/obligationDerive.d.ts +35 -0
- package/dist/audit/orchestrator/obligationDerive.d.ts.map +1 -0
- package/dist/audit/orchestrator/obligationDerive.js +50 -0
- package/dist/audit/orchestrator/obligationDerive.js.map +1 -0
- package/dist/audit/orchestrator/reviewPacketMetrics.d.ts.map +1 -1
- package/dist/audit/orchestrator/reviewPacketMetrics.js +3 -2
- package/dist/audit/orchestrator/reviewPacketMetrics.js.map +1 -1
- package/dist/audit/orchestrator/reviewPacketShared.d.ts +0 -2
- package/dist/audit/orchestrator/reviewPacketShared.d.ts.map +1 -1
- package/dist/audit/orchestrator/reviewPacketShared.js +0 -4
- package/dist/audit/orchestrator/reviewPacketShared.js.map +1 -1
- package/dist/audit/orchestrator/reviewPackets.d.ts.map +1 -1
- package/dist/audit/orchestrator/reviewPackets.js +3 -2
- package/dist/audit/orchestrator/reviewPackets.js.map +1 -1
- package/dist/audit/orchestrator/selectiveDeepening/conflict.d.ts.map +1 -1
- package/dist/audit/orchestrator/selectiveDeepening/conflict.js +3 -2
- package/dist/audit/orchestrator/selectiveDeepening/conflict.js.map +1 -1
- package/dist/audit/orchestrator/selectiveDeepening/findingFollowup.d.ts.map +1 -1
- package/dist/audit/orchestrator/selectiveDeepening/findingFollowup.js +3 -2
- package/dist/audit/orchestrator/selectiveDeepening/findingFollowup.js.map +1 -1
- package/dist/audit/orchestrator/selectiveDeepening/highRiskClean.d.ts.map +1 -1
- package/dist/audit/orchestrator/selectiveDeepening/highRiskClean.js +3 -2
- package/dist/audit/orchestrator/selectiveDeepening/highRiskClean.js.map +1 -1
- package/dist/audit/orchestrator/selectiveDeepening/lensVerification.d.ts.map +1 -1
- package/dist/audit/orchestrator/selectiveDeepening/lensVerification.js +4 -3
- package/dist/audit/orchestrator/selectiveDeepening/lensVerification.js.map +1 -1
- package/dist/audit/orchestrator/selectiveDeepening/runtimeValidation.d.ts.map +1 -1
- package/dist/audit/orchestrator/selectiveDeepening/runtimeValidation.js +2 -1
- package/dist/audit/orchestrator/selectiveDeepening/runtimeValidation.js.map +1 -1
- package/dist/audit/orchestrator/selectiveDeepening/shared.d.ts +0 -2
- package/dist/audit/orchestrator/selectiveDeepening/shared.d.ts.map +1 -1
- package/dist/audit/orchestrator/selectiveDeepening/shared.js +0 -27
- package/dist/audit/orchestrator/selectiveDeepening/shared.js.map +1 -1
- package/dist/audit/orchestrator/selectiveDeepening/stewardFollowup.d.ts.map +1 -1
- package/dist/audit/orchestrator/selectiveDeepening/stewardFollowup.js +10 -1
- package/dist/audit/orchestrator/selectiveDeepening/stewardFollowup.js.map +1 -1
- package/dist/audit/orchestrator/state.d.ts.map +1 -1
- package/dist/audit/orchestrator/state.js +21 -14
- package/dist/audit/orchestrator/state.js.map +1 -1
- package/dist/audit/orchestrator/synthesisExecutors.d.ts +8 -0
- package/dist/audit/orchestrator/synthesisExecutors.d.ts.map +1 -1
- package/dist/audit/orchestrator/synthesisExecutors.js +10 -0
- package/dist/audit/orchestrator/synthesisExecutors.js.map +1 -1
- package/dist/audit/reporting/synthesis.d.ts +42 -2
- package/dist/audit/reporting/synthesis.d.ts.map +1 -1
- package/dist/audit/reporting/synthesis.js +264 -12
- package/dist/audit/reporting/synthesis.js.map +1 -1
- package/dist/audit/supervisor/operatorHandoff.d.ts.map +1 -1
- package/dist/audit/supervisor/operatorHandoff.js +14 -6
- package/dist/audit/supervisor/operatorHandoff.js.map +1 -1
- package/dist/audit/systemic/secondOrderAdversaryPrompt.d.ts.map +1 -1
- package/dist/audit/systemic/secondOrderAdversaryPrompt.js +14 -0
- package/dist/audit/systemic/secondOrderAdversaryPrompt.js.map +1 -1
- package/dist/audit/types/analyzerCapability.d.ts +35 -11
- package/dist/audit/types/analyzerCapability.d.ts.map +1 -1
- package/dist/audit/types/analyzerCapability.js +83 -5
- package/dist/audit/types/analyzerCapability.js.map +1 -1
- package/dist/audit/types/auditState.d.ts +8 -8
- package/dist/audit/types/charterRegister.d.ts +33 -3
- package/dist/audit/types/charterRegister.d.ts.map +1 -1
- package/dist/audit/types/charterRegister.js +11 -1
- package/dist/audit/types/charterRegister.js.map +1 -1
- package/dist/audit/types/conceptualAdjudication.d.ts +395 -16
- package/dist/audit/types/conceptualAdjudication.d.ts.map +1 -1
- package/dist/audit/types/conceptualAdjudication.js +109 -5
- package/dist/audit/types/conceptualAdjudication.js.map +1 -1
- package/dist/audit/types/designAssessment.d.ts +1 -1
- package/dist/audit/types/designAssessment.d.ts.map +1 -1
- package/dist/audit/types.d.ts +9 -4
- package/dist/audit/types.d.ts.map +1 -1
- package/dist/remediate/droppedFindingsRecord.d.ts +13 -0
- package/dist/remediate/droppedFindingsRecord.d.ts.map +1 -0
- package/dist/remediate/droppedFindingsRecord.js +113 -0
- package/dist/remediate/droppedFindingsRecord.js.map +1 -0
- package/dist/remediate/intake.d.ts +17 -0
- package/dist/remediate/intake.d.ts.map +1 -1
- package/dist/remediate/intake.js +23 -0
- package/dist/remediate/intake.js.map +1 -1
- package/dist/remediate/intent/intentOrdering.d.ts.map +1 -1
- package/dist/remediate/intent/intentOrdering.js +29 -1
- package/dist/remediate/intent/intentOrdering.js.map +1 -1
- package/dist/remediate/phases/close.d.ts +1 -1
- package/dist/remediate/phases/close.d.ts.map +1 -1
- package/dist/remediate/phases/close.js +68 -6
- package/dist/remediate/phases/close.js.map +1 -1
- package/dist/remediate/phases/grounding.d.ts +12 -4
- package/dist/remediate/phases/grounding.d.ts.map +1 -1
- package/dist/remediate/phases/grounding.js +23 -60
- package/dist/remediate/phases/grounding.js.map +1 -1
- package/dist/remediate/state/types.d.ts +17 -6
- package/dist/remediate/state/types.d.ts.map +1 -1
- package/dist/remediate/state/types.js +3 -1
- package/dist/remediate/state/types.js.map +1 -1
- package/dist/remediate/steps/contractPipeline.d.ts.map +1 -1
- package/dist/remediate/steps/contractPipeline.js +10 -4
- package/dist/remediate/steps/contractPipeline.js.map +1 -1
- package/dist/remediate/steps/contractPipelinePrompts.d.ts +10 -2
- package/dist/remediate/steps/contractPipelinePrompts.d.ts.map +1 -1
- package/dist/remediate/steps/contractPipelinePrompts.js +56 -12
- package/dist/remediate/steps/contractPipelinePrompts.js.map +1 -1
- package/dist/remediate/steps/dispatch/hostHandoff.d.ts.map +1 -1
- package/dist/remediate/steps/dispatch/hostHandoff.js +277 -146
- package/dist/remediate/steps/dispatch/hostHandoff.js.map +1 -1
- package/dist/remediate/steps/nextStep.d.ts.map +1 -1
- package/dist/remediate/steps/nextStep.js +253 -75
- package/dist/remediate/steps/nextStep.js.map +1 -1
- package/dist/remediate/steps/prompts.d.ts +14 -0
- package/dist/remediate/steps/prompts.d.ts.map +1 -1
- package/dist/remediate/steps/prompts.js +52 -4
- package/dist/remediate/steps/prompts.js.map +1 -1
- package/dist/remediate/steps/types.d.ts +1 -1
- package/dist/remediate/steps/types.d.ts.map +1 -1
- package/dist/remediate/steps/types.js.map +1 -1
- package/dist/remediate/validation/contractPipelineGates.d.ts +0 -34
- package/dist/remediate/validation/contractPipelineGates.d.ts.map +1 -1
- package/dist/remediate/validation/contractPipelineGates.js +181 -143
- package/dist/remediate/validation/contractPipelineGates.js.map +1 -1
- package/dist/shared/agentReflections.d.ts +44 -3
- package/dist/shared/agentReflections.d.ts.map +1 -1
- package/dist/shared/agentReflections.js +63 -4
- package/dist/shared/agentReflections.js.map +1 -1
- package/dist/shared/analyzers/acquisitionEngine.d.ts +20 -1
- package/dist/shared/analyzers/acquisitionEngine.d.ts.map +1 -1
- package/dist/shared/analyzers/acquisitionEngine.js +17 -3
- package/dist/shared/analyzers/acquisitionEngine.js.map +1 -1
- package/dist/shared/analyzers/candidates.d.ts.map +1 -1
- package/dist/shared/analyzers/candidates.js +13 -4
- package/dist/shared/analyzers/candidates.js.map +1 -1
- package/dist/shared/analyzers/types.d.ts +17 -6
- package/dist/shared/analyzers/types.d.ts.map +1 -1
- package/dist/shared/analyzers/types.js +6 -15
- package/dist/shared/analyzers/types.js.map +1 -1
- package/dist/shared/decompose/systemicChallenge.d.ts +116 -9
- package/dist/shared/decompose/systemicChallenge.d.ts.map +1 -1
- package/dist/shared/decompose/systemicChallenge.js +32 -1
- package/dist/shared/decompose/systemicChallenge.js.map +1 -1
- package/dist/shared/engine/obligationEngine.d.ts +23 -6
- package/dist/shared/engine/obligationEngine.d.ts.map +1 -1
- package/dist/shared/engine/obligationEngine.js +38 -3
- package/dist/shared/engine/obligationEngine.js.map +1 -1
- package/dist/shared/findings/dedupe.d.ts +10 -0
- package/dist/shared/findings/dedupe.d.ts.map +1 -1
- package/dist/shared/findings/dedupe.js +15 -0
- package/dist/shared/findings/dedupe.js.map +1 -1
- package/dist/shared/friction/triage.d.ts.map +1 -1
- package/dist/shared/friction/triage.js +5 -1
- package/dist/shared/friction/triage.js.map +1 -1
- package/dist/shared/git.d.ts +6 -0
- package/dist/shared/git.d.ts.map +1 -1
- package/dist/shared/git.js +8 -0
- package/dist/shared/git.js.map +1 -1
- package/dist/shared/graph/edgeConfidence.d.ts +12 -0
- package/dist/shared/graph/edgeConfidence.d.ts.map +1 -0
- package/dist/shared/graph/edgeConfidence.js +15 -0
- package/dist/shared/graph/edgeConfidence.js.map +1 -0
- package/dist/shared/index.d.ts +26 -9
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/index.js +20 -8
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/loopCorePaths.d.ts.map +1 -1
- package/dist/shared/loopCorePaths.js +4 -0
- package/dist/shared/loopCorePaths.js.map +1 -1
- package/dist/shared/measurement/measuredOutcome.d.ts +61 -0
- package/dist/shared/measurement/measuredOutcome.d.ts.map +1 -0
- package/dist/shared/measurement/measuredOutcome.js +109 -0
- package/dist/shared/measurement/measuredOutcome.js.map +1 -0
- package/dist/shared/reporting/findingDisplay.d.ts +14 -2
- package/dist/shared/reporting/findingDisplay.d.ts.map +1 -1
- package/dist/shared/reporting/findingDisplay.js +29 -2
- package/dist/shared/reporting/findingDisplay.js.map +1 -1
- package/dist/shared/reporting/lensCoverage.d.ts +70 -0
- package/dist/shared/reporting/lensCoverage.d.ts.map +1 -0
- package/dist/shared/reporting/lensCoverage.js +108 -0
- package/dist/shared/reporting/lensCoverage.js.map +1 -0
- package/dist/shared/submission/hostResultOutcomes.d.ts +42 -0
- package/dist/shared/submission/hostResultOutcomes.d.ts.map +1 -0
- package/dist/shared/submission/hostResultOutcomes.js +129 -0
- package/dist/shared/submission/hostResultOutcomes.js.map +1 -0
- package/dist/shared/submission/ingestionChecks.d.ts +146 -0
- package/dist/shared/submission/ingestionChecks.d.ts.map +1 -0
- package/dist/shared/submission/ingestionChecks.js +157 -0
- package/dist/shared/submission/ingestionChecks.js.map +1 -0
- package/dist/shared/submission/submissionClassifier.d.ts +8 -0
- package/dist/shared/submission/submissionClassifier.d.ts.map +1 -1
- package/dist/shared/submission/submissionClassifier.js.map +1 -1
- package/dist/shared/submission/submissionLedger.d.ts +24 -1
- package/dist/shared/submission/submissionLedger.d.ts.map +1 -1
- package/dist/shared/submission/submissionLedger.js +61 -0
- package/dist/shared/submission/submissionLedger.js.map +1 -1
- package/dist/shared/submission/submissionScan.d.ts +2 -0
- package/dist/shared/submission/submissionScan.d.ts.map +1 -1
- package/dist/shared/submission/submissionScan.js +4 -0
- package/dist/shared/submission/submissionScan.js.map +1 -1
- package/dist/shared/tooling/projectFacts.d.ts +71 -0
- package/dist/shared/tooling/projectFacts.d.ts.map +1 -0
- package/dist/shared/tooling/projectFacts.js +153 -0
- package/dist/shared/tooling/projectFacts.js.map +1 -0
- package/dist/shared/tooling/projectTestAdmission.d.ts +5 -15
- package/dist/shared/tooling/projectTestAdmission.d.ts.map +1 -1
- package/dist/shared/tooling/projectTestAdmission.js +14 -5
- package/dist/shared/tooling/projectTestAdmission.js.map +1 -1
- package/dist/shared/types/charterPacket.d.ts +156 -0
- package/dist/shared/types/charterPacket.d.ts.map +1 -0
- package/dist/shared/types/charterPacket.js +9 -0
- package/dist/shared/types/charterPacket.js.map +1 -0
- package/dist/shared/types/closingActions.d.ts +16 -0
- package/dist/shared/types/closingActions.d.ts.map +1 -0
- package/dist/shared/types/closingActions.js +25 -0
- package/dist/shared/types/closingActions.js.map +1 -0
- package/dist/shared/types/finding.d.ts +275 -40
- package/dist/shared/types/finding.d.ts.map +1 -1
- package/dist/shared/types/finding.js +87 -0
- package/dist/shared/types/finding.js.map +1 -1
- package/dist/shared/types/intentCheckpoint.d.ts +50 -0
- package/dist/shared/types/intentCheckpoint.d.ts.map +1 -1
- package/dist/shared/types/intentCheckpoint.js +31 -0
- package/dist/shared/types/intentCheckpoint.js.map +1 -1
- package/dist/shared/validation/citationGrounding.d.ts +115 -0
- package/dist/shared/validation/citationGrounding.d.ts.map +1 -0
- package/dist/shared/validation/citationGrounding.js +347 -0
- package/dist/shared/validation/citationGrounding.js.map +1 -0
- package/dist/shared/validation/findingsReport.d.ts.map +1 -1
- package/dist/shared/validation/findingsReport.js +62 -0
- package/dist/shared/validation/findingsReport.js.map +1 -1
- package/docs/audit-pkg/contracts.md +34 -12
- package/docs/audit-pkg/operator-guide.md +10 -7
- package/package.json +3 -2
- package/schemas/audit-code-v1alpha1.schema.json +2 -1
- package/skills/audit-code/audit-code.prompt.md +5 -3
- package/dist/remediate/state/closingActions.d.ts +0 -3
- package/dist/remediate/state/closingActions.d.ts.map +0 -1
- package/dist/remediate/state/closingActions.js +0 -10
- package/dist/remediate/state/closingActions.js.map +0 -1
|
@@ -4,11 +4,11 @@ import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
|
4
4
|
import { dirname, join, resolve } from "node:path";
|
|
5
5
|
import { StateStore } from "../state/store.js";
|
|
6
6
|
// IO / validation / rendering helpers
|
|
7
|
-
import { discardOnSchemaVersionMismatch, readOptionalJsonFile, stagedAndUntracked, writeJsonFile, writeTextFile, buildAuditDeliverablePair, formatValidationIssues, isRecord, withFsRetry, RunLogger, coerceJsonObjectArg, headCommit, projectAuditFindingsReportSubset,
|
|
7
|
+
import { discardOnSchemaVersionMismatch, readOptionalJsonFile, stagedAndUntracked, writeJsonFile, writeTextFile, buildAuditDeliverablePair, formatValidationIssues, isRecord, withFsRetry, RunLogger, coerceJsonObjectArg, renderPromptCommand, headCommit, projectAuditFindingsReportSubset,
|
|
8
8
|
// obligation engine + intent
|
|
9
9
|
interpretFreeFormIntent, interpretIntent, unresolvedFromClauses, advance, describeStoppedFold, decideFrictionTriage, buildFrictionTriageBlock, linkFrictionRunIds,
|
|
10
10
|
// domain constants
|
|
11
|
-
LENSES, SEVERITIES, } from "audit-tools/shared";
|
|
11
|
+
LENSES, SEVERITIES, CLOSING_ACTIONS, detectProjectFacts, isClosingAction, neutralProjectFacts, } from "audit-tools/shared";
|
|
12
12
|
import { applyPlanPipeline, buildCoverageLedger } from "../phases/plan.js";
|
|
13
13
|
import { groundExtractedFindings, } from "../phases/grounding.js";
|
|
14
14
|
import { runTriagePhase } from "../phases/triage.js";
|
|
@@ -32,9 +32,10 @@ import { contractArtifactExists, contractPipelineDir, } from "../contractPipelin
|
|
|
32
32
|
import { buildReviewRequest, applyReviewResolution, isResolutionForRequest, screenResolutionIds, REVIEW_REQUEST_SCHEMA_VERSION, } from "../review/reviewGate.js";
|
|
33
33
|
import { buildAutonomousReviewDecision } from "../review/autonomousGate.js";
|
|
34
34
|
import { runFindingFilterPass } from "../findingFilter.js";
|
|
35
|
-
import {
|
|
35
|
+
import { droppedFindingsRecordPath, renderDroppedFindingsRecord, } from "../droppedFindingsRecord.js";
|
|
36
|
+
import { intakePaths, isIntakeReady, manifestIsInputBound, readIntakeArtifacts, readProjectFacts, writeProjectFacts, resolveManifestSources, } from "../intake.js";
|
|
36
37
|
import { ensureIntakeRiskSignal, readIntakeRiskSignal, writeIntakeRiskSignal, escalateRiskSignal, findingRiskEvidence, distinctAffectedFiles, } from "../riskSignal.js";
|
|
37
|
-
import { ambiguityReviewPrompt, clarificationPrompt, collectIntakeClarificationsPrompt, collectStartingPointPrompt, loaderCommand, reviewApprovalPrompt, synthesizeIntakePrompt, triagePrompt, } from "./prompts.js";
|
|
38
|
+
import { ambiguityReviewPrompt, clarificationPrompt, collectIntakeClarificationsPrompt, collectStartingPointPrompt, extractedPlanDiscardedPrompt, loaderCommand, reviewApprovalPrompt, synthesizeIntakePrompt, triagePrompt, } from "./prompts.js";
|
|
38
39
|
// Single-sourced prose renders of the canonical lens / severity vocabularies
|
|
39
40
|
// (`audit-tools/shared` `LENSES` / `SEVERITIES`) for the intent-checkpoint
|
|
40
41
|
// prompt copy. Previously these 11-lens / 5-severity lists were hand-copied as
|
|
@@ -355,7 +356,7 @@ async function applyCheckpointIntentOrdering(artifactsDir, plan) {
|
|
|
355
356
|
const ordered = applyIntentOrdering(plan.findings, plan.blocks, interpretFreeFormIntent(freeForm));
|
|
356
357
|
return { ...plan, findings: ordered.findings, blocks: ordered.blocks };
|
|
357
358
|
}
|
|
358
|
-
function normalizeExtractedPlan(value) {
|
|
359
|
+
function normalizeExtractedPlan(value, facts) {
|
|
359
360
|
if (!isRecord(value)) {
|
|
360
361
|
throw new Error("extracted-plan.json must be an object.");
|
|
361
362
|
}
|
|
@@ -399,10 +400,28 @@ function normalizeExtractedPlan(value) {
|
|
|
399
400
|
...(typeof value.source === "string" ? { source: value.source } : {}),
|
|
400
401
|
findings: dedup.findings,
|
|
401
402
|
blocks: dedupBlocks,
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
403
|
+
// Project facts (owner decision 92b0e2dd7cfdc06d): the input's own VALID
|
|
404
|
+
// values win — the contract pipeline detects them itself — and the run's
|
|
405
|
+
// detected facts fill the rest. Candidates are what the host chooses
|
|
406
|
+
// FROM at the intent checkpoint; nothing here selects one.
|
|
407
|
+
project_type: typeof value.project_type === "string" && value.project_type !== "unknown"
|
|
408
|
+
? value.project_type
|
|
409
|
+
: facts.project_type,
|
|
410
|
+
...(typeof value.test_command === "string" && value.test_command.trim().length > 0
|
|
411
|
+
? { test_command: value.test_command, test_command_source: "explicit" }
|
|
412
|
+
: facts.commands.test
|
|
413
|
+
? { test_command: renderPromptCommand(facts.commands.test), test_command_source: "project_facts" }
|
|
414
|
+
: {}),
|
|
415
|
+
...(typeof value.e2e_command === "string" && value.e2e_command.trim().length > 0
|
|
416
|
+
? { e2e_command: value.e2e_command, e2e_command_source: "explicit" }
|
|
417
|
+
: facts.commands.e2e
|
|
418
|
+
? { e2e_command: renderPromptCommand(facts.commands.e2e), e2e_command_source: "project_facts" }
|
|
419
|
+
: {}),
|
|
420
|
+
candidate_closing_actions: Array.isArray(value.candidate_closing_actions) &&
|
|
421
|
+
value.candidate_closing_actions.length > 0 &&
|
|
422
|
+
value.candidate_closing_actions.every(isClosingAction)
|
|
423
|
+
? value.candidate_closing_actions
|
|
424
|
+
: facts.candidate_closing_actions,
|
|
406
425
|
block_strategy: value.block_strategy === "test_graph" ||
|
|
407
426
|
value.block_strategy === "git_cocommit" ||
|
|
408
427
|
value.block_strategy === "file_overlap" ||
|
|
@@ -419,6 +438,33 @@ function normalizeExtractedPlan(value) {
|
|
|
419
438
|
}
|
|
420
439
|
return { plan, sourceFindings: findings, mergeMap: dedup.mergeMap };
|
|
421
440
|
}
|
|
441
|
+
/**
|
|
442
|
+
* The closing plan the HOST chose on the confirmed checkpoint: its action, or
|
|
443
|
+
* `none` when the field is absent, plus the argv a `custom` choice carries.
|
|
444
|
+
* Never a detected candidate: detection presents, the host chooses (owner
|
|
445
|
+
* decision 92b0e2dd7cfdc06d). An invalid action, or a `custom` with no
|
|
446
|
+
* command, cannot reach here — the confirm_intent obligation refuses both —
|
|
447
|
+
* so membership is the whole check.
|
|
448
|
+
*/
|
|
449
|
+
async function confirmedClosingPlan(artifactsDir) {
|
|
450
|
+
const checkpoint = await readOptionalJsonFile(join(artifactsDir, "intent_checkpoint.json"));
|
|
451
|
+
if (!checkpoint || checkpoint.confirmed_by !== "host")
|
|
452
|
+
return { action: "none" };
|
|
453
|
+
const chosen = checkpoint.closing_action;
|
|
454
|
+
if (!isClosingAction(chosen))
|
|
455
|
+
return { action: "none" };
|
|
456
|
+
const command = customCommandOf(checkpoint);
|
|
457
|
+
return chosen === "custom" && command ? { action: chosen, custom_command: command } : { action: chosen };
|
|
458
|
+
}
|
|
459
|
+
/** The checkpoint's `closing_custom_command` when it is a non-empty argv of non-empty strings. */
|
|
460
|
+
function customCommandOf(checkpoint) {
|
|
461
|
+
const raw = checkpoint.closing_custom_command;
|
|
462
|
+
return Array.isArray(raw) &&
|
|
463
|
+
raw.length > 0 &&
|
|
464
|
+
raw.every((part) => typeof part === "string" && part.length > 0)
|
|
465
|
+
? raw
|
|
466
|
+
: null;
|
|
467
|
+
}
|
|
422
468
|
async function saveStateForPlan(artifactsDir, existing, plan, planCoverage) {
|
|
423
469
|
const { host_handoff: _staleHostHandoff, ...carryForwardState } = existing;
|
|
424
470
|
const items = {};
|
|
@@ -435,7 +481,7 @@ async function saveStateForPlan(artifactsDir, existing, plan, planCoverage) {
|
|
|
435
481
|
status: "planning",
|
|
436
482
|
plan,
|
|
437
483
|
items,
|
|
438
|
-
closing_plan:
|
|
484
|
+
closing_plan: await confirmedClosingPlan(artifactsDir),
|
|
439
485
|
...(planCoverage ? { plan_coverage: planCoverage } : {}),
|
|
440
486
|
};
|
|
441
487
|
await new StateStore(artifactsDir).saveState(state);
|
|
@@ -559,7 +605,13 @@ async function forceReplanFromExistingIntake(root, artifactsDir, previous, store
|
|
|
559
605
|
await store.saveState(pendingState);
|
|
560
606
|
return null;
|
|
561
607
|
}
|
|
562
|
-
const
|
|
608
|
+
const outcome = await handlePendingExtractedPlan(root, artifactsDir, pendingState, extractedPlan, runLogger);
|
|
609
|
+
if (outcome.kind === "discarded") {
|
|
610
|
+
// Carried up rather than collapsed to null: the decide loop emits the step
|
|
611
|
+
// that names the discard.
|
|
612
|
+
return outcome;
|
|
613
|
+
}
|
|
614
|
+
const replanned = outcome.state;
|
|
563
615
|
if (!replanned) {
|
|
564
616
|
return null;
|
|
565
617
|
}
|
|
@@ -737,6 +789,31 @@ async function buildImplementDispatchStep(ctx) {
|
|
|
737
789
|
if (ingested === "unsupported_retired_state") {
|
|
738
790
|
throw new Error("Remediation state uses a retired dispatch shape and cannot cross the host handoff boundary.");
|
|
739
791
|
}
|
|
792
|
+
// DURABLY RECORD EVERY CLASSIFIED ISSUE BEFORE ANY EXIT PATH.
|
|
793
|
+
//
|
|
794
|
+
// This loop used to sit below the `state_changed` early return, next to the
|
|
795
|
+
// prompt that renders the same issues — so it only ran when NOTHING was
|
|
796
|
+
// accepted. On a partial batch (some results accepted, some rejected)
|
|
797
|
+
// `state_changed` is true, the call transitions here, and every rejection was
|
|
798
|
+
// lost: not logged, not rendered, not carried. The one path where a host most
|
|
799
|
+
// needs to know that some of its work was refused was the path that said
|
|
800
|
+
// nothing at all.
|
|
801
|
+
//
|
|
802
|
+
// The rendering half is separate and still only reached on the re-emit path;
|
|
803
|
+
// this is the DURABLE half, and it must not depend on which exit is taken. The
|
|
804
|
+
// ledger already records the rejection, but the run log is what a person reads
|
|
805
|
+
// when reconstructing a run.
|
|
806
|
+
for (const issue of ingested.issues) {
|
|
807
|
+
runLogger.event({
|
|
808
|
+
phase: "next-step",
|
|
809
|
+
kind: "outcome",
|
|
810
|
+
obligation: "host_ingest",
|
|
811
|
+
note: `host_ingest_issue code=${issue.code}` +
|
|
812
|
+
(issue.work_item_id ? ` work_item=${issue.work_item_id}` : "") +
|
|
813
|
+
(issue.result_path ? ` result=${issue.result_path}` : "") +
|
|
814
|
+
` message=${issue.message}`,
|
|
815
|
+
});
|
|
816
|
+
}
|
|
740
817
|
if (ingested.state_changed) {
|
|
741
818
|
const { contract_version: _contractVersion, ...persistableState } = ingested.state;
|
|
742
819
|
await store.saveState(persistableState);
|
|
@@ -768,21 +845,9 @@ async function buildImplementDispatchStep(ctx) {
|
|
|
768
845
|
// persisted handoff record for the dispatch run, the step contract's own run id for
|
|
769
846
|
// the step — never synthesized from the other.
|
|
770
847
|
await linkFrictionRunIds(artifactsDir, stateRunId(state), { step_run_id: runId, dispatch_run_id: handoff.handoff_record.run_id }, "remediate-code");
|
|
771
|
-
//
|
|
772
|
-
// exactly as long as the host reads
|
|
773
|
-
//
|
|
774
|
-
// as well as rendered.
|
|
775
|
-
for (const issue of ingested.issues) {
|
|
776
|
-
runLogger.event({
|
|
777
|
-
phase: "next-step",
|
|
778
|
-
kind: "outcome",
|
|
779
|
-
obligation: "host_ingest",
|
|
780
|
-
note: `host_ingest_issue code=${issue.code}` +
|
|
781
|
-
(issue.work_item_id ? ` work_item=${issue.work_item_id}` : "") +
|
|
782
|
-
(issue.result_path ? ` result=${issue.result_path}` : "") +
|
|
783
|
-
` message=${issue.message}`,
|
|
784
|
-
});
|
|
785
|
-
}
|
|
848
|
+
// The issues were logged above, before any exit path. What follows is the
|
|
849
|
+
// RENDER — a channel that survives exactly as long as the host reads this one
|
|
850
|
+
// step, and that is reached only when nothing was accepted.
|
|
786
851
|
const resultDiagnostics = ingested.issues.length === 0
|
|
787
852
|
? ""
|
|
788
853
|
: `
|
|
@@ -913,6 +978,21 @@ async function archiveExtractedPlan(extractedPlanPath) {
|
|
|
913
978
|
}
|
|
914
979
|
return archivePath;
|
|
915
980
|
}
|
|
981
|
+
/** Render the step that STATES a discard, rather than asking for an input again. */
|
|
982
|
+
async function emitExtractedPlanDiscardedStep(root, artifactsDir, discard) {
|
|
983
|
+
const paths = intakePaths(artifactsDir);
|
|
984
|
+
return writeCurrentStep({
|
|
985
|
+
stepKind: "extracted_plan_discarded",
|
|
986
|
+
status: "blocked",
|
|
987
|
+
runId: randomRunId("PLAN-DISCARD"),
|
|
988
|
+
repoRoot: root,
|
|
989
|
+
artifactsDir,
|
|
990
|
+
prompt: extractedPlanDiscardedPrompt(discard.reason, discard.archivePath, paths),
|
|
991
|
+
allowedCommands: [loaderCommand("next-step")],
|
|
992
|
+
stopCondition: "Stop after writing a corrected extracted plan and rerunning next-step.",
|
|
993
|
+
artifactPaths: { extracted_plan: paths.extractedPlan },
|
|
994
|
+
});
|
|
995
|
+
}
|
|
916
996
|
async function handlePendingExtractedPlan(root, artifactsDir, existing, extractedPlan,
|
|
917
997
|
// The plan path's high-consequence events — findings dropped by grounding, and
|
|
918
998
|
// the plan being destroyed — are DURABLE, so the logger is a parameter rather
|
|
@@ -938,7 +1018,10 @@ runLogger) {
|
|
|
938
1018
|
let mergeMap;
|
|
939
1019
|
let grounding;
|
|
940
1020
|
try {
|
|
941
|
-
({ plan, sourceFindings, mergeMap } = normalizeExtractedPlan(extractedPlan
|
|
1021
|
+
({ plan, sourceFindings, mergeMap } = normalizeExtractedPlan(extractedPlan,
|
|
1022
|
+
// Persisted by the confirm step; planning spawns nothing (the
|
|
1023
|
+
// backend-independent planning contract), so it never detects here.
|
|
1024
|
+
(await readProjectFacts(artifactsDir)) ?? neutralProjectFacts()));
|
|
942
1025
|
// INTENT ORDERING, applied where the plan's findings and blocks are
|
|
943
1026
|
// FINALIZED. `applyIntentOrdering` existed with no production caller at all:
|
|
944
1027
|
// the checkpoint's interpreted intent was written and never read back, so
|
|
@@ -1024,8 +1107,18 @@ runLogger) {
|
|
|
1024
1107
|
note: `extracted_plan_removed reason=${reason} ` +
|
|
1025
1108
|
`archive=${archivePath ?? "(nothing on disk to archive)"}`,
|
|
1026
1109
|
});
|
|
1027
|
-
process.stderr.write(`[remediate-code] Unusable extracted-plan.json removed (${reason}); archived at ${archivePath ?? "(nothing on disk to archive)"}.
|
|
1028
|
-
|
|
1110
|
+
process.stderr.write(`[remediate-code] Unusable extracted-plan.json removed (${reason}); archived at ${archivePath ?? "(nothing on disk to archive)"}. Emitting the plan-discarded step.\n`);
|
|
1111
|
+
// The reason travels with the outcome, so the EMITTED STEP can state it.
|
|
1112
|
+
// Returning a bare `null` here is what made a destroyed plan indistinguishable
|
|
1113
|
+
// from a run that never had an input: the decide loop fell through to
|
|
1114
|
+
// `collect_starting_point` and the host was told to go and find an input it
|
|
1115
|
+
// had already supplied. Everything needed to say so was already computed —
|
|
1116
|
+
// it just had nowhere to go.
|
|
1117
|
+
return {
|
|
1118
|
+
kind: "discarded",
|
|
1119
|
+
reason,
|
|
1120
|
+
...(archivePath ? { archivePath } : {}),
|
|
1121
|
+
};
|
|
1029
1122
|
}
|
|
1030
1123
|
// Past the recovery boundary: a failure below is a real failure and propagates.
|
|
1031
1124
|
const pipelined = await applyPlanPipeline(plan, { root, artifactsDir });
|
|
@@ -1084,7 +1177,10 @@ runLogger) {
|
|
|
1084
1177
|
},
|
|
1085
1178
|
])),
|
|
1086
1179
|
});
|
|
1087
|
-
return
|
|
1180
|
+
return {
|
|
1181
|
+
kind: "planned",
|
|
1182
|
+
state: await saveStateForPlan(artifactsDir, existing, pipelined, coverage),
|
|
1183
|
+
};
|
|
1088
1184
|
}
|
|
1089
1185
|
// ── Review-approval gate (go-forward program item 1) ───────────────────────────
|
|
1090
1186
|
//
|
|
@@ -1109,6 +1205,42 @@ function reviewResolutionPath(artifactsDir) {
|
|
|
1109
1205
|
function reviewDecisionPath(artifactsDir) {
|
|
1110
1206
|
return join(artifactsDir, "review_decision.json");
|
|
1111
1207
|
}
|
|
1208
|
+
/**
|
|
1209
|
+
* Stamp and persist one review decision. Three sites built this literal — the
|
|
1210
|
+
* autonomous and interactive arms of the approval gate, and the planning gate —
|
|
1211
|
+
* and a schema stamp that lives in three places is one edit away from meaning
|
|
1212
|
+
* two different things on disk.
|
|
1213
|
+
*
|
|
1214
|
+
* Persistence only. WHICH ids are approved, where the plan id comes from, and
|
|
1215
|
+
* what the caller does next are all decided by the caller and stay there: the
|
|
1216
|
+
* autonomous arm mints a run id and declines nothing, the two resolution arms
|
|
1217
|
+
* carry the live plan's id and the operator's declines.
|
|
1218
|
+
*/
|
|
1219
|
+
async function writeReviewDecisionRecord(decisionPath, fields) {
|
|
1220
|
+
const record = {
|
|
1221
|
+
schema_version: REVIEW_DECISION_SCHEMA_VERSION,
|
|
1222
|
+
plan_id: fields.planId,
|
|
1223
|
+
approved_ids: fields.approvedIds,
|
|
1224
|
+
declined: fields.declined,
|
|
1225
|
+
created_at: new Date().toISOString(),
|
|
1226
|
+
};
|
|
1227
|
+
await writeJsonFile(decisionPath, record);
|
|
1228
|
+
}
|
|
1229
|
+
/**
|
|
1230
|
+
* Archive the inputs a gate has just consumed, so it cannot re-halt on them.
|
|
1231
|
+
*
|
|
1232
|
+
* Renaming rather than deleting keeps the operator's own answer recoverable;
|
|
1233
|
+
* the timestamp suffix keeps a second consumption from colliding with the
|
|
1234
|
+
* first. An absent path is not an error — a gate reached through the autonomous
|
|
1235
|
+
* arm never wrote one.
|
|
1236
|
+
*/
|
|
1237
|
+
async function archiveConsumedInputs(paths) {
|
|
1238
|
+
for (const p of paths) {
|
|
1239
|
+
if (existsSync(p)) {
|
|
1240
|
+
await withFsRetry(() => rename(p, `${p}.consumed-${Date.now()}`));
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1112
1244
|
// Up-front ambiguity gate (note 3, part A) — its own request/resolution/decision
|
|
1113
1245
|
// files, mirroring the review gate so it fires (and halts) at most once per run.
|
|
1114
1246
|
function ambiguityRequestPath(artifactsDir) {
|
|
@@ -1197,14 +1329,11 @@ async function runReviewApprovalGate(root, artifactsDir, survivors, autonomous =
|
|
|
1197
1329
|
// Leftovers stay LIVE: declined is EMPTY (no durable rejection). The
|
|
1198
1330
|
// decision REPLAY keys on approved_ids (COR-227a02ae), so on later calls
|
|
1199
1331
|
// exactly the approved subset — never the live leftovers — re-enters.
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
approved_ids: auto.approved_ids,
|
|
1332
|
+
await writeReviewDecisionRecord(decisionPath, {
|
|
1333
|
+
planId: randomRunId("path-a-review"),
|
|
1334
|
+
approvedIds: auto.approved_ids,
|
|
1204
1335
|
declined: [],
|
|
1205
|
-
|
|
1206
|
-
};
|
|
1207
|
-
await writeJsonFile(decisionPath, record);
|
|
1336
|
+
});
|
|
1208
1337
|
// Re-emit the leftovers as a standard, re-consumable audit deliverable pair
|
|
1209
1338
|
// so the next nightly run picks them up via defaultInputCandidates. Always
|
|
1210
1339
|
// on disk regardless of whether a git remote / PR is available.
|
|
@@ -1248,20 +1377,12 @@ async function runReviewApprovalGate(root, artifactsDir, survivors, autonomous =
|
|
|
1248
1377
|
if (refusalStep)
|
|
1249
1378
|
return { kind: "halt", step: refusalStep };
|
|
1250
1379
|
const decision = applyReviewResolution(request, resolution);
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
approved_ids: decision.approved_ids,
|
|
1380
|
+
await writeReviewDecisionRecord(decisionPath, {
|
|
1381
|
+
planId: request.plan_id,
|
|
1382
|
+
approvedIds: decision.approved_ids,
|
|
1255
1383
|
declined: decision.declined,
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
await writeJsonFile(decisionPath, record);
|
|
1259
|
-
// Archive the consumed inputs so the gate cannot re-halt.
|
|
1260
|
-
for (const p of [resolutionPath, requestPath]) {
|
|
1261
|
-
if (existsSync(p)) {
|
|
1262
|
-
await withFsRetry(() => rename(p, `${p}.consumed-${Date.now()}`));
|
|
1263
|
-
}
|
|
1264
|
-
}
|
|
1384
|
+
});
|
|
1385
|
+
await archiveConsumedInputs([resolutionPath, requestPath]);
|
|
1265
1386
|
}
|
|
1266
1387
|
// Decision recorded (now or on a prior call): split the survivors. The
|
|
1267
1388
|
// replay honours the recorded approved_ids (COR-227a02ae) — an autonomous
|
|
@@ -1349,6 +1470,11 @@ async function persistReviewFilterDispositions(artifactsDir, originals, filter)
|
|
|
1349
1470
|
droppedByCheckpoint: filter.droppedByCheckpoint,
|
|
1350
1471
|
};
|
|
1351
1472
|
await writeJsonFile(reviewFilterDispositionsPath(artifactsDir), payload);
|
|
1473
|
+
// The human half of the same fact. The JSON above keeps only IDS, which told a
|
|
1474
|
+
// reader an id and nothing else; this states what each removed finding WAS and
|
|
1475
|
+
// why it went. Written beside it, on every pass, so its absence means the pass
|
|
1476
|
+
// did not run rather than "nothing was dropped".
|
|
1477
|
+
await writeFile(droppedFindingsRecordPath(artifactsDir), renderDroppedFindingsRecord(originals, filter), "utf8");
|
|
1352
1478
|
}
|
|
1353
1479
|
async function handleReadyIntakeContractPipeline(root, artifactsDir, options, runLogger) {
|
|
1354
1480
|
// Fast path: if an extracted-plan.json already exists (pipeline complete or
|
|
@@ -1357,7 +1483,10 @@ async function handleReadyIntakeContractPipeline(root, artifactsDir, options, ru
|
|
|
1357
1483
|
// ground+plan" and the grounding tests that write extracted-plan.json directly.
|
|
1358
1484
|
const earlyExtractedPlan = await readExtractedPlanIfPresent(artifactsDir);
|
|
1359
1485
|
if (earlyExtractedPlan) {
|
|
1360
|
-
|
|
1486
|
+
const outcome = await handlePendingExtractedPlan(root, artifactsDir, { status: "pending" }, earlyExtractedPlan, runLogger);
|
|
1487
|
+
return outcome.kind === "discarded"
|
|
1488
|
+
? emitExtractedPlanDiscardedStep(root, artifactsDir, outcome)
|
|
1489
|
+
: outcome.state;
|
|
1361
1490
|
}
|
|
1362
1491
|
const intake = await readIntakeArtifacts(artifactsDir);
|
|
1363
1492
|
if (!intake.summary || !isIntakeReady(intake.summary)) {
|
|
@@ -1501,7 +1630,10 @@ async function handleReadyIntakeContractPipeline(root, artifactsDir, options, ru
|
|
|
1501
1630
|
if (!extractedPlan) {
|
|
1502
1631
|
return null;
|
|
1503
1632
|
}
|
|
1504
|
-
|
|
1633
|
+
const outcome = await handlePendingExtractedPlan(root, artifactsDir, { status: "pending" }, extractedPlan, runLogger);
|
|
1634
|
+
return outcome.kind === "discarded"
|
|
1635
|
+
? emitExtractedPlanDiscardedStep(root, artifactsDir, outcome)
|
|
1636
|
+
: outcome.state;
|
|
1505
1637
|
}
|
|
1506
1638
|
async function handlePendingIntake(root, artifactsDir, options, runLogger) {
|
|
1507
1639
|
// Short-circuit: if an extracted-plan.json already exists (promoted from the
|
|
@@ -1881,20 +2013,12 @@ async function runPlanningReviewGate(root, artifactsDir, state, store) {
|
|
|
1881
2013
|
if (refusalStep)
|
|
1882
2014
|
return refusalStep;
|
|
1883
2015
|
const decision = applyReviewResolution(request, resolution);
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
approved_ids: decision.approved_ids,
|
|
2016
|
+
await writeReviewDecisionRecord(decisionPath, {
|
|
2017
|
+
planId: request.plan_id,
|
|
2018
|
+
approvedIds: decision.approved_ids,
|
|
1888
2019
|
declined: decision.declined,
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
await writeJsonFile(decisionPath, record);
|
|
1892
|
-
// Archive the consumed inputs so the gate cannot re-halt.
|
|
1893
|
-
for (const p of [resolutionPath, requestPath]) {
|
|
1894
|
-
if (existsSync(p)) {
|
|
1895
|
-
await withFsRetry(() => rename(p, `${p}.consumed-${Date.now()}`));
|
|
1896
|
-
}
|
|
1897
|
-
}
|
|
2020
|
+
});
|
|
2021
|
+
await archiveConsumedInputs([resolutionPath, requestPath]);
|
|
1898
2022
|
// Declined nodes → recorded terminal disposition (never a silent close).
|
|
1899
2023
|
let changed = false;
|
|
1900
2024
|
for (const { finding_id, reason } of decision.declined) {
|
|
@@ -2695,6 +2819,27 @@ async function buildConfirmResumeOrRestartStep(ctx) {
|
|
|
2695
2819
|
},
|
|
2696
2820
|
});
|
|
2697
2821
|
}
|
|
2822
|
+
/**
|
|
2823
|
+
* The closing-action choice, rendered from DETECTED facts. Lists only the
|
|
2824
|
+
* candidates the repository's shape makes appropriate, each with the fact
|
|
2825
|
+
* behind it, and says outright that the tool selects nothing: an omitted
|
|
2826
|
+
* `closing_action` is `none`.
|
|
2827
|
+
*/
|
|
2828
|
+
function renderClosingActionSection(facts) {
|
|
2829
|
+
const candidateLines = facts.candidate_closing_actions
|
|
2830
|
+
.map((action) => `- \`${action}\` — ${facts.candidate_rationale[action] ?? ""}`)
|
|
2831
|
+
.join("\n");
|
|
2832
|
+
const vocabulary = CLOSING_ACTIONS.map((action) => `\`${action}\``).join(", ");
|
|
2833
|
+
return [
|
|
2834
|
+
"## Closing Action — you choose",
|
|
2835
|
+
"",
|
|
2836
|
+
`Detected project type: \`${facts.project_type}\`. The repository's shape makes these closing actions appropriate. The tool never selects one: set \`closing_action\` in the checkpoint, or omit it to choose \`none\`.`,
|
|
2837
|
+
"",
|
|
2838
|
+
candidateLines,
|
|
2839
|
+
"",
|
|
2840
|
+
`Any other value from ${vocabulary} is accepted as an explicit alternative. \`custom\` runs the argv you write beside it as \`closing_custom_command\` (for example ["npm", "run", "release"]); a \`custom\` without one is refused.`,
|
|
2841
|
+
].join("\n");
|
|
2842
|
+
}
|
|
2698
2843
|
async function buildConfirmIntentStep(ctx) {
|
|
2699
2844
|
const { root, artifactsDir, state } = ctx;
|
|
2700
2845
|
const runId = stateRunId(state);
|
|
@@ -2703,6 +2848,21 @@ async function buildConfirmIntentStep(ctx) {
|
|
|
2703
2848
|
// Read the pre-drafted checkpoint if one exists (confirmed_by: "draft").
|
|
2704
2849
|
const draft = await readOptionalJsonFile(checkpointPath);
|
|
2705
2850
|
const isDraft = draft?.confirmed_by === "draft";
|
|
2851
|
+
// Closing action: DETECTED candidates, presented for the host to choose
|
|
2852
|
+
// from; the tool never selects one (owner decision 92b0e2dd7cfdc06d).
|
|
2853
|
+
const facts = await detectProjectFacts(root);
|
|
2854
|
+
// Persisted for planning, which spawns nothing by contract and reads this
|
|
2855
|
+
// artifact instead of detecting again.
|
|
2856
|
+
await writeProjectFacts(artifactsDir, facts);
|
|
2857
|
+
const closingSection = renderClosingActionSection(facts);
|
|
2858
|
+
// A confirmed checkpoint whose closing_action is not in the vocabulary
|
|
2859
|
+
// re-enters this step by name — a refusal, never a silent default.
|
|
2860
|
+
const rawChoice = draft?.confirmed_by === "host" ? draft.closing_action : undefined;
|
|
2861
|
+
const refusal = rawChoice !== undefined && !isClosingAction(rawChoice)
|
|
2862
|
+
? `> **Refused:** \`closing_action\` ${JSON.stringify(rawChoice)} is not one of ${CLOSING_ACTIONS.map((a) => `\`${a}\``).join(", ")}. Rewrite the checkpoint with a valid value, or omit the field for \`none\`.\n`
|
|
2863
|
+
: rawChoice === "custom" && customCommandOf(draft) === null
|
|
2864
|
+
? "> **Refused:** `closing_action` \"custom\" needs `closing_custom_command`, a non-empty argv array such as [\"npm\", \"run\", \"release\"]. Add it, or choose another action.\n"
|
|
2865
|
+
: "";
|
|
2706
2866
|
let prompt;
|
|
2707
2867
|
if (isDraft && draft) {
|
|
2708
2868
|
// Build a consolidated single-stop proposal from the draft.
|
|
@@ -2714,7 +2874,6 @@ async function buildConfirmIntentStep(ctx) {
|
|
|
2714
2874
|
const blockingQs = preDraftQuestions.filter((q) => q.blocking === true);
|
|
2715
2875
|
const nonBlockingQs = preDraftQuestions.filter((q) => q.blocking !== true);
|
|
2716
2876
|
const intentInterpretation = typeof draftRaw.intent_interpretation === "string" ? draftRaw.intent_interpretation : undefined;
|
|
2717
|
-
const suggestedClosingAction = typeof draftRaw.closing_action === "string" ? draftRaw.closing_action : undefined;
|
|
2718
2877
|
const questionLines = [
|
|
2719
2878
|
...blockingQs.map((q) => `- **[blocking] ${q.id}**: ${q.question}`),
|
|
2720
2879
|
...nonBlockingQs.map((q) => `- **[FYI] ${q.id}**: ${q.question}`),
|
|
@@ -2722,9 +2881,8 @@ async function buildConfirmIntentStep(ctx) {
|
|
|
2722
2881
|
const filtersBlock = draft.filters && Object.keys(draft.filters).length > 0
|
|
2723
2882
|
? `\`\`\`json\n${JSON.stringify(draft.filters, null, 2)}\n\`\`\``
|
|
2724
2883
|
: "(none — remediating all findings)";
|
|
2725
|
-
const closingOptions = "`commit` or `none`";
|
|
2726
2884
|
prompt = `
|
|
2727
|
-
# Confirm Remediation Scope and Intent
|
|
2885
|
+
${refusal}# Confirm Remediation Scope and Intent
|
|
2728
2886
|
|
|
2729
2887
|
The intake worker has pre-populated the following proposal. Review each section
|
|
2730
2888
|
and adjust where needed, then confirm by writing the final \`intent_checkpoint.json\`.
|
|
@@ -2745,9 +2903,7 @@ ${filtersBlock}
|
|
|
2745
2903
|
|
|
2746
2904
|
${questionLines}
|
|
2747
2905
|
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
${suggestedClosingAction ?? "commit"} (valid options: ${closingOptions})
|
|
2906
|
+
${closingSection}
|
|
2751
2907
|
|
|
2752
2908
|
---
|
|
2753
2909
|
|
|
@@ -2765,7 +2921,9 @@ To confirm, write the final checkpoint to:
|
|
|
2765
2921
|
"free_form_intent": "<optional: additional guidance>",
|
|
2766
2922
|
"filters": ${JSON.stringify(draft.filters ?? {}, null, 2)},
|
|
2767
2923
|
"excluded_scope": [{ "path": "<path or prefix>", "reason": "<why>" }],
|
|
2768
|
-
"must_not_touch": []
|
|
2924
|
+
"must_not_touch": [],
|
|
2925
|
+
"closing_action": "<one of the candidates above, or omit the field for none>",
|
|
2926
|
+
"closing_custom_command": ["<only with custom: the argv to run>"]
|
|
2769
2927
|
}
|
|
2770
2928
|
\`\`\`
|
|
2771
2929
|
|
|
@@ -2781,7 +2939,7 @@ Once written with \`"confirmed_by": "host"\`, run:
|
|
|
2781
2939
|
else {
|
|
2782
2940
|
// Fallback for when there is no pre-drafted checkpoint.
|
|
2783
2941
|
prompt = `
|
|
2784
|
-
# Confirm Remediation Scope and Intent
|
|
2942
|
+
${refusal}# Confirm Remediation Scope and Intent
|
|
2785
2943
|
|
|
2786
2944
|
Please review the intake summary at \`.audit-tools/remediation/intake/intake-summary.json\` (and the audit report, if this run consumes one).
|
|
2787
2945
|
|
|
@@ -2804,10 +2962,14 @@ Only \`scope_summary\` and \`intent_summary\` are required; add the optional fie
|
|
|
2804
2962
|
"themes": ["<theme id>"]
|
|
2805
2963
|
},
|
|
2806
2964
|
"excluded_scope": [{ "path": "<path or prefix>", "reason": "<why>" }],
|
|
2807
|
-
"must_not_touch": ["<glob>"]
|
|
2965
|
+
"must_not_touch": ["<glob>"],
|
|
2966
|
+
"closing_action": "<one of the candidates below, or omit the field for none>",
|
|
2967
|
+
"closing_custom_command": ["<only with custom: the argv to run>"]
|
|
2808
2968
|
}
|
|
2809
2969
|
\`\`\`
|
|
2810
2970
|
|
|
2971
|
+
${closingSection}
|
|
2972
|
+
|
|
2811
2973
|
- \`filters\` drop findings that don't match BEFORE planning, so only the work you want is remediated. Valid severities: ${VALID_SEVERITIES_PROSE}. Valid lenses: ${VALID_LENSES_PROSE}. Draw \`packages\`/\`themes\` from the findings in the audit report.
|
|
2812
2974
|
- \`excluded_scope\` drops findings whose files match a path or directory prefix; \`must_not_touch\` globs are never written.
|
|
2813
2975
|
- Skipped findings are listed in the final remediation report under "Skipped by Intent Checkpoint".
|
|
@@ -3065,11 +3227,20 @@ export function buildPreIntakeObligations(ctx, snapshot) {
|
|
|
3065
3227
|
id: "confirm_intent",
|
|
3066
3228
|
derive: (state) => {
|
|
3067
3229
|
const checkpointIsDraft = existingCheckpoint?.confirmed_by === "draft";
|
|
3230
|
+
// A host-confirmed checkpoint carrying a closing_action outside the
|
|
3231
|
+
// vocabulary is not a confirmation: the step re-emits naming the value
|
|
3232
|
+
// (owner decision 92b0e2dd7cfdc06d — never a silent default).
|
|
3233
|
+
const chosenClosingAction = existingCheckpoint?.confirmed_by === "host"
|
|
3234
|
+
? existingCheckpoint.closing_action
|
|
3235
|
+
: undefined;
|
|
3236
|
+
const invalidClosingAction = (chosenClosingAction !== undefined && !isClosingAction(chosenClosingAction)) ||
|
|
3237
|
+
(chosenClosingAction === "custom" && customCommandOf(existingCheckpoint) === null);
|
|
3068
3238
|
const activeRunState = state != null &&
|
|
3069
3239
|
state.status !== "pending" &&
|
|
3070
3240
|
state.status !== "complete" &&
|
|
3071
3241
|
state.status !== "closing";
|
|
3072
3242
|
const fires = checkpointIsDraft ||
|
|
3243
|
+
invalidClosingAction ||
|
|
3073
3244
|
(!existsSync(checkpointPath) &&
|
|
3074
3245
|
(existsSync(ip.summary) ||
|
|
3075
3246
|
existsSync(ip.extractedPlan) ||
|
|
@@ -3493,7 +3664,14 @@ async function advanceUnderPhaseLock(deps) {
|
|
|
3493
3664
|
// transitions, never a recursive decideNextStepLoop), so this fires at most once.
|
|
3494
3665
|
if (options.forceReplan && state != null) {
|
|
3495
3666
|
await countStep(state);
|
|
3496
|
-
|
|
3667
|
+
const replanOutcome = await forceReplanFromExistingIntake(root, artifactsDir, state, store, runLogger);
|
|
3668
|
+
// A discarded plan is REPORTED here, not collapsed into `state = null`. Once
|
|
3669
|
+
// it is null the loop can no longer tell "the plan was destroyed, and here is
|
|
3670
|
+
// why" from "there was never an input", and it emits the second.
|
|
3671
|
+
if (replanOutcome !== null && "kind" in replanOutcome) {
|
|
3672
|
+
return emitExtractedPlanDiscardedStep(root, artifactsDir, replanOutcome);
|
|
3673
|
+
}
|
|
3674
|
+
state = replanOutcome;
|
|
3497
3675
|
}
|
|
3498
3676
|
// Pre-read the once-async signals the pre-intake derive()s consume
|
|
3499
3677
|
// synchronously (no transition inside this advance call rewrites either file).
|