@caddis/cli 0.2.3 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +11 -0
  2. package/bundles/antigravity-plugin/agents/anchor.md +60 -0
  3. package/bundles/antigravity-plugin/agents/claude-md-curator.md +144 -0
  4. package/bundles/antigravity-plugin/agents/codebase-audit.md +53 -0
  5. package/bundles/antigravity-plugin/agents/data-engineer.md +51 -0
  6. package/bundles/antigravity-plugin/agents/debug.md +48 -0
  7. package/bundles/antigravity-plugin/agents/knowledge-transfer.md +139 -0
  8. package/bundles/antigravity-plugin/agents/security-analyst.md +49 -0
  9. package/bundles/antigravity-plugin/agents/sql-expert.md +46 -0
  10. package/bundles/antigravity-plugin/agents/tester.md +45 -0
  11. package/bundles/antigravity-plugin/agents/ui-design-reviewer.md +110 -0
  12. package/bundles/antigravity-plugin/plugin.json +1 -1
  13. package/bundles/antigravity-plugin/skills/_registry.md +6 -0
  14. package/bundles/antigravity-plugin/skills/advisory-hub/SKILL.md +183 -0
  15. package/bundles/antigravity-plugin/skills/advisory-hub/reference/context-template.md +214 -0
  16. package/bundles/antigravity-plugin/skills/advisory-hub/reference/hub-handbook.md +233 -0
  17. package/bundles/antigravity-plugin/skills/advisory-hub/reference/report-contract.md +94 -0
  18. package/bundles/antigravity-plugin/skills/advisory-hub/reference/succession.md +96 -0
  19. package/bundles/antigravity-plugin/skills/brainstorming/SKILL.md +1 -1
  20. package/bundles/antigravity-plugin/skills/code-review/SKILL.md +7 -0
  21. package/bundles/antigravity-plugin/skills/context-curator/SKILL.md +1 -1
  22. package/bundles/antigravity-plugin/skills/cross-review/SKILL.md +71 -14
  23. package/bundles/antigravity-plugin/skills/dashboard-perf-sweep/SKILL.md +18 -18
  24. package/bundles/antigravity-plugin/skills/feature-plan/SKILL.md +164 -9
  25. package/bundles/antigravity-plugin/skills/gate-preflight/SKILL.md +34 -0
  26. package/bundles/antigravity-plugin/skills/gate-review/SKILL.md +36 -0
  27. package/bundles/antigravity-plugin/skills/golden-plan/SKILL.md +22 -13
  28. package/bundles/antigravity-plugin/skills/handoff/SKILL.md +78 -0
  29. package/bundles/antigravity-plugin/skills/implement/SKILL.md +182 -3
  30. package/bundles/antigravity-plugin/skills/mermaid-diagrams/SKILL.md +57 -1
  31. package/bundles/antigravity-plugin/skills/park/SKILL.md +126 -0
  32. package/bundles/antigravity-plugin/skills/prd/SKILL.md +4 -2
  33. package/bundles/antigravity-plugin/skills/preflight/SKILL.md +5 -0
  34. package/bundles/antigravity-plugin/skills/spawn-hub/SKILL.md +287 -0
  35. package/bundles/antigravity-plugin/skills/validate-phase/SKILL.md +112 -0
  36. package/bundles/antigravity-plugin/skills/writing-plans/SKILL.md +7 -4
  37. package/bundles/antigravity-plugin/warm_start_agy.py +35 -6
  38. package/bundles/antigravity-plugin-extras/plugin.json +1 -1
  39. package/bundles/antigravity-plugin-extras/skills/agent-orchestration/SKILL.md +9 -9
  40. package/bundles/antigravity-plugin-extras/skills/cross-review/SKILL.md +56 -6
  41. package/bundles/antigravity-plugin-extras/skills/requesting-code-review/SKILL.md +1 -1
  42. package/bundles/antigravity-plugin-extras/skills/schema-migration/SKILL.md +2 -2
  43. package/bundles/antigravity-plugin-extras/skills/state-tracking/SKILL.md +4 -4
  44. package/bundles/manifest.json +3 -3
  45. package/dist/cli.js +143 -59
  46. package/package.json +1 -1
