# Solo

> Unattended run from a spec - or from instructions typed straight into the invocation, or already settled in this conversation, in which case the spec gets written for you. Plan, execute, decide, log every call for audit, and survive a session-limit hit: the run checkpoints to disk and a launchd watcher boots a fresh session from it. Closes with an HTML run report - timeline, decisions, hiccups - and optionally a delivery check and a correctness review that fix what they find. /solo <spec-path|instructions> emits a mandate to paste into a fresh session; /solo go ... runs it here, now.

- Skill: `marekpolcar/solo` (Agent Skill, multi-file: 7 files)
- Install (CLI): `npx skillmds@latest add marekpolcar/solo`
- Raw SKILL.md: https://api.skillmd.com/api/skills/marekpolcar/solo/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: marekpolcar (https://skillmd.com/u/marekpolcar)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/marekpolcar/solo

---


# Solo - Unattended Execution Contract

## Overview

An unattended run succeeds or fails on **the mandate**. No one is steering, so every guardrail it needs must be written down before it starts. This skill turns a spec/design doc/task brief - **or the operator's raw instructions, from which it writes the spec itself** - into **one self-contained mandate**: planning, executing, making its own calls, verifying, and **logging every decision for the operator to audit afterward**.

The deal it encodes: **full decision authority for the model, full auditability for the operator.**

The auditability half is not the decision log alone. A run that worked for six hours ends by writing an **HTML run report** - the timeline, every decision with its rejected alternative, every hiccup with its dead ends, what is verified and what is not - because a one-screen markdown summary cannot carry six hours. And two optional phases put the delivery under review *before* that report is written: `--check-delivery` measures it against its own spec and fixes what it finds, `--review` puts an adversarial correctness panel on the result.

It is task-shaped, not build-shaped: a build, a migration, a refactor, an audit, a research sweep - anything with an acceptance bar. A spec **file** is optional; an acceptance bar is not.

**A run long enough to be worth doing unattended is long enough to hit the session limit.** That limit *ends the session* - there is no live conversation left, and `claude --resume` on a limited account fails the same way. So this skill assumes the run will be killed mid-flight and builds for it: the run checkpoints its state to disk as it goes, and a launchd watcher (`scripts/solo-watch.sh`) boots a **fresh** session from that state when the account comes back. Both halves are mandatory - a watcher with nothing checkpointed resumes into amnesia, and checkpoints with no watcher wait for a human to notice.

**`<solo-dir>` is this skill's own directory - resolve it once, now.** It is the absolute path of the directory holding this `SKILL.md`: `$CLAUDE_PLUGIN_ROOT/skills/solo` when this was installed as a plugin, `~/.claude/skills/solo` when it sits in user scope. Every `<solo-dir>/...` path below is written for a session that does **not** have this skill loaded - the pasted mandate and the watcher's resume prompt both start in a fresh one - so **substitute the resolved absolute path before you write either of them**. Left as a placeholder, or shortened to a relative path, it resolves to nothing there, and the run loses its watcher and its closing phases without saying so.

## Two modes - decide this FIRST, before anything else

The operator typed: **`$ARGUMENTS`**

Read that line. It is the whole invocation, verbatim, and it decides the mode:

| That line contains | Mode | What you do |
|---|---|---|
| `go`, `--go`, "run it now", "run it here", "in this conversation", "don't give me a prompt, just do it" | **GO** | Assemble the mandate, write it to `<abs>/mandate.md`, then **adopt it as your own instructions and run it to completion in this conversation**. |
| anything else - including empty | **EMIT** (default) | Assemble the mandate, print it + `pbcopy` it, then **STOP**. |

**Ambiguous → EMIT.** Emitting when they wanted GO costs one paste. Running when they wanted a prompt burns an unattended run into a context they meant to keep clean, and there's no undo.

The watcher is armed in **both** modes by default. If that invocation line contains `--no-watch` (or "no watcher", "don't install anything"), drop the arming steps only - mandate step 1 and §6b step 2. Still write `resume-prompt.md` and still checkpoint: the run then dies for good at the session limit unless a human restarts it, and that paste is what makes the restart one keystroke instead of an archaeology session.

This skill only ever runs because the operator typed `/solo` - never because it looked relevant. So the invocation line above is a deliberate instruction, not an inference: take the mode from it literally rather than from the surrounding conversation's mood.

### Closing-phase flags - read them off the same line

