@danmoisan/drm-copilot-mcp 1.1.22 → 1.1.24
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/out/mcp-server.js +18758 -12030
- package/package.json +1 -1
- package/resources/claude-customizations/.claude/agent-memory/orchestrator/MEMORY.md +1 -1
- package/resources/claude-customizations/.claude/agent-memory/orchestrator/feedback_test_files_count_against_500_cap.md +4 -4
- package/resources/claude-customizations/.claude/agents/csharp-typed-engineer.md +1 -1
- package/resources/claude-customizations/.claude/agents/discovery-capability-sentinel.md +34 -0
- package/resources/claude-customizations/.claude/agents/feature-review.md +8 -0
- package/resources/claude-customizations/.claude/agents/legacy-parity-analyst.md +101 -43
- package/resources/claude-customizations/.claude/agents/migration-coverage-reviewer.md +107 -43
- package/resources/claude-customizations/.claude/agents/orchestrator.md +1 -1
- package/resources/claude-customizations/.claude/agents/parallel-orchestrator.md +60 -6
- package/resources/claude-customizations/.claude/agents/parallel-planner.md +21 -1
- package/resources/claude-customizations/.claude/agents/powershell-typed-engineer.md +1 -1
- package/resources/claude-customizations/.claude/agents/pr-author.md +48 -7
- package/resources/claude-customizations/.claude/agents/python-typed-engineer.md +1 -1
- package/resources/claude-customizations/.claude/agents/requirements-reconciler.md +117 -42
- package/resources/claude-customizations/.claude/agents/runtime-characterization-analyst.md +103 -43
- package/resources/claude-customizations/.claude/hooks/discovery-capability-probe.ps1 +102 -0
- package/resources/claude-customizations/.claude/hooks/enforce-discovery-artifact-gate.ps1 +69 -194
- package/resources/claude-customizations/.claude/hooks/enforce-discovery-planning-gate.ps1 +87 -0
- package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate-green-ci.ps1 +325 -0
- package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate.ps1 +29 -7
- package/resources/claude-customizations/.claude/hooks/enforce-epic-worktree-removal-gate-resolution.ps1 +23 -10
- package/resources/claude-customizations/.claude/hooks/enforce-epic-worktree-removal-gate.ps1 +29 -21
- package/resources/claude-customizations/.claude/hooks/enforce-file-size-limit.ps1 +244 -0
- package/resources/claude-customizations/.claude/hooks/enforce-model-routing-receipt.ps1 +51 -0
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1 +168 -48
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate.ps1 +1 -1
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-worktree-removal-gate.ps1 +22 -11
- package/resources/claude-customizations/.claude/hooks/enforce-powershell-batch-budget.ps1 +59 -20
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-command-allowlist.ps1 +51 -4
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill-helpers.ps1 +72 -11
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.current-branch.ps1 +149 -0
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.epic-base-branch.ps1 +4 -2
- package/resources/claude-customizations/.claude/hooks/enforce-python-batch-budget.ps1 +59 -20
- package/resources/claude-customizations/.claude/hooks/record-discovery-agent-start.ps1 +132 -0
- package/resources/claude-customizations/.claude/hooks/validate-discovery-artifact-gate.ps1 +56 -212
- package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output-feature-folder.ps1 +146 -0
- package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output-rejection.ps1 +172 -0
- package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output.ps1 +34 -4
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadius.psm1 +9 -3
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusAggregate.psm1 +154 -0
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusCombination.psm1 +228 -0
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusExtraction.psm1 +1 -0
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusNormalization.psm1 +4 -2
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusScheduling.psm1 +63 -16
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusTokenShape.psm1 +56 -1
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusWriteIntent.psm1 +4 -1
- package/resources/claude-customizations/.claude/lib/cleanup-manifest/CleanupWorktreeManifest.psm1 +33 -6
- package/resources/claude-customizations/.claude/lib/codex-routing/CodexDeployment.psm1 +5 -1
- package/resources/claude-customizations/.claude/lib/codex-routing/CodexDiscoveryRouting.psm1 +161 -0
- package/resources/claude-customizations/.claude/lib/codex-routing/CodexTopology.psm1 +25 -2
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryAuthority.psd1 +90 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryAuthority.psm1 +493 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryAuthorization.psm1 +479 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryCapability.psm1 +468 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryEncoding.psm1 +156 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryManifest.psm1 +384 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryObservation.psm1 +217 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryPayload.psm1 +276 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryPlanning.psm1 +336 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryRootGrant.psm1 +164 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryStart.psm1 +440 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryStartRecord.psm1 +296 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryStop.psm1 +336 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryToolRouting.psm1 +228 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryValidation.psm1 +188 -341
- package/resources/claude-customizations/.claude/lib/file-size-policy/FileSizePolicy.psm1 +434 -0
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateFeatureFolderRecord.psm1 +166 -0
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateIssueAdoption.psm1 +8 -3
- package/resources/claude-customizations/.claude/lib/worktree-resolution/HookTargetWorktree.psm1 +391 -0
- package/resources/claude-customizations/.claude/lib/worktree-resolution/WorktreeRunRecordPath.psm1 +185 -0
- package/resources/claude-customizations/.claude/lib/worktree-resolution/WorktreeRunResolution.psm1 +11 -21
- package/resources/claude-customizations/.claude/rules/general-code-change.md +4 -1
- package/resources/claude-customizations/.claude/rules/orchestrator-state.md +29 -5
- package/resources/claude-customizations/.claude/rules/parallel-orchestration.md +152 -20
- package/resources/claude-customizations/.claude/rules/powershell.md +1 -1
- package/resources/claude-customizations/.claude/rules/shell.md +1 -1
- package/resources/claude-customizations/.claude/settings.json +36 -3
- package/resources/claude-customizations/.claude/skills/adjudicate-unspecified-behavior/SKILL.md +135 -0
- package/resources/claude-customizations/.claude/skills/characterize-runtime-behavior/SKILL.md +134 -0
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/SKILL.md +2 -2
- package/resources/claude-customizations/.claude/skills/discovery-behavior-reconciliation/SKILL.md +28 -47
- package/resources/claude-customizations/.claude/skills/discovery-coverage-ledger/SKILL.md +32 -48
- package/resources/claude-customizations/.claude/skills/discovery-parity-matrix/SKILL.md +28 -45
- package/resources/claude-customizations/.claude/skills/discovery-repo-inventory/SKILL.md +28 -62
- package/resources/claude-customizations/.claude/skills/discovery-runtime-characterization/SKILL.md +28 -45
- package/resources/claude-customizations/.claude/skills/discovery-validate-artifacts/SKILL.md +28 -61
- package/resources/claude-customizations/.claude/skills/discovery-workflow/SKILL.md +55 -139
- package/resources/claude-customizations/.claude/skills/execution-environment/SKILL.md +25 -10
- package/resources/claude-customizations/.claude/skills/extract-feature-contract/SKILL.md +133 -0
- package/resources/claude-customizations/.claude/skills/feature-promotion-lifecycle/SKILL.md +1 -0
- package/resources/claude-customizations/.claude/skills/generate-acceptance-scenarios/SKILL.md +132 -0
- package/resources/claude-customizations/.claude/skills/initialize-discovery-workspace/SKILL.md +131 -0
- package/resources/claude-customizations/.claude/skills/inventory-legacy-system/SKILL.md +131 -0
- package/resources/claude-customizations/.claude/skills/orchestrate/SKILL.md +15 -7
- package/resources/claude-customizations/.claude/skills/parallel-add/SKILL.md +25 -2
- package/resources/claude-customizations/.claude/skills/parallel-close/SKILL.md +11 -1
- package/resources/claude-customizations/.claude/skills/parallel-orchestrate/SKILL.md +124 -14
- package/resources/claude-customizations/.claude/skills/parallel-plan/SKILL.md +72 -7
- package/resources/claude-customizations/.claude/skills/parallel-remove/SKILL.md +15 -0
- package/resources/claude-customizations/.claude/skills/parallel-run/SKILL.md +6 -0
- package/resources/claude-customizations/.claude/skills/pr-author/SKILL.md +56 -9
- package/resources/claude-customizations/.claude/skills/reconcile-parity-matrix/SKILL.md +131 -0
- package/resources/claude-customizations/.claude/skills/review-discovery-coverage/SKILL.md +129 -0
- package/resources/claude-customizations/.claude/skills/validate-discovery-artifacts/SKILL.md +127 -0
- package/resources/claude-customizations/.claude-variants/csharp-legacy/agents/csharp-typed-engineer.md +1 -1
- package/resources/claude-customizations/config/blast-radius.json +6 -5
- package/resources/claude-customizations/config/orchestration-routing.json +61 -1
- package/resources/claude-customizations/pack-manifests/core.json +40 -1
- package/resources/codex-and-agents-customizations/.agents/skills/adjudicate-unspecified-behavior/SKILL.md +135 -0
- package/resources/codex-and-agents-customizations/.agents/skills/atomic-planner/SKILL.md +7 -0
- package/resources/codex-and-agents-customizations/.agents/skills/characterize-runtime-behavior/SKILL.md +134 -0
- package/resources/codex-and-agents-customizations/.agents/skills/discovery-behavior-reconciliation/SKILL.md +46 -0
- package/resources/codex-and-agents-customizations/.agents/skills/discovery-coverage-ledger/SKILL.md +50 -0
- package/resources/codex-and-agents-customizations/.agents/skills/discovery-parity-matrix/SKILL.md +46 -0
- package/resources/codex-and-agents-customizations/.agents/skills/discovery-repo-inventory/SKILL.md +46 -0
- package/resources/codex-and-agents-customizations/.agents/skills/discovery-runtime-characterization/SKILL.md +46 -0
- package/resources/codex-and-agents-customizations/.agents/skills/discovery-validate-artifacts/SKILL.md +46 -0
- package/resources/codex-and-agents-customizations/.agents/skills/discovery-workflow/SKILL.md +62 -0
- package/resources/codex-and-agents-customizations/.agents/skills/execution-environment/SKILL.md +25 -10
- package/resources/codex-and-agents-customizations/.agents/skills/extract-feature-contract/SKILL.md +133 -0
- package/resources/codex-and-agents-customizations/.agents/skills/feature-promotion-lifecycle/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents/skills/feature-review/SKILL.md +8 -0
- package/resources/codex-and-agents-customizations/.agents/skills/general-code-change/SKILL.md +4 -1
- package/resources/codex-and-agents-customizations/.agents/skills/generate-acceptance-scenarios/SKILL.md +132 -0
- package/resources/codex-and-agents-customizations/.agents/skills/initialize-discovery-workspace/SKILL.md +131 -0
- package/resources/codex-and-agents-customizations/.agents/skills/inventory-legacy-system/SKILL.md +131 -0
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrator-workflow/SKILL.md +8 -0
- package/resources/codex-and-agents-customizations/.agents/skills/powershell/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents/skills/reconcile-parity-matrix/SKILL.md +131 -0
- package/resources/codex-and-agents-customizations/.agents/skills/review-discovery-coverage/SKILL.md +129 -0
- package/resources/codex-and-agents-customizations/.agents/skills/validate-discovery-artifacts/SKILL.md +127 -0
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c1.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c2.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c3-elevated.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c3.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c4.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/discovery-capability-sentinel.toml +51 -0
- package/resources/codex-and-agents-customizations/.codex/agents/feature-review.toml +8 -0
- package/resources/codex-and-agents-customizations/.codex/agents/legacy-parity-analyst-c1.toml +148 -0
- package/resources/codex-and-agents-customizations/.codex/agents/legacy-parity-analyst-c2.toml +148 -0
- package/resources/codex-and-agents-customizations/.codex/agents/legacy-parity-analyst-c3-elevated.toml +148 -0
- package/resources/codex-and-agents-customizations/.codex/agents/legacy-parity-analyst-c3.toml +148 -0
- package/resources/codex-and-agents-customizations/.codex/agents/legacy-parity-analyst-c4.toml +148 -0
- package/resources/codex-and-agents-customizations/.codex/agents/legacy-parity-analyst.toml +148 -0
- package/resources/codex-and-agents-customizations/.codex/agents/migration-coverage-reviewer-c1.toml +154 -0
- package/resources/codex-and-agents-customizations/.codex/agents/migration-coverage-reviewer-c2.toml +154 -0
- package/resources/codex-and-agents-customizations/.codex/agents/migration-coverage-reviewer-c3-elevated.toml +154 -0
- package/resources/codex-and-agents-customizations/.codex/agents/migration-coverage-reviewer-c3.toml +154 -0
- package/resources/codex-and-agents-customizations/.codex/agents/migration-coverage-reviewer-c4.toml +154 -0
- package/resources/codex-and-agents-customizations/.codex/agents/migration-coverage-reviewer.toml +154 -0
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c1.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c2.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c3-elevated.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c3.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c4.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c1.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c2.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c3-elevated.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c3.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c4.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/requirements-reconciler-c1.toml +164 -0
- package/resources/codex-and-agents-customizations/.codex/agents/requirements-reconciler-c2.toml +164 -0
- package/resources/codex-and-agents-customizations/.codex/agents/requirements-reconciler-c3-elevated.toml +164 -0
- package/resources/codex-and-agents-customizations/.codex/agents/requirements-reconciler-c3.toml +164 -0
- package/resources/codex-and-agents-customizations/.codex/agents/requirements-reconciler-c4.toml +164 -0
- package/resources/codex-and-agents-customizations/.codex/agents/requirements-reconciler.toml +164 -0
- package/resources/codex-and-agents-customizations/.codex/agents/runtime-characterization-analyst-c1.toml +150 -0
- package/resources/codex-and-agents-customizations/.codex/agents/runtime-characterization-analyst-c2.toml +150 -0
- package/resources/codex-and-agents-customizations/.codex/agents/runtime-characterization-analyst-c3-elevated.toml +150 -0
- package/resources/codex-and-agents-customizations/.codex/agents/runtime-characterization-analyst-c3.toml +150 -0
- package/resources/codex-and-agents-customizations/.codex/agents/runtime-characterization-analyst-c4.toml +150 -0
- package/resources/codex-and-agents-customizations/.codex/agents/runtime-characterization-analyst.toml +150 -0
- package/resources/codex-and-agents-customizations/.codex/config.toml +39 -3
- package/resources/codex-and-agents-customizations/.codex/hooks/codex-agent-profile-attestation.ps1 +22 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/discovery-capability-probe.ps1 +97 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/discovery-start-attestation.ps1 +171 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-codex-model-routing.ps1 +4 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-discovery-artifact-gate.ps1 +187 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-discovery-planning-gate.ps1 +149 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-file-size-limit.ps1 +282 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1 +239 -2
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate.ps1 +6 -15
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-powershell-batch-budget.ps1 +54 -15
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-python-batch-budget.ps1 +54 -15
- package/resources/codex-and-agents-customizations/.codex/hooks/file-size-policy.ps1 +421 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-target-worktree.ps1 +369 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/record-subagent-routing-attestation.ps1 +8 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/validate-codex-subagent-routing.ps1 +22 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/validate-discovery-agent-output.ps1 +178 -0
- package/resources/codex-and-agents-customizations/.codex/scripts/Resolve-CodexTopology.ps1 +11 -1
- package/resources/codex-and-agents-customizations/.codex-variants/csharp-legacy/agents/csharp-typed-engineer.toml +1 -1
- package/resources/codex-and-agents-customizations/AGENTS.md +4 -1
- package/resources/codex-and-agents-customizations/pack-manifests/core.json +65 -1
- package/resources/config/orchestration-routing.json +61 -1
- package/resources/customizations/.github/agents/commentary-remediation.agent.md +1 -1
- package/resources/customizations/.github/agents/discovery-capability-sentinel.agent.md +34 -0
- package/resources/customizations/.github/agents/legacy-parity-analyst.agent.md +122 -0
- package/resources/customizations/.github/agents/migration-coverage-reviewer.agent.md +128 -0
- package/resources/customizations/.github/agents/python-execution-only-typed.agent.md +1 -1
- package/resources/customizations/.github/agents/python-typed-engineer.agent.md +1 -1
- package/resources/customizations/.github/agents/requirements-reconciler.agent.md +138 -0
- package/resources/customizations/.github/agents/runtime-characterization-analyst.agent.md +124 -0
- package/resources/customizations/.github/hooks/discovery-agent-start.ps1 +139 -0
- package/resources/customizations/.github/hooks/discovery-agent-stop.ps1 +123 -0
- package/resources/customizations/.github/hooks/discovery-capability-probe.ps1 +98 -0
- package/resources/customizations/.github/hooks/discovery-planning.ps1 +91 -0
- package/resources/customizations/.github/hooks/discovery-pre-tool.ps1 +123 -0
- package/resources/customizations/.github/hooks/discovery.json +35 -0
- package/resources/customizations/.github/instructions/general-code-change.instructions.md +5 -2
- package/resources/customizations/.github/instructions/mermaid.instructions.md +85 -0
- package/resources/customizations/.github/instructions/powershell-code-change.instructions.md +1 -1
- package/resources/customizations/.github/prompts/execute-hard-lock.prompt.md +105 -0
- package/resources/customizations/.github/prompts/remediate-comments.prompt.md +1 -1
- package/resources/customizations/.github/skills/adjudicate-unspecified-behavior/SKILL.md +135 -0
- package/resources/customizations/.github/skills/characterize-runtime-behavior/SKILL.md +134 -0
- package/resources/customizations/.github/skills/discovery-behavior-reconciliation/SKILL.md +46 -0
- package/resources/customizations/.github/skills/discovery-coverage-ledger/SKILL.md +50 -0
- package/resources/customizations/.github/skills/discovery-parity-matrix/SKILL.md +46 -0
- package/resources/customizations/.github/skills/discovery-repo-inventory/SKILL.md +46 -0
- package/resources/customizations/.github/skills/discovery-runtime-characterization/SKILL.md +46 -0
- package/resources/customizations/.github/skills/discovery-validate-artifacts/SKILL.md +46 -0
- package/resources/customizations/.github/skills/discovery-workflow/SKILL.md +62 -0
- package/resources/customizations/.github/skills/execution-environment/SKILL.md +25 -10
- package/resources/customizations/.github/skills/extract-feature-contract/SKILL.md +133 -0
- package/resources/customizations/.github/skills/feature-review-workflow/SKILL.md +8 -0
- package/resources/customizations/.github/skills/generate-acceptance-scenarios/SKILL.md +132 -0
- package/resources/customizations/.github/skills/initialize-discovery-workspace/SKILL.md +131 -0
- package/resources/customizations/.github/skills/inventory-legacy-system/SKILL.md +131 -0
- package/resources/customizations/.github/skills/reconcile-parity-matrix/SKILL.md +131 -0
- package/resources/customizations/.github/skills/review-discovery-coverage/SKILL.md +129 -0
- package/resources/customizations/.github/skills/validate-discovery-artifacts/SKILL.md +127 -0
- package/resources/lib/codex-routing/CodexDeployment.psm1 +5 -1
- package/resources/lib/codex-routing/CodexDiscoveryRouting.psm1 +161 -0
- package/resources/lib/codex-routing/CodexTopology.psm1 +25 -2
- package/resources/lib/discovery-validation/DiscoveryAuthority.psd1 +90 -0
- package/resources/lib/discovery-validation/DiscoveryAuthority.psm1 +493 -0
- package/resources/lib/discovery-validation/DiscoveryAuthorization.psm1 +479 -0
- package/resources/lib/discovery-validation/DiscoveryCapability.psm1 +468 -0
- package/resources/lib/discovery-validation/DiscoveryEncoding.psm1 +156 -0
- package/resources/lib/discovery-validation/DiscoveryManifest.psm1 +384 -0
- package/resources/lib/discovery-validation/DiscoveryObservation.psm1 +217 -0
- package/resources/lib/discovery-validation/DiscoveryPayload.psm1 +276 -0
- package/resources/lib/discovery-validation/DiscoveryPlanning.psm1 +336 -0
- package/resources/lib/discovery-validation/DiscoveryRootGrant.psm1 +164 -0
- package/resources/lib/discovery-validation/DiscoveryStart.psm1 +440 -0
- package/resources/lib/discovery-validation/DiscoveryStartRecord.psm1 +296 -0
- package/resources/lib/discovery-validation/DiscoveryStop.psm1 +336 -0
- package/resources/lib/discovery-validation/DiscoveryToolRouting.psm1 +228 -0
- package/resources/powershell/PoshQC/PoshQC.Parallel.psm1 +452 -0
- package/resources/powershell/PoshQC/PoshQC.Shard.psm1 +106 -8
- package/resources/powershell/PoshQC/PoshQC.Testing.psm1 +12 -0
- package/resources/powershell/PoshQC/PoshQC.psd1 +6 -1
- package/resources/powershell/PoshQC/PoshQC.psm1 +7 -1
- package/resources/powershell/PoshQC/README.md +20 -1
- package/resources/templates/policy_audit/code-review.yyyy-MM-ddTHH-mm.md +4 -4
- package/resources/templates/policy_audit/policy-audit.yyyy-MM-ddTHH-mm.md +4 -4
|
@@ -255,15 +255,30 @@ not a cryptographic or security control.
|
|
|
255
255
|
|
|
256
256
|
Field checks 3 through 9 run in the fixed order `pr_url`, `issue_num`, `branch_name`, `authorized_by`, `authorized_at`, `basis`, `run_slug`, `session_id`; the first failure wins and the gate denies with `STANDALONE_MERGE_AUTHORIZATION_MALFORMED` naming that field.
|
|
257
257
|
|
|
258
|
+
## Green-CI standalone merge (issue #997)
|
|
259
|
+
|
|
260
|
+
A standalone run (neither an epic child nor a parallel item) merges its own pull request at S9 step 7 of `.claude/skills/orchestrate/SKILL.md` without an authorization record. The merge gate evaluates this green-CI condition after its parallel condition and before the `standalone_merge_authorizations` condition, and allows the merge only when all of the following hold:
|
|
261
|
+
|
|
262
|
+
1. The command is a single structural `gh pr merge` naming an explicit pull request number, with no chain, wrapper, inline environment prefix, `-R` or `--repo`, `/pull/` URL selector, `--auto`, or `--admin`.
|
|
263
|
+
2. Exactly one live worktree's per-feature checkpoint records that number, and no epic or parallel checkpoint records the number or that worktree's path.
|
|
264
|
+
3. The per-feature checkpoint has `epic_mode` absent, `null`, or JSON `false`; carries no `parallel_mode: true` and no non-blank `parallel_slug`; records `step9_status` exactly `passed` and `ci_gate.conclusion` exactly `success`; records `pr_gate.pr_number` as a JSON integer equal to the command number (an authorization record does not substitute); records `ci_gate.head_sha` as a lowercase 40 or 64 character object id; and, when `pr_gate.head_sha` is present and not `null`, records it equal to `ci_gate.head_sha`.
|
|
265
|
+
4. The live pull-request head from one bounded `gh pr view` call equals `ci_gate.head_sha`, and a `--match-head-commit` value, when present, equals the live head.
|
|
266
|
+
|
|
267
|
+
`parallel_mode`, `parallel_slug`, and `pr_merge` are tolerated, unvalidated top-level checkpoint keys: no validator reads them. A parallel child records `parallel_mode: true` and `parallel_slug` at kickoff, and a standalone run records `pr_merge: { merge_commit_sha, target_branch, merged_at }` only after its merge is confirmed.
|
|
268
|
+
|
|
269
|
+
Honest disclosure: the parallel exclusion is best-effort. The `Parallel mode: true` marker lives in the delegation prompt and is not present in a Bash `PreToolUse` payload, so a parallel child whose number and worktree path the parallel checkpoint has not yet recorded, and which omits the `parallel_mode` key, is not excluded by the hook. Like the authorization record above, the green-CI condition is a policy-level control, not a security control. A push after the live-head lookup can also change the head unless the command passes `--match-head-commit`, which the hook does not require.
|
|
270
|
+
|
|
258
271
|
## Issue-Adoption Scope and Backward Compatibility
|
|
259
272
|
|
|
260
273
|
These invariants apply only when a checkpoint contains a top-level `issue_adoption` key. The key records that the orchestration adopted a GitHub issue that already existed before orchestration started (transferred, filed by hand, or created by epic decomposition), so the issue was never created through `potential_to_issue`. The key is presence-gated: a checkpoint without it validates byte-identically to before and produces no new errors. It is evaluated only by the routing-contract completion check (`validate_routing_contract` and its TypeScript and PowerShell ports). It is not a member of `REQUIRED_STATE_KEYS`, it is not read by plain (non-completion) validation, and it is not read by the PR-creation-readiness gate. No JSON Schema file is authored, imported, or read for it.
|
|
261
274
|
|
|
262
275
|
Honest disclosure: the validators perform no network I/O. They cannot confirm that the issue exists, so `evidence` and `verified_via` are an auditable declaration of the read-only verification the orchestrator performed, not proof of it. This matches the `standalone_merge_authorizations` precedent above: the record is a policy-level declaration, not a security control.
|
|
263
276
|
|
|
277
|
+
The `feature_folder_record` is likewise declaration-only in every validator: the Python, TypeScript, and PowerShell validators perform no file-system or git access, so the validator checks, the MCP `validate_orchestration_artifacts` path, the Python CLI, and Codex gates cannot confirm that the folder exists or is committed. The folder is probed only under the Claude `SubagentStop` hook `.claude/hooks/validate-orchestrator-output.ps1`, through `.claude/hooks/validate-orchestrator-output-feature-folder.ps1`: when an `orchestrator-state` checkpoint waives `new_active_feature_folder` and passes the routing contract, the hook re-checks the checkpoint `feature-folder` against the path pattern and runs `git -C <worktree root> cat-file -t HEAD:<feature-folder>`. It allows only exit code 0 with the output `tree`; any other outcome blocks with `ROUTING_CONTRACT_BLOCKED: Checkpoint feature-folder is not committed in HEAD: <feature-folder>.`, which the subagent can repair. The probe proves only that `HEAD` of the run worktree holds a tree at that path at stop time; it does not prove which tool created the folder or that its contents are correct.
|
|
278
|
+
|
|
264
279
|
## Invariants (issue_adoption object)
|
|
265
280
|
|
|
266
|
-
The object has the shape `{ issue_num, issue_url, origin, verified_via, verified_at, evidence, waived_tools, potential_record? }`.
|
|
281
|
+
The object has the shape `{ issue_num, issue_url, origin, verified_via, verified_at, evidence, waived_tools, potential_record?, feature_folder_record? }`.
|
|
267
282
|
|
|
268
283
|
| Field | Rule |
|
|
269
284
|
| --- | --- |
|
|
@@ -275,6 +290,7 @@ The object has the shape `{ issue_num, issue_url, origin, verified_via, verified
|
|
|
275
290
|
| `evidence` | A string with non-whitespace content. |
|
|
276
291
|
| `waived_tools` | A non-empty list of non-blank tool names that includes `potential_to_issue`. |
|
|
277
292
|
| `potential_record` | When waiving a promotion-entry tool: required when `origin` is `epic_decomposition`, optional when `origin` is `transferred` or `filed_before_orchestration`, and validated whenever it is present (a path under `docs/features/potential/` ending in `.md`). |
|
|
293
|
+
| `feature_folder_record` | Required when `waived_tools` includes `new_active_feature_folder`, and validated whenever it is an object: `{ path, verified_via, verified_at, evidence }`, where `path` is a folder under `docs/features/active/` equal to the checkpoint `feature-folder`, `verified_via` is `git_cat_file_head` or `git_ls_tree_head`, `verified_at` is present, and `evidence` is a non-empty string. |
|
|
278
294
|
|
|
279
295
|
The rules run in this order, and their errors accumulate:
|
|
280
296
|
|
|
@@ -287,12 +303,19 @@ The rules run in this order, and their errors accumulate:
|
|
|
287
303
|
7. `evidence` must be a non-empty string.
|
|
288
304
|
8. `waived_tools` must be a non-empty list of non-blank strings; otherwise no further rule-8 or rule-9 check runs. Each entry, in list order, receives the first applicable error of: listed more than once; not in the closed waivable set; not required by the selected route after promotion-type resolution; already holding a successful MCP receipt. The list must include `potential_to_issue`.
|
|
289
305
|
9. Only when the rule-8 shape check passed: each distinct waived promotion-entry tool (`new_potential_entry` or `new_potential_bug_entry`) requires a valid `potential_record`, except that rule 9 reports nothing when `origin` is `transferred` or `filed_before_orchestration` and the `potential_record` key is absent. A present `potential_record`, including `null`, is always validated.
|
|
306
|
+
10. Only when the rule-8 shape check passed: when `waived_tools` includes `new_active_feature_folder` and `feature_folder_record` is absent or not an object (including `null`), the error is `Checkpoint issue_adoption.feature_folder_record must be an object when waiving new_active_feature_folder.`
|
|
307
|
+
11. Only when the rule-8 shape check passed: whenever `feature_folder_record` is an object, waived or not, its fields are checked in this order, and the errors accumulate:
|
|
308
|
+
- 11a. `path` must be a string that fully matches `^docs/features/active/[A-Za-z0-9][A-Za-z0-9._-]*(/[A-Za-z0-9][A-Za-z0-9._-]*)*$`, so dot segments, empty segments, a trailing slash, backslashes, drive letters, glob characters, and a leading `-` are rejected: `Checkpoint issue_adoption.feature_folder_record.path must be a folder path under docs/features/active/ without dot segments or a trailing slash.`
|
|
309
|
+
- 11b. Only when `path` passed 11a: the checkpoint `feature-folder` must be the identical string; an absent, non-string, or different value yields `Checkpoint issue_adoption.feature_folder_record.path must equal the checkpoint feature-folder.`
|
|
310
|
+
- 11c. `verified_via` must be `git_cat_file_head` or `git_ls_tree_head`: `Checkpoint issue_adoption.feature_folder_record.verified_via must be one of git_cat_file_head, git_ls_tree_head.`
|
|
311
|
+
- 11d. `verified_at` must be present; absent, `null`, and blank strings are rejected: `Checkpoint issue_adoption.feature_folder_record.verified_at must be present.`
|
|
312
|
+
- 11e. `evidence` must be a non-empty string: `Checkpoint issue_adoption.feature_folder_record.evidence must be a non-empty string.`
|
|
290
313
|
|
|
291
|
-
The closed waivable set is `potential_to_issue`, `new_potential_entry`, and `
|
|
314
|
+
The closed waivable set is `potential_to_issue`, `new_potential_entry`, `new_potential_bug_entry`, and `new_active_feature_folder`; `new_active_feature_folder` is waived only together with a valid `feature_folder_record`. `collect_pr_context`, `validate_orchestration_artifacts`, and every other tool can never be waived. All comparisons are ordinal and case-sensitive.
|
|
292
315
|
|
|
293
316
|
A lifecycle record moved to `docs/features/potential/promoted/` satisfies the `potential_record` path rule, because the rule checks only the `docs/features/potential/` prefix and the `.md` suffix and does not check that the file exists.
|
|
294
317
|
|
|
295
|
-
Fail-closed behavior: any adoption error waives nothing, so each missing receipt is still reported as `Checkpoint missing successful MCP receipt: <tool>.`. Adoption errors are placed after the receipt-loop errors and before the `local_execution_overrides` errors. The waiver affects only receipt presence: the declared `required_mcp_tools` equality check with the routing matrix is unchanged, so a checkpoint must still declare every route tool it waives.
|
|
318
|
+
Fail-closed behavior: any adoption error waives nothing, so each missing receipt is still reported as `Checkpoint missing successful MCP receipt: <tool>.`. Adoption errors are placed after the receipt-loop errors and before the `local_execution_overrides` errors. Rule 10 and rule 11 errors follow the rule 9 errors in the adoption error list, so a checkpoint that waives `new_active_feature_folder` without a valid record reports the missing-receipt line for each unreceipted required tool first, in `required_mcp_tools` order, and the rule 10 or rule 11 error after them. The waiver affects only receipt presence: the declared `required_mcp_tools` equality check with the routing matrix is unchanged, so a checkpoint must still declare every route tool it waives.
|
|
296
319
|
|
|
297
320
|
## Enforcement
|
|
298
321
|
|
|
@@ -302,7 +325,8 @@ Fail-closed behavior: any adoption error waives nothing, so each missing receipt
|
|
|
302
325
|
- `scripts/dev_tools/validate_orchestrator_state.py` appends one error per violated `model_routing_receipts` invariant when a `model_routing_receipts` key is present, delegating to `scripts/dev_tools/_orchestrator_state_model_routing.py`, which recomputes the resolved model via `resolve_delegation_model`. The check does not import or read any schema file.
|
|
303
326
|
- `scripts/dev_tools/validate_orchestrator_state.py` appends one error per violated `require_model_routing` invariant only when the caller passes `require_model_routing=True`, delegating to `scripts/dev_tools/_orchestrator_state_model_routing_gate.py`, which reuses the complexity and model-routing per-entry validators. When the flag is not passed the gate does not run, so existing calls are byte-identical.
|
|
304
327
|
- The validator is consumed by the MCP tool `validate_orchestration_artifacts`; backward compatibility for existing step-based checkpoints is preserved.
|
|
305
|
-
- The standalone-merge authorization invariants are enforced by the `PreToolUse` merge gate (`.claude/hooks/enforce-epic-merge-gate.ps1` with its dot-sourced helpers file, and `.codex/hooks/enforce-epic-merge-gate.ps1`) at merge time. The Python checkpoint validator
|
|
328
|
+
- The standalone-merge authorization invariants are enforced by the `PreToolUse` merge gate (`.claude/hooks/enforce-epic-merge-gate.ps1` with its dot-sourced helpers file, and `.codex/hooks/enforce-epic-merge-gate.ps1`) at merge time. The green-CI standalone merge conditions are enforced by the same Claude gate through its dot-sourced sibling `.claude/hooks/enforce-epic-merge-gate-green-ci.ps1`; the Codex gate has no green-CI branch. The Python checkpoint validator
|
|
306
329
|
does not currently validate standalone_merge_authorizations
|
|
307
330
|
entries; adding that check is recorded as follow-up FU-3.
|
|
308
|
-
- The `issue_adoption` invariants are enforced at completion by the routing-contract check in all three runtimes: `scripts/dev_tools/_orchestrator_state_issue_adoption.py` (Python authority), `extensions/drm-copilot/src/lib/validate/orchestrator-state-issue-adoption.ts`, and `.claude/lib/orchestrator-state/OrchestratorStateIssueAdoption.psm1`, with byte-identical error strings pinned by the shared corpus under `tests/fixtures/orchestrator_state_issue_adoption/`.
|
|
331
|
+
- The `issue_adoption` invariants are enforced at completion by the routing-contract check in all three runtimes: `scripts/dev_tools/_orchestrator_state_issue_adoption.py` (Python authority), `extensions/drm-copilot/src/lib/validate/orchestrator-state-issue-adoption.ts`, and `.claude/lib/orchestrator-state/OrchestratorStateIssueAdoption.psm1`, with byte-identical error strings pinned by the shared corpus under `tests/fixtures/orchestrator_state_issue_adoption/`. Rules 10 and 11 live in the record modules `scripts/dev_tools/_orchestrator_state_feature_folder_record.py`, `extensions/drm-copilot/src/lib/validate/orchestrator-state-feature-folder-record.ts`, and `.claude/lib/orchestrator-state/OrchestratorStateFeatureFolderRecord.psm1`. The `HEAD` probe for a waived `new_active_feature_folder` lives in the hook sibling `.claude/hooks/validate-orchestrator-output-feature-folder.ps1`, loaded by `.claude/hooks/validate-orchestrator-output.ps1`.
|
|
332
|
+
- The batch-budget hooks (`.claude/hooks/enforce-python-batch-budget.ps1`, `.claude/hooks/enforce-powershell-batch-budget.ps1`, and the Codex copies under `.codex/hooks/`) read the checkpoint of the target worktree that `Resolve-HookTargetWorktree` resolves for the edited file, so a coordinating session never needs a checkpoint at its own root for them.
|
|
@@ -13,6 +13,7 @@ paths:
|
|
|
13
13
|
- "scripts/dev_tools/validate_orchestration_artifacts.py"
|
|
14
14
|
- "extensions/drm-copilot/src/lib/validate/orchestration-artifacts.ts"
|
|
15
15
|
- ".claude/hooks/enforce-epic-merge-gate.ps1"
|
|
16
|
+
- ".claude/hooks/validate-orchestrator-output-rejection.ps1"
|
|
16
17
|
- ".claude/agents/parallel-orchestrator.md"
|
|
17
18
|
- ".claude/agents/parallel-planner.md"
|
|
18
19
|
- ".claude/skills/parallel-*/SKILL.md"
|
|
@@ -213,6 +214,38 @@ The wave-4 features — F6 (mutation protocol), F7 (enforcement hooks), and F8 (
|
|
|
213
214
|
|
|
214
215
|
Integration-cost scheduling (issue #722) adds no `conflict_edges[].reason` member; the four members above are unchanged. The scheduling data travels in tolerated-not-validated fields: an edge may carry the extra fields `hard`, `cost`, and `benefit`, and the planner and orchestrator checkpoints may carry a `tolerated_overlaps` list. No validator reads these fields, and the Python validators and the TypeScript validator port accept them with zero errors.
|
|
215
216
|
|
|
217
|
+
## Mutation Rejection Signal (issue #1012)
|
|
218
|
+
|
|
219
|
+
A parallel skill that rejects a mutation before any run checkpoint exists stops without writing state. Its final output then carries a rejection signal so that the completion stop hook `.claude/hooks/validate-orchestrator-output.ps1` can release the stop without demanding a checkpoint that the skill correctly did not write.
|
|
220
|
+
|
|
221
|
+
**Line grammar.** The signal is the last non-blank line of the final output, after trailing whitespace (including a carriage return) is trimmed, and it matches `^PARALLEL_MUTATION_REJECTED: (?<code>[a-z_]+)$` case-sensitively: the uppercase prefix, a colon, exactly one space, and one code from the table below, with no Markdown formatting (no backticks, no bold), no leading text, and no trailing text. A token on an earlier line, inside prose, or in any other form is not a signal. Where the run's slug is known, the line `parallel_slug: <slug>` precedes the signal.
|
|
222
|
+
|
|
223
|
+
**Closed code set.** The set is defined here and nowhere else:
|
|
224
|
+
|
|
225
|
+
| Code | Meaning |
|
|
226
|
+
| --- | --- |
|
|
227
|
+
| `kickoff_artifact_missing` | `/parallel-run` found no committed kickoff artifact for the run and delegated nothing. |
|
|
228
|
+
| `run_not_started` | The run is pending or not started, or no checkpoint tracks the named `parallel_slug`, so there is no running run to mutate. |
|
|
229
|
+
| `items_in_flight` | The mutation is rejected because an item is in flight: a close while any item is in flight, or a removal of an in-flight item without `--disposition`. |
|
|
230
|
+
| `unknown_item` | The removal target is not a live item: it is unknown, `withdrawn`, or `blocked`. |
|
|
231
|
+
|
|
232
|
+
**Output signal, not a schema member.** The signal is an output signal, not a checkpoint field, and it is not one of the nine enums owned by `## Enum Ownership (F6/F7/F8 consume, never extend)`; that table and its count are unchanged. No validator reads the signal and no checkpoint records it.
|
|
233
|
+
|
|
234
|
+
**Hook behavior.** The hook evaluates the signal only for `parallel-orchestrator-state` when the checkpoint resolution status is `NoTarget`:
|
|
235
|
+
|
|
236
|
+
| Condition | Result |
|
|
237
|
+
| --- | --- |
|
|
238
|
+
| parallel, `NoTarget`, valid signal, no contradicting state in any live worktree | allow, regardless of `stop_hook_active` |
|
|
239
|
+
| parallel, `NoTarget`, no signal or an invalid signal | block as before (repairable); the message gains a hint line naming the signal form and this section, and lists the allowed codes when the final line carries the prefix with an invalid code |
|
|
240
|
+
| parallel, `NoTarget`, valid signal, and a live worktree holds parallel checkpoint text that is unparseable, has a non-object root, is off-route, lacks a `parallel_slug`, or records the slug the output names | block as before |
|
|
241
|
+
| parallel, `Ambiguous` or `Rejected`, any signal | block as before |
|
|
242
|
+
| parallel, resolved checkpoint, any signal | full validation as before |
|
|
243
|
+
| `orchestrator-state` or `epic-orchestrator-state`, any signal | unchanged |
|
|
244
|
+
|
|
245
|
+
A signal never relaxes validation when a checkpoint resolves, and a path that wrote state validates fully. The parser, the state-absence scan, and the decision live in `.claude/hooks/validate-orchestrator-output-rejection.ps1`, whose code array mirrors the table above and is pinned to it by a parity test.
|
|
246
|
+
|
|
247
|
+
**Ownership.** The parallel skills consume these codes and never redefine them. Each mapped STOP path in `parallel-run`, `parallel-add`, `parallel-close`, and `parallel-remove` names only its own code and cites this section by heading; no skill restates the full set. A new code requires an amendment to this section, to the hook array, and to the parity test in the same change.
|
|
248
|
+
|
|
216
249
|
## F7 Seam
|
|
217
250
|
|
|
218
251
|
The retrospective cohort-ordering invariant `PARALLEL_COHORT_BARRIER_VIOLATION` (design section 9, Layer 2) is F7's explicitly assigned addition to the orchestrator validator. It is NOT implemented here. The entry point of `scripts/dev_tools/validate_parallel_orchestrator_state.py` contains a clearly delimited, appendable helper-invocation block, marked with explicit begin and end comments that name F7 and the invariant token, so that F7's edit is one appended helper call with no reflow of existing code. The TypeScript core `extensions/drm-copilot/src/lib/validate/parallel-orchestrator-state-core.ts` carries the matching comment-delimited seam. Existing helper calls sit outside the block.
|
|
@@ -255,19 +288,45 @@ Three constraints bound the mandate-read exclusion:
|
|
|
255
288
|
1. **The planner remains obliged to enumerate a genuine write explicitly.** An exclusion describes
|
|
256
289
|
the default reading relationship, not a permanent ban. When an item's plan will actually write an
|
|
257
290
|
excluded path, the planner appends that exact path to the declared radius after normalization.
|
|
258
|
-
2. **`quality-tiers.yml`
|
|
259
|
-
|
|
260
|
-
|
|
291
|
+
2. **`quality-tiers.yml` is an append-only registry and a mandate read (issue #1006).** Every item
|
|
292
|
+
that adds a module appends one entry to it, so both committed truth tables list it in
|
|
293
|
+
`conflict_tolerance.append_only_paths` and in `mandate_reads`, not in `shared_surfaces`. When an
|
|
294
|
+
item really writes it, the planner-appended or observed path contends on `path_overlap` at the
|
|
295
|
+
`append_only` weight and is never a hard edge; when an item merely cites it, the mandate-read
|
|
296
|
+
exclusion drops the citation. Separator-free token acceptance for it through the root-surface rule
|
|
297
|
+
(`config_root_surfaces`, `Get-ConfigRootSurface`) no longer applies, because that rule reads only
|
|
298
|
+
the separator-free entries of `shared_surfaces`; the planner append obligation in constraint 1 and
|
|
299
|
+
`detect_escaped_paths` in constraint 3 are the backstops.
|
|
261
300
|
3. **`detect_escaped_paths` makes the read/write distinction exact at execution time.** The
|
|
262
301
|
derivation heuristic reads intent from plan text and can be wrong in either direction; drift
|
|
263
302
|
detection compares the declared radius against the paths a diff actually touched, so an item that
|
|
264
303
|
wrote an excluded path is caught against observed evidence rather than against prose.
|
|
265
304
|
|
|
266
|
-
The extractor additionally rejects
|
|
305
|
+
The extractor additionally rejects five token shapes that were never write claims: a wildcard-free
|
|
267
306
|
token whose final component names a directory rather than a file, a `docs/features/` glob whose
|
|
268
307
|
wildcard occupies or truncates the feature-folder segment, a contract token carrying no ASCII
|
|
269
|
-
letter,
|
|
270
|
-
|
|
308
|
+
letter, a token containing a placeholder or interpolation marker, and a contract token that is a
|
|
309
|
+
default spreadsheet sheet name (`Sheet` or `Chart` followed by ASCII digits, compared
|
|
310
|
+
case-insensitively). `artifacts/` is not a known top-level segment, so a bare `artifacts/**`
|
|
311
|
+
subtree claim no longer satisfies the shape rules.
|
|
312
|
+
|
|
313
|
+
#### Generic contract-token rejection (issue #1006)
|
|
314
|
+
|
|
315
|
+
A spreadsheet application names a new worksheet or chart sheet with a default stem followed by a
|
|
316
|
+
number, so a spec that mentions `Sheet1` in an interface section names a worksheet, not an
|
|
317
|
+
exported symbol, schema, or CLI identifier. Two unrelated items that both named `Sheet1` received a
|
|
318
|
+
hard `contract_dependency` edge. The stems are a code constant, not a truth-table key:
|
|
319
|
+
`GENERIC_CONTRACT_STEMS` in `scripts/dev_tools/_blast_radius_token_shapes.py` and
|
|
320
|
+
`$script:GenericContractStem` in `.claude/lib/blast-radius/BlastRadiusTokenShape.psm1`, pinned equal
|
|
321
|
+
across Python and PowerShell by a Pester parity test that reads the Python source. Workbook and
|
|
322
|
+
object names such as `Book1` and `Table1` are a different class and are not rejected. The predicate
|
|
323
|
+
(`is_generic_contract_token`, `Test-GenericContractToken`) first requires an ASCII token, because a
|
|
324
|
+
.NET case-insensitive match folds the Kelvin sign and the long s to ASCII letters while Python
|
|
325
|
+
`re.ASCII` does not (the issue #903 precedent). It is applied at all six contract-filtering sites:
|
|
326
|
+
`extract_contract_identifiers`, `extract_write_intent_contracts`, and `normalize_declared_radius` in
|
|
327
|
+
Python, and `Get-ContractIdentifier`, `Get-WriteIntentSpecContract`, and
|
|
328
|
+
`Get-NormalizedDeclaredRadius` in PowerShell, so a previously recorded `Sheet1` is dropped on
|
|
329
|
+
recompute. TypeScript has no contract extractor, so no TypeScript parity applies.
|
|
271
330
|
|
|
272
331
|
### Mechanically-mergeable path class (issue #643)
|
|
273
332
|
|
|
@@ -454,12 +513,16 @@ narrowing. The only sanctioned mechanisms for relaxing contention are the config
|
|
|
454
513
|
radius: editing a declared radius to suppress an edge remains prohibited.
|
|
455
514
|
|
|
456
515
|
**Configuration.** `config/blast-radius.json` carries an optional `conflict_tolerance` object with
|
|
457
|
-
tolerance_percent (integer, at least 0), `weights` (same_file, possible_overlap, append_only,
|
|
458
|
-
module, each an integer of at least 1), `band_durations` (C1 through C4, each an
|
|
459
|
-
1), `default_band` (one of C1 through C4),
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
516
|
+
tolerance_percent (integer, at least 0), `weights` (same_file, possible_overlap, append_only,
|
|
517
|
+
module, and contract, each an integer of at least 1), `band_durations` (C1 through C4, each an
|
|
518
|
+
integer of at least 1), `default_band` (one of C1 through C4), append_only_paths (a list of exact
|
|
519
|
+
entries and `**` globs), and the optional `combination_threshold_percent` (integer, at least 0;
|
|
520
|
+
default 400 when absent). The `contract` weight (issue #1013) is required and validated like the
|
|
521
|
+
other weights; its committed value is 8, and a destination overrides it, like every other member,
|
|
522
|
+
through `config/blast-radius.local.json`. `combination_threshold_percent` is committed as 400 and is
|
|
523
|
+
overridden through the same overlay. The reader fails fast with an error naming the key for any other
|
|
524
|
+
shape; booleans are rejected wherever an integer is required. An absent key means strict scheduling,
|
|
525
|
+
identical to tolerance_percent 0.
|
|
463
526
|
|
|
464
527
|
**Edge rule.** For each unordered pair of items:
|
|
465
528
|
|
|
@@ -473,7 +536,14 @@ tolerance_percent 0.
|
|
|
473
536
|
possible_overlap weight for a glob or directory-prefix overlap, and the module weight times the
|
|
474
537
|
number of shared modules. The append_only_paths check runs before the same_file check (append-only
|
|
475
538
|
precedence), so an append-only file stays low cost even when both items name it. Mergeable paths
|
|
476
|
-
contribute 0 because they are excluded before enumeration.
|
|
539
|
+
contribute 0 because they are excluded before enumeration. Add the contract weight times the
|
|
540
|
+
number of distinct shared contract identifiers: the set the relation intersects to report
|
|
541
|
+
`contract_dependency`, each identifier counted once however often either radius lists it.
|
|
542
|
+
`contract_dependency` remains a hard class, so the contract term changes recorded edge costs and
|
|
543
|
+
combination eligibility and never an edge set. Invariant: at tolerance_percent 0 the edge set
|
|
544
|
+
equals strict scheduling for any `contract` weight, and at every tolerance the edge set with the
|
|
545
|
+
contract term equals the edge set without it; only the `cost` of edges whose pair shares a
|
|
546
|
+
contract differs.
|
|
477
547
|
4. **Benefit** (integer, pairwise). The smaller of the two items' band durations; a missing band uses
|
|
478
548
|
`default_band`. Running the pair concurrently saves at most one cohort step of the shorter item.
|
|
479
549
|
5. **Rule.** The pair is an edge if and only if it conflicts and either it is hard or
|
|
@@ -485,8 +555,27 @@ least 1. A detected conflict that is not hard therefore has a cost of at least 1
|
|
|
485
555
|
tolerance_percent 0 the inequality `cost * 100 > 0` always holds and the edge set equals the
|
|
486
556
|
detected-conflict set exactly; cohort coloring of that set is identical to strict scheduling. At
|
|
487
557
|
every tolerance an edge requires a conflict, so every edge implies a conflict and the edge set is
|
|
488
|
-
always a subset of the detected-conflict set. Raising tolerance_percent never
|
|
489
|
-
decision for (a, b) equals the decision for (b, a).
|
|
558
|
+
always a subset of the detected-conflict set. Raising tolerance_percent never turns a pairwise
|
|
559
|
+
decision into an edge, and the decision for (a, b) equals the decision for (b, a). Because the
|
|
560
|
+
aggregate cap below can promote a tolerated overlap, this monotonicity holds for the pairwise
|
|
561
|
+
decision only, not for the capped edge set.
|
|
562
|
+
|
|
563
|
+
**Aggregate cap (issue #1013).** The pairwise rule judges each pair alone, so the single entry point
|
|
564
|
+
in each runtime (`schedule_conflict_edges` through `select_capped_pairs` in
|
|
565
|
+
`scripts/dev_tools/_blast_radius_aggregate.py`, and Get-BlastRadiusConflictEdge through
|
|
566
|
+
Get-AggregateCappedPair in `.claude/lib/blast-radius/BlastRadiusAggregate.psm1`) applies a post-pass
|
|
567
|
+
that planners and `parallel-add` cannot skip. For item `i`, `total(i)` is the summed cost of its
|
|
568
|
+
remaining tolerated overlaps, and `i` is over its cap when
|
|
569
|
+
`total(i) * 100 > band_duration(i) * tolerance_percent` (integers only; a missing band reads as
|
|
570
|
+
`default_band`). While any item is over its cap, the smallest-key such item promotes the overlap with
|
|
571
|
+
the minimum key (benefit ascending, cost descending, a ascending, b ascending) to an edge carrying
|
|
572
|
+
`hard` false and the overlap's first reason, and the totals are recomputed. At tolerance_percent 0
|
|
573
|
+
nothing is tolerated, so the pass is a no-op and strict identity holds. A single tolerated overlap
|
|
574
|
+
never exceeds the cap, so the cap binds only for an item with two or more tolerated overlaps. The
|
|
575
|
+
capped scheduling output has five pinned set-level properties: the capped edges are a superset of
|
|
576
|
+
the pairwise edges and a subset of the detected conflicts; the output at tolerance 0 equals the
|
|
577
|
+
uncapped output; every item is within its cap after the pass; the output is invariant to input
|
|
578
|
+
order; and a second pass changes nothing.
|
|
490
579
|
|
|
491
580
|
**Soft-overlap handling.** A detected, non-hard pair within tolerance is a tolerated overlap, not an
|
|
492
581
|
edge. The planner records it in a tolerated_overlaps list on the planner checkpoint (and the
|
|
@@ -502,7 +591,39 @@ the checkpoint (`default_band` when absent), through the helper module
|
|
|
502
591
|
yields an edge and the pair is not already a recorded edge. A tolerated pair whose observed overlap
|
|
503
592
|
stays within tolerance halts neither item; one whose observed overlap exceeds tolerance, or becomes
|
|
504
593
|
hard, is reported. An unevaluable peer radius still counts as an edge (fail closed). At
|
|
505
|
-
tolerance_percent 0 the drift output equals strict drift output.
|
|
594
|
+
tolerance_percent 0 the drift output equals strict drift output. Drift detection stays pairwise: it
|
|
595
|
+
does not apply the aggregate cap, and a cap-promoted pair is a recorded edge, so drift never reports
|
|
596
|
+
it as newly conflicting.
|
|
597
|
+
|
|
598
|
+
**Telemetry (issue #1013).** Three fields are tolerated and not validated; no validator reads them:
|
|
599
|
+
`tolerated_overlaps[].observed_resolution` on the orchestrator checkpoint, `items[].combined_issue_nums`
|
|
600
|
+
on the planner and orchestrator checkpoints and the run manifest, and a top-level `combinations` list
|
|
601
|
+
on the planner checkpoint. `observed_resolution` has the shape `later_item` (integer), `conflicted`
|
|
602
|
+
(boolean), `conflict_detected_at` (timestamp or null), `resolved_at` (timestamp or null),
|
|
603
|
+
`resolution_minutes` (integer), and `recorded_at` (timestamp). The parallel orchestrator writes it for
|
|
604
|
+
the later-merging item of a tolerated pair. Attribution is non-exclusive: one conflict episode is
|
|
605
|
+
attributed to every tolerated peer that merged before it. Nothing reads `observed_resolution`, and no
|
|
606
|
+
weight changes automatically from it.
|
|
607
|
+
|
|
608
|
+
**Issue combination (issue #1013).** At planning time only, `find_combinations` in
|
|
609
|
+
`scripts/dev_tools/_blast_radius_combination.py` and Get-BlastRadiusCombination in
|
|
610
|
+
`.claude/lib/blast-radius/BlastRadiusCombination.psm1` find pairs that are cheaper to deliver as one
|
|
611
|
+
item. Combination is disabled when `conflict_tolerance` is absent or tolerance_percent is 0. A
|
|
612
|
+
conflicting pair is a candidate when its full reasons contain `contract_dependency` or it has a
|
|
613
|
+
same-file overlap (two equal concrete entries, after the mergeable exclusion, neither matching
|
|
614
|
+
append_only_paths), and it qualifies when `cost * 100 >= benefit * combination_threshold_percent`.
|
|
615
|
+
A contract-only pair is a candidate and qualifies when its contract-term cost meets the threshold;
|
|
616
|
+
one that does not qualify still serializes as a hard `contract_dependency` edge. Qualifying pairs
|
|
617
|
+
are grouped into connected components; each becomes one combination with ascending members, the
|
|
618
|
+
smallest member as primary, its pairs sorted by `(a, b)`, and `estimated_savings` equal to the sum
|
|
619
|
+
of its pair costs. There is no size cap on a combined item. The planner re-plans the primary
|
|
620
|
+
member's branch to cover every member, removes the other members from `items[]`, and records
|
|
621
|
+
`combined_issue_nums` and the `combinations` entry. No umbrella issue is created: the member issues
|
|
622
|
+
stay separate on GitHub, and the one PR closes every member through its author-asserted autoclose
|
|
623
|
+
line. A combined item remediates as one unit (one child, one `remediation_loop`, one PR) and never
|
|
624
|
+
splits back into separate PRs. A larger combined PR to review and a shared remediation budget are an
|
|
625
|
+
accepted trade; a destination tunes `combination_threshold_percent` to change how often items
|
|
626
|
+
combine.
|
|
506
627
|
|
|
507
628
|
### Write-intent extraction (issue #722)
|
|
508
629
|
|
|
@@ -674,8 +795,19 @@ keys are appended after the base keys. An overlay `version` must equal the base
|
|
|
674
795
|
forbidden-glob guard (`**`, `docs/**`, `tests/**`) applies to the composed module map, including
|
|
675
796
|
overlay-authored modules. A malformed overlay, a `version` mismatch, or a forbidden glob raises an
|
|
676
797
|
error before any write, so `config/blast-radius.json` keeps its prior bytes. With no overlay
|
|
677
|
-
present, the written file is byte-identical to the base document.
|
|
678
|
-
|
|
798
|
+
present, the written file is byte-identical to the base document. A destination demotes a shipped
|
|
799
|
+
shared surface with the overlay directive `shared_surfaces_demote`, a list of strings (issue
|
|
800
|
+
#1006). It is applied after all other keys are composed: each named entry is removed from
|
|
801
|
+
`shared_surfaces`, with the order of the remaining entries preserved, and unioned into
|
|
802
|
+
`conflict_tolerance.append_only_paths`, base entries first. The directive is consumed, not emitted,
|
|
803
|
+
so the composed file stays within the truth-table key set. An entry that is already an append-only
|
|
804
|
+
path and not a shared surface is accepted as a no-op, so composing a composed result again yields
|
|
805
|
+
identical output. The directive fails closed, before any write, on a non-list value, a non-string
|
|
806
|
+
member, a composed document without `conflict_tolerance.append_only_paths` (no partial
|
|
807
|
+
`conflict_tolerance` is created), or an unknown entry that is neither a shared surface nor an
|
|
808
|
+
append-only path. Demotion never touches `modules`, so the forbidden-glob guard is unchanged. A
|
|
809
|
+
demoted entry that a `shared_surface_globs` pattern still matches stays shared through the glob; the
|
|
810
|
+
bundled glob list is empty. The overlay still cannot remove a derived module.
|
|
679
811
|
|
|
680
812
|
## Enforcement
|
|
681
813
|
|
|
@@ -686,5 +818,5 @@ shipped surface or a derived module.
|
|
|
686
818
|
- The TypeScript parity port at `extensions/drm-copilot/src/lib/validate/parallel-state-shared.ts`, `parallel-state-structures.ts`, `parallel-state-records.ts`, `parallel-orchestrator-state-core.ts`, and `parallel-planner-state-core.ts` reproduces the same invariants and is dispatched from `extensions/drm-copilot/src/lib/validate/orchestration-artifacts.ts` for both new `artifact_type` values. Verified scope: 96 of 96 error strings matched across 43 constructed documents, for JSON-representable values that round-trip through both runtimes' native types. Three divergence classes are known outside that verified scope: (1) **`pythonRepr` quote selection** — `parallel-state-shared.ts:112-132` always single-quotes, while Python's `repr` switches to double quotes when the value contains a single quote (recorded repo-wide at `docs/features/potential/2026-08-07-python-repr-quote-selection-divergence.md`); (2) **integral floats** — `JSON.parse` erases Python's `int`/`float` distinction, so an integral float value produces a different Python-side error count than the TypeScript side; (3) **boolean/integer equality** — `parallel-state-structures.ts:228` uses `===`, so a boolean value is not selected the way Python's `True == 1` equality selects it, producing differing error counts. For ready-gate invariant P10, `extensions/drm-copilot/src/lib/validate/parallel-planner-state-routing.ts` enforces the P10 structural subset (the band enums, the assessment and receipt object checks, `signals_present` shape, `band >= floor` ordering, non-empty `rationale` and `assessed_at`, the band-equality cross-checks, `agent`, and the `fable_policy` enum) with byte-identical error strings; the Python validator is authoritative for floor equality, resolved-model equality, and the disabled clamp, which the TypeScript port does not check.
|
|
687
819
|
- Enforcement is therefore Python validator logic, plus the TypeScript parity port, plus this prose file. It is NEVER an imported JSON Schema. No schema file is read at validation time.
|
|
688
820
|
- The `parallel` route entry lives in `config/orchestration-routing.json` with `requires_pr_gate: false` (there is no run-level pull request to gate; each child's own route checkpoint enforces its per-item pull-request gate) and is mirrored byte-for-byte in `extensions/drm-copilot/resources/config/orchestration-routing.json`.
|
|
689
|
-
- The `PreToolUse` merge gate `.claude/hooks/enforce-epic-merge-gate.ps1` carries a parallel allow-branch that authorizes a per-item `gh pr merge --merge` from the parallel-orchestrator checkpoint when `route_id == "parallel"`, the target item's `merge_status == "ci_green"`, and the command's PR number matches that item's `pr_number`; any other case fails closed with `EPIC_MERGE_GATE_BLOCKED`.
|
|
690
|
-
- The `PreToolUse` worktree-removal gate `.claude/hooks/enforce-epic-worktree-removal-gate.ps1` likewise carries a parallel allow-branch that authorizes a per-item worktree removal from the parallel-orchestrator checkpoint when `route_id == "parallel"` and the `items[]` entry whose `worktree_path` matches the
|
|
821
|
+
- The `PreToolUse` merge gate `.claude/hooks/enforce-epic-merge-gate.ps1` carries a parallel allow-branch that authorizes a per-item `gh pr merge --merge` from the parallel-orchestrator checkpoint when `route_id == "parallel"`, the target item's `merge_status == "ci_green"`, and the command's PR number matches that item's `pr_number`; any other case fails closed with `EPIC_MERGE_GATE_BLOCKED`. After the parallel allow-branch, a standalone green-CI branch (issue #997), implemented in `.claude/hooks/enforce-epic-merge-gate-green-ci.ps1`, allows a run to merge its own pull request only when no epic or parallel checkpoint records the PR number or the item worktree path, the per-feature checkpoint carries no `parallel_mode` or `parallel_slug` marker, and its recorded green S9 gate matches the live PR head. That parallel exclusion is best-effort, because the `Parallel mode: true` marker is not visible in a Bash payload; a parallel child never merges its own pull request.
|
|
822
|
+
- The `PreToolUse` worktree-removal gate `.claude/hooks/enforce-epic-worktree-removal-gate.ps1` likewise carries a parallel allow-branch that authorizes a per-item worktree removal from the parallel-orchestrator checkpoint when `route_id == "parallel"` and the `items[]` entry whose `worktree_path` matches the removal target has `merge_status` in `{merged, worktree_removed}`, where a rooted `worktree_path` is compared to the normalized target, a relative one is joined to the main checkout root and to the root holding the checkpoint, and a blank, `.`, `..`, dot-segment, or `:`-bearing relative value matches nothing, through `Test-WorktreeRunRecordedPathMatchesTarget` in `.claude/lib/worktree-resolution/WorktreeRunRecordPath.psm1` (issue #995); any other case — neither checkpoint present, either checkpoint unparseable, `route_id` absent or not `"parallel"`, no matching `worktree_path`, or a matched entry whose `merge_status` is outside that set or absent — fails closed with `EPIC_WORKTREE_REMOVAL_BLOCKED`. Removal is keyed on the worktree path rather than on `pr_number`, because the command names a path. This gate and the sibling gate `.claude/hooks/enforce-parallel-worktree-removal-gate.ps1`, which owns `PARALLEL_WORKTREE_REMOVAL_BLOCKED`, both fire on the same command, and `PreToolUse` denials are conjunctive, so both must allow for a removal to proceed.
|
|
@@ -32,7 +32,7 @@ Run the toolchain in order: format → analyze → test. Restart from step 1 if
|
|
|
32
32
|
- Avoid `Invoke-Expression`, plaintext secrets, and hard-coded credentials/paths.
|
|
33
33
|
- Use `Write-Error`/`throw` for failures; avoid silent catch-alls.
|
|
34
34
|
- Use approved verbs and descriptive nouns for function names (PSScriptAnalyzer enforces this).
|
|
35
|
-
- Keep scripts cohesive and
|
|
35
|
+
- Keep scripts cohesive and within the tiered file-size policy in `.claude/rules/general-code-change.md` (`## File Size Limit`).
|
|
36
36
|
|
|
37
37
|
## Change Budget
|
|
38
38
|
|
|
@@ -89,7 +89,7 @@ single pass. Do not substitute the VS Code task wrappers for the native command
|
|
|
89
89
|
- Use shfmt default formatting (tab indentation, as in `scripts/bash/coverage_lib.sh`).
|
|
90
90
|
- Quote all expansions; resolve tools with `command -v` (honoring the `SHELL_QC_<TOOL>_BIN`
|
|
91
91
|
override seam).
|
|
92
|
-
-
|
|
92
|
+
- Production, test, and reusable shell files follow the tiered file-size policy in `.claude/rules/general-code-change.md` (`## File Size Limit`).
|
|
93
93
|
- Tests live in `tests/shell/*.bats` and mirror `scripts/bash/`. Tests must not create
|
|
94
94
|
temporary files; use checked-in fixtures under `tests/fixtures/` and checked-in stub
|
|
95
95
|
binaries under `tests/fixtures/shell_qc/stub-bin/` wired through the `SHELL_QC_<TOOL>_BIN`
|
|
@@ -150,6 +150,10 @@
|
|
|
150
150
|
"type": "command",
|
|
151
151
|
"command": "pwsh -NoProfile -File .claude/hooks/enforce-evidence-locations.ps1"
|
|
152
152
|
},
|
|
153
|
+
{
|
|
154
|
+
"type": "command",
|
|
155
|
+
"command": "pwsh -NoProfile -File .claude/hooks/enforce-file-size-limit.ps1"
|
|
156
|
+
},
|
|
153
157
|
{
|
|
154
158
|
"type": "command",
|
|
155
159
|
"command": "pwsh -NoProfile -File .claude/hooks/enforce-orchestration-preimplementation-gate.ps1"
|
|
@@ -168,11 +172,16 @@
|
|
|
168
172
|
},
|
|
169
173
|
{
|
|
170
174
|
"type": "command",
|
|
171
|
-
"command": "pwsh -NoProfile -File .claude/hooks/enforce-
|
|
172
|
-
}
|
|
175
|
+
"command": "pwsh -NoProfile -File .claude/hooks/enforce-mermaid-validation.ps1"
|
|
176
|
+
}
|
|
177
|
+
]
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"matcher": "Bash|Write|Edit|MultiEdit|NotebookEdit|Agent|Task|WebFetch|WebSearch|mcp__.*",
|
|
181
|
+
"hooks": [
|
|
173
182
|
{
|
|
174
183
|
"type": "command",
|
|
175
|
-
"command": "pwsh -NoProfile -File .claude/hooks/enforce-
|
|
184
|
+
"command": "pwsh -NoProfile -File .claude/hooks/enforce-discovery-artifact-gate.ps1"
|
|
176
185
|
}
|
|
177
186
|
]
|
|
178
187
|
},
|
|
@@ -183,6 +192,10 @@
|
|
|
183
192
|
"type": "command",
|
|
184
193
|
"command": "pwsh -NoProfile -File .claude/hooks/enforce-prd-feature-before-planner.ps1"
|
|
185
194
|
},
|
|
195
|
+
{
|
|
196
|
+
"type": "command",
|
|
197
|
+
"command": "pwsh -NoProfile -File .claude/hooks/enforce-discovery-planning-gate.ps1"
|
|
198
|
+
},
|
|
186
199
|
{
|
|
187
200
|
"type": "command",
|
|
188
201
|
"command": "pwsh -NoProfile -File .claude/hooks/enforce-orchestration-preimplementation-gate.ps1"
|
|
@@ -210,6 +223,17 @@
|
|
|
210
223
|
]
|
|
211
224
|
}
|
|
212
225
|
],
|
|
226
|
+
"SubagentStart": [
|
|
227
|
+
{
|
|
228
|
+
"matcher": "legacy-parity-analyst|runtime-characterization-analyst|requirements-reconciler|migration-coverage-reviewer",
|
|
229
|
+
"hooks": [
|
|
230
|
+
{
|
|
231
|
+
"type": "command",
|
|
232
|
+
"command": "pwsh -NoProfile -File .claude/hooks/record-discovery-agent-start.ps1"
|
|
233
|
+
}
|
|
234
|
+
]
|
|
235
|
+
}
|
|
236
|
+
],
|
|
213
237
|
"SubagentStop": [
|
|
214
238
|
{
|
|
215
239
|
"matcher": "atomic-planner|atomic-executor|feature-review|task-researcher|prd-feature|staged-review|epic-review|status-updater|python-typed-engineer|powershell-typed-engineer|csharp-typed-engineer|typescript-engineer|orchestrator|epic-orchestrator|epic-planner",
|
|
@@ -220,6 +244,15 @@
|
|
|
220
244
|
}
|
|
221
245
|
]
|
|
222
246
|
},
|
|
247
|
+
{
|
|
248
|
+
"matcher": "legacy-parity-analyst|runtime-characterization-analyst|requirements-reconciler|migration-coverage-reviewer",
|
|
249
|
+
"hooks": [
|
|
250
|
+
{
|
|
251
|
+
"type": "command",
|
|
252
|
+
"command": "pwsh -NoProfile -File .claude/hooks/validate-discovery-artifact-gate.ps1"
|
|
253
|
+
}
|
|
254
|
+
]
|
|
255
|
+
},
|
|
223
256
|
{
|
|
224
257
|
"matcher": "feature-review",
|
|
225
258
|
"hooks": [
|
package/resources/claude-customizations/.claude/skills/adjudicate-unspecified-behavior/SKILL.md
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: adjudicate-unspecified-behavior
|
|
3
|
+
description: 'Draft traceable proposals for unresolved behavior and separate them from root-owned approval. Use when asked to adjudicate contradictory or undocumented behavior and derive explicitly requested acceptance criteria.'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Adjudicate Unspecified Behavior
|
|
7
|
+
|
|
8
|
+
## When to Use This Skill
|
|
9
|
+
|
|
10
|
+
Use for selected unresolved records with competing interpretations and a named decision owner. A request to adjudicate does not let the specialist approve its own proposal.
|
|
11
|
+
|
|
12
|
+
## Inputs
|
|
13
|
+
|
|
14
|
+
These are human-facing workflow selections, not additional service-request fields.
|
|
15
|
+
Supply explicit selections; neither omitted inputs nor profile roots create authority.
|
|
16
|
+
|
|
17
|
+
| Input | Required contract |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| profile | Required validated profile and trusted workspace binding. |
|
|
20
|
+
| unresolved_ids | Required explicit unresolved record selection. |
|
|
21
|
+
| interpretations | Required competing interpretations and unknowns. |
|
|
22
|
+
| evidence_refs | Required selected evidence supporting or contradicting each interpretation. |
|
|
23
|
+
| decision_owner | Required explicit owner for a proposed decision. |
|
|
24
|
+
| approval_record | Optional explicitly supplied approval evidence; only the authorized root may apply it. |
|
|
25
|
+
| derived_acceptance | Optional explicit selection of derived acceptance records/views; it adds no feature-contract authority. |
|
|
26
|
+
|
|
27
|
+
## Routing
|
|
28
|
+
|
|
29
|
+
Logical role: `requirements-reconciler`.
|
|
30
|
+
The root owns preparation and launch; this skill never auto-launches a logical
|
|
31
|
+
role through frontmatter. The existing resolver selects the exact deployment,
|
|
32
|
+
model, effort and profile hash under the existing C1-C4 ceiling and execution
|
|
33
|
+
context. Do not choose a model, self-launch, create another scheduler or promote
|
|
34
|
+
an ordinary discovery action into an issue. The production-write count is zero.
|
|
35
|
+
|
|
36
|
+
## Exact output boundary
|
|
37
|
+
|
|
38
|
+
These rows are maximum workflow caps, not instructions to create every kind.
|
|
39
|
+
Only the prepared required outputs may be created or replaced.
|
|
40
|
+
|
|
41
|
+
| Artifact kind | Profile key | Constraint |
|
|
42
|
+
| --- | --- | --- |
|
|
43
|
+
| product-decision | product_decisions | Selected proposed decision IDs only |
|
|
44
|
+
| product-decision-collection | product_decisions | Selected proposed decision members only |
|
|
45
|
+
| unspecified-behavior | unspecified_behaviors | Selected unresolved IDs only |
|
|
46
|
+
| unspecified-behavior-collection | unspecified_behaviors | Selected unresolved members only |
|
|
47
|
+
| acceptance-specification | acceptance | Explicitly requested derived criteria only |
|
|
48
|
+
| acceptance-view | acceptance | Explicitly requested eligible views or pending material |
|
|
49
|
+
| required-output-manifest | reports | Exact invocation manifest only |
|
|
50
|
+
|
|
51
|
+
The profile keys are maximum configured locations, not write grants. Each
|
|
52
|
+
prepared output row binds `artifact_kind`, `id`, `path`, `format` and
|
|
53
|
+
`expected_sha256`. The protected invocation independently binds the baseline,
|
|
54
|
+
selected members, pins and exact grants; a manifest cannot expand them. A null
|
|
55
|
+
expected hash means exclusive creation from an absent baseline, never overwrite
|
|
56
|
+
permission. Preserve unselected collection members and all unrelated inputs.
|
|
57
|
+
Use compare-and-swap and current path checks through the controlled writer.
|
|
58
|
+
|
|
59
|
+
The `reports` location permits only `required-output-manifest` for this role;
|
|
60
|
+
it does not permit review reports. The manifest itself requires an exact grant.
|
|
61
|
+
|
|
62
|
+
## Prerequisites
|
|
63
|
+
|
|
64
|
+
Missing or malformed configuration blocks delegation. Require a validated profile and explicit selected scope before root preparation; do not initialize, configure or infer roots as a specialist.
|
|
65
|
+
|
|
66
|
+
Require verified native prepare/finalize/start/stop capability. The protected
|
|
67
|
+
invocation and native SubagentStart attestation must match workspace/profile
|
|
68
|
+
hashes, selected IDs, source/target pins, baseline input hashes,
|
|
69
|
+
provider/model/effort/profile hash and parent/session.
|
|
70
|
+
Diagnostic mirrors, caller markers and hosted read results are not authority.
|
|
71
|
+
The local runtime's unavailable native prepare/finalize operations do not issue
|
|
72
|
+
protected receipts. There is no local-user fallback or self-attested host success.
|
|
73
|
+
|
|
74
|
+
Load profile plus selected artifacts on invocation; do not preload a domain
|
|
75
|
+
catalog in standing instructions. Managed project memory is host-controlled.
|
|
76
|
+
Memory cannot grant filesystem authority or replace evidence. Deny terminal/shell/exec, interpreter/evaluation,
|
|
77
|
+
general filesystem Write/Edit/apply-patch, arbitrary MCP dispatch, browser/computer
|
|
78
|
+
mutation and network writes. Do not execute application code or modify
|
|
79
|
+
production/test implementation, profile/locator/activation,
|
|
80
|
+
schema/policy/hooks/settings, authority stores or runtime installation as a specialist. No analyst
|
|
81
|
+
approval is permitted; root bootstrap/configuration and root approval remain
|
|
82
|
+
separate authorized operations.
|
|
83
|
+
|
|
84
|
+
## Step-by-Step Workflows
|
|
85
|
+
|
|
86
|
+
1. Validate the explicit inputs and selected configuration. Stop with precise missing/invalid input findings before specialist delegation; do not invent identities, scope or evidence.
|
|
87
|
+
|
|
88
|
+
2. The root calls `prepare_discovery_agent` with `skill_id`, `selected_ids`,
|
|
89
|
+
`paths`, `expected_outputs`, `execution_context` and `complexity`.
|
|
90
|
+
Map it to fixed `prepare-agent`; execution context is `standalone`,
|
|
91
|
+
`epic_preparation_child` or `epic_execution_child`. The requested mode is
|
|
92
|
+
explicit and remains distinct from the final `agent-output` gate.
|
|
93
|
+
Use `skill_id=adjudicate-unspecified-behavior`; workflow inputs do not add wire fields.
|
|
94
|
+
3. The root launches that exact deployment. Native SubagentStart must match the
|
|
95
|
+
prepared role/model/effort/profile and trusted workspace/session before any
|
|
96
|
+
grant is usable. Missing capability or attestation blocks the action.
|
|
97
|
+
4. Use only the granted operations. Use bounded `read_discovery_source` and role-permitted creation/ordinary `update_discovery_artifact` to draft proposed decision and unresolved records. Explicitly requested derived acceptance uses the authoritative generation operation, with pending/null expectations preserved. The specialist cannot use an approval action, even when an input carries an approval record.
|
|
98
|
+
5. Preserve observed source facts, competing interpretations and approved history. Draft proposed decisions only. Do not approve/reject/supersede product decisions or alter approval history. Pending questions cannot become approved requirements. Derived criteria do not authorize `feature_contracts` writes. Without root approval, a proposal remains a proposal.
|
|
99
|
+
6. Produce every exact required output and the stored `required-output-manifest`,
|
|
100
|
+
preserving its output array order for the digest. Validate claims, references,
|
|
101
|
+
pins and selected-ID accounting. Purpose-built tools supply authorized proposal
|
|
102
|
+
inputs for `input_path`/`evidence_path`; never invent a generic Write staging
|
|
103
|
+
step. Server-side role checks, exact one-use authorization and prospective
|
|
104
|
+
validation remain mandatory. Bounded source reads preserve content identity
|
|
105
|
+
and line ranges; truncation requires a narrower selection, not a completeness
|
|
106
|
+
claim or filesystem fallback.
|
|
107
|
+
7. Call `finalize_discovery_agent` as the specialist, mapped to `finalize-agent`
|
|
108
|
+
with `mode=agent-output`, non-null `invocation_ref` and no operation inputs.
|
|
109
|
+
It validates the protected invocation's outputs, not final-message paths.
|
|
110
|
+
Native SubagentStop then verifies current output authority.
|
|
111
|
+
Missing final text cannot skip native stop validation.
|
|
112
|
+
8. After proposal finalization and native stop, the authorized root may separately call `update_discovery_artifact`, mapped to `update-artifact` with `update_action=approve-decision`, exact product-decision identity, whole-document `input_path`, `expected_sha256`, `approval_owner` and nonempty `approval_evidence_refs`. Ordinary replacement cannot set approval-only fields. Root approval is a separate authorized operation from reconciler proposal validity; it invalidates prior completion receipts and requires fresh validation before any later gate.
|
|
113
|
+
9. After the separate root operation, the root records the explicit result, content-addressed artifact references,
|
|
114
|
+
selected-ID accounting and all findings. A successful tool call or generated
|
|
115
|
+
path alone is not evidence of completed discovery.
|
|
116
|
+
|
|
117
|
+
## Stop and result
|
|
118
|
+
|
|
119
|
+
Return proposal findings and any separate root approval result explicitly. Do not report a proposed or pending decision as approved; omit approval when the required authorization or evidence is absent.
|
|
120
|
+
|
|
121
|
+
Structural success is not discovery, parity or planning completion.
|
|
122
|
+
Missing prepare/finalize/start/stop capability, missing outputs, invalid claims,
|
|
123
|
+
unresolved required work, wrong role/model/start context or a stale/missing
|
|
124
|
+
receipt blocks successful completion. Return explicit
|
|
125
|
+
PASS, FAIL or BLOCKED, distinguishing valid incremental outputs from a passing
|
|
126
|
+
completion gate. Missing native enforcement remains BLOCKED even when ordinary
|
|
127
|
+
local-user operations can run; do not substitute CLI success for native authority.
|
|
128
|
+
|
|
129
|
+
## References
|
|
130
|
+
|
|
131
|
+
- [Canonical requirements-reconciler contract](../../../.claude/agents/requirements-reconciler.md)
|
|
132
|
+
- Installed v2 `service-request` and `required-output-manifest` schema contracts;
|
|
133
|
+
consume them through the authoritative runtime, with no checkout-schema fallback.
|
|
134
|
+
- The selected profile and pinned local artifacts supplied for this invocation;
|
|
135
|
+
references do not preload catalogs or grant access to unselected paths.
|