audit-tools 0.34.42 → 0.35.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/audit/cli/args.d.ts +6 -0
- package/dist/audit/cli/args.d.ts.map +1 -1
- package/dist/audit/cli/args.js +21 -4
- package/dist/audit/cli/args.js.map +1 -1
- package/dist/audit/cli/auditStep.d.ts +6 -15
- package/dist/audit/cli/auditStep.d.ts.map +1 -1
- package/dist/audit/cli/auditStep.js +1 -1
- package/dist/audit/cli/auditStep.js.map +1 -1
- package/dist/audit/cli/dispatch/hostFanoutGate.d.ts +21 -61
- package/dist/audit/cli/dispatch/hostFanoutGate.d.ts.map +1 -1
- package/dist/audit/cli/dispatch/hostFanoutGate.js +18 -167
- package/dist/audit/cli/dispatch/hostFanoutGate.js.map +1 -1
- package/dist/audit/cli/dispatch/packetFilter.d.ts +2 -2
- package/dist/audit/cli/dispatch/packetFilter.d.ts.map +1 -1
- package/dist/audit/cli/dispatch/packetFilter.js +3 -1
- package/dist/audit/cli/dispatch/packetFilter.js.map +1 -1
- package/dist/audit/cli/dispatch/quotaPool.d.ts +2 -14
- package/dist/audit/cli/dispatch/quotaPool.d.ts.map +1 -1
- package/dist/audit/cli/dispatch/quotaPool.js +16 -6
- package/dist/audit/cli/dispatch/quotaPool.js.map +1 -1
- package/dist/audit/cli/dispatch/tierRouting.d.ts +2 -2
- package/dist/audit/cli/dispatch/tokenUsageObservation.d.ts.map +1 -1
- package/dist/audit/cli/dispatch/tokenUsageObservation.js +10 -2
- package/dist/audit/cli/dispatch/tokenUsageObservation.js.map +1 -1
- package/dist/audit/cli/dispatch.d.ts +14 -3
- package/dist/audit/cli/dispatch.d.ts.map +1 -1
- package/dist/audit/cli/dispatch.js +87 -65
- package/dist/audit/cli/dispatch.js.map +1 -1
- package/dist/audit/cli/forceSynthesisCommand.d.ts.map +1 -1
- package/dist/audit/cli/forceSynthesisCommand.js +9 -1
- package/dist/audit/cli/forceSynthesisCommand.js.map +1 -1
- package/dist/audit/cli/hybridDispatch.d.ts +4 -9
- package/dist/audit/cli/hybridDispatch.d.ts.map +1 -1
- package/dist/audit/cli/hybridDispatch.js +1 -1
- package/dist/audit/cli/hybridDispatch.js.map +1 -1
- package/dist/audit/cli/lineIndex.d.ts +2 -0
- package/dist/audit/cli/lineIndex.d.ts.map +1 -1
- package/dist/audit/cli/lineIndex.js +4 -0
- package/dist/audit/cli/lineIndex.js.map +1 -1
- package/dist/audit/cli/nextStepCommand.d.ts +0 -26
- package/dist/audit/cli/nextStepCommand.d.ts.map +1 -1
- package/dist/audit/cli/nextStepCommand.js +18 -360
- package/dist/audit/cli/nextStepCommand.js.map +1 -1
- package/dist/audit/cli/nextStepHelpers.d.ts +5 -16
- package/dist/audit/cli/nextStepHelpers.d.ts.map +1 -1
- package/dist/audit/cli/nextStepHelpers.js +27 -157
- package/dist/audit/cli/nextStepHelpers.js.map +1 -1
- package/dist/audit/cli/quotaCommand.d.ts.map +1 -1
- package/dist/audit/cli/quotaCommand.js +1 -5
- package/dist/audit/cli/quotaCommand.js.map +1 -1
- package/dist/audit/cli/reviewRun.d.ts.map +1 -1
- package/dist/audit/cli/reviewRun.js +58 -23
- package/dist/audit/cli/reviewRun.js.map +1 -1
- package/dist/audit/cli/rollingAuditDispatch.d.ts +1 -1
- package/dist/audit/cli/semanticReviewStep.d.ts.map +1 -1
- package/dist/audit/cli/semanticReviewStep.js +35 -54
- package/dist/audit/cli/semanticReviewStep.js.map +1 -1
- package/dist/audit/cli/steps.d.ts +4 -4
- package/dist/audit/cli/steps.d.ts.map +1 -1
- package/dist/audit/cli/steps.js +0 -1
- package/dist/audit/cli/steps.js.map +1 -1
- package/dist/audit/cli/workPartitionRuntime.d.ts +11 -0
- package/dist/audit/cli/workPartitionRuntime.d.ts.map +1 -0
- package/dist/audit/cli/workPartitionRuntime.js +39 -0
- package/dist/audit/cli/workPartitionRuntime.js.map +1 -0
- package/dist/audit/contracts/wrapperResponse.d.ts +6 -6
- package/dist/audit/extractors/analyzers/candidates.d.ts.map +1 -1
- package/dist/audit/extractors/analyzers/candidates.js +45 -54
- package/dist/audit/extractors/analyzers/candidates.js.map +1 -1
- package/dist/audit/io/artifacts.d.ts +1 -3
- package/dist/audit/io/artifacts.d.ts.map +1 -1
- package/dist/audit/io/artifacts.js +0 -3
- package/dist/audit/io/artifacts.js.map +1 -1
- package/dist/audit/orchestrator/advance.d.ts.map +1 -1
- package/dist/audit/orchestrator/advance.js +0 -35
- package/dist/audit/orchestrator/advance.js.map +1 -1
- package/dist/audit/orchestrator/advanceTypes.d.ts +4 -63
- package/dist/audit/orchestrator/advanceTypes.d.ts.map +1 -1
- package/dist/audit/orchestrator/executorRunners.d.ts.map +1 -1
- package/dist/audit/orchestrator/executorRunners.js +9 -12
- package/dist/audit/orchestrator/executorRunners.js.map +1 -1
- package/dist/audit/orchestrator/executors.d.ts +2 -0
- package/dist/audit/orchestrator/executors.d.ts.map +1 -1
- package/dist/audit/orchestrator/executors.js +8 -7
- package/dist/audit/orchestrator/executors.js.map +1 -1
- package/dist/audit/orchestrator/hostInputPause.d.ts +1 -1
- package/dist/audit/orchestrator/hostInputPause.js +1 -1
- package/dist/audit/orchestrator/ingestionExecutors.d.ts.map +1 -1
- package/dist/audit/orchestrator/ingestionExecutors.js +4 -1
- package/dist/audit/orchestrator/ingestionExecutors.js.map +1 -1
- package/dist/audit/orchestrator/intakeExecutors.d.ts +1 -65
- package/dist/audit/orchestrator/intakeExecutors.d.ts.map +1 -1
- package/dist/audit/orchestrator/intakeExecutors.js +3 -425
- package/dist/audit/orchestrator/intakeExecutors.js.map +1 -1
- package/dist/audit/orchestrator/nextStep.d.ts +0 -13
- package/dist/audit/orchestrator/nextStep.d.ts.map +1 -1
- package/dist/audit/orchestrator/nextStep.js +2 -9
- package/dist/audit/orchestrator/nextStep.js.map +1 -1
- package/dist/audit/orchestrator/planningExecutors.d.ts.map +1 -1
- package/dist/audit/orchestrator/planningExecutors.js +4 -1
- package/dist/audit/orchestrator/planningExecutors.js.map +1 -1
- package/dist/audit/orchestrator/rollingDispatch.d.ts +1 -1
- package/dist/audit/orchestrator/rollingDispatch.d.ts.map +1 -1
- package/dist/audit/orchestrator/rollingDispatch.js +5 -4
- package/dist/audit/orchestrator/rollingDispatch.js.map +1 -1
- package/dist/audit/orchestrator/staleness.d.ts.map +1 -1
- package/dist/audit/orchestrator/staleness.js +3 -3
- package/dist/audit/orchestrator/staleness.js.map +1 -1
- package/dist/audit/orchestrator/state.d.ts +0 -39
- package/dist/audit/orchestrator/state.d.ts.map +1 -1
- package/dist/audit/orchestrator/state.js +3 -29
- package/dist/audit/orchestrator/state.js.map +1 -1
- package/dist/audit/orchestrator/synthesisExecutors.d.ts +8 -2
- package/dist/audit/orchestrator/synthesisExecutors.d.ts.map +1 -1
- package/dist/audit/orchestrator/synthesisExecutors.js +7 -5
- package/dist/audit/orchestrator/synthesisExecutors.js.map +1 -1
- package/dist/audit/providers/index.d.ts +12 -6
- package/dist/audit/providers/index.d.ts.map +1 -1
- package/dist/audit/providers/index.js +24 -14
- package/dist/audit/providers/index.js.map +1 -1
- package/dist/audit/quota/hostLimits.d.ts +4 -6
- package/dist/audit/quota/hostLimits.d.ts.map +1 -1
- package/dist/audit/quota/hostLimits.js +5 -8
- package/dist/audit/quota/hostLimits.js.map +1 -1
- package/dist/audit/reporting/findingIdentity.d.ts +2 -2
- package/dist/audit/reporting/findingIdentity.js +2 -2
- package/dist/audit/reporting/synthesis.d.ts +7 -1
- package/dist/audit/reporting/synthesis.d.ts.map +1 -1
- package/dist/audit/reporting/synthesis.js +27 -7
- package/dist/audit/reporting/synthesis.js.map +1 -1
- package/dist/audit/reporting/workBlocks.d.ts +14 -3
- package/dist/audit/reporting/workBlocks.d.ts.map +1 -1
- package/dist/audit/reporting/workBlocks.js +163 -73
- package/dist/audit/reporting/workBlocks.js.map +1 -1
- package/dist/audit/types/activeDispatch.d.ts +8 -7
- package/dist/audit/types/activeDispatch.d.ts.map +1 -1
- package/dist/audit/types/auditState.d.ts +6 -6
- package/dist/audit/types/externalAnalyzer.d.ts +6 -6
- package/dist/audit/validation/auditResults.d.ts.map +1 -1
- package/dist/audit/validation/auditResults.js +6 -1
- package/dist/audit/validation/auditResults.js.map +1 -1
- package/dist/audit/validation/sessionConfig.d.ts.map +1 -1
- package/dist/audit/validation/sessionConfig.js +27 -29
- package/dist/audit/validation/sessionConfig.js.map +1 -1
- package/dist/remediate/contractPipeline/phaseCut.d.ts +8 -0
- package/dist/remediate/contractPipeline/phaseCut.d.ts.map +1 -1
- package/dist/remediate/contractPipeline/phaseCut.js +63 -0
- package/dist/remediate/contractPipeline/phaseCut.js.map +1 -1
- package/dist/remediate/contractPipeline/phaseCutArtifact.d.ts.map +1 -1
- package/dist/remediate/contractPipeline/phaseCutArtifact.js +5 -3
- package/dist/remediate/contractPipeline/phaseCutArtifact.js.map +1 -1
- package/dist/remediate/phases/plan.d.ts.map +1 -1
- package/dist/remediate/phases/plan.js +35 -12
- package/dist/remediate/phases/plan.js.map +1 -1
- package/dist/remediate/providers/index.d.ts +12 -7
- package/dist/remediate/providers/index.d.ts.map +1 -1
- package/dist/remediate/providers/index.js +24 -15
- package/dist/remediate/providers/index.js.map +1 -1
- package/dist/remediate/quota/hostLimits.d.ts +4 -6
- package/dist/remediate/quota/hostLimits.d.ts.map +1 -1
- package/dist/remediate/quota/hostLimits.js +5 -8
- package/dist/remediate/quota/hostLimits.js.map +1 -1
- package/dist/remediate/steps/contractPipeline.d.ts +6 -2
- package/dist/remediate/steps/contractPipeline.d.ts.map +1 -1
- package/dist/remediate/steps/contractPipeline.js +90 -6
- 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 +4 -2
- package/dist/remediate/steps/contractPipelinePrompts.js.map +1 -1
- package/dist/remediate/steps/dispatch/marshal.d.ts +6 -0
- package/dist/remediate/steps/dispatch/marshal.d.ts.map +1 -1
- package/dist/remediate/steps/dispatch/marshal.js +16 -17
- package/dist/remediate/steps/dispatch/marshal.js.map +1 -1
- package/dist/remediate/steps/dispatch/waveScheduling.d.ts +7 -15
- package/dist/remediate/steps/dispatch/waveScheduling.d.ts.map +1 -1
- package/dist/remediate/steps/dispatch/waveScheduling.js +26 -19
- package/dist/remediate/steps/dispatch/waveScheduling.js.map +1 -1
- package/dist/remediate/steps/nextStep.d.ts +6 -8
- package/dist/remediate/steps/nextStep.d.ts.map +1 -1
- package/dist/remediate/steps/nextStep.js +264 -219
- package/dist/remediate/steps/nextStep.js.map +1 -1
- package/dist/remediate/steps/rollingSession.d.ts +2 -1
- package/dist/remediate/steps/rollingSession.d.ts.map +1 -1
- package/dist/remediate/steps/rollingSession.js +14 -8
- package/dist/remediate/steps/rollingSession.js.map +1 -1
- package/dist/remediate/steps/sessionConfigLoad.d.ts +3 -2
- package/dist/remediate/steps/sessionConfigLoad.d.ts.map +1 -1
- package/dist/remediate/steps/sessionConfigLoad.js +16 -13
- package/dist/remediate/steps/sessionConfigLoad.js.map +1 -1
- package/dist/remediate/validation/contractPipeline.d.ts +1 -1
- package/dist/remediate/validation/contractPipeline.d.ts.map +1 -1
- package/dist/remediate/validation/contractPipeline.js +7 -1
- package/dist/remediate/validation/contractPipeline.js.map +1 -1
- package/dist/remediate/validation/contractPipelineGates.d.ts +8 -0
- package/dist/remediate/validation/contractPipelineGates.d.ts.map +1 -1
- package/dist/remediate/validation/contractPipelineGates.js +92 -8
- package/dist/remediate/validation/contractPipelineGates.js.map +1 -1
- package/dist/shared/config/resolveSessionConfig.d.ts.map +1 -1
- package/dist/shared/config/resolveSessionConfig.js +6 -5
- package/dist/shared/config/resolveSessionConfig.js.map +1 -1
- package/dist/shared/decompose/workPartition.d.ts +66 -0
- package/dist/shared/decompose/workPartition.d.ts.map +1 -0
- package/dist/shared/decompose/workPartition.js +523 -0
- package/dist/shared/decompose/workPartition.js.map +1 -0
- package/dist/shared/dispatch/admissionLoop.d.ts +5 -44
- package/dist/shared/dispatch/admissionLoop.d.ts.map +1 -1
- package/dist/shared/dispatch/admissionLoop.js +20 -82
- package/dist/shared/dispatch/admissionLoop.js.map +1 -1
- package/dist/shared/dispatch/coordinator.d.ts +5 -5
- package/dist/shared/dispatch/coordinator.d.ts.map +1 -1
- package/dist/shared/dispatch/coordinator.js +12 -11
- package/dist/shared/dispatch/coordinator.js.map +1 -1
- package/dist/shared/dispatch/costRank.d.ts +5 -155
- package/dist/shared/dispatch/costRank.d.ts.map +1 -1
- package/dist/shared/dispatch/costRank.js +2 -179
- package/dist/shared/dispatch/costRank.js.map +1 -1
- package/dist/shared/dispatch/dispatchQuotaContract.d.ts +37 -38
- package/dist/shared/dispatch/dispatchQuotaContract.d.ts.map +1 -1
- package/dist/shared/dispatch/dispatchQuotaContract.js +0 -1
- package/dist/shared/dispatch/dispatchQuotaContract.js.map +1 -1
- package/dist/shared/dispatch/hybridDispatch.d.ts +6 -2
- package/dist/shared/dispatch/hybridDispatch.d.ts.map +1 -1
- package/dist/shared/dispatch/hybridDispatch.js +1 -1
- package/dist/shared/dispatch/hybridDispatch.js.map +1 -1
- package/dist/shared/dispatch/rollingDispatch.d.ts +4 -4
- package/dist/shared/dispatch/rollingDispatch.d.ts.map +1 -1
- package/dist/shared/dispatch/rollingDispatch.js +13 -11
- package/dist/shared/dispatch/rollingDispatch.js.map +1 -1
- package/dist/shared/dispatch/unifiedRolling.d.ts +2 -2
- package/dist/shared/dispatch/unifiedRolling.d.ts.map +1 -1
- package/dist/shared/dispatch/unifiedRolling.js +1 -1
- package/dist/shared/dispatch/unifiedRolling.js.map +1 -1
- package/dist/shared/engine/obligationEngine.d.ts +2 -2
- package/dist/shared/friction/stepBoundaryCapture.d.ts +5 -59
- package/dist/shared/friction/stepBoundaryCapture.d.ts.map +1 -1
- package/dist/shared/friction/stepBoundaryCapture.js +11 -107
- package/dist/shared/friction/stepBoundaryCapture.js.map +1 -1
- package/dist/shared/index.d.ts +16 -17
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/index.js +11 -14
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/io/stateDir.d.ts +2 -2
- package/dist/shared/io/stateDir.js +2 -2
- package/dist/shared/providers/agyProvider.d.ts.map +1 -1
- package/dist/shared/providers/agyProvider.js +12 -26
- package/dist/shared/providers/agyProvider.js.map +1 -1
- package/dist/shared/providers/auditorSources.d.ts +10 -84
- package/dist/shared/providers/auditorSources.d.ts.map +1 -1
- package/dist/shared/providers/auditorSources.js +42 -267
- package/dist/shared/providers/auditorSources.js.map +1 -1
- package/dist/shared/providers/dispatchExclusion.d.ts +22 -0
- package/dist/shared/providers/dispatchExclusion.d.ts.map +1 -0
- package/dist/shared/providers/dispatchExclusion.js +23 -0
- package/dist/shared/providers/dispatchExclusion.js.map +1 -0
- package/dist/shared/providers/identity.d.ts +2 -66
- package/dist/shared/providers/identity.d.ts.map +1 -1
- package/dist/shared/providers/identity.js +2 -72
- package/dist/shared/providers/identity.js.map +1 -1
- package/dist/shared/providers/orchestratorBindings.d.ts +42 -0
- package/dist/shared/providers/orchestratorBindings.d.ts.map +1 -0
- package/dist/shared/providers/orchestratorBindings.js +30 -0
- package/dist/shared/providers/orchestratorBindings.js.map +1 -0
- package/dist/shared/providers/providerFactory.d.ts +0 -3
- package/dist/shared/providers/providerFactory.d.ts.map +1 -1
- package/dist/shared/providers/providerFactory.js +8 -37
- package/dist/shared/providers/providerFactory.js.map +1 -1
- package/dist/shared/providers/providerPathGuard.d.ts +3 -3
- package/dist/shared/providers/providerPathGuard.d.ts.map +1 -1
- package/dist/shared/providers/providerPathGuard.js +24 -27
- package/dist/shared/providers/providerPathGuard.js.map +1 -1
- package/dist/shared/quota/apiPool.d.ts +19 -22
- package/dist/shared/quota/apiPool.d.ts.map +1 -1
- package/dist/shared/quota/apiPool.js +66 -47
- package/dist/shared/quota/apiPool.js.map +1 -1
- package/dist/shared/quota/capacity.d.ts +29 -24
- package/dist/shared/quota/capacity.d.ts.map +1 -1
- package/dist/shared/quota/capacity.js +30 -4
- package/dist/shared/quota/capacity.js.map +1 -1
- package/dist/shared/quota/codexHostConfig.d.ts +6 -13
- package/dist/shared/quota/codexHostConfig.d.ts.map +1 -1
- package/dist/shared/quota/codexHostConfig.js +8 -14
- package/dist/shared/quota/codexHostConfig.js.map +1 -1
- package/dist/shared/quota/fileLock.d.ts +7 -0
- package/dist/shared/quota/fileLock.d.ts.map +1 -1
- package/dist/shared/quota/fileLock.js +32 -4
- package/dist/shared/quota/fileLock.js.map +1 -1
- package/dist/shared/quota/hostLimits.d.ts +19 -1
- package/dist/shared/quota/hostLimits.d.ts.map +1 -1
- package/dist/shared/quota/hostLimits.js +21 -11
- package/dist/shared/quota/hostLimits.js.map +1 -1
- package/dist/shared/quota/hostPool.d.ts +1 -1
- package/dist/shared/quota/hostPool.js +2 -2
- package/dist/shared/quota/hostPool.js.map +1 -1
- package/dist/shared/quota/limits.d.ts +6 -9
- package/dist/shared/quota/limits.d.ts.map +1 -1
- package/dist/shared/quota/limits.js +67 -50
- package/dist/shared/quota/limits.js.map +1 -1
- package/dist/shared/quota/scheduler.d.ts +2 -3
- package/dist/shared/quota/scheduler.d.ts.map +1 -1
- package/dist/shared/quota/scheduler.js +3 -12
- package/dist/shared/quota/scheduler.js.map +1 -1
- package/dist/shared/quota/types.d.ts +10 -10
- package/dist/shared/quota/types.d.ts.map +1 -1
- package/dist/shared/quota/types.js +4 -7
- package/dist/shared/quota/types.js.map +1 -1
- package/dist/shared/repair/brokeredDispatch.d.ts.map +1 -1
- package/dist/shared/repair/brokeredDispatch.js +3 -0
- package/dist/shared/repair/brokeredDispatch.js.map +1 -1
- package/dist/shared/reporting/auditDeliverable.d.ts.map +1 -1
- package/dist/shared/reporting/auditDeliverable.js +1 -0
- package/dist/shared/reporting/auditDeliverable.js.map +1 -1
- package/dist/shared/rolling/pausedState.d.ts +7 -7
- package/dist/shared/rolling/pausedState.js +3 -3
- package/dist/shared/tokens.d.ts +2 -5
- package/dist/shared/tokens.d.ts.map +1 -1
- package/dist/shared/tokens.js +15 -15
- package/dist/shared/tokens.js.map +1 -1
- package/dist/shared/types/auditorDescriptor.d.ts +3 -2
- package/dist/shared/types/auditorDescriptor.d.ts.map +1 -1
- package/dist/shared/types/auditorDescriptor.js +3 -2
- package/dist/shared/types/auditorDescriptor.js.map +1 -1
- package/dist/shared/types/finding.d.ts +80 -0
- package/dist/shared/types/finding.d.ts.map +1 -1
- package/dist/shared/types/finding.js +17 -0
- package/dist/shared/types/finding.js.map +1 -1
- package/dist/shared/types/sessionConfig.d.ts +8 -8
- package/dist/shared/types/sessionConfig.d.ts.map +1 -1
- package/dist/shared/types/sessionConfig.js +1 -1
- package/dist/shared/validation/findingsReport.d.ts.map +1 -1
- package/dist/shared/validation/findingsReport.js +3 -0
- package/dist/shared/validation/findingsReport.js.map +1 -1
- package/docs/audit-pkg/development.md +3 -2
- package/docs/audit-pkg/operator-guide.md +13 -106
- package/docs/audit-pkg/product.md +8 -7
- package/docs/audit-pkg/release.md +38 -29
- package/opencode.json +2 -2
- package/package.json +6 -4
- package/skills/audit-code/SKILL.md +2 -1
- package/skills/audit-code/audit-code.prompt.md +4 -3
- package/skills/remediate-code/remediate-code.prompt.md +2 -1
- package/dist/audit/cli/providerConfirmationStep.d.ts +0 -106
- package/dist/audit/cli/providerConfirmationStep.d.ts.map +0 -1
- package/dist/audit/cli/providerConfirmationStep.js +0 -396
- package/dist/audit/cli/providerConfirmationStep.js.map +0 -1
- package/dist/audit/orchestrator/providerConfirmation.d.ts +0 -25
- package/dist/audit/orchestrator/providerConfirmation.d.ts.map +0 -1
- package/dist/audit/orchestrator/providerConfirmation.js +0 -60
- package/dist/audit/orchestrator/providerConfirmation.js.map +0 -1
- package/dist/audit/providers/agyProvider.d.ts +0 -11
- package/dist/audit/providers/agyProvider.d.ts.map +0 -1
- package/dist/audit/providers/agyProvider.js +0 -18
- package/dist/audit/providers/agyProvider.js.map +0 -1
- package/dist/audit/providers/claudeCodeProvider.d.ts +0 -11
- package/dist/audit/providers/claudeCodeProvider.d.ts.map +0 -1
- package/dist/audit/providers/claudeCodeProvider.js +0 -23
- package/dist/audit/providers/claudeCodeProvider.js.map +0 -1
- package/dist/audit/providers/claudeWorkerProvider.d.ts +0 -10
- package/dist/audit/providers/claudeWorkerProvider.d.ts.map +0 -1
- package/dist/audit/providers/claudeWorkerProvider.js +0 -15
- package/dist/audit/providers/claudeWorkerProvider.js.map +0 -1
- package/dist/audit/providers/opencodeProvider.d.ts +0 -2
- package/dist/audit/providers/opencodeProvider.d.ts.map +0 -1
- package/dist/audit/providers/opencodeProvider.js +0 -7
- package/dist/audit/providers/opencodeProvider.js.map +0 -1
- package/dist/remediate/providers/agyProvider.d.ts +0 -12
- package/dist/remediate/providers/agyProvider.d.ts.map +0 -1
- package/dist/remediate/providers/agyProvider.js +0 -19
- package/dist/remediate/providers/agyProvider.js.map +0 -1
- package/dist/remediate/providers/claudeCodeProvider.d.ts +0 -12
- package/dist/remediate/providers/claudeCodeProvider.d.ts.map +0 -1
- package/dist/remediate/providers/claudeCodeProvider.js +0 -24
- package/dist/remediate/providers/claudeCodeProvider.js.map +0 -1
- package/dist/remediate/providers/claudeWorkerProvider.d.ts +0 -11
- package/dist/remediate/providers/claudeWorkerProvider.d.ts.map +0 -1
- package/dist/remediate/providers/claudeWorkerProvider.js +0 -16
- package/dist/remediate/providers/claudeWorkerProvider.js.map +0 -1
- package/dist/remediate/providers/opencodeProvider.d.ts +0 -2
- package/dist/remediate/providers/opencodeProvider.d.ts.map +0 -1
- package/dist/remediate/providers/opencodeProvider.js +0 -7
- package/dist/remediate/providers/opencodeProvider.js.map +0 -1
- package/dist/shared/providers/providerConfirmation.d.ts +0 -141
- package/dist/shared/providers/providerConfirmation.d.ts.map +0 -1
- package/dist/shared/providers/providerConfirmation.js +0 -420
- package/dist/shared/providers/providerConfirmation.js.map +0 -1
- package/dist/shared/providers/proxyCatalog.d.ts +0 -158
- package/dist/shared/providers/proxyCatalog.d.ts.map +0 -1
- package/dist/shared/providers/proxyCatalog.js +0 -658
- package/dist/shared/providers/proxyCatalog.js.map +0 -1
- package/dist/shared/providers/sharedProviderConfirmation.d.ts +0 -802
- package/dist/shared/providers/sharedProviderConfirmation.d.ts.map +0 -1
- package/dist/shared/providers/sharedProviderConfirmation.js +0 -1865
- package/dist/shared/providers/sharedProviderConfirmation.js.map +0 -1
- package/dist/shared/types/providerConfirmation.d.ts +0 -334
- package/dist/shared/types/providerConfirmation.d.ts.map +0 -1
- package/dist/shared/types/providerConfirmation.js +0 -35
- package/dist/shared/types/providerConfirmation.js.map +0 -1
|
@@ -3,7 +3,18 @@ import { existsSync, statSync } from "node:fs";
|
|
|
3
3
|
import { mkdir, readFile, rename } from "node:fs/promises";
|
|
4
4
|
import { dirname, join, resolve } from "node:path";
|
|
5
5
|
import { StateStore } from "../state/store.js";
|
|
6
|
-
|
|
6
|
+
// IO / validation / rendering helpers
|
|
7
|
+
import { discardOnSchemaVersionMismatch, buildSelfSpawnExclusion, readOptionalJsonFile, readValidatedRepoSessionIntent, stagedAndUntracked, writeJsonFile, writeTextFile, buildAuditDeliverablePair, formatValidationIssues, isRecord, withFsRetry, RunLogger, DISPATCH_PROMPT_HANDOFF_NOTE, renderHostScratchNote, hostScratchDir, renderQuotaCoverageNudge, renderTokenBudgetView, coerceJsonObjectArg,
|
|
8
|
+
// rolling engine + quota
|
|
9
|
+
driveRolling, resolveLedgerBudgets, setQuotaStateDir, detectHostDispatchWall, admissionBlockedOnBudget, classifyEmptyGrantCause, reconcileAdmissionLeasesFromQuotaFile, buildQuotaPausedTerminal, HostSessionQuotaSource, quotaPoolKey,
|
|
10
|
+
// obligation engine + intent
|
|
11
|
+
interpretFreeFormIntent, advance, decideFrictionTriage, buildFrictionTriageBlock,
|
|
12
|
+
// dispatch planning / provider classification
|
|
13
|
+
planHybridDispatch, readSettledPools, addSettledPool, isPoolSettlingOutcome, isInProcessWorkerProvider, sourceByPoolId, classifyProvider, selectDispatchDriver, renderDispatchDriverInstruction, resolveHostProviderName, resolveHostDispatchProviderName, resolveHostDispatchCapability as sharedResolveHostDispatchCapability, resolveAutonomousMode, resolveRollingEngineFlag,
|
|
14
|
+
// friction capture
|
|
15
|
+
captureStepBoundaryFriction, captureZeroCapacityFriction, captureCostDriftFriction, captureCreditExhaustionFriction, captureQuotaUnclassifiedFriction, captureModelUnavailableFriction, capturePacketTooLargeFriction, createDispatchDecisionLog,
|
|
16
|
+
// domain constants
|
|
17
|
+
LENSES, SEVERITIES, } from "audit-tools/shared";
|
|
7
18
|
import { readRemediationAccessMemory, computeBlockContinuityScores } from "../state/accessMemory.js";
|
|
8
19
|
import { applyPlanPipeline, buildCoverageLedger } from "../phases/plan.js";
|
|
9
20
|
import { groundExtractedFindings } from "../phases/grounding.js";
|
|
@@ -71,19 +82,15 @@ export function resolveRollingEngineEnabled(options) {
|
|
|
71
82
|
env: options.env,
|
|
72
83
|
});
|
|
73
84
|
}
|
|
74
|
-
/** Conservative context-window floor, applied ONLY at true first contact (nothing persisted). */
|
|
75
|
-
const HOST_CONTEXT_TOKENS_FLOOR = DEFAULT_CONTEXT_TOKENS;
|
|
76
85
|
function finiteOrUndefined(value) {
|
|
77
86
|
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
78
87
|
}
|
|
79
88
|
/**
|
|
80
89
|
* Pure per-field host-capability resolver (C1). Each field resolves as
|
|
81
|
-
* `explicit ?? persisted
|
|
82
|
-
* clobber that would drop fields the current call omitted.
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* than re-flooring. Corrupt / non-finite persisted numbers degrade to undefined
|
|
86
|
-
* without throwing.
|
|
90
|
+
* `explicit ?? persisted` — a per-field merge, never a whole-object
|
|
91
|
+
* clobber that would drop fields the current call omitted. Corrupt / non-finite
|
|
92
|
+
* persisted numbers degrade to undefined without throwing; missing capability
|
|
93
|
+
* stays missing and is handled by the dispatch/plan refusal seam.
|
|
87
94
|
*
|
|
88
95
|
* Returns:
|
|
89
96
|
* - `resolved` — the merged capabilities to drive downstream dispatch sizing;
|
|
@@ -93,11 +100,9 @@ function finiteOrUndefined(value) {
|
|
|
93
100
|
export function resolveHostCapabilities(explicit, persisted) {
|
|
94
101
|
const exp = explicit ?? {};
|
|
95
102
|
const per = persisted && typeof persisted === "object" ? persisted : undefined;
|
|
96
|
-
const firstContact = per === undefined;
|
|
97
103
|
const pick = (e, p) => e ?? p ?? undefined;
|
|
98
104
|
const context_tokens = finiteOrUndefined(exp.context_tokens) ??
|
|
99
|
-
finiteOrUndefined(per?.context_tokens)
|
|
100
|
-
(firstContact ? HOST_CONTEXT_TOKENS_FLOOR : undefined);
|
|
105
|
+
finiteOrUndefined(per?.context_tokens);
|
|
101
106
|
const resolved = {
|
|
102
107
|
can_dispatch_subagents: pick(exp.can_dispatch_subagents, per?.can_dispatch_subagents),
|
|
103
108
|
max_concurrent: finiteOrUndefined(exp.max_concurrent) ?? finiteOrUndefined(per?.max_concurrent),
|
|
@@ -106,8 +111,7 @@ export function resolveHostCapabilities(explicit, persisted) {
|
|
|
106
111
|
model_id: pick(exp.model_id, per?.model_id),
|
|
107
112
|
models: exp.models ?? per?.models,
|
|
108
113
|
};
|
|
109
|
-
// Persist ONLY the explicitly-supplied fields (the delta)
|
|
110
|
-
// never an omitted field.
|
|
114
|
+
// Persist ONLY the explicitly-supplied fields (the delta), never an omitted field.
|
|
111
115
|
const toPersist = {};
|
|
112
116
|
if (exp.can_dispatch_subagents !== undefined)
|
|
113
117
|
toPersist.can_dispatch_subagents = exp.can_dispatch_subagents;
|
|
@@ -592,7 +596,7 @@ export async function driveRollingDispatch(levels, options) {
|
|
|
592
596
|
};
|
|
593
597
|
}
|
|
594
598
|
/**
|
|
595
|
-
* Whether
|
|
599
|
+
* Whether an eligible pool is one the orchestrator launches IN-PROCESS this cycle
|
|
596
600
|
* (vs. the conversation host's subagent pool) — the shared
|
|
597
601
|
* `isInProcessWorkerProvider` predicate (H3), same remediate policy.
|
|
598
602
|
*/
|
|
@@ -698,7 +702,7 @@ export async function driveRollingImplementDispatch(options) {
|
|
|
698
702
|
}, "remediate-code");
|
|
699
703
|
},
|
|
700
704
|
});
|
|
701
|
-
//
|
|
705
|
+
// Eligible pools: quota-derived concurrency, never the raw host flag (INV-QD-11).
|
|
702
706
|
// A partition-scoped caller supplies its coordinator's already-built set instead.
|
|
703
707
|
const builtPools = options.poolsOverride
|
|
704
708
|
? null
|
|
@@ -709,13 +713,10 @@ export async function driveRollingImplementDispatch(options) {
|
|
|
709
713
|
hostOutputTokens: options.waveOptions?.hostOutputTokens,
|
|
710
714
|
hostModels: options.waveOptions?.hostModels,
|
|
711
715
|
hostModelId: options.waveOptions?.hostModelId,
|
|
712
|
-
capabilityRanks:
|
|
716
|
+
capabilityRanks: null,
|
|
713
717
|
hostSession,
|
|
714
|
-
//
|
|
715
|
-
|
|
716
|
-
// recomputed against THIS process's env rather than inherited from the auditor
|
|
717
|
-
// that wrote the confirmation.
|
|
718
|
-
excludedBackends: resolveDispatchExclusion(await readConfirmedDispatchPolicy(options.root)),
|
|
718
|
+
// Mechanical self-spawn exclusion, recomputed from this process's environment.
|
|
719
|
+
excludedBackends: buildSelfSpawnExclusion(),
|
|
719
720
|
});
|
|
720
721
|
const confirmedPools = options.poolsOverride ?? builtPools.pools;
|
|
721
722
|
// The operator's own policy left this dispatch with no capacity at all. Loud, not
|
|
@@ -1029,12 +1030,12 @@ function normalizeExtractedPlan(value) {
|
|
|
1029
1030
|
}
|
|
1030
1031
|
async function saveStateForPlan(artifactsDir, existing, plan, planCoverage) {
|
|
1031
1032
|
const items = {};
|
|
1033
|
+
const blockIds = blockIdsByFinding(plan);
|
|
1032
1034
|
for (const finding of plan.findings) {
|
|
1033
|
-
const block = plan.blocks.find((candidate) => candidate.items.includes(finding.id));
|
|
1034
1035
|
items[finding.id] = {
|
|
1035
1036
|
finding_id: finding.id,
|
|
1036
1037
|
status: "pending",
|
|
1037
|
-
block_id:
|
|
1038
|
+
block_id: blockIds.get(finding.id) ?? "UNKNOWN",
|
|
1038
1039
|
};
|
|
1039
1040
|
}
|
|
1040
1041
|
const state = {
|
|
@@ -1073,11 +1074,20 @@ function stripPlanTimeBookkeeping(value) {
|
|
|
1073
1074
|
function findingCarryForwardKey(finding) {
|
|
1074
1075
|
return JSON.stringify(stripPlanTimeBookkeeping(finding));
|
|
1075
1076
|
}
|
|
1077
|
+
// FIRST-wins on multi-block membership: `fixupBlocksAfterDedup` can leave a
|
|
1078
|
+
// dedup survivor in more than one block's items, and historically the two
|
|
1079
|
+
// consumers disagreed (saveStateForPlan scanned blocks first-wins while this
|
|
1080
|
+
// map overwrote last-wins), so the same plan could yield different block_ids
|
|
1081
|
+
// per path. First-wins is pinned as the single semantic. The root question —
|
|
1082
|
+
// whether a finding should ever belong to two blocks at all — is tracked in
|
|
1083
|
+
// docs/backlog/open-bugs.md.
|
|
1076
1084
|
function blockIdsByFinding(plan) {
|
|
1077
1085
|
const byFinding = new Map();
|
|
1078
1086
|
for (const block of plan.blocks) {
|
|
1079
1087
|
for (const id of block.items) {
|
|
1080
|
-
byFinding.
|
|
1088
|
+
if (!byFinding.has(id)) {
|
|
1089
|
+
byFinding.set(id, block.block_id);
|
|
1090
|
+
}
|
|
1081
1091
|
}
|
|
1082
1092
|
}
|
|
1083
1093
|
return byFinding;
|
|
@@ -1245,6 +1255,9 @@ async function buildImplementDispatchStep(ctx) {
|
|
|
1245
1255
|
hostOutputTokens: resolvedHostOutputTokens,
|
|
1246
1256
|
hostModels: resolvedHostModels,
|
|
1247
1257
|
hostModelId: resolvedHostModelId,
|
|
1258
|
+
// An attended host is the dispatch authority. Headless/in-process paths
|
|
1259
|
+
// leave this false and retain the shared admission engine.
|
|
1260
|
+
hostOwnedDispatch: canDispatchImpl,
|
|
1248
1261
|
};
|
|
1249
1262
|
// H2+H4 collapse: ONE fan-out over the eligible pool set. `buildConfirmedPools`
|
|
1250
1263
|
// folds the configured primary in-process backend in as a source pool
|
|
@@ -1270,27 +1283,33 @@ async function buildImplementDispatchStep(ctx) {
|
|
|
1270
1283
|
const hybridHostSession = new HostSessionQuotaSource({
|
|
1271
1284
|
providerModelKey: hybridHostSessionModelKey,
|
|
1272
1285
|
});
|
|
1273
|
-
const { pools: confirmedPools, zeroedByExclusion } = await buildConfirmedPools({
|
|
1286
|
+
const { pools: confirmedPools, zeroedByExclusion, sourcePoolIds } = await buildConfirmedPools({
|
|
1274
1287
|
sessionConfig: sessionConfigImpl ?? null,
|
|
1275
1288
|
hostMaxConcurrent: resolvedHostMaxConcurrent,
|
|
1276
1289
|
hostContextTokens: resolvedHostContextTokens,
|
|
1277
1290
|
hostOutputTokens: resolvedHostOutputTokens,
|
|
1278
1291
|
hostModels: resolvedHostModels,
|
|
1279
1292
|
hostModelId: resolvedHostModelId,
|
|
1280
|
-
capabilityRanks:
|
|
1293
|
+
capabilityRanks: null,
|
|
1281
1294
|
hostSession: hybridHostSession,
|
|
1282
1295
|
// Attendance IS pool-set membership: headless ⇒ no host pool in the set.
|
|
1283
1296
|
hostCanDispatch: canDispatchImpl,
|
|
1284
|
-
//
|
|
1285
|
-
|
|
1286
|
-
|
|
1297
|
+
// Mechanical self-spawn exclusion uses the same resolved driver identity as quota.
|
|
1298
|
+
excludedBackends: buildSelfSpawnExclusion({
|
|
1299
|
+
activeHostProvider: canDispatchImpl ? hybridProviderName : null,
|
|
1300
|
+
}),
|
|
1287
1301
|
});
|
|
1288
1302
|
// Loud, not silent: on the headless branch below there is no host pool to fall
|
|
1289
1303
|
// back to, so a policy-zeroed set means this dispatch does nothing at all.
|
|
1290
1304
|
if (zeroedByExclusion) {
|
|
1291
1305
|
await captureZeroCapacityFriction(artifactsDir, runId, zeroedByExclusion, "remediate-code");
|
|
1292
1306
|
}
|
|
1293
|
-
|
|
1307
|
+
// Engine-drivable backends are SOURCE pools only, by declared class — never
|
|
1308
|
+
// re-derived from the provider name. The neutral worker-command host identity
|
|
1309
|
+
// name-collides with the in-process worker class, so a name-only test would
|
|
1310
|
+
// hand the HOST's own pool to the engine as a spawnable worker.
|
|
1311
|
+
const isEngineDrivableId = (poolId, providerName) => sourcePoolIds.has(poolId) && isInProcessPool({ providerName });
|
|
1312
|
+
const backendPools = confirmedPools.filter((p) => isEngineDrivableId(p.id, p.providerName));
|
|
1294
1313
|
if (!canDispatchImpl) {
|
|
1295
1314
|
// Headless: no host pool in the eligible set — when any dispatchable
|
|
1296
1315
|
// backend pool is confirmed, the engine drives the FULL rolling implement
|
|
@@ -1381,7 +1400,7 @@ async function buildImplementDispatchStep(ctx) {
|
|
|
1381
1400
|
settled.add(id);
|
|
1382
1401
|
await addSettledPool(settledPath, id);
|
|
1383
1402
|
},
|
|
1384
|
-
isInProcess:
|
|
1403
|
+
isInProcess: (a) => isEngineDrivableId(a.poolId, a.providerName),
|
|
1385
1404
|
});
|
|
1386
1405
|
// Drive the in-process partition through the ROLLING ENGINE (H2 plan D2 —
|
|
1387
1406
|
// `executeInProcessPartition`'s direct Promise.all executor is deleted; one
|
|
@@ -1516,7 +1535,9 @@ async function buildImplementDispatchStep(ctx) {
|
|
|
1516
1535
|
// nodes stay PENDING and re-dispatch on resume. The in-process partition (above)
|
|
1517
1536
|
// already ran on its own cooldown-safe pool, so its work still lands.
|
|
1518
1537
|
if (rolling.wall) {
|
|
1519
|
-
|
|
1538
|
+
if (rolling.quotaPath) {
|
|
1539
|
+
await reconcileAdmissionLeasesFromQuotaFile(rolling.quotaPath);
|
|
1540
|
+
}
|
|
1520
1541
|
const paused = await store.loadState();
|
|
1521
1542
|
if (paused) {
|
|
1522
1543
|
paused.partial_completion_terminal = buildQuotaPausedTerminal(rolling.wall.strandedBlockIds, rolling.wall.detected.earliestResetAt, rolling.wall.detected.emptyGrantCause);
|
|
@@ -1536,7 +1557,9 @@ async function buildImplementDispatchStep(ctx) {
|
|
|
1536
1557
|
if (rolling.session.frontier.length === 0) {
|
|
1537
1558
|
const structuralRefusal = detectStructuralRefusalPause(await readOptionalJsonFile(rolling.quotaPath));
|
|
1538
1559
|
if (structuralRefusal.pause) {
|
|
1539
|
-
|
|
1560
|
+
if (rolling.quotaPath) {
|
|
1561
|
+
await reconcileAdmissionLeasesFromQuotaFile(rolling.quotaPath);
|
|
1562
|
+
}
|
|
1540
1563
|
const paused = await store.loadState();
|
|
1541
1564
|
if (paused) {
|
|
1542
1565
|
paused.partial_completion_terminal = buildQuotaPausedTerminal(structuralRefusal.refusedIds, null, "no_capable_pool");
|
|
@@ -1565,6 +1588,16 @@ async function buildImplementDispatchStep(ctx) {
|
|
|
1565
1588
|
const rollNext = loaderCommand("next-step");
|
|
1566
1589
|
const acceptCmd = loaderCommand(`accept-node --id <BLOCK_ID> --run-id ${runId}`);
|
|
1567
1590
|
const reverifyCmd = loaderCommand(`reverify-node --id <BLOCK_ID> --run-id ${runId}`);
|
|
1591
|
+
const hostOwnedRolling = rolling.quotaPath === null;
|
|
1592
|
+
const dispatchAuthorityNote = hostOwnedRolling
|
|
1593
|
+
? `The attended host and llm-relay own provider selection, failover, quota, and
|
|
1594
|
+
concurrency. Dispatch the COMPLETE eligible set of ${rolling.session.frontier.length}
|
|
1595
|
+
node(s) below; audit-tools imposes no admission subset, cold-start wall, or concurrency
|
|
1596
|
+
cap. When they are all accepted, merge and re-invoke next-step.`
|
|
1597
|
+
: `The tool admitted this set against the live budget (and any declared in-flight cap):
|
|
1598
|
+
dispatch EXACTLY the ${rolling.session.frontier.length} node(s) below and no more.
|
|
1599
|
+
Their count is the whole grant — there is no separate concurrency cap. When they are
|
|
1600
|
+
all accepted, merge and re-invoke next-step; the tool re-grants the pending remainder.`;
|
|
1568
1601
|
const nodeLines = rolling.initial
|
|
1569
1602
|
.map((n) => `- \`${n.block_id}\` — prompt: \`${n.prompt_path}\` — worktree (subagent cwd): \`${n.worktree_root}\``)
|
|
1570
1603
|
.join("\n");
|
|
@@ -1581,19 +1614,16 @@ Each granted node runs in its OWN git worktree (hard isolation between nodes). T
|
|
|
1581
1614
|
TOOL owns commit -> verify -> merge + write-scope; you only spawn a subagent per
|
|
1582
1615
|
node and call \`accept-node\` as each finishes.
|
|
1583
1616
|
|
|
1584
|
-
|
|
1585
|
-
dispatch EXACTLY the ${rolling.session.frontier.length} node(s) below and no more.
|
|
1586
|
-
Their count is the whole grant — there is no separate concurrency cap. When they are
|
|
1587
|
-
all accepted, merge and re-invoke next-step; the tool re-grants the pending remainder.
|
|
1617
|
+
${dispatchAuthorityNote}
|
|
1588
1618
|
|
|
1589
|
-
${renderDispatchDriverInstruction(driverSelection, `the ${rolling.session.frontier.length} granted node(s)`)}
|
|
1619
|
+
${renderDispatchDriverInstruction(driverSelection, `the ${rolling.session.frontier.length} ${hostOwnedRolling ? "eligible" : "granted"} node(s)`)}
|
|
1590
1620
|
|
|
1591
1621
|
Spawn ONE subagent for EACH granted node below. Give the subagent that node's
|
|
1592
1622
|
\`prompt\`, and set its working directory to the node's **worktree** path. The
|
|
1593
1623
|
subagent edits source files INSIDE that worktree and writes ONLY its result file.
|
|
1594
1624
|
Do NOT let any subagent edit the main repository tree.
|
|
1595
1625
|
|
|
1596
|
-
Granted nodes (worktrees already created):
|
|
1626
|
+
${hostOwnedRolling ? "Eligible" : "Granted"} nodes (worktrees already created):
|
|
1597
1627
|
${nodeLines}
|
|
1598
1628
|
|
|
1599
1629
|
As EACH subagent finishes, run (substituting the finished node's block id):
|
|
@@ -1642,7 +1672,10 @@ ${renderHostScratchNote(hostScratchDir(artifactsDir, runId))}
|
|
|
1642
1672
|
`,
|
|
1643
1673
|
allowedCommands: [acceptCmd, reverifyCmd, rollMerge, rollNext],
|
|
1644
1674
|
stopCondition: "Stop after every node has reached a terminal accept (accept-node returns done), results merged, and next-step has been run.",
|
|
1645
|
-
artifactPaths: {
|
|
1675
|
+
artifactPaths: {
|
|
1676
|
+
dispatch_plan: rolling.planPath,
|
|
1677
|
+
...(rolling.quotaPath ? { dispatch_quota: rolling.quotaPath } : {}),
|
|
1678
|
+
},
|
|
1646
1679
|
}) };
|
|
1647
1680
|
}
|
|
1648
1681
|
}
|
|
@@ -1716,40 +1749,43 @@ Then run:
|
|
|
1716
1749
|
// of `implementing`) emits the resumable `quota_paused` step this same advance; the
|
|
1717
1750
|
// ungranted nodes stay PENDING and re-dispatch on resume (never abandoned to partial
|
|
1718
1751
|
// coverage — the remediate divergence from audit's read-only bound-and-give-up).
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
implQuota?.capacity_pools?.
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1752
|
+
if (!waveOptsImpl.hostOwnedDispatch) {
|
|
1753
|
+
const implQuota = await readOptionalJsonFile(implQuotaPath);
|
|
1754
|
+
// D1 parity: the binding budget window (from the host pool's capacity summary) so an
|
|
1755
|
+
// empty_grant wall derives a reset time instead of the bare `earliestResetAt: null` —
|
|
1756
|
+
// but ONLY on a genuine BUDGET block, not a `cap_reached` ledger-contention wall
|
|
1757
|
+
// (frees in seconds; the window reset may be days out).
|
|
1758
|
+
const implBudgetBound = admissionBlockedOnBudget(implQuota?.admission?.explains ?? []);
|
|
1759
|
+
const implBindingWindow = implBudgetBound
|
|
1760
|
+
? implQuota?.capacity_pools?.find((p) => p.is_conversation_host)?.binding_window ??
|
|
1761
|
+
implQuota?.capacity_pools?.[0]?.binding_window ??
|
|
1762
|
+
null
|
|
1763
|
+
: null;
|
|
1764
|
+
const implWall = detectHostDispatchWall({
|
|
1765
|
+
grantedCount: implQuota?.admission?.granted_packet_ids?.length ?? 0,
|
|
1766
|
+
cooldownUntil: implQuota?.cooldown_until ?? null,
|
|
1767
|
+
bindingWindow: implBindingWindow,
|
|
1768
|
+
// Step E parity: classify the zero-grant cause so the quota_paused terminal's
|
|
1769
|
+
// reset semantics stay honest (a no_capable_pool wall has no reset to wait for).
|
|
1770
|
+
explains: implQuota?.admission?.explains ?? [],
|
|
1771
|
+
now: Date.now(),
|
|
1772
|
+
});
|
|
1773
|
+
if (implWall.atWall) {
|
|
1774
|
+
// Release the leases the grant just reserved — pausing skips the merge that would
|
|
1775
|
+
// reconcile them, so without this they leak until TTL and mis-size the resume grant.
|
|
1776
|
+
await reconcileAdmissionLeasesFromQuotaFile(implQuotaPath);
|
|
1777
|
+
const strandedIds = dispatchPlan.items
|
|
1778
|
+
.map((item) => item.block_id)
|
|
1779
|
+
.filter((id) => typeof id === "string");
|
|
1780
|
+
const paused = await store.loadState();
|
|
1781
|
+
if (paused) {
|
|
1782
|
+
paused.partial_completion_terminal = buildQuotaPausedTerminal(strandedIds, implWall.earliestResetAt, implWall.emptyGrantCause);
|
|
1783
|
+
await store.saveState(paused);
|
|
1784
|
+
}
|
|
1785
|
+
return { kind: "transition", state: paused };
|
|
1750
1786
|
}
|
|
1751
|
-
return { kind: "transition", state: paused };
|
|
1752
1787
|
}
|
|
1788
|
+
const hostOwnedLegacy = waveOptsImpl.hostOwnedDispatch === true;
|
|
1753
1789
|
return { kind: "emit", step: await writeCurrentStep({
|
|
1754
1790
|
stepKind: "dispatch_implement",
|
|
1755
1791
|
status: "ready",
|
|
@@ -1759,29 +1795,28 @@ Then run:
|
|
|
1759
1795
|
prompt: `
|
|
1760
1796
|
# Dispatch Implementation Work (rolling)
|
|
1761
1797
|
|
|
1762
|
-
Read the dispatch plan and quota JSONs:
|
|
1798
|
+
Read the dispatch plan${hostOwnedLegacy ? "" : " and quota JSONs"}:
|
|
1763
1799
|
|
|
1764
1800
|
\`${planPath}\`
|
|
1765
|
-
|
|
1801
|
+
${hostOwnedLegacy ? "" : `\`${implQuotaPath}\``}
|
|
1766
1802
|
|
|
1767
1803
|
Every item in \`items\` is a node whose dependencies are all VERIFIED-COMPLETE
|
|
1768
|
-
(INV-RS-01).
|
|
1769
|
-
|
|
1770
|
-
set is the whole grant (there is no separate concurrency cap). Each item's
|
|
1804
|
+
(INV-RS-01). ${hostOwnedLegacy
|
|
1805
|
+
? "The attended host and llm-relay own provider selection, failover, quota, and concurrency. Dispatch every item in this complete eligible plan; audit-tools imposes no admission subset, cold-start wall, or concurrency cap."
|
|
1806
|
+
: "The tool admitted a budget-bounded subset: dispatch EXACTLY the block ids in the quota file's `admission.granted_packet_ids` and no others — that granted set is the whole grant (there is no separate concurrency cap)."} Each item's
|
|
1771
1807
|
\`model_hint.tier\` suggests which model to use (small/standard/deep). If your
|
|
1772
1808
|
provider has rate limits, pace launches accordingly.
|
|
1773
1809
|
|
|
1774
|
-
For each GRANTED item in \`items
|
|
1810
|
+
For each ${hostOwnedLegacy ? "eligible" : "GRANTED"} item in \`items\`${hostOwnedLegacy ? "" : " (its `block_id` in `admission.granted_packet_ids`)"},
|
|
1775
1811
|
dispatch one subagent with that item's \`prompt_path\`. Each subagent may edit source
|
|
1776
1812
|
files needed for that bounded block and must write only its assigned \`result_path\`.
|
|
1777
|
-
After the granted set is merged and you run next-step, the tool re-grants the pending
|
|
1778
|
-
remainder.
|
|
1813
|
+
${hostOwnedLegacy ? "After the complete plan is merged, run next-step." : "After the granted set is merged and you run next-step, the tool re-grants the pending remainder."}
|
|
1779
1814
|
|
|
1780
1815
|
${SHARED_REBUILD_BETWEEN_LEVELS_NOTE}
|
|
1781
1816
|
|
|
1782
|
-
${renderQuotaCoverageNudge(implQuotaPath, artifactsDir)}
|
|
1817
|
+
${renderQuotaCoverageNudge(hostOwnedLegacy ? null : implQuotaPath, artifactsDir)}
|
|
1783
1818
|
|
|
1784
|
-
${renderTokenBudgetView(implQuotaPath)}
|
|
1819
|
+
${renderTokenBudgetView(hostOwnedLegacy ? null : implQuotaPath)}
|
|
1785
1820
|
|
|
1786
1821
|
${DISPATCH_PROMPT_HANDOFF_NOTE}
|
|
1787
1822
|
|
|
@@ -1797,7 +1832,10 @@ Then run:
|
|
|
1797
1832
|
`,
|
|
1798
1833
|
allowedCommands: [mergeCommand, nextCommand],
|
|
1799
1834
|
stopCondition: "Stop after all implementation results have been merged and next-step has been run.",
|
|
1800
|
-
artifactPaths: {
|
|
1835
|
+
artifactPaths: {
|
|
1836
|
+
dispatch_plan: planPath,
|
|
1837
|
+
...(hostOwnedLegacy ? {} : { dispatch_quota: implQuotaPath }),
|
|
1838
|
+
},
|
|
1801
1839
|
}) };
|
|
1802
1840
|
}
|
|
1803
1841
|
/**
|
|
@@ -1971,6 +2009,7 @@ async function handlePendingExtractedPlan(root, artifactsDir, existing, extracte
|
|
|
1971
2009
|
// way declined findings are recorded; their payloads recover at close from the
|
|
1972
2010
|
// unfiltered intake source.
|
|
1973
2011
|
const filterDisp = await readOptionalJsonFile(reviewFilterDispositionsPath(artifactsDir));
|
|
2012
|
+
const pipelinedBlockIds = blockIdsByFinding(pipelined);
|
|
1974
2013
|
const coverage = filterDisp
|
|
1975
2014
|
? buildCoverageLedger({
|
|
1976
2015
|
planId: pipelined.plan_id,
|
|
@@ -1997,8 +2036,7 @@ async function handlePendingExtractedPlan(root, artifactsDir, existing, extracte
|
|
|
1997
2036
|
{
|
|
1998
2037
|
finding_id: finding.id,
|
|
1999
2038
|
status: "pending",
|
|
2000
|
-
block_id:
|
|
2001
|
-
?.block_id ?? "UNKNOWN",
|
|
2039
|
+
block_id: pipelinedBlockIds.get(finding.id) ?? "UNKNOWN",
|
|
2002
2040
|
},
|
|
2003
2041
|
])),
|
|
2004
2042
|
});
|
|
@@ -2352,31 +2390,49 @@ async function handleReadyIntakeContractPipeline(root, artifactsDir, options) {
|
|
|
2352
2390
|
if (!intake.summary || !isIntakeReady(intake.summary)) {
|
|
2353
2391
|
return null;
|
|
2354
2392
|
}
|
|
2393
|
+
// Resolve the manifest sources ONCE for the whole step (risk signal, Path A,
|
|
2394
|
+
// and the pipeline source inputs all consume the same snapshot), and read the
|
|
2395
|
+
// structured-audit source file at most once via a memoized reader (an
|
|
2396
|
+
// unreadable source memoizes `undefined`; extractAuditFindings on undefined
|
|
2397
|
+
// yields the empty set, so consumers degrade exactly as before).
|
|
2398
|
+
const manifestSources = intake.manifest
|
|
2399
|
+
? resolveManifestSources(root, intake.manifest).resolved
|
|
2400
|
+
: [];
|
|
2401
|
+
const auditSource = intake.summary.source_type === "structured_audit"
|
|
2402
|
+
? manifestSources.find((s) => s.type === "structured_audit")
|
|
2403
|
+
: undefined;
|
|
2404
|
+
let auditFindingsCache;
|
|
2405
|
+
const readAuditFindingsOnce = async () => {
|
|
2406
|
+
if (!auditSource) {
|
|
2407
|
+
return undefined;
|
|
2408
|
+
}
|
|
2409
|
+
if (!auditFindingsCache) {
|
|
2410
|
+
let value;
|
|
2411
|
+
try {
|
|
2412
|
+
value = JSON.parse(await readFile(auditSource.path, "utf8"));
|
|
2413
|
+
}
|
|
2414
|
+
catch {
|
|
2415
|
+
value = undefined;
|
|
2416
|
+
}
|
|
2417
|
+
auditFindingsCache = { value };
|
|
2418
|
+
}
|
|
2419
|
+
return auditFindingsCache.value;
|
|
2420
|
+
};
|
|
2355
2421
|
// Slice 2 — compute & persist the shared intake risk/complexity signal the
|
|
2356
2422
|
// self-scaling dials (Slices 3/4) will read. Idempotent: recorded once from
|
|
2357
2423
|
// intake-available data only (affected_files + goals + path-risk patterns), so
|
|
2358
|
-
// a later escalate-on-evidence raise is never clobbered. The
|
|
2359
|
-
//
|
|
2360
|
-
// where the top-level summary.affected_files is
|
|
2361
|
-
// per-finding) — it unions the per-finding
|
|
2362
|
-
// patterns actually fire (fail-closed: a
|
|
2363
|
-
// `low`). No behavior keys on it yet —
|
|
2424
|
+
// a later escalate-on-evidence raise is never clobbered. The audit-source read
|
|
2425
|
+
// happens only on the run that actually computes (memoized above), and for
|
|
2426
|
+
// structured_audit — where the top-level summary.affected_files is
|
|
2427
|
+
// legitimately empty (paths live per-finding) — it unions the per-finding
|
|
2428
|
+
// affected files so the path-risk patterns actually fire (fail-closed: a
|
|
2429
|
+
// risky-subsystem audit must not land `low`). No behavior keys on it yet —
|
|
2430
|
+
// this establishes the source of truth.
|
|
2364
2431
|
await ensureIntakeRiskSignal(artifactsDir, async () => {
|
|
2365
2432
|
const summary = intake.summary;
|
|
2366
2433
|
const affectedFiles = summary.affected_files.map((f) => f.path);
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
if (auditSource) {
|
|
2370
|
-
try {
|
|
2371
|
-
const parsed = JSON.parse(await readFile(auditSource.path, "utf8"));
|
|
2372
|
-
affectedFiles.push(...distinctAffectedFiles(extractAuditFindings(parsed)));
|
|
2373
|
-
}
|
|
2374
|
-
catch {
|
|
2375
|
-
// Unreadable audit source — leave the summary-derived list; an empty
|
|
2376
|
-
// list with non-empty goals still rates conservatively via intent.
|
|
2377
|
-
}
|
|
2378
|
-
}
|
|
2379
|
-
}
|
|
2434
|
+
const parsed = await readAuditFindingsOnce();
|
|
2435
|
+
affectedFiles.push(...distinctAffectedFiles(extractAuditFindings(parsed)));
|
|
2380
2436
|
return { affectedFiles, goals: summary.goals };
|
|
2381
2437
|
});
|
|
2382
2438
|
const pipeline = shouldEnterContractPipeline(artifactsDir, intake.summary.source_type);
|
|
@@ -2401,118 +2457,109 @@ async function handleReadyIntakeContractPipeline(root, artifactsDir, options) {
|
|
|
2401
2457
|
// ledger is built over the originals (every audit finding → exactly one
|
|
2402
2458
|
// disposition). The gate may halt to collect the user's decision.
|
|
2403
2459
|
let reviewSourceSwap;
|
|
2404
|
-
if (
|
|
2405
|
-
const
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2460
|
+
if (auditSource) {
|
|
2461
|
+
const auditFindings = await readAuditFindingsOnce();
|
|
2462
|
+
const originals = extractAuditFindings(auditFindings);
|
|
2463
|
+
if (originals.length > 0) {
|
|
2464
|
+
const checkpoint = await readOptionalJsonFile(join(artifactsDir, "intent_checkpoint.json"));
|
|
2465
|
+
const filter = await runFindingFilterPass(originals, {
|
|
2466
|
+
root,
|
|
2467
|
+
checkpoint: checkpoint ?? undefined,
|
|
2468
|
+
evidenceGrounding: true,
|
|
2469
|
+
});
|
|
2470
|
+
const gate = await runReviewApprovalGate(root, artifactsDir, filter.survivors,
|
|
2471
|
+
// Autonomy resolves from the PERSISTED session config (hoisted load
|
|
2472
|
+
// above) → env → attended default, never from the bare CLI options.
|
|
2473
|
+
resolveAutonomousMode({ sessionConfig: sessionConfigForDispatch }));
|
|
2474
|
+
if (gate.kind === "halt") {
|
|
2475
|
+
return gate.step;
|
|
2410
2476
|
}
|
|
2411
|
-
|
|
2412
|
-
|
|
2477
|
+
// Persist the filter dispositions so coverage is built over the originals.
|
|
2478
|
+
await persistReviewFilterDispositions(artifactsDir, originals, filter);
|
|
2479
|
+
// Lean path = the `low` risk tier's realization (D-68 — the standalone lean
|
|
2480
|
+
// fast-path folded into the self-scaling dial; its two mechanisms now live in
|
|
2481
|
+
// `riskSignal.ts` (light-review) + `contractPipeline.ts` (lean plan builder)).
|
|
2482
|
+
// A run skips the heavy contract DESIGN loop and
|
|
2483
|
+
// synthesizes the extracted plan directly IFF its effective risk tier is `low`;
|
|
2484
|
+
// the plan→implement→close machinery (per-node verify-before-merge + the final
|
|
2485
|
+
// whole-repo gate) is the retained safety net. Runs only here — on Path A
|
|
2486
|
+
// (structured_audit), the only intake with a pre-existing finding set to judge.
|
|
2487
|
+
//
|
|
2488
|
+
// First fold the APPROVED set's finding-level risk (grounding / confidence /
|
|
2489
|
+
// coupling / systemic / architecture / count — the finding-QUALITY dimension the
|
|
2490
|
+
// intake path/breadth/intent signal doesn't see) INTO the shared risk signal as
|
|
2491
|
+
// escalate-on-evidence. This makes the tier the SINGLE classifier: there is no
|
|
2492
|
+
// separate fast-path boolean that can DISAGREE with it (a grounded handful
|
|
2493
|
+
// touching a risk subsystem stays `high` and takes the full pipeline, instead of
|
|
2494
|
+
// bypassing it as the old parallel `evaluateFastPath` allowed).
|
|
2495
|
+
const findingEvidence = findingRiskEvidence(gate.approved);
|
|
2496
|
+
let riskSignal = await readIntakeRiskSignal(artifactsDir);
|
|
2497
|
+
if (findingEvidence && riskSignal) {
|
|
2498
|
+
const raised = escalateRiskSignal(riskSignal, findingEvidence);
|
|
2499
|
+
// escalateRiskSignal returns the SAME reference when the evidence does not
|
|
2500
|
+
// raise the tier — only persist on an actual change (no byte-identical rewrite).
|
|
2501
|
+
if (raised !== riskSignal) {
|
|
2502
|
+
riskSignal = raised;
|
|
2503
|
+
await writeIntakeRiskSignal(artifactsDir, riskSignal);
|
|
2504
|
+
}
|
|
2413
2505
|
}
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
// Autonomy resolves from the PERSISTED session config (hoisted load
|
|
2424
|
-
// above) → env → attended default, never from the bare CLI options.
|
|
2425
|
-
resolveAutonomousMode({ sessionConfig: sessionConfigForDispatch }));
|
|
2426
|
-
if (gate.kind === "halt") {
|
|
2427
|
-
return gate.step;
|
|
2506
|
+
// T1 slice 3b — the lean tier is NOT zero-scrutiny: a `low`-tier run first runs
|
|
2507
|
+
// a bounded LIGHT adversarial review over the approved findings (the floor,
|
|
2508
|
+
// never off — `adversarialDepthForTier("low") === "light"`). A clear verdict
|
|
2509
|
+
// proceeds to the lean plan; a verdict that surfaces a real concern escalates
|
|
2510
|
+
// the risk signal and routes to the full pipeline below.
|
|
2511
|
+
if (gate.approved.length > 0 && riskSignal?.tier === "low") {
|
|
2512
|
+
const review = await runLeanLightReviewGate(root, artifactsDir, gate.approved);
|
|
2513
|
+
if (review.kind === "halt") {
|
|
2514
|
+
return review.step;
|
|
2428
2515
|
}
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
// (structured_audit), the only intake with a pre-existing finding set to judge.
|
|
2439
|
-
//
|
|
2440
|
-
// First fold the APPROVED set's finding-level risk (grounding / confidence /
|
|
2441
|
-
// coupling / systemic / architecture / count — the finding-QUALITY dimension the
|
|
2442
|
-
// intake path/breadth/intent signal doesn't see) INTO the shared risk signal as
|
|
2443
|
-
// escalate-on-evidence. This makes the tier the SINGLE classifier: there is no
|
|
2444
|
-
// separate fast-path boolean that can DISAGREE with it (a grounded handful
|
|
2445
|
-
// touching a risk subsystem stays `high` and takes the full pipeline, instead of
|
|
2446
|
-
// bypassing it as the old parallel `evaluateFastPath` allowed).
|
|
2447
|
-
const findingEvidence = findingRiskEvidence(gate.approved);
|
|
2448
|
-
let riskSignal = await readIntakeRiskSignal(artifactsDir);
|
|
2449
|
-
if (findingEvidence && riskSignal) {
|
|
2450
|
-
const raised = escalateRiskSignal(riskSignal, findingEvidence);
|
|
2451
|
-
// escalateRiskSignal returns the SAME reference when the evidence does not
|
|
2452
|
-
// raise the tier — only persist on an actual change (no byte-identical rewrite).
|
|
2453
|
-
if (raised !== riskSignal) {
|
|
2454
|
-
riskSignal = raised;
|
|
2455
|
-
await writeIntakeRiskSignal(artifactsDir, riskSignal);
|
|
2456
|
-
}
|
|
2516
|
+
if (review.kind === "escalate") {
|
|
2517
|
+
// Escalate-on-evidence: raise the signal to at least `medium` so the
|
|
2518
|
+
// full pipeline's adversarial depth is `full` (see slice 3a), then
|
|
2519
|
+
// fall through to the full pipeline.
|
|
2520
|
+
await writeIntakeRiskSignal(artifactsDir, escalateRiskSignal(riskSignal, {
|
|
2521
|
+
tier: "medium",
|
|
2522
|
+
reason: `lean light review surfaced a concern: ${review.concerns.join("; ")}`,
|
|
2523
|
+
}));
|
|
2524
|
+
process.stderr.write(`[remediate-code] Lean light review escalated (${review.concerns.join("; ")}); routing to the full contract pipeline.\n`);
|
|
2457
2525
|
}
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
return review.step;
|
|
2526
|
+
else {
|
|
2527
|
+
// Clear verdict → proceed with the lean plan.
|
|
2528
|
+
const leanPlan = buildLeanExtractedPlan(gate.approved, randomRunId("LEAN"));
|
|
2529
|
+
await writeJsonFile(intakePaths(artifactsDir).extractedPlan, leanPlan);
|
|
2530
|
+
process.stderr.write(`[remediate-code] Lean fast path (risk tier low): ${riskSignal.rationale.join("; ")}; light review clear. Routing to plan→implement.\n`);
|
|
2531
|
+
const planned = await handlePendingExtractedPlan(root, artifactsDir, { status: "pending" }, leanPlan);
|
|
2532
|
+
if (planned) {
|
|
2533
|
+
return planned;
|
|
2467
2534
|
}
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
tier: "medium",
|
|
2474
|
-
reason: `lean light review surfaced a concern: ${review.concerns.join("; ")}`,
|
|
2475
|
-
}));
|
|
2476
|
-
process.stderr.write(`[remediate-code] Lean light review escalated (${review.concerns.join("; ")}); routing to the full contract pipeline.\n`);
|
|
2477
|
-
}
|
|
2478
|
-
else {
|
|
2479
|
-
// Clear verdict → proceed with the lean plan.
|
|
2480
|
-
const leanPlan = buildLeanExtractedPlan(gate.approved, randomRunId("LEAN"));
|
|
2481
|
-
await writeJsonFile(intakePaths(artifactsDir).extractedPlan, leanPlan);
|
|
2482
|
-
process.stderr.write(`[remediate-code] Lean fast path (risk tier low): ${riskSignal.rationale.join("; ")}; light review clear. Routing to plan→implement.\n`);
|
|
2483
|
-
const planned = await handlePendingExtractedPlan(root, artifactsDir, { status: "pending" }, leanPlan);
|
|
2484
|
-
if (planned) {
|
|
2485
|
-
return planned;
|
|
2486
|
-
}
|
|
2487
|
-
// Defensive: a deterministically-built lean plan should always
|
|
2488
|
-
// normalize. If it somehow didn't, handlePendingExtractedPlan removed
|
|
2489
|
-
// the file; fall through to the full pipeline (the safety net) rather
|
|
2490
|
-
// than stalling the run.
|
|
2491
|
-
process.stderr.write("[remediate-code] Lean fast-path plan failed to materialize; falling back to the contract pipeline.\n");
|
|
2492
|
-
}
|
|
2493
|
-
}
|
|
2494
|
-
// Seed the pipeline with the approved survivors only. When that set is
|
|
2495
|
-
// narrower than the originals (anything filtered or declined), route the
|
|
2496
|
-
// seed AND the pipeline's source inputs at a filtered file so a removed
|
|
2497
|
-
// finding can never re-enter via the raw audit-findings.json (tool-enforced).
|
|
2498
|
-
const approvedPayload = isRecord(auditFindings)
|
|
2499
|
-
? { ...auditFindings, findings: gate.approved }
|
|
2500
|
-
: { findings: gate.approved };
|
|
2501
|
-
let seedSourcePath = auditSource.path;
|
|
2502
|
-
if (gate.approved.length < originals.length) {
|
|
2503
|
-
await mkdir(contractPipelineDir(artifactsDir), { recursive: true });
|
|
2504
|
-
seedSourcePath = join(contractPipelineDir(artifactsDir), "approved-findings.json");
|
|
2505
|
-
await writeJsonFile(seedSourcePath, approvedPayload);
|
|
2506
|
-
reviewSourceSwap = { from: auditSource.path, to: seedSourcePath };
|
|
2507
|
-
}
|
|
2508
|
-
try {
|
|
2509
|
-
await writePathASeedFromFindings(artifactsDir, seedSourcePath, approvedPayload);
|
|
2510
|
-
}
|
|
2511
|
-
catch {
|
|
2512
|
-
// If the seed cannot be written, the pipeline still runs; the LLM
|
|
2513
|
-
// phases use the source files from sourcePaths.
|
|
2535
|
+
// Defensive: a deterministically-built lean plan should always
|
|
2536
|
+
// normalize. If it somehow didn't, handlePendingExtractedPlan removed
|
|
2537
|
+
// the file; fall through to the full pipeline (the safety net) rather
|
|
2538
|
+
// than stalling the run.
|
|
2539
|
+
process.stderr.write("[remediate-code] Lean fast-path plan failed to materialize; falling back to the contract pipeline.\n");
|
|
2514
2540
|
}
|
|
2515
2541
|
}
|
|
2542
|
+
// Seed the pipeline with the approved survivors only. When that set is
|
|
2543
|
+
// narrower than the originals (anything filtered or declined), route the
|
|
2544
|
+
// seed AND the pipeline's source inputs at a filtered file so a removed
|
|
2545
|
+
// finding can never re-enter via the raw audit-findings.json (tool-enforced).
|
|
2546
|
+
const approvedPayload = isRecord(auditFindings)
|
|
2547
|
+
? { ...auditFindings, findings: gate.approved }
|
|
2548
|
+
: { findings: gate.approved };
|
|
2549
|
+
let seedSourcePath = auditSource.path;
|
|
2550
|
+
if (gate.approved.length < originals.length) {
|
|
2551
|
+
await mkdir(contractPipelineDir(artifactsDir), { recursive: true });
|
|
2552
|
+
seedSourcePath = join(contractPipelineDir(artifactsDir), "approved-findings.json");
|
|
2553
|
+
await writeJsonFile(seedSourcePath, approvedPayload);
|
|
2554
|
+
reviewSourceSwap = { from: auditSource.path, to: seedSourcePath };
|
|
2555
|
+
}
|
|
2556
|
+
try {
|
|
2557
|
+
await writePathASeedFromFindings(artifactsDir, seedSourcePath, approvedPayload);
|
|
2558
|
+
}
|
|
2559
|
+
catch {
|
|
2560
|
+
// If the seed cannot be written, the pipeline still runs; the LLM
|
|
2561
|
+
// phases use the source files from sourcePaths.
|
|
2562
|
+
}
|
|
2516
2563
|
}
|
|
2517
2564
|
}
|
|
2518
2565
|
const paths = intakePaths(artifactsDir);
|
|
@@ -2520,14 +2567,12 @@ async function handleReadyIntakeContractPipeline(root, artifactsDir, options) {
|
|
|
2520
2567
|
if (existsSync(paths.brief)) {
|
|
2521
2568
|
sourcePaths.add(paths.brief);
|
|
2522
2569
|
}
|
|
2523
|
-
|
|
2524
|
-
for
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
: source.path);
|
|
2530
|
-
}
|
|
2570
|
+
for (const source of manifestSources) {
|
|
2571
|
+
// Swap the raw audit-findings.json for the approved-only filtered file so a
|
|
2572
|
+
// declined finding can never re-enter the pipeline as a source input.
|
|
2573
|
+
sourcePaths.add(reviewSourceSwap && source.path === reviewSourceSwap.from
|
|
2574
|
+
? reviewSourceSwap.to
|
|
2575
|
+
: source.path);
|
|
2531
2576
|
}
|
|
2532
2577
|
// Resolve the independent-critic dispatch capability from the SAME handshake
|
|
2533
2578
|
// (`resolveHostDispatchCapability`) implement dispatch uses — never a manual
|
|
@@ -4057,7 +4102,7 @@ async function decideNextStepLoop(options, runLogger) {
|
|
|
4057
4102
|
// When the fold ran only inside the implement-dispatch step builder, a
|
|
4058
4103
|
// next-step call carrying the flags that landed on any other obligation (a
|
|
4059
4104
|
// triage re-drive — the 2026-07-22 dogfood wall) silently dropped them and
|
|
4060
|
-
// dispatch capability stayed
|
|
4105
|
+
// dispatch capability stayed unknown and produced a resumable refusal.
|
|
4061
4106
|
if (state) {
|
|
4062
4107
|
const { toPersist } = resolveHostCapabilities({
|
|
4063
4108
|
can_dispatch_subagents: options.hostCanDispatchSubagents,
|