@@ -43,11 +43,115 @@ folder you will touch (the canonical rules; `CLAUDE.md` is an `@AGENTS.md` shim)
43
43
  `.caddis/PROJECT-FACTS.md` if present (for the real run/test commands) —
44
44
  **read it, never edit it**. Identify the test command the plan/facts specify so you can run it yourself.
45
45
 
46
+ **Run the machine gates first — they decide, not your reading of the prose below.**
47
+
48
+ ```bash
49
+ python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_gate.py" lane-check --plan <plan> --phase <N>
50
+ python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_gate.py" verdict-gate --plan <plan> --phase <N>
51
+ python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_gate.py" tracker-vs-git --plan <plan>
52
+ ```
53
+
54
+ Obey the exit code: **0** proceed · **1** STOP and report why · **2** proceed but record the note it
55
+ printed · **3** wrong lane — the launch command is on stdout, spawn it · **4** the launch command is
56
+ malformed, do not run it.
57
+
58
+ **If the script is missing, proceed** — it degrades open by design, and an older install or a
59
+ plugin-only consumer must not be blocked by a gate it does not have. The prose below is the same
60
+ contract in words, and remains the fallback.
61
+
62
+ **Check the phase's `Lane:` before implementing anything.** The plan assigns every phase an
63
+ execution lane, and until now nothing read it: on one 14-phase plan, Phases 1 and 2 were both
64
+ assigned `glm-headless` and both ran on `claude`, silently, twice in a row — the plan advertised a
65
+ cheap lane for 4 of 14 phases that executed nothing, and every cost assumption resting on it was
66
+ quietly false. **The `Lane:` line is a routing directive, not a note.**
67
+
68
+ You cannot always prove your own lane, but you can detect a known mismatch — a Claude session
69
+ looking at `Lane: glm-headless`. Apply this **asymmetrically: act on a known mismatch, proceed when
70
+ unsure.** On a known mismatch:
71
+
72
+ - **Interactive session (no `CADDIS_HEADLESS`, no `DOCKET_PLAN`/`DOCKET_BRANCH` in the environment)
73
+ → spawn the assigned lane.** Run the phase's literal launch command yourself — e.g.
74
+ `claude-glm -p "/caddis:implement <plan> — Phase N only"` — wait for it, then verify it (below).
75
+ On Windows `claude-glm` is `claude-glm.ps1` and resolves only on the **PowerShell** PATH; a
76
+ Bash `command -v claude-glm` returns nothing and looks like "not installed", which it is not.
77
+ If the spawn fails for any reason, implement the phase here and record the deviation (below) —
78
+ a failed spawn must never silently become a skipped phase.
79
+ > **First, check the launch command carries `-p` or `--print`. If it does not, REFUSE to run it**
80
+ > — report the malformed command and implement here instead. The launchers set `CADDIS_HEADLESS`
81
+ > *only* on `-p`/`--print`, and that variable is the entire loop guard. A launch command missing
82
+ > it spawns a session that is not marked headless, which reads this same `Lane:` line and spawns
83
+ > again — unbounded recursion. Without `-p` the command also opens an interactive session, so the
84
+ > parent waits forever on a child that is sitting at a prompt.
85
+ - **Headless or docket-runner session → never spawn. Implement here and record the deviation.**
86
+ You may already *be* the spawned lane, and a session that spawns its own lane on every start is
87
+ an infinite loop. The env markers above are the guard: if either is set, someone else placed you.
88
+
89
+ **After the spawn, verify it — do not assume.** Re-read the plan's Tracker row for that phase and
90
+ confirm the status and commit hash the child claims to have written. "Wait for it and report" checks
91
+ nothing: a mistyped plan path in the launch command silently implements a *different plan* while you
92
+ move on. If the row is unchanged, treat the phase as **not done** and say so.
93
+
94
+ **If your arguments carry a phase restriction — `— Phase N only` — implement exactly that phase and
95
+ stop**, then emit the final JSON block. Every launch command this system generates ends that way, and
96
+ nothing used to honour it: a child spawned for phase 2 of 14 would run phases 2 *through 14*, pulling
97
+ later `claude`-lane and security-sensitive phases onto the cheap model. That is the precise inverse of
98
+ the bug the lane routing exists to fix.
99
+
100
+ **Record the lane you actually ran on in the Tracker's `Lane` column** — the lane you ran, never the
101
+ lane the plan planned. A deviation then shows up as a diff between the phase block and the tracker
102
+ row, visible to any later reader without an Advisory Hub having to catch it live.
103
+
104
+ **Advisory-Hub mode (conditional — OFF by default).** Check whether a companion file
105
+ `<plan-dir>/<plan-stem>-advisory-context.md` exists (e.g. plan `.caddis/plans/foo.md` → look for
106
+ `.caddis/plans/foo-advisory-context.md`). **If it does not exist — the normal case, including every
107
+ docket run — Advisory-Hub mode is OFF and nothing else in this command changes.** If it exists, read it
108
+ and set Advisory-Hub mode ON for this run: it names locked decisions you may not change unilaterally,
109
+ this project's declared safety conventions, and how to re-derive the plan's anchor numbers. See the
110
+ `advisory-hub` skill for the full contract.
111
+
112
+ **In Advisory-Hub mode, the previous phase's VERDICT gates this one.** Before starting phase N, require
113
+ a verdict in `.caddis/advisory-hub-reports/` that satisfies **all three** of:
114
+
115
+ 1. **It covers phase N-1.** Usually `phase-(N-1).verdict.md`, but a **batched** verdict counts: a file
116
+ whose `phase:` is a range — `phase-10-11.verdict.md`, `phase: 10-11` — satisfies the gate for every
117
+ phase the range **covers**. Batched pairs are normal, not exotic: one live plan alone carries
118
+ `phase-05-06`, `08-09`, `10-11` and `13-14`. A literal `phase-(N-1)` lookup sends phase 12 hunting
119
+ for a `phase-11.verdict.md` that will never exist, and falsely blocks a properly validated plan.
120
+ 2. **It belongs to the plan you are implementing.** The report directory is flat and shared, so with two
121
+ hub-mode plans in one repo, plan A's `phase-02.verdict.md` would otherwise satisfy plan B's phase-3
122
+ gate. Match the verdict's identity field against the plan. **Accept either `plan:` (a path) or
123
+ `feature:` (a slug) — both are in live fleet use** and neither is wrong; one project's verdicts carry
124
+ one, another's carry the other. If a verdict carries neither, treat its identity as unproven: say so
125
+ and do not let it gate anything.
126
+ 3. **It carries `verdict: accept` or `verdict: accept-with-correction`.**
127
+
128
+ - **Missing** → the Hub has not validated it yet. **STOP.** Mark the Tracker row
129
+ `blocked-pending-hub` and say which verdict you are waiting on.
130
+ - **`verdict: reject`** → **STOP.** The phase is to be redone, not built upon.
131
+ - **`verdict: accept-degraded`** → the Hub validated it **without an advisory context**, so the
132
+ locked-decision and safety-rule re-checks never ran. It is a partial check wearing an accept. Proceed
133
+ only if the phase is low-stakes, and **say in your report that you did so on a degraded verdict**.
134
+ - Phase 1 (or the first phase of the plan) has no predecessor — proceed.
135
+
136
+ This is the Hub's central power and until now it ran on human discipline alone: the verdict recorded
137
+ whether the next phase could start, and *nothing read it*. Five lines of check make the claim true by
138
+ machine.
139
+
140
+ **If a `phase-NN.prompt.md` exists for the phase you are about to run, it is the INSTRUCTION OF
141
+ RECORD** — read it, and measure your DEVIATIONS against it, not against the plan alone. The Hub writes
142
+ that file before the phase precisely so a deviation is falsifiable; an executor that never reads it
143
+ undermines the whole argument.
144
+
46
145
  **2. Determine where to resume.** The `## Tracker` table is the resume signal. Start at the first phase whose