| Flag | Effect |
|---|---|
| `--check-delivery` | After the work, run the sibling `check-delivery` skill against the run's own plan and spec, and **fix what it finds**, under the fix policy in `references/closing-phases.md`. |
| `--review` | After that, dispatch an adversarial **correctness** panel over the final state and fix what it finds, same policy. |
| *(default, always on)* | Write the **HTML run report** to the repo's reports directory or `<run-dir>/report.html`. |
| `--no-report` | Skip the HTML report only. `report.md` is still written; it is the terminator. |

Both review flags are off unless asked for. `--check-delivery --review` is the pair worth having on anything that will ship: the first asks *does this match what it was supposed to be*, the second asks *does this code work* - and the second reviews the first one's fixes, which is code nobody else has looked at.

**Recognise `--flag` forms anywhere in the line.** A bare `review` or `check-delivery` counts as a flag only when the rest of the invocation is a path plus short flags. Inside prose instructions it is part of the spec, not a flag - `/solo go build me a code review dashboard` requests a dashboard, and turning that into a review phase is the mirror of the routing mistake above.

The full contract for these phases - ordering, the fix policy, the interactive stops that have to be answered in advance - is `references/closing-phases.md`, and the report's is `references/run-report.md`. Read the one you need before running that phase, not while.

## When to use

- You have a spec/design doc/task brief and want it **carried out end-to-end unattended** - the model decides, you review its calls and the result afterward.
- Or you have **no spec file at all** - just what you typed into the `/solo` line, or what this conversation already settled. Step 1 writes the spec from that copy; you don't go find a document first.

**Not** when: the intent itself is still unsettled - you can't yet say what "done" looks like, so there is nothing to derive an acceptance bar from (brainstorm first; a topic is not a spec) · you'll supervise step-by-step (`runbook-execute`) · you're continuing in-flight work (`handoff`) · it's an ops deploy/migration runbook (`runbook-autoexecute`).

## ⚠️ In EMIT mode you generate the mandate - you do NOT execute it

The single biggest failure here: the invoking agent reads "fully build this" and starts planning/implementing. **Don't - unless the invocation said `go`.** In EMIT mode your only job is to emit the mandate and stop. Do not create the plan, do not write code, do not spawn subagents, do not touch the spec's targets. Output the mandate, then stop.

EMIT writes exactly three files: `<run-dir>/spec.md` when the spec had to be derived (§1), `<run-dir>/resume-prompt.md` (§4), and `/tmp/claude-solo.md` for the clipboard. That is the whole disk footprint - and none of it is a head start on executing: the spec and the resume prompt are inputs the pasted session needs on disk before its first move, not work done on its behalf. It arms the watcher, plans, and builds. You don't.

The mirror failure is just as bad: invoked with `go`, emitting a prompt and stopping. `go` means the operator wants the work done here, now - handing them a block to paste is a non-answer.

## Procedure

### 1. Resolve the spec - find one, or write one

Two invocation shapes, both first-class:

- `/solo docs/plans/thing.md` - **a spec file.** Use it as written. This is unchanged from before, and it stays the best input when one exists.
- `/solo build me X that does Y` - **no file.** The instructions are the spec; you write it down.

**Either way, never ask for a spec path.** A spec *file* is optional; instructions are not, and the operator has already given them. Take the highest-precedence source present:

| What you have | The spec is | Everything else becomes |
|---|---|---|
| A path to a spec / design doc / plan in the invocation | that file, unchanged | any prose typed alongside it → extra constraints in the mandate's **Scope** |
| Instructions typed into the `/solo` line itself | **derived - you write it** | this conversation → supporting facts (paths, hosts, names, calls already made) |
| Neither, but this conversation settled what to do | **derived - you write it** | - |
| Neither, and the intent is still open | nothing yet - **stop and say so** | - |

**Floor test, before deriving anything: can you write concrete, checkable acceptance criteria from what you have?** If no, you're holding a topic, not a spec - say that in one line and stop. Everything downstream assumes an acceptance bar exists; an unattended run without one doesn't finish, it drifts.

#### With a spec file

Read it. **If what you were handed is an implementation PLAN rather than a spec - or a plan plus its spec plus a review log - do not rewrite any of them, and do not author a second plan.** Write `<run-dir>/plan.md` and `<run-dir>/spec.md` as one-line pointers at the real paths, because `closing-phases.md` and the resume prompt both resolve those two names and will otherwise find nothing. Then write the 1-3 sentence gloss the mandate needs, and lift its acceptance criteria into `Done =` (§3) - quoted, not paraphrased. Don't rewrite the spec, don't restructure it into the six-section shape below, don't move it: it is already the contract, and the operator wrote it.

