@danmoisan/drm-copilot-mcp 1.1.17 → 1.1.19
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 +1405 -684
- package/package.json +6 -4
- package/resources/claude-customizations/.claude/agents/atomic-executor.md +11 -0
- package/resources/claude-customizations/.claude/agents/atomic-planner.md +10 -0
- package/resources/claude-customizations/.claude/agents/epic-orchestrator.md +12 -4
- package/resources/claude-customizations/.claude/agents/epic-planner.md +5 -4
- package/resources/claude-customizations/.claude/agents/feature-review.md +16 -5
- package/resources/claude-customizations/.claude/agents/orchestrator.md +21 -7
- package/resources/claude-customizations/.claude/agents/parallel-orchestrator.md +37 -13
- package/resources/claude-customizations/.claude/agents/parallel-planner.md +9 -6
- package/resources/claude-customizations/.claude/agents/pr-author.md +15 -2
- package/resources/claude-customizations/.claude/agents/prd-feature.md +1 -1
- package/resources/claude-customizations/.claude/hooks/check-powershell-test-purity.ps1 +7 -1
- package/resources/claude-customizations/.claude/hooks/check-python-test-purity.ps1 +7 -1
- package/resources/claude-customizations/.claude/hooks/enforce-checkpoint-monotonic.ps1 +7 -1
- package/resources/claude-customizations/.claude/hooks/enforce-completion-consistency.ps1 +111 -46
- package/resources/claude-customizations/.claude/hooks/enforce-completion-helpers.ps1 +105 -0
- package/resources/claude-customizations/.claude/hooks/enforce-discovery-artifact-gate.ps1 +8 -1
- package/resources/claude-customizations/.claude/hooks/enforce-epic-invocation-origin.ps1 +7 -1
- package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate-resolution.ps1 +116 -59
- package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate.ps1 +55 -23
- package/resources/claude-customizations/.claude/hooks/enforce-epic-wave-barrier.ps1 +74 -75
- package/resources/claude-customizations/.claude/hooks/enforce-epic-worktree-removal-gate-resolution.ps1 +127 -35
- package/resources/claude-customizations/.claude/hooks/enforce-epic-worktree-removal-gate.ps1 +61 -57
- package/resources/claude-customizations/.claude/hooks/enforce-evidence-locations.ps1 +7 -1
- package/resources/claude-customizations/.claude/hooks/enforce-feature-folder-order.ps1 +129 -39
- package/resources/claude-customizations/.claude/hooks/enforce-mermaid-validation.ps1 +7 -1
- package/resources/claude-customizations/.claude/hooks/enforce-model-routing-receipt.ps1 +9 -3
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1 +39 -51
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-helpers.ps1 +31 -58
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-modes.ps1 +63 -47
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-targets.ps1 +433 -0
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate.ps1 +17 -12
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-abandon-gate.ps1 +9 -3
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-cohort-barrier.ps1 +65 -50
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-drift-gate.ps1 +49 -42
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-worktree-removal-gate.ps1 +54 -72
- package/resources/claude-customizations/.claude/hooks/enforce-powershell-batch-budget.ps1 +8 -2
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-command-allowlist.ps1 +279 -0
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill-helpers.ps1 +129 -75
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.artifact-root.ps1 +233 -0
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.docs-only.ps1 +224 -0
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.ps1 +69 -24
- package/resources/claude-customizations/.claude/hooks/enforce-prd-feature-before-planner-helpers.ps1 +29 -18
- package/resources/claude-customizations/.claude/hooks/enforce-prd-feature-before-planner.ps1 +10 -4
- package/resources/claude-customizations/.claude/hooks/enforce-promotion-mcp-only.ps1 +14 -5
- package/resources/claude-customizations/.claude/hooks/enforce-python-batch-budget.ps1 +8 -2
- package/resources/claude-customizations/.claude/hooks/feature-folder-resolution.ps1 +373 -0
- package/resources/claude-customizations/.claude/hooks/feature-review-coverage-thresholds.ps1 +85 -0
- package/resources/claude-customizations/.claude/hooks/hook-command-heredoc.ps1 +119 -0
- package/resources/claude-customizations/.claude/hooks/hook-command-invocation-operands.ps1 +198 -0
- package/resources/claude-customizations/.claude/hooks/hook-command-invocation.ps1 +254 -255
- package/resources/claude-customizations/.claude/hooks/hook-command-payload-powershell.ps1 +201 -0
- package/resources/claude-customizations/.claude/hooks/hook-command-payload.ps1 +484 -0
- package/resources/claude-customizations/.claude/hooks/hook-command-scanner.ps1 +27 -110
- package/resources/claude-customizations/.claude/hooks/hook-dependency-guard.ps1 +114 -0
- package/resources/claude-customizations/.claude/hooks/hook-docs-only-diff.ps1 +493 -0
- package/resources/claude-customizations/.claude/hooks/subagentstop-envelope.ps1 +192 -0
- package/resources/claude-customizations/.claude/hooks/validate-bash.ps1 +9 -3
- package/resources/claude-customizations/.claude/hooks/validate-discovery-artifact-gate.ps1 +40 -42
- package/resources/claude-customizations/.claude/hooks/validate-executor-output.ps1 +66 -38
- package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage-metrics.ps1 +180 -0
- package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage-rules.ps1 +195 -0
- package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage.ps1 +141 -395
- package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output-resolution.ps1 +311 -0
- package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output-routing.ps1 +170 -0
- package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output.ps1 +115 -190
- package/resources/claude-customizations/.claude/hooks/validate-planner-output.ps1 +64 -32
- package/resources/claude-customizations/.claude/hooks/validate-pr-author-output.ps1 +39 -44
- package/resources/claude-customizations/.claude/hooks/validate-prd-feature-output.ps1 +43 -14
- package/resources/claude-customizations/.claude/hooks/validate-required-artifact-output.ps1 +66 -36
- package/resources/claude-customizations/.claude/hooks/validate-task-researcher-output.ps1 +31 -34
- package/resources/claude-customizations/.claude/lib/bash/mutate-parallel-run.sh +191 -0
- package/resources/claude-customizations/.claude/lib/bash/parallel-cohorts.sh +13 -3
- package/resources/claude-customizations/.claude/lib/bash/parallel-lane-assertion.sh +4 -2
- package/resources/claude-customizations/.claude/lib/bash/parallel-mutation-cli.sh +152 -0
- package/resources/claude-customizations/.claude/lib/bash/parallel-mutation-ops.sh +193 -0
- package/resources/claude-customizations/.claude/lib/bash/parallel-mutation.sh +322 -0
- package/resources/claude-customizations/.claude/lib/bash/remove-parallel-item.sh +146 -0
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusExtraction.psm1 +23 -33
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusTokenShape.psm1 +86 -6
- package/resources/claude-customizations/.claude/lib/ci-gate/Invoke-CiGateParser.ps1 +91 -19
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorState.psm1 +6 -13
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateEpicWaveBarrier.psm1 +346 -0
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateIssueAdoption.psm1 +396 -0
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateReceipts.psm1 +22 -15
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateRemediationAccounting.psm1 +337 -0
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateRoutingContract.psm1 +9 -1
- package/resources/claude-customizations/.claude/lib/worktree-resolution/WorktreeItemResolution.psm1 +79 -2
- package/resources/claude-customizations/.claude/lib/worktree-resolution/WorktreeRunResolution.psm1 +3 -3
- package/resources/claude-customizations/.claude/rules/architecture-boundaries.md +5 -5
- package/resources/claude-customizations/.claude/rules/csharp.md +2 -2
- package/resources/claude-customizations/.claude/rules/general-code-change.md +1 -1
- package/resources/claude-customizations/.claude/rules/general-unit-test.md +3 -2
- package/resources/claude-customizations/.claude/rules/orchestrator-state.md +153 -4
- package/resources/claude-customizations/.claude/rules/parallel-orchestration.md +50 -5
- package/resources/claude-customizations/.claude/rules/plan-acceptance-gates.md +47 -8
- package/resources/claude-customizations/.claude/rules/quality-tiers.md +11 -7
- package/resources/claude-customizations/.claude/rules/shell.md +10 -8
- package/resources/claude-customizations/.claude/rules/typescript.md +1 -1
- package/resources/claude-customizations/.claude/settings.json +3 -4
- package/resources/claude-customizations/.claude/skills/acceptance-criteria-tracking/SKILL.md +9 -1
- package/resources/claude-customizations/.claude/skills/atomic-plan-contract/SKILL.md +7 -1
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/SKILL.md +11 -3
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup-worktrees.sh +11 -2
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_detached_lib.sh +1 -1
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_enumerate_lib.sh +171 -5
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_preserve_lib.sh +1 -1
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_report_records_lib.sh +6 -43
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_scan_helper.sh +6 -15
- package/resources/claude-customizations/.claude/skills/epic-orchestrate/SKILL.md +45 -11
- package/resources/claude-customizations/.claude/skills/epic-plan/SKILL.md +1 -1
- package/resources/claude-customizations/.claude/skills/evidence-and-timestamp-conventions/SKILL.md +13 -0
- package/resources/claude-customizations/.claude/skills/feature-promotion-lifecycle/SKILL.md +10 -0
- package/resources/claude-customizations/.claude/skills/feature-review-workflow/SKILL.md +7 -4
- package/resources/claude-customizations/.claude/skills/orchestrate/SKILL.md +42 -16
- package/resources/claude-customizations/.claude/skills/parallel-add/SKILL.md +52 -14
- package/resources/claude-customizations/.claude/skills/parallel-close/SKILL.md +22 -9
- package/resources/claude-customizations/.claude/skills/parallel-orchestrate/SKILL.md +97 -19
- package/resources/claude-customizations/.claude/skills/parallel-plan/SKILL.md +63 -7
- package/resources/claude-customizations/.claude/skills/parallel-remove/SKILL.md +35 -12
- package/resources/claude-customizations/.claude/skills/pr-author/SKILL.md +3 -1
- package/resources/claude-customizations/.claude/skills/quota-throttling/SKILL.md +1 -1
- package/resources/claude-customizations/.claude/skills/remediation-handoff-atomic-planner/SKILL.md +7 -3
- package/resources/claude-customizations/pack-manifests/core.json +25 -0
- package/resources/codex-and-agents-customizations/.agents/skills/acceptance-criteria-tracking/SKILL.md +9 -1
- package/resources/codex-and-agents-customizations/.agents/skills/architecture-boundaries/SKILL.md +5 -5
- package/resources/codex-and-agents-customizations/.agents/skills/atomic-executor/SKILL.md +11 -0
- package/resources/codex-and-agents-customizations/.agents/skills/atomic-plan-contract/SKILL.md +4 -0
- package/resources/codex-and-agents-customizations/.agents/skills/atomic-planner/SKILL.md +10 -0
- package/resources/codex-and-agents-customizations/.agents/skills/csharp/SKILL.md +2 -2
- package/resources/codex-and-agents-customizations/.agents/skills/csharp-qa-gate/SKILL.md +2 -2
- package/resources/codex-and-agents-customizations/.agents/skills/epic-orchestrate/SKILL.md +13 -3
- package/resources/codex-and-agents-customizations/.agents/skills/epic-plan/SKILL.md +17 -1
- package/resources/codex-and-agents-customizations/.agents/skills/epic-run/SKILL.md +2 -1
- package/resources/codex-and-agents-customizations/.agents/skills/evidence-and-timestamp-conventions/SKILL.md +13 -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 +30 -6
- package/resources/codex-and-agents-customizations/.agents/skills/feature-review-workflow/SKILL.md +16 -6
- package/resources/codex-and-agents-customizations/.agents/skills/general-code-change/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents/skills/general-unit-test/SKILL.md +3 -2
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrate/SKILL.md +43 -11
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrator-state/SKILL.md +41 -2
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrator-workflow/SKILL.md +19 -4
- package/resources/codex-and-agents-customizations/.agents/skills/quality-tiers/SKILL.md +11 -7
- package/resources/codex-and-agents-customizations/.agents/skills/remediation-handoff-atomic-planner/SKILL.md +2 -0
- package/resources/codex-and-agents-customizations/.agents/skills/translate-claude-to-codex/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents-variants/csharp-legacy/skills/csharp/SKILL.md +2 -2
- package/resources/codex-and-agents-customizations/.agents-variants/csharp-legacy/skills/csharp-qa-gate/SKILL.md +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c1.toml +11 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c2.toml +11 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c3-elevated.toml +11 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c3.toml +11 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c4.toml +11 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor.toml +11 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c1.toml +10 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c2.toml +10 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c3-elevated.toml +10 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c3.toml +10 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c4.toml +10 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner.toml +10 -0
- package/resources/codex-and-agents-customizations/.codex/agents/epic-orchestrator.toml +2 -1
- package/resources/codex-and-agents-customizations/.codex/agents/feature-review.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer-c1.toml +1 -0
- package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer-c2.toml +1 -0
- package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer-c3-elevated.toml +1 -0
- package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer-c3.toml +1 -0
- package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer-c4.toml +1 -0
- package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer.toml +1 -0
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c1.toml +3 -3
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c2.toml +3 -3
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c3-elevated.toml +3 -3
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c3.toml +3 -3
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c4.toml +3 -3
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator.toml +3 -3
- package/resources/codex-and-agents-customizations/.codex/codex-web-setup.sh +318 -273
- package/resources/codex-and-agents-customizations/.codex/config.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/check-powershell-test-purity.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/check-python-test-purity.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/codex-epic-child-launch-attestation.ps1 +1 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-checkpoint-monotonic.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-codex-model-routing.ps1 +8 -2
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-completion-consistency.ps1 +97 -44
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-completion-helpers.ps1 +105 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-child-worktree-binding.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-merge-gate.ps1 +37 -5
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-planning-only.ps1 +6 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-root-invocation.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-wave-barrier.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-worktree-removal-gate.ps1 +54 -41
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-evidence-locations.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1 +35 -14
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-helpers.ps1 +31 -58
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-modes.ps1 +63 -47
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-targets.ps1 +433 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate.ps1 +24 -11
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-powershell-batch-budget.ps1 +8 -2
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-promotion-mcp-only.ps1 +13 -4
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-python-batch-budget.ps1 +8 -2
- package/resources/codex-and-agents-customizations/.codex/hooks/feature-folder-resolution.ps1 +373 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/feature-review-coverage-thresholds.ps1 +85 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-heredoc.ps1 +119 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-invocation-operands.ps1 +198 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-invocation.ps1 +254 -255
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-payload-powershell.ps1 +201 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-payload.ps1 +484 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-scanner.ps1 +27 -110
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-dependency-guard.ps1 +114 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-docs-only-diff.ps1 +493 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/validate-bash.ps1 +8 -2
- package/resources/codex-and-agents-customizations/.codex/hooks/validate-codex-subagent-routing.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/validate-feature-review-coverage.ps1 +24 -8
- package/resources/codex-and-agents-customizations/pack-manifests/core.json +9 -0
- package/resources/customizations/.github/agents/csharp-typed-engineer.agent.md +2 -2
- package/resources/customizations/.github/instructions/csharp-code-change.instructions.md +4 -4
- package/resources/customizations/.github/instructions/csharp-unit-test.instructions.md +2 -2
- package/resources/customizations/.github/skills/acceptance-criteria-tracking/SKILL.md +9 -1
- package/resources/customizations/.github/skills/atomic-plan-contract/SKILL.md +4 -0
- package/resources/customizations/.github/skills/evidence-and-timestamp-conventions/SKILL.md +13 -0
- package/resources/customizations/.github/skills/feature-review-workflow/SKILL.md +1 -1
- package/resources/powershell/PoshQC/PoshQC.Coverage.psm1 +314 -0
- package/resources/powershell/PoshQC/PoshQC.Testing.psm1 +25 -28
- package/resources/powershell/PoshQC/PoshQC.psm1 +1 -0
- package/resources/powershell/PoshQC/README.md +8 -2
- package/resources/powershell/PoshQC/settings/pester.runsettings.psd1 +2 -315
|
@@ -24,7 +24,7 @@ description: Checkpoint invariants for the orchestration state artifact and the
|
|
|
24
24
|
|
|
25
25
|
# Orchestrator-State Remediation-Cycle and Human-Interaction Invariants
|
|
26
26
|
|
|
27
|
-
This rule governs remediation-cycle records and the optional `human_interaction` block in the orchestrator-state checkpoint at `artifacts/orchestration/orchestrator-state.json`. It documents
|
|
27
|
+
This rule governs remediation-cycle records and the optional `human_interaction` block in the orchestrator-state checkpoint at `artifacts/orchestration/orchestrator-state.json`. It documents the invariants that must hold for each remediation cycle and for the remediation-loop review outcomes and attempt count, plus three invariants for the `human_interaction` block, so that resume and review workflows do not depend on a structurally invalid checkpoint.
|
|
28
28
|
|
|
29
29
|
## Foreign Schema Warning (do not copy verbatim)
|
|
30
30
|
|
|
@@ -32,9 +32,40 @@ A hardened snapshot from another repository contains a JSON Schema for the orche
|
|
|
32
32
|
|
|
33
33
|
This prohibition is specific to the disqualified foreign schema identified by the `drmoisan.github.io/mix-calculator/` `$id`. A schema whose `$id` is repo-local and whose required-field set and `additionalProperties` policy match this repository's checkpoint contract is not the disqualified foreign artifact; even so, the repository's enforcement mechanism remains the Python validator prose-and-logic above, not an imported schema file.
|
|
34
34
|
|
|
35
|
+
## Required Top-Level Keys
|
|
36
|
+
|
|
37
|
+
Plain validation requires every key below at the top level of the orchestrator-state checkpoint. The authority is `REQUIRED_STATE_KEYS` in `scripts/dev_tools/validate_orchestrator_state.py`. The TypeScript port in `extensions/drm-copilot/src/lib/validate/orchestrator-state-core.ts` and the PowerShell port in `.claude/lib/orchestrator-state/OrchestratorState.psm1` carry the same keys in the same order.
|
|
38
|
+
|
|
39
|
+
- `objective`
|
|
40
|
+
- `change_budget_estimate`
|
|
41
|
+
- `path_selected`
|
|
42
|
+
- `promotion-type`
|
|
43
|
+
- `short-name`
|
|
44
|
+
- `relativeFile`
|
|
45
|
+
- `long-name`
|
|
46
|
+
- `issue-num`
|
|
47
|
+
- `feature-folder`
|
|
48
|
+
- `work-mode`
|
|
49
|
+
- `plan-path`
|
|
50
|
+
- `completed_steps`
|
|
51
|
+
- `next_step`
|
|
52
|
+
- `last_updated`
|
|
53
|
+
- `step5_status`
|
|
54
|
+
- `step6_status`
|
|
55
|
+
- `step7_status`
|
|
56
|
+
- `step8_status`
|
|
57
|
+
- `step9_status`
|
|
58
|
+
- `step10_status`
|
|
59
|
+
- `delegation_receipts`
|
|
60
|
+
- `blocked_reason`
|
|
61
|
+
|
|
62
|
+
The check is unconditional: it runs with or without `--require-complete`, `--require-pr-creation-ready`, `--require-model-routing`, `--require-codex-model-routing`, and `--require-codex-topology`, and it is skipped only for a `portable_orchestration_handoff` envelope. The check is presence-only: a key whose value is any JSON value, including `null`, satisfies it. Each absent key produces one error line, `Checkpoint missing required key: <key>`. Some keys carry further validation when present, such as the step-status vocabulary for the `step*_status` keys and the Blocked-Reason Vocabulary below for `blocked_reason`.
|
|
63
|
+
|
|
64
|
+
`last_updated` records when the checkpoint was last written. Write it as an ISO-8601 UTC date-time string, for example `2026-10-08T17:28:00Z`. The value is rewritten on every checkpoint write: after every completed step and every state transition, including halts. The validators check presence only and do not parse the value, so a non-UTC, placeholder, or `null` value still passes the required-key check.
|
|
65
|
+
|
|
35
66
|
## Scope and Backward Compatibility
|
|
36
67
|
|
|
37
|
-
These invariants apply only when the checkpoint contains a top-level `remediation_loop
|
|
68
|
+
These invariants apply only when the checkpoint contains a top-level `remediation_loop`; the per-cycle invariants apply when it has a `cycles` array, and the review-outcome and attempt-count invariants apply when their keys are present. A checkpoint with no `remediation_loop` (the existing step-based checkpoint shape) is unaffected: it validates exactly as before and produces no new errors. The invariants are additive.
|
|
38
69
|
|
|
39
70
|
## Invariants (per remediation cycle)
|
|
40
71
|
|
|
@@ -44,6 +75,45 @@ These invariants apply only when the checkpoint contains a top-level `remediatio
|
|
|
44
75
|
|
|
45
76
|
3. **Exit gate requires zero blocking findings.** When a cycle's `exit_condition_met == true`, its `blocking_count` must be `0`. A non-zero `blocking_count` with `exit_condition_met == true` is a malformed cycle (the exit gate was marked satisfied while blocking findings remained).
|
|
46
77
|
|
|
78
|
+
4. **`candidate_applied` is a boolean (R5).** When a cycle object carries `candidate_applied`, its value must be a JSON boolean, and any other value is a malformed cycle.
|
|
79
|
+
|
|
80
|
+
5. **A completed attempt requires completed execution (R6).** A cycle whose `candidate_applied == true` must have `execution_status == "complete"`, and `candidate_applied == true` with any other execution status is a malformed cycle.
|
|
81
|
+
|
|
82
|
+
6. **`opened_by_review` references a remediation review (R11).** When a cycle object carries `opened_by_review`, its value must be a non-negative integer (not a boolean) that indexes an object entry of the `remediation_loop.review_outcomes` list whose `verdict` is `REMEDIATION_REQUIRED`, and a value that is not such an integer, is out of range, or references an outcome with any other verdict is a malformed cycle.
|
|
83
|
+
|
|
84
|
+
7. **`completed_attempts` counts completed attempts (R7).** When `remediation_loop.completed_attempts` is present, it must be a non-negative integer (not a boolean) equal to the number of object cycles whose `candidate_applied` is `true` (zero when `cycles` is absent or not a list), and any other value is a malformed loop.
|
|
85
|
+
|
|
86
|
+
## Invariants (remediation_loop.review_outcomes)
|
|
87
|
+
|
|
88
|
+
These invariants apply only when `remediation_loop` contains a `review_outcomes` key. The orchestrator appends one entry per review, including a `PASS` review, in the shape `{"verdict": <verdict>, "findings": [{"remediability": <class>}, ...]}`, where `findings` lists the review's blocking findings only. A halt or wait verdict records no remediation cycle.
|
|
89
|
+
|
|
90
|
+
Review verdicts (exact, case-sensitive):
|
|
91
|
+
|
|
92
|
+
| Verdict | Condition over the classes of the review's blocking findings |
|
|
93
|
+
|---|---|
|
|
94
|
+
| `PASS` | No blocking findings. |
|
|
95
|
+
| `REMEDIATION_REQUIRED` | At least one `autonomous` finding. |
|
|
96
|
+
| `HALT_NON_REMEDIABLE` | No `autonomous` finding, and at least one `external_dependency`, `policy_hold`, or `human_decision_required` finding. |
|
|
97
|
+
| `AWAITING_CI` | At least one finding, and every finding is `awaiting_ci`. |
|
|
98
|
+
|
|
99
|
+
Remediability classes (exact, case-sensitive) and the `blocked_reason` member (#523) that a halt or wait records for each class:
|
|
100
|
+
|
|
101
|
+
| Class | Meaning | `blocked_reason` member |
|
|
102
|
+
|---|---|---|
|
|
103
|
+
| `autonomous` | Repository remediation can resolve the finding without a human decision. | none (remediation loop) |
|
|
104
|
+
| `external_dependency` | A system, service, runtime, or published artifact outside the repository is unavailable or mismatched. | `external_dependency` |
|
|
105
|
+
| `policy_hold` | Proceeding requires a policy decision, exception, or authorization that the orchestrator may not grant. | `policy_hold` |
|
|
106
|
+
| `awaiting_ci` | The finding resolves when a CI result that has not completed becomes available. | `awaiting_ci` |
|
|
107
|
+
| `human_decision_required` | A human must choose between alternatives or approve a direction. | `human_decision_required` |
|
|
108
|
+
|
|
109
|
+
Derivation order. The verdict is a pure function of the findings' classes, evaluated in this order: no findings yields `PASS`; any `autonomous` finding yields `REMEDIATION_REQUIRED`; any `external_dependency`, `policy_hold`, or `human_decision_required` finding yields `HALT_NON_REMEDIABLE`; otherwise the verdict is `AWAITING_CI`.
|
|
110
|
+
|
|
111
|
+
1. **`review_outcomes` is a list of objects (R8).** `review_outcomes` must be a list, and each entry must be an object. A non-list value or a non-object entry is malformed.
|
|
112
|
+
|
|
113
|
+
2. **Verdict and class membership (R9).** Each outcome's `verdict` must be a string among the four verdicts, its `findings` must be a list (a missing key is not a list), and each finding must be an object whose `remediability` is a string among the five classes. Comparisons are case-sensitive, so a case variant such as `Pass` or `Autonomous` is malformed.
|
|
114
|
+
|
|
115
|
+
3. **Verdict matches its findings (R10).** When an outcome passes the membership checks, its `verdict` must equal the verdict that the derivation order yields for its findings' classes. A mismatch is a malformed outcome.
|
|
116
|
+
|
|
47
117
|
## Human-Interaction Scope and Backward Compatibility
|
|
48
118
|
|
|
49
119
|
These invariants apply only when the checkpoint contains a top-level `human_interaction` block. A checkpoint with no `human_interaction` key (the existing checkpoint shape) is unaffected: it validates exactly as before and produces no new errors. The invariants are additive and support the autonomous-execution mandate documented in `.claude/skills/orchestrate/SKILL.md`.
|
|
@@ -56,6 +126,41 @@ These invariants apply only when the checkpoint contains a top-level `human_inte
|
|
|
56
126
|
|
|
57
127
|
3. **Exception requires `runbook_path`.** A requirement whose `response == "exception"` must carry a non-empty `runbook_path` string. A missing, non-string, or empty/whitespace-only `runbook_path` on an `exception` requirement is a malformed requirement.
|
|
58
128
|
|
|
129
|
+
## Blocked-Reason Vocabulary
|
|
130
|
+
|
|
131
|
+
The checkpoint key `blocked_reason` accepts exactly the twelve members below. The authoritative definition is `scripts/dev_tools/_orchestrator_state_blocked_reason.py`; the TypeScript module `extensions/drm-copilot/src/lib/validate/orchestrator-state-blocked-reason.ts` and the grouped arrays in `.claude/lib/orchestrator-state/OrchestratorState.psm1` mirror it.
|
|
132
|
+
|
|
133
|
+
| Member | Partition | Definition |
|
|
134
|
+
|---|---|---|
|
|
135
|
+
| `none` | not blocked | The run is not blocked. JSON `null` is equivalent for classification. |
|
|
136
|
+
| `spawn_agent_unavailable` | mechanical | Existing member; meaning unchanged. |
|
|
137
|
+
| `delegation_launch_failed` | mechanical | Existing member; meaning unchanged. |
|
|
138
|
+
| `delegate_no_receipt` | mechanical | Existing member; meaning unchanged. |
|
|
139
|
+
| `delegate_contract_incomplete` | mechanical | Existing member; meaning unchanged. |
|
|
140
|
+
| `validator_failed` | mechanical | Existing member; meaning unchanged. |
|
|
141
|
+
| `user_requested_stop` | mechanical | Existing member; meaning unchanged. |
|
|
142
|
+
| `premise_falsified` | non-mechanical | Every delegation and validator succeeded, but evidence gathered during execution falsified the premise on which the plan was built, so continuing would implement an invalid plan. |
|
|
143
|
+
| `external_dependency` | non-mechanical | The run cannot proceed because a system, service, runtime, or artifact outside the repository's control is unavailable or mismatched, and no in-repository remediation can resolve it. |
|
|
144
|
+
| `policy_hold` | non-mechanical | The run is stopped because proceeding requires a policy decision, exception, or authorization that the orchestrator is not permitted to grant autonomously. |
|
|
145
|
+
| `awaiting_ci` | non-mechanical | The run is waiting for a CI result that has not yet completed, and no remediation is warranted until that result is available. |
|
|
146
|
+
| `human_decision_required` | non-mechanical | The run requires a human to choose between alternatives or approve a direction before it can continue. |
|
|
147
|
+
|
|
148
|
+
Partition definitions:
|
|
149
|
+
|
|
150
|
+
- **Not blocked:** `none`, JSON `null`, or key absent at a gate. Plain validation still reports an absent key through the required-key check.
|
|
151
|
+
- **Mechanical:** the orchestration process itself did not complete a step: a tool or delegation failed, a delegate returned no or an incomplete receipt, a validator failed, or the operator stopped execution. Membership is defined by the published constant, not by the wording.
|
|
152
|
+
- **Non-mechanical:** every process step could proceed, but the work cannot continue for a reason that no retry or remediation cycle of the process resolves.
|
|
153
|
+
|
|
154
|
+
The classification is recoverable from `blocked_reason` alone by looking the value up in the published partition (`classify_blocked_reason` in Python, `classifyBlockedReason` in TypeScript).
|
|
155
|
+
|
|
156
|
+
Enforcement parity: the Python, PowerShell, and TypeScript validators enforce this vocabulary identically, with case-sensitive comparison. A value outside the vocabulary, including a case variant of any member, is rejected with `Checkpoint has invalid blocked_reason: <value>`. Every non-`none` member, including the five non-mechanical members, blocks completion and PR-creation readiness with the existing messages.
|
|
157
|
+
|
|
158
|
+
Relationship to `human_interaction.requirements[].response == "halt"`: a human-decision halt may appear in both places. `blocked_reason: "human_decision_required"` classifies the run's halt, and a `human_interaction.requirements[]` entry with `response: "halt"` describes the specific requirement. There is no cross-field rule between them: either may appear without the other, and neither is validated against the other.
|
|
159
|
+
|
|
160
|
+
Producer guidance for `premise_falsified`: set it when every delegation and validator succeeded but evidence gathered during execution falsified the plan's premise. The evidence path is still recorded in free-form checkpoint keys; `blocked_reason` carries the classification only.
|
|
161
|
+
|
|
162
|
+
Extension point for #484: #484 consumes `external_dependency`, `policy_hold`, `awaiting_ci`, and `human_decision_required` without renaming, removing, or re-partitioning them; any further halt class is a separate contract change that appends the literal to the non-mechanical partition in all three runtimes, updates the partition oracle and corpus, and updates this section.
|
|
163
|
+
|
|
59
164
|
## Complexity-Assessment Scope and Backward Compatibility
|
|
60
165
|
|
|
61
166
|
These invariants apply only when the checkpoint contains a top-level `complexity_assessments` array. A checkpoint with no `complexity_assessments` key (the existing checkpoint shape) is unaffected: it validates exactly as before and produces no new errors. The invariants are additive and support the two-axis model-selection mechanism documented in `.claude/skills/orchestrate/SKILL.md` (`## Model Selection`). Enforcement is the Python validator, not an imported schema.
|
|
@@ -92,7 +197,11 @@ The session `model_budget.fable_policy` switch is a three-way enum `disabled | a
|
|
|
92
197
|
|
|
93
198
|
## Require-Model-Routing Mode Scope and Backward Compatibility
|
|
94
199
|
|
|
95
|
-
The complexity-assessment and model-routing-receipt invariants above are key-gated: they run only when their key is present, so a checkpoint that omits both arrays passes at every stage. The `require_model_routing` mode adds an existence gate that closes that gap without changing the default behavior. It is an opt-in keyword on `validate_orchestrator_state_text(..., require_model_routing=False)` (CLI flag `--require-model-routing
|
|
200
|
+
The complexity-assessment and model-routing-receipt invariants above are key-gated: they run only when their key is present, so a checkpoint that omits both arrays passes at every stage. The `require_model_routing` mode adds an existence gate that closes that gap without changing the default behavior. It is an opt-in keyword on `validate_orchestrator_state_text(..., require_model_routing=False)` (CLI flag `--require-model-routing`, accepted by the dispatcher `orchestrator-state` subcommand and by the bare-module CLI; MCP parameter `require_model_routing`), defaulting off. Plain, `require_complete`, and `require_pr_creation_ready` calls are unaffected and produce byte-identical results.
|
|
201
|
+
|
|
202
|
+
## Bare-Module CLI Contract
|
|
203
|
+
|
|
204
|
+
The validator module runs directly as `python -m scripts.dev_tools.validate_orchestrator_state <path> [--require-complete] [--require-model-routing] [--require-pr-creation-ready] [--require-codex-model-routing] [--require-codex-topology]`. The dispatcher stays available and accepts the same flags in two invocation forms: the module form `python -m scripts.dev_tools.validate_orchestration_artifacts orchestrator-state`, run from the repository root, and the file-path form `python scripts/dev_tools/validate_orchestration_artifacts.py orchestrator-state`. Both forms reach the same `main()`, so their flags, output lines, and exit codes are identical, and a relative artifact path resolves against the working directory in both. The file-path form derives the repository root from the script location and inserts it first in `sys.path` only when the script runs without a package context. The bare-module validator is supported in the module form only. Exit code 0 means the checkpoint passed and the success line `orchestrator-state validation passed: <path>` is written to stdout. Exit code 1 means validation errors, written one per stderr line. Exit code 2 means the path is missing, unreadable, or not UTF-8, with one stderr diagnostic and no traceback; argparse usage errors also exit 2.
|
|
96
205
|
|
|
97
206
|
## Invariants (require_model_routing mode)
|
|
98
207
|
|
|
@@ -126,7 +235,7 @@ Enforcement is validator logic plus this prose, never an imported JSON Schema. T
|
|
|
126
235
|
|
|
127
236
|
These invariants apply only when a checkpoint contains a top-level `standalone_merge_authorizations` array. The key may appear in any of the three checkpoints the epic merge gate reads: `artifacts/orchestration/orchestrator-state.json`, `artifacts/orchestration/epic-orchestrator-state.json`, and `artifacts/orchestration/parallel-orchestrator-state.json`. A checkpoint with no such key (the existing checkpoint shape) is unaffected: it validates exactly as before and produces no new errors. The invariants are additive and key-gated. No JSON Schema file is authored, imported, or read for the block (see the Foreign Schema Warning above); the enforcing surface is the `PreToolUse` merge gate (issue #670).
|
|
128
237
|
|
|
129
|
-
Each entry records one authorized standalone merge with the shape `{ pr_number, pr_url, issue_num, branch_name, authorized_by, authorized_at, session_id, basis, run_slug? }`. The gate consults the array only for a `gh pr merge --merge` command that names an explicit pull request number, and only after its per-feature, epic, and parallel allow conditions have all declined.
|
|
238
|
+
Each entry records one authorized standalone merge with the shape `{ pr_number, pr_url, issue_num, branch_name, authorized_by, authorized_at, session_id, basis, run_slug? }`. The gate consults the array only for a `gh pr merge --merge` command that names an explicit pull request number, and only after its per-feature, epic, and parallel allow conditions have all declined. For a command that names an explicit pull request number, the gate reads the per-feature checkpoint `artifacts/orchestration/orchestrator-state.json` beneath the one live worktree whose checkpoint records that number in `pr_gate.pr_number` or in a `standalone_merge_authorizations` entry, and it reads no per-feature checkpoint when no live worktree or more than one records it; a bare command reads the checkpoint beneath the session worktree.
|
|
130
239
|
|
|
131
240
|
Honest disclosure: the standalone-merge authorization record is a policy-level, auditable declaration and is
|
|
132
241
|
not a cryptographic or security control.
|
|
@@ -146,6 +255,45 @@ not a cryptographic or security control.
|
|
|
146
255
|
|
|
147
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.
|
|
148
257
|
|
|
258
|
+
## Issue-Adoption Scope and Backward Compatibility
|
|
259
|
+
|
|
260
|
+
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
|
+
|
|
262
|
+
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
|
+
|
|
264
|
+
## Invariants (issue_adoption object)
|
|
265
|
+
|
|
266
|
+
The object has the shape `{ issue_num, issue_url, origin, verified_via, verified_at, evidence, waived_tools, potential_record? }`.
|
|
267
|
+
|
|
268
|
+
| Field | Rule |
|
|
269
|
+
| --- | --- |
|
|
270
|
+
| `issue_num` | A string of decimal digits without a leading zero; equal to the checkpoint `issue-num` when that is a string. |
|
|
271
|
+
| `issue_url` | A string ending with `/issues/` followed by `issue_num`. |
|
|
272
|
+
| `origin` | One of `transferred`, `filed_before_orchestration`, `epic_decomposition`. |
|
|
273
|
+
| `verified_via` | One of `gh_issue_view`, `gh_api_get`, `github_mcp_issue_read`. |
|
|
274
|
+
| `verified_at` | Present, not `null`, and not a blank string. |
|
|
275
|
+
| `evidence` | A string with non-whitespace content. |
|
|
276
|
+
| `waived_tools` | A non-empty list of non-blank tool names that includes `potential_to_issue`. |
|
|
277
|
+
| `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`). |
|
|
278
|
+
|
|
279
|
+
The rules run in this order, and their errors accumulate:
|
|
280
|
+
|
|
281
|
+
1. A present value that is not an object (including `null`) yields `Checkpoint issue_adoption must be an object when present.` and evaluation stops.
|
|
282
|
+
2. `issue_num` must be a string of decimal digits without a leading zero (a JSON number is invalid). Only when it is valid and the checkpoint `issue-num` is a different string, `issue_num` must equal the checkpoint issue-num.
|
|
283
|
+
3. `issue_url` must end with `/issues/` followed by a valid `issue_num`.
|
|
284
|
+
4. `origin` must be one of the three origin values.
|
|
285
|
+
5. `verified_via` must be one of the three verification values.
|
|
286
|
+
6. `verified_at` must be present: absent, `null`, and blank strings are rejected; any other value passes.
|
|
287
|
+
7. `evidence` must be a non-empty string.
|
|
288
|
+
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
|
+
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.
|
|
290
|
+
|
|
291
|
+
The closed waivable set is `potential_to_issue`, `new_potential_entry`, and `new_potential_bug_entry`. `new_active_feature_folder`, `collect_pr_context`, `validate_orchestration_artifacts`, and every other tool can never be waived. All comparisons are ordinal and case-sensitive.
|
|
292
|
+
|
|
293
|
+
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
|
+
|
|
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.
|
|
296
|
+
|
|
149
297
|
## Enforcement
|
|
150
298
|
|
|
151
299
|
- `scripts/dev_tools/validate_orchestrator_state.py` appends one error per violated invariant when a `remediation_loop` is present, using the existing validator message style (literal, checkpoint-context prefixed). The validator returns a list of error strings and does not mutate its input.
|
|
@@ -157,3 +305,4 @@ Field checks 3 through 9 run in the fixed order `pr_url`, `issue_num`, `branch_n
|
|
|
157
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
|
|
158
306
|
does not currently validate standalone_merge_authorizations
|
|
159
307
|
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/`.
|
|
@@ -87,13 +87,13 @@ When `require_complete` is not passed, invariants 20 and 21 contribute zero erro
|
|
|
87
87
|
|
|
88
88
|
## Invariants (parallel planner checkpoint)
|
|
89
89
|
|
|
90
|
-
Enforced by `validate_parallel_planner_state_text(text, *, require_ready_for_execution=False)` in `scripts/dev_tools/validate_parallel_planner_state.py`. P1 through P4 are enforced unconditionally; P6 through
|
|
90
|
+
Enforced by `validate_parallel_planner_state_text(text, *, require_ready_for_execution=False)` in `scripts/dev_tools/validate_parallel_planner_state.py`. P1 through P4 are enforced unconditionally; P6 through P10 are ready-gate invariants, enforced only under `require_ready_for_execution`.
|
|
91
91
|
|
|
92
92
|
- **P1 — Required keys.** The checkpoint must carry `objective`, `parallel_slug`, `parallel_manifest_path`, `mode`, `max_concurrency`, `items`, `cohorts`, `conflict_edges`, `recolor_generation`, `completed_steps`, `next_step`, and `last_updated`. One error is emitted per missing key. `kickoff_prompt_path` is optional outside the ready gate.
|
|
93
93
|
|
|
94
94
|
- **P2 — Route-consistent identity.** `parallel_slug` and `parallel_manifest_path` must be non-empty strings; `mode` and `max_concurrency` satisfy orchestrator invariants 3 and 4.
|
|
95
95
|
|
|
96
|
-
- **P3 — Item shape.** Each `items[]` entry must carry `issue_num`, `feature_folder`, `kind`, `state`, `blast_radius`, `preparation_status`, `research_path`, `plan_path`, and `preflight_status`. `issue_num` must be a positive integer unique across items; `kind` must be in `{feature, bug}`; `state` must be in the item-state enum; `blast_radius` must satisfy orchestrator invariant 9; `complexity_band
|
|
96
|
+
- **P3 — Item shape.** Each `items[]` entry must carry `issue_num`, `feature_folder`, `kind`, `state`, `blast_radius`, `preparation_status`, `research_path`, `plan_path`, and `preflight_status`. `issue_num` must be a positive integer unique across items; `kind` must be in `{feature, bug}`; `state` must be in the item-state enum; `blast_radius` must satisfy orchestrator invariant 9; `complexity_band` is optional outside the ready gate (P10 requires it under `require_ready_for_execution`) and, when present, must be in `{C1, C2, C3, C4}`. The prohibited-key rejections of orchestrator invariants 10 and 11 apply.
|
|
97
97
|
|
|
98
98
|
- **P4 — Cohort and edge shape.** `cohorts[]`, `conflict_edges[]`, and `recolor_generation` satisfy orchestrator invariants 12 through 15.
|
|
99
99
|
|
|
@@ -107,7 +107,9 @@ Enforced by `validate_parallel_planner_state_text(text, *, require_ready_for_exe
|
|
|
107
107
|
|
|
108
108
|
- **P9 — Ready gate, kickoff path.** Under `require_ready_for_execution`, `kickoff_prompt_path` must be exactly `artifacts/orchestration/parallel-kickoff-<parallel_slug>.md`.
|
|
109
109
|
|
|
110
|
-
|
|
110
|
+
- **P10 — Ready gate, routing record.** Under `require_ready_for_execution`, each object-shaped item must carry `complexity_band` in `{C1, C2, C3, C4}`; a `complexity_assessment` object `{band, floor, signals_present, rationale, assessed_at}` whose `floor` equals `compute_complexity_floor(signals_present)`, whose `band` is at or above `floor` and equals `complexity_band`, and whose `rationale` and `assessed_at` are non-empty strings; and a Claude `model_routing_receipt` object `{agent, phase, complexity_band, fable_policy, table_model, clamped_from, model}` with `agent == 'orchestrator'`, `complexity_band` equal to the item's band, `fable_policy` in `{disabled, available, preferred}`, and `model` equal to `resolve_delegation_model('orchestrator', complexity_band, fable_policy)['model']`, including the disabled-mode clamp invariants. The checks run per item in this order: (1) the band enum, reported as `None` when absent; (2) the assessment object, skipping checks 3 through 5 when it fails; (3) the assessment entry checks of `_validate_complexity_assessments`, prefix-rewritten to `<item> complexity_assessment`; (4) `assessed_at`; (5) assessment band equals item band; (6) the receipt object, skipping checks 7 through 10 when it fails; (7) the receipt entry checks of `_validate_model_routing_receipts`, prefix-rewritten to `<item> model_routing_receipt`; (8) `agent`; (9) receipt band equals item band; (10) the `fable_policy` enum. Checks 5 and 9 are reported whenever the two values differ, including when check 1 failed. Each item's P10 errors follow that item's P7 errors.
|
|
111
|
+
|
|
112
|
+
The planner checkpoint carries no `epic_worthiness` analogue and no `NON_EPIC_RECOMMENDED` branch; the parallel surface has no worthiness verdict, and scale assessment happens before parallel planning is invoked. When `require_ready_for_execution` is not passed, P6 through P10 contribute zero errors.
|
|
111
113
|
|
|
112
114
|
## Invariants (parallel run manifest)
|
|
113
115
|
|
|
@@ -380,6 +382,44 @@ admits.
|
|
|
380
382
|
Enforcement of this rejection is prose plus validator logic, exactly as for the three shapes above.
|
|
381
383
|
No JSON Schema is authored, imported, or read for it, and `config/blast-radius.json` gains no key.
|
|
382
384
|
|
|
385
|
+
### File-shape recognition (issue #797)
|
|
386
|
+
|
|
387
|
+
The classifier accepts a wildcard-free token that carries a separator only when its final component
|
|
388
|
+
names a file. After any `:<line>` suffix is stripped, the final component names a file when either
|
|
389
|
+
condition holds:
|
|
390
|
+
|
|
391
|
+
1. **Dotted file name.** The component has a non-empty stem before its last dot, and the text after
|
|
392
|
+
that dot, lower-cased, fully matches the pattern
|
|
393
|
+
`[a-z][a-z0-9]*`
|
|
394
|
+
(an ASCII letter followed by ASCII letters or digits).
|
|
395
|
+
2. **Known file name.** The component is an exact, ordinal member of the closed known-name set:
|
|
396
|
+
`Dockerfile`, `Makefile`, `LICENSE`, `CODEOWNERS`, `NOTICE`, `.gitignore`, `.gitattributes`,
|
|
397
|
+
`.gitkeep`, `.gitmodules`, `.vscodeignore`, `.npmignore`, `.npmrc`, `.nvmrc`, `.editorconfig`,
|
|
398
|
+
`.prettierrc`, `.prettierignore`, `.eslintignore`, `.shellcheckrc`.
|
|
399
|
+
|
|
400
|
+
This rule replaces the former extension allowlist, which dropped files a plan writes with an
|
|
401
|
+
unlisted extension (`.bats`, `.cjs`, `.out`), every dotfile, and every extensionless file name. The
|
|
402
|
+
same predicate decides the wildcard branch: a wildcard token outside the known top-level segments is
|
|
403
|
+
accepted only when its final component names a file by this rule.
|
|
404
|
+
|
|
405
|
+
Directory-shaped tokens remain rejected (issue #489). A final component with no dot, a trailing
|
|
406
|
+
slash, a dot-directory such as `.claude` or `.git` that is not in the known-name set, a digit-led
|
|
407
|
+
tail such as `v1.2.0`, and a trailing dot all fail the predicate.
|
|
408
|
+
|
|
409
|
+
**Accepted residuals (fail-closed direction).** Three token shapes that do not name a file are
|
|
410
|
+
accepted by this rule: a dotted directory cited without a trailing slash, such as the C#-style
|
|
411
|
+
`src/<Product>.Domain`; host-qualified tokens such as `example.com/page.html` or `owner/repo.git`;
|
|
412
|
+
and refs whose final segment has a letter-led dotted tail. Each produces at most an extra contention
|
|
413
|
+
edge, which serializes work. A missed write schedules concurrent edits, which is the unsafe
|
|
414
|
+
direction under this doctrine. In the self-hosted repository W4 removes the host-qualified cases; in
|
|
415
|
+
destinations, where `path_roots` is empty, W2 and W3 bound them.
|
|
416
|
+
|
|
417
|
+
**Parity.** The known-name set and the extension pattern are code constants in both runtimes
|
|
418
|
+
(`scripts/dev_tools/_blast_radius_token_shapes.py` and
|
|
419
|
+
`.claude/lib/blast-radius/BlastRadiusTokenShape.psm1`), not configuration keys, so neither copy of
|
|
420
|
+
`config/blast-radius.json` changes. A Pester test reads the Python source and pins the PowerShell
|
|
421
|
+
known-name set and extension pattern equal to it.
|
|
422
|
+
|
|
383
423
|
### Module-map granularity criterion
|
|
384
424
|
|
|
385
425
|
Issue #472 removed the location-bucket modules `docs` and `tests` because a bucket keyed on where a
|
|
@@ -525,6 +565,11 @@ Write-intent extraction can drop a genuine write in these cases:
|
|
|
525
565
|
5. a new top-level directory not yet in `path_roots` (W4);
|
|
526
566
|
6. a genuine file whose stem is in the placeholder set (W6).
|
|
527
567
|
|
|
568
|
+
The file-shape classifier, which runs before write-intent extraction, drops one further case: a
|
|
569
|
+
genuine file cited only as a separator-free bare file name is not recorded, because only
|
|
570
|
+
repository-relative paths and configured root surfaces are accepted (issue #797). The planner
|
|
571
|
+
cites the repository-relative path or appends it to the declared radius.
|
|
572
|
+
|
|
528
573
|
Three mitigations bound these cases:
|
|
529
574
|
|
|
530
575
|
1. **The planner remains obliged to enumerate a genuine write explicitly.** When an item's plan will
|
|
@@ -635,10 +680,10 @@ shipped surface or a derived module.
|
|
|
635
680
|
## Enforcement
|
|
636
681
|
|
|
637
682
|
- `scripts/dev_tools/validate_parallel_orchestrator_state.py`, with the helper modules `scripts/dev_tools/_parallel_state_common.py`, `scripts/dev_tools/_parallel_state_structures.py`, and `scripts/dev_tools/_parallel_state_records.py`, appends one error per violated orchestrator invariant. The completion-gate invariants 20 and 21 run only when the caller passes `require_complete=True`.
|
|
638
|
-
- `scripts/dev_tools/validate_parallel_planner_state.py` appends one error per violated planner invariant. The ready-gate invariants P6 through
|
|
683
|
+
- `scripts/dev_tools/validate_parallel_planner_state.py`, with the helper module `scripts/dev_tools/_parallel_planner_state_routing.py` for invariant P10, appends one error per violated planner invariant. The ready-gate invariants P6 through P10 run only when the caller passes `require_ready_for_execution=True`.
|
|
639
684
|
- `scripts/dev_tools/parallel_manifest_contract.py` appends one error per violated manifest invariant and exposes the default-resolving accessors. Manifest validation is a library call, not an MCP artifact type.
|
|
640
685
|
- `scripts/dev_tools/validate_orchestration_artifacts.py` registers the CLI subparsers `parallel-orchestrator-state` (with `--require-complete`) and `parallel-planner-state` (with `--require-ready-for-execution`). An unknown artifact type continues to fail with `Unsupported artifact type: {type}`.
|
|
641
|
-
- 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.
|
|
686
|
+
- 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.
|
|
642
687
|
- 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.
|
|
643
688
|
- 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`.
|
|
644
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`.
|
|
@@ -7,14 +7,14 @@ paths:
|
|
|
7
7
|
- "docs/features/**/plan.*.md"
|
|
8
8
|
- "docs/features/**/remediation-plan.*.md"
|
|
9
9
|
- ".claude/skills/atomic-plan-contract/SKILL.md"
|
|
10
|
-
description: Acceptance-gate rules G1 through
|
|
10
|
+
description: Acceptance-gate rules G1 through G10 for atomic plans. G1 through G9 judge the shell commands a plan states as acceptance conditions; the document-level G10 rule reports a SCRATCH definition that is not namespaced by issue number.
|
|
11
11
|
---
|
|
12
12
|
|
|
13
13
|
# Atomic-Plan Acceptance Gates (G1 through G6)
|
|
14
14
|
|
|
15
|
-
This rule governs the acceptance-gate rules the plan validator applies to the shell commands
|
|
15
|
+
This rule governs the acceptance-gate rules the plan validator applies to an atomic plan: G1 through G9 judge the shell commands the plan states as acceptance conditions, and G10 judges the whole plan document. It exists because a plan can state an acceptance condition that cannot fail: a coverage argument that collects no data, or a search for a literal that returns zero matches whatever the executor does. Such a condition reads as a verification step and gates nothing (issue #486).
|
|
16
16
|
|
|
17
|
-
The rules are enforced by `scripts/dev_tools/plan_gate_discrimination.py` and by the TypeScript parity port at `extensions/drm-copilot/src/lib/validate/plan-gate-discrimination.ts` with its shared-predicate module `plan-gate-rules.ts
|
|
17
|
+
The rules are enforced by `scripts/dev_tools/plan_gate_discrimination.py` and by the TypeScript parity port at `extensions/drm-copilot/src/lib/validate/plan-gate-discrimination.ts` with its shared-predicate module `plan-gate-rules.ts`. G1 through G9 are fed by the command extractor (`scripts/dev_tools/plan_gate_commands.py` and `extensions/drm-copilot/src/lib/validate/plan-gate-commands.ts`); G10 reads the whole document through `scripts/dev_tools/plan_gate_scratch.py` and `extensions/drm-copilot/src/lib/validate/plan-gate-scratch.ts`. Enforcement is validator logic plus this prose file. No JSON Schema is authored, imported, or read.
|
|
18
18
|
|
|
19
19
|
## Scope of Invocation — no grandfathering or exemption mechanism
|
|
20
20
|
|
|
@@ -26,7 +26,7 @@ The consequence is that adding a rule to this set is cheap in migration cost and
|
|
|
26
26
|
|
|
27
27
|
## Rule Table
|
|
28
28
|
|
|
29
|
-
Every finding string begins with the square-bracketed `P#-T#` identifier of the task the command is attributed to, and renders the offending value or literal between backticks.
|
|
29
|
+
Every finding string begins with the square-bracketed `P#-T#` identifier of the task the command is attributed to, and renders the offending value or literal between backticks. The G10 exception: a G10 finding begins with `Line N: ` instead, because a SCRATCH definition sits outside any task window; the prefix matches the structural-error prefix in the same error channel, and the offending logical line is still rendered between backticks.
|
|
30
30
|
|
|
31
31
|
| Rule | Condition | Shipped severity |
|
|
32
32
|
| --- | --- | --- |
|
|
@@ -40,14 +40,15 @@ Every finding string begins with the square-bracketed `P#-T#` identifier of the
|
|
|
40
40
|
| **G8** | A `git diff` invocation carrying no non-flag ref operand and neither `--cached` nor `--staged`. It compares the worktree against the index, which is ambient state: the comparison passes vacuously once the change is committed. Exonerated when the attributed task text carries a second `git diff` or a `git status` span. | **Warning** |
|
|
41
41
|
| **G8b** | A `git diff` invocation carrying a non-flag ref operand together with `--name-only` or `--name-status`, whose attributed task text carries neither a `git add` span nor a `git status --porcelain` span. A name-listing diff enumerates tracked changes only, so a path the plan creates is invisible to it. | **Warning** |
|
|
42
42
|
| **G9** | A command carrying a `--cov` token, carrying no token beginning `--cov-report=term` and no token beginning `--cov-fail-under`, whose project `addopts` value also carries no `--cov-report=term`. No coverage table is printed, so a coverage number the acceptance condition demands can never be read. | **Warning** |
|
|
43
|
+
| **G10** | An unfenced logical line of the plan document (a physical line plus its indented continuation lines) that matches the SCRATCH definition predicate, and whose text after the first definition match carries neither an `issue-<issue-num>` nor an `issue-<digits>` namespace. One finding per logical line, reported against its first physical line. | **Blocking** |
|
|
43
44
|
|
|
44
|
-
G1 through
|
|
45
|
+
G1 through G10 are the complete shipped set. G1 through G6 were added by issue #486, G7 through G9 by issue #519, and G10 by issue #932; the parenthetical in this file's title names the original set only.
|
|
45
46
|
|
|
46
47
|
G1 through G4 form a cascade over each `--cov` value: the value is decided once, so a value G1 rejects is never additionally reported by G2 or G3. G4 is evaluated independently of the cascade because the ambiguous form is a defect whatever the value resolves to. G6 is evaluated before G5, because cross-line presence falsifies G5's tree-absence claim.
|
|
47
48
|
|
|
48
49
|
G8b is a distinct rule from G8 and not a sub-case of it: G8 reports a diff with no ref operand, G8b reports one that has a ref operand but cannot observe an untracked path. A single invocation can satisfy only one of the two, because the presence of a ref operand decides between them.
|
|
49
50
|
|
|
50
|
-
G1 and G4 are context-free and run on every invocation. G2, G3, G5, and G6 require a repository seam; with no context supplied they do not run
|
|
51
|
+
G1 and G4 are context-free and run on every invocation. G2, G3, G5, and G6 require a repository seam; with no context supplied they do not run. G7, G8, and G8b are likewise context-free and run on every invocation. G9 requires the repository seam, because it reads the project `addopts` value through it, so with no context supplied G9 does not run. All four of the rules added by issue #519 ship in the Warning channel, so none of them can alter the Blocking list at all. G10 is context-free and document-level: it reads the whole plan text, including the preamble and terms lists the command extractor drops, runs on every invocation, and can add Blocking findings without a context.
|
|
51
52
|
|
|
52
53
|
### Attribution window
|
|
53
54
|
|
|
@@ -136,6 +137,43 @@ The remaining 4 findings are true positives, and each is the exact defect the ru
|
|
|
136
137
|
|
|
137
138
|
Counts, and every one of the 4 false positives named by plan path, task identifier, offending span, and the reason its acceptance condition is falsifiable: `docs/features/completed/2026-08-23-plan-acceptance-gates-miss-unobservable-and-ambient-state-gates-519/evidence/qa-gates/corpus-measurement.2026-08-24T00-00.md`.
|
|
138
139
|
|
|
140
|
+
### G10 — ships as Blocking by operator-approved scope and the pre-declared rule
|
|
141
|
+
|
|
142
|
+
G10 enforces the child-unique scratch location rule introduced by issue #900: a plan that uses scratch files points the `SCRATCH` token at `<session scratchpad>/issue-<issue-num>/`, so concurrent child runs in one session do not collide. Unlike G1 through G9, it judges document prose rather than task-attributed commands, because a SCRATCH definition is written in a plan preamble or terms list that the command extractor drops.
|
|
143
|
+
|
|
144
|
+
The detection contract has two steps, and both patterns use no lookbehind so the Python and JavaScript dialects agree. Step 1 is the definition predicate; step 2 is the namespace that accepts the line when it appears in the text after the first definition match:
|
|
145
|
+
|
|
146
|
+
```text
|
|
147
|
+
(?:^|[^A-Za-z0-9_<>$/.-])`?SCRATCH`?(?:\*\*)?[ \t]*(?:means\b|:=|=|:|is (?:the|a|an)\b|resolves to\b|abbreviates\b|denotes\b|refers to\b|stands for\b)
|
|
148
|
+
issue-(?:<issue-num>|[0-9]+)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Lines inside fenced code blocks are skipped, and a logical line is reported once however many definition matches it contains.
|
|
152
|
+
|
|
153
|
+
A continuation line is non-blank, begins with whitespace, and is not a fence line, so a heading or task line written at column 0 ends the logical line, and an indented heading or task line is absorbed into it. Both runtimes split the document into physical lines on the CR LF, LF, and CR terminators only; a form feed, a vertical tab, the information separators, NEL, and the Unicode line and paragraph separators do not end a physical line. Both runtimes share one explicit whitespace class for the blank-line test, the continuation test, and whitespace normalization, declared once per runtime as `PLAN_WHITESPACE_CLASS` in the command extractor module, with an identical pattern string in both: tab, line feed, vertical tab, form feed, carriage return, space, the Unicode space separators, and the Unicode line and paragraph separators. NEL, the information separators, and the byte-order mark are outside that class, so in both runtimes a line that begins with one of them ends the logical line, and the character is kept verbatim in the normalized text. G6 uses the same class for its single-line test, its sliding-window join, and the split of the search literal into words, so a tracked file that contains NEL, an information separator, or the byte-order mark produces the same G6 result in both runtimes; the plan-quotation exoneration, which reads the plan text rather than a tracked file, keeps each runtime's native class. The fence test keeps the command extractor's fence pattern, whose leading whitespace is each runtime's native class, so a fence line that begins with NEL, an information separator, or the byte-order mark can be recognized differently by the two runtimes, for G1 through G9 as well as for G10.
|
|
154
|
+
|
|
155
|
+
The severity was fixed by the same two-conjunct decision rule used for G5 through G9, written and committed before the measurement was taken: Blocking if and only if the total G10 finding count is greater than zero **and** the recorded false-positive count is zero; otherwise the measurement indicates Warning. The pre-declared false-positive definition is a flagged logical line that is not a SCRATCH definition, or that defines SCRATCH in the canonical issue-namespaced form.
|
|
156
|
+
|
|
157
|
+
The measurement is recorded in `docs/features/active/2026-10-15-plan-validator-accepts-bare-scratch-paths-932/evidence/qa-gates/g10-corpus-measurement.2026-10-16T01-21.md`. It scanned 493 plan and remediation-plan files under `docs/` at the merge base and produced 17 findings, all 17 true positives and 0 false positives, so both conjuncts hold and the rule yields Blocking.
|
|
158
|
+
|
|
159
|
+
G10 also ships Blocking by operator-approved scope for issue #932. The measurement alone is a weaker basis than the G7 through G9 precedent, because the research for issue #932 observed the committed plan corpus, including the definition forms the predicate targets, before the measurement was taken. The severity is a single constant in each runtime (`G10_SEVERITY`), and a parity test asserts the two constants agree.
|
|
160
|
+
|
|
161
|
+
### Known false-negative classes — G10
|
|
162
|
+
|
|
163
|
+
G10 does not report the following, and each is a stated limitation rather than a deferred promise:
|
|
164
|
+
|
|
165
|
+
- **Wrong issue number.** A namespaced definition whose issue number differs from the plan's own issue is accepted, because the predicate checks the namespace shape, not its value.
|
|
166
|
+
- **`SCRATCHPAD`-family tokens.** `SCRATCHPAD`, `<SCRATCHPAD>`, and `<SCRATCH>` tokens, and root paths written under them, are excluded by the preceding-character class and the token boundary.
|
|
167
|
+
- **Definition by reference.** A plan that defines SCRATCH by pointing at another plan's definition carries no definition text for the predicate to match.
|
|
168
|
+
- **Fenced definitions.** A definition placed inside a fenced code block is skipped, which is also what lets plans and specifications quote rejected forms as examples.
|
|
169
|
+
- **Any issue token after the definition.** A logical line is accepted when an `issue-<digits>` or `issue-<issue-num>` token appears anywhere in its text after the first definition match, including a cross-reference that is not the scratch location, such as `(see issue-900 for context)`. Step 2 checks the namespace shape anywhere in that text, not inside a path segment.
|
|
170
|
+
|
|
171
|
+
One false-positive class is possible and recorded: the colon connector matches prose in which the word SCRATCH is directly followed by a colon that introduces something other than a definition, as in the line below. The measured corpus contains no instance.
|
|
172
|
+
|
|
173
|
+
```text
|
|
174
|
+
Each artifact names the token SCRATCH: it never records a host path.
|
|
175
|
+
```
|
|
176
|
+
|
|
139
177
|
## The Write-Mode Register
|
|
140
178
|
|
|
141
179
|
G7 reads a fixed register of six entries. Each entry is an argv predicate plus a set of observation markers matched case-sensitively as substrings of the owning task's attributed text. The register is data, not code, so the same six entries are transcribed into the TypeScript twin without porting behaviour.
|
|
@@ -239,7 +277,7 @@ The following are prohibited in gate messages:
|
|
|
239
277
|
|
|
240
278
|
The reason is byte-identity across the two runtimes. Python's `repr` selects its quote character based on the value's contents, switching to double quotes when the value contains a single quote, while the TypeScript `pythonRepr` helper used elsewhere in this repository always single-quotes. A value carrying an apostrophe would therefore render differently in the two runtimes, and the parity requirement would fail on exactly the class of value a maintainer is most likely to encounter in a path or a prose literal. Backtick delimiting has no content-dependent behaviour and needs no helper.
|
|
241
279
|
|
|
242
|
-
The prohibition is enforced by tests, not only by prose: a parity test asserts the Python gate module contains neither `!r` nor `repr(`, a companion test asserts no `pythonRepr(` call appears in any of the
|
|
280
|
+
The prohibition is enforced by tests, not only by prose: a parity test asserts the Python gate module contains neither `!r` nor `repr(`, a companion test asserts no `pythonRepr(` call appears in any of the TypeScript gate modules, and the parity fixture set includes an apostrophe-bearing `--cov` value and an apostrophe-bearing search literal whose expected strings are asserted identically in both runtimes.
|
|
243
281
|
|
|
244
282
|
## Authoring Guidance for Plan Authors
|
|
245
283
|
|
|
@@ -251,7 +289,8 @@ The prohibition is enforced by tests, not only by prose: a parity test asserts t
|
|
|
251
289
|
|
|
252
290
|
## Enforcement
|
|
253
291
|
|
|
254
|
-
- `scripts/dev_tools/plan_gate_commands.py` extracts task-attributed command candidates; `scripts/dev_tools/plan_gate_discrimination.py` evaluates G1 through
|
|
292
|
+
- `scripts/dev_tools/plan_gate_commands.py` extracts task-attributed command candidates; `scripts/dev_tools/plan_gate_discrimination.py` evaluates G1 through G9, calls `scripts/dev_tools/plan_gate_scratch.py` for G10, and returns the two severity channels.
|
|
255
293
|
- `scripts/dev_tools/validate_orchestration_artifacts.py` routes the existing `plan` artifact type through the two-channel entry point, prints each Warning to stderr prefixed with `PLAN GATE WARNING: `, and derives its exit code from the error channel alone. No new flag, option, or artifact type is added.
|
|
256
294
|
- The TypeScript parity port is dispatched from `extensions/drm-copilot/src/lib/validate/orchestration-artifacts.ts` for the existing `plan` artifact type. The MCP `validate_orchestration_artifacts` input-schema property-key set is unchanged; Warnings surface on an optional `warnings` field that is absent when there are none.
|
|
295
|
+
- `scripts/dev_tools/plan_gate_scratch.py` evaluates G10, the document-level SCRATCH definition rule, and `evaluate_plan_gates` in `scripts/dev_tools/plan_gate_discrimination.py` calls it on every invocation, with or without a context. The TypeScript twin `extensions/drm-copilot/src/lib/validate/plan-gate-scratch.ts` is called the same way from `evaluatePlanGates`. Through the Python CLI a G10 finding is printed as an error and the process exits 1; through the MCP service call it causes the call to throw with the message included.
|
|
257
296
|
- `.claude/hooks/validate-planner-output.ps1` is not modified by this rule and carries no part of its enforcement.
|
|
@@ -6,19 +6,21 @@ description: Module rigor tier system and uniform coverage thresholds.
|
|
|
6
6
|
|
|
7
7
|
# Module Rigor Tiers
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Applicability: this rule applies only when `quality-tiers.yml` exists at the repository root, which indicates that the repository has adopted module rigor tiers. When that file is absent, there is no tier classification requirement, no `tier-classification` CI stage, and no tier-dependent gate (the escape-hatch limits, property-test density, mutation score, contract-bump rule, determinism retry rate, golden tests, and E2E suite scope in the Tier-dependent table below), and the absence of `quality-tiers.yml` is not a defect. The coverage defaults listed under Uniform across all tiers do not depend on tier adoption; their precedence is stated in that section.
|
|
10
|
+
|
|
11
|
+
When `quality-tiers.yml` exists, this rule defines the T1–T4 module rigor tier system used by the repository's CI gates, and the tier definitions and gate matrix in this document are the tier system's source of truth.
|
|
10
12
|
|
|
11
13
|
## Tiers
|
|
12
14
|
|
|
13
|
-
- **T1 — Critical.** Behavior bugs cause silent data loss, model drift, or security holes. Examples
|
|
14
|
-
- **T2 — Core.** Bugs cause feature regressions but not data loss. Examples:
|
|
15
|
-
- **T3 — Adapters & UI.** Glue around APIs the team does not own. Examples:
|
|
15
|
+
- **T1 — Critical.** Behavior bugs cause silent data loss, model drift, or security holes. Examples: classifier and scoring engines, identifier allocators and hierarchy operations, adapters that write to an external system of record, authentication and token handling, command dispatch.
|
|
16
|
+
- **T2 — Core.** Bugs cause feature regressions but not data loss. Examples: domain and application layers, data-transfer objects, settings store abstractions, schema definitions.
|
|
17
|
+
- **T3 — Adapters & UI.** Glue around APIs the team does not own. Examples: user-interface surfaces, host-platform API wrappers, third-party API and SDK wrappers, persistence I/O.
|
|
16
18
|
- **T4 — Scaffolding.** Examples: DI wiring, bootstrap, build scripts, dev tooling, generated code, manifests.
|
|
17
19
|
|
|
18
20
|
## Source of Truth
|
|
19
21
|
|
|
20
|
-
- `quality-tiers.yml` at
|
|
21
|
-
-
|
|
22
|
+
- When `quality-tiers.yml` exists at the repository root, it maps every project to one tier.
|
|
23
|
+
- In a repository that runs a `tier-classification` CI stage, that stage validates that every project entry has a tier and that no unclassified project exists, and it fails CI for an unclassified project.
|
|
22
24
|
|
|
23
25
|
## Uniform-vs-Tier-Dependent Gate Matrix
|
|
24
26
|
|
|
@@ -26,6 +28,8 @@ Per Authoritative Decision #2, line and branch coverage thresholds are uniform a
|
|
|
26
28
|
|
|
27
29
|
### Uniform across all tiers (T1–T4)
|
|
28
30
|
|
|
31
|
+
Threshold precedence: when the repository's root `CLAUDE.md` states line or branch coverage thresholds, those thresholds govern. The 85% line and 75% branch figures are defaults that apply only when the root `CLAUDE.md` states none. This precedence applies to every restatement of these figures in other rule files, agents, and skills. Each metric falls back independently: when the root `CLAUDE.md` states only a line threshold or only a branch threshold, the stated threshold governs that metric and the default governs the other.
|
|
32
|
+
|
|
29
33
|
- Format check: 100% pass.
|
|
30
34
|
- Lint errors: 0.
|
|
31
35
|
- Type errors: 0.
|
|
@@ -48,4 +52,4 @@ Per Authoritative Decision #2, line and branch coverage thresholds are uniform a
|
|
|
48
52
|
|
|
49
53
|
## Rationale (uniform coverage thresholds)
|
|
50
54
|
|
|
51
|
-
High test coverage is a fundamental quality-control design choice that enables autonomous agentic development and trust in the work product. For that reason, line coverage >= 85% applies uniformly across T1–T4 to every coverage language, and branch coverage >= 75% applies uniformly across T1–T4 to every language whose coverage tooling measures branch coverage; tier-specific lower coverage floors are not used
|
|
55
|
+
High test coverage is a fundamental quality-control design choice that enables autonomous agentic development and trust in the work product. For that reason, line coverage >= 85% applies uniformly across T1–T4 to every coverage language, and branch coverage >= 75% applies uniformly across T1–T4 to every language whose coverage tooling measures branch coverage; tier-specific lower coverage floors are not used. These figures are defaults under the threshold precedence stated above: a root `CLAUDE.md` that states coverage thresholds overrides them. Each metric falls back independently, so a root `CLAUDE.md` that states only one of the two thresholds overrides only that one. The branch threshold is not applied to PowerShell or bash because Pester and kcov do not measure branch coverage. That exemption is a capability limit on an unevaluable threshold, not a licence to exclude files from measurement: PowerShell and bash production files remain in the coverage denominator under the Coverage Exclusion Policy in `.claude/rules/general-unit-test.md`.
|
|
@@ -45,11 +45,12 @@ single pass. Do not substitute the VS Code task wrappers for the native command
|
|
|
45
45
|
|
|
46
46
|
## Discovery Contract
|
|
47
47
|
|
|
48
|
-
- Search roots: `tools/`, `scripts/`, `.claude/lib/bash/`,
|
|
49
|
-
current working directory; a missing root is silently skipped. The `.claude/lib/bash/` root
|
|
50
|
-
the destination-portable bash library published by push-down,
|
|
51
|
-
scripts bundled inside a skill folder,
|
|
52
|
-
|
|
48
|
+
- Search roots: `tools/`, `scripts/`, `.claude/lib/bash/`, `.claude/skills/`, and `.codex/`, relative
|
|
49
|
+
to the current working directory; a missing root is silently skipped. The `.claude/lib/bash/` root
|
|
50
|
+
carries the destination-portable bash library published by push-down, the `.claude/skills/` root
|
|
51
|
+
carries scripts bundled inside a skill folder, and the `.codex/` root carries the Codex runtime
|
|
52
|
+
scripts (for example `.codex/codex-web-setup.sh`), so those scripts are held to the same format,
|
|
53
|
+
lint, test, and coverage standards as `tools/` and `scripts/`.
|
|
53
54
|
- A file is a shell script when its suffix (lowercased) is `.sh` or its first line is a
|
|
54
55
|
shebang whose resolved interpreter is `bash` or `sh` (including `env` and `env -S`/`-flag`
|
|
55
56
|
forms; the shebang is lowercased before parsing, so `#!/usr/bin/env BASH` qualifies).
|
|
@@ -63,9 +64,10 @@ single pass. Do not substitute the VS Code task wrappers for the native command
|
|
|
63
64
|
- Coverage is measured with kcov, which emits a single merged Cobertura report `cov.xml` under
|
|
64
65
|
`artifacts/pester/kcov` (or `SHELL_QC_KCOV_OUT_DIR`). The run prints
|
|
65
66
|
`Bash coverage (lines): NN.N%`.
|
|
66
|
-
- The kcov include pattern covers all
|
|
67
|
-
`.claude/lib/bash/`,
|
|
68
|
-
measured, not merely discovered. The `tests/` tree remains
|
|
67
|
+
- The kcov include pattern covers all five discovery roots — `tools/`, `scripts/`,
|
|
68
|
+
`.claude/lib/bash/`, `.claude/skills/`, and `.codex/` — so the Claude bash library, skill-bundled
|
|
69
|
+
scripts, and Codex runtime scripts are measured, not merely discovered. The `tests/` tree remains
|
|
70
|
+
excluded.
|
|
69
71
|
- kcov reports **line coverage only**. The uniform line-coverage threshold (>= 85% per
|
|
70
72
|
`.claude/rules/quality-tiers.md`) applies. Branch coverage is not measurable by kcov for
|
|
71
73
|
bash; there is no bash branch-coverage gate.
|
|
@@ -54,7 +54,7 @@ Run the toolchain in order: format → lint → type-check → test. Restart fro
|
|
|
54
54
|
|
|
55
55
|
## Architecture Boundaries
|
|
56
56
|
|
|
57
|
-
Layer rules and the
|
|
57
|
+
Layer rules and the host-neutral architecture assertions are defined in `.claude/rules/architecture-boundaries.md` under the heading "Host-Neutral Architecture Rules (enforceable assertions)". The TypeScript enforcement tool is `dependency-cruiser` with configuration file `.dependency-cruiser.cjs`.
|
|
58
58
|
|
|
59
59
|
## Property-Based and Mutation Testing
|
|
60
60
|
|
|
@@ -5,8 +5,11 @@
|
|
|
5
5
|
"Bash(git *)",
|
|
6
6
|
"Bash(poetry run *)",
|
|
7
7
|
"Bash(pwsh *)",
|
|
8
|
+
"Bash(bash .claude/lib/bash/abandon-parallel-item.sh*)",
|
|
8
9
|
"Bash(bash .claude/lib/bash/compute-cohorts.sh*)",
|
|
9
10
|
"Bash(bash .claude/lib/bash/compute-concurrency-batches.sh*)",
|
|
11
|
+
"Bash(bash .claude/lib/bash/mutate-parallel-run.sh*)",
|
|
12
|
+
"Bash(bash .claude/lib/bash/remove-parallel-item.sh*)",
|
|
10
13
|
"Bash(bash .claude/lib/bash/validate-parallel-manifest.sh*)",
|
|
11
14
|
"Read",
|
|
12
15
|
"Edit(docs/**)",
|
|
@@ -211,10 +214,6 @@
|
|
|
211
214
|
{
|
|
212
215
|
"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",
|
|
213
216
|
"hooks": [
|
|
214
|
-
{
|
|
215
|
-
"type": "command",
|
|
216
|
-
"command": "pwsh -NoProfile -Command \"$input = $env:CLAUDE_HOOK_INPUT | ConvertFrom-Json; $output = $input.output; if (-not ($output -match '(plan-path|research-path|review-artifact|PREFLIGHT|evidence/)')) { Write-Error 'Subagent stopped without required completion artifact path'; exit 1 }; exit 0\""
|
|
217
|
-
},
|
|
218
217
|
{
|
|
219
218
|
"type": "command",
|
|
220
219
|
"command": "pwsh -NoProfile -File .claude/hooks/validate-discovery-artifact-gate.ps1"
|
package/resources/claude-customizations/.claude/skills/acceptance-criteria-tracking/SKILL.md
CHANGED
|
@@ -70,6 +70,14 @@ During plan execution, after completing a task whose work satisfies an acceptanc
|
|
|
70
70
|
|
|
71
71
|
Timing: Check off AC items as soon as the corresponding plan task passes verification — do not defer all AC updates to the end of plan execution.
|
|
72
72
|
|
|
73
|
+
### CI-Dependent Criteria
|
|
74
|
+
|
|
75
|
+
A CI-dependent criterion is one whose verification requires the result of CI on the PR head. It cannot be verified before the pull request exists, so it stays unchecked and is listed as pending-CI in the AC verification artifact until CI has run.
|
|
76
|
+
|
|
77
|
+
- Owner: the item's own orchestrator run owns the check-off and performs it at S9; this is the one case in which an orchestrator run checks off AC. A parent or coordinating session never commits the check-off from its own root.
|
|
78
|
+
- Timing: after the CI green gate (S9) records `ci_gate.conclusion` as `success`, and before the run reports DONE.
|
|
79
|
+
- Push and re-verify: the check-off is committed in the item's own worktree and pushed to the PR branch, and the CI green gate is re-run against the new head SHA so that `ci_gate.head_sha` equals the final PR head before DONE.
|
|
80
|
+
|
|
73
81
|
### When Reviewers Check Off AC
|
|
74
82
|
|
|
75
83
|
During feature review (feature-audit phase):
|
|
@@ -80,7 +88,7 @@ During feature review (feature-audit phase):
|
|
|
80
88
|
|
|
81
89
|
### When Orchestrators Enforce AC Tracking
|
|
82
90
|
|
|
83
|
-
Orchestrators do not directly check off AC items.
|
|
91
|
+
Orchestrators do not directly check off AC items. The one exception is a CI-dependent criterion, which the item's own orchestrator run checks off at S9 as described in `### CI-Dependent Criteria` above. For every other criterion, orchestrators instead:
|
|
84
92
|
|
|
85
93
|
1. Ensure delegated executors and reviewers reference this skill.
|
|
86
94
|
2. After executor or reviewer completion, verify that AC source files reflect delivered work (spot-check; do not re-execute verification).
|