@danmoisan/drm-copilot-mcp 1.1.16 → 1.1.18
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 +1139 -133
- package/package.json +4 -3
- package/resources/claude-customizations/.claude/agents/feature-review.md +10 -1
- package/resources/claude-customizations/.claude/agents/orchestrator.md +16 -3
- package/resources/claude-customizations/.claude/agents/parallel-orchestrator.md +18 -6
- package/resources/claude-customizations/.claude/agents/python-typed-engineer.md +3 -3
- package/resources/claude-customizations/.claude/hooks/{enforce-powershell-batch-budget-route.ps1 → enforce-batch-budget-route.ps1} +12 -10
- package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate-resolution.ps1 +221 -0
- package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate.ps1 +42 -66
- package/resources/claude-customizations/.claude/hooks/enforce-epic-wave-barrier.ps1 +58 -10
- package/resources/claude-customizations/.claude/hooks/enforce-epic-worktree-removal-gate-resolution.ps1 +144 -0
- package/resources/claude-customizations/.claude/hooks/enforce-epic-worktree-removal-gate.ps1 +36 -47
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1 +179 -27
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate.ps1 +21 -38
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-abandon-gate.ps1 +4 -4
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-cohort-barrier.ps1 +58 -10
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-drift-gate.ps1 +59 -9
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-worktree-removal-gate.ps1 +114 -37
- package/resources/claude-customizations/.claude/hooks/enforce-powershell-batch-budget.ps1 +3 -3
- package/resources/claude-customizations/.claude/hooks/enforce-python-batch-budget.ps1 +99 -64
- package/resources/claude-customizations/.claude/lib/bash/abandon-parallel-item.sh +176 -0
- package/resources/claude-customizations/.claude/lib/bash/parallel-lane-assertion.sh +4 -2
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusConflict.psm1 +193 -14
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusGlob.psm1 +51 -28
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusScheduling.psm1 +5 -8
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorState.psm1 +6 -13
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateIssueAdoption.psm1 +375 -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/parallel-drift/Invoke-ParallelDriftDetection.ps1 +336 -0
- package/resources/claude-customizations/.claude/lib/parallel-drift/ParallelDrift.psm1 +467 -0
- package/resources/claude-customizations/.claude/lib/parallel-drift/ParallelDriftHalt.psm1 +388 -0
- package/resources/claude-customizations/.claude/lib/worktree-resolution/EpicScopeResolution.psm1 +53 -32
- package/resources/claude-customizations/.claude/lib/worktree-resolution/WorktreeItemResolution.psm1 +19 -4
- package/resources/claude-customizations/.claude/lib/worktree-resolution/WorktreeRunResolution.psm1 +497 -0
- package/resources/claude-customizations/.claude/rules/orchestrator-state.md +119 -3
- package/resources/claude-customizations/.claude/rules/parallel-orchestration.md +21 -0
- package/resources/claude-customizations/.claude/rules/quality-tiers.md +1 -1
- package/resources/claude-customizations/.claude/skills/acceptance-criteria-tracking/SKILL.md +8 -0
- package/resources/claude-customizations/.claude/skills/atomic-plan-contract/SKILL.md +2 -0
- 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_enumerate_lib.sh +169 -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 +4 -15
- package/resources/claude-customizations/.claude/skills/epic-orchestrate/SKILL.md +15 -6
- package/resources/claude-customizations/.claude/skills/evidence-and-timestamp-conventions/SKILL.md +4 -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 +3 -1
- package/resources/claude-customizations/.claude/skills/invoke-csharp-engineer/SKILL.md +4 -0
- package/resources/claude-customizations/.claude/skills/invoke-powershell-engineer/SKILL.md +4 -0
- package/resources/claude-customizations/.claude/skills/invoke-python-engineer/SKILL.md +6 -3
- package/resources/claude-customizations/.claude/skills/orchestrate/SKILL.md +33 -13
- package/resources/claude-customizations/.claude/skills/parallel-orchestrate/SKILL.md +50 -21
- package/resources/claude-customizations/.claude/skills/parallel-remove/SKILL.md +10 -10
- package/resources/claude-customizations/.claude/skills/python-change-budget-router/SKILL.md +11 -35
- package/resources/claude-customizations/.claude/skills/remediation-handoff-atomic-planner/SKILL.md +5 -1
- package/resources/claude-customizations/pack-manifests/core.json +10 -0
- package/resources/claude-customizations/pack-manifests/powershell.json +0 -1
- package/resources/codex-and-agents-customizations/.agents/skills/acceptance-criteria-tracking/SKILL.md +8 -0
- package/resources/codex-and-agents-customizations/.agents/skills/epic-orchestrate/SKILL.md +5 -3
- package/resources/codex-and-agents-customizations/.agents/skills/evidence-and-timestamp-conventions/SKILL.md +4 -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 +3 -1
- package/resources/codex-and-agents-customizations/.agents/skills/invoke-powershell-engineer/SKILL.md +0 -1
- package/resources/codex-and-agents-customizations/.agents/skills/invoke-python-engineer/SKILL.md +2 -3
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrate/SKILL.md +30 -7
- 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 +18 -3
- package/resources/codex-and-agents-customizations/.agents/skills/python-change-budget-router/SKILL.md +10 -34
- package/resources/codex-and-agents-customizations/.agents/skills/quality-tiers/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents/skills/remediation-handoff-atomic-planner/SKILL.md +2 -0
- 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 +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c2.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c3-elevated.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c3.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c4.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/python-orchestrator.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c1.toml +3 -3
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c2.toml +3 -3
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c3-elevated.toml +3 -3
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c3.toml +3 -3
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c4.toml +3 -3
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer.toml +3 -3
- package/resources/codex-and-agents-customizations/.codex/config.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-batch-budget-route.ps1 +139 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-powershell-batch-budget.ps1 +4 -124
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-python-batch-budget.ps1 +169 -79
- package/resources/codex-and-agents-customizations/pack-manifests/core.json +1 -0
- package/resources/customizations/.github/agents/python-orchestrator.agent.md +4 -4
- package/resources/customizations/.github/agents/python-typed-engineer.agent.md +7 -8
- package/resources/customizations/.github/prompts/orchestrate-python-work.prompt.md +3 -3
- package/resources/customizations/.github/skills/acceptance-criteria-tracking/SKILL.md +8 -0
- package/resources/customizations/.github/skills/evidence-and-timestamp-conventions/SKILL.md +4 -0
- package/resources/powershell/PoshQC/settings/pester.runsettings.psd1 +16 -1
|
@@ -123,6 +123,8 @@ checkpoint write, and on CI-green (S9 step 6) merges its own PR into the integra
|
|
|
123
123
|
recording `epic_merge: { merge_commit_sha, target_branch, merged_at }`. Standalone (non-epic)
|
|
124
124
|
orchestration is unchanged: `epic_mode` absent or `false` makes S9 step 6 a no-op.
|
|
125
125
|
|
|
126
|
+
The run gates `enforce-orchestration-preimplementation-gate.ps1` and `enforce-epic-wave-barrier.ps1` locate the epic checkpoint by the `integration_branch:` value of this line. They select the live worktree whose `artifacts/orchestration/epic-orchestrator-state.json` records `route_id` `epic` and that integration branch, prefer the worktree that has the branch checked out when more than one records it, and deny the delegation with `TARGET_WORKTREE_NOT_DERIVABLE` or `TARGET_WORKTREE_AMBIGUOUS` when none or more than one remains. A stale copy of the epic checkpoint is moved to `artifacts/orchestration/handoff/` rather than left at a worktree root. The child run's own delegations to implementation agents carry the canonical issue-number line and `branch:` label defined in `.claude/skills/orchestrate/SKILL.md` `## Issue Number Consistency`.
|
|
127
|
+
|
|
126
128
|
## Bounded Child Return Contract
|
|
127
129
|
|
|
128
130
|
A child `orchestrator`'s final report is consumed as a fixed eight-field shape and nothing else:
|
|
@@ -219,9 +221,10 @@ Procedure, triggered by S9 step 6's merge failure:
|
|
|
219
221
|
3. The existing R1–R5 loop processes this finding exactly as a local blocking finding:
|
|
220
222
|
`atomic-planner` (R1) plans the resolution, `atomic-executor` performs preflight (R2) then
|
|
221
223
|
resolves the conflict markers, stages, and commits (R3), `feature-review` re-audits (R4).
|
|
222
|
-
4.
|
|
223
|
-
|
|
224
|
-
|
|
224
|
+
4. Conflict cycles share the child's own `remediation_loop.completed_attempts` count with
|
|
225
|
+
local-finding and CI-failure cycles. The active cycle number is `completed_attempts + 1`, and a
|
|
226
|
+
cycle without an applied candidate consumes no number.
|
|
227
|
+
5. After three completed attempts without resolution, the child's `orchestrator` records
|
|
225
228
|
`step9_status: "blocked_conflict_loop_limit"` (parallel to `blocked_ci_loop_limit`), does not
|
|
226
229
|
write DONE, and halts. It reports this status to `epic-orchestrator`, which mirrors it into
|
|
227
230
|
the epic checkpoint's per-feature `merge_status: "blocked_conflict_loop_limit"` field.
|
|
@@ -240,9 +243,15 @@ cross-call/conversation-state visibility.
|
|
|
240
243
|
dependency's `merge_status` is `merged` or `worktree_removed`.
|
|
241
244
|
- **Layer 2 — retrospective backstop:** the wave-barrier ordering invariant inside
|
|
242
245
|
`validate_epic_orchestrator_state_text`, enforced at `epic-orchestrator` `SubagentStop` time via
|
|
243
|
-
the parameterized `validate-orchestrator-output.ps1` hook. It
|
|
244
|
-
|
|
245
|
-
|
|
246
|
+
the parameterized `validate-orchestrator-output.ps1` hook. It checks only a dependent feature
|
|
247
|
+
that is treated as started: one with a string `worktree_created_at`, or with a `merge_status`
|
|
248
|
+
other than `not_started` (a missing or non-string `merge_status` counts as started). It appends
|
|
249
|
+
exactly one error per violated dependency edge. When the dependency's `merge_status` is not
|
|
250
|
+
`merged` or `worktree_removed`, the error is
|
|
251
|
+
`EPIC_WAVE_BARRIER_VIOLATION: <f> is treated as started while dependency <d> is not merged`.
|
|
252
|
+
Otherwise, when the dependency's `merge_confirmed_at` is later than the dependent's
|
|
253
|
+
`worktree_created_at`, the error is
|
|
254
|
+
`EPIC_WAVE_BARRIER_VIOLATION: <f> worktree_created_at precedes dependency <d> merge_confirmed_at`.
|
|
246
255
|
|
|
247
256
|
Both layers are required; neither alone closes the gap. `epic-orchestrator` does not launch wave
|
|
248
257
|
N+1 until every wave-N feature's dependency edges are durably confirmed merged, verified against
|
package/resources/claude-customizations/.claude/skills/evidence-and-timestamp-conventions/SKILL.md
CHANGED
|
@@ -46,6 +46,8 @@ Use this skill when:
|
|
|
46
46
|
Use `yyyy-MM-ddTHH-mm` for all audit, remediation, and evidence artifacts.
|
|
47
47
|
Example: `2026-02-06T14-30`.
|
|
48
48
|
|
|
49
|
+
The `Timestamp` value is local time read from the host system clock when the recorded command runs (for example `Get-Date -Format yyyy-MM-ddTHH-mm`); the agent never composes or estimates it.
|
|
50
|
+
|
|
49
51
|
## Canonical Evidence Locations
|
|
50
52
|
|
|
51
53
|
- Baseline evidence: `evidence/baseline/`
|
|
@@ -110,6 +112,8 @@ When evidence artifacts are used for automated checking or plan reconciliation,
|
|
|
110
112
|
- `Command: <exact command>`
|
|
111
113
|
- `EXIT_CODE: <int>`
|
|
112
114
|
|
|
115
|
+
The first occurrence of `Timestamp`, `Command`, `EXIT_CODE`, and `ExpectedExitCode` forms the record in both the Python and the TypeScript parser; later occurrences, including empty later values, are ignored. An artifact that records several gates therefore reports its first gate.
|
|
116
|
+
|
|
113
117
|
One optional field may also be declared:
|
|
114
118
|
- `ExpectedExitCode: <int>` — the exit code the gate is expected to produce.
|
|
115
119
|
|
|
@@ -40,6 +40,16 @@ Each `delegation_receipts.promotion.*` field stores the raw MCP receipt payload
|
|
|
40
40
|
|
|
41
41
|
Note: VS Code command-palette commands may exist for interactive extension use, but this note is non-authoritative for agent sessions.
|
|
42
42
|
|
|
43
|
+
## Pre-Existing Issue Path
|
|
44
|
+
|
|
45
|
+
When the GitHub issue already exists (it was transferred, filed before orchestration, or created by epic decomposition), do not call `potential_to_issue`: that tool creates a new issue and would duplicate the existing one. Instead:
|
|
46
|
+
|
|
47
|
+
1. Verify the issue read-only with `gh issue view`, a `gh api` GET request, or a GitHub MCP issue read, and use its number as `${issue-num}`.
|
|
48
|
+
2. Record a top-level `issue_adoption` object in the orchestrator checkpoint (`issue_num`, `issue_url`, `origin`, `verified_via`, `verified_at`, `evidence`, `waived_tools`, and `potential_record` when a promotion-entry tool is waived). A valid record waives the `potential_to_issue` receipt requirement at completion.
|
|
49
|
+
3. `delegation_receipts.promotion.issue` may be omitted, because no promotion receipt exists for an adopted issue.
|
|
50
|
+
|
|
51
|
+
The field rules, the closed set of waivable tools, and the fail-closed behavior are defined in `.claude/rules/orchestrator-state.md` under `## Invariants (issue_adoption object)`.
|
|
52
|
+
|
|
43
53
|
## Canonical Variables
|
|
44
54
|
|
|
45
55
|
- `${promotion-type}`: `feature` or `bug`
|
|
@@ -72,7 +72,7 @@ If the branch diff modifies any path matching `.github/workflows/**`, `scripts/b
|
|
|
72
72
|
- The rule provides a second, independent line of defense for CI-gate-modifying features, separate from and prior to the orchestrator's S9 CI green gate.
|
|
73
73
|
- "Green workflow run against the branch head" means a workflow run whose head SHA matches the current branch head and whose conclusion is success for the affected workflow.
|
|
74
74
|
- A green `workflow_dispatch` run against the branch head also satisfies the rule, not only a PR-context run. This mitigates the chicken-and-egg case where a feature must land its CI gate before the gate can run in PR context (see spec.md Risks & Mitigations).
|
|
75
|
-
- When the rule fires and no qualifying green-run evidence is present, record a Blocking finding and
|
|
75
|
+
- When the rule fires and no qualifying green-run evidence is present, record a Blocking finding classified `awaiting_ci` (the remediation inputs carry `Remediability: awaiting_ci` and a `Remediability-Evidence:` line naming the awaited workflow) and route it to the wait path (`AWAITING_CI` when no other class is present) instead of the remediation handoff.
|
|
76
76
|
|
|
77
77
|
## Ordered Procedure
|
|
78
78
|
|
|
@@ -147,6 +147,8 @@ If the branch diff modifies any path matching `.github/workflows/**`, `scripts/b
|
|
|
147
147
|
- required acceptance criteria are FAIL or PARTIAL
|
|
148
148
|
- coverage regression below policy threshold (< 80% repo-wide per language, < 80% or regression for modified files, or < 90% for new files)
|
|
149
149
|
- coverage artifact absent for any language that has changed files
|
|
150
|
+
- Classify each blocking finding before triggering remediation: each receives one remediability class (`autonomous`, `external_dependency`, `policy_hold`, `awaiting_ci`, or `human_decision_required`; `autonomous` when no class is stated). A published MCP runtime that lags the repository contract is classified `external_dependency`.
|
|
151
|
+
- Trigger the remediation handoff only when at least one blocking finding is `autonomous`. When every blocking finding is non-remediable, write the remediation inputs with the `HALT_NON_REMEDIABLE` or `AWAITING_CI` verdict and create no remediation plan target.
|
|
150
152
|
- Create `remediation-inputs.<timestamp>.md` first.
|
|
151
153
|
- Create the target remediation plan file from the canonical plan template.
|
|
152
154
|
- Hand off plan creation through `remediation-handoff-atomic-planner`.
|
|
@@ -42,6 +42,10 @@ The worker must return the following reporting block:
|
|
|
42
42
|
4. Diffs (patch-style or full-file replacements).
|
|
43
43
|
5. QA Gate Results (CSharpier, .NET Analyzers, Nullable Analysis, xUnit, and coverage deltas, or clearly marked **unverified**).
|
|
44
44
|
|
|
45
|
+
## Delegation Identity Lines
|
|
46
|
+
|
|
47
|
+
Every delegation prompt this skill sends to `csharp-typed-engineer` carries the canonical issue-number line (`Canonical issue number for this feature is <issue_num>. All artifact content, file paths, and cross-references must use this number.`) and a `branch: <name>` label naming the branch checked out in the item's worktree, written as the first `branch:` occurrence in the prompt. `enforce-orchestration-preimplementation-gate.ps1` resolves the item's worktree from these two lines and denies a delegation that carries neither with `TARGET_WORKTREE_NOT_DERIVABLE`.
|
|
48
|
+
|
|
45
49
|
## Worker Routing
|
|
46
50
|
|
|
47
51
|
- Worker: `csharp-typed-engineer`
|
|
@@ -41,6 +41,10 @@ The worker must return the `powershell-qa-gate` reporting block:
|
|
|
41
41
|
4. Diffs (patch-style or full-file replacements).
|
|
42
42
|
5. QA Gate Results (PSScriptAnalyzer, Pester, and coverage deltas, or clearly marked **unverified**).
|
|
43
43
|
|
|
44
|
+
## Delegation Identity Lines
|
|
45
|
+
|
|
46
|
+
Every delegation prompt this skill sends to `powershell-typed-engineer` carries the canonical issue-number line (`Canonical issue number for this feature is <issue_num>. All artifact content, file paths, and cross-references must use this number.`) and a `branch: <name>` label naming the branch checked out in the item's worktree, written as the first `branch:` occurrence in the prompt. `enforce-orchestration-preimplementation-gate.ps1` resolves the item's worktree from these two lines and denies a delegation that carries neither with `TARGET_WORKTREE_NOT_DERIVABLE`.
|
|
47
|
+
|
|
44
48
|
## Worker Routing
|
|
45
49
|
|
|
46
50
|
- Worker: `powershell-typed-engineer`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: invoke-python-engineer
|
|
3
|
-
description: Invoke the python-typed-engineer worker to design, implement, and verify Python changes within typed repository boundaries. Applies Black -> Ruff -> Pyright -> Pytest toolchain, the 3
|
|
3
|
+
description: Invoke the python-typed-engineer worker to design, implement, and verify Python changes within typed repository boundaries. Applies Black -> Ruff -> Pyright -> Pytest toolchain, the 1-3 production-file direct-mode budget with routing to the orchestrated large path above it, and zero-regression quality gates.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Implement Python Skill
|
|
@@ -15,7 +15,7 @@ Use this skill when:
|
|
|
15
15
|
- Estimated scope fits the small path (1-3 production files plus corresponding tests).
|
|
16
16
|
- The toolchain (Black, Ruff, Pyright, Pytest) can be run in the current environment, or the user has explicitly authorized an unverified plan-only response.
|
|
17
17
|
|
|
18
|
-
If the estimated scope
|
|
18
|
+
If the estimated scope is more than 3 production files, this skill defers to the orchestrated large path (`/orchestrate`) via `python-change-budget-router` instead of proceeding directly. The large path has no production-file cap, and test files are not counted toward the routing threshold.
|
|
19
19
|
|
|
20
20
|
## Inputs
|
|
21
21
|
|
|
@@ -23,7 +23,6 @@ If the estimated scope exceeds the small-path budget, this skill defers to the o
|
|
|
23
23
|
- Files or entrypoints in scope.
|
|
24
24
|
- Constraints, including public APIs that must be preserved.
|
|
25
25
|
- Optional approved plan. If none is supplied, the worker delegates plan authoring to `atomic_planner` before any edits.
|
|
26
|
-
- Optional budget override in the form `budget: prod=<N>, test=<M>` subject to repo policy compliance.
|
|
27
26
|
|
|
28
27
|
## Output Paths
|
|
29
28
|
|
|
@@ -42,6 +41,10 @@ The worker must return the `python-qa-gate` reporting block:
|
|
|
42
41
|
4. Diffs (patch-style or full-file replacements).
|
|
43
42
|
5. QA Gate Results (Ruff, Pyright, Pytest, and coverage deltas, or clearly marked **unverified**).
|
|
44
43
|
|
|
44
|
+
## Delegation Identity Lines
|
|
45
|
+
|
|
46
|
+
Every delegation prompt this skill sends to `python-typed-engineer` carries the canonical issue-number line (`Canonical issue number for this feature is <issue_num>. All artifact content, file paths, and cross-references must use this number.`) and a `branch: <name>` label naming the branch checked out in the item's worktree, written as the first `branch:` occurrence in the prompt. `enforce-orchestration-preimplementation-gate.ps1` resolves the item's worktree from these two lines and denies a delegation that carries neither with `TARGET_WORKTREE_NOT_DERIVABLE`.
|
|
47
|
+
|
|
45
48
|
## Worker Routing
|
|
46
49
|
|
|
47
50
|
- Worker: `python-typed-engineer`
|
|
@@ -81,7 +81,7 @@ blocked result before launch.
|
|
|
81
81
|
|
|
82
82
|
Because model selection is required once delegation occurs (see `## Model Selection`), a resuming orchestrator must repair a missing model choice deterministically before delegating at a delegating `next_step`. When the resumed `next_step` is a delegating step:
|
|
83
83
|
|
|
84
|
-
a. **Preflight the checkpoint.** Run the orchestrator-state validator with `--require-model-routing` (via `mcp__drm-copilot__validate_orchestration_artifacts` or the local CLI) against `artifacts/orchestration/orchestrator-state.json` before the first delegation. Record the result in a `model_routing_preflight` block `{ status ("pass"|"fail"), checked_at (ISO-8601 UTC), validator_command, output_summary }`.
|
|
84
|
+
a. **Preflight the checkpoint.** Run the orchestrator-state validator with `--require-model-routing` (via `mcp__drm-copilot__validate_orchestration_artifacts` or the repository-local validator CLI documented in `.claude/rules/orchestrator-state.md`) against `artifacts/orchestration/orchestrator-state.json` before the first delegation. Record the result in a `model_routing_preflight` block `{ status ("pass"|"fail"), checked_at (ISO-8601 UTC), validator_command, output_summary }`.
|
|
85
85
|
b. **Recompute the floor.** For the upcoming phase, recompute the complexity floor with `Get-ComplexityFloor -SignalsPresent <names>` (`.claude/lib/model-routing/ModelRouting.psm1`); do not reimplement the formula.
|
|
86
86
|
c. **Record the assessment.** Write a `complexity_assessments[]` entry `{ phase, band, floor, signals_present[], rationale, assessed_at }` with `floor` equal to the recomputed value and `band >= floor`.
|
|
87
87
|
d. **Resolve and record the receipt.** Resolve the model with `Resolve-DelegationModel -Agent <agent> -Band <complexity_band> -FablePolicy <fable_policy>` (`.claude/lib/model-routing/ModelRouting.psm1`) and write a `model_routing_receipts[]` entry `{ agent, phase, complexity_band, fable_policy, table_model, clamped_from | null, model }`.
|
|
@@ -137,6 +137,7 @@ A delegation prompt carrying the literal marker `Preparation mode: true` (issued
|
|
|
137
137
|
- **Route.** Select `route_id: preparation`. The route's routing-matrix entry requires receipts for `task-researcher`, `prd-feature`, `atomic-planner`, and `atomic-executor`; the skills `orchestrate`, `feature-promotion-lifecycle`, and `atomic-plan-contract`; and the promotion plus validator MCP tools.
|
|
138
138
|
- **Scope.** Run promotion (MCP surface), research, feature documents (`spec.md`, `user-story.md`), atomic planning, and the atomic-executor preflight (precondition validation only, R2 semantics: iterate plan revisions until `PREFLIGHT: ALL CLEAR`). Atomic execution, PR authoring, CI monitoring, and feature review are out of scope and are executed later by `epic-orchestrator`.
|
|
139
139
|
- **Terminal checkpoint.** Stop with `completed_steps` containing `S3_promotion` and `S4_atomic_planning`, `next_step: "S5_atomic_execution"`, out-of-scope step statuses set to `not-applicable`, and `blocked_reason: "none"`. Do NOT assert completion (`next_step: "complete"`, `S12_complete`, or a `completed` step8/9/10 status): the run has no PR or CI evidence, and the route's `requires_ci_gate: false` exempts it from `ci_gate` at the completion validator instead.
|
|
140
|
+
- **Premise-falsified halt.** Use `blocked_reason: "premise_falsified"` when every delegation and validator succeeded but evidence gathered during execution falsified the plan's premise. Still record the evidence path in free-form checkpoint keys; `blocked_reason` carries only the classification. The preparation terminal checkpoint above still sets `blocked_reason: "none"`. The full `blocked_reason` vocabulary and its partition are in `.claude/rules/orchestrator-state.md`.
|
|
140
141
|
- **Commit.** Commit the prepared feature folder and plan to the current branch (the worktree branch created off the epic integration branch) before stopping, and report the `plan-path` and preflight status in the final output.
|
|
141
142
|
|
|
142
143
|
## Epic Mode Bounded Return
|
|
@@ -184,7 +185,7 @@ PR creation and PR body edits are delegated work, not orchestrator work. The orc
|
|
|
184
185
|
The mandatory sequence is:
|
|
185
186
|
|
|
186
187
|
1. The orchestrator first refreshes the PR-context artifact via `mcp__drm-copilot__collect_pr_context` (or the equivalent context-collection mechanism), which writes `artifacts/pr_context.summary.txt`.
|
|
187
|
-
2. The orchestrator runs the orchestrator-state validator (`mcp__drm-copilot__validate_orchestration_artifacts` or the equivalent local CLI
|
|
188
|
+
2. The orchestrator runs the orchestrator-state validator (`mcp__drm-copilot__validate_orchestration_artifacts` or the equivalent repository-local validator CLI documented in `.claude/rules/orchestrator-state.md`) against `artifacts/orchestration/orchestrator-state.json --require-pr-creation-ready` and records the pass/fail result under a new `pr_author_preflight` field in the checkpoint, alongside `pr_author_receipt`: `{status ("pass"|"fail"), checked_at (ISO-8601 UTC), checkpoint_path, validator_command, output_summary}`. The orchestrator must not delegate to `Agent(pr-author)` when this preflight fails. The validator's full-lifecycle completion flag (`ci_gate`/`pr_gate`/routing-contract receipts) remains reserved for the post-PR/CI completion context (Step S9 / PR Creation Gate condition 6), not this pre-PR-creation preflight, because those values cannot exist before the first `gh pr create` of a branch.
|
|
188
189
|
3. The orchestrator then delegates PR creation and any PR body edits to `Agent(pr-author)`. The `pr-author` agent runs the `pr-author` skill to author the body, writes the body file `artifacts/pr_body_<N>.md` and the sibling receipt `artifacts/pr_body_<N>.receipt.json` with the shape `{skill, pr_body_path, number, sha256 (lowercase hex of the body bytes), context_summary_path, created_at (ISO-8601 UTC, strictly newer than `artifacts/pr_context.summary.txt` last-write)}`, issues `gh pr create --body-file artifacts/pr_body_<N>.md` (or `gh pr edit --body-file ...`), and reports the resulting PR URL or PR number.
|
|
189
190
|
4. The orchestrator records `pr_author_receipt` in the checkpoint, citing the body-file path and the receipt path that were verified.
|
|
190
191
|
|
|
@@ -237,20 +238,32 @@ After each `feature-review` delegation returns:
|
|
|
237
238
|
|
|
238
239
|
1. Locate `remediation-inputs.<timestamp>.md` in the active feature folder (match the highest ISO-8601 timestamp).
|
|
239
240
|
2. If no such file exists, treat as zero blocking findings and advance to the PR creation gate.
|
|
240
|
-
3. If the file exists, count lines matching `BLOCKING` or `Severity: Blocking` (case-sensitive). If count >= 1, enter the remediation loop. If count = 0, advance to the PR creation gate.
|
|
241
|
+
3. If the file exists, count lines matching `BLOCKING` or `Severity: Blocking` (case-sensitive). If count >= 1, enter the remediation loop. If count = 0, advance to the PR creation gate. This count rule applies unchanged when the file carries no `Review-Verdict:` line: a count of at least 1 is `REMEDIATION_REQUIRED` and every finding is treated as `autonomous`.
|
|
242
|
+
4. If the file carries a `Review-Verdict:` line, recompute the verdict from the `Remediability:` lines of the blocking findings (a blocking finding block without a `Remediability:` line counts as `autonomous`): no blocking finding is `PASS`; any `autonomous` finding is `REMEDIATION_REQUIRED`; otherwise any `external_dependency`, `policy_hold`, or `human_decision_required` finding is `HALT_NON_REMEDIABLE`; otherwise `AWAITING_CI`. The `remediation-inputs` file is authoritative; the optional `review-status:` token in the review result is a cross-check.
|
|
243
|
+
5. A mismatch between the declared and recomputed verdicts is a reviewer contract error: record it under `artifact_errors`, re-request the review once, and halt with `blocked_reason: "delegate_contract_incomplete"` if it persists.
|
|
244
|
+
6. Append a `remediation_loop.review_outcomes[]` entry (`verdict` plus one `findings[]` object with `remediability` per blocking finding) for every review, including `PASS`.
|
|
245
|
+
7. Act on the verdict: `PASS` advances to the PR creation gate; `REMEDIATION_REQUIRED` enters the remediation loop with the plan scoped to the `autonomous` findings, carrying the non-remediable findings forward unchanged; `HALT_NON_REMEDIABLE` follows the halt branch; `AWAITING_CI` follows the wait branch.
|
|
246
|
+
|
|
247
|
+
Halt branch (`HALT_NON_REMEDIABLE`): set `blocked_reason` to the highest-precedence halt class present, append one `human_interaction.requirements[]` entry with `response: "halt"` for each halt class present (`external_dependency`, `policy_hold`, `human_decision_required`) describing the human action needed, leave `remediation_loop.completed_attempts` unchanged, write no cycle, create no remediation plan, and stop. The precedence is:
|
|
248
|
+
|
|
249
|
+
Halt precedence: human_decision_required > policy_hold > external_dependency
|
|
250
|
+
|
|
251
|
+
Wait branch (`AWAITING_CI`): set `blocked_reason: "awaiting_ci"` and set `next_step` to the step that re-checks (`S7_feature_review` for a review-time wait, `S9_ci_green` for an S9 poll timeout). Record no `human_interaction.requirements[]` entry for a wait, write no cycle, and create no remediation plan. Poll within the existing bounded S9 interval and timeout; when the bound is exhausted, persist and stop. On resume, set `blocked_reason: "none"` and re-run the named step. For S9, the awaited run is identified by `ci_gate.head_sha` and `ci_gate.pr_pipeline_run_id` with `conclusion: "pending"`; for a review-time wait, the awaited workflow is named in the finding's `Remediability-Evidence:` line.
|
|
241
252
|
|
|
242
253
|
## Remediation Loop (R1–R5)
|
|
243
254
|
|
|
244
|
-
A bounded loop consisting of five steps. The
|
|
255
|
+
A bounded loop consisting of five steps. The attempt count is `remediation_loop.completed_attempts`, and `remediation_pass` equals `remediation_loop.completed_attempts`. The active cycle number is `completed_attempts + 1`, and `remediation.cycle_N` in `next_step` uses that number; `remediation_loop.current_cycle` is a record position in `cycles[]`, not a count. A halt or wait verdict never opens a cycle, and every cycle opened from a review records `opened_by_review`, the zero-based index of that `review_outcomes[]` entry.
|
|
256
|
+
|
|
257
|
+
Cycle accounting: a remediation attempt is complete when R3 execution finished (`execution_status: "complete"`) and the pre-R4 commit recorded a non-empty change set; only then set `candidate_applied: true` on that cycle and increment `completed_attempts`. A cycle that ends without a candidate (execution not started, execution failed, or an empty staged change set) records `candidate_applied: false` and consumes no number. It is followed by at most one re-plan under the same number when the executor output identifies an autonomous plan defect; otherwise reclassify the blocker (typically `external_dependency`) and halt. Two consecutive no-candidate cycles halt with `step6_status: "blocked_remediation_loop_limit"`. Local, CI-failure, merge-conflict, and parallel-drift cycles share the one count.
|
|
245
258
|
|
|
246
259
|
- **R1 — Remediation planning:** Delegate to `atomic-planner` with `remediation-inputs.<timestamp>.md` path as primary context. Receive `remediation-plan.<timestamp>.md` in the active feature folder.
|
|
247
260
|
- **R2 — Preflight clearance:** Delegate to `atomic-executor` for precondition validation only (no implementation). If the executor does not return `PREFLIGHT: ALL CLEAR`, return to R1 and re-delegate to `atomic-planner` with the required-changes output from the executor. Only after `PREFLIGHT: ALL CLEAR` may the orchestrator advance to R3.
|
|
248
261
|
- **R3 — Remediation execution:** Delegate to `atomic-executor` with full execution authorization. Each task's toolchain loop (format → lint → type-check → test) is mandatory; no skipping.
|
|
249
262
|
- **Pre-R4 commit:** Stage all changes (`git add -A`), delegate to `Agent(commit-message)` to generate a commit message from the staged diff (the agent returns message text only and does not commit), then commit with the generated message. The `git commit` action remains on the orchestrator. Advance to R4 only after a successful commit.
|
|
250
263
|
- **R4 — Re-audit:** Delegate to `feature-review` with the same inputs as the original review (resolved base branch, feature folder, refreshed PR context artifacts, acceptance-criteria source). No scope narrowing. The canonical issue number line must be included.
|
|
251
|
-
- **R5 — Loop-exit decision:**
|
|
264
|
+
- **R5 — Loop-exit decision:** Evaluate the re-audit per Post-Review Outcome Evaluation. If it produces zero blocking findings, exit the loop and advance to the PR creation gate. If its verdict is `HALT_NON_REMEDIABLE` or `AWAITING_CI`, follow the halt or wait branch instead of opening the next cycle. Otherwise, record the cycle's `candidate_applied` value and the resulting `completed_attempts` in the checkpoint and return to R1.
|
|
252
265
|
|
|
253
|
-
**Termination guard:**
|
|
266
|
+
**Termination guard:** Halt after three completed attempts: when `remediation_loop.completed_attempts` equals 3 and the latest verdict is not `PASS`, the orchestrator records `step6_status: "blocked_remediation_loop_limit"` in the checkpoint and halts. No further automation is attempted.
|
|
254
267
|
|
|
255
268
|
## Issue Number Consistency
|
|
256
269
|
|
|
@@ -260,7 +273,9 @@ Every delegation prompt to a receipt-gated subagent type — `atomic-planner`, `
|
|
|
260
273
|
|
|
261
274
|
> `Canonical issue number for this feature is <issue_num>. All artifact content, file paths, and cross-references must use this number.`
|
|
262
275
|
|
|
263
|
-
Each such prompt also carries a `branch: <name>` label naming the branch checked out in the item's worktree, written as the first `branch:` occurrence in the prompt. Before promotion assigns an issue number, the branch label alone is required.
|
|
276
|
+
Each such prompt also carries a `branch: <name>` label naming the branch checked out in the item's worktree, written as the first `branch:` occurrence in the prompt. Before promotion assigns an issue number, the branch label alone is required. Three gates, `enforce-model-routing-receipt.ps1`, `enforce-prd-feature-before-planner.ps1`, and `enforce-orchestration-preimplementation-gate.ps1`, identify the item from these two lines: they deny a gated delegation they cannot identify rather than checking it against whichever checkpoint occupies the calling session's root, and they never use a feature-folder path to choose the worktree, because a merged feature folder exists in every checkout branched from main.
|
|
277
|
+
|
|
278
|
+
The same two lines are required on every delegation to an implementation agent (`python-typed-engineer`, `powershell-typed-engineer`, `typescript-engineer`, `csharp-typed-engineer`, and `atomic-executor`) and on every `Agent(orchestrator)` delegation that carries no epic-mode, parallel-mode, or preparation-mode kickoff marker. `enforce-orchestration-preimplementation-gate.ps1` resolves such a delegation's worktree from these lines and denies it with `TARGET_WORKTREE_NOT_DERIVABLE` when neither line is present, or with `TARGET_WORKTREE_AMBIGUOUS` when the lines disagree or match more than one live worktree.
|
|
264
279
|
|
|
265
280
|
If a subagent artifact references a different issue number, the orchestrator rejects it, requests correction, and records the discrepancy under `artifact_errors` in the checkpoint.
|
|
266
281
|
|
|
@@ -273,10 +288,12 @@ S9 procedure:
|
|
|
273
288
|
1. Resolve the live PR head SHA for the feature branch (`gh pr view --json headRefOid` or equivalent).
|
|
274
289
|
2. Invoke `gh pr checks --required --json bucket,name,state,link,workflow` (or an equivalent JSON-emitting command) against that head SHA. `gh` is the only sanctioned channel for querying GitHub Actions state.
|
|
275
290
|
3. Parse the JSON by running `pwsh -NoProfile -File .claude/lib/ci-gate/Invoke-CiGateParser.ps1 -ChecksJson <checks-json> -HeadSha <head-sha>`, which emits the `ci_gate` object defined below and derives `ci_gate.conclusion` as `success` when all required checks pass, `failure` when any required check failed, and `pending` when any required check is still in progress.
|
|
276
|
-
4. Poll with a bounded interval and a documented total timeout while `conclusion == "pending"`. When the timeout is exhausted,
|
|
291
|
+
4. Poll with a bounded interval and a documented total timeout while `conclusion == "pending"`. When the timeout is exhausted, record the timeout as a finding with `Remediability: awaiting_ci` in `remediation-inputs.<timestamp>.md` and follow the wait branch in Post-Review Outcome Evaluation (`blocked_reason: "awaiting_ci"`, `next_step: "S9_ci_green"`); `step9_status` stays `pending`. A poll timeout does not enter the remediation loop.
|
|
277
292
|
5. Write the `ci_gate` object and `last_verified_ci_sha` to the checkpoint, and set `step9_status` to `passed` only when `ci_gate.conclusion == "success"` AND `ci_gate.head_sha` equals the current PR head SHA.
|
|
278
293
|
6. If the checkpoint's `epic_mode` is `true`, execute `gh pr merge --merge <PR>` merging the feature branch into `epic_context.integration_branch` (already the PR's base branch per the epic-mode `--base` override applied at S8). On success, record `epic_merge: { merge_commit_sha, target_branch, merged_at }` in the checkpoint. On failure due to merge conflict (non-mergeable PR), do not retry blindly: convert the conflict into a synthetic Blocking finding per "Merge-Conflict Remediation" below and re-enter the standard R1–R5 remediation loop; do not proceed to DONE.
|
|
279
294
|
|
|
295
|
+
CI-dependent acceptance criteria: when the item has acceptance criteria whose verification requires the result of CI on the PR head, the item's own orchestrator run owns their check-off, and a parent or coordinating session never commits them from its own root. After step 5 records `ci_gate.conclusion == "success"`, check off each CI-dependent criterion in the item's own worktree, commit, push to the PR branch, and re-run S9 from step 1 against the new head SHA, so that `ci_gate.head_sha` equals the final PR head before DONE. In epic mode this completes before step 6 merges. A failed re-run enters `## Remediation Loop — CI-Failure Handling` below; the shared `remediation_loop.completed_attempts` count and its halt after three completed attempts are unchanged.
|
|
296
|
+
|
|
280
297
|
DONE is not written while `step9_status` is anything other than `passed`.
|
|
281
298
|
|
|
282
299
|
## Checkpoint Schema — CI Gate Fields
|
|
@@ -319,13 +336,13 @@ A checkpoint that predates this schema and has no `ci_gate` object (or no `step9
|
|
|
319
336
|
|
|
320
337
|
## Remediation Loop — CI-Failure Handling
|
|
321
338
|
|
|
322
|
-
When S9 records `step9_status: "failed_remediation_required"` (a failed required check
|
|
339
|
+
When S9 records `step9_status: "failed_remediation_required"` (a failed required check; a poll timeout follows the wait branch per S9 step 4):
|
|
323
340
|
|
|
324
|
-
1. The failed-check log from `gh run view <run-id> --log-failed`
|
|
341
|
+
1. The failed-check log from `gh run view <run-id> --log-failed` is written as `remediation-inputs.<timestamp>.md` in the active feature folder.
|
|
325
342
|
2. The failure is converted to a synthetic finding with severity `Blocking` that identifies the failing check by name and the failing job by URL.
|
|
326
343
|
3. The existing R1-R5 remediation loop processes that finding exactly as it processes a local blocking finding. No new loop is introduced.
|
|
327
|
-
4.
|
|
328
|
-
5.
|
|
344
|
+
4. CI-failure cycles share `remediation_loop.completed_attempts` with local-finding cycles; a CI-failure finding stays `autonomous`, and the active cycle number is `completed_attempts + 1`.
|
|
345
|
+
5. The shared guard applies: after three completed attempts without a passing result, the orchestrator records `step9_status: "blocked_ci_loop_limit"`, does not write DONE, and halts. No further automation is attempted.
|
|
329
346
|
|
|
330
347
|
## PR Creation Gate
|
|
331
348
|
|
|
@@ -333,6 +350,7 @@ The orchestrator must not create a PR, push a branch for PR purposes, or report
|
|
|
333
350
|
|
|
334
351
|
1. `blocking_findings_resolved: true` — the most recent `feature-review` produced zero blocking findings.
|
|
335
352
|
2. The AC verification artifact (`p14-acceptance-criteria-checkoff.md` or equivalent) confirms all acceptance criteria pass.
|
|
353
|
+
A CI-dependent acceptance criterion, one whose verification requires the result of CI on the PR head, cannot pass before CI exists: condition 2 is satisfied when every other criterion passes and each CI-dependent criterion is listed as pending-CI in the AC verification artifact. Pending-CI criteria are checked off under S9 before DONE. This clarifies condition 2 and adds no condition.
|
|
336
354
|
3. The mandatory toolchain passed in its most recent run on the branch (no linting/type-check/test failures).
|
|
337
355
|
4. The checkpoint `next_step` is `S8_create_pr` (precondition to entering S9).
|
|
338
356
|
5. PR body produced via the pr-author handoff: `artifacts/pr_body_<N>.md` exists with a matching `artifacts/pr_body_<N>.receipt.json`, created with `--body-file`.
|
|
@@ -418,6 +436,8 @@ Example:
|
|
|
418
436
|
]
|
|
419
437
|
```
|
|
420
438
|
|
|
421
|
-
The validator counts an MCP receipt as successful only when `tool` is a non-empty string, `ok` is exactly `true`, and `evidence` is a non-empty string. Every `required_mcp_tools` entry must have such a receipt.
|
|
439
|
+
The validator counts an MCP receipt as successful only when `tool` is a non-empty string, `ok` is exactly `true`, and `evidence` is a non-empty string. Every `required_mcp_tools` entry must have such a receipt unless a valid `issue_adoption` record waives it.
|
|
440
|
+
|
|
441
|
+
When the GitHub issue already exists before orchestration starts (transferred, filed by hand, or created by epic decomposition) and has been verified read-only (`gh issue view`, a `gh api` GET, or a GitHub MCP issue read), do not call `potential_to_issue`. Record a top-level `issue_adoption` object in the checkpoint instead of a `potential_to_issue` receipt. It may waive only `potential_to_issue` and, with a valid `potential_record` under `docs/features/potential/`, the checkpoint's promotion-entry tool (`new_potential_entry`, or `new_potential_bug_entry` for a bug-type checkpoint); `potential_to_issue` must always be listed. Every other required tool still needs a successful receipt. Any adoption error waives nothing. The field rules, the closed waivable set, and the error placement are defined in `.claude/rules/orchestrator-state.md` under `## Invariants (issue_adoption object)`.
|
|
422
442
|
|
|
423
443
|
These three receipt arrays, populated with the retained required names of the selected route, are what allow the routing-contract validation under `require_complete: true` to pass.
|
|
@@ -277,6 +277,8 @@ Negative obligations on the prompt:
|
|
|
277
277
|
Excluded from the prompt as parent-side concerns: the item's declared blast radius,
|
|
278
278
|
`max_concurrency`, and `mode`. Keeping the prompt minimal preserves the child contract unchanged.
|
|
279
279
|
|
|
280
|
+
The run gates `enforce-orchestration-preimplementation-gate.ps1`, `enforce-parallel-cohort-barrier.ps1`, and `enforce-parallel-drift-gate.ps1` locate the parallel checkpoint by the `parallel_slug:` value of the marker line. They select the single live worktree whose `artifacts/orchestration/parallel-orchestrator-state.json` records `route_id` `parallel` and that slug, and deny the delegation with `TARGET_WORKTREE_NOT_DERIVABLE` or `TARGET_WORKTREE_AMBIGUOUS` when none or more than one matches. The child run's own delegations to implementation agents carry the canonical issue-number line and `branch:` label defined in `.claude/skills/orchestrate/SKILL.md` `## Issue Number Consistency`.
|
|
281
|
+
|
|
280
282
|
## Model Selection
|
|
281
283
|
|
|
282
284
|
When `parallel-orchestrator` delegates an item to `Agent(orchestrator)`, the prompt appends the
|
|
@@ -311,6 +313,12 @@ unchanged: `.claude/skills/orchestrate/SKILL.md` is **not modified by this featu
|
|
|
311
313
|
`parallel_mode` clause in its step 9, no `parallel_merge` object in the child checkpoint, and no
|
|
312
314
|
additional condition on the child's PR Creation Gate.
|
|
313
315
|
|
|
316
|
+
Issue #744 later amended two parts of that child contract for CI-dependent acceptance criteria,
|
|
317
|
+
whose verification requires the result of CI on the item's pull-request head: PR Creation Gate
|
|
318
|
+
condition 2 and step S9 of `.claude/skills/orchestrate/SKILL.md`. The child checks those criteria
|
|
319
|
+
off in its own worktree, pushes the check-off commit to its pull-request branch, and re-runs S9
|
|
320
|
+
before DONE. The parent never commits acceptance-criteria check-offs from the coordinator root.
|
|
321
|
+
|
|
314
322
|
Procedure, per item:
|
|
315
323
|
|
|
316
324
|
1. The item's child orchestration runs unmodified, with `epic_mode` `false` or absent, and finishes
|
|
@@ -321,6 +329,11 @@ Procedure, per item:
|
|
|
321
329
|
`gh pr view --json state,mergedAt,headRefOid`, and with `gh pr checks` when the check conclusion
|
|
322
330
|
must be re-read — never from an in-memory completion notification — then record
|
|
323
331
|
`merge_status: ci_green`.
|
|
332
|
+
Before recording `merge_status: ci_green`, confirm that the `headRefOid` value equals the
|
|
333
|
+
`ci_gate.head_sha` the child reported at DONE and that the child reported no pending
|
|
334
|
+
CI-dependent acceptance criteria. When either check fails, do not record
|
|
335
|
+
`merge_status: ci_green` and do not run `gh pr merge`; the item waits until its child pushes
|
|
336
|
+
the check-off and re-runs S9, and the parent does not commit the check-off itself.
|
|
324
337
|
3. Execute `gh pr merge --merge <PR>` for that item's pull request, whose base is `main`.
|
|
325
338
|
4. On success, record `merge_commit_sha`, `merged_at`, and `merge_status: merged`, then regenerate
|
|
326
339
|
`docs/features/parallel/<slug>/parallel-status.md`.
|
|
@@ -415,8 +428,10 @@ the escalation path.
|
|
|
415
428
|
2. The parent re-delegates that item's child orchestration. The child processes the finding through
|
|
416
429
|
its unmodified R1 through R5 remediation loop exactly as it processes any local Blocking
|
|
417
430
|
finding. No new remediation loop is introduced by this procedure.
|
|
418
|
-
3.
|
|
419
|
-
|
|
431
|
+
3. Drift cycles share the child's `remediation_loop.completed_attempts` count with its
|
|
432
|
+
local-finding and CI-failure cycles, and the child halts after three completed attempts. The
|
|
433
|
+
active cycle number is `completed_attempts + 1`, and a cycle without an applied candidate
|
|
434
|
+
consumes no number.
|
|
420
435
|
4. Each remediated pass ends again at child DONE with the pull request open and CI green, after
|
|
421
436
|
which the parent retries the merge per `## Per-Item Merge to Main (Merge-on-Green)`. During
|
|
422
437
|
remediation the item's `merge_status` legitimately remains `pr_open` or `ci_green`: the
|
|
@@ -565,6 +580,8 @@ hold:
|
|
|
565
580
|
`artifact_type: "parallel-orchestrator-state"`.
|
|
566
581
|
4. Each item's acceptance criteria have been checked off in that item's own acceptance-criteria
|
|
567
582
|
source files by that item's own run, per the `acceptance-criteria-tracking` skill.
|
|
583
|
+
A CI-dependent criterion is checked off and pushed by that item's own run before its DONE, so
|
|
584
|
+
the head the parent merges already contains the check-off; the parent never commits it.
|
|
568
585
|
|
|
569
586
|
In `open` mode there is no automatic completion. The run is a standing queue and terminates only via
|
|
570
587
|
`/parallel-close`, which is owned by F6 and is neither specified nor shipped by this feature. Do not
|
|
@@ -729,8 +746,8 @@ a detached item.
|
|
|
729
746
|
### Abandon confirmation-marker contract
|
|
730
747
|
|
|
731
748
|
The `abandon` disposition is destructive: it closes the item's pull request and removes its
|
|
732
|
-
worktree. Both side effects run through ONE deterministic
|
|
733
|
-
|
|
749
|
+
worktree. Both side effects run through ONE deterministic invocation of the bundled bash entry
|
|
750
|
+
point `.claude/lib/bash/abandon-parallel-item.sh`, documented in full in
|
|
734
751
|
`.claude/skills/parallel-remove/SKILL.md`. Executing the abandon disposition through ad hoc `gh` or
|
|
735
752
|
`git` commands is prohibited, because an ad hoc command is not matchable and would bypass the
|
|
736
753
|
confirmation contract.
|
|
@@ -875,25 +892,35 @@ carries no such marker, evaluates no drift, and is unaffected.
|
|
|
875
892
|
|
|
876
893
|
#### CLI Invocation
|
|
877
894
|
|
|
878
|
-
Detection logic is pure and lives in
|
|
879
|
-
detection, `drift_events[]` construction,
|
|
880
|
-
|
|
881
|
-
|
|
895
|
+
Detection logic is pure and lives in `.claude/lib/parallel-drift/ParallelDrift.psm1` (escape
|
|
896
|
+
detection, `drift_events[]` construction, and conflict recomputation) and
|
|
897
|
+
`.claude/lib/parallel-drift/ParallelDriftHalt.psm1` (halt selection). The first calls the bundled
|
|
898
|
+
blast-radius library under `.claude/lib/blast-radius/` rather than re-deriving it. All I/O is confined
|
|
899
|
+
to the destination-runtime entry point `.claude/lib/parallel-drift/Invoke-ParallelDriftDetection.ps1`,
|
|
900
|
+
which needs PowerShell 7 and no Python interpreter, invoked as:
|
|
882
901
|
|
|
883
902
|
```
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
[
|
|
887
|
-
[
|
|
888
|
-
[
|
|
903
|
+
pwsh -NoProfile -NonInteractive -File .claude/lib/parallel-drift/Invoke-ParallelDriftDetection.ps1 \
|
|
904
|
+
-ItemKey <issue_num> \
|
|
905
|
+
[-CheckpointPath artifacts/orchestration/parallel-orchestrator-state.json] \
|
|
906
|
+
[-ConfigPath config/blast-radius.json] \
|
|
907
|
+
[-At <yyyy-MM-ddTHH-mm>] [-ComputedAt <yyyy-MM-ddTHH-mm>] \
|
|
889
908
|
<CHANGED_PATH>...
|
|
890
909
|
```
|
|
891
910
|
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
911
|
+
The Python modules `scripts/dev_tools/parallel_drift_detection.py` and
|
|
912
|
+
`scripts/dev_tools/parallel_drift_halt.py`, with their thin wrapper
|
|
913
|
+
`scripts/dev_tools/parallel_drift_detection_cli.py`, remain the repository authority and the parity
|
|
914
|
+
reference; the shared corpus under `tests/fixtures/parallel_drift/` binds the two, and the Python
|
|
915
|
+
modules are not invoked on the destination-runtime path.
|
|
916
|
+
|
|
917
|
+
Argument surface: `-ItemKey` is the only required argument and is the item's `issue_num`;
|
|
918
|
+
`-CheckpointPath` and `-ConfigPath` default to the two paths shown and resolve against the caller's
|
|
919
|
+
working directory; `-At` is the timestamp recorded on the `drift_events[]` entry and `-ComputedAt` the
|
|
920
|
+
timestamp recorded on the observed radius, each defaulting at the I/O boundary so the pure functions
|
|
921
|
+
never read a clock; and the changed paths are positional and variadic. No parameter is mandatory, so
|
|
922
|
+
a missing `-ItemKey` exits `2` instead of prompting. An empty changed-path list is legal and yields
|
|
923
|
+
`no_escape`.
|
|
897
924
|
|
|
898
925
|
The changed-path list is an argument, not something the module derives: the caller produces it with
|
|
899
926
|
`git diff --name-only <merge-base(origin/main, HEAD)> HEAD` at the child's pre-review commit, and
|
|
@@ -930,7 +957,8 @@ escaped paths is not a drift event. `observed_radius` is the serialized observed
|
|
|
930
957
|
parent writes back in step 7 of `#### Seven-Step Procedure`: it carries the six invariant-9 keys with
|
|
931
958
|
`source: observed`, is built by F1's library rather than by hand, and is `null` exactly when `result`
|
|
932
959
|
is `no_escape`, on the same precondition as `drift_event`. Exit status is `0` on success, `1` on
|
|
933
|
-
missing or malformed input, and
|
|
960
|
+
missing or malformed input (one stderr line prefixed "parallel drift detection failed: "), and `2`
|
|
961
|
+
on a usage error, such as a missing or non-integer `-ItemKey` or an unrecognized parameter.
|
|
934
962
|
|
|
935
963
|
#### Synthetic Blocking Finding
|
|
936
964
|
|
|
@@ -958,7 +986,8 @@ on its own R1 through R5 loop for the drift finding, so halting it would deadloc
|
|
|
958
986
|
that resolves the drift.
|
|
959
987
|
|
|
960
988
|
The exclusion is applied **at the call site, before the later-started comparator runs**:
|
|
961
|
-
`
|
|
989
|
+
`Get-ParallelDriftHaltedItemKey` in `.claude/lib/parallel-drift/ParallelDriftHalt.psm1` (the port of
|
|
990
|
+
`halted_item_keys` in `scripts/dev_tools/parallel_drift_detection_cli.py`) drops the drifting key from
|
|
962
991
|
each pair's candidate list, then halts the single remaining candidate, or applies the comparator when
|
|
963
992
|
two remain. Because a recomputed pair holds two distinct canonical keys, the candidate list is always
|
|
964
993
|
one or two entries and can never be empty. It remains true, and remains a real structural guarantee,
|
|
@@ -1099,7 +1128,7 @@ R5 loop that drives the remediation preceding either write is **reused
|
|
|
1099
1128
|
unmodified**: `atomic-planner` plans the resolution, `atomic-executor` performs preflight then
|
|
1100
1129
|
resolves, `feature-review` re-audits, and the loop exits on zero blocking findings. No new
|
|
1101
1130
|
remediation loop is authored, no line of the existing loop is modified, and the shared
|
|
1102
|
-
`
|
|
1131
|
+
`remediation_loop.completed_attempts` count applies, with the halt after three completed attempts. `.claude/skills/orchestrate/SKILL.md` is not modified by this
|
|
1103
1132
|
feature.
|
|
1104
1133
|
|
|
1105
1134
|
#### Layer-1 Narrowing — a Documented Limitation
|
|
@@ -108,8 +108,8 @@ Do not record a partial removal, and do not record the rejection itself in `muta
|
|
|
108
108
|
removing the worktree — through the single deterministic CLI invocation below and through nothing
|
|
109
109
|
else:
|
|
110
110
|
|
|
111
|
-
```
|
|
112
|
-
|
|
111
|
+
```shell
|
|
112
|
+
bash .claude/lib/bash/abandon-parallel-item.sh --item <key> --disposition abandon --confirm-abandon --pr <pr-number> --worktree <worktree-path>
|
|
113
113
|
```
|
|
114
114
|
|
|
115
115
|
Executing the abandon disposition through ad hoc `gh pr close` or `git worktree remove` commands
|
|
@@ -146,14 +146,14 @@ The abandon path is guarded by the PreToolUse hook
|
|
|
146
146
|
- A command carrying both tokens is allowed.
|
|
147
147
|
- A command carrying neither is out of scope and is allowed unchanged.
|
|
148
148
|
|
|
149
|
-
The two token values are declared once each in
|
|
150
|
-
`scripts/dev_tools/parallel_mutation_abandon_cli.py` (the
|
|
151
|
-
|
|
152
|
-
`tests/scripts/dev_tools/test_parallel_abandon_token_seam.py` parses all
|
|
153
|
-
the hook, and the invocation line in step 5 above — at run time
|
|
154
|
-
a token in one artifact without the identical rename in the
|
|
155
|
-
invocation in step 5 is the file's only executable abandon command
|
|
156
|
-
that one line; do not add a second one.
|
|
149
|
+
The two token values are declared once each in `.claude/lib/bash/abandon-parallel-item.sh` (the
|
|
150
|
+
pushed-down producer), once each in `scripts/dev_tools/parallel_mutation_abandon_cli.py` (the retained
|
|
151
|
+
Python parity reference), and once each in the hook (the consumer). The seam test
|
|
152
|
+
`tests/scripts/dev_tools/test_parallel_abandon_token_seam.py` parses all four artifacts — the bundled
|
|
153
|
+
entry point, the Python reference, the hook, and the invocation line in step 5 above — at run time
|
|
154
|
+
to prove they still agree. Renaming a token in one artifact without the identical rename in the
|
|
155
|
+
others fails that test. The invocation in step 5 is the file's only executable abandon command
|
|
156
|
+
line, and the seam test parses that one line; do not add a second one.
|
|
157
157
|
|
|
158
158
|
When the gate denies a command, the correct response is to add the confirmation marker
|
|
159
159
|
deliberately, not to reformulate the command to evade the match. Reformulating to evade the gate
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: python-change-budget-router
|
|
3
|
-
description: Budget-first routing
|
|
3
|
+
description: Budget-first routing contract for Python work. Estimate production-file scope, choose small vs large path, and route direct-mode work of more than 3 production files to the orchestrated large path.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Python Change Budget Router
|
|
7
7
|
|
|
8
|
-
Canonical guidance for deciding whether Python work stays on the small path (`python-typed-engineer` direct mode) or escalates to the
|
|
8
|
+
Canonical guidance for deciding whether Python work stays on the small path (`python-typed-engineer` direct mode) or escalates to the orchestrated large path through `/orchestrate` (the `orchestrator` agent).
|
|
9
9
|
|
|
10
10
|
## When to Use This Skill
|
|
11
11
|
|
|
@@ -14,50 +14,27 @@ Use this skill when:
|
|
|
14
14
|
- Intake starts from a natural-language Python request.
|
|
15
15
|
- An agent must decide the execution path before planning or implementation.
|
|
16
16
|
- A direct-mode route must reject over-budget requests and switch to orchestrated flow.
|
|
17
|
-
- An executor must confirm a batch fits within the 3 production + 3 test file cap before editing.
|
|
18
17
|
|
|
19
18
|
## Canonical Routing Rules
|
|
20
19
|
|
|
21
20
|
1. Estimate rough change budget first based on likely **production Python files** touched.
|
|
22
21
|
2. Route:
|
|
23
22
|
- `1-3` production files (plus corresponding tests) → **small path** (`python-typed-engineer` direct mode).
|
|
24
|
-
-
|
|
25
|
-
|
|
26
|
-
## Per-Batch Change Budget (Hard Gate)
|
|
27
|
-
|
|
28
|
-
During Phase C execution:
|
|
29
|
-
|
|
30
|
-
- A single batch may change at most **3 production files** and **3 test files**.
|
|
31
|
-
- The default cap applies unless the user supplies an override of the form `budget: prod=<N>, test=<M>` in the initiating prompt.
|
|
32
|
-
- A user override may be honored only if it complies with repo policy and approved scope. If the requested scope exceeds 3 production files overall, stop before execution and seek explicit approval.
|
|
33
|
-
- If an override is requested, confirm compliance with repo policy before entering Phase C.
|
|
34
|
-
|
|
35
|
-
## Scope Expansion Protocol
|
|
36
|
-
|
|
37
|
-
When in-scope work is required beyond 3 production files, stop and return:
|
|
38
|
-
|
|
39
|
-
- a one-paragraph justification for the additional files,
|
|
40
|
-
- the exact additional file paths,
|
|
41
|
-
- the smallest alternative that avoids expanding scope,
|
|
42
|
-
|
|
43
|
-
and wait for explicit user approval before proceeding.
|
|
44
|
-
|
|
45
|
-
Allowed minimal-seam exceptions (still within the 3-file cap) are:
|
|
46
|
-
|
|
47
|
-
- introducing a minimal seam for testability (I/O boundary isolation, dependency injection),
|
|
48
|
-
- typing changes required for Pyright cleanliness in the slice,
|
|
49
|
-
- updating the smallest set of call sites needed to preserve a stable public API.
|
|
23
|
+
- More than 3 production files → **large path** (`/orchestrate`, the `orchestrator` agent). The large path has no production-file cap.
|
|
24
|
+
3. Test files are not counted toward the routing threshold.
|
|
50
25
|
|
|
51
26
|
## Direct-Mode Rejection Rule
|
|
52
27
|
|
|
53
|
-
If `python-typed-engineer` is invoked directly and estimated scope is
|
|
28
|
+
If `python-typed-engineer` is invoked directly and the estimated scope, or the scope discovered during implementation, is more than 3 production files:
|
|
54
29
|
|
|
55
|
-
- Stop before
|
|
56
|
-
-
|
|
30
|
+
- Stop before editing the 4th production file.
|
|
31
|
+
- Report the production files already changed and the production files still required.
|
|
32
|
+
- Return an explicit routing instruction to invoke `/orchestrate`.
|
|
33
|
+
- Do not request an exception to the threshold; routing is the only path past it.
|
|
57
34
|
|
|
58
35
|
## Orchestrated Small-Path Requirements
|
|
59
36
|
|
|
60
|
-
When routed through
|
|
37
|
+
When routed through `/orchestrate`, the small path still requires lifecycle scaffolding before implementation:
|
|
61
38
|
|
|
62
39
|
- invoke promotion and folder lifecycle steps through `vscode/runCommand` and extension access per `feature-promotion-lifecycle` when available. Use script or CLI fallback only when direct extension command execution is unavailable.
|
|
63
40
|
- promote the potential item to a GitHub issue with `--work-mode minor-audit`,
|
|
@@ -75,5 +52,4 @@ Record in the agent response or logs:
|
|
|
75
52
|
|
|
76
53
|
- estimated production file count,
|
|
77
54
|
- chosen path (`small` or `large`),
|
|
78
|
-
- rationale summary (1-3 bullets)
|
|
79
|
-
- any requested budget override and its approval state.
|
|
55
|
+
- rationale summary (1-3 bullets).
|
package/resources/claude-customizations/.claude/skills/remediation-handoff-atomic-planner/SKILL.md
CHANGED
|
@@ -54,6 +54,8 @@ Trigger remediation when any of these are true:
|
|
|
54
54
|
- Acceptance criteria are not met.
|
|
55
55
|
- A required CI check fails after the PR is open (workflow-file changes specifically must enter the loop and trigger the `modified-workflow-needs-green-run` rule defined in `.claude/skills/feature-review-workflow/SKILL.md`).
|
|
56
56
|
|
|
57
|
+
Remediation triggers only on blocking findings classified `autonomous`. Each blocking finding carries one remediability class (`autonomous`, `external_dependency`, `policy_hold`, `awaiting_ci`, or `human_decision_required`; `autonomous` when no class is stated). When no blocking finding is `autonomous`, the review verdict is `HALT_NON_REMEDIABLE` or `AWAITING_CI`: the orchestrator halts or waits, and no cycle, remediation plan, or `atomic-planner` handoff is created.
|
|
58
|
+
|
|
57
59
|
## Required Remediation Inputs
|
|
58
60
|
|
|
59
61
|
The orchestrator authors `remediation/<entry-ts>/remediation-inputs.md` with:
|
|
@@ -118,11 +120,13 @@ Iteration ceiling. When a cycle's `iterations` would exceed 2, the orchestrator
|
|
|
118
120
|
|
|
119
121
|
When preflight is clear, `atomic-executor` executes the plan task-by-task. The executor invokes workers (`python-typed-engineer`, `typescript-engineer`, `csharp-typed-engineer`, `powershell-typed-engineer`) internally as needed. The orchestrator does not call workers.
|
|
120
122
|
|
|
123
|
+
Before the reaudit, the orchestrator records `candidate_applied` on the current cycle: `true` only when execution finished with `execution_status: "complete"` and the pre-reaudit commit recorded a non-empty change set, and `false` otherwise (execution not started, execution failed, or an empty staged change set). `remediation_loop.completed_attempts` equals the number of cycles whose `candidate_applied` is `true`, and a cycle with `candidate_applied: false` consumes no attempt number.
|
|
124
|
+
|
|
121
125
|
When execution is complete, the orchestrator delegates to `feature-review`. `feature-review` produces the three reaudit artifacts under `docs/features/active/<slug>/audit/<exit-ts>/` using the exit timestamp.
|
|
122
126
|
|
|
123
127
|
## Exit Gate
|
|
124
128
|
|
|
125
|
-
The orchestrator reads the latest cycle's three reaudit artifacts and computes `blocking_count` as the total number of FAIL findings plus material PARTIAL findings flagged as blocking. Only when `blocking_count == 0` does the orchestrator set `exit_condition_met = true` on the current cycle and mark the remediation loop complete. Otherwise, the orchestrator opens cycle N+1 with a new `remediation/<new-ts>/remediation-inputs.md` and runs the full chain again.
|
|
129
|
+
The orchestrator reads the latest cycle's three reaudit artifacts and computes `blocking_count` as the total number of FAIL findings plus material PARTIAL findings flagged as blocking. Only when `blocking_count == 0` does the orchestrator set `exit_condition_met = true` on the current cycle and mark the remediation loop complete. Otherwise, when at least one remaining blocking finding is `autonomous`, the orchestrator opens cycle N+1 with a new `remediation/<new-ts>/remediation-inputs.md` and runs the full chain again. When the remaining blocking findings are all non-remediable, the orchestrator does not open the next cycle: it halts on `HALT_NON_REMEDIABLE` or waits on `AWAITING_CI`.
|
|
126
130
|
|
|
127
131
|
## Context Package (When Required)
|
|
128
132
|
|