peaks-cli 1.2.3 → 1.2.5
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/dist/src/cli/commands/openspec-commands.js +31 -0
- package/dist/src/cli/commands/project-commands.js +51 -1
- package/dist/src/cli/commands/sop-commands.js +2 -2
- package/dist/src/cli/commands/workspace-commands.js +38 -4
- package/dist/src/services/memory/project-memory-service.d.ts +50 -0
- package/dist/src/services/memory/project-memory-service.js +412 -35
- package/dist/src/services/openspec/openspec-init-service.d.ts +23 -0
- package/dist/src/services/openspec/openspec-init-service.js +122 -0
- package/dist/src/services/session/index.d.ts +1 -1
- package/dist/src/services/session/index.js +1 -1
- package/dist/src/services/session/session-manager.d.ts +11 -0
- package/dist/src/services/session/session-manager.js +19 -0
- package/dist/src/services/skills/skill-presence-service.js +11 -0
- package/dist/src/services/sop/sop-check-service.d.ts +16 -0
- package/dist/src/services/sop/sop-check-service.js +35 -2
- package/dist/src/services/sop/sop-service.d.ts +8 -0
- package/dist/src/services/sop/sop-service.js +13 -2
- package/dist/src/services/sop/sop-types.d.ts +7 -0
- package/dist/src/services/workspace/workspace-service.d.ts +15 -0
- package/dist/src/services/workspace/workspace-service.js +60 -1
- package/dist/src/shared/version.d.ts +1 -1
- package/dist/src/shared/version.js +1 -1
- package/package.json +1 -1
- package/skills/peaks-prd/SKILL.md +36 -0
- package/skills/peaks-qa/SKILL.md +92 -2
- package/skills/peaks-rd/SKILL.md +70 -2
- package/skills/peaks-solo/SKILL.md +253 -40
- package/skills/peaks-solo/references/swarm-dispatch-contract.md +186 -0
- package/skills/peaks-sop/SKILL.md +17 -0
- package/skills/peaks-sop/references/sop-authoring.md +1 -1
- package/skills/peaks-txt/SKILL.md +16 -0
- package/skills/peaks-ui/SKILL.md +61 -2
|
@@ -9,6 +9,16 @@ Peaks-Cli Solo is the orchestration facade for the Peaks-Cli short skill family.
|
|
|
9
9
|
|
|
10
10
|
Use this skill to identify the user scenario, recommend an execution mode, coordinate role skills, and produce the final handoff report. Do not collapse role responsibilities into this skill.
|
|
11
11
|
|
|
12
|
+
## Skill-first architecture note (read once, internalise)
|
|
13
|
+
|
|
14
|
+
This skill is the **primary surface**. The `peaks <cmd>` CLI is **auxiliary** — invoked by the skill prompt when a primitive is the right tool (atomic side effect, machine-enforced gate, structured JSON for a downstream decision, or backstop the LLM cannot skip). Concretely:
|
|
15
|
+
|
|
16
|
+
- Behaviour that only an LLM in a skill prompt would use (e.g. "scan a handoff for memory blocks", "decide if a stable fact deserves persistence") lives **here in the SKILL.md**, not as a new CLI command.
|
|
17
|
+
- The CLI earns its keep when it is (a) hook- / script- / CI-invokable, (b) the consumer needs a structured JSON envelope to gate a downstream decision, or (c) it is a destructive side effect that needs an explicit `--apply` opt-in.
|
|
18
|
+
- When you reach for `peaks <X> --project <repo> --json` in a runbook step, that command is the **contract** you are calling; the LLM work around it (deciding what to pass, interpreting the response, deciding the next step) is what this skill owns.
|
|
19
|
+
|
|
20
|
+
See `.claude/rules/common/dev-preference.md` for the full dev policy and the decision template. The user-facing consequence: every iteration on this skill and the rest of the peaks-* family is judged first by "is this skill work or CLI work?", and only the latter opens a new command.
|
|
21
|
+
|
|
12
22
|
## Code-Change Red Line (BLOCKING — read before ANY tool call)
|
|
13
23
|
|
|
14
24
|
**Peaks-Cli Solo is an orchestrator, NOT an implementer. You MUST NOT write, edit, or modify any application source code directly.**
|
|
@@ -17,12 +27,12 @@ Every code change — bugfix, feature, refactor, or config — MUST go through t
|
|
|
17
27
|
|
|
18
28
|
```
|
|
19
29
|
peaks-solo (orchestrate only)
|
|
20
|
-
→
|
|
30
|
+
→ RD work ← ALL code changes happen HERE
|
|
21
31
|
→ Unit tests written + pass (Peaks-Cli Gate B2)
|
|
22
32
|
→ Karpathy standards enforced (file-size ≤800 lines, TypeScript rules)
|
|
23
33
|
→ Code review evidence (Peaks-Cli Gate B3)
|
|
24
34
|
→ Security review evidence (Peaks-Cli Gate B4)
|
|
25
|
-
→
|
|
35
|
+
→ QA work ← ALL validation happens HERE
|
|
26
36
|
→ Functional test execution (Peaks-Cli Gate A2)
|
|
27
37
|
→ Performance check (Peaks-Cli Gate A4)
|
|
28
38
|
→ Security test (Peaks-Cli Gate A3)
|
|
@@ -30,35 +40,83 @@ peaks-solo (orchestrate only)
|
|
|
30
40
|
→ Verdict: pass | return-to-rd | blocked
|
|
31
41
|
```
|
|
32
42
|
|
|
43
|
+
**Mechanism for "RD work" / "QA work" depends on the orchestration mode** (full details in "Peaks-Cli Swarm parallel phase" and "How Solo invokes another role"):
|
|
44
|
+
|
|
45
|
+
| Mode | Swarm side (after PRD) | Repair loop side (RD↔QA) |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| `full-auto` / `swarm` | `Task(subagent_type="general-purpose")` sub-agent running `peaks-rd`/`peaks-qa`/`peaks-ui` body | `Task(...)` sub-agent per cycle |
|
|
48
|
+
| `assisted` / `strict` / inline-fallback | Solo executes the role steps inline in the main loop (the `peaks-solo` skill IS the role's owner) | Solo executes inline |
|
|
49
|
+
|
|
50
|
+
In all modes, the work itself follows the same `peaks-rd` and `peaks-qa` contracts. The only difference is whether the role's body is being read by a sub-agent Task prompt or by Solo's own main loop. **Never bypass the role contracts regardless of which path runs.**
|
|
51
|
+
|
|
33
52
|
**Violations (BLOCKING — Solo must refuse to proceed):**
|
|
34
53
|
|
|
35
|
-
1. Writing implementation code directly instead of
|
|
36
|
-
2. Declaring work "done" without
|
|
54
|
+
1. Writing implementation code directly instead of routing through the RD contract (whether inline or via sub-agent)
|
|
55
|
+
2. Declaring work "done" without producing QA evidence after RD
|
|
37
56
|
3. Skipping unit tests ("it's a small change")
|
|
38
57
|
4. Skipping code review or security review
|
|
39
58
|
5. Skipping QA functional/performance/security validation
|
|
40
59
|
|
|
41
|
-
**If you catch yourself about to write code in this skill, STOP.
|
|
60
|
+
**If you catch yourself about to write code in this skill, STOP. Hand off to the RD contract path immediately** (sub-agent Task in full-auto, inline execution in assisted/strict).
|
|
42
61
|
|
|
43
62
|
**Before declaring workflow complete, run:** `peaks workflow verify-pipeline --rid <rid> --project <repo> --json`
|
|
44
63
|
|
|
45
64
|
## Peaks-Cli Startup sequence (MANDATORY — execute in order)
|
|
46
65
|
|
|
47
|
-
### Peaks-Cli Step 0:
|
|
66
|
+
### Peaks-Cli Step 0.5: OpenSpec first-run opt-in (conditional)
|
|
48
67
|
|
|
49
|
-
|
|
68
|
+
After the workspace is anchored, before project scan, Solo checks whether
|
|
69
|
+
the project already has an `openspec/` directory. The lifecycle
|
|
70
|
+
(`render → validate → show → to-rd → validate → archive`) only applies
|
|
71
|
+
when `openspec/` exists; without it, RD/QA/SC silently skip the
|
|
72
|
+
openspec-aware paths and you lose change-proposal tracking, commit
|
|
73
|
+
boundaries from `tasks.md`, and the historical archive.
|
|
74
|
+
|
|
75
|
+
To make that opt-in visible instead of silent, Solo runs:
|
|
50
76
|
|
|
51
77
|
```bash
|
|
52
|
-
#
|
|
53
|
-
|
|
54
|
-
|
|
78
|
+
# 1. Detect whether the project already has openspec/.
|
|
79
|
+
ls <repo>/openspec/changes 2>&1
|
|
80
|
+
# 2. If absent, ask the user once — only on the first Solo run in this
|
|
81
|
+
# project. The decision is sticky: write it to .peaks/.peaks-openspec-opt-in.json
|
|
82
|
+
# so subsequent Solo invocations do not re-ask.
|
|
83
|
+
test -f <repo>/.peaks/.peaks-openspec-opt-in.json || \
|
|
84
|
+
echo "{\"enabled\": <bool>}" > <repo>/.peaks/.peaks-openspec-opt-in.json
|
|
55
85
|
```
|
|
56
86
|
|
|
57
|
-
|
|
87
|
+
**AskUserQuestion** (only when `openspec/` is absent and the opt-in
|
|
88
|
+
file is missing):
|
|
89
|
+
|
|
90
|
+
| Option | What it does |
|
|
91
|
+
|---|---|
|
|
92
|
+
| Enable OpenSpec for this project (Recommended) | Run `peaks openspec init --project <repo> --apply`. After that, every Solo run uses the change-proposal lifecycle for the same project. |
|
|
93
|
+
| Skip for now | Do nothing. Solo proceeds without openspec; the question is re-asked on the next first-run detection. |
|
|
94
|
+
| Never ask again for this project | Write `{enabled: false, sticky: true}`. Solo stops asking. The user can re-enable later by removing `.peaks/.peaks-openspec-opt-in.json` and re-running. |
|
|
95
|
+
|
|
96
|
+
The first option is the recommended default because it gives Solo the
|
|
97
|
+
full change-proposal lifecycle (proposal / tasks / design / specs
|
|
98
|
+
deltas, archive on ship, commit boundaries from `tasks.md`). It costs
|
|
99
|
+
only a single scaffolded directory and pays back the first time the
|
|
100
|
+
project needs a real review trail.
|
|
101
|
+
|
|
102
|
+
If the user picks "Enable", the only required follow-up is to make
|
|
103
|
+
sure `openspec/changes/` is added to git (it is part of the project
|
|
104
|
+
repo, not a tool-managed artefact). Solo does not run `git add` for
|
|
105
|
+
the user; that is the user's commit boundary.
|
|
106
|
+
|
|
107
|
+
### Peaks-Cli Step 0: Anchor the workflow (MANDATORY FIRST ACTIONS — no bail-out)
|
|
108
|
+
|
|
109
|
+
The instant Peaks-Cli Solo is invoked, **before** the mode-selection question, before any analysis, and before you decide whether the request "needs" the full pipeline, you MUST run these two commands and see their output:
|
|
58
110
|
|
|
59
111
|
```bash
|
|
60
|
-
|
|
61
|
-
|
|
112
|
+
# Session ID is auto-generated when omitted; the command returns it in the JSON output.
|
|
113
|
+
# Do NOT pass --session-id manually — the CLI is the single source of truth for the
|
|
114
|
+
# project session binding. If you forge a session id with `openssl rand` and pass it
|
|
115
|
+
# via --session-id, peaks workspace init will write it to .peaks/.session.json but
|
|
116
|
+
# the binding only sticks if no prior session is open. To avoid the "two sessions
|
|
117
|
+
# in .peaks/" confusion that bites Solo, always omit --session-id here and let the
|
|
118
|
+
# CLI auto-generate.
|
|
119
|
+
peaks workspace init --project <repo> --json
|
|
62
120
|
peaks skill presence:set peaks-solo --project <repo> --gate startup
|
|
63
121
|
```
|
|
64
122
|
|
|
@@ -68,6 +126,9 @@ peaks skill presence:set peaks-solo --project <repo> --gate startup
|
|
|
68
126
|
|
|
69
127
|
**Anti-bail-out rule (BLOCKING):** You MUST NOT exit the peaks-solo workflow, hand control back, or produce a final answer before Step 0 has run. If you catch yourself thinking "this is just analysis, I don't need the workflow" — STOP. Run Step 0, set presence, then continue. A pure-analysis request runs the **lightweight analysis branch** (project scan + standards dry-run + handoff with a Standards-increment section), but it still anchors the workspace and keeps presence active. Declining to anchor is a workflow violation.
|
|
70
128
|
|
|
129
|
+
**Session conflict resolution (read once, internalise):** If `peaks workspace init` returns `code: "CONFLICTING_SESSION"` with a body like
|
|
130
|
+
`{"existingSessionId":"<Y>","requestedSessionId":"<X>"}`, the project is already bound to a different in-flight session `<Y>` (the one you or a prior run was working on). The fix is **NOT** to pass `--allow-session-rebind` to clobber `<Y>` — that destroys an active session's data. Instead: finish or abandon `<Y>` first (use `peaks session list --json` to see what it is, then `peaks session finish --id <Y>` or `peaks session abandon --id <Y>` — see your session command's help for the exact verbs). Only after `<Y>` is closed should you re-run `peaks workspace init`. The same rule applies to `peaks workspace init --session-id "<manually-forged>"` — do not pre-forge session ids; the CLI's auto-generated value is the binding.
|
|
131
|
+
|
|
71
132
|
`presence:set` accepts no `--mode` here on purpose — mode is unknown until Step 1. It is re-run with the selected mode in Step 2. Setting presence early guarantees the status header/line shows `peaks-solo` from the very first turn even if the user never reaches mode selection.
|
|
72
133
|
|
|
73
134
|
### Peaks-Cli Step 1: Mode selection
|
|
@@ -595,19 +656,112 @@ ls <repo>/.claude/rules/common/coding-style.md \
|
|
|
595
656
|
```
|
|
596
657
|
|
|
597
658
|
|
|
598
|
-
## Peaks-Cli Swarm parallel phase
|
|
659
|
+
## Peaks-Cli Swarm parallel phase (sub-agent fan-out, conditional)
|
|
660
|
+
|
|
661
|
+
The Swarm phase is **conditional**, not unconditional. It only runs when there is a real, user-confirmed requirement. Solo derives the fan-out set from the PRD type and the request content — never from a default of "always launch three".
|
|
662
|
+
|
|
663
|
+
### Swarm gate (decide BEFORE fan-out)
|
|
664
|
+
|
|
665
|
+
Before launching any sub-agent, Solo must compute the **swarm plan** from three signals:
|
|
666
|
+
|
|
667
|
+
1. **PRD state** — `prd/requests/<rid>.md` must be in state `confirmed-by-user` or `handed-off`. If not, STOP. The Swarm is downstream of PRD, not a substitute for it.
|
|
668
|
+
2. **Request type** (`--type` from `peaks request init`):
|
|
669
|
+
- `feature` / `refactor` / `bugfix` → RD(planning) and QA(test-cases) are always in the swarm
|
|
670
|
+
- `config` / `docs` / `chore` → no swarm. RD/QA artefacts are not required by Gates B/C/D for these types. Skip the Swarm phase entirely and proceed to step 4 (RD implementation) with only the PRD in hand.
|
|
671
|
+
3. **Frontend touch** — does the request affect user-visible behavior? This is decided by:
|
|
672
|
+
- Reading `.peaks/<session-id>/rd/project-scan.md` `## Project mode` for `frontendOnly` (project-shape signal)
|
|
673
|
+
- **AND** scanning the PRD body for frontend keywords: 页面 / 组件 / 表单 / 弹窗 / 表格 / 样式 / 布局 / 交互 / UI / UX / page / component / form / modal / table / styling / layout / interaction
|
|
674
|
+
- UI joins the swarm when (a) is `true` OR (b) matches. Both signals required `false` to skip UI.
|
|
675
|
+
|
|
676
|
+
Solo records the swarm plan in `.peaks/<session-id>/sc/swarm-plan.json` so SC and TXT can audit what was launched:
|
|
677
|
+
|
|
678
|
+
```json
|
|
679
|
+
{
|
|
680
|
+
"rid": "<rid>",
|
|
681
|
+
"type": "feature",
|
|
682
|
+
"frontendOnly": true,
|
|
683
|
+
"frontendKeywordHit": true,
|
|
684
|
+
"subAgents": ["ui", "rd-planning", "qa-test-cases"]
|
|
685
|
+
}
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
Sub-agent presence in this list = Solo launched a Task for it. Absence = the role was skipped with documented reason.
|
|
689
|
+
|
|
690
|
+
### Mode-driven fan-out shape
|
|
691
|
+
|
|
692
|
+
| Mode | How the swarm plan is decided | What Solo does |
|
|
693
|
+
|---|---|---|
|
|
694
|
+
| `full-auto` | Compute plan from signals above, no question to user | Auto-launch all sub-agents in the plan in parallel |
|
|
695
|
+
| `swarm` | Same as `full-auto` | Same as `full-auto` (this profile name is historical — behavior is identical) |
|
|
696
|
+
| `assisted` | `AskUserQuestion` with three options: (a) Full — UI + RD(planning) + QA(test-cases); (b) Backend-only — RD(planning) + QA(test-cases); (c) Sequential — run RD first, then QA, skip UI | Use the user's choice as the plan |
|
|
697
|
+
| `strict` | Same as `assisted` (the question is informational; strict still enforces confirmation gates later) | Same as `assisted` |
|
|
698
|
+
|
|
699
|
+
In all modes, **the plan must be written to `sc/swarm-plan.json` before any Task call.** Solo updates `.peaks/.active-skill.json` to `gate=swarm-fan-out` at this point.
|
|
700
|
+
|
|
701
|
+
### Sub-agent mechanism (Task tool, NOT Skill tool)
|
|
702
|
+
|
|
703
|
+
**Solo is itself a skill running in the current session. To invoke a role in the Swarm, Solo MUST use the `Task` tool with `subagent_type="general-purpose"` and a prompt that embeds the role's contract — NOT the `Skill` tool.** The `Skill` tool is single-stack and blocking; using it for "parallel" work was the v1.x illusion of concurrency. The Task tool is the only mechanism that gives real fan-out in Claude Code.
|
|
704
|
+
|
|
705
|
+
Each sub-agent Task call looks like:
|
|
706
|
+
|
|
707
|
+
```
|
|
708
|
+
Task(
|
|
709
|
+
subagent_type="general-purpose",
|
|
710
|
+
description="<role> for rid=<rid>",
|
|
711
|
+
prompt="<paste peaks-<role>/SKILL.md body, minus the self-presence / Step 0 blocks, plus
|
|
712
|
+
the runtime arguments: project=<repo>, session-id=<sid>, request-id=<rid>, mode=<mode>>
|
|
713
|
+
plus the explicit output contract: 'Write your artefacts to the paths listed below and
|
|
714
|
+
return only the list of paths. Do not call Skill(...). Do not set presence. Do not
|
|
715
|
+
hand back prose.'"
|
|
716
|
+
)
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
The role's required artefact paths (also see peaks-ui/rd/qa SKILL.md and `references/swarm-dispatch-contract.md`):
|
|
720
|
+
|
|
721
|
+
| Role | Writes | Reads (PRD-side) |
|
|
722
|
+
|---|---|---|
|
|
723
|
+
| `ui` | `.peaks/<sid>/ui/design-draft.md`, `.peaks/<sid>/ui/requests/<rid>.md` | PRD body, project-scan, archetype |
|
|
724
|
+
| `rd-planning` | `.peaks/<sid>/rd/tech-doc.md` (feature/refactor) or `.peaks/<sid>/rd/bug-analysis.md` (bugfix) | PRD body, project-scan, existing-system, codegraph |
|
|
725
|
+
| `qa-test-cases` | `.peaks/<sid>/qa/test-cases/<rid>.md` | PRD body, RD planning artefact, project-scan, codegraph |
|
|
726
|
+
|
|
727
|
+
**Solo launches all sub-agents in the swarm plan in a single message (multiple Task tool calls in parallel)** — this is what gives real concurrency. Do not sequentialize them. Solo then waits for all to return, runs `ls` checks against the paths above (Peaks-Cli Gate B), and only then advances to RD implementation.
|
|
728
|
+
|
|
729
|
+
**Hard prohibitions on sub-agents** (also passed in each Task prompt):
|
|
730
|
+
|
|
731
|
+
- Do NOT call `Skill(skill="...")` — sub-agents must not recursively activate skills, that defeats the fan-out.
|
|
732
|
+
- Do NOT call `peaks skill presence:set` — only the main Solo loop owns `.peaks/.active-skill.json`. Sub-agents write to a per-agent marker file `.peaks/<sid>/system/sub-agent-<role>.json` if they need to record state, but never the main presence file.
|
|
733
|
+
- Do NOT open interactive user prompts. If a sub-agent needs clarification, it must return a `blocked` verdict in its return string and let Solo handle the user message.
|
|
734
|
+
- Do NOT commit, push, install hooks, or apply settings.json mutations. Only Solo holds those permissions.
|
|
735
|
+
|
|
736
|
+
After every sub-agent Task returns, Solo **restores presence** once (not per-agent), then continues to Gate B verification:
|
|
737
|
+
|
|
738
|
+
```bash
|
|
739
|
+
peaks skill presence:set peaks-solo --project <repo> --mode <mode> --gate swarm-converged
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
### Degradation when swarm roles fail or are absent
|
|
743
|
+
|
|
744
|
+
| Condition | Solo action | TXT handoff note |
|
|
745
|
+
|---|---|---|
|
|
746
|
+
| UI sub-agent returns blocked/error | RD continues with PRD visual descriptions | `ui-design-missing` |
|
|
747
|
+
| RD planning sub-agent returns blocked/error | RD continues with PRD-derived planning | `tech-doc-missing` |
|
|
748
|
+
| QA test-cases sub-agent returns blocked/error | RD continues; QA backfills test cases before verdict | `qa-test-cases-missing` |
|
|
749
|
+
| Two or more of the above | Fall back to sequential: `peaks request transition rd → spec-locked` then inline RD run, then QA | `swarm-degraded-to-sequential` |
|
|
750
|
+
| All three fail | Pause workflow; surface to user; request confirmation to continue | `swarm-aborted` |
|
|
751
|
+
|
|
752
|
+
Skipping the entire swarm (when `--type` is `config|docs|chore`) is not a degradation — record `swarm-skipped: type=<type>` and proceed.
|
|
599
753
|
|
|
600
|
-
|
|
754
|
+
### Frontend-only trigger pre-flight
|
|
601
755
|
|
|
602
|
-
|
|
756
|
+
Before computing the swarm plan, Solo runs the keyword scan deterministically:
|
|
603
757
|
|
|
604
|
-
1.
|
|
605
|
-
2.
|
|
606
|
-
3.
|
|
607
|
-
4.
|
|
608
|
-
5.
|
|
758
|
+
1. Read `.peaks/<session-id>/prd/requests/<rid>.md` body.
|
|
759
|
+
2. Lowercase + strip markdown; check regex `\b(页面|组件|表单|弹窗|表格|样式|布局|交互|UI|UX|page|component|form|modal|table|styling|layout|interaction|frontend|前端)\b`.
|
|
760
|
+
3. If match count ≥ 1 → `frontendKeywordHit=true`.
|
|
761
|
+
4. If `frontendOnly` (from project-scan) is `true` and no keyword hit → UI joins anyway (frontend-only project, even non-visual changes may need visual sanity for regressions).
|
|
762
|
+
5. If `frontendOnly` is `false` and no keyword hit → UI skipped.
|
|
609
763
|
|
|
610
|
-
|
|
764
|
+
Solo records the pre-flight result in `sc/swarm-plan.json` so the audit trail shows why UI was or was not included.
|
|
611
765
|
|
|
612
766
|
## Peaks-Cli Mandatory RD QA repair loop (AUTO-PROCEED)
|
|
613
767
|
|
|
@@ -622,19 +776,24 @@ After PRD reaches `confirmed-by-user`, Solo launches peaks-ui, peaks-rd(planning
|
|
|
622
776
|
|
|
623
777
|
After `peaks-rd` finishes any implementation, repair, or code-output slice, Peaks-Cli Solo MUST automatically route the result to `peaks-qa` without waiting for user confirmation. This is not optional in full-auto mode. Solo must not declare the workflow complete, emit a TXT handoff, or stop at RD completion.
|
|
624
778
|
|
|
625
|
-
**How Solo invokes another role
|
|
779
|
+
**How Solo invokes another role (mechanism, not metaphor):**
|
|
780
|
+
|
|
781
|
+
Solo is itself a skill running in the current session. There are **two distinct mechanisms** in this skill, and they MUST NOT be confused:
|
|
782
|
+
|
|
783
|
+
1. **Swarm fan-out (planning side, after PRD confirmed)** — uses the `Task` tool with `subagent_type="general-purpose"` to launch real concurrent sub-agents. See "Peaks-Cli Swarm parallel phase" above for the full contract. Sub-agents do NOT call Skill(...) back into the role; they execute the role's instructions inline from the prompt.
|
|
784
|
+
2. **Sequential handoff (execution side, RD↔QA repair loop)** — Solo is the only loop, and after RD or QA finishes (whether as a sub-agent or directly), Solo drives the next step from the orchestrator seat. Do NOT use the `Skill` tool to "reactivate" peaks-rd or peaks-qa in the main loop; doing so is the v1.x anti-pattern that masqueraded as "calling the role" but actually just re-prompted the same session. From v1.3 onward, the main loop drives roles via the CLI gate (`peaks request transition`) and reads back artefacts (`peaks request show ... --json`); the actual RD/QA work is either done inline by Solo (when Solo has just been re-invoked by the user) or by a Task sub-agent (in swarm mode).
|
|
626
785
|
|
|
627
|
-
|
|
786
|
+
After RD completes (whether inline or sub-agent), Solo does not stop — it must advance to QA. There is no "RD done, ask the user" state in full-auto mode. The only valid stops are: (a) QA verdict=pass, (b) repair cap hit, (c) explicit user cancel.
|
|
628
787
|
|
|
629
|
-
**Presence restoration after
|
|
788
|
+
**Presence restoration after RD/QA work returns (MANDATORY):** In v1.x, role skills called `peaks skill presence:set <role>` internally and stomped on `.peaks/.active-skill.json`. From v1.3 onward, sub-agents in the Swarm path are forbidden from calling `peaks skill presence:set` (see "Sub-agent dispatch" in each role's SKILL.md), so the main loop's presence file is preserved across the fan-out window by construction. The one place Solo still has to actively restore presence is **once after the fan-out returns** (gate=swarm-converged) and again **after each RD↔QA repair iteration** (gate=repair-cycle-<N>). Use the same command from Step 2 with the current mode and the gate that has just advanced:
|
|
630
789
|
|
|
631
790
|
```bash
|
|
632
791
|
peaks skill presence:set peaks-solo --project <repo> --mode <mode> --gate <current-gate>
|
|
633
792
|
```
|
|
634
793
|
|
|
635
|
-
This keeps the CLAUDE.md status header accurate (`Peaks-Cli Skill: peaks-solo`) instead of showing a stale role name. Use the current mode and gate values; the gate may have advanced since startup. Skipping this step causes the header to display the last
|
|
794
|
+
This keeps the CLAUDE.md status header accurate (`Peaks-Cli Skill: peaks-solo`) instead of showing a stale role name. Use the current mode and gate values; the gate may have advanced since startup. Skipping this step causes the header to display the last-known gate permanently.
|
|
636
795
|
|
|
637
|
-
**Full-auto auto-proceed rule**: In the `full-auto` profile, when RD transitions to `qa-handoff`, Solo immediately
|
|
796
|
+
**Full-auto auto-proceed rule**: In the `full-auto` profile, when RD transitions to `qa-handoff`, Solo immediately drives QA — by launching a `Task(subagent_type="general-purpose", ...)` sub-agent carrying the `peaks-qa` body (swarm path), or by running QA inline in the main loop (assisted/strict path). Do not pause, do not ask the user, do not summarize RD results as if they were final. The only valid reason to skip QA is when `--type` is `docs` or `chore` (no acceptance surface).
|
|
638
797
|
|
|
639
798
|
A QA report with any failing, blocked, missing, or unverified acceptance item is not a pass.
|
|
640
799
|
|
|
@@ -650,9 +809,12 @@ When `peaks-qa` returns `verdict=return-to-rd`, Solo does NOT manually rewrite R
|
|
|
650
809
|
--project <repo> --json
|
|
651
810
|
```
|
|
652
811
|
`spec-locked` is the canonical "needs more RD work" state. The reason is mandatory in repair cycles so the artifact history shows the loop.
|
|
653
|
-
3.
|
|
812
|
+
3. Re-launch `peaks-rd` work. Two paths, mode-driven:
|
|
813
|
+
- **Swarm / full-auto**: launch a fresh `Task(subagent_type="general-purpose", ...)` sub-agent with the same `peaks-rd` body used in the Swarm phase, plus the QA findings path so it can read the failure list. Solo restores presence after the sub-agent returns.
|
|
814
|
+
- **Assisted / strict / inline-fallback**: Solo executes the RD repair steps directly in the main loop, since there is no concurrent fan-out to coordinate.
|
|
815
|
+
In both paths, pass the QA findings path so the repair sees what failed.
|
|
654
816
|
4. peaks-rd fixes the reported issues only (red-line scope: do not modify unrelated surfaces), regenerates code-review and security-review evidence if changes touched reviewed surfaces, then transitions `rd → implemented → qa-handoff` again.
|
|
655
|
-
5. Solo
|
|
817
|
+
5. Solo re-runs QA (sub-agent Task in swarm/full-auto, inline in assisted/strict) with the same `<request-id>`. QA re-runs gates against the new diff.
|
|
656
818
|
6. Repeat steps 1-5 until QA returns `verdict=pass`, or the cap below fires.
|
|
657
819
|
**After each repair iteration** (after peaks-rd and peaks-qa both return), Solo MUST restore presence:
|
|
658
820
|
```bash
|
|
@@ -707,14 +869,40 @@ peaks request lint <rid> --role prd --project <repo> --json
|
|
|
707
869
|
peaks request transition <rid> --role prd --state confirmed-by-user --project <repo> --json
|
|
708
870
|
peaks request transition <rid> --role prd --state handed-off --project <repo> --json
|
|
709
871
|
|
|
710
|
-
# 3. Peaks-Cli Swarm parallel —
|
|
711
|
-
#
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
872
|
+
# 3. Peaks-Cli Swarm parallel — sub-agent fan-out (Task tool, NOT Skill tool)
|
|
873
|
+
# Solo computes the swarm plan from --type + frontendOnly + frontend-keyword scan,
|
|
874
|
+
# writes it to .peaks/<sid>/sc/swarm-plan.json, then launches one
|
|
875
|
+
# Task(subagent_type="general-purpose", ...) call per sub-agent in the same message.
|
|
876
|
+
# See "Peaks-Cli Swarm parallel phase" above for the full decision table and the
|
|
877
|
+
# prompt template; the role's required artefact paths are listed there.
|
|
878
|
+
# Hard rule: do NOT call Skill(skill="peaks-rd" | "peaks-qa" | "peaks-ui") from
|
|
879
|
+
# the Swarm phase — that's the v1.x anti-pattern.
|
|
880
|
+
#
|
|
881
|
+
# 3a. Pre-fan-out: Solo initialises every role's request artefact slot in the main
|
|
882
|
+
# loop so sub-agents find a stable rid <-> artefact binding. Each role's
|
|
883
|
+
# sub-agent may also call peaks request init itself (idempotent on the same rid);
|
|
884
|
+
# Solo's call here is the source of truth. Only init roles that are in the
|
|
885
|
+
# swarm plan — roles not in the plan do not get a slot yet.
|
|
886
|
+
peaks skill presence:set peaks-solo --project <repo> --mode <mode> --gate swarm-fan-out
|
|
887
|
+
# for each role in swarm-plan.subAgents:
|
|
888
|
+
# peaks request init --role ui --id <rid> --project <repo> --apply --type <type> --json
|
|
889
|
+
# peaks request init --role rd --id <rid> --project <repo> --apply --type <type> --json
|
|
890
|
+
# peaks request init --role qa --id <rid> --project <repo> --apply --type <type> --json
|
|
891
|
+
# e.g. if plan = [ui, rd, qa]: run init for ui, rd, qa.
|
|
892
|
+
# If plan = [rd, qa]: run for rd, qa only.
|
|
893
|
+
# If plan = [] (config|docs|chore skip): no inits here, jump to step 4 directly.
|
|
894
|
+
# 3b. Solo issues N Task(subagent_type="general-purpose", ...) calls in ONE message
|
|
895
|
+
# (N = len(swarm-plan.subAgents)). Each prompt embeds the role's body minus
|
|
896
|
+
# Step 0 / presence, plus the runtime args (rid / sid / mode / type / paths).
|
|
897
|
+
# 3c. After fan-out, Solo restores presence once and runs Gate B (ls checks):
|
|
898
|
+
peaks skill presence:set peaks-solo --project <repo> --mode <mode> --gate swarm-converged
|
|
899
|
+
ls .peaks/<sid>/prd/requests/<rid>.md # PRD artefact must exist (Gate B hard)
|
|
900
|
+
# feature / refactor → ls .peaks/<sid>/rd/tech-doc.md
|
|
901
|
+
# bugfix → ls .peaks/<sid>/rd/bug-analysis.md
|
|
902
|
+
ls .peaks/<sid>/qa/test-cases/<rid>.md # QA test-cases (skipped for docs|chore)
|
|
903
|
+
# ui (only when in plan):
|
|
904
|
+
ls .peaks/<sid>/ui/design-draft.md 2>&1 # non-blocking (Gate B info)
|
|
905
|
+
# Apply the degradation rules in the main SKILL.md if any artefact is missing.
|
|
718
906
|
# → Peaks-Cli Gate B convergence check. Assisted/Strict: [CONFIRM]
|
|
719
907
|
|
|
720
908
|
# 4. Peaks-Cli RD planning artifact (the file required by the prerequisite gate)
|
|
@@ -762,10 +950,30 @@ peaks openspec validate <cid> --project <repo> --json
|
|
|
762
950
|
peaks openspec archive <cid> --project <repo> --apply --json
|
|
763
951
|
|
|
764
952
|
# 10. Peaks-Cli TXT handoff — invoke peaks-txt which embeds memory markers and extracts
|
|
765
|
-
# peaks-txt writes the handoff capsule to .peaks/<id>/txt/handoff.md
|
|
766
|
-
# <!-- peaks-memory:start --> blocks
|
|
767
|
-
#
|
|
953
|
+
# peaks-txt writes the handoff capsule to .peaks/<id>/txt/handoff.md. Inside the
|
|
954
|
+
# capsule body, peaks-txt embeds <!-- peaks-memory:start --> blocks for every
|
|
955
|
+
# stable project fact surfaced this session.
|
|
956
|
+
#
|
|
957
|
+
# 10a. Skill-side scan (do this BEFORE the AskUserQuestion below):
|
|
958
|
+
# grep -n "peaks-memory:start" .peaks/<id>/txt/handoff.md
|
|
959
|
+
# Record the count. This is the skill doing the work, not a CLI command —
|
|
960
|
+
# we deliberately do not ship a `peaks memory scan` because the LLM is
|
|
961
|
+
# the only consumer and the LLM has grep.
|
|
962
|
+
|
|
963
|
+
# 10b. AskUserQuestion (only if 10a returned count >= 1):
|
|
964
|
+
# "The TXT handoff has N peaks-memory:start blocks. Persist to .peaks/memory/?
|
|
965
|
+
# (a) Apply all — `peaks memory extract --project <repo>
|
|
966
|
+
# --artifact .peaks/<id>/txt/handoff.md --apply --json`
|
|
967
|
+
# (b) Apply selectively — re-edit handoff.md first, then re-apply
|
|
968
|
+
# (c) Skip for now — blocks stay in the handoff only, no .peaks/memory/ write"
|
|
969
|
+
# If 10a returned 0 AND the session surfaced a stable project fact
|
|
970
|
+
# (decision / convention / approved refactor), STOP — peaks-txt must go
|
|
971
|
+
# back and embed at least one block before Solo can advance.
|
|
972
|
+
|
|
973
|
+
# 10c. After the user picks (a) or (b), run:
|
|
768
974
|
peaks memory extract --project <repo> --artifact .peaks/<id>/txt/handoff.md --apply --json
|
|
975
|
+
# --apply is REQUIRED to write .peaks/memory/; without it the command only
|
|
976
|
+
# previews. The extract regenerates index.json in the same call.
|
|
769
977
|
|
|
770
978
|
# 11. Peaks-Cli Final snapshot
|
|
771
979
|
peaks project dashboard --project <repo> --json
|
|
@@ -836,6 +1044,11 @@ Use Peaks-Cli TXT for the compact handoff capsule: mode, validated decisions, ar
|
|
|
836
1044
|
|
|
837
1045
|
Do NOT call `peaks skill presence:clear --project <repo>` at workflow end. The presence file and header remain active so the user stays inside the workflow context. The user can continue with follow-up requirements naturally — no need to re-invoke `/peaks-solo`. The header continues to display the active skill and current gate.
|
|
838
1046
|
|
|
1047
|
+
Before ending, extract durable memories from this session:
|
|
1048
|
+
```bash
|
|
1049
|
+
peaks project memories:extract --session-id <session-id> --project <repo> --json
|
|
1050
|
+
```
|
|
1051
|
+
|
|
839
1052
|
## Peaks-Cli External references and lifecycle
|
|
840
1053
|
|
|
841
1054
|
**Codegraph**: Optional project-analysis before RD handoff. Use `peaks codegraph affected --project <path> <changed-files...> --json` for regression-surface hints. Output as untrusted supporting evidence only; never commit `.codegraph/` artifacts.
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# Swarm dispatch contract
|
|
2
|
+
|
|
3
|
+
> Reference for `peaks-solo` Swarm phase and the role sub-agents (`peaks-ui` / `peaks-rd` planning / `peaks-qa` test-cases). Defines the **mechanism** of fan-out: how Solo launches sub-agents, what the sub-agent prompt must contain, what the sub-agent must return, and how Solo reduces the result.
|
|
4
|
+
|
|
5
|
+
## 1. Why this exists
|
|
6
|
+
|
|
7
|
+
The previous "Swarm" used `Skill(skill="peaks-rd")` calls. That is **single-stack and blocking** — there is no concurrency. Three sequential `Skill` calls run in order on the same main loop, not in parallel. The "parallel Agent calls" wording in the old SKILL.md was a v1.x illusion.
|
|
8
|
+
|
|
9
|
+
This contract moves the Swarm to the `Task` tool with `subagent_type="general-purpose"`, which is the only Claude Code mechanism that gives real concurrent fan-out. Solo launches all sub-agents in a single message; the platform schedules them concurrently.
|
|
10
|
+
|
|
11
|
+
## 2. When to swarm (decision)
|
|
12
|
+
|
|
13
|
+
Solo runs the swarm only after `peaks request show <rid> --role prd` is in state `confirmed-by-user` or `handed-off`. Before that, there is nothing for the sub-agents to derive from.
|
|
14
|
+
|
|
15
|
+
Solo computes the **swarm plan** from three signals (see "Swarm gate" in the main SKILL.md):
|
|
16
|
+
|
|
17
|
+
1. `--type` from `peaks request init` (already on the PRD artefact).
|
|
18
|
+
2. `frontendOnly` from `.peaks/<session-id>/rd/project-scan.md` `## Project mode`.
|
|
19
|
+
3. Frontend keyword scan over the PRD body.
|
|
20
|
+
|
|
21
|
+
The plan is written to `.peaks/<session-id>/sc/swarm-plan.json` before any Task call, so SC and TXT can audit what was launched. Solo updates `.peaks/.active-skill.json` to `gate=swarm-fan-out` at this point.
|
|
22
|
+
|
|
23
|
+
| `--type` | Frontend signal | Plan |
|
|
24
|
+
|---|---|---|
|
|
25
|
+
| `feature` / `refactor` / `bugfix` | keyword hit OR `frontendOnly=true` | `[ui, rd-planning, qa-test-cases]` |
|
|
26
|
+
| `feature` / `refactor` / `bugfix` | no keyword hit AND `frontendOnly=false` | `[rd-planning, qa-test-cases]` |
|
|
27
|
+
| `config` / `docs` / `chore` | (any) | `[]` (swarm skipped, recorded in plan) |
|
|
28
|
+
|
|
29
|
+
In `assisted` and `strict` modes, Solo replaces signal (3) with a three-option `AskUserQuestion` (see "Mode-driven fan-out shape" in the main SKILL.md) and uses the user's choice as the plan.
|
|
30
|
+
|
|
31
|
+
## 3. Sub-agent invocation template
|
|
32
|
+
|
|
33
|
+
Solo emits one Task call per sub-agent in the plan, all in the same message:
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
Task({
|
|
37
|
+
subagent_type: "general-purpose",
|
|
38
|
+
description: "<role> for rid=<rid>",
|
|
39
|
+
prompt: <see role-specific sections below>
|
|
40
|
+
})
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 3.1 Common prompt header (all sub-agents)
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
You are a sub-agent invoked by peaks-solo. You are NOT the main Claude session.
|
|
47
|
+
Your job: execute ONE role from the peaks skill family and write its artefact(s).
|
|
48
|
+
Return a compact JSON envelope — do not write prose.
|
|
49
|
+
|
|
50
|
+
## Hard prohibitions
|
|
51
|
+
- Do NOT call Skill(skill="..."). You are the role.
|
|
52
|
+
- Do NOT call `peaks skill presence:set` — the main loop owns .peaks/.active-skill.json.
|
|
53
|
+
If you need to record state, write to .peaks/<session-id>/system/sub-agent-<role>.json.
|
|
54
|
+
- Do NOT commit, push, install hooks, or apply settings.json mutations.
|
|
55
|
+
- Do NOT ask the user interactive questions. If you need clarification, return
|
|
56
|
+
{"status":"blocked","blockedReason":"<text>"} and let the main loop handle it.
|
|
57
|
+
|
|
58
|
+
## Runtime arguments (provided by Solo)
|
|
59
|
+
- project: <repo> (git repo root, NOT a sub-package)
|
|
60
|
+
- session-id: <sid> (from .peaks/.active-skill.json or .peaks/.session.json)
|
|
61
|
+
- request-id: <rid> (PRD id)
|
|
62
|
+
- type: <type> (feature | bugfix | refactor | config | docs | chore)
|
|
63
|
+
- mode: <mode> (full-auto | swarm | assisted | strict)
|
|
64
|
+
- project-scan-path: <path> (read this for component library / CSS / build tool)
|
|
65
|
+
- existing-system-path: <path> (legacy projects only)
|
|
66
|
+
- frontendOnly: <bool> (from project-scan)
|
|
67
|
+
- frontendKeywordHit: <bool> (Solo's PRD scan result)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 3.2 peaks-ui sub-agent prompt
|
|
71
|
+
|
|
72
|
+
Append after the common header:
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
## Role: UI design direction
|
|
76
|
+
You are running peaks-ui. Produce design direction, not code. RD will implement.
|
|
77
|
+
|
|
78
|
+
Steps:
|
|
79
|
+
1. peaks request init --role ui --id <rid> --project <repo> --apply --type <type> --json
|
|
80
|
+
2. peaks request show <rid> --role prd --project <repo> --json
|
|
81
|
+
3. Read <project-scan-path> for component library / CSS framework.
|
|
82
|
+
4. Run the prototype fidelity gate: Figma file? PRD visuals? Headed browser?
|
|
83
|
+
5. Write TWO artefacts:
|
|
84
|
+
- .peaks/<sid>/ui/design-draft.md
|
|
85
|
+
- .peaks/<sid>/ui/requests/<rid>.md
|
|
86
|
+
6. Return:
|
|
87
|
+
{
|
|
88
|
+
"role": "ui",
|
|
89
|
+
"rid": "<rid>",
|
|
90
|
+
"status": "ok" | "blocked" | "skipped",
|
|
91
|
+
"artefacts": [".peaks/<sid>/ui/design-draft.md", ".peaks/<sid>/ui/requests/<rid>.md"],
|
|
92
|
+
"warnings": [],
|
|
93
|
+
"blockedReason": null
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
If you determine the request is non-visual (no UI surface, no design impact),
|
|
97
|
+
return {"status":"skipped","reason":"non-frontend-request"} so Solo can record
|
|
98
|
+
the misfire in sc/swarm-plan.json.
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### 3.3 peaks-rd (planning) sub-agent prompt
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
## Role: RD planning
|
|
105
|
+
You are running peaks-rd's planning step. Produce the planning artefact, not code.
|
|
106
|
+
Code is written in a later sub-agent or inline run.
|
|
107
|
+
|
|
108
|
+
Steps:
|
|
109
|
+
1. peaks request init --role rd --id <rid> --project <repo> --apply --type <type> --json
|
|
110
|
+
2. peaks request show <rid> --role prd --project <repo> --json
|
|
111
|
+
3. peaks request show <rid> --role ui --project <repo> --json (if ui in plan)
|
|
112
|
+
4. Read <project-scan-path>. If absent and Solo did not pre-create it, create it
|
|
113
|
+
by running `peaks scan archetype --project <repo> --json` and copying the JSON
|
|
114
|
+
into rd/project-scan.md.
|
|
115
|
+
5. Read <existing-system-path> if archetype is legacy-*.
|
|
116
|
+
6. Write the type-appropriate planning artefact:
|
|
117
|
+
- feature | refactor → .peaks/<sid>/rd/tech-doc.md
|
|
118
|
+
- bugfix → .peaks/<sid>/rd/bug-analysis.md
|
|
119
|
+
- config | docs | chore → no planning artefact required. Return skipped.
|
|
120
|
+
7. Return:
|
|
121
|
+
{
|
|
122
|
+
"role": "rd-planning",
|
|
123
|
+
"rid": "<rid>",
|
|
124
|
+
"status": "ok" | "blocked" | "skipped",
|
|
125
|
+
"artefacts": [".peaks/<sid>/rd/tech-doc.md"], // or [] when skipped
|
|
126
|
+
"warnings": [],
|
|
127
|
+
"blockedReason": null
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### 3.4 peaks-qa (test-cases) sub-agent prompt
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
## Role: QA test-case generation (planning, not execution)
|
|
135
|
+
You are running peaks-qa's planning step. Produce test cases, do NOT execute them.
|
|
136
|
+
The execution step runs after RD implementation in a separate sub-agent.
|
|
137
|
+
|
|
138
|
+
Steps:
|
|
139
|
+
1. peaks request init --role qa --id <rid> --project <repo> --apply --type <type> --json
|
|
140
|
+
2. peaks request show <rid> --role prd --project <repo> --json
|
|
141
|
+
3. peaks request show <rid> --role rd --project <repo> --json
|
|
142
|
+
4. Read <project-scan-path>.
|
|
143
|
+
5. Write .peaks/<sid>/qa/test-cases/<rid>.md with test cases linked to PRD
|
|
144
|
+
acceptance items (use **Acceptance:** A1, A2 style).
|
|
145
|
+
6. Return:
|
|
146
|
+
{
|
|
147
|
+
"role": "qa-test-cases",
|
|
148
|
+
"rid": "<rid>",
|
|
149
|
+
"status": "ok" | "blocked" | "skipped",
|
|
150
|
+
"artefacts": [".peaks/<sid>/qa/test-cases/<rid>.md"],
|
|
151
|
+
"warnings": [],
|
|
152
|
+
"blockedReason": null
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
If --type is docs|chore, return {"status":"skipped","reason":"type=<type>"} —
|
|
156
|
+
no acceptance surface to plan tests for.
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## 4. Reducer (Solo side)
|
|
160
|
+
|
|
161
|
+
After all sub-agent Tasks return, Solo:
|
|
162
|
+
|
|
163
|
+
1. Restores presence ONCE (not per-agent):
|
|
164
|
+
```
|
|
165
|
+
peaks skill presence:set peaks-solo --project <repo> --mode <mode> --gate swarm-converged
|
|
166
|
+
```
|
|
167
|
+
2. Runs `ls` checks against `sc/swarm-plan.json` — every promised artefact must exist (Gate B hard). If any are missing, apply the degradation rules in "Degradation when swarm roles fail or are absent" (main SKILL.md).
|
|
168
|
+
3. Updates `sc/swarm-plan.json` with the final status of each sub-agent (ok / blocked / skipped / error).
|
|
169
|
+
4. Advances to step 4 (RD implementation) with all the artefacts in hand.
|
|
170
|
+
|
|
171
|
+
## 5. Presence restoration (single-shot)
|
|
172
|
+
|
|
173
|
+
Sub-agents are explicitly forbidden from calling `peaks skill presence:set`. That means `.peaks/.active-skill.json` does not move during the fan-out. Solo sets it to `gate=swarm-fan-out` before fan-out and to `gate=swarm-converged` once after all Tasks return. The status header (the `Peaks-Cli Skill: peaks-solo | Peaks-Cli Gate: <gate>` line) therefore reads consistently across the fan-out window.
|
|
174
|
+
|
|
175
|
+
If a sub-agent is misbehaving and writes to `.peaks/.active-skill.json` anyway, the next Solo presence-set (after fan-out) overwrites it — the bug self-heals on the next gate advance, but the swarm-phase display may be off. The hard prohibition is there to prevent this; Solo should still treat the file as a single-writer resource.
|
|
176
|
+
|
|
177
|
+
## 6. Why not a `peaks-swarm` skill?
|
|
178
|
+
|
|
179
|
+
A skill cannot itself trigger sub-agents — the Skill tool runs in the main loop. The orchestrator (peaks-solo) has to be in the main loop and has to use the Task tool directly. Putting swarm logic into a separate skill would either re-introduce the "single-stack blocking" anti-pattern or require a custom slash command that bypasses the Skill tool. The current design keeps swarm control in peaks-solo where it belongs.
|
|
180
|
+
|
|
181
|
+
## 7. Tests / dogfood
|
|
182
|
+
|
|
183
|
+
- `peaks scan archetype --project <repo> --json` must keep emitting `frontendOnly` and `frontendOnlyReason`. Both fields are read here and by the existing pre-RD scan contract.
|
|
184
|
+
- `peaks request show <rid> --role prd --json` must surface the `--type` chosen at `peaks request init`. Sub-agents pass it through unchanged.
|
|
185
|
+
- `peaks skill presence:set` must remain single-writer-friendly (the sub-agents do not call it).
|
|
186
|
+
- Smoke test: a full-auto peaks-solo run on a `legacy-frontend` project with a UI-affecting PRD should produce `sc/swarm-plan.json` containing all three sub-agents and three corresponding artefacts in `ui/`, `rd/`, `qa/`.
|
|
@@ -97,6 +97,22 @@ The three gate primitives are domain-neutral, so the same engine governs very di
|
|
|
97
97
|
|
|
98
98
|
The one boundary to explain: a gate must reduce to **a file existing, text matching in a file, or a command's exit code**. A purely human-judgment gate ("did the editor approve?") is expressed by reifying it into a signal — e.g. require an `approved.md` file, or that a status file contains "approved". The `command` gate is the universal adapter for anything scriptable.
|
|
99
99
|
|
|
100
|
+
### Literal-word trap and `stripMeta` (added by PRD 006 on 2026-06-02)
|
|
101
|
+
|
|
102
|
+
A naive `grep` gate for a content-publishing SOP has a self-referential failure mode: the author writing *about* the gate's pattern ("we use a `grep absent: "TODO"` gate to block leftover T-O-D-O") ends up triggering the gate they just described. This is rare in code-review SOPs and very common in content/publishing SOPs.
|
|
103
|
+
|
|
104
|
+
**Opt-in workaround**: add `stripMeta: true` to the gate's check. The evaluator strips HTML comments (`<!-- … -->`), fenced code blocks (` ``` … ``` `), and C-style block comments (`/* … */`) from the file content *before* applying the regex. The author's discussion of the gate in those areas is no longer counted.
|
|
105
|
+
|
|
106
|
+
```json
|
|
107
|
+
{
|
|
108
|
+
"id": "no-todo",
|
|
109
|
+
"phase": "publish",
|
|
110
|
+
"check": { "type": "grep", "file": "post.md", "pattern": "TODO", "absent": true, "stripMeta": true }
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Default `false` preserves byte-identical behavior for existing SOPs. The stripper is conservative on malformed input (unclosed fences / block comments fall through un-stripped). Not covered by this slice: inline code (`` `TODO` ``) and blockquotes (`> TODO`) — both are content the author explicitly chose to render, so they remain subject to the regex. If a future dogfood surfaces a need to strip those too, open a follow-up PRD.
|
|
115
|
+
|
|
100
116
|
## Un-bypassable enforcement (optional, opt-in)
|
|
101
117
|
|
|
102
118
|
By default a SOP gate only blocks the `peaks sop advance` command — nothing forces the agent through it. To make a gate **physically un-bypassable**, a SOP can declare **guards** that bind a concrete irreversible Bash action to a phase, and the user installs a PreToolUse hook:
|
|
@@ -162,6 +178,7 @@ peaks hooks status --project <repo>
|
|
|
162
178
|
peaks gate bypass --sop <sop-id> --phase <phase> --reason "<why>" --project <repo>
|
|
163
179
|
|
|
164
180
|
# 9. hand the SOP to the user; clear presence when done
|
|
181
|
+
peaks project memories:extract --session-id <session-id> --project <repo> --json # extract durable memories
|
|
165
182
|
peaks skill presence:clear --project <repo>
|
|
166
183
|
```
|
|
167
184
|
|