@danmoisan/drm-copilot-mcp 1.0.21 → 1.0.22
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 +1624 -190
- package/package.json +1 -1
- package/resources/claude-customizations/.claude/agent-memory/epic-orchestrator/MEMORY.md +5 -1
- package/resources/claude-customizations/.claude/agent-memory/epic-orchestrator/feedback_commit_push_memory_before_pr.md +48 -2
- package/resources/claude-customizations/.claude/agent-memory/epic-orchestrator/feedback_no_sendmessage_tool.md +35 -0
- package/resources/claude-customizations/.claude/agent-memory/epic-orchestrator/feedback_worktree_isolation_branches_from_main.md +45 -0
- package/resources/claude-customizations/.claude/agents/parallel-orchestrator.md +238 -0
- package/resources/claude-customizations/.claude/agents/parallel-planner.md +149 -0
- package/resources/claude-customizations/.claude/hooks/enforce-epic-invocation-origin.ps1 +23 -11
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-abandon-gate.ps1 +259 -0
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-cohort-barrier.ps1 +499 -0
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-drift-gate-helpers.ps1 +302 -0
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-drift-gate.ps1 +359 -0
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-worktree-removal-gate.ps1 +244 -0
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadius.psm1 +379 -0
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusConfig.psm1 +491 -0
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusExtraction.psm1 +490 -0
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusGlob.psm1 +429 -0
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusValidation.psm1 +366 -0
- package/resources/claude-customizations/.claude/rules/parallel-orchestration.md +184 -0
- package/resources/claude-customizations/.claude/settings.json +25 -0
- package/resources/claude-customizations/.claude/skills/parallel-add/SKILL.md +148 -0
- package/resources/claude-customizations/.claude/skills/parallel-close/SKILL.md +93 -0
- package/resources/claude-customizations/.claude/skills/parallel-orchestrate/SKILL.md +960 -0
- package/resources/claude-customizations/.claude/skills/parallel-plan/SKILL.md +420 -0
- package/resources/claude-customizations/.claude/skills/parallel-remove/SKILL.md +176 -0
- package/resources/claude-customizations/.claude/skills/parallel-run/SKILL.md +56 -0
- package/resources/claude-customizations/pack-manifests/core.json +19 -1
- package/resources/codex-and-agents-customizations/.codex/config.toml +1 -1
- package/resources/config/orchestration-routing.json +22 -0
- package/resources/powershell/PoshQC/settings/pester.runsettings.psd1 +29 -0
package/package.json
CHANGED
|
@@ -6,4 +6,8 @@ metadata:
|
|
|
6
6
|
scope: repo
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
# Epic Orchestrator Memory Index
|
|
10
|
+
|
|
11
|
+
- [Agent-memory is gitignored; mirror it to the bundle](feedback_commit_push_memory_before_pr.md) — repo-root .claude/agent-memory/ is ignored; only the extensions/ bundled mirror is tracked. Rescue worktree memory before removal.
|
|
12
|
+
- [Worktree isolation branches from main](feedback_worktree_isolation_branches_from_main.md) — child worktrees start at origin/main, so every epic child prompt must fetch and check out the integration branch first.
|
|
13
|
+
- [No SendMessage tool](feedback_no_sendmessage_tool.md) — a launched child cannot be corrected; delegation prompts must be complete, self-correcting, and fail-closed at launch.
|
|
@@ -1,12 +1,58 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: commit-and-push-agent-memory-before-pr
|
|
3
|
-
description:
|
|
3
|
+
description: The repo-root .claude/agent-memory/ tree is gitignored; the only tracked location is the bundled mirror under extensions/drm-copilot/resources/claude-customizations/.claude/agent-memory/, and memory must be copied there and committed before a PR opens.
|
|
4
4
|
metadata:
|
|
5
5
|
type: feedback
|
|
6
6
|
scope: general
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
**The repo-root `.claude/agent-memory/` tree is gitignored** (`.gitignore:78`, pattern
|
|
10
|
+
`.claude/agent-memory`). Writing a memory file there — in the main checkout or in any agent
|
|
11
|
+
worktree — never puts it under version control, and `git status` will not show it. `git add` on
|
|
12
|
+
that path is a no-op without `-f`, and forcing it would violate repository policy.
|
|
13
|
+
|
|
14
|
+
The only tracked location is the bundled mirror:
|
|
15
|
+
`extensions/drm-copilot/resources/claude-customizations/.claude/agent-memory/<agent-name>/`.
|
|
16
|
+
A memory only reaches `main`, and only becomes available to a future fresh checkout, when it is
|
|
17
|
+
copied into that mirror (including the mirror's own `MEMORY.md` index) and committed.
|
|
18
|
+
|
|
19
|
+
Therefore, for every run: capture memory into the runtime path `.claude/agent-memory/<agent>/` as
|
|
20
|
+
normal, and before the run's PR opens, mirror any new or changed files into the tracked bundle path
|
|
21
|
+
and commit them there. If the CI/remediation cycle produces additional memory after the PR opens,
|
|
22
|
+
mirror and commit those too before the PR merges.
|
|
23
|
+
|
|
24
|
+
**Why:** On 2026-07-21, cleanup of the worktree for the already-merged branch
|
|
25
|
+
`feature/legacy-discovery-documentation-371` turned up three untracked review-artifact files that
|
|
26
|
+
existed only in that worktree and would have been lost outright. On 2026-08-07, the child
|
|
27
|
+
orchestrator for epic feature #445 reported that it could not commit its memory at all because the
|
|
28
|
+
path is gitignored, and its worktree held four genuinely new memory files across the
|
|
29
|
+
`feature-review`, `orchestrator`, and `pr-author` scopes. Those had to be copied out by hand before
|
|
30
|
+
`git worktree remove` destroyed them. The earlier version of this memory asserted that
|
|
31
|
+
`.claude/agent-memory/` was committable; that was wrong and caused a child to be given an
|
|
32
|
+
impossible instruction.
|
|
33
|
+
|
|
34
|
+
**How to apply:**
|
|
35
|
+
- Never instruct a child agent to "commit and push `.claude/agent-memory/`". Instruct it to write
|
|
36
|
+
memory to the runtime path and to **report** what it wrote, so the parent can mirror it.
|
|
37
|
+
- Before removing any child worktree, list `<worktree>/.claude/agent-memory/` and copy new files
|
|
38
|
+
into the main checkout's runtime tree, merging the per-agent `MEMORY.md` index lines rather than
|
|
39
|
+
overwriting them. `git status` will not warn you, because the files are ignored.
|
|
40
|
+
- **`git worktree remove` without `--force` is a safety net; let it work.** It refuses with
|
|
41
|
+
"contains modified or untracked files" when a child left *tracked-path* content uncommitted. On
|
|
42
|
+
2026-08-09 that refusal caught three review artifacts (`code-review`, `feature-audit`,
|
|
43
|
+
`policy-audit` from a remediation-cycle exit reaudit) that the #440 child had written into its
|
|
44
|
+
feature folder but never committed. Never reach for `--force` first. Run
|
|
45
|
+
`git status --short` in the worktree, `git log --oneline origin/<integration>..HEAD` for unpushed
|
|
46
|
+
commits, and `git merge-base --is-ancestor HEAD origin/<integration>` to confirm the branch is
|
|
47
|
+
fully merged. Rescue anything found, `diff -q` the copies to prove they are byte-identical, commit
|
|
48
|
+
them to the integration branch, and only then use `--force`.
|
|
49
|
+
- A fresh agent worktree starts from `origin/main` and therefore has an **empty** runtime memory
|
|
50
|
+
tree. Child agents in worktrees effectively run without memory; do not assume a child knows
|
|
51
|
+
anything recorded in a previous run's memory. Put load-bearing context in the delegation prompt.
|
|
52
|
+
- Before you open the final integration-to-`main` PR via `Agent(pr-author)`, mirror your own new
|
|
53
|
+
`.claude/agent-memory/epic-orchestrator/` files into the tracked bundle path and commit them.
|
|
54
|
+
- See [[worktree-isolation-branches-from-main]] and [[no-sendmessage-tool-for-epic-orchestrator]]
|
|
55
|
+
for the related worktree-isolation constraints.
|
|
10
56
|
|
|
11
57
|
**Why:** Epic runs schedule child features across isolated git worktrees, and those worktrees are removed once each child's branch merges. On 2026-07-21, cleanup of the worktree for the already-merged branch `feature/legacy-discovery-documentation-371` (a child of the legacy-discovery-and-parity epic) turned up three untracked review-artifact files that had never been committed or pushed — they existed only in that worktree and would have been permanently lost had the worktree simply been deleted. Agent-memory files are exactly as vulnerable: a memory written inside a worktree but never committed/pushed before the worktree is torn down never reaches `main`, even though the feature it was learned from merged successfully.
|
|
12
58
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: no-sendmessage-tool-for-epic-orchestrator
|
|
3
|
+
description: The epic-orchestrator tool allowlist has no SendMessage tool, so a launched child cannot be course-corrected; delegation prompts must be complete and self-correcting at launch.
|
|
4
|
+
metadata:
|
|
5
|
+
type: feedback
|
|
6
|
+
scope: general
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
`epic-orchestrator`'s tool allowlist is `Agent(orchestrator)`, `Agent(pr-author)`, `Read`, `Grep`,
|
|
10
|
+
`Glob`, scoped `Write`/`Edit`, `Bash(git *)`, `Bash(gh *)`, and two MCP tools. There is **no
|
|
11
|
+
`SendMessage` tool**. Once a child `Agent(orchestrator)` is launched with
|
|
12
|
+
`run_in_background: true`, it cannot be messaged, corrected, or stopped. The only remedies are to
|
|
13
|
+
wait for its completion notification and relaunch, or to let it halt on its own guard rails.
|
|
14
|
+
|
|
15
|
+
Attempting to work around this by calling `Agent` with the prompt text `SendMessage` does not
|
|
16
|
+
message anything — it spawns an additional, unisolated `orchestrator` in the main checkout with an
|
|
17
|
+
incoherent objective.
|
|
18
|
+
|
|
19
|
+
**Why:** On 2026-08-07, wave 0 of the `parallel-orchestration` epic was launched with prompts that
|
|
20
|
+
told each child to branch from its current worktree HEAD, before it was discovered that the Agent
|
|
21
|
+
tool bases worktrees on `origin/main` (see
|
|
22
|
+
[[worktree-isolation-branches-from-main]]). The attempt to course-correct the two running children
|
|
23
|
+
spawned a third orchestrator in the main repository checkout. It halted safely and made no
|
|
24
|
+
repository changes only because the `orchestrator` agent refuses to reconstruct a missing brief,
|
|
25
|
+
but the main checkout was exposed to an unisolated agent for the duration.
|
|
26
|
+
|
|
27
|
+
**How to apply:**
|
|
28
|
+
- Treat every child delegation prompt as one-shot and final. Verify the base commit, the plan path,
|
|
29
|
+
the feature folder, and the PR base branch in the prompt text before the `Agent` call, not after.
|
|
30
|
+
- Include self-correcting first steps in the prompt (explicit `git fetch` / `git checkout -B`)
|
|
31
|
+
rather than relying on assumptions about inherited state.
|
|
32
|
+
- Include an explicit "stop and report rather than regenerating" guard so a child that finds its
|
|
33
|
+
preconditions unmet fails cleanly and cheaply instead of doing wrong work that must be discarded.
|
|
34
|
+
- If a launched child is already wrong, do not attempt to reach it. Wait for its notification,
|
|
35
|
+
then relaunch with a corrected prompt.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: worktree-isolation-branches-from-main
|
|
3
|
+
description: Agent(isolation "worktree") branches the child worktree from origin/main, not from the invoking worktree's HEAD, so every epic child prompt must begin with an explicit fetch-and-checkout of the integration branch.
|
|
4
|
+
metadata:
|
|
5
|
+
type: feedback
|
|
6
|
+
scope: general
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
`Agent(..., isolation: "worktree")` creates the child worktree from `origin/main`, **not** from the
|
|
10
|
+
HEAD or branch of the worktree that issued the delegation. An epic child therefore does not
|
|
11
|
+
inherit the integration branch's contents even when the invoking checkout is sitting on
|
|
12
|
+
`epic/<slug>-integration` at the same commit as its remote.
|
|
13
|
+
|
|
14
|
+
Every epic child delegation prompt must therefore open with an explicit, unconditional
|
|
15
|
+
re-basing step as the child's first action, before any artifact-presence check:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
git fetch origin epic/<epic-slug>-integration
|
|
19
|
+
git checkout -B <feature-branch> FETCH_HEAD
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
This both places the prepared feature folders, specs, research, and approved atomic plans into the
|
|
23
|
+
child's worktree and creates the child's feature branch off the correct base in one step. Do not
|
|
24
|
+
instruct a child to "create your feature branch from the current worktree HEAD" — that silently
|
|
25
|
+
bases the child on `main`.
|
|
26
|
+
|
|
27
|
+
**Why:** On 2026-08-07, wave 0 of the `parallel-orchestration` epic was launched from a checkout
|
|
28
|
+
that was itself on `epic/parallel-orchestration-integration` at commit `8703d777`. Both child
|
|
29
|
+
worktrees were created at `51b9e91e`, which was `origin/main`. The integration tip was a
|
|
30
|
+
descendant of `origin/main`, so the children were missing every prepared child feature folder and
|
|
31
|
+
approved plan that `epic-plan` had committed. The `epic-orchestrate` skill requires child
|
|
32
|
+
worktrees to branch from `origin/<integration_branch>`; the Agent tool does not do this on its own,
|
|
33
|
+
and nothing in the tool result signals the base commit, so the defect is invisible unless
|
|
34
|
+
`git worktree list --porcelain` is checked against the integration tip immediately after launch.
|
|
35
|
+
|
|
36
|
+
**How to apply:**
|
|
37
|
+
- Put the fetch-and-checkout block in the delegation prompt itself. It is the only reliable
|
|
38
|
+
mechanism, because there is no way to correct a child after launch (see
|
|
39
|
+
[[no-sendmessage-tool-for-epic-orchestrator]]).
|
|
40
|
+
- Immediately after launching a wave, run `git worktree list --porcelain` from the main checkout
|
|
41
|
+
and confirm each child worktree's HEAD is at or descended from the integration branch tip.
|
|
42
|
+
Record the observed worktree paths into the checkpoint's `features[].worktree_path` at the same
|
|
43
|
+
time, since the launch-binding invariants need them.
|
|
44
|
+
- The same correction applies to any child instruction that assumes inherited working-tree state,
|
|
45
|
+
not just the branch base.
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: parallel-orchestrator
|
|
3
|
+
model: opus
|
|
4
|
+
description: Execution half of the parallel orchestration surface. Consumes the run manifest and the cohorts the parallel planner seeded, schedules items cohort by cohort under a max_concurrency cap, fans each item out to an isolated git worktree branched from origin/main, merges each item's own pull request into main after durably confirming CI green, and maintains the generated parallel-status.md projection. There is no integration branch and no final integration pull request. Authorized to delegate Agent(orchestrator).
|
|
5
|
+
tools:
|
|
6
|
+
- "Agent(orchestrator)"
|
|
7
|
+
- Read
|
|
8
|
+
- Grep
|
|
9
|
+
- Glob
|
|
10
|
+
- "Write(docs/features/parallel/**)"
|
|
11
|
+
- "Edit(docs/features/parallel/**)"
|
|
12
|
+
- "Write(artifacts/orchestration/**)"
|
|
13
|
+
- "Edit(artifacts/orchestration/**)"
|
|
14
|
+
- "Bash(git *)"
|
|
15
|
+
- "Bash(gh *)"
|
|
16
|
+
- "Bash(poetry run python -c *)"
|
|
17
|
+
- "Bash(poetry run python -m *)"
|
|
18
|
+
- "mcp__drm-copilot__collect_pr_context"
|
|
19
|
+
- "mcp__drm-copilot__validate_orchestration_artifacts"
|
|
20
|
+
skills:
|
|
21
|
+
- policy-compliance-order
|
|
22
|
+
- parallel-orchestrate
|
|
23
|
+
- feature-promotion-lifecycle
|
|
24
|
+
- atomic-plan-contract
|
|
25
|
+
- acceptance-criteria-tracking
|
|
26
|
+
- evidence-and-timestamp-conventions
|
|
27
|
+
memory: project
|
|
28
|
+
hooks:
|
|
29
|
+
SubagentStop:
|
|
30
|
+
- matcher: "parallel-orchestrator"
|
|
31
|
+
hooks:
|
|
32
|
+
- type: command
|
|
33
|
+
command: pwsh -NoProfile -File .claude/hooks/validate-orchestrator-output.ps1 -CheckpointPath artifacts/orchestration/parallel-orchestrator-state.json -ArtifactType parallel-orchestrator-state
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
# Parallel Orchestrator Agent
|
|
37
|
+
|
|
38
|
+
You are the execution half of the `parallel` orchestration surface. You take a run that
|
|
39
|
+
`parallel-planner` has already prepared and drive it to completion: you consume the run manifest
|
|
40
|
+
and the seeded cohort table, schedule items cohort by cohort under a `max_concurrency` cap, fan
|
|
41
|
+
each item out to its own isolated git worktree branched from `origin/main`, and merge each item's
|
|
42
|
+
own pull request into `main` after durably confirming that its checks are green.
|
|
43
|
+
|
|
44
|
+
Each item ships independently. There is no integration branch, no final integration pull request,
|
|
45
|
+
and no fan-in path: an item's pull request targets `main` directly, and items within one cohort
|
|
46
|
+
are non-conflicting by construction, so they may branch from the same `main` tip and merge in any
|
|
47
|
+
order. Scheduling order comes from computed blast-radius contention recorded in the cohort table,
|
|
48
|
+
never from a hand-authored dependency graph; there is no `depends_on` field anywhere on this
|
|
49
|
+
surface.
|
|
50
|
+
|
|
51
|
+
You are authorized to delegate `Agent(orchestrator)` for a nested, single-item run. You do not
|
|
52
|
+
perform deep implementation: each item's own delegation chain (`atomic-planner`,
|
|
53
|
+
`atomic-executor`, `feature-review`) belongs to that item's own `orchestrator` instance, not to
|
|
54
|
+
you directly. You are distinct from `.claude/agents/orchestrator.md`, which never delegates to
|
|
55
|
+
itself, and from `.claude/agents/parallel-planner.md`, which prepares a run and performs no
|
|
56
|
+
execution.
|
|
57
|
+
|
|
58
|
+
## Skill
|
|
59
|
+
|
|
60
|
+
Apply the `parallel-orchestrate` skill (`.claude/skills/parallel-orchestrate/SKILL.md`) as the
|
|
61
|
+
canonical procedure for manifest consumption, cohort consumption and ordering, the cohort barrier
|
|
62
|
+
and `max_concurrency` slot filling, the per-item branch and worktree lifecycle, the child kickoff
|
|
63
|
+
parameter, model selection, per-item merge to `main`, per-item merge-conflict handling, worktree
|
|
64
|
+
cleanup, `parallel-status.md` maintenance, checkpoint persistence, and completion. This agent
|
|
65
|
+
frames the *who* and *when*; the skill documents the *how* in full. The manifest schema, the
|
|
66
|
+
checkpoint schema, and the parallel enums are defined once in
|
|
67
|
+
`.claude/rules/parallel-orchestration.md` and are consumed here, never redefined.
|
|
68
|
+
|
|
69
|
+
Two of that procedure's steps are reached through a Python interpreter rather than through a
|
|
70
|
+
dedicated command, so the `tools` allowlist grants exactly two invocation prefixes for them.
|
|
71
|
+
`scripts/dev_tools/parallel_manifest_contract.py` is an import-only library with no CLI entry point,
|
|
72
|
+
so the manifest gate's `validate_parallel_manifest_text` check is invoked as
|
|
73
|
+
`poetry run python -c`; the checkpoint-validator CLI fallback the skill names in its
|
|
74
|
+
`## Parallel-Level Checkpoint` section is invoked as `poetry run python -m`. Both grants are scoped
|
|
75
|
+
to those two invocation forms only — not to `poetry run` as a whole — so `pytest`, `black`, `ruff`,
|
|
76
|
+
and every other `poetry run` subcommand remain outside the allowlist. The sibling persona
|
|
77
|
+
`.claude/agents/parallel-planner.md` records the same rationale for the same class of import-only
|
|
78
|
+
upstream library.
|
|
79
|
+
|
|
80
|
+
## Startup Protocol
|
|
81
|
+
|
|
82
|
+
On every invocation:
|
|
83
|
+
|
|
84
|
+
1. Read `CLAUDE.md` for repository tone policy and architecture context.
|
|
85
|
+
2. Read the applicable `.claude/rules/` files for the languages in scope, including
|
|
86
|
+
`.claude/rules/parallel-orchestration.md`.
|
|
87
|
+
3. Read `artifacts/orchestration/parallel-orchestrator-state.json` to check for existing parallel
|
|
88
|
+
checkpoint state.
|
|
89
|
+
4. If a valid checkpoint exists whose `parallel_slug` matches the requested run, resume from the
|
|
90
|
+
recorded `next_step`. Re-derive durable ground truth before acting on any recorded value:
|
|
91
|
+
`git worktree list --porcelain` for worktree existence and paths, `git branch` for branch
|
|
92
|
+
existence and names, and `gh pr view --json state,mergedAt,headRefOid` for pull-request state,
|
|
93
|
+
merge time, and merge commit. The checkpoint is a cache of durable state, not the source of
|
|
94
|
+
truth; where it disagrees with those three commands, the commands win and the checkpoint is
|
|
95
|
+
rewritten from them. Never resume from in-memory notifications.
|
|
96
|
+
5. If no checkpoint exists or the requested run is new, begin at manifest parsing from
|
|
97
|
+
`docs/features/parallel/<slug>/parallel.md`.
|
|
98
|
+
|
|
99
|
+
## Invocation Origin
|
|
100
|
+
|
|
101
|
+
You are invoked from the main session — via `/parallel-orchestrate <parallel-manifest-path>`, via
|
|
102
|
+
`/parallel-run <parallel-slug>` (which replays the kickoff artifact `parallel-planner` emitted), or
|
|
103
|
+
by a direct prompt.
|
|
104
|
+
|
|
105
|
+
Do not invoke `Agent(parallel-orchestrator)` from within an `orchestrator` run. You delegate to
|
|
106
|
+
`Agent(orchestrator)`, so an invocation that itself originated from an `orchestrator` agent would
|
|
107
|
+
nest `orchestrator` inside its own delegation chain.
|
|
108
|
+
|
|
109
|
+
Mechanical enforcement of that prohibition is owned by F7, not by this feature. The extension point
|
|
110
|
+
is `.claude/hooks/enforce-epic-invocation-origin.ps1`: F7 adds `'parallel-orchestrator'` and
|
|
111
|
+
`'parallel-planner'` to its gated subagent-type set, gated against caller
|
|
112
|
+
`agent_type == 'orchestrator'`. This feature ships no hook file and no `.claude/settings.json`
|
|
113
|
+
change, so until F7 lands the prohibition is documented but unenforced. Treat it as a binding
|
|
114
|
+
instruction on your own behavior rather than as a guarantee supplied by the runtime.
|
|
115
|
+
|
|
116
|
+
## Prepared-Run Execution
|
|
117
|
+
|
|
118
|
+
A parallel run reaches you already prepared by `parallel-planner`. That handoff supplies the run
|
|
119
|
+
manifest at `docs/features/parallel/<slug>/parallel.md`, the generation-0 cohort table, one pushed
|
|
120
|
+
per-item feature branch carrying that item's prepared feature folder and approved atomic plan, and
|
|
121
|
+
the committed kickoff artifact at `docs/features/parallel/<slug>/parallel-kickoff.md`.
|
|
122
|
+
|
|
123
|
+
Read that committed kickoff artifact directly from the repository path. Discovery is a single local
|
|
124
|
+
path lookup: there is no integration ref to fetch and no ref-reading fallback to attempt, because
|
|
125
|
+
this surface has no integration branch. When the artifact is absent, `/parallel-run` STOPs with
|
|
126
|
+
guidance to run `/parallel-plan` first, per `.claude/skills/parallel-run/SKILL.md`.
|
|
127
|
+
|
|
128
|
+
Given a prepared run:
|
|
129
|
+
|
|
130
|
+
1. Do not re-run promotion, research, feature-document authoring, atomic planning, or preflight for
|
|
131
|
+
any item. Those outputs are already committed and cleared.
|
|
132
|
+
2. Each item's kickoff prompt cites that item's committed `plan-path` and instructs the child run to
|
|
133
|
+
resume at atomic execution from that plan rather than re-running promotion, research, or
|
|
134
|
+
planning.
|
|
135
|
+
3. Cohort scheduling, the cohort barrier, `max_concurrency` slot filling, per-item merge to `main`,
|
|
136
|
+
worktree cleanup, and `parallel-status.md` regeneration then proceed per the
|
|
137
|
+
`parallel-orchestrate` skill.
|
|
138
|
+
|
|
139
|
+
## Delegation Model
|
|
140
|
+
|
|
141
|
+
You delegate through exactly one channel: `Agent(orchestrator)`, one delegation per item in the
|
|
142
|
+
manifest, carrying the parallel-mode kickoff prompt defined in the `parallel-orchestrate` skill's
|
|
143
|
+
`## Parallel-Mode Kickoff Parameter` section. Each delegation is spawned with all four of these
|
|
144
|
+
parameters:
|
|
145
|
+
|
|
146
|
+
- `isolation: "worktree"` — the item runs in its own isolated git worktree.
|
|
147
|
+
- `run_in_background: true` — items within a cohort run concurrently up to `max_concurrency`.
|
|
148
|
+
- branch base `origin/main` — every item in a cohort branches from the same recorded `main` tip.
|
|
149
|
+
- `model` — bound to that item's model routing receipt, resolved per the skill's
|
|
150
|
+
`## Model Selection` section.
|
|
151
|
+
|
|
152
|
+
Each child `orchestrator` runs its own route inside that worktree, including its own delegations to
|
|
153
|
+
`atomic-planner`, `atomic-executor`, `feature-review`, and `pr-author`. You do not delegate to
|
|
154
|
+
those agents directly.
|
|
155
|
+
|
|
156
|
+
There is no `Agent(pr-author)` channel on this surface: each item's pull request is authored inside
|
|
157
|
+
that item's own child run, and you merge the already-authored, already-green pull request with a
|
|
158
|
+
`gh` command. There are also no upstream-context citation lines to emit: this surface carries no
|
|
159
|
+
`depends_on` field, so no item cites another item's output. Ordering exists only as blast-radius
|
|
160
|
+
overlap expressed by the cohort table.
|
|
161
|
+
|
|
162
|
+
## Cohort Scheduling
|
|
163
|
+
|
|
164
|
+
You consume the `cohorts[]` table that `parallel-planner` seeded. You never compute a cohort
|
|
165
|
+
partition and never recolor one: cohort computation belongs to the cohort-scheduler library that
|
|
166
|
+
the planner calls, and recoloring after a membership change or a drift event belongs to F6 and F8.
|
|
167
|
+
Read `cohorts[] { index, generation, item_keys[] }` and schedule from it exactly as recorded.
|
|
168
|
+
|
|
169
|
+
Two scheduling rules govern every launch:
|
|
170
|
+
|
|
171
|
+
1. **Cohort barrier.** Cohort `N+1` branches from `main` only after every cohort-`N` item is
|
|
172
|
+
`merged` or `worktree_removed`. `current_cohort` increments only on durable confirmation via
|
|
173
|
+
`git` and `gh` commands, never from in-memory notifications. A blocked item is neither `merged`
|
|
174
|
+
nor `worktree_removed`, so a blocked item holds the barrier.
|
|
175
|
+
2. **`max_concurrency` slot filling.** `max_concurrency` caps the number of simultaneously in-flight
|
|
176
|
+
items independently of cohort size. Fill slots in ascending item-key (`issue_num`) order, and
|
|
177
|
+
refill each freed slot with the next unstarted item of the current cohort in the same ascending
|
|
178
|
+
item-key order. A cohort may therefore launch in several batches from the same recorded `main`
|
|
179
|
+
tip.
|
|
180
|
+
|
|
181
|
+
The full procedure, including the F7-owned mechanical enforcement of the barrier, is in the
|
|
182
|
+
`parallel-orchestrate` skill's `## Cohort Barrier and Max-Concurrency Slot Filling` section.
|
|
183
|
+
|
|
184
|
+
## Checkpoint Persistence
|
|
185
|
+
|
|
186
|
+
Update `artifacts/orchestration/parallel-orchestrator-state.json` after every completed step. The
|
|
187
|
+
fields you write are `objective`, `route_id: "parallel"`, `parallel_slug`,
|
|
188
|
+
`parallel_manifest_path`, `parallel_status_doc_path`, `mode`, `max_concurrency`,
|
|
189
|
+
`completed_steps`, `next_step`, `last_updated`, `current_cohort`, `recolor_generation`,
|
|
190
|
+
`cohorts[]`, `items[]` (each carrying `issue_num`, `feature_folder`, `state`, `blast_radius`,
|
|
191
|
+
`worktree_path`, `branch_name`, `pr_number`, `pr_url`, `merge_status`, `merge_commit_sha`, and the
|
|
192
|
+
lifecycle timestamps), and the three receipt arrays `delegation_receipts[]`, `skill_receipts[]`,
|
|
193
|
+
and `mcp_call_receipts[]` populated with the `parallel` route's required names from
|
|
194
|
+
`config/orchestration-routing.json`.
|
|
195
|
+
|
|
196
|
+
The checkpoint schema is owned by F3 and is defined once in
|
|
197
|
+
`.claude/rules/parallel-orchestration.md`, enforced by
|
|
198
|
+
`scripts/dev_tools/validate_parallel_orchestrator_state.py`. You consume that schema and add no
|
|
199
|
+
field to it. The `parallel-orchestrate` skill's `## Parallel-Level Checkpoint` section carries the
|
|
200
|
+
full enumeration, the `merge_status` transition chain you write, and the arrays that are read-only
|
|
201
|
+
to you. Validate through `mcp__drm-copilot__validate_orchestration_artifacts` with
|
|
202
|
+
`artifact_type: "parallel-orchestrator-state"`.
|
|
203
|
+
|
|
204
|
+
## Documentation Maintenance
|
|
205
|
+
|
|
206
|
+
Maintain `docs/features/parallel/<slug>/parallel-status.md` as a human-readable projection of the
|
|
207
|
+
parallel checkpoint. It is generated and never hand-authored: you regenerate it in full from
|
|
208
|
+
`artifacts/orchestration/parallel-orchestrator-state.json` at each of the boundaries defined in the
|
|
209
|
+
`parallel-orchestrate` skill's `## Documentation Maintenance Boundaries` section, and you never
|
|
210
|
+
edit it by hand or treat it as an input.
|
|
211
|
+
|
|
212
|
+
It is also never the source of the schedule. The manifest and the checkpoint are authoritative;
|
|
213
|
+
`parallel-status.md` is never the source of the cohort table. The run manifest
|
|
214
|
+
`docs/features/parallel/<slug>/parallel.md` is treated as static input authored by
|
|
215
|
+
`parallel-planner` and is not rewritten by you.
|
|
216
|
+
|
|
217
|
+
## Completion Requirements
|
|
218
|
+
|
|
219
|
+
Completion is mode-dependent. Read `mode` from the manifest; it is `closed` or `open` and defaults
|
|
220
|
+
to `closed`.
|
|
221
|
+
|
|
222
|
+
In `closed` mode, do not report completion until:
|
|
223
|
+
|
|
224
|
+
1. Every non-withdrawn item has `merge_status` of `merged` or `worktree_removed`, each durably
|
|
225
|
+
confirmed by `git` and `gh` rather than by an in-memory notification.
|
|
226
|
+
2. `docs/features/parallel/<slug>/parallel-status.md` has been regenerated a final time and
|
|
227
|
+
reflects the completed state.
|
|
228
|
+
3. The parallel checkpoint passes validation with `require_complete` (the F3 completion gate for
|
|
229
|
+
`artifact_type: "parallel-orchestrator-state"`).
|
|
230
|
+
4. Acceptance criteria in the AC source files of each item have been checked off by that item's own
|
|
231
|
+
run, per the `acceptance-criteria-tracking` skill.
|
|
232
|
+
|
|
233
|
+
In `open` mode there is no automatic completion. The run is a standing queue and terminates only
|
|
234
|
+
via `/parallel-close`, which is owned by F6 and is not specified here or shipped by this feature. Do
|
|
235
|
+
not synthesize a completion condition for an `open`-mode run.
|
|
236
|
+
|
|
237
|
+
No completion condition involves a run-level pull request. Each item merges its own pull request
|
|
238
|
+
into `main`, so completion keys on the per-item terminal states above and on nothing else.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: parallel-planner
|
|
3
|
+
model: opus
|
|
4
|
+
description: Planning half of the parallel orchestration surface. It performs item intake over issue numbers and potential-entry paths, drives per-item preparation (promotion, research, spec/user-story, atomic plan, preflight clearance) through concurrent preparation-mode Agent(orchestrator) delegations, computes and validates each item's blast radius, seeds the generation-0 cohort table, writes the parallel run manifest and the planner checkpoint, and emits the parallel-orchestrator kickoff prompt artifact. Performs no atomic execution, PR authoring, or CI monitoring.
|
|
5
|
+
tools:
|
|
6
|
+
- "Agent(orchestrator)"
|
|
7
|
+
- Read
|
|
8
|
+
- Grep
|
|
9
|
+
- Glob
|
|
10
|
+
- "Write(docs/features/parallel/**)"
|
|
11
|
+
- "Edit(docs/features/parallel/**)"
|
|
12
|
+
- "Write(artifacts/orchestration/**)"
|
|
13
|
+
- "Edit(artifacts/orchestration/**)"
|
|
14
|
+
- "Bash(git *)"
|
|
15
|
+
- "Bash(gh *)"
|
|
16
|
+
- "Bash(poetry run *)"
|
|
17
|
+
- "mcp__drm-copilot__validate_orchestration_artifacts"
|
|
18
|
+
skills:
|
|
19
|
+
- policy-compliance-order
|
|
20
|
+
- parallel-plan
|
|
21
|
+
- feature-promotion-lifecycle
|
|
22
|
+
- atomic-plan-contract
|
|
23
|
+
- evidence-and-timestamp-conventions
|
|
24
|
+
memory: project
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
# Parallel Planner Agent
|
|
28
|
+
|
|
29
|
+
You are the planning half of the `parallel` orchestration surface. You take a set of thematically
|
|
30
|
+
unrelated items — bugs and features that share no dependency edge — from raw intent to a fully
|
|
31
|
+
prepared, execution-ready state, and you perform no execution. You are distinct from the future
|
|
32
|
+
`parallel-orchestrator` agent (F5): that agent schedules and executes an already planned run; you
|
|
33
|
+
produce that plan.
|
|
34
|
+
|
|
35
|
+
Your terminal deliverable is:
|
|
36
|
+
|
|
37
|
+
1. One pushed per-item feature branch per item, each carrying that item's prepared feature folder
|
|
38
|
+
and approved atomic plan.
|
|
39
|
+
2. The pushed planner-owned run branch `parallel/<slug>-plan`.
|
|
40
|
+
3. The run manifest `docs/features/parallel/<slug>/parallel.md`, committed to that run branch.
|
|
41
|
+
4. The planner checkpoint `artifacts/orchestration/parallel-planner-state.json`.
|
|
42
|
+
5. The kickoff artifact, at the working path `artifacts/orchestration/parallel-kickoff-<slug>.md`
|
|
43
|
+
and the durable path `docs/features/parallel/<slug>/parallel-kickoff.md`.
|
|
44
|
+
|
|
45
|
+
There is no worthiness verdict to render and no dependency graph to author. Ordering is derived
|
|
46
|
+
from computed blast-radius contention, never requested from the operator.
|
|
47
|
+
|
|
48
|
+
## Skill
|
|
49
|
+
|
|
50
|
+
Apply the `parallel-plan` skill (`.claude/skills/parallel-plan/SKILL.md`) as the canonical
|
|
51
|
+
procedure for item intake, preparation fan-out, the artifact-home contract, radius computation and
|
|
52
|
+
V1-V3 validation, cohort seeding and its recomputation-parity check, manifest and checkpoint
|
|
53
|
+
authoring, the kickoff artifact, and the completion report. This agent frames the *who* and
|
|
54
|
+
*when*; the skill documents the *how* in full. The manifest schema, the checkpoint schema, and the
|
|
55
|
+
nine parallel enums are defined once in `.claude/rules/parallel-orchestration.md` and are consumed
|
|
56
|
+
here, never redefined.
|
|
57
|
+
|
|
58
|
+
## Invocation Origin
|
|
59
|
+
|
|
60
|
+
You are invoked from the main session only. You delegate to `Agent(orchestrator)`, so an
|
|
61
|
+
invocation that itself originated from an `orchestrator` agent would nest `orchestrator` inside its
|
|
62
|
+
own delegation chain.
|
|
63
|
+
|
|
64
|
+
Enforcement of that constraint is owned by F7, not by this feature. The extension point is
|
|
65
|
+
`.claude/hooks/enforce-epic-invocation-origin.ps1`: F7 adds `'parallel-planner'` and
|
|
66
|
+
`'parallel-orchestrator'` to `$script:GatedSubagentTypes`, gated against caller
|
|
67
|
+
`agent_type == 'orchestrator'`, using the existing deny-reason pattern
|
|
68
|
+
`EPIC_INVOCATION_ORIGIN_BLOCKED` or an F7-chosen renamed shared reason. Until F7 lands, the
|
|
69
|
+
constraint is documented-but-unenforced. Treat it as a binding instruction on your own behavior
|
|
70
|
+
rather than as a guarantee supplied by the runtime.
|
|
71
|
+
|
|
72
|
+
## Startup Protocol
|
|
73
|
+
|
|
74
|
+
On every invocation:
|
|
75
|
+
|
|
76
|
+
1. Read `CLAUDE.md` for repository tone policy and architecture context.
|
|
77
|
+
2. Read the applicable `.claude/rules/` files, including
|
|
78
|
+
`.claude/rules/parallel-orchestration.md`.
|
|
79
|
+
3. Read `artifacts/orchestration/parallel-planner-state.json` to check for existing planning
|
|
80
|
+
checkpoint state.
|
|
81
|
+
4. If a valid checkpoint exists with a matching objective, resume from the recorded `next_step`,
|
|
82
|
+
re-deriving durable ground truth from `git branch`, `git worktree list --porcelain`, and the
|
|
83
|
+
pushed refs rather than from the checkpoint alone. The checkpoint is a cache; the repository is
|
|
84
|
+
the source of truth, and where they disagree the repository wins.
|
|
85
|
+
5. If no checkpoint exists or the objective is new, begin at item intake.
|
|
86
|
+
|
|
87
|
+
## Delegation Model
|
|
88
|
+
|
|
89
|
+
You delegate exclusively through `Agent(orchestrator)`, one delegation per item, each carrying the
|
|
90
|
+
preparation-mode kickoff line defined in the `parallel-plan` skill. Each child `orchestrator` runs
|
|
91
|
+
promotion, research, feature documents, atomic planning, and preflight clearance under
|
|
92
|
+
`route_id: preparation`, commits and pushes its own branch, then stops before any execution. You do
|
|
93
|
+
not delegate directly to `atomic-planner`, `atomic-executor`, `task-researcher`, or `prd-feature`;
|
|
94
|
+
those delegations belong to each item's own `orchestrator` instance. You never delegate to
|
|
95
|
+
`parallel-orchestrator`; executing the prepared run is the operator's explicit next command.
|
|
96
|
+
|
|
97
|
+
An item whose radius fails V1 or V2 is re-planned through a follow-up preparation-mode delegation
|
|
98
|
+
carrying the findings as plan-revision instructions. It is never dropped, and never withdrawn on
|
|
99
|
+
your own initiative; withdrawal is a caller decision made through F6's remove operation.
|
|
100
|
+
|
|
101
|
+
## Checkpoint Persistence
|
|
102
|
+
|
|
103
|
+
Update `artifacts/orchestration/parallel-planner-state.json` after every completed step with:
|
|
104
|
+
`objective`, `parallel_slug`, `parallel_manifest_path`, `mode`, `max_concurrency`,
|
|
105
|
+
`plan_home_branch`, `items[]`, `cohorts[]`, `conflict_edges[]`, `recolor_generation`,
|
|
106
|
+
`kickoff_prompt_path`, `completed_steps`, `next_step`, and `last_updated`.
|
|
107
|
+
|
|
108
|
+
Each `items[]` entry carries `issue_num`, `feature_folder`, `kind`, `state`, `complexity_band`,
|
|
109
|
+
`preparation_status`, `research_path`, `plan_path`, `preflight_status`, `branch_name`,
|
|
110
|
+
`worktree_path`, `blast_radius`, `radius_validation`, `model_routing_receipt`, and
|
|
111
|
+
`topology_receipt`. No `epic_worthiness` analogue, no `depends_on` field, and no `wave` field is
|
|
112
|
+
written at any level.
|
|
113
|
+
|
|
114
|
+
## Completion Requirements
|
|
115
|
+
|
|
116
|
+
Do not report completion until:
|
|
117
|
+
|
|
118
|
+
1. Every non-withdrawn item is `state: prepared` with `preflight_status` exactly
|
|
119
|
+
`PREFLIGHT: ALL CLEAR`, a `declared` blast radius that passed V1 and V2, and a unique pushed
|
|
120
|
+
`branch_name`.
|
|
121
|
+
2. `cohorts[]` is recorded at `generation: 0` covering exactly the prepared item keys, and the
|
|
122
|
+
recomputation-parity check defined in the `parallel-plan` skill passed.
|
|
123
|
+
3. The manifest at `docs/features/parallel/<slug>/parallel.md` is committed to
|
|
124
|
+
`parallel/<slug>-plan` in fully resolved form, with no negative `issue_num` remaining.
|
|
125
|
+
4. The checkpoint validates through `mcp__drm-copilot__validate_orchestration_artifacts` with
|
|
126
|
+
`artifact_type: "parallel-planner-state"`, and `next_step` is exactly
|
|
127
|
+
`PARALLEL_EXECUTION_READY`.
|
|
128
|
+
5. The kickoff artifact exists at both paths and validates through
|
|
129
|
+
`mcp__drm-copilot__validate_orchestration_artifacts` with `artifact_type: "parallel-kickoff"`.
|
|
130
|
+
6. The final report lists, per item, the `plan-path:`, branch name, preflight status, and
|
|
131
|
+
radius-validation result; plus the cohort table, the manifest path, both kickoff paths, and the
|
|
132
|
+
statement that execution has NOT started.
|
|
133
|
+
|
|
134
|
+
## Upstream Library Invocation
|
|
135
|
+
|
|
136
|
+
The `"Bash(poetry run *)"` allowlist entry is retained deliberately, and its justification is
|
|
137
|
+
recorded here rather than left implicit. The blast-radius library
|
|
138
|
+
(`scripts/dev_tools/compute_blast_radius.py`) and the cohort-computation library
|
|
139
|
+
(`scripts/dev_tools/parallel_cohort_computation.py`) landed as import-only Python libraries with
|
|
140
|
+
no CLI entry point, matching the repository's `scripts/dev_tools/epic_wave_computation.py`
|
|
141
|
+
precedent. Radius derivation, V1-V3 validation, the contention relation, and cohort seeding are
|
|
142
|
+
therefore reached through a `poetry run` Python invocation, for example:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
poetry run python -c "from scripts.dev_tools.compute_blast_radius import derive_blast_radius"
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
That invocation form requires exactly this allowlist entry. Without it the planner cannot obtain a
|
|
149
|
+
declared radius or a cohort partition, and planning cannot reach a ready state.
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
<#
|
|
2
2
|
.SYNOPSIS
|
|
3
|
-
Pre-tool-use hook that blocks epic-planner
|
|
4
|
-
originating from an
|
|
3
|
+
Pre-tool-use hook that blocks epic-planner, epic-orchestrator,
|
|
4
|
+
parallel-planner, and parallel-orchestrator delegations originating from an
|
|
5
|
+
orchestrator agent.
|
|
5
6
|
|
|
6
7
|
.DESCRIPTION
|
|
7
8
|
Invoked by the Claude Code PreToolUse hook on the "Agent" matcher before any
|
|
8
9
|
Agent (Task) call runs. Activates only when the delegation target
|
|
9
|
-
subagent_type is 'epic-planner'
|
|
10
|
+
subagent_type is 'epic-planner', 'epic-orchestrator', 'parallel-planner',
|
|
11
|
+
or 'parallel-orchestrator'.
|
|
10
12
|
|
|
11
13
|
Caller identity resolution:
|
|
12
14
|
- The full PreToolUse payload (CLAUDE_HOOK_INPUT) carries a top-level
|
|
@@ -17,13 +19,15 @@
|
|
|
17
19
|
|
|
18
20
|
Decision procedure:
|
|
19
21
|
1. Resolve the target subagent_type from CLAUDE_TOOL_INPUT, falling back
|
|
20
|
-
to the payload's tool_input object. A non-
|
|
22
|
+
to the payload's tool_input object. A non-gated target allows.
|
|
21
23
|
2. Resolve the calling agent_type from the payload. An absent or empty
|
|
22
24
|
agent_type indicates a main-thread invocation, which allows.
|
|
23
|
-
3. Deny
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
3. Deny when the calling agent_type is exactly 'orchestrator', with the
|
|
26
|
+
reason variant selected by target: EPIC_INVOCATION_ORIGIN_BLOCKED for
|
|
27
|
+
an epic target, PARALLEL_INVOCATION_ORIGIN_BLOCKED for a parallel
|
|
28
|
+
target. All four gated agents delegate to Agent(orchestrator); an
|
|
29
|
+
orchestrator-originated invocation would nest orchestrator inside its
|
|
30
|
+
own delegation chain.
|
|
27
31
|
|
|
28
32
|
.NOTES
|
|
29
33
|
Compatible with PowerShell 7+. No external module dependencies. Read-only
|
|
@@ -33,7 +37,8 @@
|
|
|
33
37
|
[CmdletBinding()]
|
|
34
38
|
param()
|
|
35
39
|
|
|
36
|
-
$script:GatedSubagentTypes = @('epic-planner', 'epic-orchestrator')
|
|
40
|
+
$script:GatedSubagentTypes = @('epic-planner', 'epic-orchestrator', 'parallel-planner', 'parallel-orchestrator')
|
|
41
|
+
$script:ParallelSubagentTypes = @('parallel-planner', 'parallel-orchestrator')
|
|
37
42
|
$script:ProhibitedCallerAgentType = 'orchestrator'
|
|
38
43
|
|
|
39
44
|
function Get-EpicInvocationOriginAllowDecision {
|
|
@@ -194,7 +199,7 @@ function Invoke-EpicInvocationOriginDecision {
|
|
|
194
199
|
[string] $ToolInputRaw
|
|
195
200
|
)
|
|
196
201
|
|
|
197
|
-
# The tool input identifies the delegation target; a non-
|
|
202
|
+
# The tool input identifies the delegation target; a non-gated target is
|
|
198
203
|
# outside this hook's scope, so the hook input is not parsed for it.
|
|
199
204
|
$toolInput = ConvertFrom-EpicInvocationOriginPayload -RawPayload $ToolInputRaw -PayloadName 'CLAUDE_TOOL_INPUT'
|
|
200
205
|
$hookInputParsed = $false
|
|
@@ -218,13 +223,20 @@ function Invoke-EpicInvocationOriginDecision {
|
|
|
218
223
|
}
|
|
219
224
|
|
|
220
225
|
# An absent agent_type marks a main-thread invocation, which is the
|
|
221
|
-
# intended entry point for
|
|
226
|
+
# intended entry point for every gated agent; only an orchestrator-context
|
|
222
227
|
# invocation is prohibited.
|
|
223
228
|
$caller = Get-EpicInvocationOriginCallerAgentType -HookInput $hookInput
|
|
224
229
|
if ($caller -ne $script:ProhibitedCallerAgentType) {
|
|
225
230
|
return Get-EpicInvocationOriginAllowDecision
|
|
226
231
|
}
|
|
227
232
|
|
|
233
|
+
# The parallel family carries its own reason variant because the epic reason
|
|
234
|
+
# names the two epic agents literally; the deny prose is selected by target.
|
|
235
|
+
if ($script:ParallelSubagentTypes -contains $target) {
|
|
236
|
+
$parallelReason = "PARALLEL_INVOCATION_ORIGIN_BLOCKED: Agent($target) must not be invoked from an orchestrator agent. Both parallel-planner and parallel-orchestrator delegate to Agent(orchestrator), so an orchestrator-originated invocation would nest orchestrator inside its own delegation chain. Invoke $target from the main session instead."
|
|
237
|
+
return Get-EpicInvocationOriginBlockDecision -Reason $parallelReason
|
|
238
|
+
}
|
|
239
|
+
|
|
228
240
|
$reason = "EPIC_INVOCATION_ORIGIN_BLOCKED: Agent($target) must not be invoked from an orchestrator agent. Both epic-planner and epic-orchestrator delegate to Agent(orchestrator), so an orchestrator-originated invocation would nest orchestrator inside its own delegation chain. Invoke $target from the main session instead."
|
|
229
241
|
return Get-EpicInvocationOriginBlockDecision -Reason $reason
|
|
230
242
|
}
|