agentic-team 6.1.0 → 6.2.0
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/README.md +8 -3
- package/bin/build-template.js +2 -2
- package/bin/index.js +234 -39
- package/bin/platforms.js +510 -0
- package/package.json +4 -4
- package/template/.claude-plugin/plugin.json +2 -2
- package/template/.orchestra/README.md +41 -51
- package/template/.orchestra/config.yml +16 -0
- package/template/.orchestra/roles/product-manager.md +3 -2
- package/template/.orchestra/scripts/compact-diff.awk +1 -1
- package/template/.orchestra/scripts/context.mjs +373 -0
- package/template/.orchestra/stacks/_repo/setup.sh +7 -3
- package/template/.orchestra/stacks/mobile-expo/setup.sh +1 -1
- package/template/CLAUDE.md +1 -1
- package/template/agents/lead.md +171 -116
- package/template/agents/milestone-reviewer.md +5 -3
- package/template/agents/product-manager.md +3 -2
- package/template/agents/re-reviewer.md +25 -0
- package/template/agents/reviewer.md +7 -5
- package/template/agents/scaffolder.md +26 -0
- package/template/commands/help.md +1 -0
- package/template/commands/hotfix.md +3 -1
- package/template/commands/rewind.md +10 -8
- package/template/commands/setup.md +2 -1
- package/template/commands/start.md +2 -2
- package/template/commands/status.md +1 -1
- package/template/commands/sync.md +5 -2
- package/template/commands/verifier.md +2 -2
- package/template/hooks/audit-context.sh +15 -2
- package/template/hooks/enforce-role.sh +21 -3
- package/template/hooks/protect-system-files.sh +2 -2
- package/template/hooks/review-rounds.sh +1 -1
- package/template/rules/code-standards.orchestra.md +3 -2
- package/template/rules/design-parity.orchestra.md +12 -1
- package/template/rules/observability.orchestra.md +3 -0
- package/template/rules/performance.orchestra.md +5 -1
- package/template/rules/phase-limits.orchestra.md +1 -1
- package/template/rules/pull-request.orchestra.md +7 -2
- package/template/rules/role-boundaries.orchestra.md +24 -9
- package/template/rules/security.orchestra.md +1 -1
- package/template/rules/stuck-detection.orchestra.md +1 -1
- package/template/rules/testing-standards.orchestra.md +10 -5
- package/template/rules/tracker-authority.orchestra.md +9 -1
- package/template/skills/push-notifications/SKILL.md +1 -1
- package/template/skills/testing/SKILL.md +2 -1
|
@@ -507,7 +507,7 @@ jobs:
|
|
|
507
507
|
# One script, not a second copy of these steps. It carries the
|
|
508
508
|
# locale, the Sentry opt-out, the JDK check maestro needs and the
|
|
509
509
|
# Release/--no-bundler reasoning — see the file. Anyone can reproduce a
|
|
510
|
-
# red e2e by running it, and the
|
|
510
|
+
# red e2e by running it, and the agentic-team repo's own CI runs the same
|
|
511
511
|
# thing rather than a paraphrase of it.
|
|
512
512
|
- name: e2e
|
|
513
513
|
run: ./e2e-ios.sh
|
|
@@ -1078,12 +1078,15 @@ fi
|
|
|
1078
1078
|
# URL design into .fetched/, and the capture the PR shows lands in .captures/.
|
|
1079
1079
|
# Committed, both of them: gh cannot upload an image, so a screenshot that is
|
|
1080
1080
|
# not in the branch cannot appear in a pull request.
|
|
1081
|
-
mkdir -p designs/.captures designs/.fetched
|
|
1081
|
+
mkdir -p designs/.captures designs/.fetched designs/.reports
|
|
1082
1082
|
# git does not track an empty directory, so without these the two folders
|
|
1083
1083
|
# vanish on the next clone and the first phase with a design has to invent a
|
|
1084
1084
|
# location — which is how two of them end up disagreeing.
|
|
1085
1085
|
: > designs/.captures/.gitkeep
|
|
1086
1086
|
: > designs/.fetched/.gitkeep
|
|
1087
|
+
# Machine output of a comparison is regenerated from the images and never
|
|
1088
|
+
# committed; one project committed ~100k lines of JSON reports here.
|
|
1089
|
+
printf '*\n!.gitignore\n' > designs/.reports/.gitignore
|
|
1087
1090
|
cat > designs/README.md <<'MD'
|
|
1088
1091
|
# designs
|
|
1089
1092
|
|
|
@@ -1093,7 +1096,8 @@ The source of truth for any screen this repo builds.
|
|
|
1093
1096
|
designs/
|
|
1094
1097
|
├── <screen>.png the design. mirrors the screen structure.
|
|
1095
1098
|
├── .fetched/ a design given as a URL, fetched once when the phase starts
|
|
1096
|
-
|
|
1099
|
+
├── .captures/ what was actually built, so a pull request can show both
|
|
1100
|
+
└── .reports/ a comparison tool's output — regenerated, never committed
|
|
1097
1101
|
```
|
|
1098
1102
|
|
|
1099
1103
|
A phase points at one with `design:` in its frontmatter — a path in here, or a
|
|
@@ -318,7 +318,7 @@ yarn biome check --write . >/dev/null 2>&1 || true
|
|
|
318
318
|
# ── e2e, as a script rather than only as CI steps ─────────────────────────
|
|
319
319
|
# The workflow used to carry the build and the maestro run inline, which made
|
|
320
320
|
# it unrunnable anywhere else: nobody could reproduce a red e2e locally, and
|
|
321
|
-
# the
|
|
321
|
+
# the agentic-team repo's own CI could only test a *copy* of those steps. A copy
|
|
322
322
|
# that drifts proves nothing. One script, called by both.
|
|
323
323
|
cat > e2e-ios.sh <<'E2E'
|
|
324
324
|
#!/usr/bin/env bash
|
package/template/CLAUDE.md
CHANGED
|
@@ -48,7 +48,7 @@ Role IDs: orchestrator, product-manager
|
|
|
48
48
|
|
|
49
49
|
- Two-terminal model: PM plans in one terminal, lead executes in another
|
|
50
50
|
- Each role writes only to its ownership scope (defined in role file)
|
|
51
|
-
- Rules (`.claude/rules/*.orchestra.md`) auto-loaded. Skills loaded per phase.
|
|
51
|
+
- Rules (`.claude/rules/*.orchestra.md`) auto-loaded, except those with `paths:` frontmatter, which load with their files and are read where named. Skills loaded per phase.
|
|
52
52
|
- **PROTECTED:** Non-Orchestrator roles NEVER modify `.orchestra/roles/`, `.orchestra/config.yml`, `.orchestra/README.md`, `.orchestra/blueprints/`, `.orchestra/stacks/`, `.orchestra/trackers/`, `.orchestra/scripts/`, `.claude/agents/`, `.claude/hooks/`, `.claude/rules/*.orchestra.md`, `.claude/skills/*/SKILL.md`, `.claude/commands/orchestra/`, `CLAUDE.md`, or `docs/`.
|
|
53
53
|
|
|
54
54
|
<!-- /orchestra -->
|
package/template/agents/lead.md
CHANGED
|
@@ -12,6 +12,12 @@ You NEVER implement code yourself.
|
|
|
12
12
|
|
|
13
13
|
## Startup
|
|
14
14
|
|
|
15
|
+
Some rules load only when an agent touches the files they govern — `paths:`
|
|
16
|
+
in their frontmatter — so an engineer is not handed the tracker or the
|
|
17
|
+
pull-request rule on every call. Those paths match from the project root, and
|
|
18
|
+
a sub-agent in a worktree does not trigger them, so wherever this file names a
|
|
19
|
+
rule, read it rather than assume it is loaded.
|
|
20
|
+
|
|
15
21
|
| Command | Behavior |
|
|
16
22
|
|---------|----------|
|
|
17
23
|
| `/orchestra:start` | Asks user at approval gates |
|
|
@@ -41,8 +47,8 @@ When started:
|
|
|
41
47
|
severity scale nobody defined, and went nine rounds on one phase.
|
|
42
48
|
3. Read `.orchestra/README.md` for orchestration rules.
|
|
43
49
|
3b. Read `tracker.provider`. If it is not `none`, the tracker owns the
|
|
44
|
-
requirements and this changes where you read work from —
|
|
45
|
-
`.claude/rules/tracker-authority.orchestra.md
|
|
50
|
+
requirements and this changes where you read work from — read
|
|
51
|
+
`.claude/rules/tracker-authority.orchestra.md` now.
|
|
46
52
|
- Fetch each task once, at the start of the run, into
|
|
47
53
|
`.orchestra/milestones/<slug>/.cache/`. That directory is gitignored and
|
|
48
54
|
is not authority after the run — it exists so a run that started does not
|
|
@@ -55,15 +61,14 @@ When started:
|
|
|
55
61
|
- Read each to check Status field
|
|
56
62
|
- `status: in-progress` → resume | `status: planning` → start
|
|
57
63
|
- `status: failed` → do NOT silently skip. Report it to the user with the
|
|
58
|
-
recorded reason from
|
|
64
|
+
recorded reason from `journal.md`, and ask whether to retry or move on.
|
|
59
65
|
In `--auto`, skip it but list it in the final report.
|
|
60
66
|
- all `done` → report complete
|
|
61
|
-
6.
|
|
62
|
-
|
|
63
|
-
-
|
|
64
|
-
-
|
|
65
|
-
|
|
66
|
-
7. Begin execution loop.
|
|
67
|
+
6. Begin execution loop: one milestone agent per milestone — see Milestone
|
|
68
|
+
Agent Delegation. Phase work never starts in this session:
|
|
69
|
+
`.claude/hooks/enforce-role.sh` refuses an `engineer-*`, `reviewer` or
|
|
70
|
+
`re-reviewer` launched from it, because one run kept two milestones here
|
|
71
|
+
and grew to 738 calls and a 925k-token context.
|
|
67
72
|
|
|
68
73
|
## Pipeline Selection
|
|
69
74
|
|
|
@@ -154,7 +159,7 @@ their content into the prompt. This eliminates sub-agent startup Read calls.
|
|
|
154
159
|
Cache skills content in lead context — don't re-read for consecutive
|
|
155
160
|
phases with the same skills.
|
|
156
161
|
|
|
157
|
-
1. Read skill files from phase `.claude/skills/{name}/SKILL.md` → skills_content (skip already-read skills)
|
|
162
|
+
1. Read skill files from phase `.claude/skills/{name}/SKILL.md` → skills_content (skip already-read skills). A name with no `SKILL.md` is not installed for this project's platforms: say so in the phase result and go on without it — never improvise its content
|
|
158
163
|
2. Read phase file → phase_content
|
|
159
164
|
3. Extract verification commands from config.yml (read once at startup, reuse)
|
|
160
165
|
Determine `{app_dir}` from the phase `## Scope` — the app directory its
|
|
@@ -196,7 +201,8 @@ same identity runs consecutive phases), dynamic content last.
|
|
|
196
201
|
|
|
197
202
|
```
|
|
198
203
|
You are executing a phase for Orchestra lead.
|
|
199
|
-
Rules from `.claude/rules/*.orchestra.md` are
|
|
204
|
+
Rules from `.claude/rules/*.orchestra.md` are loaded for you, except those
|
|
205
|
+
that load with their own files; any rule this prompt names, read yourself.
|
|
200
206
|
|
|
201
207
|
**Verification (run in this order, stop at first failure):**
|
|
202
208
|
Working directory: {app_dir}
|
|
@@ -244,7 +250,8 @@ not a difference to split.
|
|
|
244
250
|
{codebase_map}
|
|
245
251
|
|
|
246
252
|
**Previous phase summary:**
|
|
247
|
-
{previous_phase_result_summary —
|
|
253
|
+
{previous_phase_result_summary — the output of `context.mjs live <m>` (open
|
|
254
|
+
decisions only) plus a concise summary of the artifacts
|
|
248
255
|
that affect this phase. Omit for first phase.}
|
|
249
256
|
|
|
250
257
|
## Your Task
|
|
@@ -259,7 +266,7 @@ that affect this phase. Omit for first phase.}
|
|
|
259
266
|
4. Design parity — only when a **Design** section is present above.
|
|
260
267
|
Render the screen, capture it, and compare against the design across
|
|
261
268
|
layout and spacing, typography, colour, component states and content.
|
|
262
|
-
Fix every blocking discrepancy and repeat.
|
|
269
|
+
Fix every blocking discrepancy and repeat. Read and follow
|
|
263
270
|
`.claude/rules/design-parity.orchestra.md` — it defines what blocks, how
|
|
264
271
|
to capture on this platform, and where the capture is written.
|
|
265
272
|
Reading the code is not a comparison. If you cannot produce a capture, say
|
|
@@ -359,9 +366,11 @@ When generating the identity block, use these domain-specific priorities:
|
|
|
359
366
|
simulator in this session" is an honest unverified. "Close enough" is not
|
|
360
367
|
a reason and is sent back.
|
|
361
368
|
1. Lead commits
|
|
362
|
-
2.
|
|
369
|
+
2. Record it: `context.mjs phase <m> <phase> done "commit: … | files: …"`,
|
|
370
|
+
then `decide` / `journal` for what the sub-agent's notes say — see
|
|
371
|
+
Context Persistence
|
|
363
372
|
- If **failed** (verification failed after max retries):
|
|
364
|
-
1.
|
|
373
|
+
1. `context.mjs phase <m> <phase> failed "error: … | retries: …"`
|
|
365
374
|
2. Decide: retry with new sub-agent or escalate to user
|
|
366
375
|
|
|
367
376
|
**Note:** Lead owns commit only. Sub-agents own implementation + verification.
|
|
@@ -403,7 +412,9 @@ Unless config says `review: skip`:
|
|
|
403
412
|
### `pr` mode
|
|
404
413
|
|
|
405
414
|
1. Open the pull request first — see Delivery below.
|
|
406
|
-
2. Call the reviewer
|
|
415
|
+
2. Call the reviewer with the PR number — `subagent_type: reviewer` for the
|
|
416
|
+
first round, at `high`, and `re-reviewer` for every round after, at
|
|
417
|
+
`medium`. It posts **one review**
|
|
407
418
|
with each finding attached to the line it is about, as the authenticated
|
|
408
419
|
user, and labels the PR with its verdict. Every round is a **new** reviewer
|
|
409
420
|
launch whose prompt carries a line
|
|
@@ -416,8 +427,8 @@ Unless config says `review: skip`:
|
|
|
416
427
|
are this phase's entry in `.orchestra/.sessions/review-rounds.json`; read
|
|
417
428
|
it there after a restart rather than from memory. After **every** review,
|
|
418
429
|
whatever its verdict, record each `[suggestion]` comment it left: a
|
|
419
|
-
`tech_debt` task with a provider,
|
|
420
|
-
`
|
|
430
|
+
`tech_debt` task with a provider, `context.mjs decide <m> tech_debt` with
|
|
431
|
+
`tracker.provider: none`. A later round
|
|
421
432
|
need not repeat it, so one not recorded now is lost.
|
|
422
433
|
3. **`review:approved`** → the task is done; stop for the human, or
|
|
423
434
|
squash-merge under `--auto`.
|
|
@@ -445,7 +456,10 @@ Unless config says `review: skip`:
|
|
|
445
456
|
The verdict is a label rather than a review state because the author cannot
|
|
446
457
|
approve their own pull request — and a label is readable after a crash. A
|
|
447
458
|
run that dies mid-cycle asks the PR what state it is in instead of guessing.
|
|
448
|
-
5. Re-review the
|
|
459
|
+
5. Re-review with `re-reviewer`. Its prompt names the range — the PR head the
|
|
460
|
+
last review saw to the head the fix pushed — and tells it to read
|
|
461
|
+
`.claude/rules/pull-request.orchestra.md` for the query that lists the
|
|
462
|
+
open threads. Max rounds: `thresholds.stuck_retry_limit`, and
|
|
449
463
|
the hook refuses the launch past it. When the last allowed review still
|
|
450
464
|
requests changes, the user decides, not you: give them its open Blocking
|
|
451
465
|
and Important findings and stop. Under `--auto`, set the task `blocked`
|
|
@@ -461,7 +475,9 @@ The engineer answers the review, not you. Its context is the code, the diff
|
|
|
461
475
|
and the thread — all on the pull request, which is why a fresh one can answer
|
|
462
476
|
it and you cannot answer it from a summary.
|
|
463
477
|
|
|
464
|
-
The commands are in `.claude/rules/pull-request.orchestra.md
|
|
478
|
+
The commands are in `.claude/rules/pull-request.orchestra.md`; read it before
|
|
479
|
+
the first pull request, and tell every fix-round engineer to read it before
|
|
480
|
+
it answers a thread.
|
|
465
481
|
|
|
466
482
|
## Delivery
|
|
467
483
|
|
|
@@ -477,14 +493,16 @@ which has always said one task one PR. A milestone-wide PR is a diff nobody
|
|
|
477
493
|
can review and a body that cannot show a screen, because the design table has
|
|
478
494
|
one row and the milestone has ten screens.
|
|
479
495
|
|
|
480
|
-
1. Branch per task, off
|
|
496
|
+
1. Branch per task, off the freshly fetched `origin/{delivery.base_branch}`:
|
|
497
|
+
**`<git-user>/<task-id>-<slug>`**, taking the
|
|
481
498
|
user from `git config user.name` and the id from `tracker.yml`. With no
|
|
482
499
|
tracker, drop the id segment. The id is in the branch so the board can find
|
|
483
500
|
the work without anyone pasting a link.
|
|
484
501
|
2. Commit the task's work to it, conventionally. A task PR usually ends up with
|
|
485
502
|
more than one commit — the implementation, then whatever review asked for —
|
|
486
|
-
and the squash is what makes it one on
|
|
487
|
-
3. Push and open its PR with `gh
|
|
503
|
+
and the squash is what makes it one on the base branch.
|
|
504
|
+
3. Push and open its PR with `gh pr create --base {delivery.base_branch}`,
|
|
505
|
+
titled **`#<task-id> - <subject>`** —
|
|
488
506
|
the subject is the phase's `title:`, the same sentence the board shows. The
|
|
489
507
|
PR comes **before** review now, not after — the review happens on it, and
|
|
490
508
|
the reviewer is still the first reader, so the human never meets unreviewed
|
|
@@ -530,8 +548,9 @@ one row and the milestone has ten screens.
|
|
|
530
548
|
|
|
531
549
|
**With `--auto`:** squash-merge the PR yourself, post the resulting commit
|
|
532
550
|
link on the tracker task, move its status, delete the branch, and start the
|
|
533
|
-
next task off the freshly merged
|
|
534
|
-
because every task is on
|
|
551
|
+
next task off the freshly merged base branch. Nothing stacks and nothing
|
|
552
|
+
waits, because every task is on the base branch before the next one
|
|
553
|
+
branches.
|
|
535
554
|
|
|
536
555
|
**Without `--auto`:** stop. **Do not merge** — the human squashes. Which
|
|
537
556
|
task you may start next is decided by `depends_on`:
|
|
@@ -544,9 +563,10 @@ one row and the milestone has ten screens.
|
|
|
544
563
|
squashes, so the parent's commits reappear in the child's diff until it is
|
|
545
564
|
rebased, and an agent repeating that gets it wrong.
|
|
546
565
|
8. A human review arriving later is the same loop, entered from the other
|
|
547
|
-
end: unresolved threads on the PR are work to do
|
|
548
|
-
|
|
549
|
-
review is ready — never
|
|
566
|
+
end: unresolved threads on the PR are work to do. Launch a single-phase
|
|
567
|
+
agent (below) in fix mode for that phase and PR; its new engineer answers
|
|
568
|
+
them the same way. Fetch when the user says the review is ready — never
|
|
569
|
+
poll.
|
|
550
570
|
|
|
551
571
|
For any phase with a design source, run the parity loop from
|
|
552
572
|
`.claude/rules/design-parity.orchestra.md`: render, compare, fix blocking
|
|
@@ -565,8 +585,8 @@ the two failure modes below are what turn an unattended run into a codebase
|
|
|
565
585
|
somebody has to live with.
|
|
566
586
|
|
|
567
587
|
Both need a tracker. With `tracker.provider: none` there is nowhere to put
|
|
568
|
-
them, so
|
|
569
|
-
and say so in the final report.
|
|
588
|
+
them, so record them with `context.mjs decide <m> blocker` and
|
|
589
|
+
`decide <m> tech_debt`, and say so in the final report.
|
|
570
590
|
|
|
571
591
|
### Blocked — stop this task, not the run
|
|
572
592
|
|
|
@@ -637,14 +657,14 @@ Before marking a milestone done, confirm:
|
|
|
637
657
|
default) — see `.claude/rules/observability.orchestra.md`
|
|
638
658
|
- [ ] KPI events for this milestone fire and were observed arriving, per
|
|
639
659
|
`.claude/rules/analytics-kpi.orchestra.md`
|
|
640
|
-
- [ ] `pr` mode: PR opened and left unmerged, and its URL
|
|
660
|
+
- [ ] `pr` mode: PR opened and left unmerged, and its URL in the phase's `context.mjs phase` note
|
|
641
661
|
|
|
642
662
|
Any unchecked item is reported to the user, not quietly skipped.
|
|
643
663
|
|
|
644
664
|
Then:
|
|
645
665
|
1. Update milestone.md `status: done`, remove `Locked-By`.
|
|
646
666
|
On failure: set `status: failed`, **also remove `Locked-By`**, and record the
|
|
647
|
-
reason
|
|
667
|
+
reason with `context.mjs journal <m> milestone "…"`. A milestone left locked blocks every future run.
|
|
648
668
|
2. Proceed to next milestone.
|
|
649
669
|
|
|
650
670
|
## Next Milestone
|
|
@@ -662,7 +682,8 @@ milestone agent. Lead only accumulates ~1-2k tokens per milestone
|
|
|
662
682
|
|
|
663
683
|
## Milestone Agent Delegation
|
|
664
684
|
|
|
665
|
-
Every milestone runs as a separate sub-agent
|
|
685
|
+
Every milestone runs as a separate sub-agent, and the role hook holds you to
|
|
686
|
+
it. Lead is a two-tier dispatcher:
|
|
666
687
|
- Lead spawns one milestone agent per milestone
|
|
667
688
|
- Milestone agent spawns phase sub-agents (same as current phase delegation)
|
|
668
689
|
- When milestone agent completes, its context is freed entirely
|
|
@@ -671,7 +692,9 @@ Every milestone runs as a separate sub-agent. Lead is a two-tier dispatcher:
|
|
|
671
692
|
|
|
672
693
|
```
|
|
673
694
|
You are a Milestone Agent executing milestone {milestone_id}: {title}.
|
|
674
|
-
Rules from `.claude/rules/*.orchestra.md` are
|
|
695
|
+
Rules from `.claude/rules/*.orchestra.md` are loaded for you, except those
|
|
696
|
+
that load with their own files; any rule this prompt or lead's sections name,
|
|
697
|
+
read yourself.
|
|
675
698
|
|
|
676
699
|
**Config:**
|
|
677
700
|
{config_yml_content}
|
|
@@ -686,15 +709,15 @@ Rules from `.claude/rules/*.orchestra.md` are automatically loaded.
|
|
|
686
709
|
{grooming.md content}
|
|
687
710
|
|
|
688
711
|
**Context (if resuming):**
|
|
689
|
-
{context.md content}
|
|
690
|
-
|
|
691
|
-
|
|
712
|
+
{context.md content} — Status, Phases (skip `done` ones), Codebase Map
|
|
713
|
+
{output of `context.mjs live <m>`} — the open binding decisions; run `open` for
|
|
714
|
+
the blockers, questions and tech debt; the journal is not sent
|
|
692
715
|
|
|
693
716
|
**Phase files:**
|
|
694
717
|
{all phase file contents, in order}
|
|
695
718
|
|
|
696
719
|
## Git Rules (non-negotiable)
|
|
697
|
-
- **One branch per task**, off `
|
|
720
|
+
- **One branch per task**, off `origin/{delivery.base_branch}`, named for the task. Never one branch
|
|
698
721
|
for the milestone: that produces a diff nobody can review and a body with
|
|
699
722
|
one design row facing every screen the milestone touched.
|
|
700
723
|
- Never switch to an unrelated branch.
|
|
@@ -707,12 +730,16 @@ Sections: `## Status` (milestone state), `## Phases` (per-phase status — skip
|
|
|
707
730
|
- without it → **never merge your own PR.** The human squashes, and a task
|
|
708
731
|
whose `depends_on` is unmerged waits and is named rather than stalling.
|
|
709
732
|
- with it → squash-merge, post the commit link on the tracker task, move its
|
|
710
|
-
status, delete the branch, branch the next task off the merged
|
|
733
|
+
status, delete the branch, branch the next task off the merged base branch.
|
|
711
734
|
|
|
712
735
|
## Your Task
|
|
713
736
|
Execute this milestone using the Phase Execution protocol:
|
|
737
|
+
0. If the milestone's scope spans 3+ directories or 20+ files, launch a scout
|
|
738
|
+
(`subagent_type: engineer-low`, `model: {pipeline.model}`) to return a map of at most 30 lines —
|
|
739
|
+
`path/file — one-line description` — and write it with
|
|
740
|
+
`context.mjs map <m>` and a heredoc. Smaller scopes skip it.
|
|
714
741
|
1. For each phase: pre-flight → derive identity → compose prompt → delegate to phase sub-agent → process result
|
|
715
|
-
2. Lead (you) commits after each successful phase
|
|
742
|
+
2. Lead (you) commits after each successful phase and records it with `context.mjs`
|
|
716
743
|
3. Per task: push, open its PR, run the reviewer on it (unless config says
|
|
717
744
|
skip), answer the threads, then merge or wait per `--auto`. Before the
|
|
718
745
|
first phase, read the Phase Execution and Review sections of
|
|
@@ -723,7 +750,7 @@ Execute this milestone using the Phase Execution protocol:
|
|
|
723
750
|
open is set `blocked` with a comment naming them, listed in `review_blocked`,
|
|
724
751
|
and you move on to the next task
|
|
725
752
|
4. Never a single review at the end — a milestone is reviewed one task at a time
|
|
726
|
-
5. On phase failure after max retries:
|
|
753
|
+
5. On phase failure after max retries: `context.mjs phase <m> <phase> failed "…"`
|
|
727
754
|
- If stuck: set milestone status to `failed`, return immediately
|
|
728
755
|
6. You own exactly ONE milestone — do NOT loop to other milestones
|
|
729
756
|
|
|
@@ -744,104 +771,130 @@ IMPORTANT: Do NOT write to any Orchestra system files — lead handles updates.
|
|
|
744
771
|
Lead processes the return:
|
|
745
772
|
|
|
746
773
|
- **status: done + pushed: true** → Update milestone.md status to `done`, remove `Locked-By`, proceed to next milestone.
|
|
747
|
-
- **status: failed** →
|
|
774
|
+
- **status: failed** → `context.mjs journal <m> <phase> "<the failure>"`.
|
|
748
775
|
- `--auto` mode: move to next milestone.
|
|
749
776
|
- Normal mode: stop and report to user with options: (a) retry with fresh agent, (b) skip, (c) stop.
|
|
750
777
|
- **status: done + pushed: false** → Log error, escalate to user.
|
|
751
778
|
- **`review_blocked` not empty** → before the next milestone, give the user
|
|
752
779
|
each phase and its open findings and ask whether to approve another round.
|
|
753
|
-
On a yes,
|
|
754
|
-
|
|
755
|
-
|
|
780
|
+
On a yes, launch a single-phase agent (below) in fix mode for that phase,
|
|
781
|
+
with the user's approval quoted: it runs Review step 4's fix, then the
|
|
782
|
+
re-review with the approval line. A relaunched milestone agent for the
|
|
783
|
+
whole milestone would skip phases already `done`, and the role hook keeps
|
|
784
|
+
you from running the round here. Under `--auto`, leave
|
|
756
785
|
them `blocked` and name them in the final report.
|
|
757
786
|
|
|
787
|
+
### Single-Phase Agent
|
|
788
|
+
|
|
789
|
+
Work on one phase after its milestone agent has ended — a human review on an
|
|
790
|
+
open PR, an approved extra review round, a `/orchestra:sync` comment that
|
|
791
|
+
needs code — runs in a general-purpose agent with this prompt. The role hook
|
|
792
|
+
refuses an engineer or reviewer launched from your own session, so this is
|
|
793
|
+
the only route.
|
|
794
|
+
|
|
795
|
+
```
|
|
796
|
+
You are a Single-Phase Agent for {milestone_id}/{phase}.
|
|
797
|
+
Read the Phase Execution and Review sections of `.claude/agents/lead.md`
|
|
798
|
+
and follow them exactly; you have lead's capabilities for this one phase.
|
|
799
|
+
|
|
800
|
+
**Mode:** fix | build
|
|
801
|
+
**Phase file:** {phase file content}
|
|
802
|
+
**PR:** {number, or none in build mode}
|
|
803
|
+
**Why you exist:** {the review threads to answer | the user's approval,
|
|
804
|
+
quoted — copy it into the reviewer prompt as `Extra round approved by the
|
|
805
|
+
user: …` | the sync comment, quoted with its link}
|
|
806
|
+
|
|
807
|
+
Fix mode: do not rebuild the phase. Go straight to Review step 4 — a new
|
|
808
|
+
engineer fixes and answers the threads — then the re-review.
|
|
809
|
+
Build mode: build it as a phase on its own branch, open its PR, review it.
|
|
810
|
+
Either way, return: status, PR, open Blocking/Important findings if the cap
|
|
811
|
+
was reached.
|
|
812
|
+
```
|
|
813
|
+
|
|
758
814
|
### Milestone Agent Configuration
|
|
759
815
|
|
|
760
816
|
- Use default (general-purpose) subagent_type — milestone identity is in the prompt
|
|
761
817
|
- Do NOT use `isolation: "worktree"` — milestones run sequentially, not in parallel
|
|
762
818
|
- Milestone agent inherits all lead capabilities: git, Agent tool, file access
|
|
763
|
-
- On resume (milestone was `in-progress`): include context.md in prompt — milestone agent reads phase statuses and continues from last completed phase
|
|
819
|
+
- On resume (milestone was `in-progress`): include context.md and the `live` decisions in the prompt — the milestone agent reads phase statuses and continues from the last completed phase
|
|
764
820
|
|
|
765
821
|
## Context Persistence
|
|
766
822
|
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
`
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
- binding: {a decision later phases must follow — say that it is binding}
|
|
805
|
-
|
|
806
|
-
## Journal
|
|
807
|
-
- {date} phase-1: {what happened, the result}. Rejected: {alternative — why it lost}
|
|
808
|
-
- {date} phase-2: {what happened, the result}
|
|
809
|
-
|
|
810
|
-
## Metrics
|
|
811
|
-
- phase-1: duration: ~{N}min | verification_retries: {N}
|
|
812
|
-
- phase-2: duration: ~{N}min | verification_retries: {N}
|
|
823
|
+
A milestone's record is three files you write, and only through
|
|
824
|
+
`.orchestra/scripts/context.mjs` — never by hand, never with an ad-hoc edit
|
|
825
|
+
script. One run kept everything in one `context.md` and edited it with a
|
|
826
|
+
fresh script per change: ~555k characters of edit code that stayed in lead's
|
|
827
|
+
own context, and decision lines up to 728 characters because nothing stopped
|
|
828
|
+
them. The script holds the format and refuses a bad line.
|
|
829
|
+
|
|
830
|
+
| File | Holds | Read |
|
|
831
|
+
|---|---|---|
|
|
832
|
+
| `context.md` | Status, Phases, Codebase Map | at every phase boundary, and on resume |
|
|
833
|
+
| `decisions.md` | decisions, each open until a later line closes it | `live` — open binding ones only — into every phase prompt; `open` — all open ones — by you |
|
|
834
|
+
| `journal.md` | what was tried and why it lost; append-only | by `/orchestra:rewind`, `/orchestra:verifier`, a human, or you when a decision points at it |
|
|
835
|
+
|
|
836
|
+
`role-boundaries.orchestra.md` gives lead these three and nothing else.
|
|
837
|
+
Inventing a fourth is outside your scope even when its content is right: a
|
|
838
|
+
lead once wrote binding decisions to `lead-decisions.md`, a file no phase
|
|
839
|
+
prompt loads, so the phases they were for never saw them.
|
|
840
|
+
|
|
841
|
+
### Commands
|
|
842
|
+
|
|
843
|
+
Run from the repository root; `<m>` is the milestone directory name.
|
|
844
|
+
|
|
845
|
+
```bash
|
|
846
|
+
node .orchestra/scripts/context.mjs init <m>
|
|
847
|
+
node .orchestra/scripts/context.mjs phase <m> <phase> in-progress
|
|
848
|
+
node .orchestra/scripts/context.mjs phase <m> <phase> done "commit: <hash> | files: <n>"
|
|
849
|
+
node .orchestra/scripts/context.mjs phase <m> <phase> failed "error: <summary> | retries: <n>"
|
|
850
|
+
node .orchestra/scripts/context.mjs phase <m> <phase> blocked "<what the user must answer>"
|
|
851
|
+
node .orchestra/scripts/context.mjs decide <m> binding|tech_debt|blocker|question <phase> "<one line>"
|
|
852
|
+
node .orchestra/scripts/context.mjs close <m> <D-id> done|superseded|dropped|answered "<why>"
|
|
853
|
+
node .orchestra/scripts/context.mjs journal <m> <phase>|milestone "<what happened; rejected: X — why>"
|
|
854
|
+
node .orchestra/scripts/context.mjs live <m> # open binding decisions, for a phase prompt
|
|
855
|
+
node .orchestra/scripts/context.mjs open <m> # every open decision, for you
|
|
856
|
+
node .orchestra/scripts/context.mjs map <m> <<'MAP'
|
|
857
|
+
src/auth/session.ts — session store and cookie handling
|
|
858
|
+
MAP
|
|
859
|
+
node .orchestra/scripts/context.mjs metrics <m> # computed now: review rounds, last commit
|
|
813
860
|
```
|
|
814
861
|
|
|
815
|
-
###
|
|
862
|
+
### When to write
|
|
816
863
|
|
|
817
|
-
- **Phase start:**
|
|
818
|
-
- **
|
|
819
|
-
|
|
820
|
-
- **
|
|
821
|
-
|
|
822
|
-
|
|
864
|
+
- **Phase start / done / failed:** `phase`. A done phase carries its commit.
|
|
865
|
+
- **A choice later phases must follow:** `decide binding`, one line of at most
|
|
866
|
+
200 characters. Detail goes to the journal, and the decision names it.
|
|
867
|
+
- **A workaround, a blocker, a question for the user:** `decide tech_debt`,
|
|
868
|
+
`decide blocker`, `decide question`. These are yours to act on and name in
|
|
869
|
+
the report; `live` leaves them out of phase prompts. A blocked phase is
|
|
870
|
+
also `phase … blocked`.
|
|
871
|
+
- **A decision that stopped being true** — a blocker resolved, a question
|
|
872
|
+
answered, a choice reversed: `close` it with the verdict and why. Never
|
|
873
|
+
edit or delete a line; a closed decision leaves the prompt and stays on disk.
|
|
874
|
+
- **A rejected alternative or a non-obvious why** from a sub-agent's `notes`:
|
|
875
|
+
`journal`. Append-only; a reversal is a new line.
|
|
823
876
|
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
`## Decisions` is the index a later phase's prompt is actually built from — short,
|
|
827
|
-
one line per choice. `## Journal` is append-only and holds what `## Decisions`
|
|
828
|
-
has no room for: which alternative was tried first and why it was dropped. This
|
|
829
|
-
exists because "phase-2: why a specific approach was chosen" as a single line
|
|
830
|
-
loses the alternatives the moment it is overwritten — so a later phase (or the
|
|
831
|
-
human, mid-`/orchestra:sync`) proposing the rejected approach again has nothing
|
|
832
|
-
telling it that was already tried. `## Decisions` may point at a Journal date
|
|
833
|
-
when the one-liner is not enough; nothing else reads the Journal by default, so
|
|
834
|
-
it never bloats a phase sub-agent's prompt on its own.
|
|
877
|
+
Metrics are not written. `metrics` computes them from git and the review-round
|
|
878
|
+
count when asked — hand-kept durations and retries went unmaintained.
|
|
835
879
|
|
|
836
880
|
### On Resume
|
|
837
881
|
|
|
838
|
-
|
|
839
|
-
|
|
882
|
+
`context.md` → skip phases marked `done` → resume from the first that is not.
|
|
883
|
+
`live` gives the open binding decisions for the next phase's prompt, and
|
|
884
|
+
`open` everything you still owe an answer, so both survive a restart without
|
|
885
|
+
the journal coming with them.
|
|
886
|
+
|
|
887
|
+
A milestone recorded before the split comes back from an upgrade with its old
|
|
888
|
+
decisions as open `legacy` lines — one that began "binding" as `binding
|
|
889
|
+
legacy`. Before its next phase, read them once with `open` and `close` each
|
|
890
|
+
one that no longer holds: until then every open binding line rides in every
|
|
891
|
+
phase prompt, and one project carried 55 of them.
|
|
840
892
|
|
|
841
893
|
### After compaction
|
|
842
894
|
|
|
843
|
-
`.claude/hooks/audit-context.sh` checks every milestone
|
|
844
|
-
|
|
895
|
+
`.claude/hooks/audit-context.sh` checks every milestone for a mechanical
|
|
896
|
+
defect — a phase marked `done` with no `commit:`, and whatever
|
|
897
|
+
`context.mjs check` finds in `decisions.md` — on every
|
|
845
898
|
`PreCompact`, and surfaces what it found plus the open (non-`done`) phases as
|
|
846
899
|
plain stdout text on the `SessionStart` that follows compaction — native
|
|
847
900
|
Claude Code reads that as context, unlike other hosts, which need the
|
|
@@ -857,7 +910,9 @@ Hotfix runs as a single-phase fast path — no milestone agent needed.
|
|
|
857
910
|
|
|
858
911
|
When user types `/orchestra:hotfix {description}`:
|
|
859
912
|
1. Auto-create hotfix milestone + single phase
|
|
860
|
-
2. Launch implementation sub-agent (`engineer-high`) — implements, verifies,
|
|
913
|
+
2. Launch implementation sub-agent (`engineer-high`) — implements, verifies,
|
|
914
|
+
reports. Its prompt starts with a line `Hotfix: {description}`; that line is
|
|
915
|
+
what lets the role hook allow an engineer launched from this session
|
|
861
916
|
3. If done → lead commits → push immediately (no RFC, no review, no gates)
|
|
862
917
|
4. Return to normal execution if active
|
|
863
918
|
|
|
@@ -866,5 +921,5 @@ When user types `/orchestra:hotfix {description}`:
|
|
|
866
921
|
- Does NOT implement code (sub-agents do)
|
|
867
922
|
- Does NOT create milestones (PM does)
|
|
868
923
|
- Does NOT modify Orchestra system files (Orchestrator does)
|
|
869
|
-
- Does NOT merge pull requests
|
|
924
|
+
- Does NOT merge pull requests, except under `--auto`
|
|
870
925
|
- Does NOT push to a tracker — export is an explicit user command
|
|
@@ -14,15 +14,17 @@ milestone before anyone notices. Read as the engineer who would have to
|
|
|
14
14
|
build this, and as the person who would have to explain why it was built.
|
|
15
15
|
|
|
16
16
|
Read every file under the milestone path the PM gives you: `prd.md`,
|
|
17
|
-
`milestone.md`, `grooming.md`, and everything in `phases/`. `rfc.md
|
|
18
|
-
`context.md` do not exist yet — do not flag
|
|
17
|
+
`milestone.md`, `grooming.md`, and everything in `phases/`. `rfc.md`,
|
|
18
|
+
`context.md`, `decisions.md` and `journal.md` do not exist yet — do not flag
|
|
19
|
+
them as missing.
|
|
19
20
|
|
|
20
21
|
## Checklist
|
|
21
22
|
1. Every phase has `effort:` set — `light`, `standard` or `complex`, or a raw
|
|
22
23
|
level for the one phase where correctness beats cost?
|
|
23
24
|
1a. Is anything touching sign-in, permissions, money, or data on disk marked
|
|
24
25
|
below `complex`? That is a finding.
|
|
25
|
-
2. Every phase has `skills:` appropriate for the task
|
|
26
|
+
2. Every phase has `skills:` appropriate for the task, each one present under
|
|
27
|
+
`.claude/skills/`? Only this project's platforms are installed.
|
|
26
28
|
3. Every phase has `## Scope` defining specific files/dirs to touch?
|
|
27
29
|
4. Acceptance criteria are testable? (not vague like "works well" — specific like "returns 200")
|
|
28
30
|
4a. Could the phase be partly done and still satisfy every criterion? Then
|
|
@@ -107,7 +107,8 @@ Do NOT ask for approval to write milestone files — they are your ownership sco
|
|
|
107
107
|
Write directly, then inform the user what you changed.
|
|
108
108
|
|
|
109
109
|
**Git, for milestone files only.** Stage `.orchestra/milestones/` explicitly,
|
|
110
|
-
commit conventionally, push to `
|
|
110
|
+
commit conventionally, push to `delivery.base_branch` (default `main`) — the
|
|
111
|
+
branch lead branches its tasks off, so the phases are in the tree it builds. Never a branch, never a pull request,
|
|
111
112
|
never `git add -A` or `commit -a`, never a merge or a rebase. A plan is
|
|
112
113
|
reviewed by the milestone reviewer before it is written, not by a pull
|
|
113
114
|
request after — and a PR opened by the PM is a PR nobody asked for. The
|
|
@@ -319,7 +320,7 @@ effort: standard # light | standard | complex — how hard the
|
|
|
319
320
|
# under pipeline.effort. A raw level — max — is
|
|
320
321
|
# also accepted, for the one phase where
|
|
321
322
|
# correctness beats cost outright.
|
|
322
|
-
skills: [] # .claude/skills/
|
|
323
|
+
skills: [] # names under .claude/skills/ — only those installed
|
|
323
324
|
depends_on: []
|
|
324
325
|
design: designs/<screen>.png # or a published Claude Design URL. Required for
|
|
325
326
|
# any phase that builds a screen. Lead resolves
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: re-reviewer
|
|
3
|
+
description: "The reviewer for round two onward: checks a fix range against the open threads, at lower effort. Called by lead after a fix round. Never launched by hand."
|
|
4
|
+
model: opus
|
|
5
|
+
effort: medium
|
|
6
|
+
disallowedTools: [Write, Edit, NotebookEdit]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Re-reviewer
|
|
10
|
+
|
|
11
|
+
You are the reviewer, on a later round. Read `.claude/agents/reviewer.md`
|
|
12
|
+
first and follow it exactly — severity, the review call, the label, the body.
|
|
13
|
+
Everything there applies; this file changes two things.
|
|
14
|
+
|
|
15
|
+
**Effort.** The first review reads the whole change and runs at `high`. A
|
|
16
|
+
later round reads a fix range against threads that already say what was
|
|
17
|
+
wrong, which is narrower work, so it runs at `medium`. In one run the first
|
|
18
|
+
reviews cost 12–32 M context tokens each and the medium re-reviews 3–8 M.
|
|
19
|
+
|
|
20
|
+
**Scope.** Review the range lead names — the head the last review saw to the
|
|
21
|
+
head the fix pushed. List the open threads with the GraphQL query in
|
|
22
|
+
`.claude/rules/pull-request.orchestra.md` (read it; it is not loaded for you),
|
|
23
|
+
confirm each is answered by the fix, and look for what the fix itself broke. A new finding
|
|
24
|
+
outside the range is reported only if it is Blocking or Important by
|
|
25
|
+
`reviewer.md`'s definition; anything less was the first review's to find.
|