audit-tools 0.51.7 → 0.51.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/audit/clarification/blastRadius.d.ts +17 -16
- package/dist/audit/clarification/blastRadius.d.ts.map +1 -1
- package/dist/audit/clarification/blastRadius.js +48 -44
- package/dist/audit/clarification/blastRadius.js.map +1 -1
- package/dist/audit/clarification/dials.d.ts +4 -4
- package/dist/audit/clarification/dials.d.ts.map +1 -1
- package/dist/audit/clarification/dials.js +1 -0
- package/dist/audit/clarification/dials.js.map +1 -1
- package/dist/audit/clarification/partition.d.ts +12 -21
- package/dist/audit/clarification/partition.d.ts.map +1 -1
- package/dist/audit/clarification/partition.js +52 -59
- package/dist/audit/clarification/partition.js.map +1 -1
- package/dist/audit/clarification/riskGate.d.ts +2 -2
- package/dist/audit/clarification/riskGate.d.ts.map +1 -1
- package/dist/audit/clarification/riskGate.js +1 -0
- package/dist/audit/clarification/riskGate.js.map +1 -1
- package/dist/audit/clarification/voiQueue.d.ts +3 -3
- package/dist/audit/clarification/voiQueue.d.ts.map +1 -1
- package/dist/audit/clarification/voiQueue.js +1 -0
- package/dist/audit/clarification/voiQueue.js.map +1 -1
- package/dist/audit/cli/auditStep.d.ts +14 -2
- package/dist/audit/cli/auditStep.d.ts.map +1 -1
- package/dist/audit/cli/auditStep.js +13 -5
- package/dist/audit/cli/auditStep.js.map +1 -1
- package/dist/audit/cli/charterClarificationPrompt.d.ts +6 -9
- package/dist/audit/cli/charterClarificationPrompt.d.ts.map +1 -1
- package/dist/audit/cli/charterClarificationPrompt.js +35 -47
- package/dist/audit/cli/charterClarificationPrompt.js.map +1 -1
- package/dist/audit/cli/charterComparisonPrompt.d.ts +14 -0
- package/dist/audit/cli/charterComparisonPrompt.d.ts.map +1 -0
- package/dist/audit/cli/charterComparisonPrompt.js +111 -0
- package/dist/audit/cli/charterComparisonPrompt.js.map +1 -0
- package/dist/audit/cli/charterExtractionPrompt.d.ts +14 -17
- package/dist/audit/cli/charterExtractionPrompt.d.ts.map +1 -1
- package/dist/audit/cli/charterExtractionPrompt.js +81 -104
- package/dist/audit/cli/charterExtractionPrompt.js.map +1 -1
- package/dist/audit/cli/charterFidelityPrompt.d.ts +14 -0
- package/dist/audit/cli/charterFidelityPrompt.d.ts.map +1 -0
- package/dist/audit/cli/charterFidelityPrompt.js +58 -0
- package/dist/audit/cli/charterFidelityPrompt.js.map +1 -0
- package/dist/audit/cli/conceptualDispatch.d.ts +39 -6
- package/dist/audit/cli/conceptualDispatch.d.ts.map +1 -1
- package/dist/audit/cli/conceptualDispatch.js +59 -12
- package/dist/audit/cli/conceptualDispatch.js.map +1 -1
- package/dist/audit/cli/confirmIntentStep.d.ts.map +1 -1
- package/dist/audit/cli/confirmIntentStep.js +46 -2
- package/dist/audit/cli/confirmIntentStep.js.map +1 -1
- package/dist/audit/cli/dispatch/hostHandoff.d.ts +18 -6
- package/dist/audit/cli/dispatch/hostHandoff.d.ts.map +1 -1
- package/dist/audit/cli/dispatch/hostHandoff.js +525 -67
- package/dist/audit/cli/dispatch/hostHandoff.js.map +1 -1
- package/dist/audit/cli/fanoutLanes.d.ts +24 -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/foldTransaction.d.ts.map +1 -1
- package/dist/audit/cli/foldTransaction.js +14 -3
- package/dist/audit/cli/foldTransaction.js.map +1 -1
- package/dist/audit/cli/forceSynthesisCommand.d.ts.map +1 -1
- package/dist/audit/cli/forceSynthesisCommand.js +4 -1
- 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 +1 -0
- package/dist/audit/cli/intakeCommand.js.map +1 -1
- package/dist/audit/cli/laneSubmissions.d.ts +18 -12
- package/dist/audit/cli/laneSubmissions.d.ts.map +1 -1
- package/dist/audit/cli/laneSubmissions.js +40 -4
- package/dist/audit/cli/laneSubmissions.js.map +1 -1
- package/dist/audit/cli/laneValidators.d.ts.map +1 -1
- package/dist/audit/cli/laneValidators.js +14 -14
- package/dist/audit/cli/laneValidators.js.map +1 -1
- package/dist/audit/cli/nextStepCommand.d.ts +7 -0
- package/dist/audit/cli/nextStepCommand.d.ts.map +1 -1
- package/dist/audit/cli/nextStepCommand.js +206 -31
- package/dist/audit/cli/nextStepCommand.js.map +1 -1
- package/dist/audit/cli/nextStepHelpers.d.ts +92 -28
- package/dist/audit/cli/nextStepHelpers.d.ts.map +1 -1
- package/dist/audit/cli/nextStepHelpers.js +363 -126
- package/dist/audit/cli/nextStepHelpers.js.map +1 -1
- package/dist/audit/cli/prompts.d.ts +10 -0
- package/dist/audit/cli/prompts.d.ts.map +1 -1
- package/dist/audit/cli/prompts.js +3 -1
- package/dist/audit/cli/prompts.js.map +1 -1
- package/dist/audit/cli/reviewRun.d.ts +12 -0
- package/dist/audit/cli/reviewRun.d.ts.map +1 -1
- package/dist/audit/cli/reviewRun.js +242 -29
- package/dist/audit/cli/reviewRun.js.map +1 -1
- package/dist/audit/cli/sampleRunCommand.d.ts +12 -4
- package/dist/audit/cli/sampleRunCommand.d.ts.map +1 -1
- package/dist/audit/cli/semanticReviewStep.d.ts +9 -0
- package/dist/audit/cli/semanticReviewStep.d.ts.map +1 -1
- package/dist/audit/cli/semanticReviewStep.js +71 -30
- package/dist/audit/cli/semanticReviewStep.js.map +1 -1
- package/dist/audit/cli/statusCommand.d.ts.map +1 -1
- package/dist/audit/cli/statusCommand.js +29 -66
- package/dist/audit/cli/statusCommand.js.map +1 -1
- package/dist/audit/cli/stepScaffold.d.ts +43 -2
- package/dist/audit/cli/stepScaffold.d.ts.map +1 -1
- package/dist/audit/cli/stepScaffold.js +24 -10
- package/dist/audit/cli/stepScaffold.js.map +1 -1
- package/dist/audit/cli/steps.d.ts +52 -29
- package/dist/audit/cli/steps.d.ts.map +1 -1
- package/dist/audit/cli/steps.js +44 -14
- package/dist/audit/cli/steps.js.map +1 -1
- package/dist/audit/cli/synthesizeCommand.d.ts.map +1 -1
- package/dist/audit/cli/synthesizeCommand.js +4 -1
- package/dist/audit/cli/synthesizeCommand.js.map +1 -1
- package/dist/audit/contracts/workerSchemas.d.ts +65 -16
- package/dist/audit/contracts/workerSchemas.d.ts.map +1 -1
- package/dist/audit/contracts/workerSchemas.js +89 -8
- package/dist/audit/contracts/workerSchemas.js.map +1 -1
- package/dist/audit/contracts/wrapperResponse.d.ts +14 -21
- package/dist/audit/contracts/wrapperResponse.d.ts.map +1 -1
- package/dist/audit/contracts/wrapperResponse.js +0 -1
- package/dist/audit/contracts/wrapperResponse.js.map +1 -1
- package/dist/audit/decompose/findings.d.ts.map +1 -1
- package/dist/audit/decompose/findings.js +10 -2
- package/dist/audit/decompose/findings.js.map +1 -1
- package/dist/audit/extractors/designAssessment.d.ts.map +1 -1
- package/dist/audit/extractors/designAssessment.js +13 -4
- package/dist/audit/extractors/designAssessment.js.map +1 -1
- package/dist/audit/extractors/disposition.d.ts.map +1 -1
- package/dist/audit/extractors/disposition.js +17 -5
- package/dist/audit/extractors/disposition.js.map +1 -1
- package/dist/audit/extractors/graph.d.ts +1 -1
- package/dist/audit/extractors/graph.js +1 -1
- package/dist/audit/extractors/graphRoutes.d.ts.map +1 -1
- package/dist/audit/extractors/graphRoutes.js +224 -17
- package/dist/audit/extractors/graphRoutes.js.map +1 -1
- package/dist/audit/extractors/leadLineage.d.ts +10 -0
- package/dist/audit/extractors/leadLineage.d.ts.map +1 -0
- package/dist/audit/extractors/leadLineage.js +44 -0
- package/dist/audit/extractors/leadLineage.js.map +1 -0
- package/dist/audit/io/artifacts.d.ts.map +1 -1
- package/dist/audit/io/artifacts.js +25 -8
- package/dist/audit/io/artifacts.js.map +1 -1
- package/dist/audit/io/runArtifacts.d.ts +76 -1
- package/dist/audit/io/runArtifacts.d.ts.map +1 -1
- package/dist/audit/io/runArtifacts.js +113 -20
- package/dist/audit/io/runArtifacts.js.map +1 -1
- package/dist/audit/io/toolingManifest.d.ts +15 -0
- package/dist/audit/io/toolingManifest.d.ts.map +1 -1
- package/dist/audit/io/toolingManifest.js +158 -11
- package/dist/audit/io/toolingManifest.js.map +1 -1
- package/dist/audit/orchestrator/advance.d.ts.map +1 -1
- package/dist/audit/orchestrator/advance.js +30 -4
- package/dist/audit/orchestrator/advance.js.map +1 -1
- package/dist/audit/orchestrator/advanceTypes.d.ts +28 -5
- package/dist/audit/orchestrator/advanceTypes.d.ts.map +1 -1
- package/dist/audit/orchestrator/artifactMetadata.d.ts.map +1 -1
- package/dist/audit/orchestrator/artifactMetadata.js +39 -1
- package/dist/audit/orchestrator/artifactMetadata.js.map +1 -1
- package/dist/audit/orchestrator/auditTaskUtils.d.ts.map +1 -1
- package/dist/audit/orchestrator/auditTaskUtils.js +4 -1
- package/dist/audit/orchestrator/auditTaskUtils.js.map +1 -1
- package/dist/audit/orchestrator/charterClarificationExecutor.d.ts +11 -17
- package/dist/audit/orchestrator/charterClarificationExecutor.d.ts.map +1 -1
- package/dist/audit/orchestrator/charterClarificationExecutor.js +61 -93
- package/dist/audit/orchestrator/charterClarificationExecutor.js.map +1 -1
- package/dist/audit/orchestrator/charterComparisonExecutor.d.ts +24 -0
- package/dist/audit/orchestrator/charterComparisonExecutor.d.ts.map +1 -0
- package/dist/audit/orchestrator/charterComparisonExecutor.js +110 -0
- package/dist/audit/orchestrator/charterComparisonExecutor.js.map +1 -0
- package/dist/audit/orchestrator/charterExtractionExecutor.d.ts +34 -20
- package/dist/audit/orchestrator/charterExtractionExecutor.d.ts.map +1 -1
- package/dist/audit/orchestrator/charterExtractionExecutor.js +80 -106
- package/dist/audit/orchestrator/charterExtractionExecutor.js.map +1 -1
- package/dist/audit/orchestrator/charterFidelityExecutor.d.ts +20 -0
- package/dist/audit/orchestrator/charterFidelityExecutor.d.ts.map +1 -0
- package/dist/audit/orchestrator/charterFidelityExecutor.js +76 -0
- package/dist/audit/orchestrator/charterFidelityExecutor.js.map +1 -0
- package/dist/audit/orchestrator/charterFidelityPacket.d.ts +7 -0
- package/dist/audit/orchestrator/charterFidelityPacket.d.ts.map +1 -0
- package/dist/audit/orchestrator/charterFidelityPacket.js +68 -0
- package/dist/audit/orchestrator/charterFidelityPacket.js.map +1 -0
- package/dist/audit/orchestrator/dependencyMap.d.ts.map +1 -1
- package/dist/audit/orchestrator/dependencyMap.js +9 -8
- package/dist/audit/orchestrator/dependencyMap.js.map +1 -1
- package/dist/audit/orchestrator/dependencySlices.d.ts.map +1 -1
- package/dist/audit/orchestrator/dependencySlices.js +7 -6
- package/dist/audit/orchestrator/dependencySlices.js.map +1 -1
- package/dist/audit/orchestrator/designReviewProjection.d.ts.map +1 -1
- package/dist/audit/orchestrator/designReviewProjection.js +7 -0
- package/dist/audit/orchestrator/designReviewProjection.js.map +1 -1
- package/dist/audit/orchestrator/designReviewPrompt.d.ts.map +1 -1
- package/dist/audit/orchestrator/designReviewPrompt.js +58 -19
- package/dist/audit/orchestrator/designReviewPrompt.js.map +1 -1
- package/dist/audit/orchestrator/executorRunners.d.ts.map +1 -1
- package/dist/audit/orchestrator/executorRunners.js +6 -2
- package/dist/audit/orchestrator/executorRunners.js.map +1 -1
- package/dist/audit/orchestrator/executors.d.ts.map +1 -1
- package/dist/audit/orchestrator/executors.js +22 -8
- package/dist/audit/orchestrator/executors.js.map +1 -1
- package/dist/audit/orchestrator/hostInputPause.js +1 -0
- package/dist/audit/orchestrator/hostInputPause.js.map +1 -1
- package/dist/audit/orchestrator/intentCheckpointExecutor.d.ts +40 -0
- package/dist/audit/orchestrator/intentCheckpointExecutor.d.ts.map +1 -1
- package/dist/audit/orchestrator/intentCheckpointExecutor.js +32 -2
- package/dist/audit/orchestrator/intentCheckpointExecutor.js.map +1 -1
- package/dist/audit/orchestrator/intentCheckpointGate.d.ts +5 -3
- package/dist/audit/orchestrator/intentCheckpointGate.d.ts.map +1 -1
- package/dist/audit/orchestrator/intentCheckpointGate.js +34 -5
- package/dist/audit/orchestrator/intentCheckpointGate.js.map +1 -1
- package/dist/audit/orchestrator/intentEquivalenceExecutor.d.ts +2 -2
- package/dist/audit/orchestrator/intentInterpreter.d.ts +1 -1
- package/dist/audit/orchestrator/intentInterpreter.js +1 -1
- package/dist/audit/orchestrator/nextStep.d.ts.map +1 -1
- package/dist/audit/orchestrator/nextStep.js +3 -1
- package/dist/audit/orchestrator/nextStep.js.map +1 -1
- package/dist/audit/orchestrator/obligationPolicy.d.ts +2 -1
- package/dist/audit/orchestrator/obligationPolicy.d.ts.map +1 -1
- package/dist/audit/orchestrator/obligationPolicy.js +19 -7
- package/dist/audit/orchestrator/obligationPolicy.js.map +1 -1
- package/dist/audit/orchestrator/partitionTaskGraph.d.ts.map +1 -1
- package/dist/audit/orchestrator/partitionTaskGraph.js +1 -0
- package/dist/audit/orchestrator/partitionTaskGraph.js.map +1 -1
- package/dist/audit/orchestrator/resultIngestion.d.ts.map +1 -1
- package/dist/audit/orchestrator/resultIngestion.js +3 -1
- package/dist/audit/orchestrator/resultIngestion.js.map +1 -1
- package/dist/audit/orchestrator/runtimeCommand.d.ts +72 -0
- package/dist/audit/orchestrator/runtimeCommand.d.ts.map +1 -1
- package/dist/audit/orchestrator/runtimeCommand.js +177 -20
- package/dist/audit/orchestrator/runtimeCommand.js.map +1 -1
- package/dist/audit/orchestrator/scopeIndexBaseline.d.ts +56 -0
- package/dist/audit/orchestrator/scopeIndexBaseline.d.ts.map +1 -0
- package/dist/audit/orchestrator/scopeIndexBaseline.js +114 -0
- package/dist/audit/orchestrator/scopeIndexBaseline.js.map +1 -0
- package/dist/audit/orchestrator/staleness.d.ts +70 -1
- package/dist/audit/orchestrator/staleness.d.ts.map +1 -1
- package/dist/audit/orchestrator/staleness.js +171 -21
- package/dist/audit/orchestrator/staleness.js.map +1 -1
- package/dist/audit/orchestrator/state.d.ts.map +1 -1
- package/dist/audit/orchestrator/state.js +49 -25
- package/dist/audit/orchestrator/state.js.map +1 -1
- package/dist/audit/orchestrator/structureExecutors.d.ts.map +1 -1
- package/dist/audit/orchestrator/structureExecutors.js +7 -5
- package/dist/audit/orchestrator/structureExecutors.js.map +1 -1
- package/dist/audit/orchestrator/syntaxResolutionExecutor.d.ts.map +1 -1
- package/dist/audit/orchestrator/syntaxResolutionExecutor.js +1 -0
- package/dist/audit/orchestrator/syntaxResolutionExecutor.js.map +1 -1
- package/dist/audit/orchestrator/systemicChallengeExecutor.d.ts +13 -2
- package/dist/audit/orchestrator/systemicChallengeExecutor.d.ts.map +1 -1
- package/dist/audit/orchestrator/systemicChallengeExecutor.js +166 -12
- package/dist/audit/orchestrator/systemicChallengeExecutor.js.map +1 -1
- package/dist/audit/reporting/mergeFindings.d.ts.map +1 -1
- package/dist/audit/reporting/mergeFindings.js +6 -5
- package/dist/audit/reporting/mergeFindings.js.map +1 -1
- package/dist/audit/reporting/synthesis.d.ts +117 -0
- package/dist/audit/reporting/synthesis.d.ts.map +1 -1
- package/dist/audit/reporting/synthesis.js +277 -10
- package/dist/audit/reporting/synthesis.js.map +1 -1
- package/dist/audit/supervisor/operatorHandoff.d.ts +0 -2
- package/dist/audit/supervisor/operatorHandoff.d.ts.map +1 -1
- package/dist/audit/supervisor/operatorHandoff.js +0 -3
- package/dist/audit/supervisor/operatorHandoff.js.map +1 -1
- package/dist/audit/systemic/coveredThemes.d.ts +28 -0
- package/dist/audit/systemic/coveredThemes.d.ts.map +1 -0
- package/dist/audit/systemic/coveredThemes.js +52 -0
- package/dist/audit/systemic/coveredThemes.js.map +1 -0
- package/dist/audit/systemic/reviewFileMap.d.ts +81 -0
- package/dist/audit/systemic/reviewFileMap.d.ts.map +1 -0
- package/dist/audit/systemic/reviewFileMap.js +169 -0
- package/dist/audit/systemic/reviewFileMap.js.map +1 -0
- package/dist/audit/systemic/secondOrderAdversaryPrompt.d.ts.map +1 -1
- package/dist/audit/systemic/secondOrderAdversaryPrompt.js +149 -26
- package/dist/audit/systemic/secondOrderAdversaryPrompt.js.map +1 -1
- package/dist/audit/systemic/systemicChallengeLoop.d.ts +44 -4
- package/dist/audit/systemic/systemicChallengeLoop.d.ts.map +1 -1
- package/dist/audit/systemic/systemicChallengeLoop.js +114 -10
- package/dist/audit/systemic/systemicChallengeLoop.js.map +1 -1
- package/dist/audit/types/auditState.d.ts +6 -6
- package/dist/audit/types/charterClarification.d.ts +9 -4
- package/dist/audit/types/charterClarification.d.ts.map +1 -1
- package/dist/audit/types/charterRegister.d.ts +48 -93
- package/dist/audit/types/charterRegister.d.ts.map +1 -1
- package/dist/audit/types/charterRegister.js +15 -26
- package/dist/audit/types/charterRegister.js.map +1 -1
- package/dist/audit/types/conceptualAdjudication.d.ts +88 -18
- package/dist/audit/types/conceptualAdjudication.d.ts.map +1 -1
- package/dist/audit/types/conceptualAdjudication.js +77 -16
- package/dist/audit/types/conceptualAdjudication.js.map +1 -1
- package/dist/audit/types/designAssessment.d.ts +8 -6
- package/dist/audit/types/designAssessment.d.ts.map +1 -1
- package/dist/audit/types/reviewPlanning.d.ts +2 -2
- package/dist/audit/types/systemicChallenge.d.ts +43 -7
- package/dist/audit/types/systemicChallenge.d.ts.map +1 -1
- package/dist/audit/types.d.ts +71 -10
- package/dist/audit/types.d.ts.map +1 -1
- package/dist/audit/types.js +23 -2
- package/dist/audit/types.js.map +1 -1
- package/dist/audit/validation/auditResults.d.ts +30 -0
- package/dist/audit/validation/auditResults.d.ts.map +1 -1
- package/dist/audit/validation/auditResults.js +50 -8
- package/dist/audit/validation/auditResults.js.map +1 -1
- package/dist/audit/validation/ingestIssueCodes.d.ts +1 -1
- package/dist/audit/validation/ingestIssueCodes.d.ts.map +1 -1
- package/dist/audit/validation/ingestIssueCodes.js +14 -0
- package/dist/audit/validation/ingestIssueCodes.js.map +1 -1
- package/dist/remediate/contractPipeline/artifactStore.d.ts +97 -2
- package/dist/remediate/contractPipeline/artifactStore.d.ts.map +1 -1
- package/dist/remediate/contractPipeline/artifactStore.js +163 -9
- package/dist/remediate/contractPipeline/artifactStore.js.map +1 -1
- package/dist/remediate/contractPipeline/changeClassification.d.ts.map +1 -1
- package/dist/remediate/contractPipeline/changeClassification.js +93 -3
- package/dist/remediate/contractPipeline/changeClassification.js.map +1 -1
- package/dist/remediate/contractPipeline/cyclicSeamResolution.d.ts.map +1 -1
- package/dist/remediate/contractPipeline/cyclicSeamResolution.js +31 -0
- package/dist/remediate/contractPipeline/cyclicSeamResolution.js.map +1 -1
- package/dist/remediate/contractPipeline/derive.d.ts +0 -14
- package/dist/remediate/contractPipeline/derive.d.ts.map +1 -1
- package/dist/remediate/contractPipeline/derive.js +52 -24
- package/dist/remediate/contractPipeline/derive.js.map +1 -1
- package/dist/remediate/contractPipeline/finalizedContractFields.d.ts +50 -0
- package/dist/remediate/contractPipeline/finalizedContractFields.d.ts.map +1 -0
- package/dist/remediate/contractPipeline/finalizedContractFields.js +77 -0
- package/dist/remediate/contractPipeline/finalizedContractFields.js.map +1 -0
- package/dist/remediate/contractPipeline/idRegistry.d.ts +85 -0
- package/dist/remediate/contractPipeline/idRegistry.d.ts.map +1 -1
- package/dist/remediate/contractPipeline/idRegistry.js +147 -0
- package/dist/remediate/contractPipeline/idRegistry.js.map +1 -1
- package/dist/remediate/contractPipeline/phaseCut.d.ts +13 -16
- package/dist/remediate/contractPipeline/phaseCut.d.ts.map +1 -1
- package/dist/remediate/contractPipeline/phaseCut.js +15 -30
- package/dist/remediate/contractPipeline/phaseCut.js.map +1 -1
- package/dist/remediate/contractPipeline/reviewSnapshot.d.ts +20 -1
- package/dist/remediate/contractPipeline/reviewSnapshot.d.ts.map +1 -1
- package/dist/remediate/contractPipeline/reviewSnapshot.js +23 -7
- package/dist/remediate/contractPipeline/reviewSnapshot.js.map +1 -1
- package/dist/remediate/contractPipeline/semanticProjection.d.ts +17 -0
- package/dist/remediate/contractPipeline/semanticProjection.d.ts.map +1 -1
- package/dist/remediate/contractPipeline/semanticProjection.js +6 -9
- package/dist/remediate/contractPipeline/semanticProjection.js.map +1 -1
- package/dist/remediate/contractPipeline/sketchSource.d.ts +183 -0
- package/dist/remediate/contractPipeline/sketchSource.d.ts.map +1 -0
- package/dist/remediate/contractPipeline/sketchSource.js +255 -0
- package/dist/remediate/contractPipeline/sketchSource.js.map +1 -0
- package/dist/remediate/findingFilter.d.ts.map +1 -1
- package/dist/remediate/findingFilter.js +1 -0
- package/dist/remediate/findingFilter.js.map +1 -1
- package/dist/remediate/index.d.ts +81 -0
- package/dist/remediate/index.d.ts.map +1 -1
- package/dist/remediate/index.js +162 -53
- package/dist/remediate/index.js.map +1 -1
- package/dist/remediate/intake.d.ts +43 -0
- package/dist/remediate/intake.d.ts.map +1 -1
- package/dist/remediate/intake.js +82 -13
- package/dist/remediate/intake.js.map +1 -1
- package/dist/remediate/phases/close.d.ts +33 -2
- package/dist/remediate/phases/close.d.ts.map +1 -1
- package/dist/remediate/phases/close.js +227 -13
- package/dist/remediate/phases/close.js.map +1 -1
- package/dist/remediate/phases/closeVerifyHeadEvidence.d.ts +154 -0
- package/dist/remediate/phases/closeVerifyHeadEvidence.d.ts.map +1 -0
- package/dist/remediate/phases/closeVerifyHeadEvidence.js +242 -0
- package/dist/remediate/phases/closeVerifyHeadEvidence.js.map +1 -0
- package/dist/remediate/state/runStatus.d.ts +35 -0
- package/dist/remediate/state/runStatus.d.ts.map +1 -0
- package/dist/remediate/state/runStatus.js +46 -0
- package/dist/remediate/state/runStatus.js.map +1 -0
- package/dist/remediate/state/store.d.ts +52 -2
- package/dist/remediate/state/store.d.ts.map +1 -1
- package/dist/remediate/state/store.js +124 -21
- package/dist/remediate/state/store.js.map +1 -1
- package/dist/remediate/state/types.d.ts +83 -13
- package/dist/remediate/state/types.d.ts.map +1 -1
- package/dist/remediate/steps/contractPipeline.d.ts +65 -1
- package/dist/remediate/steps/contractPipeline.d.ts.map +1 -1
- package/dist/remediate/steps/contractPipeline.js +302 -85
- package/dist/remediate/steps/contractPipeline.js.map +1 -1
- package/dist/remediate/steps/contractPipelinePrompts.d.ts.map +1 -1
- package/dist/remediate/steps/contractPipelinePrompts.js +58 -21
- package/dist/remediate/steps/contractPipelinePrompts.js.map +1 -1
- package/dist/remediate/steps/dispatch/hostHandoff.d.ts +87 -2
- package/dist/remediate/steps/dispatch/hostHandoff.d.ts.map +1 -1
- package/dist/remediate/steps/dispatch/hostHandoff.js +344 -44
- package/dist/remediate/steps/dispatch/hostHandoff.js.map +1 -1
- package/dist/remediate/steps/finalGate.d.ts +109 -5
- package/dist/remediate/steps/finalGate.d.ts.map +1 -1
- package/dist/remediate/steps/finalGate.js +135 -27
- package/dist/remediate/steps/finalGate.js.map +1 -1
- package/dist/remediate/steps/gateCommands.d.ts +167 -0
- package/dist/remediate/steps/gateCommands.d.ts.map +1 -1
- package/dist/remediate/steps/gateCommands.js +428 -1
- package/dist/remediate/steps/gateCommands.js.map +1 -1
- package/dist/remediate/steps/intakeResolver.d.ts +2 -13
- package/dist/remediate/steps/intakeResolver.d.ts.map +1 -1
- package/dist/remediate/steps/intakeResolver.js +22 -4
- package/dist/remediate/steps/intakeResolver.js.map +1 -1
- package/dist/remediate/steps/nextStep.d.ts +44 -40
- package/dist/remediate/steps/nextStep.d.ts.map +1 -1
- package/dist/remediate/steps/nextStep.js +501 -106
- package/dist/remediate/steps/nextStep.js.map +1 -1
- package/dist/remediate/steps/stepWriter.d.ts +1 -1
- package/dist/remediate/steps/stepWriter.d.ts.map +1 -1
- package/dist/remediate/steps/stepWriter.js +1 -0
- package/dist/remediate/steps/stepWriter.js.map +1 -1
- package/dist/remediate/steps/types.d.ts +32 -1
- package/dist/remediate/steps/types.d.ts.map +1 -1
- package/dist/remediate/steps/types.js +1 -0
- package/dist/remediate/steps/types.js.map +1 -1
- package/dist/remediate/types/options.d.ts +8 -0
- package/dist/remediate/types/options.d.ts.map +1 -1
- package/dist/remediate/utils/fileIntegrity.d.ts +8 -0
- package/dist/remediate/utils/fileIntegrity.d.ts.map +1 -1
- package/dist/remediate/utils/fileIntegrity.js +12 -1
- package/dist/remediate/utils/fileIntegrity.js.map +1 -1
- package/dist/remediate/validation/artifacts.d.ts +1 -1
- package/dist/remediate/validation/artifacts.d.ts.map +1 -1
- package/dist/remediate/validation/artifacts.js +19 -2
- package/dist/remediate/validation/artifacts.js.map +1 -1
- package/dist/remediate/validation/contractPipeline.d.ts.map +1 -1
- package/dist/remediate/validation/contractPipeline.js +26 -39
- package/dist/remediate/validation/contractPipeline.js.map +1 -1
- package/dist/remediate/validation/contractPipelineGates.d.ts +18 -1
- package/dist/remediate/validation/contractPipelineGates.d.ts.map +1 -1
- package/dist/remediate/validation/contractPipelineGates.js +33 -5
- package/dist/remediate/validation/contractPipelineGates.js.map +1 -1
- package/dist/shared/analyzers/acquisitionEngine.d.ts +83 -5
- package/dist/shared/analyzers/acquisitionEngine.d.ts.map +1 -1
- package/dist/shared/analyzers/acquisitionEngine.js +46 -14
- package/dist/shared/analyzers/acquisitionEngine.js.map +1 -1
- package/dist/shared/analyzers/binaryAcquisition.d.ts +35 -2
- package/dist/shared/analyzers/binaryAcquisition.d.ts.map +1 -1
- package/dist/shared/analyzers/binaryAcquisition.js +5 -5
- package/dist/shared/analyzers/binaryAcquisition.js.map +1 -1
- package/dist/shared/analyzers/candidates.d.ts.map +1 -1
- package/dist/shared/analyzers/candidates.js +1 -0
- package/dist/shared/analyzers/candidates.js.map +1 -1
- package/dist/shared/analyzers/clippy.d.ts +9 -1
- package/dist/shared/analyzers/clippy.d.ts.map +1 -1
- package/dist/shared/analyzers/clippy.js +10 -2
- package/dist/shared/analyzers/clippy.js.map +1 -1
- package/dist/shared/analyzers/normalizeExternal.d.ts.map +1 -1
- package/dist/shared/analyzers/normalizeExternal.js +1 -0
- package/dist/shared/analyzers/normalizeExternal.js.map +1 -1
- package/dist/shared/analyzers/rubocop.d.ts +7 -1
- package/dist/shared/analyzers/rubocop.d.ts.map +1 -1
- package/dist/shared/analyzers/rubocop.js +8 -2
- package/dist/shared/analyzers/rubocop.js.map +1 -1
- package/dist/shared/analyzers/types.d.ts +24 -24
- package/dist/shared/analyzers/types.d.ts.map +1 -1
- package/dist/shared/analyzers/types.js +15 -0
- package/dist/shared/analyzers/types.js.map +1 -1
- package/dist/shared/artifactFreshness.d.ts.map +1 -1
- package/dist/shared/artifactFreshness.js +42 -7
- package/dist/shared/artifactFreshness.js.map +1 -1
- package/dist/shared/chunkByBudget.d.ts.map +1 -1
- package/dist/shared/chunkByBudget.js.map +1 -1
- package/dist/shared/continuityScore.d.ts.map +1 -1
- package/dist/shared/continuityScore.js +12 -4
- package/dist/shared/continuityScore.js.map +1 -1
- package/dist/shared/decompose/charterClarification.d.ts +49 -45
- package/dist/shared/decompose/charterClarification.d.ts.map +1 -1
- package/dist/shared/decompose/charterClarification.js +50 -57
- package/dist/shared/decompose/charterClarification.js.map +1 -1
- package/dist/shared/decompose/charterExtraction.d.ts +616 -342
- package/dist/shared/decompose/charterExtraction.d.ts.map +1 -1
- package/dist/shared/decompose/charterExtraction.js +590 -488
- package/dist/shared/decompose/charterExtraction.js.map +1 -1
- package/dist/shared/decompose/contentCoherence.d.ts +36 -2
- package/dist/shared/decompose/contentCoherence.d.ts.map +1 -1
- package/dist/shared/decompose/contentCoherence.js +45 -5
- package/dist/shared/decompose/contentCoherence.js.map +1 -1
- package/dist/shared/decompose/modularity.d.ts +98 -1
- package/dist/shared/decompose/modularity.d.ts.map +1 -1
- package/dist/shared/decompose/modularity.js +89 -8
- package/dist/shared/decompose/modularity.js.map +1 -1
- package/dist/shared/decompose/systemicChallenge.d.ts +111 -0
- package/dist/shared/decompose/systemicChallenge.d.ts.map +1 -1
- package/dist/shared/decompose/systemicChallenge.js +28 -0
- package/dist/shared/decompose/systemicChallenge.js.map +1 -1
- package/dist/shared/engine/obligationEngine.d.ts +2 -2
- package/dist/shared/engine/obligationEngine.d.ts.map +1 -1
- package/dist/shared/engine/obligationEngine.js +8 -2
- package/dist/shared/engine/obligationEngine.js.map +1 -1
- package/dist/shared/findingSimilarity.d.ts +8 -0
- package/dist/shared/findingSimilarity.d.ts.map +1 -1
- package/dist/shared/findingSimilarity.js +10 -3
- package/dist/shared/findingSimilarity.js.map +1 -1
- package/dist/shared/findings/dedupe.d.ts +15 -0
- package/dist/shared/findings/dedupe.d.ts.map +1 -1
- package/dist/shared/findings/dedupe.js +137 -1
- package/dist/shared/findings/dedupe.js.map +1 -1
- package/dist/shared/friction/frictionRecord.d.ts.map +1 -1
- package/dist/shared/friction/frictionRecord.js +14 -1
- package/dist/shared/friction/frictionRecord.js.map +1 -1
- package/dist/shared/friction/triage.d.ts +4 -0
- package/dist/shared/friction/triage.d.ts.map +1 -1
- package/dist/shared/friction/triage.js +41 -29
- package/dist/shared/friction/triage.js.map +1 -1
- package/dist/shared/git.d.ts +14 -0
- package/dist/shared/git.d.ts.map +1 -1
- package/dist/shared/git.js +22 -0
- package/dist/shared/git.js.map +1 -1
- package/dist/shared/index.d.ts +42 -38
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/index.js +35 -23
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/intent/clauseBoundaries.d.ts +75 -0
- package/dist/shared/intent/clauseBoundaries.d.ts.map +1 -0
- package/dist/shared/intent/clauseBoundaries.js +134 -0
- package/dist/shared/intent/clauseBoundaries.js.map +1 -0
- package/dist/shared/intent/clauseInterpreter.d.ts +11 -5
- package/dist/shared/intent/clauseInterpreter.d.ts.map +1 -1
- package/dist/shared/intent/clauseInterpreter.js +16 -41
- package/dist/shared/intent/clauseInterpreter.js.map +1 -1
- package/dist/shared/intent/freeFormIntentInterpreter.d.ts +11 -0
- package/dist/shared/intent/freeFormIntentInterpreter.d.ts.map +1 -1
- package/dist/shared/intent/freeFormIntentInterpreter.js +31 -17
- package/dist/shared/intent/freeFormIntentInterpreter.js.map +1 -1
- package/dist/shared/io/fileLock.d.ts.map +1 -1
- package/dist/shared/io/fileLock.js +18 -6
- package/dist/shared/io/fileLock.js.map +1 -1
- package/dist/shared/io/frictionCapture.d.ts +25 -5
- package/dist/shared/io/frictionCapture.d.ts.map +1 -1
- package/dist/shared/io/frictionCapture.js +30 -9
- package/dist/shared/io/frictionCapture.js.map +1 -1
- package/dist/shared/io/schemaVersion.d.ts +4 -3
- package/dist/shared/io/schemaVersion.d.ts.map +1 -1
- package/dist/shared/io/schemaVersion.js +27 -4
- package/dist/shared/io/schemaVersion.js.map +1 -1
- package/dist/shared/io/stepContractWriter.d.ts +38 -4
- package/dist/shared/io/stepContractWriter.d.ts.map +1 -1
- package/dist/shared/io/stepContractWriter.js +59 -1
- package/dist/shared/io/stepContractWriter.js.map +1 -1
- package/dist/shared/loopCorePaths.d.ts.map +1 -1
- package/dist/shared/loopCorePaths.js +8 -0
- package/dist/shared/loopCorePaths.js.map +1 -1
- package/dist/shared/opencodePermissions.d.ts +27 -3
- package/dist/shared/opencodePermissions.d.ts.map +1 -1
- package/dist/shared/opencodePermissions.js +77 -26
- package/dist/shared/opencodePermissions.js.map +1 -1
- package/dist/shared/prompts.d.ts +12 -1
- package/dist/shared/prompts.d.ts.map +1 -1
- package/dist/shared/prompts.js +11 -1
- package/dist/shared/prompts.js.map +1 -1
- package/dist/shared/reReview/projectionDiff.d.ts +13 -0
- package/dist/shared/reReview/projectionDiff.d.ts.map +1 -1
- package/dist/shared/reReview/projectionDiff.js +1 -1
- package/dist/shared/reReview/projectionDiff.js.map +1 -1
- package/dist/shared/reporting/findingDisplay.d.ts +7 -0
- package/dist/shared/reporting/findingDisplay.d.ts.map +1 -1
- package/dist/shared/reporting/findingDisplay.js +8 -1
- package/dist/shared/reporting/findingDisplay.js.map +1 -1
- package/dist/shared/steps/stepEmissionScaffold.d.ts +15 -3
- package/dist/shared/steps/stepEmissionScaffold.d.ts.map +1 -1
- package/dist/shared/steps/stepEmissionScaffold.js +8 -6
- package/dist/shared/steps/stepEmissionScaffold.js.map +1 -1
- package/dist/shared/submission/hostHandoffCore.d.ts +37 -12
- package/dist/shared/submission/hostHandoffCore.d.ts.map +1 -1
- package/dist/shared/submission/hostHandoffCore.js +81 -18
- package/dist/shared/submission/hostHandoffCore.js.map +1 -1
- package/dist/shared/submission/hostResultOutcomes.d.ts +70 -1
- package/dist/shared/submission/hostResultOutcomes.d.ts.map +1 -1
- package/dist/shared/submission/hostResultOutcomes.js +66 -1
- package/dist/shared/submission/hostResultOutcomes.js.map +1 -1
- package/dist/shared/submission/submissionLedger.d.ts +86 -1
- package/dist/shared/submission/submissionLedger.d.ts.map +1 -1
- package/dist/shared/submission/submissionLedger.js +108 -0
- package/dist/shared/submission/submissionLedger.js.map +1 -1
- package/dist/shared/submission/submissionScan.d.ts.map +1 -1
- package/dist/shared/submission/submissionScan.js +1 -0
- package/dist/shared/submission/submissionScan.js.map +1 -1
- package/dist/shared/tooling/analyzerDeps.d.ts +14 -0
- package/dist/shared/tooling/analyzerDeps.d.ts.map +1 -1
- package/dist/shared/tooling/analyzerDeps.js +23 -0
- package/dist/shared/tooling/analyzerDeps.js.map +1 -1
- package/dist/shared/tooling/commandShape.d.ts +35 -1
- package/dist/shared/tooling/commandShape.d.ts.map +1 -1
- package/dist/shared/tooling/commandShape.js +66 -4
- package/dist/shared/tooling/commandShape.js.map +1 -1
- package/dist/shared/tooling/exec.d.ts +62 -4
- package/dist/shared/tooling/exec.d.ts.map +1 -1
- package/dist/shared/tooling/exec.js +127 -8
- package/dist/shared/tooling/exec.js.map +1 -1
- package/dist/shared/types/charter.d.ts +674 -156
- package/dist/shared/types/charter.d.ts.map +1 -1
- package/dist/shared/types/charter.js +172 -118
- package/dist/shared/types/charter.js.map +1 -1
- package/dist/shared/types/closingActions.d.ts +25 -0
- package/dist/shared/types/closingActions.d.ts.map +1 -1
- package/dist/shared/types/closingActions.js +26 -0
- package/dist/shared/types/closingActions.js.map +1 -1
- package/dist/shared/types/contractPipeline/obligations.d.ts +63 -2
- package/dist/shared/types/contractPipeline/obligations.d.ts.map +1 -1
- package/dist/shared/types/contractPipeline/obligations.js +51 -0
- package/dist/shared/types/contractPipeline/obligations.js.map +1 -1
- package/dist/shared/types/contractPipeline.d.ts +1 -0
- package/dist/shared/types/contractPipeline.d.ts.map +1 -1
- package/dist/shared/types/contractPipeline.js +1 -0
- package/dist/shared/types/contractPipeline.js.map +1 -1
- package/dist/shared/types/contractPropertyShapes.d.ts +34 -0
- package/dist/shared/types/contractPropertyShapes.d.ts.map +1 -0
- package/dist/shared/types/contractPropertyShapes.js +255 -0
- package/dist/shared/types/contractPropertyShapes.js.map +1 -0
- package/dist/shared/types/finding.d.ts +376 -18
- package/dist/shared/types/finding.d.ts.map +1 -1
- package/dist/shared/types/finding.js +111 -0
- package/dist/shared/types/finding.js.map +1 -1
- package/dist/shared/types/intentCheckpoint.d.ts +214 -2
- package/dist/shared/types/intentCheckpoint.d.ts.map +1 -1
- package/dist/shared/types/intentCheckpoint.js +273 -0
- package/dist/shared/types/intentCheckpoint.js.map +1 -1
- package/dist/shared/types/intentInterpretation.d.ts +1 -1
- package/dist/shared/types/intentInterpretation.js +1 -1
- package/dist/shared/types/remediationOutcome.d.ts +294 -30
- package/dist/shared/types/remediationOutcome.d.ts.map +1 -1
- package/dist/shared/types/remediationOutcome.js +96 -7
- package/dist/shared/types/remediationOutcome.js.map +1 -1
- package/dist/shared/types/stepContract.d.ts +47 -0
- package/dist/shared/types/stepContract.d.ts.map +1 -1
- package/dist/shared/types/stepContract.js +113 -0
- package/dist/shared/types/stepContract.js.map +1 -1
- package/dist/shared/validation/charterGate.d.ts +13 -28
- package/dist/shared/validation/charterGate.d.ts.map +1 -1
- package/dist/shared/validation/charterGate.js +13 -35
- package/dist/shared/validation/charterGate.js.map +1 -1
- package/dist/shared/validation/contractConstructionSites.d.ts +116 -0
- package/dist/shared/validation/contractConstructionSites.d.ts.map +1 -0
- package/dist/shared/validation/contractConstructionSites.js +277 -0
- package/dist/shared/validation/contractConstructionSites.js.map +1 -0
- package/dist/shared/validation/designFindingGrounding.d.ts +33 -4
- package/dist/shared/validation/designFindingGrounding.d.ts.map +1 -1
- package/dist/shared/validation/designFindingGrounding.js +40 -6
- package/dist/shared/validation/designFindingGrounding.js.map +1 -1
- package/dist/shared/validation/findingGrounding.d.ts.map +1 -1
- package/dist/shared/validation/findingGrounding.js +11 -1
- package/dist/shared/validation/findingGrounding.js.map +1 -1
- package/dist/shared/validation/findingsReport.d.ts.map +1 -1
- package/dist/shared/validation/findingsReport.js +5 -0
- package/dist/shared/validation/findingsReport.js.map +1 -1
- package/docs/audit-pkg/contracts.md +8 -2
- package/opencode.json +29 -29
- package/package.json +16 -3
- package/schemas/audit-code-v1alpha1.schema.json +0 -4
- package/scripts/audit/postinstall.mjs +81 -96
- package/scripts/remediate/postinstall.mjs +43 -83
- package/scripts/shared/host-asset-plan.mjs +176 -0
- package/scripts/shared/install-host-assets.mjs +44 -1
- package/scripts/shared/primitives.mjs +89 -0
- package/skills/audit-code/SKILL.md +4 -4
- package/skills/audit-code/audit-code.prompt.md +14 -10
- package/skills/remediate-code/SKILL.md +9 -5
- package/skills/remediate-code/remediate-code.prompt.md +11 -4
- package/wrapper/audit-code-wrapper-build.mjs +6 -3
- package/dist/audit/cli/charterDeltaPrompt.d.ts +0 -18
- package/dist/audit/cli/charterDeltaPrompt.d.ts.map +0 -1
- package/dist/audit/cli/charterDeltaPrompt.js +0 -150
- package/dist/audit/cli/charterDeltaPrompt.js.map +0 -1
- package/dist/audit/orchestrator/charterDeltaExecutor.d.ts +0 -24
- package/dist/audit/orchestrator/charterDeltaExecutor.d.ts.map +0 -1
- package/dist/audit/orchestrator/charterDeltaExecutor.js +0 -128
- package/dist/audit/orchestrator/charterDeltaExecutor.js.map +0 -1
- package/dist/audit/supervisor/runLedger.d.ts +0 -3
- package/dist/audit/supervisor/runLedger.d.ts.map +0 -1
- package/dist/audit/supervisor/runLedger.js +0 -69
- package/dist/audit/supervisor/runLedger.js.map +0 -1
- package/dist/shared/types/executionRecord.d.ts +0 -58
- package/dist/shared/types/executionRecord.d.ts.map +0 -1
- package/dist/shared/types/executionRecord.js +0 -26
- package/dist/shared/types/executionRecord.js.map +0 -1
- package/dist/shared/types/runLedger.d.ts +0 -17
- package/dist/shared/types/runLedger.d.ts.map +0 -1
- package/dist/shared/types/runLedger.js +0 -7
- package/dist/shared/types/runLedger.js.map +0 -1
|
@@ -1,21 +1,25 @@
|
|
|
1
|
+
// sites-pinned: tests/remediate/friction-capture-closeout.test.ts, tests/remediate/next-step-lifecycle.test.ts, tests/remediate/next-step-pipeline-dispatch.test.ts, tests/remediate/next-step-outcomes-contract.test.ts, tests/remediate/integration-pipeline.test.ts, tests/remediate/outcomes-roundtrip.test.ts, tests/remediate/phase-close.test.ts, tests/remediate/grounding.test.ts
|
|
2
|
+
// (the free-form branch's write
|
|
3
|
+
// scope is normalized — a backslash-spelled citation no longer wedges prepare)
|
|
4
|
+
import { AUDIT_TOOLS_DIRNAME } from "../../shared/io/auditToolsPaths.js";
|
|
1
5
|
import { loadRemediateSessionConfig } from "./sessionConfigLoad.js";
|
|
2
6
|
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
3
7
|
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
4
8
|
import { dirname, join, resolve } from "node:path";
|
|
5
9
|
import { StateStore } from "../state/store.js";
|
|
6
10
|
// IO / validation / rendering helpers
|
|
7
|
-
import { discardOnSchemaVersionMismatch, readOptionalJsonFile, stagedAndUntracked, writeJsonFile, writeTextFile, buildAuditDeliverablePair, formatValidationIssues, isRecord, withFsRetry, RunLogger, coerceJsonObjectArg, renderPromptCommand, headCommit, projectAuditFindingsReportSubset,
|
|
11
|
+
import { discardOnSchemaVersionMismatch, readOptionalJsonFile, stagedAndUntracked, writeJsonFile, writeTextFile, buildAuditDeliverablePair, formatValidationIssues, isMissingObservation, isRecord, withFsRetry, RunLogger, coerceJsonObjectArg, renderPromptCommand, headCommit, projectAuditFindingsReportSubset,
|
|
8
12
|
// obligation engine + intent
|
|
9
13
|
interpretFreeFormIntent, interpretIntent, unresolvedFromClauses, advance, describeStoppedFold, decideFrictionTriage, buildFrictionTriageBlock, linkFrictionRunIds,
|
|
10
14
|
// domain constants
|
|
11
|
-
LENSES, SEVERITIES, CLOSING_ACTIONS, detectProjectFacts, isClosingAction, neutralProjectFacts, } from "audit-tools/shared";
|
|
15
|
+
LENSES, SEVERITIES, CLOSING_ACTIONS, SKIP_WRITE, invalidateStepContracts, detectProjectFacts, isClosingAction, neutralProjectFacts, repoRelativePath, } from "audit-tools/shared";
|
|
12
16
|
import { applyPlanPipeline, buildCoverageLedger } from "../phases/plan.js";
|
|
13
17
|
import { groundExtractedFindings, } from "../phases/grounding.js";
|
|
14
18
|
import { runTriagePhase } from "../phases/triage.js";
|
|
15
19
|
import { runClosePhase } from "../phases/close.js";
|
|
16
20
|
import { validateRemediationPlan } from "../validation/remediationState.js";
|
|
17
21
|
import { readExtractedPlanIfPresent, } from "./dispatch/marshal.js";
|
|
18
|
-
import { ingestRemediationHostResults, hostDependencyLevels, permanentlyDeadPendingBlocks, precomputeRecoveryTestVerdicts, prepareRemediationHostHandoff, } from "./dispatch/hostHandoff.js";
|
|
22
|
+
import { ingestRemediationHostResults, hostDependencyLevels, permanentlyDeadPendingBlocks, precomputeRecoveryTestVerdicts, prepareRemediationHostHandoff, workloadBindingIdentity, } from "./dispatch/hostHandoff.js";
|
|
19
23
|
import { FileLockTimeoutError, withFileLock, } from "../../shared/io/fileLock.js";
|
|
20
24
|
import { AUDIT_FINDINGS_FILENAME, AUDIT_REPORT_FILENAME, auditArtifactsDir, auditFindingsPath, auditReportPath, promotedAuditFindingsPath, promotedAuditReportPath, remediationArtifactsDir, } from "../../shared/io/auditToolsPaths.js";
|
|
21
25
|
import { callerWorkingDirectory, discoverRepoRoot, resolveRepoRoot, } from "../../shared/io/repoRoot.js";
|
|
@@ -25,7 +29,9 @@ import { deduplicateCrossLensFindings, fixupBlocksAfterDedup, } from "../dedup/c
|
|
|
25
29
|
import { checkAffectedFileIntegrity } from "../utils/fileIntegrity.js";
|
|
26
30
|
import { applyIntentOrdering } from "../intent/intentOrdering.js";
|
|
27
31
|
import { resolveIntakeStep } from "./intakeResolver.js";
|
|
28
|
-
import {
|
|
32
|
+
import { carriesGateVerdict } from "../../shared/types/remediationOutcome.js";
|
|
33
|
+
import { RUNTIME_RESIDUAL_DECLARATION, readFinalGateVerdict, runToolOwnedFinalGate, writeFinalGateRedRecord, writeFinalGateOutcomeRecord, writeFinalGateVerdict, } from "./finalGate.js";
|
|
34
|
+
import { renderGateAttribution, worktreeContentId, } from "./gateCommands.js";
|
|
29
35
|
import { buildNextContractPipelineStep, shouldEnterContractPipeline, writePathASeedFromFindings, normalizeBlockTouchedFiles, checkWriteScopePathsAgainstTrackedTree, } from "./contractPipeline.js";
|
|
30
36
|
import { compareCodeUnits } from "../../shared/compareCodeUnits.js";
|
|
31
37
|
import { contractArtifactExists, contractPipelineDir, } from "../contractPipeline/artifactStore.js";
|
|
@@ -35,6 +41,7 @@ import { runFindingFilterPass } from "../findingFilter.js";
|
|
|
35
41
|
import { droppedFindingsRecordPath, renderDroppedFindingsRecord, } from "../droppedFindingsRecord.js";
|
|
36
42
|
import { intakePaths, isIntakeReady, manifestIsInputBound, readIntakeArtifacts, readProjectFacts, writeProjectFacts, resolveManifestSources, } from "../intake.js";
|
|
37
43
|
import { ensureIntakeRiskSignal, readIntakeRiskSignal, writeIntakeRiskSignal, escalateRiskSignal, findingRiskEvidence, distinctAffectedFiles, } from "../riskSignal.js";
|
|
44
|
+
import { readIntentCheckpoint, readIntentCheckpointLenient, } from "audit-tools/shared";
|
|
38
45
|
import { ambiguityReviewPrompt, clarificationPrompt, collectIntakeClarificationsPrompt, collectStartingPointPrompt, extractedPlanDiscardedPrompt, loaderCommand, reviewApprovalPrompt, synthesizeIntakePrompt, triagePrompt, } from "./prompts.js";
|
|
39
46
|
// Single-sourced prose renders of the canonical lens / severity vocabularies
|
|
40
47
|
// (`audit-tools/shared` `LENSES` / `SEVERITIES`) for the intent-checkpoint
|
|
@@ -74,11 +81,36 @@ function resolveArtifactsDir(root, artifactsDir) {
|
|
|
74
81
|
// honored verbatim.
|
|
75
82
|
return artifactsDir ? resolve(artifactsDir) : remediationArtifactsDir(root);
|
|
76
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* The run's friction-record key: the plan id, or `null` when there is no plan.
|
|
86
|
+
*
|
|
87
|
+
* There is DELIBERATELY no fallback key. A fallback ("run") is a path every
|
|
88
|
+
* planless state shares, and `decideFrictionTriage` MATERIALIZES the record it
|
|
89
|
+
* is handed — so a planless caller could MINT a fresh empty record under it,
|
|
90
|
+
* which the close gate then blocks on. That is the 2026-08-24 defect exactly.
|
|
91
|
+
*
|
|
92
|
+
* The key is therefore the plan id or nothing, and a caller handed `null` has
|
|
93
|
+
* no walk to key: the walk ran before the close archived the plan-keyed record,
|
|
94
|
+
* and the plan is where its identity came from.
|
|
95
|
+
*/
|
|
77
96
|
function stateRunId(state) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
97
|
+
return state?.plan?.plan_id ?? null;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* The run key for a caller holding a LOADED state that must carry a plan id —
|
|
101
|
+
* the host-handoff/ingest paths, whose contracts declare `run_id: string`.
|
|
102
|
+
*
|
|
103
|
+
* It throws rather than inventing a key: an absent plan id there is a
|
|
104
|
+
* reachable-but-unexpected state, and silently falling back would mint a
|
|
105
|
+
* shared path exactly as the fallback key did. Callers that can legitimately
|
|
106
|
+
* hold a planless state use {@link stateRunId} and handle the `null`.
|
|
107
|
+
*/
|
|
108
|
+
function requireStateRunId(state) {
|
|
109
|
+
const runId = stateRunId(state);
|
|
110
|
+
if (!runId) {
|
|
111
|
+
throw new Error("remediate: a loaded state with no plan id cannot name a run");
|
|
112
|
+
}
|
|
113
|
+
return runId;
|
|
82
114
|
}
|
|
83
115
|
/**
|
|
84
116
|
* Where an autonomous run's LEFTOVER deliverable pair lands.
|
|
@@ -349,14 +381,51 @@ function allItemsTerminal(state) {
|
|
|
349
381
|
* return the plan untouched.
|
|
350
382
|
*/
|
|
351
383
|
async function applyCheckpointIntentOrdering(artifactsDir, plan) {
|
|
352
|
-
|
|
384
|
+
// Ordering is an ADVISORY pass: it reorders the plan and nothing depends on
|
|
385
|
+
// it, so an unreadable checkpoint degrades to "no intent" here rather than
|
|
386
|
+
// failing the planning step. (Every other read site is a GATE and lets the
|
|
387
|
+
// throw out — see `readIntentCheckpoint`.)
|
|
388
|
+
const checkpoint = await readIntentCheckpoint(join(artifactsDir, "intent_checkpoint.json")).catch(() => undefined);
|
|
353
389
|
const freeForm = checkpoint?.free_form_intent;
|
|
354
390
|
if (typeof freeForm !== "string" || freeForm.trim().length === 0)
|
|
355
391
|
return plan;
|
|
356
392
|
const ordered = applyIntentOrdering(plan.findings, plan.blocks, interpretFreeFormIntent(freeForm));
|
|
357
393
|
return { ...plan, findings: ordered.findings, blocks: ordered.blocks };
|
|
358
394
|
}
|
|
359
|
-
|
|
395
|
+
/**
|
|
396
|
+
* The write scope a free-form finding's `affected_files` implies, in the ONE
|
|
397
|
+
* form the block contract accepts.
|
|
398
|
+
*
|
|
399
|
+
* The paths arriving here have been GROUNDED but never normalized: grounding
|
|
400
|
+
* asks whether a path resolves to a real file (`existsSync`), and on Windows
|
|
401
|
+
* `src\a.ts` does — so a Windows-spelled citation survives grounding and, copied
|
|
402
|
+
* verbatim, becomes a `touched_files` entry `assertBlockContract` refuses. The
|
|
403
|
+
* run then wedges at handoff preparation and every retry reproduces the refusal.
|
|
404
|
+
*
|
|
405
|
+
* It normalizes through the SAME shared `repoRelativePath` the handoff boundary
|
|
406
|
+
* resolves declared entries with, so this producer's output is in the form its
|
|
407
|
+
* consumer demands by construction rather than by a second, drifting rule. A
|
|
408
|
+
* path that cannot be contained (`../outside.ts`) is DROPPED rather than
|
|
409
|
+
* resolved: the block contract refuses it later anyway, and dropping it here
|
|
410
|
+
* leaves the finding itself intact — grounding already decided which paths are
|
|
411
|
+
* real, and this decides only how they are SPELLED.
|
|
412
|
+
*/
|
|
413
|
+
function normalizedWriteScope(root, finding) {
|
|
414
|
+
const normalized = [];
|
|
415
|
+
for (const affected of finding.affected_files) {
|
|
416
|
+
let path;
|
|
417
|
+
try {
|
|
418
|
+
path = repoRelativePath(root, affected.path, "affected_files[].path");
|
|
419
|
+
}
|
|
420
|
+
catch {
|
|
421
|
+
continue;
|
|
422
|
+
}
|
|
423
|
+
if (path.length > 0 && !normalized.includes(path))
|
|
424
|
+
normalized.push(path);
|
|
425
|
+
}
|
|
426
|
+
return normalized;
|
|
427
|
+
}
|
|
428
|
+
function normalizeExtractedPlan(root, value, facts) {
|
|
360
429
|
if (!isRecord(value)) {
|
|
361
430
|
throw new Error("extracted-plan.json must be an object.");
|
|
362
431
|
}
|
|
@@ -390,7 +459,9 @@ function normalizeExtractedPlan(value, facts) {
|
|
|
390
459
|
block_id: `B-${String(index + 1).padStart(3, "0")}`,
|
|
391
460
|
items: [finding.id],
|
|
392
461
|
parallel_safe: true,
|
|
393
|
-
|
|
462
|
+
// Normalized, not copied: see normalizedWriteScope — a Windows-spelled
|
|
463
|
+
// citation would otherwise become a write scope the handoff refuses.
|
|
464
|
+
touched_files: normalizedWriteScope(root, finding),
|
|
394
465
|
}));
|
|
395
466
|
const dedup = deduplicateCrossLensFindings(findings);
|
|
396
467
|
const dedupBlocks = fixupBlocksAfterDedup(blocks, dedup.mergeMap);
|
|
@@ -447,7 +518,16 @@ function normalizeExtractedPlan(value, facts) {
|
|
|
447
518
|
* so membership is the whole check.
|
|
448
519
|
*/
|
|
449
520
|
async function confirmedClosingPlan(artifactsDir) {
|
|
450
|
-
|
|
521
|
+
// LENIENT, for the same reason the gate is: this runs on the state the gate
|
|
522
|
+
// just handled, and its own contract below says an out-of-vocabulary action
|
|
523
|
+
// "cannot reach here". A strict read would turn a case this function already
|
|
524
|
+
// handles by falling back to `none` into a thrown load error instead.
|
|
525
|
+
//
|
|
526
|
+
// This function only USES validated fields, so it takes the plain lenient read
|
|
527
|
+
// and never touches `readIntentCheckpointLenient`'s raw rejections: the value
|
|
528
|
+
// returned is one the schema accepts, and `isClosingAction` / `customCommandOf`
|
|
529
|
+
// are the point-of-use checks on top of it.
|
|
530
|
+
const checkpoint = await readIntentCheckpoint(join(artifactsDir, "intent_checkpoint.json"), { lenient: true });
|
|
451
531
|
if (!checkpoint || checkpoint.confirmed_by !== "host")
|
|
452
532
|
return { action: "none" };
|
|
453
533
|
const chosen = checkpoint.closing_action;
|
|
@@ -555,8 +635,8 @@ function carryForwardMatchingItems(previous, replanned) {
|
|
|
555
635
|
// A still-pending item carries no work to preserve, so it is re-minted from
|
|
556
636
|
// the fresh plan rather than carried forward. (This test used to also admit
|
|
557
637
|
// a pending item that held an `item_spec`; the document phase that produced
|
|
558
|
-
// one was dissolved
|
|
559
|
-
//
|
|
638
|
+
// one was dissolved and the field is gone, so the second condition could
|
|
639
|
+
// never be true and is not restated here.)
|
|
560
640
|
if (!previousFinding || !previousItem) {
|
|
561
641
|
continue;
|
|
562
642
|
}
|
|
@@ -619,6 +699,29 @@ async function forceReplanFromExistingIntake(root, artifactsDir, previous, store
|
|
|
619
699
|
await store.saveState(carried);
|
|
620
700
|
return carried;
|
|
621
701
|
}
|
|
702
|
+
/**
|
|
703
|
+
* The BLOCKING friction close-out step for a run whose walk is still owed.
|
|
704
|
+
*
|
|
705
|
+
* Emitted from `handleClosing` BEFORE the close touches disk, so the record the
|
|
706
|
+
* host is told to write (`triage.recordPath`) is the plan-keyed one this very
|
|
707
|
+
* decision just materialized — and so the run's identity in that path is the
|
|
708
|
+
* plan id, not a fallback. The step is a `closing`-phase gate: `next-step`
|
|
709
|
+
* re-decides the same walk on the next call, and only a disposed walk lets the
|
|
710
|
+
* close proceed.
|
|
711
|
+
*/
|
|
712
|
+
async function buildFrictionWalkStep(root, artifactsDir, state, triage) {
|
|
713
|
+
return writeCurrentStep({
|
|
714
|
+
stepKind: "close_run",
|
|
715
|
+
status: "ready",
|
|
716
|
+
runId: requireStateRunId(state),
|
|
717
|
+
repoRoot: root,
|
|
718
|
+
artifactsDir,
|
|
719
|
+
prompt: `# Remediation Run Friction Triage\n\nComplete the friction close-out walk before the run may close.\n${buildFrictionTriageBlock(triage)}`,
|
|
720
|
+
allowedCommands: [],
|
|
721
|
+
stopCondition: "Complete friction triage (write dispositions and open_observations), then call next-step again.",
|
|
722
|
+
artifactPaths: { friction_record: triage.recordPath },
|
|
723
|
+
});
|
|
724
|
+
}
|
|
622
725
|
async function presentReportStep(root, artifactsDir, state) {
|
|
623
726
|
const reportPath = join(dirname(artifactsDir), "remediation-report.md");
|
|
624
727
|
// Terminal friction-TRIAGE close-out, folded into present_report (single-sourced in
|
|
@@ -626,13 +729,39 @@ async function presentReportStep(root, artifactsDir, state) {
|
|
|
626
729
|
// event + reflection is disposed AND ≥1 open observation written. Never trivially
|
|
627
730
|
// satisfied by an empty event set — the host must actively confirm the friction state.
|
|
628
731
|
//
|
|
629
|
-
//
|
|
630
|
-
//
|
|
631
|
-
//
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
732
|
+
// NO FRICTION RECORD IS EVER MINTED HERE. The decision was made — and the
|
|
733
|
+
// record, under the run's plan-keyed path, was walked — before the close
|
|
734
|
+
// archived it: `handleClosing` consults `decideRemediateFrictionCloseout`
|
|
735
|
+
// against the LIVE state and short-circuits the close until the walk is
|
|
736
|
+
// disposed. So ON THE GREEN PATH — the close ran to `complete`, archived the
|
|
737
|
+
// run and removed the artifacts dir — the walk was already completed when the
|
|
738
|
+
// close started, the plan-keyed record left with the other deliverables, and
|
|
739
|
+
// all that is left is to RENDER the already-recorded walk for the host.
|
|
740
|
+
//
|
|
741
|
+
// NOT-GREEN IS THE OTHER HALF, and it is not "mint nothing": a close that
|
|
742
|
+
// returned a non-`complete` state PRESERVES the artifacts dir, so the record
|
|
743
|
+
// this step decides remains where the run wrote it — the caller reaches here
|
|
744
|
+
// with the saved state still carrying its plan id, `decideFrictionTriage`
|
|
745
|
+
// materializes (or re-reads) that same plan-keyed file, and the walk is
|
|
746
|
+
// rendered from the record that is still in place.
|
|
747
|
+
//
|
|
748
|
+
// It is decided — and so materialized — ONLY when the state names a run. The
|
|
749
|
+
// guard is the plan id, not the artifacts dir: the dir is not evidence of
|
|
750
|
+
// anything here, since `decideNextStepLoop` mkdirs it unconditionally on entry,
|
|
751
|
+
// `RunLogger.event` mkdirs it again for `run.log.jsonl`, and `writeJsonFile`
|
|
752
|
+
// mkdirs any parent it is handed. So a dir-existence test is true on every
|
|
753
|
+
// path, including a run whose state the close deleted. Guarding on the dir was
|
|
754
|
+
// the 2026-08-24 defect: the decider ran with a null state, took a fallback
|
|
755
|
+
// key, and because `decideFrictionTriage` MATERIALIZES the record it is given,
|
|
756
|
+
// minted a fresh EMPTY record inside the directory the close had just deleted —
|
|
757
|
+
// re-blocking the run on the record it had created. `stateRunId` now answers
|
|
758
|
+
// `null` for a planless state and this call therefore decides nothing.
|
|
759
|
+
//
|
|
760
|
+
// A `complete` state reaching here is a run that never ran the close walk (a
|
|
761
|
+
// re-delivery of an already-complete run, whose plan the state still carries),
|
|
762
|
+
// so the walk is genuinely still owed and deciding it here is correct — it
|
|
763
|
+
// renders as the blocking step. Only a planless state renders nothing.
|
|
764
|
+
const triage = await decideRemediateFrictionCloseout(artifactsDir, state);
|
|
636
765
|
const frictionBlock = triage ? buildFrictionTriageBlock(triage) : "";
|
|
637
766
|
const isBlocked = triage?.action === "dispose";
|
|
638
767
|
return writeCurrentStep({
|
|
@@ -683,32 +812,32 @@ function currentHostBoundaryState(state) {
|
|
|
683
812
|
*
|
|
684
813
|
* So:
|
|
685
814
|
*
|
|
686
|
-
* - **Phase 1, UNLOCKED.** Snapshot the state, capture HEAD
|
|
687
|
-
* distinct required-test command exactly once
|
|
688
|
-
* (`precomputeRecoveryTestVerdicts`).
|
|
689
|
-
* after, because a host-authored command that MOVES HEAD would
|
|
690
|
-
* produce verdicts of mixed provenance and go undetected. (The
|
|
691
|
-
* commit shas: it sees HEAD movement, not worktree dirt — a
|
|
692
|
-
* dirties files is invisible to it, which is acceptable
|
|
693
|
-
* corroboration is commit-based.)
|
|
694
|
-
* - **Phase 2, LOCKED.** Re-read
|
|
695
|
-
*
|
|
696
|
-
*
|
|
697
|
-
*
|
|
698
|
-
*
|
|
815
|
+
* - **Phase 1, UNLOCKED.** Snapshot the state, capture HEAD and the workload
|
|
816
|
+
* binding, and run every distinct required-test command exactly once
|
|
817
|
+
* (`precomputeRecoveryTestVerdicts`). Both identities are captured BEFORE the
|
|
818
|
+
* spawns, not after, because a host-authored command that MOVES HEAD would
|
|
819
|
+
* otherwise produce verdicts of mixed provenance and go undetected. (The HEAD
|
|
820
|
+
* guard compares commit shas: it sees HEAD movement, not worktree dirt — a
|
|
821
|
+
* command that only dirties files is invisible to it, which is acceptable
|
|
822
|
+
* because phase 2's corroboration is commit-based.)
|
|
823
|
+
* - **Phase 2, LOCKED.** Re-read both identities and abort the whole recovery if
|
|
824
|
+
* either moved — `tree_moved_between_phases` for HEAD,
|
|
825
|
+
* `state_moved_between_phases` for the binding — because the phase-1 verdicts
|
|
826
|
+
* would describe a tree or a frontier that no longer exists, and nothing is
|
|
827
|
+
* accepted or appended. Otherwise ingest with the pre-computed verdicts, which
|
|
828
|
+
* the ingest only READS: in recovery mode it never spawns, and a command
|
|
829
|
+
* missing from the table fails closed.
|
|
699
830
|
*
|
|
700
831
|
* What remains inside the lock is git plumbing (ancestry, ref scan, diff-tree),
|
|
701
832
|
* the ledger append, and the state write — sub-second work, comfortably inside
|
|
702
|
-
* heartbeat coverage. The
|
|
703
|
-
* opens; the operational protocol is still one writer at a time, now
|
|
704
|
-
* a lock that cannot be stolen mid-hold instead of by convention.
|
|
833
|
+
* heartbeat coverage. The two unchanged-identity guards close the gap the phase
|
|
834
|
+
* split opens; the operational protocol is still one writer at a time, now
|
|
835
|
+
* enforced by a lock that cannot be stolen mid-hold instead of by convention.
|
|
705
836
|
*
|
|
706
|
-
*
|
|
707
|
-
*
|
|
708
|
-
*
|
|
709
|
-
*
|
|
710
|
-
* verb. The `state_changed` flag on the returned summary stays authoritative
|
|
711
|
-
* for callers either way.
|
|
837
|
+
* A recovery that changes nothing writes nothing: phase 2 returns the locked
|
|
838
|
+
* store's `SKIP_WRITE` sentinel, which `StateStore.mutate` now honors, so the
|
|
839
|
+
* retry loop of a genuinely-empty recovery no longer replaces `state.json` with
|
|
840
|
+
* byte-identical content on every pass.
|
|
712
841
|
*/
|
|
713
842
|
export async function recoverIngestHostResults(options) {
|
|
714
843
|
const root = resolveRoot(options.root);
|
|
@@ -720,6 +849,7 @@ export async function recoverIngestHostResults(options) {
|
|
|
720
849
|
throw new Error(`No remediation state at ${artifactsDir} — there is nothing to ingest.`);
|
|
721
850
|
}
|
|
722
851
|
const headBeforeTests = await headCommit(root);
|
|
852
|
+
const bindingBeforeTests = workloadBindingIdentity(currentHostBoundaryState(snapshot));
|
|
723
853
|
const requiredTestVerdicts = await precomputeRecoveryTestVerdicts({
|
|
724
854
|
root,
|
|
725
855
|
artifactsDir,
|
|
@@ -740,23 +870,50 @@ export async function recoverIngestHostResults(options) {
|
|
|
740
870
|
throw new Error(`No remediation state at ${artifactsDir} — there is nothing to ingest.`);
|
|
741
871
|
}
|
|
742
872
|
const headNow = await headCommit(root);
|
|
743
|
-
|
|
873
|
+
const bindingNow = workloadBindingIdentity(currentHostBoundaryState(state));
|
|
874
|
+
// TWO identities, because they catch different writers. HEAD moves when the
|
|
875
|
+
// tree does; the workload binding moves when a concurrent state writer
|
|
876
|
+
// settles items or re-mints the workload without committing anything. The
|
|
877
|
+
// verdict table describes the frontier as it was at phase 1, so either
|
|
878
|
+
// change invalidates it — and a stale table is not merely imprecise: the
|
|
879
|
+
// commands it no longer covers read as `required_test_failed`, which
|
|
880
|
+
// attributes a bookkeeping race to the host's work.
|
|
881
|
+
const moved = headNow !== headBeforeTests
|
|
882
|
+
? "tree"
|
|
883
|
+
: bindingNow !== bindingBeforeTests
|
|
884
|
+
? "state"
|
|
885
|
+
: null;
|
|
886
|
+
if (moved !== null) {
|
|
744
887
|
ingested = {
|
|
745
888
|
accepted_count: 0,
|
|
746
889
|
completed_work_item_ids: [],
|
|
747
890
|
pending_work_item_ids: state.host_handoff?.work_item_ids ?? [],
|
|
891
|
+
// This verdict aborts the whole recovery BEFORE any item is read, so
|
|
892
|
+
// there is no per-item observation to report — an empty map is the
|
|
893
|
+
// honest statement of that, not a missing field.
|
|
894
|
+
work_item_outcomes: new Map(),
|
|
748
895
|
issues: [
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
896
|
+
moved === "tree"
|
|
897
|
+
? {
|
|
898
|
+
code: "tree_moved_between_phases",
|
|
899
|
+
message: `HEAD moved from ${headBeforeTests ?? "(none)"} to ${headNow ?? "(none)"} ` +
|
|
900
|
+
"while the required tests were running, so their verdicts no longer describe " +
|
|
901
|
+
"this tree. Nothing was accepted; re-run recover-ingest on a settled tree.",
|
|
902
|
+
}
|
|
903
|
+
: {
|
|
904
|
+
code: "state_moved_between_phases",
|
|
905
|
+
message: "the run's workload binding changed while the required tests were running, " +
|
|
906
|
+
"so their verdicts no longer describe the pending frontier. Nothing was " +
|
|
907
|
+
"accepted; re-run recover-ingest once no other writer is advancing this run.",
|
|
908
|
+
},
|
|
755
909
|
],
|
|
756
910
|
state_changed: false,
|
|
757
911
|
state: currentHostBoundaryState(state),
|
|
758
912
|
};
|
|
759
|
-
|
|
913
|
+
// The lock was taken to WRITE. Nothing changed, so write nothing: the
|
|
914
|
+
// no-op sentinel is what keeps a settled recovery from replacing
|
|
915
|
+
// state.json with byte-identical content on every retry.
|
|
916
|
+
return SKIP_WRITE;
|
|
760
917
|
}
|
|
761
918
|
const outcome = await ingestRemediationHostResults({
|
|
762
919
|
root,
|
|
@@ -769,16 +926,62 @@ export async function recoverIngestHostResults(options) {
|
|
|
769
926
|
throw new Error("Remediation state uses a retired dispatch shape and cannot cross the host handoff boundary.");
|
|
770
927
|
}
|
|
771
928
|
ingested = outcome;
|
|
929
|
+
// A nothing-to-recover pass returns the sentinel, not the state it read: the
|
|
930
|
+
// mutation is a no-op and must not rewrite the file (see StateStore.mutate).
|
|
772
931
|
if (!outcome.state_changed)
|
|
773
|
-
return
|
|
774
|
-
|
|
775
|
-
|
|
932
|
+
return SKIP_WRITE;
|
|
933
|
+
// No `contract_version` strip. The boundary helper below stamps the version
|
|
934
|
+
// onto the state it hands the host handoff, and this used to peel it back
|
|
935
|
+
// off on the way to disk so `state.json` matched what was written before.
|
|
936
|
+
// The STORE now owns that field end to end — it stamps it on read and the
|
|
937
|
+
// write hook validates it — so peeling it here would persist a state
|
|
938
|
+
// without the identity the store just established, and the next read would
|
|
939
|
+
// have to re-invent it.
|
|
940
|
+
return outcome.state;
|
|
776
941
|
});
|
|
942
|
+
// The run moved, so the persisted step contract no longer describes it: it
|
|
943
|
+
// names work this ingest just resolved, against a workload binding this ingest
|
|
944
|
+
// may have cleared. Invalidate it — but only when something actually changed,
|
|
945
|
+
// because a no-op recovery must leave the tree byte-identical (which is the
|
|
946
|
+
// same reason the mutation above writes nothing).
|
|
947
|
+
if (ingested.state_changed) {
|
|
948
|
+
await invalidateStepContracts(artifactsDir);
|
|
949
|
+
}
|
|
777
950
|
return ingested;
|
|
778
951
|
}
|
|
952
|
+
/**
|
|
953
|
+
* Render the host-facing result status for an ingest, split by outcome.
|
|
954
|
+
*
|
|
955
|
+
* Takes the whole summary rather than just its issues, because the split needs
|
|
956
|
+
* BOTH halves: which items were refused (from the issues) and which landed
|
|
957
|
+
* without a result (from `work_item_outcomes`, where the run's corroborated
|
|
958
|
+
* commit for the item is what separates that case from plain unfinished work).
|
|
959
|
+
*/
|
|
960
|
+
function remediationResultDiagnostics(ingested) {
|
|
961
|
+
const describe = (issue) => `- ${issue.work_item_id ? `\`${issue.work_item_id}\`: ` : ""}${issue.message}${issue.result_path ? ` (\`${issue.result_path}\`)` : ""}`;
|
|
962
|
+
const section = (heading, lines) => lines.length === 0 ? "" : `\n${heading}\n\n${lines.join("\n")}\n`;
|
|
963
|
+
const rejected = ingested.issues.filter((issue) => !isMissingObservation(issue));
|
|
964
|
+
const landedWithoutResult = [...ingested.work_item_outcomes]
|
|
965
|
+
.filter(([, outcome]) => outcome === "missing_result_with_commit")
|
|
966
|
+
.map(([id]) => id)
|
|
967
|
+
.sort(compareCodeUnits);
|
|
968
|
+
const notYetWritten = ingested.issues.filter((issue) => isMissingObservation(issue));
|
|
969
|
+
const body = section("## Results already landed, whose result file is missing", landedWithoutResult.map((id) => `- \`${id}\`: this item's edits are IN this repository — a corroborated commit landed ` +
|
|
970
|
+
`for it and its changed files are recorded — but no result file exists at its bound ` +
|
|
971
|
+
`\`result_path\`. This is PARTIAL PROGRESS, not absent work: write the result for the ` +
|
|
972
|
+
`commit that is already there rather than redoing the edit.`)) +
|
|
973
|
+
section("## Result status requiring attention", rejected.map(describe)) +
|
|
974
|
+
section("## Results not yet written", notYetWritten.map(describe));
|
|
975
|
+
if (body === "")
|
|
976
|
+
return "";
|
|
977
|
+
return (body +
|
|
978
|
+
"\nThe workload was restored from its tool-owned digest when necessary. Repair or\n" +
|
|
979
|
+
"complete only the named result files; do not rewrite the workload or its\n" +
|
|
980
|
+
"baseline.\n");
|
|
981
|
+
}
|
|
779
982
|
async function buildImplementDispatchStep(ctx) {
|
|
780
983
|
const { root, artifactsDir, state, store, runLogger } = ctx;
|
|
781
|
-
const runId =
|
|
984
|
+
const runId = requireStateRunId(state);
|
|
782
985
|
const boundaryState = currentHostBoundaryState(state);
|
|
783
986
|
const ingested = await ingestRemediationHostResults({
|
|
784
987
|
root,
|
|
@@ -815,9 +1018,10 @@ async function buildImplementDispatchStep(ctx) {
|
|
|
815
1018
|
});
|
|
816
1019
|
}
|
|
817
1020
|
if (ingested.state_changed) {
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
1021
|
+
// Same as the recovery verb above: the version is the store's to write,
|
|
1022
|
+
// not a boundary decoration to peel off before persisting.
|
|
1023
|
+
await store.saveState(ingested.state);
|
|
1024
|
+
return { kind: "transition", state: ingested.state };
|
|
821
1025
|
}
|
|
822
1026
|
const baselineCommit = await headCommit(root);
|
|
823
1027
|
if (!baselineCommit) {
|
|
@@ -844,23 +1048,21 @@ async function buildImplementDispatchStep(ctx) {
|
|
|
844
1048
|
// `FrictionRunLinks`). Each reference is sourced from the envelope that owns it — the
|
|
845
1049
|
// persisted handoff record for the dispatch run, the step contract's own run id for
|
|
846
1050
|
// the step — never synthesized from the other.
|
|
847
|
-
await linkFrictionRunIds(artifactsDir,
|
|
1051
|
+
await linkFrictionRunIds(artifactsDir, requireStateRunId(state), { step_run_id: runId, dispatch_run_id: handoff.handoff_record.run_id }, "remediate-code");
|
|
848
1052
|
// The issues were logged above, before any exit path. What follows is the
|
|
849
1053
|
// RENDER — a channel that survives exactly as long as the host reads this one
|
|
850
1054
|
// step, and that is reached only when nothing was accepted.
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
baseline.
|
|
863
|
-
`;
|
|
1055
|
+
//
|
|
1056
|
+
// THREE STATES, THREE SECTIONS, because they have three different remedies and
|
|
1057
|
+
// a reader must not have to parse prose to tell them apart (the measured
|
|
1058
|
+
// friction: a host parser special-casing "no result file exists"):
|
|
1059
|
+
// rejected — something was written and refused; repair it.
|
|
1060
|
+
// missing + commit — the edits LANDED but no result exists; write the
|
|
1061
|
+
// result FOR THE COMMIT THAT IS ALREADY THERE.
|
|
1062
|
+
// missing, no commit — nothing yet; write it when the work is done.
|
|
1063
|
+
// The classification is on CODES, never message text, so rewording a message
|
|
1064
|
+
// cannot move an item between sections.
|
|
1065
|
+
const diagnostics = remediationResultDiagnostics(ingested);
|
|
864
1066
|
const nextCommand = loaderCommand("next-step");
|
|
865
1067
|
return {
|
|
866
1068
|
kind: "emit",
|
|
@@ -881,7 +1083,7 @@ It contains the complete, dependency-safe current frontier. Complete every work
|
|
|
881
1083
|
item and write its exact prompt-bound result contract to its \`result_path\`.
|
|
882
1084
|
The host owns execution choices, grouping, and concurrency; audit-tools performs
|
|
883
1085
|
no launch, routing, or quota decision. Do not start a later dependency level.
|
|
884
|
-
${
|
|
1086
|
+
${diagnostics}
|
|
885
1087
|
|
|
886
1088
|
After all completed changes are merged and their result files exist, run:
|
|
887
1089
|
|
|
@@ -948,9 +1150,18 @@ async function handleComplete(root, artifactsDir, state) {
|
|
|
948
1150
|
* event AND every surfaced agent-feedback reflection carries a disposition; an empty
|
|
949
1151
|
* set (zero events AND zero reflections) is trivially "disposed". Keyed only off
|
|
950
1152
|
* `(artifactsDir, runId)`; never coupled to any repo's backlog doc.
|
|
1153
|
+
*
|
|
1154
|
+
* A state with NO plan id can name no run, and since the decision MATERIALIZES
|
|
1155
|
+
* the record it keys, guessing a key there would mint one. It returns `null`
|
|
1156
|
+
* instead — "there is no run here to close out", which is the truthful answer
|
|
1157
|
+
* for a state whose plan is gone. Callers that hold the run's plan get a
|
|
1158
|
+
* decision; callers past the run boundary get nothing to render.
|
|
951
1159
|
*/
|
|
952
1160
|
export async function decideRemediateFrictionCloseout(artifactsDir, state) {
|
|
953
|
-
|
|
1161
|
+
const runId = stateRunId(state);
|
|
1162
|
+
if (!runId)
|
|
1163
|
+
return null;
|
|
1164
|
+
return decideFrictionTriage(artifactsDir, runId, "remediate-code");
|
|
954
1165
|
}
|
|
955
1166
|
/**
|
|
956
1167
|
* Copy an unusable extracted plan somewhere recoverable and PROVE the copy
|
|
@@ -1000,6 +1211,7 @@ async function handlePendingExtractedPlan(root, artifactsDir, existing, extracte
|
|
|
1000
1211
|
// captured into the artifact dir; before this, the durable tree held no trace
|
|
1001
1212
|
// that a plan had been destroyed or that findings had been dropped.
|
|
1002
1213
|
runLogger) {
|
|
1214
|
+
// <!-- comment-symbol-exempt: names deliberately-retired symbols; this block records that history -->
|
|
1003
1215
|
// The discard-and-re-extract recovery below covers EXACTLY the region whose
|
|
1004
1216
|
// failures mean the extracted PLAN is unusable: normalization and grounding.
|
|
1005
1217
|
// It deliberately stops there. Everything after it — sizing, the dirty
|
|
@@ -1018,7 +1230,7 @@ runLogger) {
|
|
|
1018
1230
|
let mergeMap;
|
|
1019
1231
|
let grounding;
|
|
1020
1232
|
try {
|
|
1021
|
-
({ plan, sourceFindings, mergeMap } = normalizeExtractedPlan(extractedPlan,
|
|
1233
|
+
({ plan, sourceFindings, mergeMap } = normalizeExtractedPlan(root, extractedPlan,
|
|
1022
1234
|
// Persisted by the confirm step; planning spawns nothing (the
|
|
1023
1235
|
// backend-independent planning contract), so it never detects here.
|
|
1024
1236
|
(await readProjectFacts(artifactsDir)) ?? neutralProjectFacts()));
|
|
@@ -1553,7 +1765,7 @@ async function handleReadyIntakeContractPipeline(root, artifactsDir, options, ru
|
|
|
1553
1765
|
const auditFindings = await readAuditFindingsOnce();
|
|
1554
1766
|
const originals = extractAuditFindings(auditFindings);
|
|
1555
1767
|
if (originals.length > 0) {
|
|
1556
|
-
const checkpoint = await
|
|
1768
|
+
const checkpoint = await readIntentCheckpoint(join(artifactsDir, "intent_checkpoint.json"));
|
|
1557
1769
|
const filter = await runFindingFilterPass(originals, {
|
|
1558
1770
|
root,
|
|
1559
1771
|
checkpoint: checkpoint ?? undefined,
|
|
@@ -2212,8 +2424,8 @@ async function handlePlanning(root, artifactsDir, state, store) {
|
|
|
2212
2424
|
if (halt)
|
|
2213
2425
|
return { kind: "emit", step: halt };
|
|
2214
2426
|
}
|
|
2215
|
-
// Document phase dissolved
|
|
2216
|
-
//
|
|
2427
|
+
// Document phase dissolved: planning transitions directly to implementing,
|
|
2428
|
+
// and the host workload reads finding context directly.
|
|
2217
2429
|
const implementBlocks = dispatchFrontier(state);
|
|
2218
2430
|
if (implementBlocks.length > 0) {
|
|
2219
2431
|
if (state.plan) {
|
|
@@ -2331,7 +2543,7 @@ function finalGateDisabledReason(options) {
|
|
|
2331
2543
|
* were indistinguishable after the fact.
|
|
2332
2544
|
*/
|
|
2333
2545
|
async function recordFinalGateOutcome(ctx) {
|
|
2334
|
-
const
|
|
2546
|
+
const verdict = carriesGateVerdict(ctx.outcome);
|
|
2335
2547
|
await writeFinalGateOutcomeRecord(ctx.artifactsDir, {
|
|
2336
2548
|
scope: ctx.scope,
|
|
2337
2549
|
outcome: ctx.outcome,
|
|
@@ -2346,9 +2558,10 @@ async function recordFinalGateOutcome(ctx) {
|
|
|
2346
2558
|
note: `${ctx.gateKey} outcome=${ctx.outcome} ` +
|
|
2347
2559
|
// "n/a", never "true": a gate that ran nothing has no verdict, and the
|
|
2348
2560
|
// durable record it is written beside carries `passed: null` for the
|
|
2349
|
-
// same reason.
|
|
2350
|
-
|
|
2351
|
-
`
|
|
2561
|
+
// same reason. A `history` outcome DOES carry a verdict — a judge ruled
|
|
2562
|
+
// on this exact tree — so it prints its verdict like an executed one.
|
|
2563
|
+
`passed=${verdict ? String(ctx.passed) : "n/a"} ` +
|
|
2564
|
+
`commands=${verdict ? String(ctx.commandsRun) : "0"}` +
|
|
2352
2565
|
(ctx.reason === undefined ? "" : ` reason=${ctx.reason}`),
|
|
2353
2566
|
...(ctx.durationMs === undefined ? {} : { duration_ms: ctx.durationMs }),
|
|
2354
2567
|
});
|
|
@@ -2372,26 +2585,56 @@ async function recordFinalGateOutcome(ctx) {
|
|
|
2372
2585
|
* the captured output, which stays in the artifact where a multi-KB suite log
|
|
2373
2586
|
* costs nothing.
|
|
2374
2587
|
*
|
|
2375
|
-
* COST OF THE PAUSE
|
|
2376
|
-
*
|
|
2377
|
-
*
|
|
2378
|
-
*
|
|
2379
|
-
* the
|
|
2380
|
-
*
|
|
2588
|
+
* COST OF THE PAUSE. The gate's verdict is cached against the TREE CONTENT, so
|
|
2589
|
+
* re-entering a boundary with the tree untouched serves the recorded verdict —
|
|
2590
|
+
* the pause re-emits from cache without spawning a builder or a suite. A green
|
|
2591
|
+
* on a fixed tree, and a re-run on a tree that MOVED, both go to the floor as
|
|
2592
|
+
* before: the cache is an equality check on content, never a counter and never a
|
|
2593
|
+
* reason to skip a tree nobody judged.
|
|
2381
2594
|
*/
|
|
2382
2595
|
async function emitFinalGateRedStep(ctx) {
|
|
2383
2596
|
const { root, artifactsDir, state, scope, gate, runLogger } = ctx;
|
|
2384
2597
|
const failed = gate.results.find((r) => !r.passed);
|
|
2385
|
-
const recordPath = await writeFinalGateRedRecord(artifactsDir, scope, failed
|
|
2598
|
+
const recordPath = await writeFinalGateRedRecord(artifactsDir, scope, failed, {
|
|
2599
|
+
root,
|
|
2600
|
+
state,
|
|
2601
|
+
});
|
|
2386
2602
|
const failingCommand = failed
|
|
2387
2603
|
? `${failed.argv.join(" ")} (exit ${String(failed.exit_code)})`
|
|
2388
2604
|
: "(the gate reported no failing command)";
|
|
2605
|
+
// Read the attribution back OFF THE RECORD rather than recomputing it: the
|
|
2606
|
+
// record is the durable statement, and a prompt that derived its own answer
|
|
2607
|
+
// from a fresh git read could disagree with the artifact the same step points
|
|
2608
|
+
// at. Absent (the record was written by the no-state path, or attribution
|
|
2609
|
+
// chose not to run) means no verdict is asserted, which is exactly what the
|
|
2610
|
+
// prompt then says.
|
|
2611
|
+
const attribution = (await readOptionalJsonFile(recordPath))?.attribution;
|
|
2612
|
+
const attributionBlock = renderGateAttribution(attribution);
|
|
2389
2613
|
runLogger.event({
|
|
2390
2614
|
phase: "next-step",
|
|
2391
2615
|
kind: "outcome",
|
|
2392
2616
|
obligation: state.status,
|
|
2393
|
-
note: `final_gate_red scope=${scope} command=${failed ? failed.argv.join(" ") : "unknown"}
|
|
2617
|
+
note: `final_gate_red scope=${scope} command=${failed ? failed.argv.join(" ") : "unknown"}` +
|
|
2618
|
+
(attribution ? ` attribution=${attribution.verdict}` : ""),
|
|
2394
2619
|
});
|
|
2620
|
+
// THE BINDING, named in the prompt. The verdict this pause repeats is cached
|
|
2621
|
+
// against the CONTENT of the tree, so an operator who reads "the suite is
|
|
2622
|
+
// still red" and fixes something the run cannot see — or, worse, who assumes
|
|
2623
|
+
// the message will change on its own — is left looping on a red that is being
|
|
2624
|
+
// SERVED, not observed. State the id and state exactly what moves it: any
|
|
2625
|
+
// edit to a non-ignored file outside the run's own artifacts. This is the
|
|
2626
|
+
// same carve-out `worktreeContentId` applies, said in the operator's terms.
|
|
2627
|
+
const bindingBlock = ctx.tree === undefined
|
|
2628
|
+
? "Binding: this gate re-runs the floor on every arrival here, so this red\n" +
|
|
2629
|
+
"describes the tree as it stands right now."
|
|
2630
|
+
: ctx.tree === null
|
|
2631
|
+
? "Binding: no tree content id could be taken, so this red is NOT cached —\n" +
|
|
2632
|
+
"the floor will run again on your next next-step whatever you change."
|
|
2633
|
+
: `Binding: this red is bound to tree \`${ctx.tree}\`. Any edit to a file\n` +
|
|
2634
|
+
`outside \`${AUDIT_TOOLS_DIRNAME}/\` — and outside anything git ignores — moves that\n` +
|
|
2635
|
+
"id, which invalidates the cached verdict and makes the next next-step run\n" +
|
|
2636
|
+
"the WHOLE floor again against what you changed. Editing nothing leaves the\n" +
|
|
2637
|
+
"id identical, so the cached red is served back without spawning anything.";
|
|
2395
2638
|
const nextCommand = loaderCommand("next-step");
|
|
2396
2639
|
return {
|
|
2397
2640
|
kind: "emit",
|
|
@@ -2420,6 +2663,10 @@ A red here is whole-repo and says nothing about which remediation item caused
|
|
|
2420
2663
|
it — it may not be this run's doing at all (a commit landed alongside the run is
|
|
2421
2664
|
enough). So this is a PAUSE, not a verdict on the work.
|
|
2422
2665
|
|
|
2666
|
+
${attributionBlock}
|
|
2667
|
+
|
|
2668
|
+
${bindingBlock}
|
|
2669
|
+
|
|
2423
2670
|
Fix the failing command — or confirm it was already broken independently of this
|
|
2424
2671
|
run — then run:
|
|
2425
2672
|
|
|
@@ -2428,10 +2675,11 @@ run — then run:
|
|
|
2428
2675
|
The gate re-runs from scratch. The moment it is green the run continues exactly
|
|
2429
2676
|
where it left off.
|
|
2430
2677
|
|
|
2431
|
-
Re-run it DELIBERATELY, not on a timer
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2678
|
+
Re-run it DELIBERATELY, not on a timer. The gate's verdict is cached against the
|
|
2679
|
+
content of the tree, so a re-run with nothing changed serves the recorded verdict
|
|
2680
|
+
without spawning anything — and the moment you fix something the tree moves, the
|
|
2681
|
+
cache misses, and the whole floor (a full build plus the suite, minutes, holding
|
|
2682
|
+
the run's phase lock) runs against your change. Fix something first, then re-run.
|
|
2435
2683
|
`,
|
|
2436
2684
|
allowedCommands: [nextCommand],
|
|
2437
2685
|
stopCondition: "Stop. Make the repository suite green, then re-run next-step to resume the run.",
|
|
@@ -2481,19 +2729,87 @@ async function runPhaseBoundaryGate(ctx) {
|
|
|
2481
2729
|
});
|
|
2482
2730
|
return null;
|
|
2483
2731
|
}
|
|
2732
|
+
// The TREE this verdict will be about. Taken BEFORE the floor runs so the
|
|
2733
|
+
// cached verdict describes the state the floor actually saw; taken ONCE so
|
|
2734
|
+
// the identity written and the identity read back cannot be two derivations
|
|
2735
|
+
// that disagree.
|
|
2736
|
+
//
|
|
2737
|
+
// A boundary that re-dispatches work will get a different id on the next call
|
|
2738
|
+
// and the floor re-runs — which is correct: the tree it certified is gone.
|
|
2739
|
+
const tree = await worktreeContentId(root);
|
|
2740
|
+
const gateKey = `phase_boundary_gate phase=${phase}`;
|
|
2741
|
+
// THE CACHE. The fold re-enters this boundary on every next-step taken before
|
|
2742
|
+
// the next phase dispatches, and the floor is build + typecheck + the whole
|
|
2743
|
+
// suite — minutes, holding the phase lock. Re-running it on a tree that cannot
|
|
2744
|
+
// have changed since the last verdict buys nothing: the answer is already
|
|
2745
|
+
// known and was already recorded. A HIT is therefore a full substitute,
|
|
2746
|
+
// including for a RED one (see {@link readFinalGateVerdict} — the pause is
|
|
2747
|
+
// rebuilt from the cached results rather than re-derived).
|
|
2748
|
+
const cached = await readFinalGateVerdict(artifactsDir, scope, tree);
|
|
2749
|
+
if (cached !== undefined) {
|
|
2750
|
+
// Recorded as a distinct outcome from a real run: the judge is `history`,
|
|
2751
|
+
// not a spawned command, and `commands_run` counts what HISTORY held, never
|
|
2752
|
+
// what this call executed. `passed` is echoed unchanged, so a cached green
|
|
2753
|
+
// still reads green and a cached red still reads red.
|
|
2754
|
+
await recordFinalGateOutcome({
|
|
2755
|
+
artifactsDir,
|
|
2756
|
+
state,
|
|
2757
|
+
scope,
|
|
2758
|
+
gateKey,
|
|
2759
|
+
runLogger,
|
|
2760
|
+
outcome: "history",
|
|
2761
|
+
passed: cached.passed,
|
|
2762
|
+
commandsRun: cached.results.length,
|
|
2763
|
+
reason: `a verdict for this exact tree content is already recorded (scope "${cached.scope}", ` +
|
|
2764
|
+
`recorded_at ${cached.recorded_at}); the floor was NOT re-run because the tree it ` +
|
|
2765
|
+
"would run against has not changed",
|
|
2766
|
+
});
|
|
2767
|
+
if (cached.passed)
|
|
2768
|
+
return null; // cached green (or scope-out) → dispatch
|
|
2769
|
+
// Cached RED. The run has not progressed since that verdict — the pause
|
|
2770
|
+
// mutates nothing — so re-entering it is the same pause, rebuilt from the
|
|
2771
|
+
// cached command results so the record keeps its failing command, exit code
|
|
2772
|
+
// and output tail.
|
|
2773
|
+
return emitFinalGateRedStep({
|
|
2774
|
+
root,
|
|
2775
|
+
artifactsDir,
|
|
2776
|
+
state,
|
|
2777
|
+
scope,
|
|
2778
|
+
gate: {
|
|
2779
|
+
passed: false,
|
|
2780
|
+
results: cached.results,
|
|
2781
|
+
outcome: cached.outcome,
|
|
2782
|
+
scoped_out: cached.scoped_out,
|
|
2783
|
+
runtime_residual: RUNTIME_RESIDUAL_DECLARATION,
|
|
2784
|
+
},
|
|
2785
|
+
// The RECORD's own tree, not the freshly-measured one: the prompt must
|
|
2786
|
+
// name the identity the cached verdict is actually bound to, which is the
|
|
2787
|
+
// one readFinalGateVerdict just matched on.
|
|
2788
|
+
tree: cached.tree,
|
|
2789
|
+
runLogger,
|
|
2790
|
+
});
|
|
2791
|
+
}
|
|
2484
2792
|
const gateStart = Date.now();
|
|
2485
2793
|
runLogger.event({
|
|
2486
2794
|
phase: "next-step",
|
|
2487
2795
|
kind: "executor_start",
|
|
2488
2796
|
obligation: state.status,
|
|
2489
|
-
note:
|
|
2797
|
+
note: gateKey,
|
|
2490
2798
|
});
|
|
2491
2799
|
const gate = await runToolOwnedFinalGate(root, { runner: options.finalGateRunner });
|
|
2800
|
+
await writeFinalGateVerdict(artifactsDir, {
|
|
2801
|
+
scope,
|
|
2802
|
+
tree,
|
|
2803
|
+
passed: gate.passed,
|
|
2804
|
+
scoped_out: gate.scoped_out,
|
|
2805
|
+
outcome: gate.outcome,
|
|
2806
|
+
results: gate.results,
|
|
2807
|
+
});
|
|
2492
2808
|
await recordFinalGateOutcome({
|
|
2493
2809
|
artifactsDir,
|
|
2494
2810
|
state,
|
|
2495
2811
|
scope,
|
|
2496
|
-
gateKey
|
|
2812
|
+
gateKey,
|
|
2497
2813
|
runLogger,
|
|
2498
2814
|
outcome: gate.outcome,
|
|
2499
2815
|
passed: gate.passed,
|
|
@@ -2513,6 +2829,9 @@ async function runPhaseBoundaryGate(ctx) {
|
|
|
2513
2829
|
state,
|
|
2514
2830
|
scope,
|
|
2515
2831
|
gate,
|
|
2832
|
+
// The id taken BEFORE the floor ran, which is what writeFinalGateVerdict
|
|
2833
|
+
// just recorded — so the prompt names the binding the cache will match on.
|
|
2834
|
+
tree,
|
|
2516
2835
|
runLogger,
|
|
2517
2836
|
});
|
|
2518
2837
|
}
|
|
@@ -2557,6 +2876,10 @@ async function handleAllTerminalTransition(root, artifactsDir, state, store, opt
|
|
|
2557
2876
|
// one at a phase boundary, so it gets the same answer: record and pause.
|
|
2558
2877
|
// The run does NOT advance to `closing` — closing on a red would write a
|
|
2559
2878
|
// report claiming an outcome the suite never corroborated.
|
|
2879
|
+
// No `tree` here on purpose: this funnel caches nothing (it runs the floor
|
|
2880
|
+
// on every arrival), so there is no verdict record for a red to be bound
|
|
2881
|
+
// to, and the prompt says exactly that instead of naming an id that would
|
|
2882
|
+
// be re-measured on the next call anyway.
|
|
2560
2883
|
return emitFinalGateRedStep({
|
|
2561
2884
|
root,
|
|
2562
2885
|
artifactsDir,
|
|
@@ -2592,6 +2915,23 @@ async function handleAllTerminalTransition(root, artifactsDir, state, store, opt
|
|
|
2592
2915
|
async function handleClosing(root, artifactsDir, state, runLogger, store) {
|
|
2593
2916
|
const closeStart = Date.now();
|
|
2594
2917
|
runLogger.event({ phase: "next-step", kind: "executor_start", obligation: state.status, note: "close" });
|
|
2918
|
+
// THE FRICTION WALK IS DECIDED HERE, BEFORE THE CLOSE TOUCHES DISK.
|
|
2919
|
+
//
|
|
2920
|
+
// `runClosePhase` ends by archiving the run's friction record into the
|
|
2921
|
+
// promoted deliverables and deleting the artifacts dir. Both the record and
|
|
2922
|
+
// the state's plan id — the key that names it — are gone after that, so this
|
|
2923
|
+
// is the last moment a decision can name the run it is closing out. Deciding
|
|
2924
|
+
// here also MATERIALIZES the plan-keyed record, which is what gives the host
|
|
2925
|
+
// a file to append to during the walk.
|
|
2926
|
+
//
|
|
2927
|
+
// An unsatisfied walk short-circuits the close ENTIRELY: no tests, no closing
|
|
2928
|
+
// action, no archive, no removal. The run stays open on the plan-keyed record
|
|
2929
|
+
// and is emitted as the blocking friction step; once disposed, the next
|
|
2930
|
+
// `next-step` re-decides it as satisfied and falls through to a real close.
|
|
2931
|
+
const frictionTriage = await decideRemediateFrictionCloseout(artifactsDir, state);
|
|
2932
|
+
if (frictionTriage && frictionTriage.action !== "disposed") {
|
|
2933
|
+
return { kind: "emit", step: await buildFrictionWalkStep(root, artifactsDir, state, frictionTriage) };
|
|
2934
|
+
}
|
|
2595
2935
|
const closed = await runClosePhase(state, { root, artifactsDir }, runLogger);
|
|
2596
2936
|
runLogger.event({ phase: "next-step", kind: "executor_end", obligation: state.status, note: "close", duration_ms: Date.now() - closeStart });
|
|
2597
2937
|
if (closed.status !== "complete") {
|
|
@@ -2602,10 +2942,10 @@ async function handleClosing(root, artifactsDir, state, runLogger, store) {
|
|
|
2602
2942
|
// Close-complete CROSSES the engine boundary: `complete` is a pre-intake
|
|
2603
2943
|
// obligation, unreachable from a main-engine transition. Emit the durable
|
|
2604
2944
|
// report directly, passing exactly what the original recursion reloaded — the
|
|
2605
|
-
// artifact dir is DELETED on a fully-green close (reload → null
|
|
2606
|
-
//
|
|
2607
|
-
// saved complete state → its plan_id). `store.loadState()`
|
|
2608
|
-
// present_report is identical to the cascade.
|
|
2945
|
+
// artifact dir is DELETED on a fully-green close (reload → null, and a null
|
|
2946
|
+
// state renders no friction block) and PRESERVED on a not-green complete
|
|
2947
|
+
// (reload → the saved complete state → its plan_id). `store.loadState()`
|
|
2948
|
+
// reproduces both, so present_report is identical to the cascade.
|
|
2609
2949
|
// (Regression-locked in next-step-implement-dispatch.)
|
|
2610
2950
|
return {
|
|
2611
2951
|
kind: "emit",
|
|
@@ -2846,8 +3186,21 @@ async function buildConfirmIntentStep(ctx) {
|
|
|
2846
3186
|
const nextCommand = loaderCommand("next-step");
|
|
2847
3187
|
const checkpointPath = join(artifactsDir, "intent_checkpoint.json");
|
|
2848
3188
|
// Read the pre-drafted checkpoint if one exists (confirmed_by: "draft").
|
|
2849
|
-
|
|
3189
|
+
//
|
|
3190
|
+
// This is the GATE, and it reads LENIENTLY on purpose: a checkpoint whose
|
|
3191
|
+
// `closing_action` is outside the vocabulary must reach the refusal below,
|
|
3192
|
+
// where the prompt names the offending value and the legal set. A strict read
|
|
3193
|
+
// would replace that affordance with a zod error. Every field consumed here as
|
|
3194
|
+
// a VALUE is still checked by name (`isClosingAction`, `customCommandOf`).
|
|
3195
|
+
//
|
|
3196
|
+
// The REFUSED values come from `rejected`, never from `draft`: the returned
|
|
3197
|
+
// checkpoint is schema-valid, so an out-of-vocabulary key is ABSENT from it
|
|
3198
|
+
// (see `parseIntentCheckpointLenient`). The value the refusal quotes is the one
|
|
3199
|
+
// the host WROTE, which is exactly what `rejected` carries.
|
|
3200
|
+
const draftRead = await readIntentCheckpointLenient(checkpointPath);
|
|
3201
|
+
const draft = draftRead.checkpoint;
|
|
2850
3202
|
const isDraft = draft?.confirmed_by === "draft";
|
|
3203
|
+
const rejectedClosingAction = draftRead.rejected.find((field) => field.key === "closing_action");
|
|
2851
3204
|
// Closing action: DETECTED candidates, presented for the host to choose
|
|
2852
3205
|
// from; the tool never selects one (owner decision 92b0e2dd7cfdc06d).
|
|
2853
3206
|
const facts = await detectProjectFacts(root);
|
|
@@ -2857,7 +3210,9 @@ async function buildConfirmIntentStep(ctx) {
|
|
|
2857
3210
|
const closingSection = renderClosingActionSection(facts);
|
|
2858
3211
|
// A confirmed checkpoint whose closing_action is not in the vocabulary
|
|
2859
3212
|
// re-enters this step by name — a refusal, never a silent default.
|
|
2860
|
-
const rawChoice = draft?.confirmed_by === "host"
|
|
3213
|
+
const rawChoice = draft?.confirmed_by === "host"
|
|
3214
|
+
? (draft.closing_action ?? rejectedClosingAction?.value)
|
|
3215
|
+
: undefined;
|
|
2861
3216
|
const refusal = rawChoice !== undefined && !isClosingAction(rawChoice)
|
|
2862
3217
|
? `> **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
3218
|
: rawChoice === "custom" && customCommandOf(draft) === null
|
|
@@ -3159,10 +3514,12 @@ export const PRE_INTAKE_PRIORITY = [
|
|
|
3159
3514
|
*/
|
|
3160
3515
|
export function buildPreIntakeObligations(ctx, snapshot) {
|
|
3161
3516
|
const { artifactsDir, inputResolution } = ctx;
|
|
3162
|
-
const { existingCheckpoint, resumeAck, entryState, suppliedInputUnchanged, guidanceFileSupplied } = snapshot;
|
|
3517
|
+
const { existingCheckpoint, rejectedCheckpointFields, resumeAck, entryState, suppliedInputUnchanged, guidanceFileSupplied } = snapshot;
|
|
3163
3518
|
const ip = intakePaths(artifactsDir);
|
|
3164
3519
|
const checkpointPath = join(artifactsDir, "intent_checkpoint.json");
|
|
3165
3520
|
const ackPath = join(artifactsDir, "confirm_resume_ack.json");
|
|
3521
|
+
/** The refused `closing_action`, if the schema dropped one — see the `fires` note. */
|
|
3522
|
+
const rejectedClosingAction = rejectedCheckpointFields.find((field) => field.key === "closing_action");
|
|
3166
3523
|
const interpretationPath = join(artifactsDir, INTENT_INTERPRETATION_FILENAME);
|
|
3167
3524
|
const reportPath = join(dirname(artifactsDir), "remediation-report.md");
|
|
3168
3525
|
return [
|
|
@@ -3230,8 +3587,18 @@ export function buildPreIntakeObligations(ctx, snapshot) {
|
|
|
3230
3587
|
// A host-confirmed checkpoint carrying a closing_action outside the
|
|
3231
3588
|
// vocabulary is not a confirmation: the step re-emits naming the value
|
|
3232
3589
|
// (owner decision 92b0e2dd7cfdc06d — never a silent default).
|
|
3590
|
+
//
|
|
3591
|
+
// The refused value comes from `rejectedCheckpointFields` as well as from
|
|
3592
|
+
// the parsed checkpoint, and it must: the lenient read DROPS a key the
|
|
3593
|
+
// schema refused, so an out-of-vocabulary `closing_action` is absent from
|
|
3594
|
+
// `existingCheckpoint` and the read of it alone would answer `undefined`
|
|
3595
|
+
// — "no answer given, so no question" — leaving every branch of `fires`
|
|
3596
|
+
// false and advancing on a checkpoint whose action was never accepted.
|
|
3597
|
+
// `confirmed_by` survives the drop, which is exactly what makes that
|
|
3598
|
+
// silent pass possible; reading the rejection back is what closes it.
|
|
3233
3599
|
const chosenClosingAction = existingCheckpoint?.confirmed_by === "host"
|
|
3234
|
-
? existingCheckpoint.closing_action
|
|
3600
|
+
? (existingCheckpoint.closing_action ??
|
|
3601
|
+
rejectedClosingAction?.value)
|
|
3235
3602
|
: undefined;
|
|
3236
3603
|
const invalidClosingAction = (chosenClosingAction !== undefined && !isClosingAction(chosenClosingAction)) ||
|
|
3237
3604
|
(chosenClosingAction === "custom" && customCommandOf(existingCheckpoint) === null);
|
|
@@ -3501,6 +3868,15 @@ export function buildMainObligations(ctx) {
|
|
|
3501
3868
|
execute: async (state) => {
|
|
3502
3869
|
const s = requireState(state);
|
|
3503
3870
|
s.status = "waiting_for_clarification";
|
|
3871
|
+
// The binding is scoped to `implementing` (INV-RSM-STATE-COMPLETE: the
|
|
3872
|
+
// load gate rejects a `host_handoff` under any other status, and the
|
|
3873
|
+
// store's write hook enforces the same rule). Leaving the status
|
|
3874
|
+
// without clearing the record produced a state the tool itself could
|
|
3875
|
+
// not read back — a state that only escaped because nothing validated
|
|
3876
|
+
// the write path. Dropping it here is also what the field MEANS: the
|
|
3877
|
+
// pending workload it digests is about to be re-prepared for the
|
|
3878
|
+
// answered item.
|
|
3879
|
+
delete s.host_handoff;
|
|
3504
3880
|
await store.saveState(s);
|
|
3505
3881
|
return { kind: "transition", state: s };
|
|
3506
3882
|
},
|
|
@@ -3676,9 +4052,27 @@ async function advanceUnderPhaseLock(deps) {
|
|
|
3676
4052
|
// Pre-read the once-async signals the pre-intake derive()s consume
|
|
3677
4053
|
// synchronously (no transition inside this advance call rewrites either file).
|
|
3678
4054
|
const checkpointPath = join(artifactsDir, "intent_checkpoint.json");
|
|
3679
|
-
|
|
3680
|
-
|
|
4055
|
+
// LENIENT: this read feeds the pre-intake derive()s, whose confirmation
|
|
4056
|
+
// obligation is what REFUSES a malformed checkpoint by name and re-asks. A
|
|
4057
|
+
// strict read here would pre-empt that obligation with a thrown load error.
|
|
4058
|
+
//
|
|
4059
|
+
// Every consumer of the VALUE here uses a validated field (as a value, or as a
|
|
4060
|
+
// presence question on a DIFFERENT field), never quotes an offending one — the
|
|
4061
|
+
// prompt that quotes the refused value is `buildConfirmIntentStep`, which reads
|
|
4062
|
+
// the raw rejections itself. So this site takes the plain lenient read, whose
|
|
4063
|
+
// value is schema-valid.
|
|
4064
|
+
//
|
|
4065
|
+
// The REJECTIONS are threaded beside it rather than discarded, because one
|
|
4066
|
+
// consumer is not a value read: `confirm_intent`'s `fires` asks whether the
|
|
4067
|
+
// checkpoint carries an ACCEPTED answer, and a refused `closing_action` is a
|
|
4068
|
+
// key the lenient read DROPPED — so the parsed value cannot answer for it, and
|
|
4069
|
+
// asking only the parsed value reads a refusal as "no answer given, so no
|
|
4070
|
+
// question". Strict is not the alternative: it would replace the gate's named
|
|
4071
|
+
// refusal with a thrown load error.
|
|
4072
|
+
const checkpointRead = existsSync(checkpointPath)
|
|
4073
|
+
? await readIntentCheckpointLenient(checkpointPath)
|
|
3681
4074
|
: undefined;
|
|
4075
|
+
const existingCheckpoint = checkpointRead?.checkpoint;
|
|
3682
4076
|
const resumeAck = await readOptionalJsonFile(join(artifactsDir, "confirm_resume_ack.json"));
|
|
3683
4077
|
// Whether a supplied `--input` matches the input the existing run was built
|
|
3684
4078
|
// from — so re-passing the same `--input` (the loader does this each next-step)
|
|
@@ -3701,6 +4095,7 @@ async function advanceUnderPhaseLock(deps) {
|
|
|
3701
4095
|
priority: PRE_INTAKE_PRIORITY,
|
|
3702
4096
|
obligations: buildPreIntakeObligations(ctx, {
|
|
3703
4097
|
existingCheckpoint,
|
|
4098
|
+
rejectedCheckpointFields: checkpointRead?.rejected ?? [],
|
|
3704
4099
|
resumeAck,
|
|
3705
4100
|
entryState: state,
|
|
3706
4101
|
suppliedInputUnchanged,
|