47
146
  status is not `done`/`✅`. If every phase is already done, verify the tests are green and go straight to the
48
147
  report — do not redo completed work.
49
148
 
50
149
  **3. Implement each remaining phase, TDD-first.** For each phase, in order:
150
+ - **LANE** — **re-check this phase's `Lane:` and apply Step 1's spawn/record rule to it.** Do this
151
+ first, every phase, not just the one you resumed at. Step 1's check only ever saw the *resume*
152
+ phase: on a plan whose phase 1 is `claude` and phase 2 is `glm-headless`, it finds no mismatch and
153
+ this loop then carries you straight through phase 2 — so the lane silently executes nothing for
154
+ every phase after the first, which is the original bug wearing a different hat.
51
155
  - **RED** — write the failing test(s) the phase names (`<test file>::<case>`). Run them; confirm they
52
156
  fail for the right reason (the missing behavior, not an import error). If a phase genuinely has no
53
157
  testable surface, say so in the review file and implement the minimal change directly.
@@ -59,19 +163,91 @@ report — do not redo completed work.
59
163
  - **COMMIT** — `git add` the phase's files and `git commit` with the phase's conventional-commit message
60
164
  (from the plan, or a faithful equivalent). Stay on the current branch.
61
165
  - **UPDATE THE TRACKER** — edit the plan's `## Tracker` row for this phase: set Status to `done`, fill