The floor test still applies. A supplied plan or design doc often has **no** acceptance bar of its own - if so, derive one from it, and flag it in the mandate as your addition (`← EDIT`) so the operator can correct the one thing the run will stop on.

#### Without one - deriving a spec: capture, don't design

You are transcribing what the operator asked for into a checkable shape - not designing the thing for them. Every requirement traces to something they actually said. A gap you had to fill goes under **Assumptions**, never silently into Requirements. This run is unattended: a requirement you invented here gets *built*, by an agent with full decision authority, and nobody sees it until the report.

Write it to `<run-dir>/spec.md`. All six sections, even where one is a single line:

| Section | Contains |
|---|---|
| `Provenance` | Derived, not operator-written - and from what: the invocation line, this conversation, or both. |
| `Objective` | One sentence: what exists at the end that doesn't now. |
| `Requirements` | What they asked for, itemised, traceable to their words. |
| `Done means` | Concrete checkable acceptance criteria. This is what stops the run. |
| `Out of scope` | What you are deliberately NOT doing. Derived specs over-scope; this is the brake. |
| `Assumptions` | Every gap you filled yourself, each with the reading you chose. These become decision-log entries #1 onward. |

**EMIT mode:** the derived spec goes into the mandate *inline* (§3) - it is the artifact most likely to be wrong, so the operator must read it in the block they're about to paste, not trust a path they'll never open. Mark `Assumptions` `← EDIT`. Don't interrogate them about it; they're reviewing before pasting.

**GO mode:** derive, write `spec.md`, log every Assumption to the decision log **before starting work**, and name the spec path + assumption count in the one-line announcement (§6b). That's the operator's cheap interrupt point if they're watching. Do **not** ask them to confirm the spec - `go` delegated that call with the rest.

### 2. Gather the rest of the inputs

- **Run directory** - one directory holds every artifact: `spec.md`, `mandate.md`, `plan.md`, `progress.md`, `decision-log.md`, `resume-prompt.md`, `report.md`, `reviews/` when a closing review ran, plus the watcher's own `.watch/`. (The HTML report is the one artifact that may live elsewhere - it moves to the repo's reports directory when there is one, so it can link that directory's stylesheet.) Default `<repo>/docs/superpowers/solo/<slug>/` inside a repo - alongside `plans/` and `runbooks/`, so a solo run files where the other superpowers artifacts already live. Outside a repo, `~/.solo/<slug>/`. Absolute paths everywhere downstream. The `<slug>` also names the launchd job (`local.solo.<slug>`, or `$SOLO_LABEL_PREFIX.<slug>` when that is set), so keep it short and unique.
- **Scope & environment** - default to **local-only** (local FS, local Docker; building images on a build host is OK; no remote/prod, no push, no deploy).
- **Commit policy** - local commits OK / leave uncommitted / commit-but-don't-push.

**EMIT mode:** pre-fill from the spec/repo and confirm with the user - they review before pasting, so prefer a sensible default + a clear `← EDIT` marker over interrogation.

**GO mode:** do **not** confirm anything. `go` already delegated these calls to you. Pick the most reasonable default for each, and record them as the first entries in the decision log.

### 3. Assemble the mandate (the contract)

Fill every angle bracket. Keep every section - the autonomy rules are what make it work unattended. In GO mode this text is your own instruction set, so fill it just as concretely; "I know what I meant" is not auditable.

