@danmoisan/drm-copilot-mcp 1.0.0 → 1.0.7
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 +814 -194
- package/package.json +1 -1
- package/resources/claude-customizations/.claude/agents/commit-message.md +42 -0
- package/resources/claude-customizations/.claude/agents/epic-orchestrator.md +127 -0
- package/resources/claude-customizations/.claude/agents/human-exception-runbook.md +48 -0
- package/resources/claude-customizations/.claude/agents/orchestrator.md +67 -2
- package/resources/claude-customizations/.claude/agents/pr-author.md +37 -21
- package/resources/claude-customizations/.claude/hooks/check-powershell-test-purity.ps1 +103 -65
- package/resources/claude-customizations/.claude/hooks/check-python-test-purity.ps1 +12 -9
- package/resources/claude-customizations/.claude/hooks/enforce-checkpoint-monotonic.ps1 +24 -16
- package/resources/claude-customizations/.claude/hooks/enforce-completion-consistency.ps1 +19 -13
- package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate.ps1 +304 -0
- package/resources/claude-customizations/.claude/hooks/enforce-epic-wave-barrier.ps1 +304 -0
- package/resources/claude-customizations/.claude/hooks/enforce-epic-worktree-removal-gate.ps1 +237 -0
- package/resources/claude-customizations/.claude/hooks/enforce-evidence-locations.ps1 +16 -12
- package/resources/claude-customizations/.claude/hooks/enforce-feature-folder-order.ps1 +14 -10
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate.ps1 +35 -8
- package/resources/claude-customizations/.claude/hooks/enforce-powershell-batch-budget.ps1 +17 -14
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.epic-base-branch.ps1 +104 -0
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.ps1 +268 -93
- package/resources/claude-customizations/.claude/hooks/enforce-prd-feature-before-planner.ps1 +19 -11
- package/resources/claude-customizations/.claude/hooks/enforce-promotion-mcp-only.ps1 +28 -6
- package/resources/claude-customizations/.claude/hooks/enforce-python-batch-budget.ps1 +17 -14
- package/resources/claude-customizations/.claude/hooks/validate-bash.ps1 +146 -36
- package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output.ps1 +19 -7
- package/resources/claude-customizations/.claude/rules/orchestrator-state.md +36 -0
- package/resources/claude-customizations/.claude/settings.json +34 -1
- package/resources/claude-customizations/.claude/skills/epic-orchestrate/SKILL.md +252 -0
- package/resources/claude-customizations/.claude/skills/orchestrate/SKILL.md +42 -13
- package/resources/claude-customizations/.claude/skills/pr-author/SKILL.md +28 -0
- package/resources/claude-customizations/.claude/skills/remediation-handoff-atomic-planner/SKILL.md +22 -18
- package/resources/claude-customizations/pack-manifests/core.json +8 -0
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrate/SKILL.md +6 -3
- package/resources/codex-and-agents-customizations/.agents/skills/remediation-handoff-atomic-planner/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents-variants/csharp-legacy/skills/csharp/SKILL.md +65 -0
- package/resources/codex-and-agents-customizations/.agents-variants/csharp-legacy/skills/csharp-qa-gate/SKILL.md +79 -0
- package/resources/codex-and-agents-customizations/.agents-variants/csharp-legacy/skills/invoke-csharp-engineer/SKILL.md +66 -0
- package/resources/codex-and-agents-customizations/.codex/config.toml +1 -25
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-pr-author-skill.ps1 +257 -93
- package/resources/codex-and-agents-customizations/.codex-variants/csharp-legacy/agents/csharp-typed-engineer.toml +98 -0
- package/resources/codex-and-agents-customizations/pack-manifests/core.json +24 -0
- package/resources/codex-and-agents-customizations/pack-manifests/csharp-legacy.json +11 -0
- package/resources/codex-and-agents-customizations/pack-manifests/csharp-modern.json +10 -0
- package/resources/codex-and-agents-customizations/pack-manifests/powershell.json +15 -0
- package/resources/codex-and-agents-customizations/pack-manifests/python.json +15 -0
- package/resources/codex-and-agents-customizations/pack-manifests/typescript.json +9 -0
- package/resources/config/orchestration-routing.json +92 -0
- package/resources/customizations/.github/agents/pr-author.agent.md +24 -18
- package/resources/icon.png +0 -0
- package/resources/powershell/PoshQC/settings/pester.runsettings.psd1 +11 -0
- package/resources/codex-and-agents-customizations/.github/workflows/_validate-orchestrator-state.yml +0 -68
- package/resources/codex-and-agents-customizations/.github/workflows/validate-orchestrator-state.yml +0 -15
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: epic-orchestrate
|
|
3
|
+
description: Route a multi-feature epic through the deterministic wave-scheduling, integration-branch, and fan-in workflow for the epic-orchestrator agent.
|
|
4
|
+
argument-hint: "[epic-manifest-path]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Epic Orchestrate Skill
|
|
8
|
+
|
|
9
|
+
This skill frames work for the `epic-orchestrator` agent, parallel to how
|
|
10
|
+
`.claude/skills/orchestrate/SKILL.md` frames work for `orchestrator`. It documents the epic
|
|
11
|
+
checkpoint handling, wave computation, integration-branch lifecycle, wave barrier,
|
|
12
|
+
merge-conflict handling, worktree cleanup, and documentation-maintenance procedures so the
|
|
13
|
+
procedure is not re-derived ad hoc on each epic run.
|
|
14
|
+
|
|
15
|
+
## Prerequisites
|
|
16
|
+
|
|
17
|
+
Before proceeding, `epic-orchestrator` must:
|
|
18
|
+
|
|
19
|
+
1. Read `CLAUDE.md` for repository tone policy and architectural context.
|
|
20
|
+
2. Read applicable `.claude/rules/` files for the languages in scope.
|
|
21
|
+
3. Read the policy files listed in the compliance reading order section of `CLAUDE.md`.
|
|
22
|
+
|
|
23
|
+
## Epic Dependency Manifest
|
|
24
|
+
|
|
25
|
+
The epic manifest is Markdown with YAML frontmatter, at
|
|
26
|
+
`docs/features/epics/<epic-slug>/epic-plan.md`. The frontmatter carries the fields that must be
|
|
27
|
+
parsed deterministically; the Markdown body below the frontmatter carries free-text epic
|
|
28
|
+
narrative (goal, scope, non-goals) that is not machine-parsed.
|
|
29
|
+
|
|
30
|
+
Frontmatter schema:
|
|
31
|
+
|
|
32
|
+
```yaml
|
|
33
|
+
---
|
|
34
|
+
epic: <epic-slug>
|
|
35
|
+
integration_branch: epic/<epic-slug>-integration
|
|
36
|
+
created_at: <iso8601>
|
|
37
|
+
features:
|
|
38
|
+
- feature_folder: <feature-folder-basename>
|
|
39
|
+
issue_num: <int>
|
|
40
|
+
depends_on: [<feature-folder-basename>, ...]
|
|
41
|
+
---
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
- `feature_folder` is the canonical identifier: the exact active-feature-folder basename,
|
|
45
|
+
matching the vocabulary already used by the per-feature checkpoint's `feature-folder` field.
|
|
46
|
+
- `depends_on` is an array of `feature_folder` values that must each already exist as another
|
|
47
|
+
entry in `features[]`. A `depends_on` entry that does not resolve to a defined `feature_folder`,
|
|
48
|
+
or a duplicate `feature_folder` value, is a malformed manifest and is rejected before epic
|
|
49
|
+
kickoff as a synthetic Blocking finding — `epic-orchestrator` does not guess.
|
|
50
|
+
|
|
51
|
+
## Wave Assignment
|
|
52
|
+
|
|
53
|
+
Wave assignment is computed deterministically by longest-path layering over the dependency DAG,
|
|
54
|
+
not by an arbitrary valid topological order:
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
wave(f) = 0 if depends_on(f) is empty
|
|
58
|
+
wave(f) = 1 + max(wave(d) for d in depends_on(f)) otherwise
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`scripts/dev_tools/epic_wave_computation.py` is the canonical, tested reference implementation
|
|
62
|
+
of this formula.
|
|
63
|
+
|
|
64
|
+
Compute this via memoized recursion with cycle detection: a `feature_folder` encountered while
|
|
65
|
+
still being resolved (i.e., it appears in its own dependency chain) indicates a cycle in the
|
|
66
|
+
manifest, which is rejected as a malformed manifest before kickoff. Within a wave, feature
|
|
67
|
+
ordering for emission into checkpoint arrays is lexicographic by `feature_folder`, purely for
|
|
68
|
+
deterministic serialization; wave *membership* itself has no ties to break since it is a pure
|
|
69
|
+
function of the DAG.
|
|
70
|
+
|
|
71
|
+
## Epic Integration Branch Lifecycle
|
|
72
|
+
|
|
73
|
+
1. Before wave 0's launch, `epic-orchestrator` creates the integration branch off the tip of
|
|
74
|
+
`main`: `git fetch origin main`, `git checkout -b epic/<epic-slug>-integration origin/main`,
|
|
75
|
+
`git push -u origin epic/<epic-slug>-integration`.
|
|
76
|
+
2. Before starting each wave, `epic-orchestrator` runs
|
|
77
|
+
`git fetch origin epic/<epic-slug>-integration` so the wave's child worktrees branch off the
|
|
78
|
+
current remote tip, not a stale local ref.
|
|
79
|
+
3. Each child feature's worktree/branch (created via
|
|
80
|
+
`Agent(orchestrator, isolation: "worktree", run_in_background: true)`) is branched from
|
|
81
|
+
`origin/<integration_branch>`, not `origin/main`. The child's own `orchestrator` instance
|
|
82
|
+
honors this via the epic-mode kickoff line below.
|
|
83
|
+
4. Each child feature's PR base branch is the integration branch, not `main` — an explicit
|
|
84
|
+
epic-mode override recorded in the checkpoint, not a reliance on `pr-base-branch-merge-base`'s
|
|
85
|
+
ancestry heuristic. Non-epic (standalone) orchestration is unchanged.
|
|
86
|
+
5. At epic completion (every feature in the final wave has `merge_status: "merged"`),
|
|
87
|
+
`epic-orchestrator` drives a final PR merging `epic/<epic-slug>-integration` into `main`,
|
|
88
|
+
delegating PR authoring to `Agent(pr-author)` and refreshing context via
|
|
89
|
+
`mcp__drm-copilot__collect_pr_context`. `epic-orchestrator` runs the same S9 CI-green
|
|
90
|
+
procedure (`scripts/orchestration/Invoke-CiGateParser.ps1`) directly against this PR, records
|
|
91
|
+
the result under the epic checkpoint's `epic_merge_pr` object, then executes
|
|
92
|
+
`gh pr merge --merge` once green, gated by `enforce-epic-merge-gate.ps1`.
|
|
93
|
+
|
|
94
|
+
## Merge-on-Green Kickoff Parameter
|
|
95
|
+
|
|
96
|
+
When `epic-orchestrator` delegates a child feature to `Agent(orchestrator)`, the prompt includes
|
|
97
|
+
the literal epic-mode kickoff line:
|
|
98
|
+
|
|
99
|
+
> `Epic mode: true. epic_feature_folder: <epic-slug>. integration_branch: epic/<epic-slug>-integration. epic_checkpoint_path: artifacts/orchestration/epic-orchestrator-state.json. PR base branch MUST be <integration_branch>, not main; pass --base <integration_branch> to gh pr create.`
|
|
100
|
+
|
|
101
|
+
The child's own `orchestrator`, on reading this line, records `epic_mode: true` and
|
|
102
|
+
`epic_context: { epic_feature_folder, integration_branch, epic_checkpoint_path }` at its first
|
|
103
|
+
checkpoint write, and on CI-green (S9 step 6) merges its own PR into the integration branch,
|
|
104
|
+
recording `epic_merge: { merge_commit_sha, target_branch, merged_at }`. Standalone (non-epic)
|
|
105
|
+
orchestration is unchanged: `epic_mode` absent or `false` makes S9 step 6 a no-op.
|
|
106
|
+
|
|
107
|
+
## Model Selection
|
|
108
|
+
|
|
109
|
+
When `epic-orchestrator` delegates a child feature to `Agent(orchestrator)`, the prompt appends the
|
|
110
|
+
session model-budget kickoff marker line, following the existing kickoff-marker pattern:
|
|
111
|
+
|
|
112
|
+
> `model_budget.fable_policy: <disabled|available|preferred>.`
|
|
113
|
+
|
|
114
|
+
The child's own `orchestrator` reads this line and applies the two-axis model-selection mechanism
|
|
115
|
+
documented in `.claude/skills/orchestrate/SKILL.md` (`## Model Selection`): it assesses a
|
|
116
|
+
judgment-based `complexity_band`, records `complexity_assessments[]` and `model_routing_receipts[]`,
|
|
117
|
+
and resolves each delegation's model tier under the given `fable_policy`. The two canonical, tested
|
|
118
|
+
reference implementations are `scripts/dev_tools/compute_complexity_floor.py`
|
|
119
|
+
(`compute_complexity_floor`) and `scripts/dev_tools/resolve_delegation_model.py`
|
|
120
|
+
(`resolve_delegation_model`). Default `fable_policy` is `disabled` when the marker is absent.
|
|
121
|
+
|
|
122
|
+
`route` is never an input to model selection; `route` remains file-count driven and governs only
|
|
123
|
+
agents, skills, and MCP tools. A skill whose frontmatter `context` field holds the value `fork`
|
|
124
|
+
inherits the parent model and ignores a model override, so model selection applies to agent
|
|
125
|
+
delegations, not to fork-routed skill invocations.
|
|
126
|
+
|
|
127
|
+
## Context Handoff to Dependent Features
|
|
128
|
+
|
|
129
|
+
When `epic-orchestrator` kicks off a feature with a non-empty `depends_on`, the delegation prompt
|
|
130
|
+
includes one literal citation line per dependency, appended after the epic-mode kickoff line
|
|
131
|
+
above:
|
|
132
|
+
|
|
133
|
+
> `Upstream context for <feature_folder>: depends on <dep_feature_folder> (spec: docs/features/active/<dep_feature_folder>/spec.md — or docs/features/completed/<dep_feature_folder>/spec.md if already promoted to completed; plan: docs/features/active/<dep_feature_folder>/plan.<ts>.md; merged as PR #<dep_pr_number>, commit <dep_merge_commit_sha>, into <integration_branch>).`
|
|
134
|
+
|
|
135
|
+
`epic-orchestrator` resolves the concrete `<dep_...>` values from its own checkpoint's
|
|
136
|
+
`features[]` records for each dependency before emitting the line, so the dependent feature's own
|
|
137
|
+
`orchestrator`/`atomic-planner` is told exactly which upstream artifacts are relevant rather than
|
|
138
|
+
being expected to rediscover prior design decisions from the diff alone.
|
|
139
|
+
|
|
140
|
+
## Merge-Conflict Handling (Fan-In)
|
|
141
|
+
|
|
142
|
+
The merge-conflict remediation loop runs inside the child feature's own `orchestrator` instance
|
|
143
|
+
(the same one that executes S9 step 6), reusing the existing R1–R5 loop
|
|
144
|
+
(`.claude/skills/orchestrate/SKILL.md` "Remediation Loop (R1–R5)") unmodified — no new loop is
|
|
145
|
+
owned by `epic-orchestrator`.
|
|
146
|
+
|
|
147
|
+
Procedure, triggered by S9 step 6's merge failure:
|
|
148
|
+
|
|
149
|
+
1. The child's `atomic-executor` runs `git fetch origin <integration_branch>`,
|
|
150
|
+
`git merge --no-commit origin/<integration_branch>`, and on non-zero exit captures
|
|
151
|
+
`git diff --name-only --diff-filter=U` (the conflicted file list) plus the raw conflict-marker
|
|
152
|
+
(`<<<<<<<`/`=======`/`>>>>>>>`) content of each conflicted file.
|
|
153
|
+
2. This is written as `remediation-inputs.<timestamp>.md` in the **child feature's own active
|
|
154
|
+
folder** (not the epic folder), severity `Blocking`, naming the conflicting branches, carrying
|
|
155
|
+
the conflicted-file list and marker excerpts — the same shape the existing CI-failure handling
|
|
156
|
+
already uses, substituting the conflict-detection output for `gh run view --log-failed`.
|
|
157
|
+
3. The existing R1–R5 loop processes this finding exactly as a local blocking finding:
|
|
158
|
+
`atomic-planner` (R1) plans the resolution, `atomic-executor` performs preflight (R2) then
|
|
159
|
+
resolves the conflict markers, stages, and commits (R3), `feature-review` re-audits (R4).
|
|
160
|
+
4. The child's own `remediation_pass` counter is shared with local-finding and CI-failure passes
|
|
161
|
+
(cap 3), unmodified.
|
|
162
|
+
5. On the third conflict pass without resolution, the child's `orchestrator` records
|
|
163
|
+
`step9_status: "blocked_conflict_loop_limit"` (parallel to `blocked_ci_loop_limit`), does not
|
|
164
|
+
write DONE, and halts. It reports this status to `epic-orchestrator`, which mirrors it into
|
|
165
|
+
the epic checkpoint's per-feature `merge_status: "blocked_conflict_loop_limit"` field.
|
|
166
|
+
|
|
167
|
+
## Wave Barrier (Two-Layer Design)
|
|
168
|
+
|
|
169
|
+
Wave-barrier enforcement is a two-layer design: no single hook mechanism can validate a whole
|
|
170
|
+
batch of concurrent `Agent` calls, since `PreToolUse` hooks fire per call with no
|
|
171
|
+
cross-call/conversation-state visibility.
|
|
172
|
+
|
|
173
|
+
- **Layer 1 — per-call deterrent:** `.claude/hooks/enforce-epic-wave-barrier.ps1`, a `PreToolUse`
|
|
174
|
+
hook on the `Agent` matcher. It fires when `subagent_type == "orchestrator"` and the serialized
|
|
175
|
+
prompt contains the marker `Epic mode: true`, resolves the target `feature_folder` from the
|
|
176
|
+
prompt text, reads `artifacts/orchestration/epic-orchestrator-state.json`, looks up that
|
|
177
|
+
feature's `depends_on`, and denies with reason `EPIC_WAVE_BARRIER_BLOCKED` unless every
|
|
178
|
+
dependency's `merge_status` is `merged` or `worktree_removed`.
|
|
179
|
+
- **Layer 2 — retrospective backstop:** the wave-barrier ordering invariant inside
|
|
180
|
+
`validate_epic_orchestrator_state_text`, enforced at `epic-orchestrator` `SubagentStop` time via
|
|
181
|
+
the parameterized `validate-orchestrator-output.ps1` hook. It appends
|
|
182
|
+
`EPIC_WAVE_BARRIER_VIOLATION: <f> started before dependency <d> merged` when a dependency edge's
|
|
183
|
+
timing invariant is violated.
|
|
184
|
+
|
|
185
|
+
Both layers are required; neither alone closes the gap. `epic-orchestrator` does not launch wave
|
|
186
|
+
N+1 until every wave-N feature's dependency edges are durably confirmed merged, verified against
|
|
187
|
+
`git worktree list --porcelain`, `git branch`, and `gh pr view --json state,mergedAt,headRefOid`
|
|
188
|
+
on resume, not from in-memory completion notifications alone.
|
|
189
|
+
|
|
190
|
+
## Worktree Cleanup
|
|
191
|
+
|
|
192
|
+
After a child feature's `epic_merge.merge_commit_sha` is recorded (S9 step 6 succeeds) and
|
|
193
|
+
`epic-orchestrator` mirrors that into its own checkpoint's `merge_status: "merged"` and
|
|
194
|
+
`merge_confirmed_at`, `epic-orchestrator` (running from the main repository checkout, not any
|
|
195
|
+
child worktree) issues `git worktree remove <worktree_path>`, gated by
|
|
196
|
+
`.claude/hooks/enforce-epic-worktree-removal-gate.ps1`, which denies with reason
|
|
197
|
+
`EPIC_WORKTREE_REMOVAL_BLOCKED` unless the epic checkpoint's matching `features[]` record has
|
|
198
|
+
`merge_status` in `{merged, worktree_removed}`. On success, `epic-orchestrator` sets
|
|
199
|
+
`merge_status: "worktree_removed"` and `worktree_removed_at`.
|
|
200
|
+
|
|
201
|
+
## Documentation Maintenance Boundaries
|
|
202
|
+
|
|
203
|
+
`epic-plan.md` (the manifest) and `epic-status.md` (a separate, epic-orchestrator-maintained
|
|
204
|
+
status document) are kept distinct. `epic-plan.md`'s frontmatter is the human-authored, largely
|
|
205
|
+
static input; automatic epic decomposition is out of scope, so this file is not repeatedly
|
|
206
|
+
rewritten. `epic-orchestrator` instead maintains
|
|
207
|
+
`docs/features/epics/<epic-slug>/epic-status.md`, regenerated (not hand-edited) from the epic
|
|
208
|
+
checkpoint at each of the following boundaries, not only at final completion:
|
|
209
|
+
|
|
210
|
+
- Epic kickoff — initial status table seeded from the manifest (one row per feature: wave,
|
|
211
|
+
status `not_started`).
|
|
212
|
+
- Each time a feature's `merge_status` changes (`worktree_created`, `pr_open`, `ci_green`,
|
|
213
|
+
`merge_conflict`, `merged`, `worktree_removed`) — the corresponding row is updated in place.
|
|
214
|
+
- Each wave transition (`current_wave` increments).
|
|
215
|
+
- Final integration PR opened, green, and merged.
|
|
216
|
+
|
|
217
|
+
Each row records: `feature_folder`, `issue_num`, `wave_number`, `merge_status`, PR link
|
|
218
|
+
(`pr_url`), `merge_commit_sha`, and the four lifecycle timestamps from the epic checkpoint.
|
|
219
|
+
`epic-status.md` is a human-readable projection of the epic checkpoint's `features[]` array; the
|
|
220
|
+
checkpoint JSON remains the durable, machine-authoritative source.
|
|
221
|
+
|
|
222
|
+
## Epic-Level Checkpoint
|
|
223
|
+
|
|
224
|
+
`artifacts/orchestration/epic-orchestrator-state.json` carries `objective`, `route_id: "epic"`,
|
|
225
|
+
`epic_feature_folder`, `epic_manifest_path`, `epic_status_doc_path`, `integration_branch`,
|
|
226
|
+
`completed_steps`, `next_step`, `last_updated`, `current_wave`, `waves[]`, `features[]`,
|
|
227
|
+
`epic_merge_pr`, and the three receipt arrays (`delegation_receipts[]`, `skill_receipts[]`,
|
|
228
|
+
`mcp_call_receipts[]`) — the full schema is defined in `spec.md` §6 of this feature. The
|
|
229
|
+
`merge_status` enum is: `not_started`, `worktree_created`, `pr_open`, `ci_green`,
|
|
230
|
+
`merge_conflict`, `blocked_conflict_loop_limit`, `merged`, `worktree_removed`.
|
|
231
|
+
|
|
232
|
+
Every field needed to re-derive state durably on resume (`worktree_path`, `branch_name`,
|
|
233
|
+
`pr_number`, `merge_status`) is re-derivable from `git worktree list --porcelain`, `git branch`,
|
|
234
|
+
and `gh pr view --json state,mergedAt,headRefOid` — the checkpoint is a cache of that durable
|
|
235
|
+
state, not the source of truth.
|
|
236
|
+
|
|
237
|
+
Validate the checkpoint via
|
|
238
|
+
`python -m scripts.dev_tools.validate_orchestration_artifacts epic-orchestrator-state <path> --require-complete`
|
|
239
|
+
(or the equivalent `mcp__drm-copilot__validate_orchestration_artifacts` call with
|
|
240
|
+
`artifact_type: "epic-orchestrator-state"`), implemented in
|
|
241
|
+
`scripts/dev_tools/validate_epic_orchestrator_state.py`.
|
|
242
|
+
|
|
243
|
+
## Completion Requirements
|
|
244
|
+
|
|
245
|
+
`epic-orchestrator` must not report completion until:
|
|
246
|
+
|
|
247
|
+
1. Every feature in the manifest has `merge_status` in `{merged, worktree_removed}`.
|
|
248
|
+
2. The final integration-to-`main` PR has merged and `epic_merge_pr.merge_commit_sha` is
|
|
249
|
+
recorded.
|
|
250
|
+
3. `docs/features/epics/<epic-slug>/epic-status.md` reflects the completed state.
|
|
251
|
+
4. The epic checkpoint passes `validate_epic_orchestrator_state_text` with
|
|
252
|
+
`require_complete=True`.
|
|
@@ -44,7 +44,7 @@ When a step cannot be performed without a human, the orchestrator chooses exactl
|
|
|
44
44
|
|
|
45
45
|
### Exception-runbook requirement
|
|
46
46
|
|
|
47
|
-
On a permitted `exception`, the orchestrator emits a human-readable runbook at `<FEATURE>/runbooks/<name>.runbook.md` and records
|
|
47
|
+
On a permitted `exception`, the orchestrator delegates runbook authoring to `Agent(human-exception-runbook)`, which emits a human-readable runbook at `<FEATURE>/runbooks/<name>.runbook.md` and returns the `runbook_path`. The orchestrator records the returned repo-root-relative path in `human_interaction.requirements[].runbook_path`. The runbook contract — canonical path, the five required sections (Cue, Prerequisites, Step-by-step Instructions, Verification, Source and Citation), and the MCP-first / web-second sourcing rule — is defined authoritatively in `.claude/skills/human-exception-runbook/SKILL.md`.
|
|
48
48
|
|
|
49
49
|
### Enforcement points
|
|
50
50
|
|
|
@@ -65,18 +65,40 @@ After reading `artifacts/orchestration/orchestrator-state.json`, the main sessio
|
|
|
65
65
|
|
|
66
66
|
The orchestrator does not perform deep implementation itself. It coordinates, tracks state, and enforces completion.
|
|
67
67
|
|
|
68
|
-
##
|
|
68
|
+
## Model Selection
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
Model selection is a second axis, strictly separate from `route`. `route` (`small | large | remediation | epic`) is deterministic and file-count driven; it governs `required_agents`, `required_skills`, and `required_mcp_tools` only. `route` is NOT an input to model selection anywhere. The sole feature-level input to the delegation model tier is a judgment-based `complexity_band` (`C1 | C2 | C3 | C4`). The authoritative values live in the `model_policy` block of `config/orchestration-routing.json`.
|
|
71
|
+
|
|
72
|
+
The two canonical, tested reference implementations express the formulas the orchestrator applies by judgment:
|
|
73
|
+
|
|
74
|
+
- `scripts/dev_tools/compute_complexity_floor.py` (`compute_complexity_floor`) — the deterministic complexity-floor formula. Each present `[floor]` signal contributes a candidate band of `C3`; the floor is the maximum triggered candidate band; the floor never exceeds `C3`. C4 is never floor-forced; it is reached only by judgment.
|
|
75
|
+
- `scripts/dev_tools/resolve_delegation_model.py` (`resolve_delegation_model`) — the delegation-model selection formula (base `complexity_to_model` table, the `preferred` overlay, and the `disabled` clamp).
|
|
76
|
+
|
|
77
|
+
End-to-end procedure:
|
|
78
|
+
|
|
79
|
+
1. **Parse the kickoff marker.** Read the session `model_budget.fable_policy` value (`disabled | available | preferred`, default `disabled`) from the kickoff marker line. This is the only session-level model-budget switch.
|
|
80
|
+
2. **Assess `complexity_band` and record it.** For each assessed phase, judge the `complexity_band` against the `model_policy.complexity` signal catalog and anchors, then record a `complexity_assessments[]` entry `{ phase, band, floor, signals_present[], rationale, assessed_at }`. The recorded `floor` must equal `compute_complexity_floor(signals_present)`, and the assessed `band` must satisfy `band >= floor`. The floor is a lower bound only; it never raises a judgment or evaluates its merit.
|
|
81
|
+
3. **Run the per-delegation selection order.** For each delegation, resolve the model as `resolve_delegation_model(agent, complexity_band, fable_policy)`: the `table_model` is the `preferred` overlay value when (`fable_policy == "preferred"` and the agent is in the overlay set `{atomic-planner, prd-feature, feature-review, task-researcher}` and `band == "C3"`), otherwise the base `complexity_to_model[band]`. Under `fable_policy == "disabled"`, a `fable` `table_model` clamps to `model = "opus"` with `clamped_from = "fable"`. `atomic-executor` and `pr-author` C3 cells stay `opus` under every policy.
|
|
82
|
+
4. **Emit a routing receipt.** Record a `model_routing_receipts[]` entry `{ agent, phase, complexity_band, fable_policy, table_model, clamped_from | null, model }`. `table_model` is the pre-clamp lookup; `model` is the post-clamp result.
|
|
83
|
+
|
|
84
|
+
The `complexity_assessments[]` and `model_routing_receipts[]` invariants are enforced by `scripts/dev_tools/validate_orchestrator_state.py` per `.claude/rules/orchestrator-state.md`; both arrays are additive and optional.
|
|
85
|
+
|
|
86
|
+
**`fork` caveat.** A skill whose frontmatter `context` field holds the value `fork` inherits the parent model and ignores a model override. Model selection therefore applies to agent delegations, not to fork-routed skill invocations.
|
|
87
|
+
|
|
88
|
+
## PR Authoring (pr-author Handoff)
|
|
89
|
+
|
|
90
|
+
PR creation and PR body edits are delegated work, not orchestrator work. The orchestrator MUST NOT call `gh pr create` or `gh pr edit --body*` directly from the main thread; the `enforce-pr-author-skill.ps1` PreToolUse hook blocks those commands unless the `--body-file` argument resolves to a canonical `artifacts/pr_body_<N>.md` path with a matching, verified `artifacts/pr_body_<N>.receipt.json`.
|
|
71
91
|
|
|
72
92
|
The mandatory sequence is:
|
|
73
93
|
|
|
74
|
-
1. The orchestrator first
|
|
75
|
-
2. The orchestrator
|
|
94
|
+
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`.
|
|
95
|
+
2. The orchestrator runs the orchestrator-state validator (`mcp__drm-copilot__validate_orchestration_artifacts` or the equivalent local CLI call) 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.
|
|
96
|
+
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.
|
|
97
|
+
4. The orchestrator records `pr_author_receipt` in the checkpoint, citing the body-file path and the receipt path that were verified.
|
|
76
98
|
|
|
77
|
-
`Agent(pr-author)` is the mandatory delegate for PR creation and PR body edits. Direct `gh pr create`/`gh pr edit --body*` from the main thread is prohibited and is blocked by the hook.
|
|
99
|
+
`Agent(pr-author)` is the mandatory delegate for PR creation and PR body edits. Direct `gh pr create`/`gh pr edit --body*` from the main thread is prohibited and is blocked by the hook. Before the five receipt checks, the `enforce-pr-author-skill.ps1` PreToolUse hook independently re-validates the orchestrator-state checkpoint against `--require-pr-creation-ready` (via an injectable `$Invoker` subprocess seam) and blocks with `ORCHESTRATOR_STATE_PREFLIGHT_FAILED` when the checkpoint is missing or invalid — this is the local, hook-level enforcement mechanism that closes the bypass path (it runs inside the same hook that already intercepts `gh pr create`/`gh pr edit`, not as a CI check). The PreToolUse hook then verifies the receipt in five ordered checks: canonical body-file path, receipt present, `number` match, `sha256` match against the body bytes, and `created_at` strictly newer than the context summary last-write.
|
|
78
100
|
|
|
79
|
-
The
|
|
101
|
+
The SHA-256 receipt is a policy-level integrity check, not a cryptographic or security boundary; any actor with `Write(/artifacts/**)` access can replace both the body file and its receipt together with a matching SHA-256. It binds the body bytes to the receipt, prevents accidental bypass, and requires a deliberate, documented act to circumvent.
|
|
80
102
|
|
|
81
103
|
## Evidence Location Authority
|
|
82
104
|
|
|
@@ -110,8 +132,8 @@ The orchestrator must not report completion until:
|
|
|
110
132
|
Before delegating to the `feature-review` subagent, the orchestrator must:
|
|
111
133
|
|
|
112
134
|
1. Stage all modified and new files: `git add -A`.
|
|
113
|
-
2.
|
|
114
|
-
3. Commit using the generated message: `git commit -m "<generated message>"`.
|
|
135
|
+
2. Delegate to `Agent(commit-message)` to generate a conventional commit message from the staged diff. The agent is read-only and returns message text only; it does not commit.
|
|
136
|
+
3. Commit using the generated message: `git commit -m "<generated message>"`. The `git add` and `git commit` actions remain on the orchestrator.
|
|
115
137
|
4. Only after a successful commit may the orchestrator proceed to the `feature-review` delegation.
|
|
116
138
|
|
|
117
139
|
The review subagent compares against a base branch; uncommitted changes are invisible to the diff tool and cannot be audited.
|
|
@@ -131,7 +153,7 @@ A bounded loop consisting of five steps. The loop variable `remediation_pass` st
|
|
|
131
153
|
- **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.
|
|
132
154
|
- **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.
|
|
133
155
|
- **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.
|
|
134
|
-
- **Pre-R4 commit:** Stage all changes (`git add -A`),
|
|
156
|
+
- **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.
|
|
135
157
|
- **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.
|
|
136
158
|
- **R5 — Loop-exit decision:** If the re-audit produces zero blocking findings, exit the loop and advance to the PR creation gate. Otherwise, record `remediation_pass` increment in the checkpoint and return to R1.
|
|
137
159
|
|
|
@@ -158,6 +180,7 @@ S9 procedure:
|
|
|
158
180
|
3. Parse the JSON via `scripts/orchestration/Invoke-CiGateParser.ps1`, 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.
|
|
159
181
|
4. Poll with a bounded interval and a documented total timeout while `conclusion == "pending"`. When the timeout is exhausted, set `step9_status: "failed_remediation_required"` and enter the remediation-loop CI-failure handling below with a timeout log.
|
|
160
182
|
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.
|
|
183
|
+
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.
|
|
161
184
|
|
|
162
185
|
DONE is not written while `step9_status` is anything other than `passed`.
|
|
163
186
|
|
|
@@ -173,6 +196,10 @@ The orchestrator checkpoint (`artifacts/orchestration/orchestrator-state.json`)
|
|
|
173
196
|
- `verified_at` — ISO-8601 timestamp of when S9 recorded the result.
|
|
174
197
|
- a top-level `last_verified_ci_sha` — the most recent head SHA for which S9 recorded a result.
|
|
175
198
|
- a top-level `step9_status` — an enumeration with at minimum the values `pending`, `passed`, `failed_remediation_required`, and `blocked_ci_loop_limit`.
|
|
199
|
+
- a top-level `epic_merge` object (populated only in epic mode) containing:
|
|
200
|
+
- `merge_commit_sha` — the merge commit SHA produced by merging the feature branch into `epic_context.integration_branch`.
|
|
201
|
+
- `target_branch` — the integration branch the feature branch was merged into.
|
|
202
|
+
- `merged_at` — ISO-8601 timestamp of when S9 step 6 recorded the merge.
|
|
176
203
|
|
|
177
204
|
Illustrative shape:
|
|
178
205
|
|
|
@@ -207,15 +234,17 @@ When S9 records `step9_status: "failed_remediation_required"` (a failed required
|
|
|
207
234
|
|
|
208
235
|
## PR Creation Gate
|
|
209
236
|
|
|
210
|
-
The orchestrator must not create a PR, push a branch for PR purposes, or report work complete until all
|
|
237
|
+
The orchestrator must not create a PR, push a branch for PR purposes, or report work complete until all six conditions are simultaneously true:
|
|
211
238
|
|
|
212
239
|
1. `blocking_findings_resolved: true` — the most recent `feature-review` produced zero blocking findings.
|
|
213
240
|
2. The AC verification artifact (`p14-acceptance-criteria-checkoff.md` or equivalent) confirms all acceptance criteria pass.
|
|
214
241
|
3. The mandatory toolchain passed in its most recent run on the branch (no linting/type-check/test failures).
|
|
215
242
|
4. The checkpoint `next_step` is `S8_create_pr` (precondition to entering S9).
|
|
216
|
-
5.
|
|
243
|
+
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`.
|
|
244
|
+
6. `ci_gate.conclusion == "success"` AND `ci_gate.head_sha == current head SHA of the PR branch`. DONE is not written while either sub-condition is false.
|
|
245
|
+
7. `epic_mode` is `false`, OR (`epic_mode` is `true` AND the integration-branch merge (`gh pr merge --merge`) has completed and `epic_merge.merge_commit_sha` is recorded in the checkpoint).
|
|
217
246
|
|
|
218
|
-
This gate is non-negotiable. Each condition is independently verified before PR creation proceeds. Conditions 1-4 are unchanged from the prior contract;
|
|
247
|
+
This gate is non-negotiable. Each condition is independently verified before PR creation proceeds. Conditions 1-4 are unchanged from the prior contract; conditions 5-7 (receipt handoff, CI-green gate, and epic-mode merge-on-green gate) are additive.
|
|
219
248
|
|
|
220
249
|
## Step 6 Delegation — Prohibited Prompt Language
|
|
221
250
|
|
|
@@ -42,6 +42,34 @@ Use these sections in this order:
|
|
|
42
42
|
10. **Follow-ups** — known TODOs, deferred cleanup, next PRs
|
|
43
43
|
11. **GitHub Auto-close** — `- Closes #NNN` only from verified autoclose lists; do not invent issue numbers
|
|
44
44
|
|
|
45
|
+
## Output Artifact
|
|
46
|
+
|
|
47
|
+
The PR body produced by this skill is persisted as a body file plus a sibling receipt so the
|
|
48
|
+
PreToolUse hook can verify the body passed to `gh pr create --body-file` is the one this skill
|
|
49
|
+
produced:
|
|
50
|
+
|
|
51
|
+
1. Write the body text to `artifacts/pr_body_<N>.md`, where `<N>` is the target issue or PR number.
|
|
52
|
+
2. Compute the SHA-256 of the body file bytes and render it as lowercase hexadecimal.
|
|
53
|
+
3. Write the sibling receipt `artifacts/pr_body_<N>.receipt.json` with the shape:
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"skill": "pr-author",
|
|
58
|
+
"pr_body_path": "artifacts/pr_body_<N>.md",
|
|
59
|
+
"number": <N>,
|
|
60
|
+
"sha256": "<lowercase-hex SHA-256 of the body bytes>",
|
|
61
|
+
"context_summary_path": "artifacts/pr_context.summary.txt",
|
|
62
|
+
"created_at": "<ISO-8601 UTC timestamp newer than pr_context.summary.txt last-write>"
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
4. Pass the body to the pull request via `--body-file artifacts/pr_body_<N>.md`; do not use inline
|
|
67
|
+
`--body`.
|
|
68
|
+
|
|
69
|
+
The body-file and receipt write operations remain in the pr-author agent scope, which holds
|
|
70
|
+
`Write(/artifacts/**)`. This skill authors the body text; the pr-author agent performs the file
|
|
71
|
+
writes and the `gh pr create` / `gh pr edit --body-file` handoff.
|
|
72
|
+
|
|
45
73
|
## Issue/PR Reference Rules
|
|
46
74
|
|
|
47
75
|
- Only mention an issue/PR number if it appears verbatim in the provided context.
|
package/resources/claude-customizations/.claude/skills/remediation-handoff-atomic-planner/SKILL.md
CHANGED
|
@@ -21,9 +21,9 @@ Use this skill when:
|
|
|
21
21
|
|
|
22
22
|
```
|
|
23
23
|
orchestrator
|
|
24
|
-
-> writes remediation
|
|
24
|
+
-> writes remediation/<entry-ts>/remediation-inputs.md
|
|
25
25
|
-> delegates to atomic-planner
|
|
26
|
-
-> atomic-planner authors remediation
|
|
26
|
+
-> atomic-planner authors remediation/<entry-ts>/remediation-plan.md
|
|
27
27
|
(plan shape per .claude/skills/atomic-plan-contract/SKILL.md)
|
|
28
28
|
-> orchestrator hands plan to atomic-executor for preflight
|
|
29
29
|
-> atomic-executor returns one of:
|
|
@@ -34,13 +34,15 @@ orchestrator
|
|
|
34
34
|
-> atomic-executor executes the cleared plan task-by-task
|
|
35
35
|
(workers are invoked by atomic-executor only)
|
|
36
36
|
-> orchestrator delegates to feature-review
|
|
37
|
-
-> feature-review writes code-review
|
|
38
|
-
|
|
37
|
+
-> feature-review writes audit/<exit-ts>/code-review.md,
|
|
38
|
+
audit/<exit-ts>/feature-audit.md, and audit/<exit-ts>/policy-audit.md
|
|
39
39
|
-> orchestrator evaluates exit condition:
|
|
40
40
|
blocking_count == 0 -> mark exit_condition_met = true, end loop
|
|
41
|
-
blocking_count > 0 -> begin cycle N+1 with new remediation
|
|
41
|
+
blocking_count > 0 -> begin cycle N+1 with new remediation/<new-ts>/remediation-inputs.md
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
+
Every audit (including the initial, non-remediation-triggered `feature-review` pass that first discovers findings) is written under an `audit/<timestamp>/` folder. Every remediation cycle's entry artifacts are written under a `remediation/<timestamp>/` folder. This folder-per-cycle layout is the canonical pattern for multi-cycle remediation: it keeps each cycle's inputs, plan, and reaudit artifacts visually and structurally grouped, rather than relying on filename timestamp suffixes alone to disambiguate cycles sharing a feature folder.
|
|
45
|
+
|
|
44
46
|
The orchestrator must not call typed-engineer workers directly during any phase of the cycle. The orchestrator must not act on a preflight delta itself; revisions are routed to `atomic-planner`.
|
|
45
47
|
|
|
46
48
|
## Trigger Conditions
|
|
@@ -54,7 +56,7 @@ Trigger remediation when any of these are true:
|
|
|
54
56
|
|
|
55
57
|
## Required Remediation Inputs
|
|
56
58
|
|
|
57
|
-
The orchestrator authors `remediation
|
|
59
|
+
The orchestrator authors `remediation/<entry-ts>/remediation-inputs.md` with:
|
|
58
60
|
|
|
59
61
|
- Enumerated fix list with file paths, expected behavior, and verification commands.
|
|
60
62
|
- A "do not do" list (no scope creep, no policy weakening, no silent skips).
|
|
@@ -62,24 +64,26 @@ The orchestrator authors `remediation-inputs.<entry-ts>.md` with:
|
|
|
62
64
|
|
|
63
65
|
## Required Artifacts
|
|
64
66
|
|
|
65
|
-
Each remediation cycle produces exactly five artifacts under the active feature folder:
|
|
67
|
+
Each remediation cycle produces exactly five artifacts under the active feature folder, grouped into one `remediation/<entry-ts>/` folder and one `audit/<exit-ts>/` folder:
|
|
68
|
+
|
|
69
|
+
1. `docs/features/active/<slug>/remediation/<entry-ts>/remediation-inputs.md` — orchestrator authors at cycle entry.
|
|
70
|
+
2. `docs/features/active/<slug>/remediation/<entry-ts>/remediation-plan.md` — `atomic-planner` authors at cycle entry.
|
|
71
|
+
3. `docs/features/active/<slug>/audit/<exit-ts>/code-review.md` — `feature-review` authors at cycle exit.
|
|
72
|
+
4. `docs/features/active/<slug>/audit/<exit-ts>/feature-audit.md` — `feature-review` authors at cycle exit.
|
|
73
|
+
5. `docs/features/active/<slug>/audit/<exit-ts>/policy-audit.md` — `feature-review` authors at cycle exit.
|
|
66
74
|
|
|
67
|
-
1
|
|
68
|
-
2. `docs/features/active/<slug>/remediation-plan.<entry-ts>.md` — `atomic-planner` authors at cycle entry.
|
|
69
|
-
3. `docs/features/active/<slug>/code-review.<exit-ts>.md` — `feature-review` authors at cycle exit.
|
|
70
|
-
4. `docs/features/active/<slug>/feature-audit.<exit-ts>.md` — `feature-review` authors at cycle exit.
|
|
71
|
-
5. `docs/features/active/<slug>/policy-audit.<exit-ts>.md` — `feature-review` authors at cycle exit.
|
|
75
|
+
The initial, non-remediation-triggered `feature-review` pass (the audit that first discovers findings and opens cycle 1) also writes its three artifacts under `docs/features/active/<slug>/audit/<its-own-timestamp>/`, for the same reason: one timestamped folder per audit event, regardless of whether that audit opens, closes, or does not trigger a remediation cycle.
|
|
72
76
|
|
|
73
77
|
Timestamp rule:
|
|
74
78
|
|
|
75
|
-
- `<entry-ts>` is the ISO-8601 timestamp at cycle entry, in the `yyyy-MM-ddTHH-mm` format defined in `.claude/skills/evidence-and-timestamp-conventions/SKILL.md`. It
|
|
76
|
-
- `<exit-ts>` is the ISO-8601 timestamp at cycle exit (when `feature-review` runs), in the same `yyyy-MM-ddTHH-mm` format. It
|
|
79
|
+
- `<entry-ts>` is the ISO-8601 timestamp at cycle entry, in the `yyyy-MM-ddTHH-mm` format defined in `.claude/skills/evidence-and-timestamp-conventions/SKILL.md`. It names both the `remediation/<entry-ts>/` folder and, within it, `remediation-inputs.md` and `remediation-plan.md`.
|
|
80
|
+
- `<exit-ts>` is the ISO-8601 timestamp at cycle exit (when `feature-review` runs), in the same `yyyy-MM-ddTHH-mm` format. It names the `audit/<exit-ts>/` folder and, within it, all three reaudit artifacts: `code-review.md`, `feature-audit.md`, and `policy-audit.md`.
|
|
77
81
|
|
|
78
|
-
A cycle with fewer than five artifacts is malformed. A cycle that uses
|
|
82
|
+
A cycle with fewer than five artifacts is malformed. A cycle that uses the same timestamp value for both its `remediation/<ts>/` and `audit/<ts>/` folders is malformed unless entry and exit genuinely ran within the same minute — the two folders remain distinct either way, since one is named `remediation/` and the other `audit/`.
|
|
79
83
|
|
|
80
84
|
## Plan Shape
|
|
81
85
|
|
|
82
|
-
`remediation
|
|
86
|
+
`remediation/<entry-ts>/remediation-plan.md` MUST conform to `.claude/skills/atomic-plan-contract/SKILL.md`. In particular:
|
|
83
87
|
|
|
84
88
|
- Phase headings: `### Phase N — <Title>`.
|
|
85
89
|
- Tasks: `- [ ] [P#-T#]` with sequential per-phase IDs.
|
|
@@ -102,11 +106,11 @@ The orchestrator records the preflight outcome in `remediation_loop.cycles[curre
|
|
|
102
106
|
|
|
103
107
|
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.
|
|
104
108
|
|
|
105
|
-
When execution is complete, the orchestrator delegates to `feature-review`. `feature-review` produces the three reaudit artifacts under
|
|
109
|
+
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.
|
|
106
110
|
|
|
107
111
|
## Exit Gate
|
|
108
112
|
|
|
109
|
-
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
|
|
113
|
+
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.
|
|
110
114
|
|
|
111
115
|
## Context Package (When Required)
|
|
112
116
|
|
|
@@ -5,8 +5,11 @@
|
|
|
5
5
|
".claude/settings.json",
|
|
6
6
|
".claude/agents/atomic-executor.md",
|
|
7
7
|
".claude/agents/atomic-planner.md",
|
|
8
|
+
".claude/agents/commit-message.md",
|
|
9
|
+
".claude/agents/epic-orchestrator.md",
|
|
8
10
|
".claude/agents/epic-review.md",
|
|
9
11
|
".claude/agents/feature-review.md",
|
|
12
|
+
".claude/agents/human-exception-runbook.md",
|
|
10
13
|
".claude/agents/orchestrator.md",
|
|
11
14
|
".claude/agents/prd-feature.md",
|
|
12
15
|
".claude/agents/staged-review.md",
|
|
@@ -14,9 +17,13 @@
|
|
|
14
17
|
".claude/agents/task-researcher.md",
|
|
15
18
|
".claude/hooks/enforce-checkpoint-monotonic.ps1",
|
|
16
19
|
".claude/hooks/enforce-completion-consistency.ps1",
|
|
20
|
+
".claude/hooks/enforce-epic-merge-gate.ps1",
|
|
21
|
+
".claude/hooks/enforce-epic-wave-barrier.ps1",
|
|
22
|
+
".claude/hooks/enforce-epic-worktree-removal-gate.ps1",
|
|
17
23
|
".claude/hooks/enforce-evidence-locations.ps1",
|
|
18
24
|
".claude/hooks/enforce-feature-folder-order.ps1",
|
|
19
25
|
".claude/hooks/enforce-orchestration-preimplementation-gate.ps1",
|
|
26
|
+
".claude/hooks/enforce-pr-author-skill.epic-base-branch.ps1",
|
|
20
27
|
".claude/hooks/enforce-pr-author-skill.ps1",
|
|
21
28
|
".claude/hooks/enforce-prd-feature-before-planner.ps1",
|
|
22
29
|
".claude/hooks/enforce-promotion-mcp-only.ps1",
|
|
@@ -39,6 +46,7 @@
|
|
|
39
46
|
".claude/skills/acceptance-criteria-tracking/SKILL.md",
|
|
40
47
|
".claude/skills/atomic-plan-contract/SKILL.md",
|
|
41
48
|
".claude/skills/commit-message/SKILL.md",
|
|
49
|
+
".claude/skills/epic-orchestrate/SKILL.md",
|
|
42
50
|
".claude/skills/evidence-and-timestamp-conventions/SKILL.md",
|
|
43
51
|
".claude/skills/execute-hard-lock/SKILL.md",
|
|
44
52
|
".claude/skills/feature-promotion-lifecycle/SKILL.md",
|
|
@@ -141,9 +141,12 @@ There is no fallback. If the MCP server or validation tool is unavailable, or
|
|
|
141
141
|
if validation fails, the orchestrator must update blocked state and stop rather
|
|
142
142
|
than reporting completion.
|
|
143
143
|
|
|
144
|
-
|
|
145
|
-
checkpoint is present
|
|
146
|
-
that
|
|
144
|
+
No CI workflow performs this validation. The `artifacts/` directory is gitignored,
|
|
145
|
+
so the orchestrator-state checkpoint is never present in a CI checkout; a prior
|
|
146
|
+
CI gate (`validate-orchestrator-state.yml`) that attempted this check was a
|
|
147
|
+
structural no-op for that reason and has been removed. The MCP-server-based
|
|
148
|
+
validation described above is this ecosystem's enforcement mechanism for the
|
|
149
|
+
orchestrator-state checkpoint.
|
|
147
150
|
|
|
148
151
|
Completion validation requires the checkpoint to prove mandatory handoffs and
|
|
149
152
|
skill use. The checkpoint must include:
|
|
@@ -22,7 +22,7 @@ Trigger remediation when any of these are true:
|
|
|
22
22
|
|
|
23
23
|
## Required Remediation Inputs
|
|
24
24
|
|
|
25
|
-
Create `remediation-inputs
|
|
25
|
+
Create `remediation/<timestamp>/remediation-inputs.md` (one timestamped `remediation/` folder per cycle; reaudit artifacts from a triggering or exit review live under the sibling `audit/<timestamp>/` folder, per the canonical pattern documented in the Claude-side `remediation-handoff-atomic-planner` skill) with:
|
|
26
26
|
- Enumerated fix list with file paths, expected behavior, and verification commands.
|
|
27
27
|
- A “do not do” list (no scope creep, no policy weakening, no silent skips).
|
|
28
28
|
|