62
- the short commit hash (`git rev-parse --short HEAD`) and a one-line note. This is what lets a future
63
- session (or the runner) see progress. Commit the Tracker update with the phase (or as a tiny follow-up
64
- commit) — it lives in the plan file, which is fine to commit on this branch.
166
+ the short commit hash (`git rev-parse --short HEAD`), set the `Lane` column to the lane this phase
167
+ ACTUALLY ran on (not the planned one — see Step 1), and add a one-line note. This is what lets a
168
+ future session (or the runner) see progress. Commit the Tracker update with the phase (or as a tiny
169
+ follow-up commit) — it lives in the plan file, which is fine to commit on this branch.
170
+ - **FILE THE PHASE REPORT — Advisory-Hub mode only.** *Skip this bullet entirely if Step 1 found no
171
+ `<slug>-advisory-context.md`.* Write `.caddis/advisory-hub-reports/phase-NN.report.md` (zero-padded
172
+ phase number; create the directory and add a `README.md` index row if absent — and when you
173
+ create `.caddis/advisory-hub-reports/` for the first time, also write an **`AGENTS.md`** there
174
+ carrying the naming, frontmatter and role rules from the `advisory-hub` skill, so they bind every
175
+ agent that writes to that directory including ones that never loaded the skill. The skill claims
176
+ this file ships; nothing ever created it, so it exists only where a Hub hand-wrote one.
177
+ **Never overwrite an existing `AGENTS.md`** — the hand-written ones in the fleet are the good
178
+ copies) using the
179
+ `advisory-hub` skill's report contract. Verbatim means verbatim — paste real terminal output, never
180
+ reconstruct it. Report the model/lane you actually ran on. Report every commit, including tooling and
181
+ config. `git add` the report file with this phase's commit. **If the report's SURPRISES /
182
+ CONTRADICTIONS section is non-empty, stop after this phase** — mark the Tracker row
183
+ `blocked-pending-hub`, leave later phases untouched, and let the Hub correct the plan; that is not
184
+ your call to make here.
185
+
186
+ > **Give it OKF frontmatter — `type` is REQUIRED and its absence is a defect.**
187
+ > Keep it flat (scalar `key: value` only; nested maps and lists defeat simple parsers):
188
+ > ```yaml
189
+ > ---
190
+ > type: phase-report
191
+ > plan: <path to the plan>
192
+ > phase: 12 # or 10-11 for a batched pair
193
+ > milestone: M4
194
+ > ---
195
+ > ```
196
+
65
197
 
66
198
  If a phase cannot be completed (a blocking gap the plan did not resolve, or a rule above would be
67
199
  violated), **stop there**: leave later phases untouched, record the blocker in the review file, mark the
