|
| 1 | +--- |
| 2 | +name: deviate |
| 3 | +description: > |
| 4 | + Stop an in-flight assign-to-workforce run the moment execution must diverge |
| 5 | + from the confirmed plan, get explicit human approval for the divergence, and |
| 6 | + record it as a first-class, append-only deviation record via `devague |
| 7 | + deviate` before resuming — never fold a deviation silently into drift after |
| 8 | + the fact. Use when the user says "deviate from the plan", "we need to change |
| 9 | + the plan mid-run", "record a deviation", "this isn't matching the plan |
| 10 | + anymore", or when a task agent discovers the confirmed plan no longer |
| 11 | + matches reality partway through a workforce run. Authored and maintained in |
| 12 | + agentculture/devague (origin = devague); guildmaster pulls this skill from |
| 13 | + here and broadcasts it to the AgentCulture mesh — it is NOT vendored from |
| 14 | + guildmaster like the other skills here. |
| 15 | +type: command |
| 16 | +--- |
| 17 | + |
| 18 | +# deviate — record an approved mid-run departure from the confirmed plan |
| 19 | + |
| 20 | +The skill is named **`deviate`**; it is the **execution-time leg** of the |
| 21 | +devague method — the *sixth* leg, sitting between the two execution skills: |
| 22 | + |
| 23 | +```text |
| 24 | +scope -> think -> spec-to-plan -> assign-to-workforce -> deviate -> summarize-delivery |
| 25 | +``` |
| 26 | + |
| 27 | +Where `/assign-to-workforce` fans out a converged plan's waves and |
| 28 | +`/summarize-delivery` closes the loop afterward, `/deviate` runs **during** |
| 29 | +the fan-out, at the exact moment reality stops matching the plan the human |
| 30 | +approved at gate 2 (the implementation split plan). It is not a new standing |
| 31 | +gate — it is the human owner of gate 2 **amending** the approved split |
| 32 | +mid-flight, scoped to the one deviation in front of them. |
| 33 | + |
| 34 | +The plan the user confirmed is a contract. Task agents hit constraints, |
| 35 | +discover a dependency was wrong, or find the acceptance criteria no longer |
| 36 | +make sense once code is in front of them. Until this skill existed, that |
| 37 | +reality either silently reshaped what got built (undocumented drift) or the |
| 38 | +run stalled with no recorded path forward. `/deviate` is that path: the |
| 39 | +departure is named, approved, and recorded **before** anyone keeps building |
| 40 | +against it. |
| 41 | + |
| 42 | +## The method |
| 43 | + |
| 44 | +1. **STOP the run.** The moment a task agent (or the main agent) discovers |
| 45 | + the confirmed plan no longer matches what needs to happen, halt — do not |
| 46 | + keep implementing against the stale contract and do not let the fan-out |
| 47 | + continue past this task. |
| 48 | +2. **Present what, why, and what it affects.** Lay out, for the human: |
| 49 | + - **what** is diverging — the specific change from the confirmed task(s); |
| 50 | + - **why** — the constraint or discovery that forced it; |
| 51 | + - **what it affects** — the plan item ref(s) involved (`--task`), any |
| 52 | + other task ids or coverage targets it touches (`--affects`), and which |
| 53 | + acceptance criteria are no longer accurate. |
| 54 | +3. **Get explicit human approval.** This is the one non-negotiable step. A |
| 55 | + deviation is not real until a human says yes to *this specific* departure |
| 56 | + — not a standing blanket permission, not an inference from silence. |
| 57 | +4. **Record it via `devague deviate`.** Once approved, record the deviation |
| 58 | + as a first-class ledger entry (never edit the plan itself — the plan |
| 59 | + stays the untouched historical contract; see `devague/delivery.py`). An |
| 60 | + `--origin llm` record lands `proposed` and still needs the user's |
| 61 | + `--confirm` — recording is not the same as approval landing as final. |
| 62 | +5. **Adjust the affected task briefs.** Update the working instructions the |
| 63 | + task agent(s) are building against so they reflect the approved |
| 64 | + departure, not the stale plan text. |
| 65 | +6. **Resume.** Only after the record exists (and, for an `llm`-origin record, |
| 66 | + only after it is confirmed) does the fan-out continue. |
| 67 | + |
| 68 | +Deviations are never silently folded into drift after the fact — by the time |
| 69 | +`/summarize-delivery` runs, every departure from the plan already has a |
| 70 | +`dN` record with a reason, an approval, and an optional classification. The |
| 71 | +delivery summary quotes these records; it does not reconstruct drift from |
| 72 | +memory. |
| 73 | + |
| 74 | +## The shipped CLI surface |
| 75 | + |
| 76 | +This skill invokes the CLI directly and stays self-contained (if `devague` |
| 77 | +isn't on your PATH: `uv tool install devague`). Deviation state persists |
| 78 | +under `.devague/deliveries/<plan-slug>.json` — a peer of the plan store, keyed |
| 79 | +by the plan slug, and never touches the plan JSON itself. |
| 80 | + |
| 81 | +| Move | What it does | |
| 82 | +|------|---------------| |
| 83 | +| `devague deviate "<what>" --task <tN> --reason "<text>"` | Record a deviation against plan item `<tN>`. User-origin (the default) auto-approves. | |
| 84 | +| `devague deviate "<what>" --task <tN> --reason "<text>" --affects <ref> [<ref> ...]` | Same, also naming every other plan item ref or coverage target the deviation touches (repeatable). | |
| 85 | +| `devague deviate "<what>" --task <tN> --reason "<text>" --classification acceptable\|risky\|needs-follow-up` | Same, tagging the deviation with the classification the drift-entry contract consumes downstream. | |
| 86 | +| `devague deviate "<what>" --task <tN> --reason "<text>" --origin llm` | An LLM-proposed record; lands `proposed`, not `approved`. | |
| 87 | +| `devague deviate --confirm <dN>` | User-only: approve a `proposed` deviation. | |
| 88 | +| `devague deviate --reject <dN>` | User-only: reject a `proposed` (or any) deviation. | |
| 89 | +| `devague deviate --list [--json]` | Read every recorded deviation back (also the default action with no positional/flag). | |
| 90 | +| `devague deviate ... --plan <slug>` | Target a plan other than the current one. | |
| 91 | + |
| 92 | +`--reason` is required on every record — omitting it is refused with a hint. |
| 93 | +`--task` naming the plan item ref is likewise required. |
| 94 | + |
| 95 | +## Hard rules (do not violate) |
| 96 | + |
| 97 | +- **Never record a deviation the human did not approve.** `devague deviate` |
| 98 | + without `--origin llm` auto-approves the instant it is run — so a |
| 99 | + user-origin record IS the approval. Only run it after the human has said |
| 100 | + yes to this specific departure, never preemptively "to be safe." |
| 101 | +- **Never continue past a refused approval.** If the human does not approve, |
| 102 | + the run stays stopped on that task. Do not record the deviation anyway, do |
| 103 | + not quietly implement the diverging approach, and do not advance the wave. |
| 104 | +- **LLM-origin records stay proposed until the user confirms.** `--origin |
| 105 | + llm` lands `proposed`; only `devague deviate --confirm <dN>` (user-only) |
| 106 | + makes it `approved`. Same anti-fabrication contract as every other origin |
| 107 | + in the method — an agent's own proposal never self-confirms. |
| 108 | +- **Deviations are never silently folded into drift after the fact.** Every |
| 109 | + departure from the confirmed plan gets a `dN` record at the moment it |
| 110 | + happens — not reconstructed from memory when `/summarize-delivery` runs |
| 111 | + later. |
| 112 | +- **The CLI stays non-orchestrating (issue #20).** `devague deviate` records |
| 113 | + a decision the human already made; it does not spawn agents, gate merges, |
| 114 | + mark tasks done, or make the approval decision itself. Recording is |
| 115 | + deterministic — no LLM calls inside the CLI. |
| 116 | +- **This is not a fourth standing gate.** `/assign-to-workforce`'s three |
| 117 | + human gates are the exported spec, the implementation split plan, and the |
| 118 | + final PR. `/deviate` does not add a fourth — it is the human owner of gate |
| 119 | + 2 amending the approved split for one scoped, in-flight decision. |
| 120 | + |
| 121 | +## Worked example |
| 122 | + |
| 123 | +Mid-fan-out on task `t4`, the task agent discovers the acceptance criteria |
| 124 | +assumed a helper that task `t2` never actually shipped: |
| 125 | + |
| 126 | +```bash |
| 127 | +# 1. STOP — the main agent halts t4's worktree before more code lands |
| 128 | +# against a criterion that can't be met as written. |
| 129 | + |
| 130 | +# 2. Present what/why/what-it-affects to the human: |
| 131 | +# what: t4's acceptance criterion 2 assumes a `--json` flag on a |
| 132 | +# helper that t2 shipped without one |
| 133 | +# why: t2's scope was cut to land its wave on time |
| 134 | +# affects: t4 (this task), and coverage target c9 (the criterion in |
| 135 | +# question) |
| 136 | + |
| 137 | +# --- HUMAN: approves dropping the --json assumption from t4's criterion --- |
| 138 | + |
| 139 | +# 3. Record the approved deviation |
| 140 | +devague deviate "drop the --json assumption from t4's acceptance criterion" \ |
| 141 | + --task t4 --reason "t2 shipped its helper without --json to land its wave on time" \ |
| 142 | + --affects t2 --affects c9 --classification acceptable |
| 143 | + |
| 144 | +# 4. Adjust t4's working brief to match what was approved, then resume the |
| 145 | +# task agent against the corrected instruction. |
| 146 | + |
| 147 | +# Read the ledger back at any point: |
| 148 | +devague deviate --list |
| 149 | +devague deviate --list --json |
| 150 | +``` |
| 151 | + |
| 152 | +If the agent had proposed the record itself (`--origin llm`), the same |
| 153 | +record would land `proposed` and need an explicit |
| 154 | +`devague deviate --confirm d1` from the user before `/summarize-delivery` |
| 155 | +could cite it as approved. |
| 156 | + |
| 157 | +## After recording — resume, then hand off to /summarize-delivery |
| 158 | + |
| 159 | +Once the affected task briefs are adjusted and the fan-out resumes, nothing |
| 160 | +further is needed from this skill — the record already lives in the delivery |
| 161 | +store. When the run reaches `/summarize-delivery`, that skill's Drift From |
| 162 | +Plan and Mid-work Decisions sections quote these records by their `dN` id |
| 163 | +instead of reconstructing drift from memory, so the connective tissue between |
| 164 | +the confirmed plan and the delivery summary is the ledger this skill wrote, |
| 165 | +not anyone's recollection of the run. |
| 166 | + |
| 167 | +## Provenance |
| 168 | + |
| 169 | +This is a **first-party** skill — its origin is `agentculture/devague`, the |
| 170 | +*sixth* in the outbound family after `/scope`, `/think`, `/spec-to-plan`, |
| 171 | +`/assign-to-workforce`, and `/summarize-delivery`, covering the execution-time |
| 172 | +leg that runs inside an `/assign-to-workforce` fan-out. guildmaster pulls it |
| 173 | +from here and broadcasts it to the AgentCulture mesh; because devague is |
| 174 | +upstream, it is **never re-vendored back** from guildmaster's re-broadcast |
| 175 | +copy. The `cite, don't import` policy still holds: downstream repos copy it, |
| 176 | +they don't symlink or depend on it. See `docs/skill-sources.md`. |
0 commit comments