```markdown
# Autonomous run: <one-line objective>

You are running UNATTENDED with full decision authority. No one is steering this run; the operator will review your decisions and verify the result afterward. Work autonomously to completion - do not wait for input; there is no one to answer you.

## Spec
<Operator-written spec file - point at it:>
Do exactly what this defines: `<absolute/path/to/spec.md>`
<1-3 sentence gloss so you're oriented before opening it.>

<Derived spec - paste the whole thing here verbatim instead, then this note:>
This spec was derived from the operator's instructions, not written by them; an identical
copy is at `<run-dir>/spec.md`. It is the contract - **execute it, do not re-derive it.**
Its `Assumptions` are calls already made on your behalf: adopt them, and log it in the
decision log if the work forces you to revisit one.

## Mandate
1. **Arm the watcher first, before any work** - it is what keeps this run alive if the session limit ends you:
   `bash <solo-dir>/scripts/solo-watch.sh arm <abs/run-dir> --workdir <abs/repo-root> --model opus <--add-dir <path> per extra repo>`
   then claim the lock so it doesn't start a second session alongside you:
   `bash <solo-dir>/scripts/solo-watch.sh hold <abs/run-dir> $PPID orchestrator`
2. Create the plan (use the writing-plans skill); write it to `<abs/plan.md>` so it can be audited afterward - **or, if the operator supplied a plan, execute THAT and do not write another; `<abs/plan.md>` is then a one-line pointer at it** - and seed `<abs/progress.md>` with one row per plan step, all `pending`, **followed by the closing rows C1-C4** below. Seed them now, not at the end: they are what tells a resumed session the run still owes a review and a report.
3. Then execute it to **fully working** - proven by RUNNING it, not by reading the code. Use executing-plans / subagent-driven-development.
4. Run until done or genuinely blocked. Done = <concrete acceptance checks for THIS task, e.g. "stack comes up; end-to-end flow X returns Y; tests green" - with a derived spec, write `the spec's "Done means", in full` and copy it, rather than paraphrasing it into a second, drifting bar>.
5. **Then close the run, in this order** - read `<solo-dir>/references/closing-phases.md` before starting C1 or C2, and `<solo-dir>/references/run-report.md` before C3:
   - **C1 <--check-delivery: on | off - not requested>.** Run the sibling `check-delivery` skill against `<abs/plan.md>` + `<abs/spec.md>` and this run's change. Fix BLOCKERs and contained in-scope MAJORs; never MINORs, never anything out of scope. Re-run the gates AND re-prove `Done means` afterward. Two fix rounds maximum, then the rest is residual risk.
   - **C2 <--review: on | off - not requested>.** Dispatch an adversarial correctness panel over the FINAL state - after C1's fixes - plan-agnostic, gates run first, C1's findings passed forward as already-handled. Same fix policy, same re-verification, same two-round bound.
   - **C3 <report: on | --no-report>.** Write the HTML run report: timeline, every decision, every hiccup, findings and their outcomes, what is unverified. Link the repo's shared reports stylesheet when it has one.
   - **C4.** `report.md`, then `release`. In that order, last, once.