68
200
  Tracker row `blocked`, and report honestly with `"tests":"failed"` — never fake completion.
69
201
 
202
+ **3b. Halt only at a boundary.** Implement phase after phase, committing each. Stop for exactly four
203
+ reasons — a **milestone boundary**, a phase marked `Session: fresh`, **after** a `risk: high` phase,
204
+ or a **failed/blocked** phase. A lane change is not one of them: you spawn the lane yourself (Step 1).
205
+
206
+ The `risk: high` halt is deliberately *after*, not before. Execute and commit the phase normally; the
207
+ halt exists to stop the **next** phase building on it before a human has looked, so the blast radius
208
+ stays one reviewable, revertable commit.
209
+
210
+ **At every halt, PERFORM the handoff yourself, now, before you stop.** Write `relay.md` and update
211
+ the Tracker in this session — you are the only party holding the context that makes them worth
212
+ anything, and it evaporates the moment you stop.
213
+
214
+ **Do NOT emit "run `/caddis:handoff`", "do a handoff", or "update the relay" as a next action.**
215
+ Naming the command instead of doing the work is the single most common way this step is skipped: the
216
+ session ends, the user runs `/clear`, and the durable record that should have been written never is.
217
+ `/caddis:handoff` is the same procedure a human may invoke *between* sessions; **at a halt, you are
218
+ the one performing it.** The only next action you hand back is the resume line in the halt block.
219
+
220
+ Then print the halt block as your **last output before the JSON**, so the human has one action rather
221
+ than an archaeology job:
222
+
223
+ ```
224
+ === HALT — <one-line reason> ===
225
+ Done: phases <a>-<b> (<milestone>) · commits <sha>, <sha>
226
+ Blocked: <what, or "nothing">
227
+ You: /clear, then paste ↓
228
+ read <plan path> and implement Phase <next>
229
+ ```
230
+
231
+ **In headless/runner mode, never ask — halt, write the block, and exit.** The block is how a
232
+ non-interactive run tells a human what it needs; asking is still forbidden.
233
+
70
234
  **4. Run the tests yourself.** After the last phase you complete, run the project's full test command once
71
235
  more and record the real result. The runner will re-run it independently and that decides success — but
72
236
  you run it too so your reported `"tests"` value is truthful, not assumed. Never report `"passed"` on a
73
237
  suite you did not see go green.
74
238
 
239
+ **4b. If every phase is now done, tidy the plan into `done/`.** Only when the whole plan is
240
+ finished (every `## Tracker` row is `done`, no halt, no blocker) — a mid-plan halt is not this.
241
+ Flip the plan's own frontmatter `status:` to `done` (your judgment call: only if the Tracker
242
+ genuinely backs it up), commit that with the final phase, then run:
243
+ ```
244
+ python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_tidy.py" --apply
245
+ ```
246
+ (falls back to `scripts/caddis_tidy.py` from a source checkout; **skip this step if the script is
247
+ missing** — degrades open, same as the gates in Step 1). A **collision**
248
+ (`done/<name>` already exists) is reported by the script, not fatal — note it in the review file,
249
+ do not fail the run over it.
250
+
75
251
  **5. Write a concise review file** to the path in the `DOCKET_REVIEW` env var (falls back to
76
252
  `.caddis/reviews/<slug>.md`, where `<slug>` is `DOCKET_SLUG`). Create `.caddis/reviews/` if needed.
77
253
  Keep it short and scannable — this is what the human reviewer reads before merging the branch:
@@ -108,6 +284,9 @@ showed; `review` is the review-file path you wrote:
108
284
  {"implemented":true,"phases_done":<int>,"tests":"passed|failed","review":".caddis/reviews/<slug>.md"}
