Imported from 23min/aiwf (
internal/skills/embedded-rituals/plugins/aiwf-extensions/skills/aiwfx-start-epic/SKILL.md). Install upstream withnpx skills add 23min/aiwf --skill aiwfx-start-epic. Copyright stays with the author.
aiwfx-start-epic
Activates an epic. Activation is a sovereign moment — the kernel treats aiwf promote E-NNNN active as a human-only act per the kernel's sovereignty rule, and the skill makes the surrounding deliberation explicit: preflight checks against the epic's readiness, a worktree-placement step that defaults to in-repo (the in-repo placement convention) with the per-invocation override retained, and an optional principal-to-agent delegation hand-off.
Principles
- Activation is sovereign. The kernel refuses
aiwf promote E-NNNN activefrom a non-human/actor unless--force --reason "..."is used. The sovereign act is the operator's explicit approval, not who types the command: the skill presents the exact command as an approve/deny gate, and the AI assistant orchestrating the conversation runs it directly once the operator approves — no--actoroverride, so the commit resolves to the operator's own identity exactly as if they had typed it. - Sovereign acts on
main; branch cut afterwards. State-announcement commits (the promote at step 6 and, if delegating, the authorize at step 7) land onmainBEFORE the epic branch is cut at step 8. The chokepoint behind this sequencing is the kernel's AI-target preflight onaiwf authorize— without ritual branch context the preflight refuses. The from-main--branchcarve-out makes the--branch epic/E-NNNN-<slug>future-binding frommainaccept (the named branch is cut at step 8). Theisolation-escapekernel finding provides post-hoc detection ataiwf check(warning severity) for branch-binding drift that escapes both the session-layer hook and the kernel's at-dispatch refusal. - Preflight uses kernel signals. Body completeness, drafted-milestone presence, and
aiwf checkcleanliness all surface through existing kernel rules (entity-body-empty,epic-active-no-drafted-milestones, the standard refusal-severity findings). The skill reads — it does not duplicate the rule. - Worktree placement defaults to in-repo. The recommended placement is in-repo under the configured
worktree.dir— reachable as a sandboxed devcontainer session's cwd and persistent under the mounted workspace. The default is a recommendation, not a lock: the per-invocation override (main-checkout / sibling) stays a Q&A choice, since each option still trades off parallel work, IDE state, andaiwf checkblast radius. - The promotion commit and any authorize commit are separate. One verb = one commit. The skill orchestrates both in sequence; it never bundles them.
Precondition
- The epic spec exists at
work/epics/E-NNNN-<slug>/epic.mdwith statusproposed. - At least one milestone under the epic has status
draft(the kernel'sepic-active-no-drafted-milestoneswarning fires otherwise; the skill's step 2 surfaces it). - Working tree clean.
If any precondition fails, stop and report. Do not improvise around a half-planned epic.
Workflow
1. Preflight: read the epic spec
Open work/epics/E-NNNN-<slug>/epic.md. Confirm the Goal, Scope, Out of scope, and Constraints sections are concrete prose, not template placeholders. The kernel's entity-body-empty finding catches the worst case (all-template body); this step catches the in-between case (body present but vague).
If any section is template-shaped, stop and return the operator to aiwfx-plan-epic to flesh it out.
2. Drafted-milestone check
Run aiwf check and look for the epic-active-no-drafted-milestones warning targeting this epic. If it fires, the epic has no draft-status milestone yet — the skill cannot proceed because there is nothing queued to start.
If it fires, hand the operator to aiwfx-plan-milestones E-NNNN to allocate at least one milestone, then re-enter aiwfx-start-epic.
3. aiwf check clean of refusal-level findings
The drafted-milestone check (step 2) is a warning; this step is the broader pass. Run aiwf check and confirm no error-severity findings touch this epic, its milestones, or files the operator is about to commit.
If error-severity findings exist, the skill stops. Resolve them before activation.
4. Project tests/build advisory pass
Run the project's tests and build. This step is advisory — a red baseline does not block activation, but the operator should know the state before committing to the work.
Report the result. If red, ask the operator whether to proceed or to fix the baseline first.
5. Delegation prompt (Q&A)
Ask the operator whether the work proceeds in-loop (the operator drives every milestone) or delegated (an aiwf authorize scope is opened to a named ai/<id> agent). The answer determines whether step 7 runs.
- In-loop — no scope opened. Step 7 is skipped.
- Delegate to
ai/<id>— step 7 runsaiwf authorize E-NNNN --to ai/<id> --branch epic/E-NNNN-<slug>. The operator names the agent and the future epic branch (typicallyepic/E-NNNN-<slug>derived from the epic id and slug).
The delegation choice is asked BEFORE the sovereign acts because the authorize trailer (if delegating) binds the scope to a named branch, and the epic-branch name should be known when the authorize commit lands on main. The authorize commit's aiwf-branch: trailer is a forward-binding — the named branch is cut at step 8.
6. 🛑 Sovereign promotion (approve/deny gate)
Confirm with the operator that the epic is on main (or the parent branch the sovereign acts will land on). Both this step and step 7 (if delegating) run with the operator's HEAD on main — the epic branch is cut afterwards at step 8.
Activation is the sovereign moment. Present the exact command and wait for explicit approval — never run it unprompted:
aiwf promote E-NNNN active
Promote
E-NNNNto active? (Y/n)
On approval, run it directly with no --actor override. The bare command resolves the actor from the operator's own git config user.email, exactly as if they had typed it themselves — the kernel's sovereignty rule (which refuses any actor not prefixed human/) passes transparently. Don't pass --actor ai/<id> for this ordinary case; that would deliberately trip the refusal for no reason. A general "go ahead" from earlier in the conversation is not this gate — ask again, right before running it.
The override path exists for genuine sovereign-act-shaped exceptions (a ratification run by a bot account, a recovery flow after a half-applied prior promote) — not for the ordinary gated case above, which never needs it:
aiwf promote E-NNNN active --force --reason "<one-sentence justification>"
The standard provenance-coherence rule still requires the --force invocation itself to come from a human/ actor, so the override remains human-sovereign by construction. Use it sparingly; the default gated path above is the right one.
This is commit 1 — the verb writes exactly one commit on main with the standard aiwf-verb: promote, aiwf-entity: E-NNNN, aiwf-actor: human/<id> trailers.
7. Sovereign authorize (only if delegating)
If step 5 chose delegation, the operator runs (still on main):
aiwf authorize E-NNNN --to ai/<id> --branch epic/E-NNNN-<slug> --reason "<one-sentence rationale>"
The --branch flag names the future epic branch — the one step 8 will cut. The branch does not yet exist when this verb runs. The kernel's AI-target preflight permits this combination via the from-main --branch carve-out: from a checkout on main, an explicit --branch whose value matches the ritual shape (epic//milestone//patch/ per internal/branchparse/) accepts even when the named branch does not yet exist. The commit's aiwf-branch: trailer carries the future ref; step 8's branch cut closes the binding.
This is a separate commit from step 6. The scope is active from this commit forward; the agent operates within it until the epic reaches a terminal status or the operator pauses the scope.
If the operator is NOT on main when this step runs (e.g. they jumped to a feature branch first), the preflight classifies the current checkout's rung against the --branch target's rung; a pair that isn't a legal ritual flow (here trunk → epic) refuses with rung-pair-illegal, naming both branches' rungs. (Omitting --branch from a non-ritual checkout instead refuses with branch-context-required.) The override path is the same sovereign-act shape:
aiwf authorize E-NNNN --to ai/<id> --branch epic/E-NNNN-<slug> --force --reason "<one-sentence justification>"
The --force invocation requires a human/ actor, so the override remains human-sovereign by construction. The default path (operator on main, no --force) is the right one.
If step 5 chose in-loop, skip.
8. Worktree placement and branch creation (Q&A)
Lead with the default: in-repo placement under the configured worktree.dir (default .claude/worktrees/<branch>/). In-repo is the default because a Claude Code session in a sandboxed devcontainer is confined to the workspace folder — a sibling or $HOME worktree is unreachable as the session's cwd (so cwd-derived surfaces like the statusline never follow the work) and a $HOME-placed one is wiped on container rebuild. In-repo worktrees are reachable as the session cwd, persistent under the mounted workspace, and gitignored (.claude/*).
The default is a recommendation, not a lock — the per-invocation override stays. The choice still matters (parallel work, IDE state, aiwf check blast radius), so surface the three placements and let the operator override:
.claude/worktrees/<branch>/(in-repo worktree — the default). Created withaiwf worktree add epic/E-NNNN-<slug>— the verb resolves the path from the sameworktree.dirknob rather than hardcoding it, and materializes rituals (skills, agents, templates, guidance) into the new worktree atomically, in one step. Survivesgit checkouton the main worktree; gitignored; reachable as a sandboxed session's cwd. Recommended placement (see the in-repo placement convention).- No worktree, work directly on the epic branch in the main checkout. The operator's existing checkout switches to
epic/E-NNNN-<slug>viagit checkout -b. Simplest; no extra checkout state to manage. Trade-off: no isolated playground if the epic gets contentious. ../aiwf-<branch>/(sibling-directory worktree). Created withaiwf worktree add epic/E-NNNN-<slug> ../aiwf-<branch>— an explicit path is honored verbatim, never redirected back in-repo. Fully isolated path. Trade-off: unreachable as the working directory of a session started in the repository — work there needs its own session or a dispatched subagent — andfind-based tools rooted at the original repo do not see it.
The branch shape follows the branch-model convention: ritualized work on epic/E-NNNN-<slug>. If step 7's authorize commit was produced (delegated case), the branch name is already in the trailer — this step cuts that exact ref. If step 5 chose in-loop, the operator still cuts epic/E-NNNN-<slug> (the same naming convention; no aiwf-branch: trailer was emitted upstream, but the convention is the same).
Execute the branch cut against the chosen placement: aiwf worktree add --print-path for placements 1 and 3 — confirm materialization afterward with aiwf doctor --root <path>, which reports rituals as materialized with no separate aiwf update step needed — or plain git checkout -b for placement 2 (no new worktree, nothing to materialize; the current checkout already has its skills, agents, templates, and guidance). The branch operation itself does not produce an aiwf commit; it is plain git plumbing. For placement 1, if you (the calling session) are going to keep working in the new worktree yourself — as opposed to dispatching a subagent — move into it with cd "<printed path>". Use cd, not the EnterWorktree tool: a session entered that way cannot reach mainline's worktree, where aiwfx-wrap-epic merges. Stay inside the repository while you work there: a cd to a directory outside it returns the session to the directory it started in, not to this worktree, so run anything that needs another directory in a subshell, ( cd <dir> && … ). For the same reason a session started in the repository cannot move into a placement-3 worktree with cd; start a new session there, or dispatch a subagent with its path.
9. Hand-off
The epic is now active, the branch is cut, and the operator's HEAD is on epic/E-NNNN-<slug> (in the chosen worktree). The natural next step is aiwfx-start-milestone <first-M> (typically the lowest-numbered draft milestone under this epic).
If a delegation scope was opened in step 7, the hand-off is to the named agent (the subagent-spawn mechanics are Claude Code surface, outside this skill's scope). The operator names the receiving agent and transmits the milestone id; the agent then enters aiwfx-start-milestone itself.
Constraints
- 🛑 Never commit or push without explicit human approval. Step 6's promotion and step 7's authorize each require human confirmation.
- 🛑 Sovereign promotion requires the operator's explicit per-invocation approval. Per the kernel's sovereignty rule,
aiwf promote E-NNNN activefrom a non-human actor is refused unless--force --reason "..."is used. Present the exact command as an approve/deny gate; run it directly on approval with no--actoroverride — never on a standing "go ahead" from earlier in the conversation. - 🛑 Sovereign acts land on
mainbefore the branch cut. Steps 6 and 7 run with HEAD onmain; step 8 cuts the epic branch afterwards. The kernel's preflight enforces this for the authorize commit (the from-main--branchcarve-out allows the--branch <future>form frommain). - The promotion commit and any authorize commit are separate. One verb = one commit.
- Worktree placement defaults to in-repo under the configured
worktree.dir(the in-repo placement convention), but the default is a recommendation, not a lock — the per-invocation override (main-checkout / sibling) stays a Q&A choice. The branch shape follows the branch model —epic/E-NNNN-<slug>— and is not surfaced as a prompt.
Anti-patterns
- Skipping the drafted-milestone check. The epic activates with nothing queued; the next thing that happens is friction.
- Running
aiwf promote E-NNNN activewithout the operator's explicit per-invocation approval. The approve/deny gate is the sovereign act; treating an earlier "go ahead" as standing approval defeats the point. - Passing
--actor ai/<id>on the ordinary gated path. That deliberately trips the kernel's sovereignty refusal for no reason; the bare command already resolves to the operator's own identity. Reserve a non-human actor for the genuine delegated/recovery exceptions the--force --reasonoverride path covers. - Bundling the promote and authorize commits. One verb = one commit. A combined commit is two acts at one timestamp and breaks
aiwf history. - Hardcoding the worktree directory instead of reading
worktree.dir. The default is in-repo (the in-repo placement convention), but the resolved directory comes from theworktree.dirknob viaaiwf doctor— baking.claude/worktreesinto the prompt silently ignores a consumer's override. - Dropping the override to force in-repo. In-repo is the default, not a lock; the sibling and main-checkout placements stay selectable (a bare host with no sandbox confinement may legitimately prefer a sibling).
Next step
→ aiwfx-start-milestone <M-NNNN> for the first drafted milestone in the epic.