guild-cli 0.24.0__tar.gz → 0.25.0__tar.gz
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.
- guild_cli-0.25.0/.claude/skills/assign-to-workforce/SKILL.md +462 -0
- guild_cli-0.25.0/.claude/skills/assign-to-workforce/scripts/assign-to-workforce.sh +638 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/challenge/SKILL.md +40 -8
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/deviate/SKILL.md +24 -8
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/scope/SKILL.md +76 -10
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/scope/scripts/scope.sh +2 -2
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/spec-to-plan/SKILL.md +129 -19
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/spec-to-plan/scripts/spec-to-plan.sh +1 -1
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/summarize-delivery/SKILL.md +55 -15
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/think/SKILL.md +135 -21
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/think/scripts/think.sh +1 -1
- guild_cli-0.25.0/.claude/skills/validate-delivery/SKILL.md +242 -0
- guild_cli-0.25.0/.claude/skills/validate-delivery/scripts/validate-delivery.sh +96 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/CHANGELOG.md +59 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/PKG-INFO +1 -1
- {guild_cli-0.24.0 → guild_cli-0.25.0}/docs/skill-sources.md +44 -16
- {guild_cli-0.24.0 → guild_cli-0.25.0}/pyproject.toml +1 -1
- {guild_cli-0.24.0 → guild_cli-0.25.0}/uv.lock +1 -1
- guild_cli-0.24.0/.claude/skills/assign-to-workforce/SKILL.md +0 -242
- guild_cli-0.24.0/.claude/skills/assign-to-workforce/scripts/assign-to-workforce.sh +0 -212
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/agent-config/SKILL.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/agent-config/data/backend-fingerprints.yaml +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/agent-config/scripts/show.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/ask-colleague/SKILL.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/ask-colleague/prompts/explore.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/ask-colleague/prompts/review.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/ask-colleague/prompts/write.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/ask-colleague/scripts/ask-colleague.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/challenge/scripts/challenge.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/cicd/SKILL.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/cicd/scripts/_resolve-nick.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/cicd/scripts/portability-lint.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/cicd/scripts/pr-reply.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/cicd/scripts/pr-status.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/cicd/scripts/workflow.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/communicate/SKILL.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/communicate/scripts/fetch-issues.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/communicate/scripts/mesh-message.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/communicate/scripts/post-comment.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/communicate/scripts/post-issue.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/communicate/scripts/templates/skill-new-brief.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/communicate/scripts/templates/skill-update-brief.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/deviate/scripts/deviate.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/doc-test-alignment/SKILL.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/doc-test-alignment/scripts/check.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/guild/SKILL.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/guild/scripts/configure-repo.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/guild/scripts/create.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/guild/scripts/overview.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/onboard/SKILL.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/onboard/scripts/onboard.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/outsource/SKILL.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/outsource/prompts/explore.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/outsource/prompts/review.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/outsource/prompts/write.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/outsource/scripts/outsource.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/pypi-maintainer/SKILL.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/pypi-maintainer/scripts/switch-source.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/recall/SKILL.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/recall/scripts/recall.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/remember/SKILL.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/remember/scripts/remember.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/run-tests/SKILL.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/run-tests/scripts/test.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/sonarclaude/SKILL.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/sonarclaude/scripts/sonar.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/summarize-delivery/scripts/summarize-delivery.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/teach/SKILL.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/teach/scripts/teach.sh +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/version-bump/SKILL.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills/version-bump/scripts/bump.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.claude/skills.local.yaml.example +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.devague/frames/guildmaster-ships-teach-and-onboard-two-agent-firs.json +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.devague/plans/guildmaster-ships-teach-and-onboard-two-agent-firs.json +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.eidetic/memory/default__public.jsonl +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.eidetic/memory/guildmaster__public.jsonl +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.flake8 +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.github/workflows/publish.yml +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.github/workflows/tests.yml +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.gitignore +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/.markdownlint-cli2.yaml +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/CLAUDE.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/LICENSE +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/README.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/culture.yaml +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/docs/cutover.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/docs/onboarding/reachy-mini-mcp.json +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/docs/plans/2026-05-24-guildmaster-ships-teach-and-onboard-two-agent-firs.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/docs/specs/2026-05-24-guildmaster-ships-teach-and-onboard-two-agent-firs.md +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/guild/__init__.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/guild/__main__.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/guild/cli/__init__.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/guild/cli/_commands/__init__.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/guild/cli/_commands/_broadcast.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/guild/cli/_commands/_provision_template.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/guild/cli/_commands/create.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/guild/cli/_commands/explain.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/guild/cli/_commands/learn.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/guild/cli/_commands/onboard.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/guild/cli/_commands/overview.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/guild/cli/_commands/show.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/guild/cli/_commands/teach.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/guild/cli/_commands/whoami.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/guild/cli/_errors.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/guild/cli/_output.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/guild/cli/_repo.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/guild/scaffold/__init__.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/guild/scaffold/instantiate.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/guild/skills/__init__.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/guild/skills/identity.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/guild/skills/ledger.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/guild/skills/render.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/guild/skills/sources.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/sonar-project.properties +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/tests/__init__.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/tests/test_broadcast_post.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/tests/test_cli.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/tests/test_cli_create.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/tests/test_cli_explain.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/tests/test_cli_learn.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/tests/test_cli_onboard.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/tests/test_cli_overview.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/tests/test_cli_show.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/tests/test_cli_teach.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/tests/test_cli_whoami.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/tests/test_configure_repo_sonar.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/tests/test_scaffold_instantiate.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/tests/test_skills_convention.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/tests/test_skills_identity.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/tests/test_skills_ledger.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/tests/test_skills_render.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/tests/test_skills_sources.py +0 -0
- {guild_cli-0.24.0 → guild_cli-0.25.0}/tests/test_version_fallback.py +0 -0
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: assign-to-workforce
|
|
3
|
+
description: >
|
|
4
|
+
Fan out a converged devague plan's dependency waves to parallel agents in
|
|
5
|
+
isolated git worktrees, one agent per task per wave, with TDD-gated merges
|
|
6
|
+
by the main agent. Human gates: the exported spec, the implementation split
|
|
7
|
+
plan (task map + per-task agent/model proposal + go/no-go), and the final PR.
|
|
8
|
+
The devague CLI stays deterministic and non-orchestrating (#20) — it only
|
|
9
|
+
*describes* the graph via `devague plan waves`; the operator (main agent)
|
|
10
|
+
performs the fan-out. Use when the user says "assign to workforce",
|
|
11
|
+
"fan out the plan", "parallel subagents", or after /spec-to-plan exports a
|
|
12
|
+
plan. Authored and maintained in agentculture/devague (origin = devague);
|
|
13
|
+
guildmaster pulls this skill from here and broadcasts it to the AgentCulture
|
|
14
|
+
mesh — it is NOT vendored from guildmaster like the inbound skills here.
|
|
15
|
+
type: command
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# assign-to-workforce — fan out a converged plan's waves to parallel agents
|
|
19
|
+
|
|
20
|
+
The skill is named **`assign-to-workforce`**; the product/CLI it reads is the
|
|
21
|
+
**`devague plan waves`** command. (The prior leg — turning a spec into a plan —
|
|
22
|
+
is the sibling **`/spec-to-plan`** skill.)
|
|
23
|
+
|
|
24
|
+
`assign-to-workforce` takes a **converged devague plan** and fans out its
|
|
25
|
+
dependency waves to parallel agents (subagents, teammate agents, or generalist
|
|
26
|
+
agents) — one agent per task per wave — each working in an **isolated git
|
|
27
|
+
worktree**. The main agent merges each completed worktree gated by TDD. The
|
|
28
|
+
human owns exactly three gates: the exported spec, the implementation split
|
|
29
|
+
plan, and the final PR.
|
|
30
|
+
|
|
31
|
+
The devague CLI is **never orchestrated by devague itself** — `devague plan
|
|
32
|
+
waves` describes the dependency graph (#20); it does not spawn agents, manage
|
|
33
|
+
worktrees, mark tasks done, or pick a backend. The fan-out is the *operator's*
|
|
34
|
+
job — this skill and the main agent perform it.
|
|
35
|
+
|
|
36
|
+
## How to run
|
|
37
|
+
|
|
38
|
+
The entry point is `scripts/assign-to-workforce.sh`. Invoke it from the
|
|
39
|
+
repository whose plan you are implementing (plans persist under `.devague/`
|
|
40
|
+
in the current directory):
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
bash .claude/skills/assign-to-workforce/scripts/assign-to-workforce.sh split-plan [--plan <slug>] [--write]
|
|
44
|
+
bash .claude/skills/assign-to-workforce/scripts/assign-to-workforce.sh waves [--plan <slug>] [--json]
|
|
45
|
+
bash .claude/skills/assign-to-workforce/scripts/assign-to-workforce.sh help
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
It resolves the CLI portably — an installed `devague` on `PATH` (the normal
|
|
49
|
+
case), falling back to `uv run devague` when you are inside the devague
|
|
50
|
+
checkout, else an install hint. The `split-plan` subcommand reads
|
|
51
|
+
`devague plan waves --json` — the enriched payload (devague#53 t9) that
|
|
52
|
+
carries every active task's summary, instruction, acceptance criteria, and
|
|
53
|
+
covered targets keyed by task id — and renders the human-facing
|
|
54
|
+
implementation split plan: task map (task id, wave, summary verbatim, whether
|
|
55
|
+
an instruction is present, acceptance-criteria count), proposed per-task
|
|
56
|
+
agent + model assignment, the go/no-go question, and — last — an End state
|
|
57
|
+
section that is the verbatim output of `devague plan deliverables` (#70),
|
|
58
|
+
degrading to a one-line hint on a `devague` too old to have the verb. Adding
|
|
59
|
+
`--write` (issue #82) additionally persists that same content — plus an
|
|
60
|
+
owner/model annotation table the script reads back on the next `--write` —
|
|
61
|
+
to a durable file next to the exported plan-md; see *The durable split
|
|
62
|
+
artifact* below. The `waves` subcommand forwards to `devague plan waves`
|
|
63
|
+
verbatim.
|
|
64
|
+
|
|
65
|
+
### Usage
|
|
66
|
+
|
|
67
|
+
| Subcommand | What it does |
|
|
68
|
+
|------------|--------------|
|
|
69
|
+
| `split-plan [--plan S] [--write]` | Read `devague plan waves --json` and print the implementation split plan — task map (summary/instruction/acceptance-criteria count, verbatim) with per-task agent + model proposal, go/no-go, and a trailing End state section quoting `devague plan deliverables` verbatim (one-line hint on an older devague) — ready for human go/no-go review. With `--write`, also persist that content to `docs/plans/<created-date>-<slug>-split.md` (issue #82) — the durable gate-2 record; re-running overwrites the same path in place and preserves any hand-edited Owner/Model cells. |
|
|
70
|
+
| `waves [--plan S] [--json]` | Forward to `devague plan waves [--json]`. Read-only; lists wave batches. On a converged plan exits 0 listing the waves. |
|
|
71
|
+
| `help` | Print usage. |
|
|
72
|
+
|
|
73
|
+
## The full flow
|
|
74
|
+
|
|
75
|
+
The flow has three human gates and one automated TDD merge loop.
|
|
76
|
+
|
|
77
|
+
### Human gate 1 — the exported spec
|
|
78
|
+
|
|
79
|
+
The plan is seeded from a converged frame (`devague plan new --frame <slug>`).
|
|
80
|
+
The human reviewed and approved the spec when it was exported by the `/think`
|
|
81
|
+
skill. No re-approval needed here — the spec gate is already closed.
|
|
82
|
+
|
|
83
|
+
### Human gate 2 — the implementation split plan
|
|
84
|
+
|
|
85
|
+
Before any task is assigned, the main agent presents the **implementation split
|
|
86
|
+
plan** for human go/no-go. This is the only gate the human owns at the
|
|
87
|
+
implementation stage (per task, the TDD gate is the main agent's).
|
|
88
|
+
|
|
89
|
+
The split plan contains:
|
|
90
|
+
|
|
91
|
+
1. **Task map** — every task id, its one-line summary (verbatim), whether it
|
|
92
|
+
carries a working instruction, its acceptance-criteria count, and the wave
|
|
93
|
+
it belongs to — all read straight from `devague plan waves --json` (no
|
|
94
|
+
operator paraphrasing).
|
|
95
|
+
2. **Per-task agent + model proposal** — for each task: the proposed agent type
|
|
96
|
+
(subagent / teammate / generalist), the proposed model (e.g. a cheaper/faster
|
|
97
|
+
model for a well-scoped task), and the scope justification (why this task is
|
|
98
|
+
safe to delegate).
|
|
99
|
+
3. **Go/no-go question** — explicit human decision: "Approve this split and
|
|
100
|
+
assign the plan to the workforce, or edit it first?"
|
|
101
|
+
4. **End state** — the verbatim output of `devague plan deliverables` (#70):
|
|
102
|
+
what the plan actually produces — confirmed after-state claims, terminal
|
|
103
|
+
tasks with acceptance criteria, and surviving open items. Present this to
|
|
104
|
+
the human alongside the go/no-go question, not just the task map — approving
|
|
105
|
+
a fan-out without seeing the world it produces is the gap this closes. On a
|
|
106
|
+
`devague` too old to have the verb, this degrades to a one-line hint naming
|
|
107
|
+
the minimum version instead of failing the split plan.
|
|
108
|
+
|
|
109
|
+
The human may edit any row (agent type, model, scope) before approving. The
|
|
110
|
+
plan is model-agnostic — devague does not pick a backend (#20).
|
|
111
|
+
|
|
112
|
+
Run `split-plan` to print the proposed table:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
bash .claude/skills/assign-to-workforce/scripts/assign-to-workforce.sh split-plan
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Do not proceed to fan-out until the human approves the split plan.
|
|
119
|
+
|
|
120
|
+
### The durable split artifact (`split-plan --write`)
|
|
121
|
+
|
|
122
|
+
Unlike the exported spec (`docs/specs/*.md`) and the exported plan
|
|
123
|
+
(`docs/plans/*.md`), the implementation split plan — gate 2 — survived only
|
|
124
|
+
in conversation before issue #82. `split-plan --write` closes that gap with
|
|
125
|
+
an **artifact-only** change (decision c25): the written file *is* the record;
|
|
126
|
+
there is no plan-schema change and no new `devague` CLI verb, so `devague
|
|
127
|
+
plan waves`/`show`/`deliverables` stay read-only exactly as before.
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
bash .claude/skills/assign-to-workforce/scripts/assign-to-workforce.sh split-plan --write
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
This writes (or overwrites) `docs/plans/<created-date>-<slug>-split.md` —
|
|
134
|
+
the same date-prefix convention `devague plan export` uses for the plan-md
|
|
135
|
+
it sits beside, derived from the plan's own `created` timestamp (via
|
|
136
|
+
`devague plan show --json`) rather than today's date, so re-running the
|
|
137
|
+
command is idempotent: it updates the same file in place instead of spawning
|
|
138
|
+
a dated duplicate. The file carries:
|
|
139
|
+
|
|
140
|
+
1. The dependency waves and the full per-task content (summary, instruction,
|
|
141
|
+
acceptance criteria, covered targets) for every wave — quoted verbatim
|
|
142
|
+
from `devague plan waves --json`, organized under one `## Wave N` heading
|
|
143
|
+
per wave and one `### <task-id> — <summary>` heading per task.
|
|
144
|
+
2. A **Task assignments** table (`Task | Owner | Model`) — the durable form
|
|
145
|
+
of the human's per-task owner/model decision (#82 ask 2). The script
|
|
146
|
+
**reads this table back** from any existing file at the same path before
|
|
147
|
+
regenerating: a human's edited `Owner`/`Model` cell for a given task id
|
|
148
|
+
survives the next `--write`, matched by task id, rather than being
|
|
149
|
+
clobbered back to the `sonnet` default. Only edit this table (or add a
|
|
150
|
+
new plan/task and re-run) — don't hand-edit the wave/task sections above
|
|
151
|
+
it, since those are fully regenerated every run.
|
|
152
|
+
3. The same End state section as plain `split-plan` — the verbatim output of
|
|
153
|
+
`devague plan deliverables`, nested under its own `## End state` heading.
|
|
154
|
+
|
|
155
|
+
Present this file (or its stdout twin from plain `split-plan`) at the go/no-go
|
|
156
|
+
either way; `--write` is for keeping a committed record of what was actually
|
|
157
|
+
approved, not a replacement for the live review.
|
|
158
|
+
|
|
159
|
+
### The `waves --json` payload — the single source for every brief
|
|
160
|
+
|
|
161
|
+
`devague plan waves --json` emits `{"plan": "<slug>", "waves": [[...], ...],
|
|
162
|
+
"tasks": {...}}` — the ordered dependency-wave batches plus a top-level
|
|
163
|
+
`tasks` object keyed by task id, each entry carrying that task's full working
|
|
164
|
+
contract:
|
|
165
|
+
|
|
166
|
+
```json
|
|
167
|
+
{
|
|
168
|
+
"plan": "<slug>",
|
|
169
|
+
"waves": [["t1"], ["t2", "t3"]],
|
|
170
|
+
"tasks": {
|
|
171
|
+
"t1": {
|
|
172
|
+
"summary": "<task summary>",
|
|
173
|
+
"instruction": "<verbatim instruction, or \"\" if none>",
|
|
174
|
+
"acceptance_criteria": ["<criterion>", "..."],
|
|
175
|
+
"covers": ["<c*/h* id>", "..."]
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
This one payload is enough to build a per-subagent brief with **no external
|
|
182
|
+
context** — no need to also read `devague plan show --json` or the exported
|
|
183
|
+
plan-md. `split-plan` reads it to render the task map above; the fan-out step
|
|
184
|
+
below reads the same payload to build each task agent's brief. Quote
|
|
185
|
+
`summary`, `instruction`, `acceptance_criteria`, and `covers` **verbatim**
|
|
186
|
+
into every brief — never paraphrase them. (Documented identically in the
|
|
187
|
+
sibling `/spec-to-plan` skill, since both skills consume the same payload —
|
|
188
|
+
stay consistent if either changes.)
|
|
189
|
+
|
|
190
|
+
### Fan-out — one agent per task per wave in isolated worktrees
|
|
191
|
+
|
|
192
|
+
Once the human approves, the main agent fans out each wave in order:
|
|
193
|
+
|
|
194
|
+
1. **Create an isolated git worktree** for each task in the current wave,
|
|
195
|
+
**inside this repo's own worktree root** — `.worktrees.<repo-name>`, a
|
|
196
|
+
sibling of the repo directory:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
repo_root=$(git rev-parse --show-toplevel)
|
|
200
|
+
wt_root="$(dirname "$repo_root")/.worktrees.$(basename "$repo_root")"
|
|
201
|
+
git worktree add "$wt_root/agent-<task-id>" -b agent/<task-id>
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Never use a bare `../worktrees/` or an in-repo path. The
|
|
205
|
+
`.worktrees.<repo-name>` root is mandatory for three reasons:
|
|
206
|
+
|
|
207
|
+
- **Nobody else will delete it.** A shared `../worktrees/` in a multi-repo
|
|
208
|
+
parent directory looks like anyone's scratch space; a directory named
|
|
209
|
+
after *your* repo is visibly owned, so another agent or human cleaning up
|
|
210
|
+
their own worktrees won't sweep away a live fan-out mid-wave.
|
|
211
|
+
- **No cross-repo collision.** Task ids restart at `t1` in every repo and
|
|
212
|
+
every plan, so `../worktrees/agent-t1` from two concurrent repos is the
|
|
213
|
+
same path. Namespacing by repo name keeps concurrent fan-outs disjoint.
|
|
214
|
+
- **The repo working tree stays clean.** An in-repo path (`.worktrees/`,
|
|
215
|
+
`.claude/worktrees/`) puts N checkouts inside the tree you are about to
|
|
216
|
+
commit and PR — `git add -A` sweeps them in and `git clean -fdx` destroys
|
|
217
|
+
them. Outside the repo, neither can touch them.
|
|
218
|
+
|
|
219
|
+
2. **Spawn a task agent** inside that worktree (using the approved model from
|
|
220
|
+
the split plan), with:
|
|
221
|
+
- The task id, summary, working instruction, acceptance criteria, and
|
|
222
|
+
covered targets as its brief — **quoted verbatim** from `devague plan
|
|
223
|
+
waves --json` (see *The `waves --json` payload* above). No operator
|
|
224
|
+
paraphrasing anywhere in this flow: the plan text *is* the contract the
|
|
225
|
+
user confirmed, and a reworded brief silently drifts from it. If a task
|
|
226
|
+
has no instruction (`""`), say so rather than inventing one.
|
|
227
|
+
- Instruction to work **test-first** (TDD): write the failing test(s) that
|
|
228
|
+
match the acceptance criteria before implementing.
|
|
229
|
+
- Instruction to commit its work to the worktree branch.
|
|
230
|
+
- Instruction to **report, never file**, any reasoning-degradation lapse it
|
|
231
|
+
notices in its own work — a skipped check, an assumption standing in for
|
|
232
|
+
a real measurement, an unverified grader, missing provenance, or another
|
|
233
|
+
of the six `LAPSE_CODES` in `devague/frame.py`. The task agent names it
|
|
234
|
+
in its transcript or final report; it never runs `devague lapse` itself,
|
|
235
|
+
because it never runs any devague command inside its worktree (see the
|
|
236
|
+
hard rule below). The **main agent** files the record (`devague lapse
|
|
237
|
+
"<what>" --code <code> --origin llm`) the moment the task agent reports
|
|
238
|
+
it — not deferred to closeout — since written late is written
|
|
239
|
+
flattering.
|
|
240
|
+
|
|
241
|
+
3. **Same-wave tasks run in parallel** (within-wave tasks have no
|
|
242
|
+
inter-task dependency; the dependency graph guarantees this). Same-file
|
|
243
|
+
overlap surfaces as a merge conflict at reconcile time, not a live race —
|
|
244
|
+
isolated worktrees prevent clobbering.
|
|
245
|
+
|
|
246
|
+
4. **Wait for all tasks in the wave to complete** before starting the next wave.
|
|
247
|
+
|
|
248
|
+
### TDD-gated merge — main agent, no human per task
|
|
249
|
+
|
|
250
|
+
For each completed task worktree, the main agent:
|
|
251
|
+
|
|
252
|
+
1. **Runs the task's tests before merge** (on the main branch): baseline must
|
|
253
|
+
pass (or the relevant tests must be absent — the task adds them).
|
|
254
|
+
2. **Merges the worktree branch** into the main branch:
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
git merge --no-ff agent/<task-id>
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
3. **Runs the task's tests after merge**: they must pass. If they do not, the
|
|
261
|
+
merge is reverted and the task agent is given the failure output to fix.
|
|
262
|
+
4. **Removes the worktree** once the merge is accepted:
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
git worktree remove "$wt_root/agent-<task-id>"
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Remove only the worktrees this run created — never `rm -rf` the
|
|
269
|
+
`.worktrees.<repo-name>` root itself, and never touch another repo's
|
|
270
|
+
worktree root. A concurrent fan-out may be live inside it.
|
|
271
|
+
|
|
272
|
+
The human does **not** review individual task merges. Per-task acceptance is
|
|
273
|
+
the main agent's responsibility — the TDD gate (tests pass before AND after
|
|
274
|
+
merge) plus the task's acceptance criteria. This mirrors the non-authoritative
|
|
275
|
+
working state pattern of the Human Review Loop (#17): per-task merge records
|
|
276
|
+
are uncommitted working state; the authoritative human gate is the final PR.
|
|
277
|
+
|
|
278
|
+
Advance to the next wave only after all tasks in the current wave are merged
|
|
279
|
+
and their tests pass.
|
|
280
|
+
|
|
281
|
+
### Human gate 3 — the final PR
|
|
282
|
+
|
|
283
|
+
Once all waves are merged and the full test suite passes, the main agent opens
|
|
284
|
+
a PR via the `cicd` skill (`agex pr open`). The human reviews and merges. This
|
|
285
|
+
is the last and only remaining human gate.
|
|
286
|
+
|
|
287
|
+
## Hand-offs: mid-run and after the final PR
|
|
288
|
+
|
|
289
|
+
Two hand-offs bracket execution — one that can fire mid-run, one that always
|
|
290
|
+
fires after the final PR merges:
|
|
291
|
+
|
|
292
|
+
1. **Mid-run — hand off to `/deviate`.** If a task agent (or the main agent)
|
|
293
|
+
discovers the confirmed plan no longer matches reality partway through a
|
|
294
|
+
wave, that is not a silent edit to this run — stop, get explicit human
|
|
295
|
+
approval for the divergence, and record it via the sibling **`/deviate`**
|
|
296
|
+
skill (`devague deviate`) before resuming the fan-out. This is not a fourth
|
|
297
|
+
standing gate; it is the human owner of gate 2 approving an amendment to it
|
|
298
|
+
in-flight.
|
|
299
|
+
2. **Post-merge — hand off to `/validate-delivery`, then `/summarize-delivery`.**
|
|
300
|
+
Once the final PR is **merged**, close the execution loop cleanly instead of
|
|
301
|
+
stopping at a green merge:
|
|
302
|
+
a. **Validate delivery.** Run the sibling **`/validate-delivery`** skill —
|
|
303
|
+
the execution-to-evidence leg. It runs the plan's behavioral tests
|
|
304
|
+
agent-side and files what it found (obligations met, evidence, and any
|
|
305
|
+
behavioral deltas) via the devague CLI; a failing or unchecked outcome is
|
|
306
|
+
filed and reported exactly as such, never rounded up.
|
|
307
|
+
b. **Summarize the delivery.** Run the sibling **`/summarize-delivery`**
|
|
308
|
+
skill — the delivery-side closure leg. It turns the run into a committed
|
|
309
|
+
accountability artifact (`docs/deliveries/<created-date>-<slug>.md`) that
|
|
310
|
+
records planned-versus-actual delivery, the mid-work decisions the
|
|
311
|
+
workforce made, where execution drifted from the plan, evidence-backed
|
|
312
|
+
delivery claims (a claim without evidence stays `unverified`, never
|
|
313
|
+
asserted as done — the strength ladder now draws on what
|
|
314
|
+
`/validate-delivery` filed), and any remaining work. The `devague plan
|
|
315
|
+
waves --json` payload you fanned out is the planned-work baseline it
|
|
316
|
+
compares actuals against.
|
|
317
|
+
c. **Both close partial and failed runs too.** Neither skill requires every
|
|
318
|
+
wave to have merged — a run that shipped only some tasks, or none, still
|
|
319
|
+
produces a truthful record: the failure lands under drift and remaining
|
|
320
|
+
work, and no claim says done without evidence.
|
|
321
|
+
|
|
322
|
+
This is the accountability wrap-up after the three gates, not a fourth gate —
|
|
323
|
+
`/deviate`, `/validate-delivery`, and `/summarize-delivery` are all method-only
|
|
324
|
+
and record- or read-only (#20): none of them orchestrate, gate merges, or
|
|
325
|
+
mutate devague state beyond their own append-only records. Don't stop at "PR
|
|
326
|
+
merged" — the standing flow is **merge, then `/validate-delivery`, then
|
|
327
|
+
`/summarize-delivery`**.
|
|
328
|
+
|
|
329
|
+
## Hard rules (do not violate)
|
|
330
|
+
|
|
331
|
+
These protect the human-gate contract and the TDD guarantee.
|
|
332
|
+
|
|
333
|
+
- **Present the split plan before any fan-out.** Never spawn a task agent
|
|
334
|
+
without prior human approval of the implementation split plan (gate 2). The
|
|
335
|
+
split plan is the human's only implementation-stage decision.
|
|
336
|
+
- **One worktree per task.** Never run two tasks in the same worktree — file
|
|
337
|
+
contention is managed by isolation, not by trust in the dependency graph.
|
|
338
|
+
The dependency graph guarantees *logical* independence within a wave, not
|
|
339
|
+
*file* disjointness. Conflicts surface at merge time.
|
|
340
|
+
- **All worktrees live under `.worktrees.<repo-name>`.** Every worktree this
|
|
341
|
+
skill creates goes in that one repo-owned root beside the repo directory —
|
|
342
|
+
never a shared `../worktrees/`, never inside the repo. Clean up only the
|
|
343
|
+
worktrees you created; leave the root and anyone else's worktrees alone.
|
|
344
|
+
- **Tests before AND after merge — no exceptions.** The TDD gate must pass on
|
|
345
|
+
both sides. A merge that makes tests pass only after (not before) means the
|
|
346
|
+
baseline was already broken — fix the baseline first.
|
|
347
|
+
- **Human does not gate per-task merges.** The TDD contract replaces the
|
|
348
|
+
human here. Do not pause for human approval between wave tasks.
|
|
349
|
+
- **No devague move runs inside a task worktree — not just `devague plan`.**
|
|
350
|
+
`devague plan waves` is read-only scheduling metadata (#20); more broadly, a
|
|
351
|
+
task agent never runs any devague command in its worktree, including
|
|
352
|
+
`devague lapse`. If a task agent notices its own reasoning degraded — a
|
|
353
|
+
skipped check, an assumption standing in for a real measurement, an
|
|
354
|
+
unverified grader, missing provenance, or another `LAPSE_CODES` case
|
|
355
|
+
(`devague/frame.py`) — it reports the degradation in its transcript or
|
|
356
|
+
final report; it does not file it. The **main agent** files that record
|
|
357
|
+
the moment the task agent's report surfaces it, not deferred to closeout
|
|
358
|
+
(`devague lapse "<what>" --code <code> --origin llm`), the same way it
|
|
359
|
+
alone runs every plan-mutating move — mirroring the `/scope` subagent
|
|
360
|
+
boundary, where exploration subagents report and only the main agent runs
|
|
361
|
+
a `devague` move (#79/#91). Adjudicating
|
|
362
|
+
a filed lapse (`devague lapse --confirm`/`--reject`) is the same human who
|
|
363
|
+
already owns gate 2/3 — no new role — typically exercised once the run
|
|
364
|
+
reaches `/summarize-delivery`.
|
|
365
|
+
- **Three gates only.** The human's gates are: (1) the exported spec, (2) the
|
|
366
|
+
implementation split plan, (3) the final PR. No silent fourth gate.
|
|
367
|
+
- **No LLM calls in the devague CLI.** The CLI is deterministic. This skill
|
|
368
|
+
adds orchestration convention, not CLI behavior.
|
|
369
|
+
- File the record the moment the thing happens, never at closeout — written
|
|
370
|
+
late is written flattering (issue 97).
|
|
371
|
+
|
|
372
|
+
## Output contract
|
|
373
|
+
|
|
374
|
+
The `split-plan` subcommand prints to **stdout** and exits 0 when a converged
|
|
375
|
+
plan is found. On error (no plan, cyclic graph) it exits non-zero with a
|
|
376
|
+
`hint:` line on stderr. The `waves` subcommand forwards the CLI's own output
|
|
377
|
+
contract (stdout, `--json` for structured output, exit 0 on success).
|
|
378
|
+
|
|
379
|
+
The trailing End state section (#70) never fails `split-plan`: on a `devague`
|
|
380
|
+
new enough to have `plan deliverables`, it quotes that command's stdout
|
|
381
|
+
verbatim under an ``End state (from `devague plan deliverables`):`` header; on
|
|
382
|
+
an older `devague`, it prints exactly one hint line naming the minimum
|
|
383
|
+
version (e.g. `hint: End state view requires devague >= 0.18.0 (devague plan deliverables)`)
|
|
384
|
+
and `split-plan` still exits 0.
|
|
385
|
+
|
|
386
|
+
`--write` adds exactly one line after all of the above: `wrote split
|
|
387
|
+
artifact: <path>` on the first run, `updated split artifact: <path>` on every
|
|
388
|
+
run after (issue #82). It calls one additional read-only command,
|
|
389
|
+
`devague plan show --json` (for the plan's `created` timestamp and title);
|
|
390
|
+
a failure there exits non-zero with that command's own stderr, same as a
|
|
391
|
+
`plan waves --json` failure.
|
|
392
|
+
|
|
393
|
+
## Worked example
|
|
394
|
+
|
|
395
|
+
Picking up after `/spec-to-plan` exported a plan for the frame `my-feature`:
|
|
396
|
+
|
|
397
|
+
```bash
|
|
398
|
+
a() { bash .claude/skills/assign-to-workforce/scripts/assign-to-workforce.sh "$@"; }
|
|
399
|
+
|
|
400
|
+
# 1. Inspect the waves
|
|
401
|
+
a waves
|
|
402
|
+
|
|
403
|
+
# 2. Present the implementation split plan for human review
|
|
404
|
+
a split-plan
|
|
405
|
+
|
|
406
|
+
# --- HUMAN: review the table, edit agent/model assignments if needed,
|
|
407
|
+
# then say "approved" to proceed ---
|
|
408
|
+
|
|
409
|
+
# 3. Fan out wave 1 (t1, t2, t3 are independent — run in parallel).
|
|
410
|
+
# All worktrees live under this repo's own root, beside the repo dir:
|
|
411
|
+
# e.g. <parent>/devague -> <parent>/.worktrees.devague/
|
|
412
|
+
repo_root=$(git rev-parse --show-toplevel)
|
|
413
|
+
wt_root="$(dirname "$repo_root")/.worktrees.$(basename "$repo_root")"
|
|
414
|
+
|
|
415
|
+
git worktree add "$wt_root/agent-t1" -b agent/t1
|
|
416
|
+
git worktree add "$wt_root/agent-t2" -b agent/t2
|
|
417
|
+
git worktree add "$wt_root/agent-t3" -b agent/t3
|
|
418
|
+
# ... spawn task agents in each worktree, await completion ...
|
|
419
|
+
|
|
420
|
+
# 4. TDD-gated merge for each wave-1 task (no human per task)
|
|
421
|
+
git merge --no-ff agent/t1 # tests pass before + after
|
|
422
|
+
git worktree remove "$wt_root/agent-t1"
|
|
423
|
+
git merge --no-ff agent/t2
|
|
424
|
+
git worktree remove "$wt_root/agent-t2"
|
|
425
|
+
git merge --no-ff agent/t3
|
|
426
|
+
git worktree remove "$wt_root/agent-t3"
|
|
427
|
+
|
|
428
|
+
# 5. Advance to wave 2 (t4 depends on t1–t3 being merged)
|
|
429
|
+
git worktree add "$wt_root/agent-t4" -b agent/t4
|
|
430
|
+
# ... spawn, await, merge with TDD gate, remove worktree ...
|
|
431
|
+
|
|
432
|
+
# 6. Open the final PR (human gate 3)
|
|
433
|
+
bash .claude/skills/cicd/scripts/workflow.sh open
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
`devague plan waves --json` is the standing brief for each task agent — its
|
|
437
|
+
task id, summary, instruction, acceptance criteria, and the targets it covers
|
|
438
|
+
are all in that one payload. Quote those fields **verbatim** into each task
|
|
439
|
+
agent's brief; the fan-out is honest only if what the subagent builds against
|
|
440
|
+
is exactly what the user confirmed in the plan.
|
|
441
|
+
|
|
442
|
+
## Before and after this leg
|
|
443
|
+
|
|
444
|
+
```text
|
|
445
|
+
Previous leg: spec-to-plan
|
|
446
|
+
Next leg: deviate
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
After every successful, non-exempt move, the CLI prints one `next: <recommended
|
|
450
|
+
move>` line to stderr — follow it, or run `devague plan status` when unsure
|
|
451
|
+
what comes next.
|
|
452
|
+
|
|
453
|
+
## Provenance
|
|
454
|
+
|
|
455
|
+
This is a **first-party** skill — its origin is `agentculture/devague`, where
|
|
456
|
+
the devague agent maintains it alongside the tools it operates (dogfooding),
|
|
457
|
+
next to its siblings `/think` and `/spec-to-plan`. It is the *third* skill in
|
|
458
|
+
that outbound family, covering the implementation leg after a plan converges.
|
|
459
|
+
The flow runs the *opposite* direction of the vendored guildmaster skills:
|
|
460
|
+
guildmaster pulls this **from** devague and broadcasts it to the rest of the
|
|
461
|
+
AgentCulture mesh. The `cite, don't import` policy still holds: downstream repos copy it,
|
|
462
|
+
they don't symlink or depend on it. See `docs/skill-sources.md`.
|