109
285
  ```
110
286
 
287
+ (In Advisory-Hub mode, the phase report from Step 3 is a **file**, written per phase — this JSON block
288
+ remains the one and only final output of the whole run, in every mode, unchanged.)
289
+
111
290
  If you had to stop before implementing anything (e.g. you were on the default branch, or the plan was
112
291
  unreadable), still end with the block using `"implemented":false,"phases_done":0,"tests":"failed"` and put
113
292
  the reason in the review file. The only acceptable final output is the code + commits + review file + this
@@ -199,14 +199,70 @@ flowchart LR
199
199
 
200
200
  1. **Start simple** - Core elements first, add details incrementally
201
201
  2. **One concept per diagram** - Split complex views into focused diagrams
202
- 3. **Use clear labels** - Meaningful names make diagrams self-documenting
202
+ 3. **Use clear labels, but SHORT ones** - see *Label length* below. Meaningful names make diagrams
203
+ self-documenting; long ones get silently clipped, and a clipped label is worse than a terse one
204
+ because the reader cannot tell text is missing
203
205
  4. **Comment extensively** - Use `%%` to explain complex parts
204
206
  5. **Validate syntax** - Test at [mermaid.live](https://mermaid.live) before committing
205
207
  6. **Version control** - Store `.mmd` files with code
206
208
  7. **Keep updated** - Update diagrams when code changes
207
209
 
210
+ ## Label length — text is CLIPPED, not wrapped, and nothing warns you
211
+
212
+ **The most common defect in a generated diagram, and it is invisible to the author.** Mermaid does
213
+ not error, the diagram renders, and the text is simply cut off mid-word. Two distinct causes:
214
+
215
+ **1. A long unbroken token in a node label cannot wrap.** Mermaid wraps node text at *spaces* only.
216
+ `GenesysConversationTranscripts` is 30 characters with no space in it, so there is no break
217
+ opportunity — it overflows the box and is clipped to `GenesysConversationTransc…`. Identifiers,
218
+ table names, class names and file paths are all this shape.
219
+
220
+ **2. Edge labels never wrap at all.** `A -->|"E2 · no index on ConversationStart"| B` renders on one
221
+ line at any length, clipping or overlapping neighbouring nodes.
222
+
223
+ **Rules:**
224
+
225
+ - **Keep any unbroken token to ~20 characters.** Break longer ones explicitly with `<br/>`:
226
+ `["GenesysConversation<br/>Transcripts"]`.
227
+ - **Keep each `<br/>`-separated line to ~25 characters.**
228
+ - **Never put a sentence on an edge.** Edge labels get a short id or one word — `|"B2"|`, `|"reads"|`.
229
+ If it needs explaining, explain it in prose or a table beside the diagram.
230
+ - **Prefer a short display name plus a lookup table** over cramming full identifiers into nodes:
231
+
232
+ ```mermaid
233
+ flowchart TD
234
+ B["Voice<br/>transcripts"] --> APP["dashboard"]
235
+ ```
236
+
237
+ | short name | actual table |
238
+ |---|---|
239
+ | Voice transcripts | `dbo.GenesysConversationTranscripts` |
240
+
241
+ **Check it mechanically before shipping** — cheaper than rendering, and catches both causes:
242
+
243
+ ```bash
244
+ python -c "
245
+ import re,sys
246
+ body=re.search(r'\`\`\`mermaid(.*?)\`\`\`',open(sys.argv[1],encoding='utf-8').read(),re.S).group(1)
247
+ for e in re.findall(r'\|\"?([^\"|]+)\"?\|',body):
248
+ if len(e)>15: print(f'EDGE LABEL {len(e)} chars (never wraps): {e}')
249
+ for lbl in re.findall(r'\[\"(.*?)\"\]',body):
250
+ for line in lbl.split('<br/>'):
251
+ t=max((len(w) for w in line.split()),default=0)
252
+ if t>20: print(f'LONG TOKEN {t} chars (cannot wrap): {line}')
253
+ print('checked')
254
+ " FILE.md
255
+ ```
256
+
257
+ **Rendering to look at it is better still** — but only if you actually open the image. A diagram that
258
+ renders without error is not a diagram that reads correctly, which is the same trap as a passing
259
+ test that asserts nothing.
260
+
208
261
  ## Common Issues
209
262
 
263
+ **Text is cut off mid-word:** see *Label length* above — the label is too long to wrap. This does
264
+ not produce an error.
265
+
210
266
  **Diagram won't render:**
211
267
  - Check for typos in diagram type declaration
212
268
  - Validate syntax at [mermaid.live](https://mermaid.live)
@@ -0,0 +1,126 @@
1
+ ---
2
+ name: park
3
+ description: File a future-work item in the one backlog — .caddis/parking-lot/ — or list what is open
4
+ ---
5
+
6
+ # /caddis:park — put future work in the ONE place it belongs
7
+
8
+ Everything we will do later lives in `.caddis/parking-lot/`, one item per file. This command is the
9
+ only sanctioned way to add to it. Use it whenever work is identified but deliberately not done now:
10
+ a defect you are not fixing, a proposal, a plan you are parking, an idea worth keeping.
11
+
12
+ **Why a command and not just a convention.** Parking-lot item `002` records an agent that hand-wrote
13
+ a hub artifact into the wrong directory while the correct path sat unread on line 188 of the command
14
+ it never invoked. A documented convention that nothing enforces gets bypassed by the next agent in a
15
+ hurry. This command plus the `caddis_gate.py parking-lot` gate is the fix.
16
+
17
+ The request is **$ARGUMENTS**.
18
+
19
+ ## Mode select
20
+
21
+ | `$ARGUMENTS` | Do this |
22
+ |---|---|
23
+ | empty or `list` | Go to **List mode** |
24
+ | `done <slug>` or `drop <slug>` | Go to **Close mode** |
25
+ | anything else | Go to **File mode** — the text is what to park |
26
+
27
+ ---
28
+
29
+ ## File mode
30
+
31
+ ### Step 1 — check it belongs here
32
+
33
+ Park it only if it is work **we** will do later. Redirect these instead, and say which you chose:
34
+
35
+ | If it is | Send it to |
36
+ |---|---|
37
+ | Being worked on right now | `.caddis/plans/<feature>.md` |
38
+ | An interrupted task you will come back to this session | `/caddis:digress` |
39
+ | Blocked on a person outside this repo | `.caddis/comms/` + its `register.md` |
40
+ | A card on the docket board | the board. **Never hand-edit `.caddis/backlog/`** — docket writes it |
41
+ | A fact about the environment, not a task | the KB (`/caddis:kb`) |
42
+
43
+ ### Step 2 — do not duplicate
44
+
45
+ List `.caddis/parking-lot/*.md` and read the title line of each. If this item already exists, **update
46
+ that file** — add the new evidence and refresh `Last Updated` — and stop. Say which file you updated.
47
+
48
+ ### Step 3 — write the file
49
+
50
+ Path: `.caddis/parking-lot/<short-slug>.md`. Slug only, **no number prefix**: two sessions filing at
51
+ the same time would both pick the same number.
52
+
53
+ ```markdown
54
+ ---
55
+ type: parking-lot
56
+ status: open
57
+ future: <yes if we have committed to it; omit or `no` if it is a candidate>
58
+ severity: <high | medium | low>
59
+ found: <YYYY-MM-DD>
60
+ found-by: <repo / session / who reported it>
61
+ Creating Model: <your exact model id>
62
+ ---
63
+
64
+ # <One line that states the problem, not the solution>
65
+
66
+ ## What happened
67
+ The evidence. What was observed, where, with the actual output, path, or number.
68
+
69
+ ## What it costs
70
+ Who or what is affected, and what goes wrong if this is never done. An item with no cost
71
+ stated is an item nobody will ever prioritise.
72
+
73
+ ## Suggested fix
74
+ The smallest change that would remove the cause. Say if it is uncertain.
75
+ ```
76
+
77
+ Rules the gate enforces — get them right the first time:
78
+
79
+ - `type:` is always `parking-lot`, whatever the item started life as.
80
+ - `status:` is one of `open`, `doing`, `done`, `dropped`. Nothing else. Not `wip`, not `todo`.
81
+ - `future:` if present is exactly `yes` or `no`. It is a **separate axis** from `status`: an item can
82
+ be `status: open` and `future: yes`, meaning agreed but not started.
83
+ - Keep the file under **20 KB**. Over that it is a register, not an item, and the gate fails it.
84
+ - Set `severity` to something an outsider could check, not to how annoying it was.
85
+
86
+ ### Step 4 — verify
87
+
88
+ Run the gate and show the result:
89
+
90
+ ```bash
91
+ python scripts/caddis_gate.py parking-lot --repo-root .
92
+ ```
93
+
94
+ Exit 0 means it conforms. Exit 1 means fix what it printed, then re-run. Do not report the item as
95
+ filed until this passes.
96
+
97
+ ### Step 5 — report
98
+
99
+ One line: the path, the severity, and whether `future: yes` was set. Nothing else.
100
+
101
+ ---
102
+
103
+ ## List mode
104
+
105
+ Read every `.caddis/parking-lot/*.md` (skip `README.md` and `done/`). Print one table, sorted by
106
+ `future: yes` first, then severity high → low:
107
+
108
+ | Item | Severity | Future | Status | One-line summary |
109
+ |---|---|---|---|---|
110
+
111
+ Below the table, print the counts: how many open, how many committed (`future: yes`). Then run
112
+ `python scripts/caddis_gate.py parking-lot --repo-root .` and report any violation it prints.
113
+
114
+ If the directory is empty, say so in one line. Do not invent items.
115
+
116
+ ---
117
+
118
+ ## Close mode
119
+
120
+ 1. Find `.caddis/parking-lot/<slug>.md`. If there is no exact match, list the near matches and stop.
121
+ 2. Set `status: done` (finished) or `status: dropped` (deliberately abandoned).
122
+ 3. **For `dropped`, append a `## Why dropped` section.** This is not optional. An item deleted with
123
+ no reason gets re-raised by the next session that has the same idea; an item kept with "no,
124
+ because ..." does not.
125
+ 4. Run `python scripts/caddis_tidy.py --apply`, which moves it into `.caddis/parking-lot/done/`.
126
+ 5. Report the file's new path in one line.
@@ -21,8 +21,10 @@ Interview the user to fill gaps. Ask only what you can't infer from the codebase
21
21
  Ask in small batches; stop interviewing once the spec is testable.
22
22
 
23
23
  ## Headless mode
24
- When the invocation contains the marker **`HEADLESS RUN RULES`** (a docket runner / non-interactive
25
- caller spawned this session — no human is present), the Discovery interview above is **suspended and
24
+ When the invocation contains the marker **`HEADLESS RUN RULES`**, **or `CADDIS_HEADLESS` /
25
+ `DOCKET_PLAN` / `DOCKET_BRANCH` is set in the environment** (the caddis OSS launchers export
26
+ `CADDIS_HEADLESS` on claude's `-p`/`--print`; the docket runner sets the others) — a non-interactive
27
+ caller spawned this session and no human is present, so the Discovery interview above is **suspended and
26
28
  forbidden**. This mode exists for one-line ideas: the card may be nothing more than a short title with
27
29
  **no description**, and there may be **no codebase or `STACK.md`** to draw on. That is expected and still
28
30
  fully actionable — a terse title is enough to write a complete draft PRD.
@@ -392,6 +392,11 @@ If you revise an existing report file, preserve the original metadata fields and
392
392
  | `PASS` | Zero CRITICAL findings AND zero pending decisions |
393
393
  | `FAIL` | Any CRITICAL finding exists OR any decision is PENDING |
394
394
 
395
+ **Then, as the very last line of your output (nothing after it), emit the machine verdict:**
396
+ `PREFLIGHT: PASS` (zero CRITICAL findings and zero pending decisions) or `PREFLIGHT: FAIL` (one or
397
+ more CRITICAL findings, or any decision pending). Automated runners read only this line; it must
398
+ exactly match one of those two forms.
399
+
395
400
  `SIGNIFICANT` and `MINOR` findings do not block a PASS — they are advisory. However, they should be included in the report for the Planner to address.
396
401
 
397
402
  ---