@caddis/cli 0.4.52 → 0.4.54
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.
- package/bundles/antigravity-plugin/CADDIS-GLOSSARY.md +1 -0
- package/bundles/antigravity-plugin/guard_agy.py +184 -0
- package/bundles/antigravity-plugin/plugin.json +1 -1
- package/bundles/antigravity-plugin/repo_freshness.py +132 -5
- package/bundles/antigravity-plugin/scripts/caddis_budget.py +283 -0
- package/bundles/antigravity-plugin/scripts/caddis_checkout_guard.py +227 -0
- package/bundles/antigravity-plugin/scripts/caddis_docs_pr.py +284 -0
- package/bundles/antigravity-plugin/scripts/caddis_exit.py +2 -0
- package/bundles/antigravity-plugin/scripts/caddis_fleet.py +439 -0
- package/bundles/antigravity-plugin/scripts/caddis_frontmatter.py +1 -0
- package/bundles/antigravity-plugin/scripts/caddis_gate.py +255 -195
- package/bundles/antigravity-plugin/scripts/caddis_glossary.py +3 -3
- package/bundles/antigravity-plugin/scripts/caddis_governor.py +48 -4
- package/bundles/antigravity-plugin/scripts/caddis_inventory.py +38 -0
- package/bundles/antigravity-plugin/scripts/caddis_lanes.py +411 -127
- package/bundles/antigravity-plugin/scripts/caddis_lineage_publish.py +458 -0
- package/bundles/antigravity-plugin/scripts/caddis_merge_chain.py +237 -0
- package/bundles/antigravity-plugin/scripts/caddis_notify.py +125 -0
- package/bundles/antigravity-plugin/scripts/caddis_prod_check.py +380 -0
- package/bundles/antigravity-plugin/scripts/caddis_redact.py +99 -0
- package/bundles/antigravity-plugin/scripts/caddis_relay_git.py +2 -2
- package/bundles/antigravity-plugin/scripts/caddis_review.py +1309 -0
- package/bundles/antigravity-plugin/scripts/caddis_roadmap.py +2109 -0
- package/bundles/antigravity-plugin/scripts/caddis_roadmap_page.py +676 -0
- package/bundles/antigravity-plugin/scripts/caddis_roadmap_run.py +2605 -0
- package/bundles/antigravity-plugin/scripts/caddis_routing.py +7 -6
- package/bundles/antigravity-plugin/scripts/caddis_rows.py +476 -0
- package/bundles/antigravity-plugin/scripts/caddis_spawn.py +8 -9
- package/bundles/antigravity-plugin/scripts/caddis_spend.py +415 -0
- package/bundles/antigravity-plugin/scripts/caddis_tidy.py +357 -20
- package/bundles/antigravity-plugin/scripts/caddis_todo.py +55 -0
- package/bundles/antigravity-plugin/scripts/caddis_workstreams.py +178 -19
- package/bundles/antigravity-plugin/scripts/caddis_worktree_close.py +349 -0
- package/bundles/antigravity-plugin/scripts/check_doc_coverage.py +0 -56
- package/bundles/antigravity-plugin/scripts/claudster_doctor.py +1 -1
- package/bundles/antigravity-plugin/scripts/enforcement_inventory.py +0 -1
- package/bundles/antigravity-plugin/scripts/oss_review.py +2 -2
- package/bundles/antigravity-plugin/scripts/roadmap-recheck.ps1 +89 -0
- package/bundles/antigravity-plugin/scripts/roadmap-run.ps1 +88 -0
- package/bundles/antigravity-plugin/scripts/setup_project_ai.py +43 -1
- package/bundles/antigravity-plugin/session_end_agy.py +3 -3
- package/bundles/antigravity-plugin/skills/_registry.md +4 -6
- package/bundles/antigravity-plugin/skills/best-practices/agents/best-practices-referencer.md +1 -1
- package/bundles/antigravity-plugin/skills/best-practices/agents/codebase-context-builder.md +1 -1
- package/bundles/antigravity-plugin/skills/best-practices/agents/task-intent-analyzer.md +1 -1
- package/bundles/antigravity-plugin/skills/catchup/SKILL.md +11 -0
- package/bundles/antigravity-plugin/skills/cloud-phases/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/cross-review/SKILL.md +5 -2
- package/bundles/antigravity-plugin/skills/feature-plan/SKILL.md +35 -83
- package/bundles/antigravity-plugin/skills/fleet-close/SKILL.md +167 -0
- package/bundles/antigravity-plugin/skills/fleet-open/SKILL.md +110 -0
- package/bundles/antigravity-plugin/skills/gh-cli/SKILL.md +2 -1
- package/bundles/antigravity-plugin/skills/handoff/SKILL.md +177 -48
- package/bundles/antigravity-plugin/skills/implement/SKILL.md +87 -147
- package/bundles/antigravity-plugin/skills/migrate-dir/SKILL.md +4 -3
- package/bundles/antigravity-plugin/skills/mmr/SKILL.md +5 -2
- package/bundles/antigravity-plugin/skills/office-documents-official/SKILL.md +24 -0
- package/bundles/antigravity-plugin/skills/park/SKILL.md +0 -1
- package/bundles/antigravity-plugin/skills/pr-merge/SKILL.md +28 -20
- package/bundles/antigravity-plugin/skills/prd/SKILL.md +2 -10
- package/bundles/antigravity-plugin/skills/refactoring/SKILL.md +2 -1
- package/bundles/antigravity-plugin/skills/review-pr/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/roadmap/SKILL.md +260 -0
- package/bundles/antigravity-plugin/skills/roadmap/assets/plan-resume-prompt.md +77 -0
- package/bundles/antigravity-plugin/skills/roadmap/assets/render-check.template.mjs +68 -0
- package/bundles/antigravity-plugin/skills/roadmap/assets/review-protocol.md +78 -0
- package/bundles/antigravity-plugin/skills/roadmap/assets/roadmap.template.md +32 -0
- package/bundles/antigravity-plugin/skills/roadmap/assets/value-check.template.py +161 -0
- package/bundles/antigravity-plugin/skills/ship/SKILL.md +16 -16
- package/bundles/antigravity-plugin/skills/ship-merge/SKILL.md +15 -5
- package/bundles/antigravity-plugin/skills/ship-pr/SKILL.md +36 -16
- package/bundles/antigravity-plugin/skills/spawn-session/SKILL.md +4 -8
- package/bundles/antigravity-plugin/warm_start_agy.py +1 -3
- package/bundles/antigravity-plugin-extras/plugin.json +1 -1
- package/bundles/antigravity-plugin-extras/skills/_registry.md +1 -2
- package/bundles/antigravity-plugin-extras/skills/agent-orchestration/SKILL.md +5 -5
- package/bundles/antigravity-plugin-extras/skills/cross-review/SKILL.md +5 -2
- package/bundles/antigravity-plugin-extras/skills/runner-move/SKILL.md +214 -0
- package/bundles/codex/.codex/skills/coding/refactoring/SKILL.md +2 -1
- package/bundles/codex/.codex/skills/devops/gh-cli/SKILL.md +2 -1
- package/bundles/codex/.codex/skills/docs/office-documents-official/SKILL.md +24 -0
- package/bundles/codex/.codex/skills/workflow/best-practices/agents/best-practices-referencer.md +1 -1
- package/bundles/codex/.codex/skills/workflow/best-practices/agents/codebase-context-builder.md +1 -1
- package/bundles/codex/.codex/skills/workflow/best-practices/agents/task-intent-analyzer.md +1 -1
- package/bundles/codex/.codex/skills/workflow/roadmap/SKILL.md +260 -0
- package/bundles/codex/.codex/skills/workflow/roadmap/assets/plan-resume-prompt.md +77 -0
- package/bundles/codex/.codex/skills/workflow/roadmap/assets/render-check.template.mjs +68 -0
- package/bundles/codex/.codex/skills/workflow/roadmap/assets/review-protocol.md +78 -0
- package/bundles/codex/.codex/skills/workflow/roadmap/assets/roadmap.template.md +32 -0
- package/bundles/codex/.codex/skills/workflow/roadmap/assets/value-check.template.py +161 -0
- package/bundles/codex/AGENTS.md +5 -4
- package/bundles/manifest.json +3 -3
- package/package.json +1 -1
- package/bundles/antigravity-plugin/skills/advisory-hub/SKILL.md +0 -233
- package/bundles/antigravity-plugin/skills/advisory-hub/reference/context-template.md +0 -214
- package/bundles/antigravity-plugin/skills/advisory-hub/reference/hub-handbook.md +0 -233
- package/bundles/antigravity-plugin/skills/advisory-hub/reference/report-contract.md +0 -94
- package/bundles/antigravity-plugin/skills/advisory-hub/reference/succession.md +0 -118
- package/bundles/antigravity-plugin/skills/resume/SKILL.md +0 -6
- package/bundles/antigravity-plugin/skills/review/SKILL.md +0 -6
- package/bundles/antigravity-plugin/skills/spawn-hub/SKILL.md +0 -341
- package/bundles/antigravity-plugin/skills/statusline/SKILL.md +0 -6
- package/bundles/antigravity-plugin/skills/validate-phase/SKILL.md +0 -143
- package/bundles/antigravity-plugin-extras/skills/data-lineage/SKILL.md +0 -158
- package/bundles/antigravity-plugin-extras/skills/data-lineage/scripts/convert_doc_to_confluence.py +0 -1430
- package/bundles/antigravity-plugin-extras/skills/golden-plan/SKILL.md +0 -586
- package/bundles/codex/.codex/skills/workflow/advisory-hub/SKILL.md +0 -233
- package/bundles/codex/.codex/skills/workflow/advisory-hub/reference/context-template.md +0 -214
- package/bundles/codex/.codex/skills/workflow/advisory-hub/reference/hub-handbook.md +0 -233
- package/bundles/codex/.codex/skills/workflow/advisory-hub/reference/report-contract.md +0 -94
- package/bundles/codex/.codex/skills/workflow/advisory-hub/reference/succession.md +0 -118
|
@@ -13,9 +13,8 @@ The plan file is the **durable spine of the harness** — it must let any future
|
|
|
13
13
|
agent, on any tool) resume with zero re-discovery. Optimize for that.
|
|
14
14
|
|
|
15
15
|
## Headless mode
|
|
16
|
-
When the invocation contains the marker **`HEADLESS RUN RULES`**, **or `CADDIS_HEADLESS`
|
|
17
|
-
|
|
18
|
-
`CADDIS_HEADLESS` on claude's `-p`/`--print`; the docket runner sets the others) — a non-interactive
|
|
16
|
+
When the invocation contains the marker **`HEADLESS RUN RULES`**, **or `CADDIS_HEADLESS` is set in
|
|
17
|
+
the environment** (the caddis OSS launchers export it on claude's `-p`/`--print`) — a non-interactive
|
|
19
18
|
caller spawned this session and no human is present, so the scope-check questions and any interview are
|
|
20
19
|
**suspended and forbidden**. This mode exists for one-line ideas: the card may be a short title with **no
|
|
21
20
|
description**, and there may be **no codebase, PROJECT-FACTS, or prior PRD** to read. That is expected —
|
|
@@ -39,13 +38,6 @@ Absolute rules in this mode (they override everything below):
|
|
|
39
38
|
a bullet under `## Constraints & decisions` — never a question to the user.
|
|
40
39
|
- **Honor the caller's output path and slug** (falling back to `.caddis/plans/<feature-slug>.md`);
|
|
41
40
|
set `feature: <slug>` in the frontmatter to that slug.
|
|
42
|
-
- **Also emit a visual companion** — a self-contained, scannable HTML page at `<artifact_dir>/<slug>.html`
|
|
43
|
-
presenting the plan visually (a goal card, phases as cards with their steps, an affected-files table,
|
|
44
|
-
and a risks/decisions section). **Use inline `<style>` ONLY** — the visual is rendered in a *sandboxed*
|
|
45
|
-
iframe with no script execution, so a `<script>`/CDN (e.g. the Tailwind browser CDN) would NOT run and
|
|
46
|
-
the page would appear unstyled. Keep it fully portable — no external `<script>`/`<link>`, no local
|
|
47
|
-
asset files, no `/`-rooted paths. This is the visual the human reviews in docket alongside the markdown.
|
|
48
|
-
Write it after the `.md`; the runner finds it by the matching `<slug>.html` name.
|
|
49
41
|
- **Always write the plan file, then end with exactly one fenced `json` highlights block** — nothing
|
|
50
42
|
after it:
|
|
51
43
|
```json
|
|
@@ -62,8 +54,14 @@ points), read it first. It's a free, token-zero project fingerprint that anchors
|
|
|
62
54
|
exists instead of assumed. If the work fits comfortably in one session, say so and offer to just do it
|
|
63
55
|
instead of planning. Only produce a plan for genuinely multi-phase work.
|
|
64
56
|
|
|
57
|
+
**Check upstream first when the plan builds on Claude Code behaviour** (hooks, headless `claude -p`, permission
|
|
58
|
+
modes, subagents, worktrees, plugins and skills, Remote Control, background sessions). Read
|
|
59
|
+
`.caddis/kb/claude-code-upstream-watch.md` if the repo has it, and the latest Claude Code changelog for that area
|
|
60
|
+
(Improvements, Bug fixes, In development). Do not plan a fix or a workaround for something Claude Code has already
|
|
61
|
+
changed, fixed or announced; cite the release in **Constraints & decisions** instead.
|
|
62
|
+
|
|
65
63
|
### Evidence gate — do not write plan content while a BLOCKER is unresolved
|
|
66
|
-
|
|
64
|
+
This is the direct counter to the failure
|
|
67
65
|
mode that makes a plan dangerous: **you write the spec, so you cannot see its gaps.** A phase built
|
|
68
66
|
on guessed field names or an imagined API is confidently wrong, passes every completeness check,
|
|
69
67
|
and only fails at the exit gate — or worse, doesn't.
|
|
@@ -164,9 +162,11 @@ of that role and write its Lane line as follows:
|
|
|
164
162
|
- `sonnet`: `claude — /model sonnet`
|
|
165
163
|
- `claude`: `claude — this session`
|
|
166
164
|
- `codex`: codex — `codex exec --ephemeral --sandbox workspace-write "HEADLESS RUN RULES. Read <plan path> and its Constraints. Implement Phase N only in the current checkout. Do not switch or create branches, commit, push, or edit files outside this phase. Run its exit gate and report the literal result."`
|
|
167
|
-
- `agy`: agy — `agy --mode accept-edits --dangerously-skip-permissions --add-dir . --print-timeout 20m --output-format
|
|
165
|
+
- `agy`: agy — `python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_spend.py" run --caller lane-pN -- agy --mode accept-edits --dangerously-skip-permissions --add-dir . --print-timeout 20m --output-format json -p "HEADLESS RUN RULES. Read <plan path> and its Constraints. Implement Phase N only in the current checkout. Do not switch or create branches, commit, push, or edit files outside this phase. Run its exit gate and report the literal result."`
|
|
168
166
|
|
|
169
|
-
Replace `<plan path>` and `N` with this plan's path and phase number.
|
|
167
|
+
Replace `<plan path>` and `N` (also in `lane-pN`) with this plan's path and phase number. The agy line
|
|
168
|
+
always starts with `caddis_spend.py run`: it books the call against the global EUR spend cap, and
|
|
169
|
+
`caddis_gate.py lane-check` refuses a bare `agy` Lane line. If the routing command fails
|
|
170
170
|
or exits 3, use `claude — this session` and state the reason in that phase.
|
|
171
171
|
|
|
172
172
|
#### A phase may take a no-escalation lane only if its exit gate would fail on a spec error
|
|
@@ -186,14 +186,9 @@ internal repo path into stakeholder-facing copy, and set a `live` status flag th
|
|
|
186
186
|
framework's own "Soon" badge). `tsc` clean, 632/632 tests green, cross-review CLEAN, exit gate
|
|
187
187
|
satisfied. A headless run following it literally would have committed both, entirely green.
|
|
188
188
|
|
|
189
|
-
In an Advisory-Hub plan, treat your lane as **provisional**: the Hub writes each `phase-NN.prompt.md`
|
|
190
|
-
before the phase runs, and that is the first time anyone but the spec's author reads it. Let that
|
|
191
|
-
read confirm or downgrade the lane. It costs nothing — the prompt is being written anyway.
|
|
192
|
-
|
|
193
189
|
### Group phases into MILESTONES — only when the plan is big enough
|
|
194
190
|
**Add milestones when the plan has ~8+ phases OR spans multiple sessions.** Below that, phases and a
|
|
195
|
-
Tracker are enough; a three-phase feature gains nothing from ceremony.
|
|
196
|
-
Advisory-Hub test, deliberately — one threshold to remember, not two.)
|
|
191
|
+
Tracker are enough; a three-phase feature gains nothing from ceremony.
|
|
197
192
|
|
|
198
193
|
A milestone is **a group of phases that ship together**. It answers "what lands when this is done?",
|
|
199
194
|
which is the question a long plan otherwise leaves the executor guessing at.
|
|
@@ -211,9 +206,10 @@ resuming session can see at a glance which group it is in and what remains befor
|
|
|
211
206
|
### Flag high-risk phases (`risk:` — a marker, not a mechanism)
|
|
212
207
|
Each phase may carry **`risk: normal|high`** (default `normal` — omit the line unless the phase is
|
|
213
208
|
`high`), meaning only "this is a phase where a wrong answer is expensive" — security/authz, a
|
|
214
|
-
correctness-critical algorithm, an ambiguous spec, or an irreversible change. It
|
|
215
|
-
|
|
216
|
-
|
|
209
|
+
correctness-critical algorithm, an ambiguous spec, or an irreversible change. It selects no model and
|
|
210
|
+
implies no fan-out. It has one effect: the roadmap/plan runner reviews a finished `risk: high` phase
|
|
211
|
+
twice (`caddis_review.py --plan --phase --runs 2`), gives it one fix session on blocking
|
|
212
|
+
findings, and stops `BLOCKED review` when findings remain. Roadmap mode reviews before it publishes the PR. Do not emit orchestration, lane fan-out, or
|
|
217
213
|
`Workflow` scripts from this command; the runtime decision rules and the intent→model map live in one
|
|
218
214
|
place, the `agent-orchestration` skill's *Multi-model fan-out* section.
|
|
219
215
|
|
|
@@ -275,7 +271,10 @@ yourself (relay + Tracker) before stopping — do not hand back "run `/caddis:ha
|
|
|
275
271
|
Three rules: one attempt, one review.
|
|
276
272
|
1. **Think before you send.** Before a task goes to any coder, write its edge cases and check the facts it depends on (one query or one file read).
|
|
277
273
|
2. **Run it before review.** The coder runs the same checks as CI (name the exact commands in the task). Then run the change once on real data.
|
|
278
|
-
3. **Review
|
|
274
|
+
3. **Review by tier.** Run `python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_gate.py" review-tier --range <base>...HEAD` (add `--plan <plan> --phase <N>` inside a plan; no `TIER:` line means tier 2).
|
|
275
|
+
Tier 0: gates only. Tier 1-small: your self-check only. Tier 1: one review by another vendor; stop at
|
|
276
|
+
the first CLEAN. Tier 2: two reviewers of two other vendors, in one round. Fix blocking findings only;
|
|
277
|
+
park the rest. Re-review only the fix diff, and only when the fix changed logic. After 3 rounds, ask the owner.
|
|
279
278
|
|
|
280
279
|
- One phase at a time: read this plan → run the phase on its **Lane** → RED→GREEN→VERIFY→CROSS-REVIEW→
|
|
281
280
|
COMMIT → update the **Tracker** row. The Tracker is the resume signal for every future session.
|
|
@@ -293,6 +292,10 @@ Three rules: one attempt, one review.
|
|
|
293
292
|
normally; the halt stops anything being **built on top of it** before a human has looked. Blast
|
|
294
293
|
radius stays one reviewable, revertable commit. Halting *beforehand* buys nothing: the phase has
|
|
295
294
|
to be executed either way, and a well-specced high-risk phase is as executable as any other.
|
|
295
|
+
One exception: when the session prompt says the runner reviews `risk: high` phases (the
|
|
296
|
+
runner's `plan-resume-prompt.md` says so), the runner's review gate replaces this halt: the
|
|
297
|
+
session ends `STATUS: CONTINUE`, and the runner reviews the phase twice before anything builds
|
|
298
|
+
on it. A headless marker (`CADDIS_HEADLESS=1`) alone does not lift the halt.
|
|
296
299
|
4. **A failed or blocked phase** — tests red, exit gate unmet, or the plan turned out wrong. Stop;
|
|
297
300
|
do not build on it.
|
|
298
301
|
- **A lane change is NOT a halt.** `/caddis:implement` spawns the assigned lane itself and verifies
|
|
@@ -366,66 +369,15 @@ done:
|
|
|
366
369
|
|
|
367
370
|
If any phase relies on the implementer *reasoning out* a gap, close the gap in the plan now.
|
|
368
371
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
> **You MUST call `Skill(advisory-hub)` and read *"When it earns its keep"* before deciding.**
|
|
380
|
-
> Do not decide from memory, and do not decide from any summary — including one in this file.
|
|
381
|
-
> The test is stated in exactly one place on purpose: two copies of a rule drift on the first edit,
|
|
382
|
-
> and the copy that used to live here had already drifted. It compressed the REQUIRED leg to the
|
|
383
|
-
> phrase *"expensive-to-reverse"* and dropped the enumeration that defines it — which reads as
|
|
384
|
-
> *"can I `git revert` this?"*, and under that reading a plan that publishes € figures to business
|
|
385
|
-
> stakeholders scores "no stakes". That is the one leg that fires on reporting, analytics and
|
|
386
|
-
> dashboard work, i.e. most of what this fleet builds. Load the skill.
|
|
387
|
-
|
|
388
|
-
If the test passes, tell the user plainly what it costs and what it buys, and offer to scaffold the
|
|
389
|
-
context doc from the `advisory-hub` skill's template. **Do not create it silently** — an opt-in
|
|
390
|
-
pattern that switches itself on is no longer opt-in.
|
|
391
|
-
|
|
392
|
-
**In headless mode, never offer and never create.** Headless forbids asking anything, so an "offer"
|
|
393
|
-
is impossible there. Instead record the result as a line under `## Constraints & decisions` —
|
|
394
|
-
*"Advisory Hub: test passed (N phases, <criteria>) — not scaffolded, headless run; create
|
|
395
|
-
`<plan-stem>-advisory-context.md` to enable"* — so the decision reaches a human rather than being
|
|
396
|
-
silently dropped or silently taken.
|
|
397
|
-
|
|
398
|
-
If it does not pass, say nothing **to the user** — a three-phase feature should never hear about
|
|
399
|
-
this. But **always record the determination in the plan, pass or fail**: one line under
|
|
400
|
-
`## Constraints & decisions`, naming which REQUIRED trigger was or was not hit.
|
|
401
|
-
|
|
402
|
-
> `Advisory Hub: not applicable — no REQUIRED trigger (not a migration / security change /
|
|
403
|
-
> production data correctness / numbers published to stakeholders).`
|
|
404
|
-
|
|
405
|
-
### If the test FAILS but this repo already runs a Hub for another plan
|
|
406
|
-
|
|
407
|
-
Check for an existing `*-advisory-context.md` in `.caddis/plans/` belonging to a **different** plan.
|
|
408
|
-
If one exists, add a second line under `## Constraints & decisions`:
|
|
409
|
-
|
|
410
|
-
> `Hub conventions: this repo runs Advisory Hub for <other-plan>. This plan does NOT — if it borrows
|
|
411
|
-
> the phase-NN.prompt.md / .report.md / CONTINUE GATE conventions, the lightweight rule applies: the
|
|
412
|
-
> session that files a report must not write the next prompt without an independent re-check.`
|
|
413
|
-
|
|
414
|
-
**Why this line exists.** A repo with one Hub plan has its artefacts sitting there as the most recent
|
|
415
|
-
example of "how we structure a multi-session plan here", and the next plan copies them by analogy.
|
|
416
|
-
It inherits the file names and none of the safety, because the safety was never in the names.
|
|
417
|
-
Measured once already: an implementing session filed its own batch report and then wrote the next
|
|
418
|
-
batch's prompt in the same session, with nobody having looked in between. Nothing was wrong that
|
|
419
|
-
time — and nothing checked either.
|
|
420
|
-
|
|
421
|
-
This is the cheapest possible place to catch it: when the second plan is created, before any
|
|
422
|
-
artefact-mimicry has happened. See *"Failing this test correctly does not mean no discipline"* in the
|
|
423
|
-
`advisory-hub` skill for the rule itself. Do not restate the rule here — one home, or the copies
|
|
424
|
-
drift.
|
|
425
|
-
|
|
426
|
-
Silent to the human, auditable in the artifact. "Say nothing" once meant *leave no trace anywhere*,
|
|
427
|
-
and a wrong negative was then invisible — no line in the plan, no line in the chat, nothing for
|
|
428
|
-
anyone to challenge. A rule whose failures leave no artifact cannot be reviewed.
|
|
372
|
+
A `risk: high` phase gets two independent review runs: run by the roadmap/plan runner automatically (from caddis-next Phase 11), and by hand in an interactive `/caddis:implement` run (`caddis_review.py --plan <plan> --phase <n> --runs 2`, from Phase 10). Only a `blocking` finding fails that review (exit 1); `should-fix` and `nit` findings go on a follow-up list and do not stop the merge. A phase gets 3 completed review rounds (a run that did not complete uses none); the 4th ends with exit 5, "stop, the owner decides". The advisory hub is retired; do not plan a separate validation session.
|
|
373
|
+
|
|
374
|
+
## Programme triggers
|
|
375
|
+
|
|
376
|
+
Small work that does not meet a trigger skips its block.
|
|
377
|
+
|
|
378
|
+
**Trigger: Always.** Add one open-work row for the plan in `.caddis/open-work.md`. Set its cells with `python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_rows.py" set --file <open-work.md> --id <row id> --col Status=todo`, never with a regex edit.
|
|
379
|
+
|
|
380
|
+
**Trigger: The plan records a decision.** Record it with `/caddis:decide`.
|
|
429
381
|
|
|
430
382
|
## Step 4 — Report
|
|
431
383
|
Output the plan path (`.caddis/plans/<feature-slug>.md`), the phase list (one line each, with each
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fleet-close
|
|
3
|
+
description: Close a fleet of sessions — every session writes its handoff and acks, then print one restart sheet for the owner
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /caddis:fleet-close — close every session, collect acks, print the restart sheet
|
|
7
|
+
|
|
8
|
+
Use this when **several** sessions must stop together (a machine restart, a long break, a context
|
|
9
|
+
reset for the whole fleet). For one session, run `/caddis:handoff` instead. This session is the
|
|
10
|
+
**coordinator**: it asks every other session to write its own handoff, collects one ack from each,
|
|
11
|
+
writes its own handoff last, and prints a restart sheet. The owner starts each new session from that
|
|
12
|
+
sheet, and each new session runs `/caddis:fleet-open <role>`.
|
|
13
|
+
|
|
14
|
+
Every fleet rule (names, ack format, order, checks) lives in
|
|
15
|
+
`${CLAUDE_PLUGIN_ROOT}/scripts/caddis_fleet.py`; this command only calls it. Run the steps in order.
|
|
16
|
+
|
|
17
|
+
**Safety rules for the whole command** (a wrong close loses another session's relay or tasks):
|
|
18
|
+
- Never write, edit or move another session's relay, tasks file or watcher files. Each session writes
|
|
19
|
+
its own; you only collect acks.
|
|
20
|
+
- Never stop, end or kill another session, and never tell one to exit. The owner closes terminals
|
|
21
|
+
after reading the sheet.
|
|
22
|
+
- Never wait with a foreground `sleep`. Every wait is a background timer (`run_in_background`).
|
|
23
|
+
- A session that does not ack is never guessed: its row says `no ack`, and the owner runs
|
|
24
|
+
`/caddis:handoff` in it by hand.
|
|
25
|
+
|
|
26
|
+
The ack format (one line in a fenced block, then the session's full resume prompt):
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
FLEET-ACK name=<n> role=<r> machine=<m> folder=<abs> relay=<path> tasks=<path|none> mode=<new|keeps-running|restore-on:<machine>|nothing> owns-watchers=<yes|no> worktrees=<abs;abs|none>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Step 1 — list the fleet
|
|
33
|
+
|
|
34
|
+
Run `ListAgents`. Your own name is in its header line (`This session is <name>`): you are the
|
|
35
|
+
coordinator. Candidates:
|
|
36
|
+
- every local interactive or background session, and every Remote Control session that is not
|
|
37
|
+
`offline`: each gets the close message in Step 3;
|
|
38
|
+
- every cloud session: it is listed as `keeps-running` and gets **no** message (it keeps running in
|
|
39
|
+
the cloud). In Step 4 you save its ack yourself:
|
|
40
|
+
`FLEET-ACK name=<n> role=<role-of n> machine=cloud folder=- relay=- tasks=none mode=keeps-running owns-watchers=no worktrees=none`,
|
|
41
|
+
then the prompt line `Cloud session: keeps running; nothing to restore.`;
|
|
42
|
+
- `offline` rows and your own row are not candidates.
|
|
43
|
+
|
|
44
|
+
For each candidate, and for yourself, get the role:
|
|
45
|
+
`python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_fleet.py" role-of <name>`. **Two sessions with the same role**
|
|
46
|
+
would get one start line and one new name, and one of them would be lost. So when roles repeat, keep the
|
|
47
|
+
role for the first name (sorted), and give each other one a distinct role `<role>-b`, `<role>-c`, ...; tell
|
|
48
|
+
that session its role in Step 3 (rule 5).
|
|
49
|
+
|
|
50
|
+
Print the candidate list (name, kind, machine, role) before you send anything. If there are no candidates,
|
|
51
|
+
say so, run `/caddis:handoff` for this session only, and **stop**.
|
|
52
|
+
|
|
53
|
+
## Step 2 — make the fleet dir
|
|
54
|
+
|
|
55
|
+
The fleet dir is `.caddis/relay/fleet/<MMDD>-<HH>/` in this repo, at the coordinator's local time:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_fleet.py" new-name fleet
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
prints `fleet-<MMDD>-<HH>`; the dir name is the `<MMDD>-<HH>` part. Create it. It is local and
|
|
62
|
+
gitignored (it holds machine paths). Use the same dir for every later step, even if the hour changes.
|
|
63
|
+
|
|
64
|
+
## Step 3 — send the close message
|
|
65
|
+
|
|
66
|
+
Send each candidate (from Step 1) one `SendMessage`. The first line must be exactly:
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
FLEET CLOSE from <coordinator>: write your handoff and ack.
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Then these close rules, in the message:
|
|
73
|
+
1. Run `/caddis:handoff` for **your own** relay only. Never touch another session's files. Skip its
|
|
74
|
+
Step 7 (the `Push this note for another machine?` question): the restart sheet carries your prompt,
|
|
75
|
+
and a question nobody answers would stop you before you ack.
|
|
76
|
+
2. In a shared checkout (its `AGENTS.md` says `Shared checkout: yes`, or `git status` shows changes you
|
|
77
|
+
did not make), skip the steps the handoff checklist skips there.
|
|
78
|
+
3. If you run watchers: copy each watcher script to `.caddis/relay/<your name>-files/watchers/`, and fill
|
|
79
|
+
the relay's `## Watchers` section (per watcher: script path, exact start command, stop condition,
|
|
80
|
+
the action after the stop).
|
|
81
|
+
4. Your resume prompt must load your tasks file, greet peers with `<role> is now <your new name>`, and,
|
|
82
|
+
in a shared checkout, say: "read code facts from origin/main; a worktree needs its own fresh
|
|
83
|
+
dependencies".
|
|
84
|
+
5. Reply to `<coordinator>` with this block (one line, every field filled), then your full resume prompt:
|
|
85
|
+
```
|
|
86
|
+
FLEET-ACK name=<n> role=<r> machine=<m> folder=<abs> relay=<path> tasks=<path|none> mode=<new|keeps-running|restore-on:<machine>|nothing> owns-watchers=<yes|no> worktrees=<abs;abs|none>
|
|
87
|
+
```
|
|
88
|
+
Use `name=<your current name>` exactly as `ListAgents` shows it, and `role=<role>` as given in this
|
|
89
|
+
message (a role that repeats in the fleet gets `<role>-b`, ...). `mode=new` if your work continues
|
|
90
|
+
in a new session; `mode=nothing` if it needs no new session (for example a finished read-only review).
|
|
91
|
+
6. Remote sessions (another machine): also put your open task rows inline after the prompt, as a table
|
|
92
|
+
with exactly this header line (other headers are not read):
|
|
93
|
+
```
|
|
94
|
+
| Old # | Status | Subject |
|
|
95
|
+
|---|---|---|
|
|
96
|
+
```
|
|
97
|
+
and say whether your machine restarts (`mode=restore-on:<machine>`) or not (`mode=keeps-running`).
|
|
98
|
+
7. Do not exit or stop after the ack; the owner closes sessions.
|
|
99
|
+
|
|
100
|
+
## Step 4 — collect acks (first wait: 10 minutes)
|
|
101
|
+
|
|
102
|
+
Start a background timer, never a foreground wait:
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
sleep 600
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
with `run_in_background`. Each ack arrives as a cross-session message. For each one:
|
|
109
|
+
1. Write the message text (from the `FLEET-ACK` line to the end) to a temp file in your scratchpad.
|
|
110
|
+
2. Save it:
|
|
111
|
+
```
|
|
112
|
+
python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_fleet.py" ack add --dir <fleet dir> --text-file <temp file>
|
|
113
|
+
```
|
|
114
|
+
3. Exit 0 → acked. An error names the missing or bad field: send that session **one** reply that
|
|
115
|
+
quotes the error and asks for a corrected ack. Do not fix the ack yourself.
|
|
116
|
+
4. The ack's `name=` must be the name of the candidate that sent it, and its `role=` the role you gave
|
|
117
|
+
it. If not, send **one** reply asking for a corrected ack (a wrong name makes a phantom row and marks
|
|
118
|
+
the real session `no ack`). A second ack from the same session replaces the first (`ack add` saves by
|
|
119
|
+
name).
|
|
120
|
+
|
|
121
|
+
Also save the cloud-session acks from Step 1 here, the same way.
|
|
122
|
+
|
|
123
|
+
## Step 5 — remind once (second wait: 20 minutes)
|
|
124
|
+
|
|
125
|
+
When the 10-minute timer ends, send each silent candidate **one** reminder:
|
|
126
|
+
`FLEET CLOSE reminder from <coordinator>: your ack is still missing.` Start a 20-minute background
|
|
127
|
+
timer (`sleep 1200`, `run_in_background`) and keep saving acks as in Step 4. When it ends (or every
|
|
128
|
+
candidate has acked), stop waiting. Each session still silent is a `no ack` row (Step 7).
|
|
129
|
+
|
|
130
|
+
**A late ack is never dropped.** Until Step 8 ends, keep saving every ack that arrives, as in Step 4, and
|
|
131
|
+
remove that session from the `--no-ack` list before the next `write`.
|
|
132
|
+
|
|
133
|
+
## Step 6 — your own handoff and ack
|
|
134
|
+
|
|
135
|
+
Run `/caddis:handoff` for this session (the coordinator's own relay). Then write your own ack (the
|
|
136
|
+
`FLEET-ACK` block with your fields and your resume prompt) to a temp file and save it with
|
|
137
|
+
`ack add`, as in Step 4. The coordinator's ack is never skipped. Then record this session's presence
|
|
138
|
+
(your session id is printed at session start as `[caddis] this session's id: <id>`; never guess one):
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_fleet.py" whoami --session-id <id> --name <your name> --root .
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Step 7 — write and check the sheet
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_fleet.py" write --dir <fleet dir> --coordinator <your name> --no-ack <name> [--no-ack <name> ...]
|
|
148
|
+
python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_fleet.py" check --dir <fleet dir>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Pass `--no-ack <name>` once for each silent session from Step 5, **on every `write`**, and leave it out
|
|
152
|
+
when every session acked (a placeholder would become a fake row) (the no-ack rows are not
|
|
153
|
+
saved between runs). `write` saves `roster.md` and `restart-sheet.md` in the fleet dir.
|
|
154
|
+
|
|
155
|
+
- `check` exit 0 → go to Step 8.
|
|
156
|
+
- `check` exit 1 → send each named session **one** message that quotes its error and asks for a
|
|
157
|
+
corrected ack. Start one 5-minute background timer (`sleep 300`, `run_in_background`) and save the
|
|
158
|
+
corrected acks that arrive. Then run `write` (same `--no-ack` flags) and `check` once more. Errors that
|
|
159
|
+
remain go at the end of `restart-sheet.md` under a heading `## Needs the owner:`, one line each,
|
|
160
|
+
quoted exactly.
|
|
161
|
+
- `write` or `check` exit 3 (no acks, or a file it cannot read) → do not print a sheet. Report the exact
|
|
162
|
+
error, list every ack file in `<fleet dir>/acks/`, and **stop**: the owner decides.
|
|
163
|
+
|
|
164
|
+
## Step 8 — final reply
|
|
165
|
+
|
|
166
|
+
Reply with the whole text of `restart-sheet.md`, then its absolute path, and nothing else. The
|
|
167
|
+
restart closes this session too, so the sheet must be on screen and on disk.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fleet-open
|
|
3
|
+
description: Restore one role from the fleet restart sheet in a new session — name check, relay, tasks, peer greeting, watchers
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /caddis:fleet-open — restore a role from the restart sheet
|
|
7
|
+
|
|
8
|
+
A fleet close (`/caddis:fleet-close`) wrote a restart sheet: one row per role, with the folder to
|
|
9
|
+
start `claude` in, a start line that names the new session, and the role's resume prompt. You are the new session
|
|
10
|
+
for one of those rows. This command restores that role in one go.
|
|
11
|
+
|
|
12
|
+
The argument is the role: `$ARGUMENTS`. If it is empty, list the roles of the newest sheet (Step 1)
|
|
13
|
+
and ask which one — do not guess.
|
|
14
|
+
|
|
15
|
+
Every fleet rule lives in `${CLAUDE_PLUGIN_ROOT}/scripts/caddis_fleet.py`; this command only calls it.
|
|
16
|
+
Run each step in order. A step that says "stop" ends the command: print why, and nothing else.
|
|
17
|
+
|
|
18
|
+
## Step 1 — find the newest restart sheet that holds the role
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
ls -d .caddis/relay/fleet/*/restart-sheet.md
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The folders are named `<MMDD>-<HH>` (the coordinator's local time). Go from the newest folder to the
|
|
25
|
+
oldest and take the first `restart-sheet.md` with a section `### <n>. <role>`. Read the
|
|
26
|
+
`roster.md` beside it too: its row for the role gives the relay, the tasks file, the folder and the
|
|
27
|
+
mode.
|
|
28
|
+
|
|
29
|
+
- No sheet holds the role → say `No restart sheet holds <role>.` and **stop**.
|
|
30
|
+
- The sheet row says `no new session` (mode `keeps-running`, `nothing` or `no ack`) → say so, quote
|
|
31
|
+
the row's section, and **stop**. A `no ack` row needs `/caddis:handoff` run by hand in the old
|
|
32
|
+
session first.
|
|
33
|
+
|
|
34
|
+
## Step 2 — check this session's name before loading anything
|
|
35
|
+
|
|
36
|
+
Run `ListAgents`. Its header line says `This session is <name>`; that is your name. The sheet row's
|
|
37
|
+
Start line already names the session: `claude --name <expected> "/caddis:fleet-open <role>"`, where
|
|
38
|
+
`<expected>` is `new_name` of the role at the sheet's hour.
|
|
39
|
+
|
|
40
|
+
- `<name>` equals `<expected>` → go on.
|
|
41
|
+
- Otherwise it must at least be a name of this role:
|
|
42
|
+
```
|
|
43
|
+
python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_fleet.py" role-of <name>
|
|
44
|
+
```
|
|
45
|
+
prints `<role>` (the name is `<role>-<MMDD>-<HH>`) → go on, and note the name differs from the sheet.
|
|
46
|
+
- Anything else → tell the owner to run `/rename <expected>` and then `/caddis:fleet-open <role>`
|
|
47
|
+
again, and **stop**. A session cannot rename itself, and a role loaded under the wrong name is a
|
|
48
|
+
role its peers never reach.
|
|
49
|
+
|
|
50
|
+
Nothing is read into this session (no relay, no tasks, no watcher) until this step passes.
|
|
51
|
+
|
|
52
|
+
## Step 3 — read the relay and run its resume prompt
|
|
53
|
+
|
|
54
|
+
Read the role's relay (the roster's Relay column, `.caddis/relay/<old name>.md`), then follow the
|
|
55
|
+
resume prompt in the sheet section — the fenced block under `### <n>. <role>`. It is the same prompt
|
|
56
|
+
the old session wrote; do what it says, in order.
|
|
57
|
+
|
|
58
|
+
Load the open tasks: every row of the tasks file (roster Tasks file column,
|
|
59
|
+
`.caddis/relay/<old name>.tasks.md`, table `| Old # | Status | Subject |`) becomes one `TaskCreate`
|
|
60
|
+
with the Subject as its subject. A row with Status `in_progress` then gets
|
|
61
|
+
`TaskUpdate` to `in_progress`. A remote role's rows are inline on the sheet under
|
|
62
|
+
`Tasks (inline, remote session):` — load those the same way. Tasks file `none` → 0 tasks.
|
|
63
|
+
Count the tasks you created; Step 6 reports it.
|
|
64
|
+
|
|
65
|
+
## Step 4 — greet the live local peers
|
|
66
|
+
|
|
67
|
+
From the `ListAgents` output of Step 2 (run it again if more than a few minutes passed), take each
|
|
68
|
+
live local session whose role is in the roster (`caddis_fleet.py role-of <their name>`), other than
|
|
69
|
+
your own role. When a role has several names, address the newest:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_fleet.py" newest <their role> --names-file <file with one name per line>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Send each one message, exactly: `<role> is now <name>` (your role, your name). Skip offline sessions
|
|
76
|
+
and cloud sessions. Keep the list of names you greeted for Step 6.
|
|
77
|
+
|
|
78
|
+
## Step 5 — restart the watchers
|
|
79
|
+
|
|
80
|
+
Read the relay's `## Watchers` section. For each entry:
|
|
81
|
+
|
|
82
|
+
1. Print the entry as written (script path, start command, stop condition, after-action).
|
|
83
|
+
2. Check the script path exists (handoff copied it to `.caddis/relay/<old name>-files/watchers/`)
|
|
84
|
+
and that the stop condition and the after-action are both in the relay. If either is missing,
|
|
85
|
+
do not start it: report it as `watcher not started: <reason>` in Step 6.
|
|
86
|
+
3. Start it with its exact start command through Bash with `run_in_background`. Never a foreground
|
|
87
|
+
`sleep` or loop.
|
|
88
|
+
|
|
89
|
+
No `## Watchers` section → 0 watchers.
|
|
90
|
+
|
|
91
|
+
## Step 6 — record the name and report
|
|
92
|
+
|
|
93
|
+
Record this session's presence (your session id is printed at session start as
|
|
94
|
+
`[caddis] this session's id: <id>`; never guess one):
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_fleet.py" whoami --session-id <id> --name <name> --root .
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Then print one line, and any `watcher not started:` lines under it:
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
[FLEET-OPEN] <role> restored: <n> tasks, <k> watchers, peers greeted: <names>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Rules
|
|
107
|
+
|
|
108
|
+
- One role per session. To restore another role, start another session from the sheet.
|
|
109
|
+
- Never `claude --resume` the old session: the sheet exists so every role starts fresh.
|
|
110
|
+
- Never edit the restart sheet or the roster; they are the record of the close.
|
|
@@ -167,7 +167,8 @@ gh alias set review 'pr list --search "review-requested:@me"'
|
|
|
167
167
|
|
|
168
168
|
```bash
|
|
169
169
|
gh issue develop 42 --branch fix/issue-42
|
|
170
|
-
git add .
|
|
170
|
+
git add src/auth/login.py tests/test_login.py # named files only, never `git add .`
|
|
171
|
+
git commit -m "fix: resolve login bug" && git push -u origin HEAD
|
|
171
172
|
gh pr create --title "fix: resolve login bug" --body "Closes #42"
|
|
172
173
|
gh pr checks --watch
|
|
173
174
|
gh pr merge --squash --delete-branch
|