## Autonomy rules (you are unattended)
- **Decide, don't ask.** At any fork, pick the most reasonable option and KEEP GOING. Never stop for a clarifying question - you hold the decision authority here.
- **Log every decision AND every hiccup, as it happens.** Append to `<abs/decision-log.md>` as you go, one typed, timestamped entry per event: `[decision]` a non-trivial choice, with its rationale and the alternative you rejected · `[assumption]` a gap you filled that the spec did not settle · `[hiccup]` something that went wrong - the symptom, what you tried that did not work, what it actually was, what it cost · `[fix]` a review finding you corrected · `[blocker]` something you could not get past. This log is how the operator reviews your judgment afterward, and it is the sole source for the run report's timeline: **an event that is not in it did not happen**, as far as the report and the operator are concerned. Write hiccups when they happen, never reconstructed at the end - the session that hits them is often not the session that finishes.
- **Keep the main thread lean.** Dispatch a subagent per discrete subtask (build, test, wire-up, debug) so the orchestrating thread stays low-context for the whole run. Main thread = plan, batch, dispatch, integrate, run the gates. Read only what you must verify yourself.
- **Batch the work into waves BEFORE dispatching anything.** Do not walk a task list one at a time, and do not fire every task at once. Extract each task's file list first - one grep or awk over the plan is enough - build the conflict map, and group tasks into waves where **no two agents in a wave touch the same file**. Run each wave in parallel and integrate at its boundary. This is what makes parallelism safe AND what makes it cheap: fewer, larger agents beat many small ones, and each wave boundary is a natural checkpoint. Say the wave plan out loud in `progress.md` so a resumed session inherits the grouping instead of re-deriving it.
- **Spend each agent's context deliberately.** Give it the line range of its own task, not the whole document ("read lines 1-66, then Task 4: lines 777 to 1306; do not read other tasks"). Paste the contract it codes against - exported signatures, schema names, the shape of an already-landed dependency - instead of making it go and discover them. Tell it which commands NOT to run. An agent that reads 2800 lines of plan to do one 200-line task has spent your budget on orientation.
- **One agent per file, and assume the tree is shared.** Never dispatch a second agent onto work already in flight. Every brief carries: the exact files it owns, an explicit "N other agents are editing this tree right now", a ban on unfiltered `typecheck` / `test` / `lint` / build runs (they report a peer's half-written file and send the agent "fixing" code it does not own), and "do not stage or commit - the orchestrator commits". **No agent's own gate run is authoritative while the tree is shared**; the number that goes in the report is one cold run after every agent has finished.
- **Silence is not a verdict, and it is not a stall either.** Expect agents to finish and go idle without their report reaching you - it happened to most of them on the run these rules come from. Ask ONCE for the verdict in the shape you specified. If it does not come, **verify from the tree yourself**: the evidence is on disk, and re-reading it beats a second chase. But never start doing an agent's work while it is still listed as running - check first, because a quiet agent is usually writing up, and duplicating it burns real money on a paid path.
- **Right-size the model per subtask.** Dispatch each subagent with the cheapest model that can do its job well: a small/fast model (e.g. Haiku) for mechanical work - boilerplate, formatting, file moves, scaffolding tests, log/grep sweeps; a mid model (e.g. Sonnet) for routine implementation; reserve the strongest model (e.g. Opus) for planning, cross-cutting integration, and hard debugging. Keep the orchestrating main thread on the strong model. When genuinely unsure which tier fits, step up one - a cheap wrong answer costs more than a right one.
- **Verify before "done."** Use verification-before-completion: run the thing, capture the evidence. No "should work."
- **Checkpoint after every step, before starting the next.** Land the step COMPLETELY - edits made, gates run, evidence captured - then update `<abs/progress.md>`, append to the decision log, and refresh the watcher's lock (`solo-watch.sh hold <abs/run-dir> $PPID orchestrator`). You do not get to choose when you are killed. A half-done step with nothing written down is the one failure this harness cannot recover from.
- **Hard-stop only** for a true safety-boundary breach or an unrecoverable external blocker - and even then, log it, leave a clear note, and keep progressing everything else.

## If this session dies
The Claude Code session limit will end you mid-run without warning, and the account may be parked for hours. That is expected and handled: an hourly launchd watcher boots a **fresh** session from `<abs/resume-prompt.md>` once the account is usable again. It has none of your context - only what you wrote to disk. So the checkpoint rule above is not bookkeeping, it is the entire recovery mechanism. Never leave a step in flight across a checkpoint boundary you could have closed.

## Scope & environment
- Boundary: <local-only - local FS + local Docker; build images via <build host> OK; do NOT touch remote/prod, do NOT push, do NOT deploy>  ← EDIT
- Facts you can rely on: <e.g. "Docker is already running locally"; "build images via <user>@<build-host>">
- Commits: <local commits OK / leave uncommitted / commit but DON'T push>.

## Deliverables (for the operator's review)
When done (or blocked), produce:
- The **decision log** at `<abs/decision-log.md>` - every call you made with its rationale, and every hiccup with what it cost.
- The **progress table** at `<abs/progress.md>`, every row terminal, C1-C4 included.
- **What it cost**, when the run was authorised to spend real money: the total, the unit cost, and a flag when the unit cost is not what the plan assumed. An authorisation is a budget, not a blank cheque.
- The **review logs** at `<abs/reviews/>`, when C1 or C2 ran: findings, what was fixed, what was left open and why, and the gate output that proves it.
- The **HTML run report** at `<the reports dir>/<date>-solo-<slug>.html`, or `<abs/report.html>` when the repo has no reports directory - the audit page: timeline including any session death, decisions, hiccups, findings, residual risk, verification commands.
- A **report** at `<abs/report.md>` plus a one-screen final message: what was done, key decisions + why, what's verified (with evidence), what's incomplete or risky, exact steps for the operator to verify, and the HTML report's path on the first screen.

`report.md` is the run's terminator: the watcher sees that file and disarms itself. So write it LAST - after C1, C2 and the HTML report, and only when the run is genuinely over. A `report.md` written early ends the run's ability to resume, and a limit hit during a review it claimed to have finished ends the run for good. Then hand the baton back:
`bash <solo-dir>/scripts/solo-watch.sh release <abs/run-dir>`
```

`progress.md` is the only artifact a resumed session reads to decide **what to do next**, so keep it boring and scannable - one row per plan step, status ∈ `pending | in-progress | done | skipped | blocked`, and evidence that is a command or a path, not an adjective:

```markdown
| # | Step | Status | Evidence / note |
|---|---|---|---|
| 1 | scaffold package + tsconfig  | done        | `pnpm -F @x/y build` exits 0 |
| 2 | wire the /doctor route       | in-progress | route added, no test yet |
| C1 | check-delivery + fixes      | pending     | flag: --check-delivery |
| C2 | correctness review + fixes  | skipped     | --review not requested |
| C3 | HTML run report             | pending     | |
| C4 | report.md + watcher release | pending     | terminator, last |
```

`in-progress` on resume means *that step was interrupted* - re-verify it before continuing, don't assume either half. The C-rows are seeded with the plan, never appended at the end: a run that dies after the work resumes with no idea a review was owed unless the row is already there. A phase that wasn't requested is seeded `skipped` **with the reason**, because a resumed session cannot otherwise tell "not requested" from "not reached".

`decision-log.md` is append-only, one typed entry per event, newest last. The type and the timestamp are what let the run report build a timeline it can defend:

```markdown
## 2026-08-06T09:31:04+02:00 - [decision] Redis for the cache, not an in-process map
**Chose:** shared Redis via the existing client.
**Because:** two replicas are in the plan; an in-process map goes stale per replica.
**Rejected:** in-process LRU - simpler, but wrong the moment step 7 scales it.
**Shows up in:** `src/cache.ts:14`

## 2026-08-06T10:02:11+02:00 - [hiccup] per-package build can't resolve outDir
**Symptom:** `pnpm -F @x/y build` exit 2, `error TS5033`.
**Tried:** root `tsconfig` paths, then `--outDir` on the CLI - neither took.
**Was:** the per-package tsconfig inherits no `outDir` from the root one.
**Resolution:** explicit `outDir` per package - `packages/y/tsconfig.json:6`; build exits 0.
**Cost:** ~12 min, 2 dead ends.
```

Timestamps from `date +%FT%T%z`. Free-form prose is better than nothing, so never drop an entry because you can't shape it - but an untimestamped log makes the report's timeline unbuildable, and the report will say so rather than invent one.

### 4. Write the resume prompt - the run's second life

Write `<run-dir>/resume-prompt.md`. This is what a **fresh, zero-context** session is booted with when the limit kills the run - the watcher feeds it on stdin and nothing else. Both modes need it, and it must exist *before* the watcher is armed (`arm` refuses without it).

It is not a copy of the mandate. The mandate says what to do; the resume prompt says *you are mid-run, here is where the previous session got to, don't redo it*. Template:

```markdown
You are resuming an unattended run that a previous session started and could not finish - most
likely because the Claude Code session limit ended it mid-flight. Nothing about that session is in
your context. Everything that survived is on disk.

## The contract
Read `<abs/mandate.md>` in full and execute it. It is the whole brief: objective, spec, autonomy
rules, scope, deliverables. Do not re-derive it and do not renegotiate it.

## What already happened - read before touching anything
1. `<abs/progress.md>` - per-step status. Anything `done` is DONE. Re-running it burns the budget
   that got you here and can undo working code.
2. `<abs/decision-log.md>` - the calls already made. Adopt them; do not relitigate them.
3. `<abs/plan.md>` - if it exists, EXECUTE it, do not rewrite it. If it does not, write it first
   (writing-plans), then execute.

## How to work
- Take the first non-terminal step in `progress.md` and finish it COMPLETELY - edits, gates run,
  evidence captured, `progress.md` updated, `decision-log.md` appended - before starting the next.
  You do not get to choose when you are killed.
- Refresh the watcher's lock at every checkpoint, so it does not start a second session on top of
  you: `bash <solo-dir>/scripts/solo-watch.sh hold <abs/run-dir> $PPID orchestrator`
- Do not ask questions. The operator is away. Record the assumption in `decision-log.md` and keep
  going.

## Hard boundaries (restated because you have no memory of them)
<the mandate's Scope & environment bullets, inline and verbatim>

## The run is not over when the code works
`progress.md` ends with rows `C1`-`C4`. They are steps like any other and they are the
reason the run may still be alive: the work being finished is not the finish line.
- `C1` / `C2` - a delivery check and a correctness review, each of which FIXES what it
  finds. Read `<solo-dir>/references/closing-phases.md` before either. A row
  marked `skipped` was not requested; leave it alone.
- `C3` - the HTML run report. Read `<solo-dir>/references/run-report.md`. You
  were not here for most of this run: build it from `progress.md`, `decision-log.md` and
  `.watch/runner.log`, and do not invent an event you cannot source. The session deaths in
  that log - including the one that ended the session before you - belong on the timeline.
- `C4` - `report.md`, then release. In that order, last.

## When you are done
Write `<abs/report.md>` - that file is what ends the run and disarms the watcher, so it
comes AFTER C1-C3, never before - then
`bash <solo-dir>/scripts/solo-watch.sh release <abs/run-dir>`.

Start now.
```

**Inline the boundaries, don't reference them.** Everything else in this prompt is a path the resumed session reads; the boundaries are the one thing that must survive a failed read, because the resumed session runs with `--dangerously-skip-permissions` and they are all that stands between it and a production host.

### 5. Review before delivering

- **Self-containment** - reread as a stranger with zero memory of this chat. Every path/name/entity resolves from the mandate alone. This holds in GO mode too: you will be dispatching subagents that have none of this context. **Sharpest on a derived spec:** its source was a conversation the executing session cannot see, so anything you left implicit ("the usual host", "as discussed") resolves to nothing.
- **Acceptance bar is checkable** - read `Done means` as the agent that has to stop on it. "Works correctly" is not a stopping condition; "`./run.sh` exits 0 and `GET /health` returns 200" is.
- **All autonomy rules present** - decide-don't-ask, decision + hiccup log for audit, checkpoint-per-step, subagent orchestration, per-subtask model right-sizing, verify-before-done, hard-stop boundary. Dropping any one is the difference between a completed unattended run and one that stalls at the first question or comes back unauditable.
- **The closing sequence is in the mandate and in `progress.md`** - C1-C4 named, the requested flags resolved to on/off in writing, and `report.md` unambiguously last. A closing phase that exists only in your head is a phase a resumed session will not run.
- **The resume prompt survives amnesia** - reread it as a session that has never seen this repo. Absolute paths, boundaries inline, and a first move that is unambiguous.

### 6a. EMIT mode - deliver and stop

```bash
cat > /tmp/claude-solo.md <<'SOLO_EOF'
<the exact assembled mandate, verbatim>
SOLO_EOF
pbcopy < /tmp/claude-solo.md
```

Print the **same** text in a fenced ` ```markdown ` block, then close with one line:

```
✓ solo mandate copied - paste into a FRESH conversation (clean context is the point of an unattended run)
```

Then stop. Nothing else. **You do not arm the watcher in EMIT mode** - the pasted session does, as step 1 of its mandate, because it is the session that needs surviving. Arming here would point the watcher at a run nobody has started.

### 6b. GO mode - execute it here

1. **Write the mandate** verbatim to `<abs>/mandate.md`, next to the spec, plan and decision log. This is the contract you are about to execute; the operator audits the run against it. Don't print the whole block - print the objective line, the boundary line, and the deliverable paths.
2. **Arm the watcher, before any work.** `solo-watch.sh arm <run-dir> --workdir <repo-root> --model opus <--add-dir ...>`, then `solo-watch.sh hold <run-dir> $PPID orchestrator`. This session is the one the limit will kill; arming after the work has started means the run dies in whatever state it reached. Skip only on `--no-watch`.
3. **Announce once**, one line: `Running solo - mandate at <path>, decisions logged to <path>, watcher <label> armed, closing with <check-delivery + review + report | report only>. Reporting when done or blocked.` If the spec was derived, say so and give the count: `spec derived to <path> (N assumptions logged)`.
4. **Adopt the mandate as your own instructions** and follow it from the top. Every autonomy rule now binds *you*: decide-don't-ask, log every decision, checkpoint every step, subagent per discrete subtask, right-size the model per subtask, verify by running, hard-stop only on a safety breach.
5. **Context is the constraint.** Unlike a fresh session, this conversation has already spent context - that's the cost of `go`. Compensate by dispatching harder than you otherwise would: main thread does plan → dispatch → integrate, and nothing else. Reading files, grepping, running test loops, and debugging all belong in subagents.
6. **Dispatch is not a handoff.** A subagent you dispatched and haven't integrated is outstanding work, not progress. Wait for its result, verify it yourself, fold it in. **Wait by letting the harness notify you; do not poll in a loop** - a sleep-and-check cycle spends turns to learn nothing. **Never end your turn with dispatched work still in flight** - an orchestrator that dispatches and stops leaves the operator a "done" ping, half-integrated code, and no report. If a status line is the last thing you wrote ("dispatched X, waiting..."), the run is not finished; it is abandoned.
7. **Checkpoint at every integration point.** Each time you fold a subagent's work in: update `progress.md`, append to `decision-log.md`, and refresh the lock (`solo-watch.sh hold <run-dir> $PPID orchestrator`). The lock's 90-minute TTL is what tells the watcher you are gone - refreshing it is how you say you are not, and the checkpoint is what a resumed session inherits instead of your context.
8. **The operator may be watching, but you still don't ask.** `go` handed you the decision authority; a question is a stall. If they interject, treat it as new input, log it, and keep going.
9. **Run the closing phases** - C1, C2, C3, in that order, whichever are on. They are steps, not paperwork: C1 and C2 change code, and their fixes need the gates and the acceptance bar re-run before the run may call itself done. Checkpoint each row as you land it. `references/closing-phases.md` holds the fix policy and answers every question those reviews would otherwise stop and ask.
10. **Finish with the deliverables** - decision log, progress table, review logs, HTML run report, `report.md`, and the one-screen final message from the mandate. The report is not optional just because they can scroll up. **The run is over when `report.md` exists on disk, not when the code works** - and not before the closing phases have run, because that file disarms the watcher. Follow it with `solo-watch.sh release <run-dir>` so nothing waits on a TTL.

## Critical rules

- **Route first.** `go` → execute here. No `go` → emit and stop. Getting this backwards is the only way to fail this skill outright.
- **In EMIT mode: generate, don't execute.** Emit the mandate and stop. No planning, no code, no subagents.
- **In EMIT mode the run belongs in a FRESH session** - a clean context window is what lets it go the distance.
- **Never ask for a spec path.** No file? Derive the spec from the invocation line and this conversation, write it down, keep going. Asking is the stall this skill exists to prevent.
- **No spec file is fine; no acceptance bar is not.** Everything in a derived spec may be your reading of what they meant - except `Done means`, which has to trace to what they actually want, or the run has no stopping condition.
- **A derived spec is written down, or it does not exist.** In your head is unauditable - the operator has to be able to check what you thought they meant.
- **Keep every autonomy rule.** They're the guardrails for an unwatched run; don't trim them for brevity, in either mode.
- **The decision log is the contract.** Decision authority is only safe because every call is logged for audit - never drop that rule, and in GO mode never skip writing it.
- **Assume the session limit will kill this run.** It ends the session outright; `--resume` on a limited account fails the same way. Everything the next session needs must already be on disk when you die - that is what `progress.md` and the checkpoint rule are for.
- **Arm before working, never after.** A watcher armed at the end guards nothing. GO mode arms it as its second move; EMIT mode makes it step 1 of the pasted mandate.
- **`report.md` is the terminator.** It is what disarms the watcher, so it means *the run is over* - never write it as a progress note, and never before the closing phases have run.
- **The closing phases are steps, seeded with the plan.** C1-C4 go into `progress.md` when the plan is written, not when the work ends. A run that dies in between otherwise resumes believing it is finished.
- **A closing review fixes, it does not redesign.** BLOCKERs and contained in-scope MAJORs get fixed; MINORs and out-of-scope findings never do; two fix rounds, then residual risk. Every fix re-runs the gates and re-proves `Done means`.
- **Log the hiccups while they hurt.** The report's timeline is built from the log, not from memory, and the session that hit the problem is usually not the session that writes the report.
- **The run report is assembled from disk, never from recall.** Every event on it traces to `progress.md`, `decision-log.md`, a review log or `.watch/runner.log`. A thin log makes a thin page, and that is the honest outcome - an invented hiccup makes the whole page uncheckable.
- **EMIT: same bytes** in clipboard and printed block, **no prose around it** - the user is copy-pasting. **Absolute paths** with a one-line gloss, in both modes.

## Common mistakes

| Mistake | Why it's wrong |
|---|---|
| Asks the operator for a spec path when they typed the instructions inline | The invocation **is** the spec. Derive it, write it, keep going. |
| Operator pointed at a spec file, and it derives its own anyway | The mirror failure. A real spec outranks everything; use it as written, don't rewrite it into "your" shape. |
| Operator pointed at a spec file, and it ignores the prose typed alongside it | That prose is a constraint they added deliberately. File = spec, prose = extra Scope. |
| Derived spec grows requirements the operator never mentioned | Unattended means they get built and shipped unseen. Capture what was said; gaps go in `Assumptions`. |
| Derives a spec from a topic that has no acceptance bar | A run with no "done" doesn't finish, it drifts. Fails the floor test - stop and say so. |
| GO mode, derives the spec, then asks "is this right?" | `go` delegated that call too. Log the assumptions, announce the count, start. |
| Derived the spec but only in its head - no `spec.md` on disk | Unwritten = unauditable, exactly like an unwritten mandate. |
| EMIT mode, derived spec left as a path the operator won't open | It's the artifact most likely to be wrong. Inline it in the block they're pasting. |
| Invoked with `go`, still prints a prompt to paste | `go` means do the work. A block to paste is a non-answer. |
| Invoked without `go`, starts planning/implementing | The default is a mandate for a *fresh* session; executing here spends the context that run needs. |
| GO mode, asks the operator to confirm scope/paths first | `go` already delegated those calls. Pick defaults, log them as decisions. |
| GO mode, skips writing `man

…(truncated)
