@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
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: runner-move
|
|
3
|
+
description: >-
|
|
4
|
+
Move GitHub Actions jobs from self-hosted runners to GitHub-hosted runners, one repo at a time,
|
|
5
|
+
with a cost check and a pilot PR. Use when the user says "move CI to GitHub-hosted runners",
|
|
6
|
+
"stop using self-hosted runners", "runner migration", "move jobs off the runner box", or "run
|
|
7
|
+
CI on windows-latest or ubuntu-latest".
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# runner-move
|
|
11
|
+
|
|
12
|
+
Move the safe jobs of one repository from self-hosted runners to GitHub-hosted runners. Prove it
|
|
13
|
+
with one pilot PR. Then roll out repo by repo.
|
|
14
|
+
|
|
15
|
+
This skill is generic. It names no repository, host, path or organisation. The pilot at the end is
|
|
16
|
+
a labelled worked example only.
|
|
17
|
+
|
|
18
|
+
## The rule
|
|
19
|
+
|
|
20
|
+
Move a job only if it needs nothing that exists on the runner machine alone. When in doubt, the job
|
|
21
|
+
stays. A wrong move fails in CI. A wrong deploy move can break production.
|
|
22
|
+
|
|
23
|
+
## Step 1 - classify each job
|
|
24
|
+
|
|
25
|
+
Read the workflow file. For each job, read every `run:` step. Then read every script that the step
|
|
26
|
+
calls.
|
|
27
|
+
|
|
28
|
+
**Can move.** The job does only these things:
|
|
29
|
+
|
|
30
|
+
- checkout
|
|
31
|
+
- install dependencies
|
|
32
|
+
- lint and type-check
|
|
33
|
+
- unit and integration tests that use data in the repository
|
|
34
|
+
- builds
|
|
35
|
+
|
|
36
|
+
**Must stay.** The job does any of these things:
|
|
37
|
+
|
|
38
|
+
- writes to a server (deploy)
|
|
39
|
+
- restarts a service
|
|
40
|
+
- reads an internal host (a database, an internal git server, a file share, `localhost` of a server)
|
|
41
|
+
- uses a path that exists only on the runner (a drive path such as `C:\...` or `G:\...`, or a shared
|
|
42
|
+
cache folder)
|
|
43
|
+
- needs a licensed tool that is installed only on the runner
|
|
44
|
+
|
|
45
|
+
Search the workflow and the scripts it calls for these signs:
|
|
46
|
+
|
|
47
|
+
```powershell
|
|
48
|
+
git grep -n -i -E '[A-Z]:\\|localhost|127\.0\.0\.1|nssm|Restart-Service|Stop-Service|\\\\[a-z]' -- .github scripts
|
|
49
|
+
git grep -n -E 'secrets\.' -- .github/workflows
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Check each secret name. A secret that holds an internal host name or an internal URL means the job
|
|
53
|
+
reads that host.
|
|
54
|
+
|
|
55
|
+
Workflow-level `env:` that only the deploy jobs read does not block the check jobs. Look at which
|
|
56
|
+
job reads each variable.
|
|
57
|
+
|
|
58
|
+
Write the result as a table: job, current `runs-on`, move or stay, and the evidence line.
|
|
59
|
+
|
|
60
|
+
If no job can move, stop here and say so.
|
|
61
|
+
|
|
62
|
+
## Step 2 - cost
|
|
63
|
+
|
|
64
|
+
Do this before you edit. Hosted minutes can cost money.
|
|
65
|
+
|
|
66
|
+
```powershell
|
|
67
|
+
gh api orgs/<org> --jq .plan.name
|
|
68
|
+
gh api "organizations/<org>/settings/billing/usage?year=<Y>&month=<M>" # group the items by sku
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The old `/settings/billing/actions` endpoint returns HTTP 410. Do not use it.
|
|
72
|
+
|
|
73
|
+
Measure the minutes per run from recent runs:
|
|
74
|
+
|
|
75
|
+
```powershell
|
|
76
|
+
gh run list --workflow <file> --limit 50 --json databaseId,createdAt,conclusion
|
|
77
|
+
gh run view <id> --json jobs # startedAt and completedAt for each job
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Count the runs per month. Then compute: minutes per run, times runs per month, for each job you
|
|
81
|
+
will move.
|
|
82
|
+
|
|
83
|
+
Remember these facts:
|
|
84
|
+
|
|
85
|
+
- Windows minutes cost more than Linux minutes: about 1.7 times in the October 2026 usage data
|
|
86
|
+
(USD 0.010 against USD 0.006 a minute). Read the real rates from the usage call above.
|
|
87
|
+
- A private repository is billed after the included minutes of the plan.
|
|
88
|
+
- A public repository does not pay for hosted minutes.
|
|
89
|
+
|
|
90
|
+
**A change that adds cost needs owner approval.** Give the owner the numbers and wait for a yes.
|
|
91
|
+
|
|
92
|
+
## Step 3 - edit
|
|
93
|
+
|
|
94
|
+
Change `runs-on` only for the jobs that can move.
|
|
95
|
+
|
|
96
|
+
| The job's scripts are | Use |
|
|
97
|
+
|---|---|
|
|
98
|
+
| Windows scripts (PowerShell, batch) | `windows-latest` |
|
|
99
|
+
| Clean on Linux (no Windows-only tool) | `ubuntu-latest` |
|
|
100
|
+
|
|
101
|
+
Then fix these three things.
|
|
102
|
+
|
|
103
|
+
**1. Tool paths.** A runner-only path to Python or Node does not exist on a hosted runner. Install
|
|
104
|
+
the tool in the job. Pin the version that production and the old runner use.
|
|
105
|
+
|
|
106
|
+
```yaml
|
|
107
|
+
- uses: actions/setup-python@v5
|
|
108
|
+
id: py
|
|
109
|
+
with:
|
|
110
|
+
python-version: "<version of prod>"
|
|
111
|
+
- uses: actions/setup-node@v4
|
|
112
|
+
with:
|
|
113
|
+
node-version: "<version of prod>"
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
If a script reads an interpreter path from an environment variable, set that variable to the new
|
|
117
|
+
path:
|
|
118
|
+
|
|
119
|
+
```yaml
|
|
120
|
+
env:
|
|
121
|
+
PYTHON_EXE: ${{ steps.py.outputs.python-path }}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**2. The default shell.** Look at `defaults: run: shell:` in the workflow first. On `windows-latest`
|
|
125
|
+
the default shell is `pwsh` (PowerShell 7). The old runner often used Windows PowerShell 5.1. If the
|
|
126
|
+
workflow sets no default and the steps were written for 5.1, add this to the moved jobs:
|
|
127
|
+
|
|
128
|
+
```yaml
|
|
129
|
+
defaults:
|
|
130
|
+
run:
|
|
131
|
+
shell: powershell
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
If the workflow already sets `shell: powershell`, add nothing. Say in the PR that you checked.
|
|
135
|
+
|
|
136
|
+
**3. Shared-cache scripts.** A dependency script may read packages from a cache folder on the
|
|
137
|
+
runner. Read the script. It must fall back to a normal install when the folder is missing. If it
|
|
138
|
+
does not, the job must stay, or a separate PR must fix the script first (see "Do not").
|
|
139
|
+
|
|
140
|
+
Also:
|
|
141
|
+
|
|
142
|
+
- Leave `clean: false` on checkout. It does no harm on a fresh hosted VM.
|
|
143
|
+
- Do not add caching in the same change. A change in speed must not hide a change in behaviour.
|
|
144
|
+
Add caching in a later PR.
|
|
145
|
+
|
|
146
|
+
## Step 4 - pilot PR
|
|
147
|
+
|
|
148
|
+
Use one repository and one PR. A PR does not deploy, so it is a safe test.
|
|
149
|
+
|
|
150
|
+
**Exit gate.** Both of these must be true:
|
|
151
|
+
|
|
152
|
+
1. CI is green on the hosted runners.
|
|
153
|
+
2. The test counts equal the last self-hosted run. Compare the test summary lines of the old run
|
|
154
|
+
and the new run, line by line. Do this even for a suite that is allowed to fail. A suite that
|
|
155
|
+
"passes" with fewer tests ran less.
|
|
156
|
+
|
|
157
|
+
Then compare the job times with the last self-hosted run. Put both sets of numbers in the PR
|
|
158
|
+
description. The numbers decide whether the move is worth it.
|
|
159
|
+
|
|
160
|
+
If the counts differ, stop. Find the cause. A missing tool, a missing data folder, or a different
|
|
161
|
+
shell is the usual cause.
|
|
162
|
+
|
|
163
|
+
## Step 5 - monitoring impact
|
|
164
|
+
|
|
165
|
+
Do this before you merge. Look at every tool that watches CI or runners: dashboards, alerts and
|
|
166
|
+
reports. Ask these questions:
|
|
167
|
+
|
|
168
|
+
- Does the tool derive the job kind or group from the runner labels? Hosted jobs may fall into an
|
|
169
|
+
"other" group.
|
|
170
|
+
- Does the queue depth count jobs that wait for a hosted VM? That number now means something
|
|
171
|
+
different.
|
|
172
|
+
- Does any text say that every runner is self-hosted?
|
|
173
|
+
- Do runner-offline alerts still work? They are not affected. Hosted runners are not listed in
|
|
174
|
+
`/orgs/<org>/actions/runners`.
|
|
175
|
+
|
|
176
|
+
Write down each effect. Fix them in that tool's own PR. Do not fix them in the pilot PR.
|
|
177
|
+
|
|
178
|
+
## Step 6 - merge, watch, roll out
|
|
179
|
+
|
|
180
|
+
1. Merge the pilot PR.
|
|
181
|
+
2. Watch the first run on the default branch, **including the deploy job**. The deploy job stays on
|
|
182
|
+
the self-hosted runner. Check that it still starts and still works.
|
|
183
|
+
|
|
184
|
+
```powershell
|
|
185
|
+
python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_lanes.py" ci-watch --run <run-id> --repo <owner/name>
|
|
186
|
+
```
|
|
187
|
+
3. Only after this run is green, take the next repository. Repeat steps 1 to 6 for each one. Never
|
|
188
|
+
do all repositories at once.
|
|
189
|
+
|
|
190
|
+
## Do not
|
|
191
|
+
|
|
192
|
+
- Do not move deploy jobs.
|
|
193
|
+
- Do not move a job that reads an internal host.
|
|
194
|
+
- Do not change shared scripts in the same PR. Change them in an earlier PR, and merge it first.
|
|
195
|
+
- Do not roll out to all repositories before one pilot has passed.
|
|
196
|
+
- Do not add caching in the move PR.
|
|
197
|
+
- Do not delete the self-hosted runner. Other jobs and repositories may still use it.
|
|
198
|
+
|
|
199
|
+
## Worked example (labelled: one real pilot)
|
|
200
|
+
|
|
201
|
+
One pilot repository (a Python and React app), 2026-10-15, PR #30, merge `432d385`. The numbers
|
|
202
|
+
here are an example, not a default. The repository name is left out on purpose.
|
|
203
|
+
|
|
204
|
+
- Step 1: the check jobs (change detection, lint and test, frontend checks) could move. The deploy
|
|
205
|
+
job wrote to a server, so it stayed.
|
|
206
|
+
- Step 3: the workflow already had `shell: powershell`, so no shell change was needed. A runner-only
|
|
207
|
+
Python path became `actions/setup-python` and `actions/setup-node`.
|
|
208
|
+
- Step 4: the Python suite is non-blocking. The summary was `31 failed, 33 passed, 27 skipped` on
|
|
209
|
+
the self-hosted run and on the hosted run. The counts matched.
|
|
210
|
+
- Job times, self-hosted to hosted: change detection 132 s to 17 s, lint and test 85 s to 99 s,
|
|
211
|
+
frontend checks 482 s to 402 s.
|
|
212
|
+
- Step 5: the monitoring tool grouped jobs by runner label, so hosted jobs fell into "other". Its
|
|
213
|
+
queue count also included jobs that waited for a hosted VM. Nothing broke and no alert fired. The
|
|
214
|
+
team noted the fix for that tool's own PR.
|
|
@@ -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
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: office-documents-official
|
|
3
|
+
description: Hint for Office and PDF file work. Use when the user asks to create, edit, read or convert a Word .docx, PDF, PowerPoint .pptx or Excel .xlsx file. caddis does not ship these skills; points to Anthropic's official document-skills plugin.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Office and PDF files: use Anthropic's document-skills
|
|
7
|
+
|
|
8
|
+
caddis does not include skills for Word (.docx), PDF, PowerPoint (.pptx) or Excel (.xlsx) files.
|
|
9
|
+
These skills belong to Anthropic. Anthropic publishes them as the `document-skills` plugin.
|
|
10
|
+
|
|
11
|
+
## Install (Claude Code)
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
/plugin marketplace add anthropics/skills
|
|
15
|
+
/plugin install document-skills@anthropic-agent-skills
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Source: https://github.com/anthropics/skills (see its README, section "Claude Code").
|
|
19
|
+
|
|
20
|
+
## What to do
|
|
21
|
+
|
|
22
|
+
1. If the plugin is installed, use its `docx`, `pdf`, `pptx` or `xlsx` skill for the file type. Do not work from this note.
|
|
23
|
+
2. If the plugin is not installed, tell the user the two commands above. Then ask if they want to install it first.
|
|
24
|
+
3. If the user cannot install it, say what you can do without it. For example, write the content as Markdown and let the user convert it.
|
package/bundles/codex/.codex/skills/workflow/best-practices/agents/best-practices-referencer.md
CHANGED
|
@@ -44,7 +44,7 @@ description: >-
|
|
|
44
44
|
constraints pattern, and surfaces anti-patterns around breaking changes.
|
|
45
45
|
</commentary>
|
|
46
46
|
</example>
|
|
47
|
-
model:
|
|
47
|
+
model: sonnet
|
|
48
48
|
---
|
|
49
49
|
|
|
50
50
|
**Note: The current year is 2026.** Use this when searching for recent documentation and patterns.
|
package/bundles/codex/.codex/skills/workflow/best-practices/agents/codebase-context-builder.md
CHANGED
|
@@ -46,7 +46,7 @@ description: >-
|
|
|
46
46
|
finds slow query examples, and identifies existing performance tests.
|
|
47
47
|
</commentary>
|
|
48
48
|
</example>
|
|
49
|
-
model:
|
|
49
|
+
model: sonnet
|
|
50
50
|
---
|
|
51
51
|
|
|
52
52
|
**Note: The current year is 2026.** Use this when referencing recent patterns or documentation.
|
|
@@ -48,7 +48,7 @@ description: >-
|
|
|
48
48
|
considerations: caching, N+1 queries, database indexes, async processing.
|
|
49
49
|
</commentary>
|
|
50
50
|
</example>
|
|
51
|
-
model:
|
|
51
|
+
model: sonnet
|
|
52
52
|
---
|
|
53
53
|
|
|
54
54
|
**Note: The current year is 2026.** Use this when referencing recent patterns or documentation.
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: roadmap
|
|
3
|
+
description: "Track milestones across plans in .caddis/roadmaps/<slug>/: next batch, typed blockers, rollup. Every change is a docs PR via caddis_roadmap.py."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Roadmap
|
|
7
|
+
|
|
8
|
+
**Core rule:** the roadmap file on `origin/main` is the only truth; every change to it, by a tool or a human, is a
|
|
9
|
+
small docs PR, so it is ordered and recorded in git history. The tool's PRs are merged automatically on green checks
|
|
10
|
+
by `caddis_merge_chain.py --docs-only`; a repo that wants a human to review them protects its default branch.
|
|
11
|
+
|
|
12
|
+
`scripts/` below is the caddis scripts folder: `${CLAUDE_PLUGIN_ROOT}/scripts` in an installed plugin, `scripts/` in
|
|
13
|
+
the caddis source repo.
|
|
14
|
+
|
|
15
|
+
## The folder
|
|
16
|
+
|
|
17
|
+
`.caddis/roadmaps/<slug>/` holds:
|
|
18
|
+
|
|
19
|
+
| Path | What |
|
|
20
|
+
|---|---|
|
|
21
|
+
| `roadmap.md` | Milestones and Blockers tables (start from `assets/roadmap.template.md`) |
|
|
22
|
+
| `decisions.md` | decision register; a `Depends on` change cites an id from here |
|
|
23
|
+
| `cards/` | one **card** per unit of work handed to a lane or a reviewer: scope, files, pass criteria |
|
|
24
|
+
| `reports/` | what comes back from a card |
|
|
25
|
+
| `.local/` | machine-local: `changes.jsonl` (audit of the tool's PRs), the runner's `runner.jsonl` and `STOP` (its lock and other state are in `<git common dir>/caddis-runner/roadmap-<slug>/`) |
|
|
26
|
+
|
|
27
|
+
Plans stay in `.caddis/plans/`. Add `.caddis/roadmaps/*/.local/` to the repo's `.gitignore`. The write lock is not in
|
|
28
|
+
the folder: it is `<git common dir>/caddis-roadmaps/<slug>.write.lock`, so every worktree of the repo shares it.
|
|
29
|
+
|
|
30
|
+
## The format
|
|
31
|
+
|
|
32
|
+
```markdown
|
|
33
|
+
Runner host: <runner-host>
|
|
34
|
+
|
|
35
|
+
## Milestones
|
|
36
|
+
| ID | Milestone | Phases | Depends on | Exit check | Status | Owner | Target |
|
|
37
|
+
|---|---|---|---|---|---|---|---|
|
|
38
|
+
| S1 | Lines load | p-alpha#1, p-alpha#2 | - | `python scripts/check_s1.py` | todo | runner | WD3 |
|
|
39
|
+
|
|
40
|
+
## Blockers
|
|
41
|
+
| Milestone | Type | Reason | Check |
|
|
42
|
+
|---|---|---|---|
|
|
43
|
+
| S2 | data-condition | GPU rows not loaded | `python scripts/rows_ready.py` |
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
- **Status:** `todo`, `in-progress`, `code-done/data-pending`, `done`, `not-needed`. There is no `blocked` status: a
|
|
47
|
+
milestone is blocked when it has a Blockers row.
|
|
48
|
+
- **Blocker types:** `owner-gate`, `external`, `shared` (a shared file, the GPU, the merge line, another session),
|
|
49
|
+
`calendar`, `data-condition`. A new `calendar` blocker needs an ISO date `YYYY-MM-DD` in Check
|
|
50
|
+
(`block --type calendar --check 2026-11-01`); a date is not a command, so it needs no `--by-owner`.
|
|
51
|
+
- **Owner:** `runner` (or empty) lets the runner take it; a session name means that session does it by hand.
|
|
52
|
+
- **Phase ref** `p-alpha#2` = Phase 2 in the Tracker of `.caddis/plans/p-alpha.md` or `.caddis/plans/done/p-alpha.md`.
|
|
53
|
+
It is done only when its Tracker Status starts with `done` or a check mark **on origin**. Refs work inside one repo.
|
|
54
|
+
- **Runner host:** the one machine whose runner may run this roadmap. Write a placeholder such as `HOSTNAME` in
|
|
55
|
+
shared examples.
|
|
56
|
+
- A `Depends on` change cites a decision id in the Milestone cell: `S9 (dep waived: TC94)`. `check` warns otherwise.
|
|
57
|
+
- **Strict sections.** `## Milestones` and `## Blockers` hold only blank lines, one table whose every line starts with
|
|
58
|
+
`|`, and prose with no unescaped `|` set apart from the table by a blank line. Anything else is a parse error.
|
|
59
|
+
A roadmap allows only headings, plain paragraphs, lists and pipe tables: no code fences, no HTML, no setext
|
|
60
|
+
headings, no control or non-ASCII whitespace characters.
|
|
61
|
+
- **A malformed roadmap fails closed.** A row with the wrong cell count, a `|` line outside a table, a near-miss
|
|
62
|
+
heading such as `## Blockers (open)`, an id that is not `[A-Za-z0-9_-]+`, an unknown Status or blocker type, or a
|
|
63
|
+
phase ref to a missing plan: every command but `check` exits 4 and prints the errors. Fix the file by a PR.
|
|
64
|
+
|
|
65
|
+
## Commands
|
|
66
|
+
|
|
67
|
+
Every command runs `git fetch origin` and reads `origin/<default>`, never the working tree. Exit check and Check
|
|
68
|
+
commands run in a temporary worktree of `origin/<default>` (the merged code), with no stdin, killed with their whole
|
|
69
|
+
process tree on timeout.
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
python scripts/caddis_roadmap.py status --roadmap <slug> [--json] # "<done> of <total> done; next <id>; ..."
|
|
73
|
+
python scripts/caddis_roadmap.py render --roadmap <slug> | --all [--out <html>] # page: ~/.caddis/roadmap-pages/<repo>/<slug>.html; hub of every repo: ~/.caddis/roadmap-pages/index.html
|
|
74
|
+
python scripts/caddis_roadmap.py next --roadmap <slug> [--json] # exit 0 found, 1 nothing ready (reasons)
|
|
75
|
+
python scripts/caddis_roadmap.py check --roadmap <slug> # parse errors, unknown refs or types
|
|
76
|
+
python scripts/caddis_roadmap.py set --roadmap <slug> --id S1 --col Status|Owner|Target --value <v> [--by-owner] [--reason "<r>"]
|
|
77
|
+
python scripts/caddis_roadmap.py block --roadmap <slug> --id S2 --type <type> --reason "<text>" [--check "<cmd>" --by-owner]
|
|
78
|
+
python scripts/caddis_roadmap.py unblock --roadmap <slug> --id S2 --type <type> --reason "<text>" [--check "<cmd>"] [--by-owner]
|
|
79
|
+
python scripts/caddis_roadmap.py rollup --roadmap <slug> --id S1
|
|
80
|
+
python scripts/caddis_roadmap.py recheck --roadmap <slug>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`next` picks the first milestone in table order that is `todo` or `in-progress`, whose `Depends on` are all `done` or
|
|
84
|
+
`not-needed`, with no Blockers row, Owner `runner` or empty, and a phase not yet merged. It returns that phase.
|
|
85
|
+
|
|
86
|
+
## Rules a runner trusts
|
|
87
|
+
|
|
88
|
+
- **Only `rollup` writes `done`.** `set --value done` exits 4. `rollup` needs every phase merged on origin, every
|
|
89
|
+
`Depends on` milestone `done` or `not-needed`, and no open blocker other than `data-condition` (exit 1 names it),
|
|
90
|
+
then runs the Exit check (300 s): pass -> `done`; fail with a `data-condition` blocker -> `code-done/data-pending`;
|
|
91
|
+
fail otherwise -> an `external` blocker
|
|
92
|
+
`exit check failing (exit <n>)` (never the command's output). A milestone with no phase refs and no Exit check is
|
|
93
|
+
refused (exit 4).
|
|
94
|
+
- **Owner-only changes:** `set` Status `not-needed`, any `set` Owner, `unblock` of an `owner-gate`, and `block --check`
|
|
95
|
+
(recheck runs that command unattended later). They need `--by-owner` and are refused headless: `CADDIS_HEADLESS`
|
|
96
|
+
or `CLAUDECODE` in the environment (even empty), stdin not a terminal, or on
|
|
97
|
+
Windows stdin not a console (a NUL stdin is headless).
|
|
98
|
+
- **`unblock` removes one blocker.** When two rows share milestone, type and reason, it exits 4 until `--check`
|
|
99
|
+
names the row's Check text.
|
|
100
|
+
- **`recheck` clears `data-condition` blockers**, each row whose own Check passed (120 s), **and `calendar`
|
|
101
|
+
blockers whose Check date has passed** (UTC; no command runs). A `calendar` row whose Check is `-` stays until
|
|
102
|
+
someone runs `unblock`. Other types stay.
|
|
103
|
+
- **`not-needed` needs a reason.** `set --col Status --value not-needed --by-owner` also needs
|
|
104
|
+
`--reason "dropped: <why>"` or `--reason .caddis/parking-lot/<file>.md` (the file must be on origin). A reason with
|
|
105
|
+
`|` or a line break exits 4. The same docs PR adds `- <id> not-needed: <reason> (YYYY-MM-DD)` under `## Notes`
|
|
106
|
+
(the section is added at the end when missing).
|
|
107
|
+
- **Old blockers are listed.** `status` (and so the runner's toast) ends with
|
|
108
|
+
`old blockers: <id> <type> (<N> days), ...`, oldest first, for each blocker row older than 14 days. The age is the
|
|
109
|
+
date of the newest commit on origin that added that exact row (`git log -S`): the roadmap never stores a date, and
|
|
110
|
+
a row that was cleared and added again counts from the new add.
|
|
111
|
+
- **Commands run the merged code.** Editing a check script or a Check in the working tree changes nothing until it
|
|
112
|
+
merges.
|
|
113
|
+
|
|
114
|
+
## How a write lands
|
|
115
|
+
|
|
116
|
+
`set`, `block`, `unblock`, `rollup` and `recheck` take the write lock (after 30 s, a lock whose holder is dead on
|
|
117
|
+
this host, or an empty or non-JSON lock older than 60 s, is taken over), branch `roadmap/<slug>-<id>-<utc>` from
|
|
118
|
+
`origin/<default>` in a temp worktree, commit `docs(roadmap): <slug> <id> <change>`, push, open a PR, and hand it to
|
|
119
|
+
`caddis_merge_chain.py --docs-only`. `gh` uses the account in `GH_TOKEN` when it is set. Git network calls time out
|
|
120
|
+
after 120 s, `gh` after 60 s and the merge chain after 1800 s (exit 3); none can wait on a credential prompt. `--dry-run` prints the diff
|
|
121
|
+
and `would run: <cmd>` lines, and runs and writes nothing. Exit codes: 0 clean, 1 blocked, 3 could not run, 4 error
|
|
122
|
+
(malformed roadmap, refused change, bad usage).
|
|
123
|
+
|
|
124
|
+
## The runner
|
|
125
|
+
|
|
126
|
+
`roadmap-run.ps1 -Roadmap <slug>` (a shim over `scripts/caddis_roadmap_run.py --roadmap <slug>`) runs the roadmap
|
|
127
|
+
unattended; `-Plan <slug>` runs one plain plan instead (the two are exclusive). It starts only on the roadmap's
|
|
128
|
+
`Runner host` (else exit 3). Each iteration:
|
|
129
|
+
|
|
130
|
+
1. `next`. Nothing ready: stop `BLOCKED nothing ready` (exit 1); the notification carries the `status` line. When
|
|
131
|
+
the roadmap is finished (every milestone `done` or `not-needed`) the runner also removes its worktree if it is
|
|
132
|
+
clean (only session relay files left), and keeps it, saying so in the stop line, if not. With the worktree gone it
|
|
133
|
+
also deletes the local `caddis/roadmap/<slug>/*` branches merged into `origin/<default>` and names the others.
|
|
134
|
+
2. Print `next: <milestone> <plan>#<phase>` (`next` and the batch claim happen under one repo-level claim lock).
|
|
135
|
+
A phase whose `**Lane:**` line does not start with this engine (`claude`, `agy`, `codex`), names a cloud session
|
|
136
|
+
or the owner, or that has **no Lane line**, is not run (fail closed): the runner adds
|
|
137
|
+
`block --type owner-gate --reason "phase <n> lane: <lane>"` (`lane: none` when there is no line) and goes on.
|
|
138
|
+
3. A `todo` milestone is set `in-progress` (a docs PR). Every session of a roadmap runs in ONE dedicated worktree,
|
|
139
|
+
`%TEMP%/caddis-roadmap-<slug>-<8 hex of the repo's git common dir>`: made with `git worktree add --detach` from `origin/<default>` on the first
|
|
140
|
+
session, reused on restart, recorded in the runner folder, never the `-Repo` checkout (plan mode keeps working in
|
|
141
|
+
the given checkout). In that worktree the runner makes a fresh branch `caddis/roadmap/<slug>/<plan>-p<n>` from
|
|
142
|
+
`origin/<default>` (it refuses a branch of that name already on origin that it did not make) and ONE session runs
|
|
143
|
+
`assets/plan-resume-prompt.md` on it (if a blocked session left uncommitted work in the worktree, the runner
|
|
144
|
+
stops `BLOCKED roadmap worktree has uncommitted work from <branch>` instead, and a session branch that already
|
|
145
|
+
holds commits not on `origin/<default>` is never reset: `BLOCKED <branch> has unpublished commits from an earlier
|
|
146
|
+
session`; the owner decides), with `{{slug}}` = the plan and
|
|
147
|
+
`{{phase}}` = the phase. Every session gets its own fresh branch (also after an OWNER-GATE or BLOCKED one), so a
|
|
148
|
+
blocked phase's commits never reach another PR. Sessions stay on that branch and never push.
|
|
149
|
+
4. Relay `STATUS: CONTINUE` with new commits on that branch: the **runner** checks that the session is still on it
|
|
150
|
+
and did not touch `.caddis/roadmaps/` (else `FAILED`, nothing published), then, in this order: writes a persistent
|
|
151
|
+
claim `<git common dir>/caddis-runner/claims/<plan>#<n>.json`, pushes the branch, opens a PR (`gh api`, the account
|
|
152
|
+
from `GH_TOKEN`) titled `<plan> phase <n>: <phase title>`, writes the PR URL into the claim, records the wait in its
|
|
153
|
+
runner folder's `waiting.json` (ref, PR, milestone, branch, claim and its hash, the roadmap hash; never in the last
|
|
154
|
+
stop), and stops `BLOCKED waiting for merge <plan>#<phase> <pr url>` (exit 1). A run killed between the claim and
|
|
155
|
+
`waiting.json` leaves a claim nothing names: the next start stops on it as an orphaned claim. On restart, GitHub
|
|
156
|
+
must confirm the PR merged before any branch is deleted; a done Tracker row with the PR still open or closed
|
|
157
|
+
unmerged stops `BLOCKED <ref> Tracker row is done but PR <url> is not merged` and keeps the branch, the claim and
|
|
158
|
+
`waiting.json`. The claim keeps the phase held (`next`, other roadmaps and plan mode skip or refuse it) until the PR
|
|
159
|
+
merges or closes. A run started while the PR still waits stops at once (`BLOCKED still waiting for merge of <ref>:
|
|
160
|
+
<url>`) and changes nothing. Once it merges, the recheck task restarts the runner. The restart first checks that the merged
|
|
161
|
+
origin roadmap is the one it published against (a hash, then the frozen tables; any difference is `FAILED roadmap
|
|
162
|
+
changed`), rolls the milestone up FIRST (when every phase is merged), then removes the claim and the phase's
|
|
163
|
+
branch (locally and on origin: whoever makes a branch removes it when its PR merges), and goes on with `next`.
|
|
164
|
+
An own claim that neither the waiting record nor `pending-rollup.json` names (a run killed between the claim and
|
|
165
|
+
the wait) stops the start `BLOCKED orphaned claim <file> from a killed run`; the owner checks the branch and its PR
|
|
166
|
+
and deletes the claim.
|
|
167
|
+
CONTINUE with the phase already merged on origin: `rollup` when every phase is merged, then back to 1. CONTINUE
|
|
168
|
+
with no new commits and nothing merged stops FAILED. `STATUS: OWNER-GATE <r>` becomes an `owner-gate` blocker,
|
|
169
|
+
`STATUS: BLOCKED <r>` an `external` one; then back to 1. `STATUS: FAILED` stops.
|
|
170
|
+
5. Every `**Risk:** high` phase done on the branch and not yet reviewed clean (record in the runner's own folder:
|
|
171
|
+
`<git common dir>/caddis-runner/roadmap-<slug>/reviewed/<plan>.json`; another runner's record does not count) is
|
|
172
|
+
reviewed BEFORE step 4 writes the claim and publishes
|
|
173
|
+
(`caddis_review.py --plan --phase --runs 2`): exit 0 publishes;
|
|
174
|
+
exit 1 starts one fix session, then one more review; exit 1 again stops `BLOCKED review`, exit 3, 4 or any other
|
|
175
|
+
code `BLOCKED review not run` (neither restartable); the review cost counts against the USD caps.
|
|
176
|
+
|
|
177
|
+
Stops (each one notifies and releases the lock): a STOP file (`~/.caddis/STOP` or `.local/STOP`), any cap (10 h,
|
|
178
|
+
12 sessions, 120 min and USD 25 per session, USD 150 total; per run, in memory; the global agy spend cap of
|
|
179
|
+
`caddis_spend.py` still counts across runs), a lock or batch claim that cannot be written
|
|
180
|
+
(`BLOCKED claim not written`, before any session), the agy spend cap refusing a reservation, three sessions
|
|
181
|
+
with no newly merged phase, a roadmap write that fails, and the **snapshot guard**: one baseline for the whole run.
|
|
182
|
+
The Milestones and Blockers tables (every cell of every row, rows added, removed or moved) and the `Runner host` line
|
|
183
|
+
are frozen. Every origin read (each `next`, after the runner's own writes, after each session) is compared with the
|
|
184
|
+
previous one; the only differences allowed are the exact edits the runner itself made and recorded for that read: a
|
|
185
|
+
Status it set, a blocker row it added, and what a rollup's audit entry (`changes.jsonl`) says it actually wrote.
|
|
186
|
+
Anything else stops the run `FAILED roadmap changed`.
|
|
187
|
+
Each runner has its own state folder, `<git common dir>/caddis-runner/roadmap-<slug>/` (plan mode: `plan-<slug>/`):
|
|
188
|
+
lock, last stop, options, branches, worktree path, the saved roadmap text. `claims/` and `claim.lock` are shared at
|
|
189
|
+
the top level. The runner hashes its own folder (recursively) and its own claims before and after every session; a
|
|
190
|
+
change there stops the run `FAILED runner state changed` (not restartable). Another runner's writes never stop it. A restart checks that the claim its
|
|
191
|
+
waiting-for-merge stop records is still there with the same content; a missing record, claim or hash is
|
|
192
|
+
`FAILED own claim missing or changed` (not restartable). During the upgrade window a plan-mode lock of the base
|
|
193
|
+
version (`.caddis/plans/.local/<slug>/runner.lock`, read only) still holds its plan while its pid runs and the lock
|
|
194
|
+
file is newer than that process's start (else it is ignored). Roadmap slugs
|
|
195
|
+
match `^[a-z0-9][a-z0-9-]{0,62}$` everywhere (both scripts and `caddis_roadmap.py`). The launch options are kept
|
|
196
|
+
in memory and re-written at every stop, so a changed options file can never raise the caps.
|
|
197
|
+
|
|
198
|
+
The runner never passes `--by-owner`. Every session and every `caddis_roadmap.py` call it starts gets
|
|
199
|
+
`CADDIS_HEADLESS=1`. The runner lock is `<git common dir>/caddis-runner/roadmap-<slug>/runner.lock` (a plan-mode
|
|
200
|
+
runner: `plan-<slug>/runner.lock`), so every worktree sees it. It holds `{"host", "pid", "started_utc", "batch", "max_hours"}`. On
|
|
201
|
+
this host it is stale when its pid is not running, or the process now holding that pid started after `started_utc`
|
|
202
|
+
(pid reuse after a reboot; when the start time cannot be read, it counts as live). Another host's lock is stale when it
|
|
203
|
+
is older than its own `max_hours` plus 1 h. A stale lock is removed with a notification; a live lock is exit 3. A
|
|
204
|
+
plan-mode lock holds the whole plan (`batch` `<plan>#*`). `next` skips a phase another live lock holds, and plan mode
|
|
205
|
+
refuses a plan that a roadmap lock names, at start and before every session. `-DryRun` prints the chosen batch,
|
|
206
|
+
the session command, the worktree and any pending rollup, skips the host check, writes no files and starts nothing; it
|
|
207
|
+
does run `git fetch`, which updates the remote-tracking refs. `-GhAccount <login>` (recorded in the launch options,
|
|
208
|
+
passed on by the recheck task and in the printed task) makes every gh call of the runner and of `--last-stop` use
|
|
209
|
+
GH_TOKEN from `gh auth token -u <login>`; on a machine with several gh logins, give the repo's account. A gh call that
|
|
210
|
+
cannot answer (gh missing, 401, 404) is an error, never "not merged": the run stops
|
|
211
|
+
`BLOCKED gh cannot see <repo> with account <login>`, notified and recorded.
|
|
212
|
+
|
|
213
|
+
`roadmap-recheck.ps1 -Roadmap <slug> -Repo <path>` starts `roadmap-run.ps1 -Roadmap <slug>` detached only when:
|
|
214
|
+
the runner's last recorded stop (next to its lock) is `BLOCKED nothing ready` or there is none, and `recheck`
|
|
215
|
+
cleared a blocker; or the last stop is `BLOCKED waiting for merge` and GitHub says that PR merged
|
|
216
|
+
(`--last-stop` asks GitHub only and fetches nothing; the restarted runner checks the Tracker row on origin under its
|
|
217
|
+
lock; in that tick recheck does NOT run `recheck`, because a cleared blocker would change the roadmap the restart
|
|
218
|
+
checks against its hash). If GitHub says merged but the Tracker row is not done, the restart
|
|
219
|
+
removes the claim and stops `BLOCKED <ref> merged but its Tracker row is not done` (the owner decides). A `BLOCKED nothing ready` stop also records the batches that
|
|
220
|
+
another runner's lock or claim held; once every one of those holders is gone, `--last-stop` says `freed:` and recheck
|
|
221
|
+
restarts the runner even with no blocker cleared. A plan in flight anywhere (a live lock or a claim on any of its
|
|
222
|
+
phases) holds the whole plan for every other roadmap and for plan mode. At the top of each run the runner rolls up
|
|
223
|
+
every milestone that waits only for its rollup (Status not finished, every phase merged, and the same rule as
|
|
224
|
+
`next`: no blocker, dependencies finished, Owner the runner); `--last-stop` says `rollup-ready:` for such a milestone,
|
|
225
|
+
so recheck restarts the runner. A sweep rollup that writes nothing stops `BLOCKED rollup of <id> wrote nothing`
|
|
226
|
+
(recorded, not restartable) and is not retried or reported until the roadmap changes. The dry run lists them first. If
|
|
227
|
+
the owner edits the roadmap during a merge wait, the restart stops `FAILED roadmap changed ...` and names the
|
|
228
|
+
recovery: `roadmap-run.ps1 -Roadmap <slug> -AcceptRoadmap` (owner only, refused headless) takes the runner lock (a live
|
|
229
|
+
runner refuses it), prints the diff from the published baseline, asks you to type `accept` (or `--yes`), and accepts
|
|
230
|
+
the origin roadmap as the new baseline of the wait; the next start goes on. With `-DryRun` it prints the diff only. `--last-stop` uses `--gh-account`, else the account the run recorded
|
|
231
|
+
in its launch options. In all cases the lock must be absent or stale; for the agy engine `caddis_spend.py check` must exit 0 too (a
|
|
232
|
+
claude-engine roadmap needs no spend-cap file). A restart after a merge writes `pending-rollup.json` in its runner
|
|
233
|
+
folder, runs the rollup first, then removes the claim and the branch, and only then the file. Every stop records
|
|
234
|
+
itself: a failed rollup, a crash or a STOP file before that is not restartable (the owner decides), and the next start
|
|
235
|
+
finds the file and does the rollup first. A merged
|
|
236
|
+
branch checked out in another checkout is kept locally (HEAD never moves outside the roadmap worktree).
|
|
237
|
+
Any FAILED stop (the snapshot guard, a crash), a cap or a STOP file needs the owner: recheck prints why and starts
|
|
238
|
+
nothing; the owner's next manual run records a new last stop. A runner records the last stop `running` as soon as it
|
|
239
|
+
holds the lock, so a run killed without a stop (a reboot, a kill) also needs the owner; an unexpected exception
|
|
240
|
+
records `FAILED crash: <type>` and notifies once. Recheck restarts with the launch options the last run recorded
|
|
241
|
+
(engine, model, caps), each cap clamped to at most the built-in default (the options file is writable), never higher.
|
|
242
|
+
`roadmap-run.ps1 -Roadmap <slug> -PrintRecheckTask` prints a PowerShell block (`New-ScheduledTaskAction`,
|
|
243
|
+
`New-ScheduledTaskTrigger` every 2 hours, `Register-ScheduledTask`) for the owner to paste; it registers nothing. The
|
|
244
|
+
task runs only while you are logged on unless you add `-User` and `-Password` to `Register-ScheduledTask` (or set that
|
|
245
|
+
option in Task Scheduler).
|
|
246
|
+
|
|
247
|
+
## Limits
|
|
248
|
+
|
|
249
|
+
Sessions are cooperative (our own sessions): the runner guards against mistakes and runaway spend, not against a
|
|
250
|
+
deliberately hostile session, which runs as the same OS user and could change anything the runner can. The state
|
|
251
|
+
tripwire catches accidents in a runner's own state only. In particular, a session in another worktree of the repo can
|
|
252
|
+
delete or rewrite ANOTHER runner's claim or lock under `<git common dir>/caddis-runner/`; that is not caught while it
|
|
253
|
+
happens, and the victim runner fails closed only at its next restart (own claim missing or changed, orphaned claim). Caps are per run; the agy spend cap is the only limit across runs. Each roadmap has one
|
|
254
|
+
worktree, removed when the roadmap is finished and the worktree is clean.
|
|
255
|
+
|
|
256
|
+
Owner-only rules are enforced by this tool; a direct PR that edits `roadmap.md` bypasses them; the runner stops
|
|
257
|
+
when an owner-gate row disappears; repos that need more protect their default branch.
|
|
258
|
+
On Windows, a check's grandchild started in the instant before the job object is attached can escape the tree kill;
|
|
259
|
+
checks are owner-written, so this is accepted. Headless detection cannot see a process started in a fresh console with
|
|
260
|
+
the markers removed: anything that runs this tool unattended (the runner, scheduled tasks) must set `CADDIS_HEADLESS=1`.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: prompt
|
|
3
|
+
title: Plan resume prompt for {{slug}}
|
|
4
|
+
description: The prompt for one fresh runner session of the plan {{slug}} (runner plan mode). It does one batch and ends with a status line.
|
|
5
|
+
status: current
|
|
6
|
+
timestamp: {{date}}
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
You are a fresh session for the plan `{{slug}}`. Do ONE batch, then stop.
|
|
10
|
+
|
|
11
|
+
In the commands below, `<scripts>` is the caddis scripts folder `{{scripts}}` (put it in quotes if it holds a space).
|
|
12
|
+
Use the scripts in that folder; do not look for them in another caddis install.
|
|
13
|
+
|
|
14
|
+
## 1. Read
|
|
15
|
+
|
|
16
|
+
1. The plan `.caddis/plans/{{slug}}.md`: its goal, its decisions, its tracker. Every decision binds you.
|
|
17
|
+
2. The relay `.caddis/relay/{{slug}}.md`. Its "Next step" says where to start.
|
|
18
|
+
3. The open-work list `.caddis/open-work.md`, when it exists.
|
|
19
|
+
|
|
20
|
+
## 2. Step 0: reconcile
|
|
21
|
+
|
|
22
|
+
The relay can be old. Before you act, compare it with the real state: the plan tracker, worktrees, local branches, open
|
|
23
|
+
pull requests and remote branches. If they disagree, trust the real state. Fix the relay and the tracker. Do not build on a
|
|
24
|
+
guess.
|
|
25
|
+
|
|
26
|
+
## 3. Pick the batch
|
|
27
|
+
|
|
28
|
+
A batch is ONE tracker phase (the first row that is not done and not blocked), or ONE named batch that the plan or the relay
|
|
29
|
+
names. If no row can start, end with the status line that says why (an owner gate, a block, or FAILED).
|
|
30
|
+
|
|
31
|
+
The phase number chosen by the roadmap runner (empty: choose the batch yourself as above): {{phase}}
|
|
32
|
+
When it holds a number, that phase is the batch. Do only that phase.
|
|
33
|
+
|
|
34
|
+
Roadmap mode (a number above): the runner, not you, publishes the work. The runner made the branch you are on
|
|
35
|
+
(`caddis/roadmap/<roadmap>/<plan>-p<n>`, fresh from the default branch). Stay on it: never switch or create a branch,
|
|
36
|
+
never push, never open a pull request, and never edit anything under `.caddis/roadmaps/` (the runner refuses to
|
|
37
|
+
publish a branch that does). Commit the phase there, with its tracker row set to `done`. When you end with
|
|
38
|
+
`STATUS: CONTINUE` and new commits on that branch, the runner pushes it, opens the pull request and stops with
|
|
39
|
+
`BLOCKED waiting for merge`; the recheck task restarts the runner after the merge.
|
|
40
|
+
|
|
41
|
+
## 4. Work
|
|
42
|
+
|
|
43
|
+
- Do ONE batch with `/caddis:implement` discipline: tests first, the phase's exit gate, a commit per phase.
|
|
44
|
+
- agy sessions only: run `python {{scripts}}/caddis_spend.py check` before each agy call. Stop at the cap (exit 1 over
|
|
45
|
+
the cap, 3 not configured).
|
|
46
|
+
- You may do everything except pass an owner gate. Never pass an owner gate. Never raise a cap. Never delete a STOP file.
|
|
47
|
+
- The runner reviews `risk: high` phases. A phase marked `**Risk:** high`: do not halt for it and do not run the
|
|
48
|
+
review yourself. When its exit gate is green, set its row `done` and end with `STATUS: CONTINUE`. The runner then
|
|
49
|
+
reviews it twice and, on findings, starts one fix session.
|
|
50
|
+
- Set the tracker row of the batch to `done` (with its evidence) when its exit gate is green. Set open-work rows with
|
|
51
|
+
`python <scripts>/caddis_rows.py set` (by row id and column name).
|
|
52
|
+
|
|
53
|
+
## 5. Write the relay
|
|
54
|
+
|
|
55
|
+
Write the relay with `python <scripts>/caddis_workstreams.py put --require-status {{slug}} <file>`. Write `<file>` outside
|
|
56
|
+
the repo (for example in the temp folder). Read the current relay first with `python <scripts>/caddis_workstreams.py read {{slug}}`;
|
|
57
|
+
keep its frontmatter shape (`type: relay`, `workstream: {{slug}}`, `branch`, `session_id`, `plan`, `generated.at`). The LAST
|
|
58
|
+
non-empty line must be exactly one of these four:
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
STATUS: CONTINUE
|
|
62
|
+
STATUS: OWNER-GATE <P>-OG<n>
|
|
63
|
+
STATUS: BLOCKED <owner>
|
|
64
|
+
STATUS: FAILED <reason>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Use `STATUS: CONTINUE` only when the next batch can start with no owner input. A missing or bad line counts as FAILED.
|
|
68
|
+
An owner gate id has the form `<P>-OG<n>`: the plan's 2 to 4 capital-letter prefix (for example `PM-OG1`). Name the gate
|
|
69
|
+
in the plan's decisions with that id. Any other form is a bad line.
|
|
70
|
+
|
|
71
|
+
## 6. Notify and end
|
|
72
|
+
|
|
73
|
+
When the status is not CONTINUE, call the `PushNotification` tool as your last action. Put the plan, the status line and the
|
|
74
|
+
next step in the message. After the call succeeds, print the line `PUSH-SENT`. The runner looks for that marker. Without it,
|
|
75
|
+
the runner sends the notification itself.
|
|
76
|
+
|
|
77
|
+
Then end the session.
|