@oneie/claude 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (263) hide show
  1. package/agents/abm-strategist.md +89 -0
  2. package/agents/ads-meta.md +97 -0
  3. package/agents/analyst.md +173 -0
  4. package/agents/architect.md +280 -0
  5. package/agents/brand-guardian.md +88 -0
  6. package/agents/brand-strategist.md +92 -0
  7. package/agents/campaign-content.md +90 -0
  8. package/agents/campaign-email.md +88 -0
  9. package/agents/campaign-sms.md +87 -0
  10. package/agents/campaign-social.md +87 -0
  11. package/agents/cco.md +99 -0
  12. package/agents/ceo.md +106 -0
  13. package/agents/chairman.md +120 -0
  14. package/agents/cmo.md +101 -0
  15. package/agents/community-greeter.md +89 -0
  16. package/agents/community-moderator.md +92 -0
  17. package/agents/compliance.md +92 -0
  18. package/agents/copywriter.md +100 -0
  19. package/agents/creative-strategist.md +95 -0
  20. package/agents/cro.md +98 -0
  21. package/agents/cto.md +267 -0
  22. package/agents/customer-interviewer.md +93 -0
  23. package/agents/customer-researcher.md +89 -0
  24. package/agents/customer-success-manager.md +90 -0
  25. package/agents/customer-trainer.md +90 -0
  26. package/agents/cxo.md +100 -0
  27. package/agents/demand-creator.md +89 -0
  28. package/agents/demo-mover.md +83 -0
  29. package/agents/demo-specialist.md +89 -0
  30. package/agents/demo-thai-family-law.md +87 -0
  31. package/agents/designer.md +112 -0
  32. package/agents/discovery-caller.md +98 -0
  33. package/agents/doctor.md +139 -0
  34. package/agents/educate-coach.md +100 -0
  35. package/agents/elevate-tutor.md +83 -0
  36. package/agents/email-lifecycle-marketer.md +91 -0
  37. package/agents/engage-specialist.md +99 -0
  38. package/agents/events-coordinator.md +90 -0
  39. package/agents/foundation-builder.md +94 -0
  40. package/agents/funnel-architect.md +89 -0
  41. package/agents/gift-creator.md +100 -0
  42. package/agents/google-ads.md +103 -0
  43. package/agents/guide.md +292 -0
  44. package/agents/helpdesk-dispatcher.md +88 -0
  45. package/agents/hook-specialist.md +91 -0
  46. package/agents/identify-optimizer.md +101 -0
  47. package/agents/implementer.md +305 -0
  48. package/agents/incident-commander.md +120 -0
  49. package/agents/insights-lead.md +93 -0
  50. package/agents/journey-runner.md +113 -0
  51. package/agents/linkedin-ads.md +123 -0
  52. package/agents/live-sales-chat.md +90 -0
  53. package/agents/market-researcher.md +88 -0
  54. package/agents/media-buyer.md +96 -0
  55. package/agents/movers-customer-researcher.md +95 -0
  56. package/agents/movers-foundation-builder.md +96 -0
  57. package/agents/movers-market-researcher.md +97 -0
  58. package/agents/movers-pricing-strategist.md +171 -0
  59. package/agents/nurture-architect.md +99 -0
  60. package/agents/offer-architect.md +92 -0
  61. package/agents/onboarder.md +222 -0
  62. package/agents/onboarding-specialist.md +92 -0
  63. package/agents/operations-dashboard.md +98 -0
  64. package/agents/perf-engineer.md +348 -0
  65. package/agents/playbook-writer.md +71 -0
  66. package/agents/plg-strategist.md +91 -0
  67. package/agents/positioning-architect.md +88 -0
  68. package/agents/press-officer.md +89 -0
  69. package/agents/pricing-strategist.md +94 -0
  70. package/agents/privacy-officer.md +92 -0
  71. package/agents/referral-manager.md +91 -0
  72. package/agents/refine-analyst.md +102 -0
  73. package/agents/release-manager.md +261 -0
  74. package/agents/renewals-upsell-rep.md +90 -0
  75. package/agents/review-engineer.md +327 -0
  76. package/agents/rewards-steward.md +82 -0
  77. package/agents/sales-call-coach.md +94 -0
  78. package/agents/sales-closer.md +98 -0
  79. package/agents/security-auditor.md +313 -0
  80. package/agents/sell-closer.md +101 -0
  81. package/agents/share-amplifier.md +99 -0
  82. package/agents/social-media-manager.md +92 -0
  83. package/agents/storyteller.md +250 -0
  84. package/agents/strategist.md +83 -0
  85. package/agents/strategy-aligner.md +94 -0
  86. package/agents/support-agent.md +90 -0
  87. package/agents/tagger.md +245 -0
  88. package/agents/tech-writer.md +216 -0
  89. package/agents/test-engineer.md +243 -0
  90. package/agents/tiktok-ads.md +105 -0
  91. package/agents/tracking-engineer.md +92 -0
  92. package/agents/upsell-strategist.md +101 -0
  93. package/agents/voice.md +85 -0
  94. package/agents/w4-tools.md +153 -0
  95. package/agents/w4-verify.md +20 -138
  96. package/agents/workflow-optimiser.md +84 -0
  97. package/commands/close.md +814 -160
  98. package/commands/create.md +2 -2
  99. package/commands/deploy.md +554 -175
  100. package/commands/do.md +119 -109
  101. package/commands/fast.md +67 -0
  102. package/commands/improve.md +2 -2
  103. package/commands/one.md +418 -0
  104. package/commands/see.md +1 -1
  105. package/commands/sync.md +1 -1
  106. package/commands/tasks.md +222 -0
  107. package/commands/vespio.md +110 -0
  108. package/commands/vespio.remote.md +227 -0
  109. package/hooks/hooks.json +25 -79
  110. package/hooks/lib/governor-escape-match.sh +88 -0
  111. package/hooks/lib/hook.sh +4 -13
  112. package/hooks/lib/signal.sh +9 -2
  113. package/hooks/scripts/branch-pin.sh +6 -0
  114. package/hooks/scripts/config-protect.sh +6 -0
  115. package/hooks/scripts/do-outcome-gate.sh +19 -2
  116. package/hooks/scripts/git-add-guard.sh +43 -2
  117. package/hooks/scripts/governor-escape.sh +96 -0
  118. package/hooks/scripts/load-guard.sh +127 -0
  119. package/hooks/scripts/post-edit-check.sh +36 -29
  120. package/hooks/scripts/session-start.sh +34 -80
  121. package/hooks/scripts/task-complete-verify.sh +46 -40
  122. package/package.json +1 -1
  123. package/rules/documentation.md +9 -0
  124. package/scripts/ad-copy-lint.sh +656 -0
  125. package/scripts/agentverse-audit.sh +256 -0
  126. package/scripts/asi-walk.sh +435 -0
  127. package/scripts/astro-build-cached.sh +143 -0
  128. package/scripts/blocks-manifest-cached.sh +100 -0
  129. package/scripts/blocks-manifest.mjs +497 -0
  130. package/scripts/blocks-ratchet.sh +116 -0
  131. package/scripts/blocks-render-probe.mjs +529 -0
  132. package/scripts/blocks-usage.mjs +334 -0
  133. package/scripts/chat-context-check.sh +89 -0
  134. package/scripts/close-metrics.sh +558 -0
  135. package/scripts/close-owner.sh +268 -0
  136. package/scripts/db-sync-lock-check.sh +116 -0
  137. package/scripts/deploy-dev.sh +35 -0
  138. package/scripts/deploy-emit.sh +298 -0
  139. package/scripts/deploy-gate-check.sh +128 -0
  140. package/scripts/deploy-ready.sh +78 -0
  141. package/scripts/deploy-record.sh +605 -0
  142. package/scripts/deploy.sh +1273 -0
  143. package/scripts/do-auto.sh +598 -48
  144. package/scripts/do-brief.sh +113 -0
  145. package/scripts/do-close.sh +1137 -0
  146. package/scripts/do-commit.sh +75 -0
  147. package/scripts/do-consumer-sweep.sh +18 -1
  148. package/scripts/do-cycle-shape-check.sh +160 -0
  149. package/scripts/do-decide.sh +476 -0
  150. package/scripts/do-derive-check.sh +436 -0
  151. package/scripts/do-fleet.sh +106 -28
  152. package/scripts/do-folder.sh +10 -1
  153. package/scripts/do-next.sh +106 -0
  154. package/scripts/do-orchestrate.sh +17 -5
  155. package/scripts/do-plan-json.mjs +201 -0
  156. package/scripts/do-plan-json.sh +8 -0
  157. package/scripts/do-preflight.sh +117 -0
  158. package/scripts/do-project.sh +157 -0
  159. package/scripts/do-prove-selftest.sh +108 -0
  160. package/scripts/do-prove.sh +295 -23
  161. package/scripts/do-rank.py +31 -1
  162. package/scripts/do-recon-cache.sh +7 -1
  163. package/scripts/do-recon-pack.sh +196 -0
  164. package/scripts/do-reconcile.sh +121 -4
  165. package/scripts/do-signal.sh +280 -23
  166. package/scripts/do-smoke.sh +18 -1
  167. package/scripts/do-test-gate.sh +80 -0
  168. package/scripts/do-tick.sh +102 -0
  169. package/scripts/do-tier.sh +6 -0
  170. package/scripts/do-triage.sh +182 -0
  171. package/scripts/do-ui-gate.sh +1 -1
  172. package/scripts/do-w4-gates.sh +451 -0
  173. package/scripts/do-walk.sh +12 -1
  174. package/scripts/env-sync.sh +173 -0
  175. package/scripts/factory-brief-check.sh +330 -0
  176. package/scripts/factory-check.sh +68 -14
  177. package/scripts/factory-close-check.sh +257 -0
  178. package/scripts/factory-emit.sh +211 -0
  179. package/scripts/factory-executor-check.mjs +353 -0
  180. package/scripts/factory-peak.sh +301 -0
  181. package/scripts/factory-repo.sh +118 -3
  182. package/scripts/factory-review-check.mjs +61 -0
  183. package/scripts/factory-ship.sh +61 -0
  184. package/scripts/factory-tasks-check.sh +18 -1
  185. package/scripts/factory-turn.sh +326 -0
  186. package/scripts/factory-walk.sh +396 -0
  187. package/scripts/factory-width.sh +57 -0
  188. package/scripts/fade-toxic.sh +4 -3
  189. package/scripts/fixtures/factory-brief-real.md +44 -0
  190. package/scripts/fixtures/triage-dupe.md +5 -0
  191. package/scripts/fleet-manifest.mjs +108 -0
  192. package/scripts/fleet-status.sh +110 -0
  193. package/scripts/full-suite-paths-check.sh +144 -0
  194. package/scripts/gate-reaper-check.sh +98 -0
  195. package/scripts/gate-reaper.sh +125 -0
  196. package/scripts/gate-run.sh +73 -0
  197. package/scripts/gc-content-check.sh +140 -0
  198. package/scripts/gen-dev-config.py +20 -0
  199. package/scripts/govern-bound-check.sh +60 -0
  200. package/scripts/govern-claims-check.sh +233 -0
  201. package/scripts/govern-mem-check.sh +290 -0
  202. package/scripts/governor-doors-check.sh +362 -0
  203. package/scripts/governor-escape-check.sh +171 -0
  204. package/scripts/health.sh +413 -0
  205. package/scripts/id-inventory.mjs +418 -0
  206. package/scripts/land.sh +551 -0
  207. package/scripts/lib/gc-finished.sh +77 -0
  208. package/scripts/lib/govern.sh +361 -0
  209. package/scripts/lib/govern.ts +756 -0
  210. package/scripts/lighthouse-run.sh +187 -0
  211. package/scripts/livekit-live-check.sh +61 -0
  212. package/scripts/livekit-ratchet.sh +46 -0
  213. package/scripts/load-guard-check.sh +49 -0
  214. package/scripts/machine-check.sh +102 -0
  215. package/scripts/machine-watch.sh +177 -0
  216. package/scripts/one-agents.mjs +415 -0
  217. package/scripts/one-resume.sh +78 -0
  218. package/scripts/orphan-baseline.json +182 -0
  219. package/scripts/orphan-modules.mjs +179 -0
  220. package/scripts/pr-body.sh +335 -0
  221. package/scripts/preview-fd-check.sh +289 -0
  222. package/scripts/promise-manifest.mjs +24 -1
  223. package/scripts/release.sh +322 -0
  224. package/scripts/roles-check.sh +946 -0
  225. package/scripts/sdk-build-cached.sh +64 -0
  226. package/scripts/signal-watch.sh +241 -0
  227. package/scripts/skills-publish.sh +94 -0
  228. package/scripts/speed-cache-check.sh +173 -0
  229. package/scripts/speed-check.mjs +907 -0
  230. package/scripts/speed-parity-check.sh +648 -0
  231. package/scripts/speed-waterfall-check.sh +355 -0
  232. package/scripts/substrate-env-parity.mjs +156 -0
  233. package/scripts/tasks-claim-race.mjs +108 -0
  234. package/scripts/tasks-loop.sh +185 -0
  235. package/scripts/test-cached.sh +255 -0
  236. package/scripts/test-full.sh +87 -0
  237. package/scripts/test-honesty.mjs +137 -0
  238. package/scripts/test-lanes.sh +166 -0
  239. package/scripts/test-speed.sh +94 -0
  240. package/scripts/triage-shape-check.sh +149 -0
  241. package/scripts/tsc-cached.sh +179 -0
  242. package/scripts/typedb-flake-check.sh +197 -0
  243. package/scripts/urls-lint.sh +15 -0
  244. package/scripts/verify-fast.sh +445 -0
  245. package/scripts/vespio-sync.sh +149 -0
  246. package/scripts/wf-check.mjs +104 -1
  247. package/scripts/worktree-preview.sh +879 -0
  248. package/scripts/worktree-up.sh +208 -0
  249. package/skills/livekit-agents/SKILL.md +285 -0
  250. package/skills/livekit-agents/references/freshness-rules.md +168 -0
  251. package/skills/shadcn/SKILL.md +1 -1
  252. package/skills/signal/SKILL.md +0 -1
  253. package/skills/voice/SKILL.md +94 -6
  254. package/skills/voice/corpus-check.sh +87 -0
  255. package/hooks/scripts/compact-hint.sh +0 -35
  256. package/hooks/scripts/gate-guard.sh +0 -83
  257. package/hooks/scripts/read-tracker.sh +0 -26
  258. package/hooks/scripts/session-end-verify.sh +0 -51
  259. package/hooks/scripts/stop-reflect.sh +0 -140
  260. package/hooks/scripts/sync-priority-todo.sh +0 -57
  261. package/hooks/scripts/sync-todo-docs.sh +0 -46
  262. package/hooks/scripts/tool-signal.sh +0 -48
  263. package/scripts/do-tasks-bridge.py +0 -366
@@ -0,0 +1,418 @@
1
+ # /one — the desk and the board
2
+
3
+ ```
4
+ ██████╗ ███╗ ██╗███████╗
5
+ ██╔═══██╗████╗ ██║██╔════╝
6
+ ██║ ██║██╔██╗ ██║█████╗ one tab · many fresh minds
7
+ ██║ ██║██║╚██╗██║██╔══╝ chat the CEO · she routes
8
+ ╚██████╔╝██║ ╚████║███████╗
9
+ ╚═════╝ ╚═╝ ╚═══╝╚══════╝
10
+ ```
11
+
12
+ One word for the whole company. Two modes, decided by whether you typed
13
+ anything after it.
14
+
15
+ | You type | You get |
16
+ |---|---|
17
+ | `/one` | **the board** — the standing fleet (§1 onward). Batch, opt-in, expensive. |
18
+ | `/one <anything>` | **the desk** — you talk to the CEO; the CEO routes to fresh subagents and joins the answers. Cheap, conversational, all day. |
19
+ | `/one @cto <anything>` | **direct** — skip the CEO, hand it straight to that agent. |
20
+
21
+ ---
22
+
23
+ # THE DESK — `/one <anything>`
24
+
25
+ ## Why it exists
26
+
27
+ The problem it solves is one sentence: **you keep opening new tabs to get a
28
+ clean context.** A new tab costs you the thread — the decision you made two
29
+ hours ago, the file you already ruled out, the thing you already tried.
30
+
31
+ A subagent already gives you the clean context. `Agent(subagent_type: <anything
32
+ but "fork">)` starts **fresh** — no inherited history, no accumulated noise.
33
+ That is exactly what a new window buys, without losing the thread. `"fork"` is
34
+ the opposite: it inherits everything, and is the wrong tool here.
35
+
36
+ So the desk inverts your habit. **One tab. Many fresh contexts.** The tab holds
37
+ the conversation; the fresh contexts do the work and hand back a paragraph.
38
+
39
+ ## What the main thread is allowed to hold
40
+
41
+ The desk only works if the tab stays light. The main thread holds:
42
+
43
+ - the CEO's framing (2–3 sentences per request)
44
+ - each agent's **returned summary**
45
+ - the decisions you and the CEO made
46
+
47
+ The main thread never holds file dumps, sweep output, test logs, or search
48
+ results. Those live and die inside the subagent. **If reading it would cost the
49
+ tab more than 200 lines, it belongs in a subagent** — that is the whole rule.
50
+
51
+ ## You are talking to the CEO
52
+
53
+ When `/one` carries an argument, the main session **is** the Chief Executive
54
+ (`one.ie/ai/agents/ceo/agent.md`). Not a router — an executive. Per that file:
55
+
56
+ **1. Form a view first.** 2–3 sentences: what is actually being asked, what the
57
+ business needs right now, what a good outcome looks like. Your actual opinion —
58
+ not a hedge, not the request read back.
59
+
60
+ **2. Then route.** By the CEO's own declared emits:
61
+
62
+ | Request is about | Route | Director |
63
+ |---|---|---|
64
+ | brand, demand, campaigns, copy, ads, SEO | `route:to-marketing` | `cmo` |
65
+ | pipeline, deals, pricing, demos, onboarding | `route:to-sales` | `cro` |
66
+ | support, churn, CSAT, success, privacy | `route:to-service` | `cxo` |
67
+ | community, moderation, events, referrals | `route:to-community` | `cco` |
68
+ | builds, workflows, skills, `/do`, anything code | `route:to-engineering` | `cto` |
69
+ | spans two or more domains | `route:escalate-chairman` | — never split-route |
70
+
71
+ **3. Own the framing.** Directors execute. You are accountable for whether the
72
+ right question was asked. A brief missing its persona, its KPI, or its domain
73
+ gets rejected with exactly what is missing — not guessed at.
74
+
75
+ ## Routing without a director
76
+
77
+ A director is worth a hop when the work needs **deciding which work to do**. It
78
+ is pure overhead when the owner is obvious. Read the request:
79
+
80
+ - **Obvious owner** → spawn the specialist directly. "rewrite the pricing
81
+ headline" is `copywriter`, not `cmo → copywriter`.
82
+ - **Needs a decision** → spawn the director, take its plan, then spawn what it
83
+ named. "our activation is flat, what do we do" is `cmo` first.
84
+ - **Independent work** → spawn them **in one message** so they run
85
+ concurrently. Two agents in one block is two agents at once; two blocks is
86
+ two agents in sequence.
87
+ - **Dependent work** → chain it through one agent with ordered phases. Two
88
+ agents building either end of the same seam will disagree, and the
89
+ disagreement surfaces at merge — the worst place to find it. (§0.5.)
90
+
91
+ ## The roster
92
+
93
+ 80 platform agents are spawnable by name. They are **generated**, not written
94
+ by hand:
95
+
96
+ ```bash
97
+ node .claude/scripts/one-agents.mjs --chart # the routing table: agent · tier · staked tags
98
+ node .claude/scripts/one-agents.mjs # regenerate into .claude/agents/
99
+ node .claude/scripts/one-agents.mjs --check # fail if the output drifted from source
100
+ ```
101
+
102
+ Source of truth is `one.ie/ai/agents/**/*.md` — the same files that run the org
103
+ chart on the platform. Edit the platform agent, re-run the generator. Never
104
+ hand-edit a file carrying the `GENERATED by .claude/scripts/one-agents.mjs`
105
+ marker; the regenerate sweep is keyed on that marker, which is also what keeps
106
+ it from touching the hand-written `w1`–`w4`.
107
+
108
+ **The roster is read at SESSION START.** Regenerating mid-session does not make
109
+ a new agent spawnable — restart first. A spawn that fails with *"Agent type 'x'
110
+ not found"* listing only the old roster is this, not a broken file.
111
+
112
+ The heads: `ceo` · `cmo` (22 marketing) · `cro` (sales) · `cxo` (service) ·
113
+ `cco` (community) · `cto` (engineering).
114
+
115
+ Engineering (10): `cto` heads `architect` · `review-engineer` ·
116
+ `test-engineer` · `security-auditor` · `perf-engineer` · `release-manager` ·
117
+ `incident-commander` · `tech-writer` · `workflow-optimiser`. All ten stake the
118
+ same two tags, so pick by **tagline**, not by tag.
119
+
120
+ For `/do` work specifically, keep routing to the harness agents — they are the
121
+ ones wired into the engine and carrying its contract: `w1-recon` · `w2-decide` ·
122
+ `w3-edit` · `w4-verify`, plus `Explore` for fan-out search.
123
+
124
+ ## What every spawned agent inherits — and does not
125
+
126
+ **A subagent inherits NO parent CLAUDE.md.** That is the price of the fresh
127
+ context, and it is why every generated agent has the locked substrate facts
128
+ inlined in its body: the 6 dimensions, the 6 verbs, bare-tags-only, structural
129
+ time, where code lives, which test lane it ran. Without that inline block the
130
+ same freshness that fixes your tab problem makes every agent violate the
131
+ schema.
132
+
133
+ It still inherits nothing about **this conversation**. So the prompt you hand
134
+ it must carry every fact it needs — the file path, the measurement, the
135
+ constraint, the decision already made. A prompt that says "continue the work" is
136
+ a prompt to an agent that has no idea what work.
137
+
138
+ ## Cost
139
+
140
+ The desk is cheap because the tab stays small; it is not free. A director hop is
141
+ Opus. Prefer:
142
+
143
+ 1. the specialist directly, over director → specialist
144
+ 2. one agent with ordered phases, over N agents on one seam
145
+ 3. `Explore` (read-only, returns conclusions) over a general agent that returns files
146
+
147
+ Bare `/one` — the board below — is the expensive gesture and stays explicit
148
+ opt-in. The desk is not.
149
+
150
+ ## Don't
151
+
152
+ - **Don't use `subagent_type: "fork"`** for a fresh context. Fork inherits
153
+ everything; it is the tab you were trying not to open.
154
+ - **Don't relay a file dump into the tab.** Relay the conclusion. The agent's
155
+ report is not shown to the operator — say what matters, in your words.
156
+ - **Don't spawn an agent that already ran.** Continue it with `SendMessage` and
157
+ it keeps its context; a new `Agent` call starts over.
158
+ - **Don't invent an agent name.** `--chart` is the list. A name not on it does
159
+ not exist.
160
+ - **Don't fabricate a pending agent's result.** It arrives as a notification.
161
+ If asked before it lands, say it is still running.
162
+
163
+ ---
164
+
165
+ # THE BOARD — bare `/one`
166
+
167
+ One word to launch the whole board. Every fleet probes production rather than
168
+ reading source, and all of them are synchronised by one shared measurement pack.
169
+
170
+ **Explicit opt-in.** This spawns many agents and costs real tokens. Never infer
171
+ it — it is the same gesture as `ultracode`. The desk above is not.
172
+
173
+ ---
174
+
175
+ ## 0 · RESUME FIRST — pick up where the last harness left off
176
+
177
+ **Any harness can continue this board.** A session that runs out of credits does
178
+ not lose its fleets: every Workflow run persists its script and a journal, and a
179
+ resume replays every unchanged agent from cache for free — only edited or new
180
+ agents actually run.
181
+
182
+ ```bash
183
+ # what was in flight, and how far each got
184
+ bash .claude/scripts/one-resume.sh # the board
185
+ bash .claude/scripts/one-resume.sh --deploy # the board, then land+ship what is ready
186
+ ```
187
+
188
+ Then, per fleet still worth continuing:
189
+
190
+ ```
191
+ Workflow({ scriptPath: "<script path from the board>", resumeFromRunId: "<runId>" })
192
+ ```
193
+
194
+ **Read `text/HANDOFF.md` before spawning anything.** It carries the fleet table,
195
+ the branches, the findings that change the design, and the queue of work that was
196
+ requested but never built. Re-launching a fleet whose work already landed is the
197
+ most expensive mistake available here.
198
+
199
+ Order, always: **resume → land → deploy → only then fan out.** Landing costs no
200
+ model tokens at all; fanning out costs the most.
201
+
202
+ ---
203
+
204
+ ## 0.5 · Chain, don't scatter
205
+
206
+ When several fleets touch one flow — sell → ads → sell-credits, with upsells
207
+ tracked along it — they are ONE chain, not N independent fleets. Fan out on
208
+ *independent* work; chain dependent work through a single fleet with ordered
209
+ phases, so a later stage reads the earlier stage's real output instead of
210
+ guessing at it. Two fleets building either end of the same seam will disagree,
211
+ and the disagreement surfaces at merge, which is the worst place to find it.
212
+
213
+ ---
214
+
215
+ ## 0 · Price the box BEFORE you fan out
216
+
217
+ The binding constraint is **memory, not cores**. A cycle costs ~2GB (vitest
218
+ driver + 4 forks + tsc + node). On a 10-core/24GB box, `cores - 2` would
219
+ authorise 8 concurrent worktrees — ~16GB of gates before editors, sessions and
220
+ the OS get a byte. `gate_headroom` prices it properly and only ever *lowers* the
221
+ count.
222
+
223
+ ```bash
224
+ bash .claude/scripts/fleet-status.sh # the board: box · slots · fleet · funnel
225
+ bash .claude/scripts/machine-check.sh --watch # live: load · swap DIRECTION · orphans
226
+ ```
227
+
228
+ `fleet-status.sh` costs nothing — no agents, no network. It prints how many
229
+ cycles the box can **afford right now**, which fleet docs exist and how many
230
+ `[NOT WIRED]` / `[NOT MEASURED]` items each still carries, and the four funnel
231
+ numbers that decide whether any of it matters. Run it before and after.
232
+
233
+ **Read swap direction, not the swapin counter** — swapins spike during recovery
234
+ too. Thrash is pages going *out* while free memory shrinks.
235
+
236
+ | Knob | Default | Raise when |
237
+ |---|---|---|
238
+ | `GOVERN_MAX_GATES` | 2 | never, on this box |
239
+ | `GOVERN_GB_PER_CYCLE` | 2 | your gates got lighter |
240
+ | `GOVERN_RESERVE_GB` | 2 | you want more headroom, not less |
241
+ | `VITEST_MAX_FORKS` | 4 | a deliberate full-throughput CI run |
242
+
243
+ **Editors are the other half of the bill.** Each worktree is ~120MB on disk and
244
+ its own tsserver in RAM — 3 worktrees measured at 2.3–3.0GB of language servers,
245
+ entirely outside the governor. `.vscode/settings.json` and `.cursorignore`
246
+ exclude `.do-worktrees`; Zed needs `file_scan_exclusions` in user config.
247
+
248
+ **Sweep before launching**, or you inherit the last run's ghosts:
249
+
250
+ ```bash
251
+ git worktree prune
252
+ git worktree list # anything finished? remove it
253
+ pkill -f 'esbuild|vite/node_modules' || true # orphans outlive their fleet
254
+ ```
255
+
256
+ ---
257
+
258
+ ## 1 · Re-measure — the pack goes stale
259
+
260
+ Nine fleets fed a wrong premise all reach wrong conclusions in unison. These
261
+ were true 2026-08-25; every one is a live probe, not a file read.
262
+
263
+ ```bash
264
+ DB=one.ie/web/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/e3267303*.sqlite
265
+ sqlite3 $DB "SELECT COUNT(*) FROM owners;" # 68
266
+ sqlite3 $DB "SELECT COUNT(*) FROM owners WHERE charges_enabled=1;" # 0
267
+ sqlite3 $DB "SELECT COUNT(*) FROM wallets WHERE sui_address!='';" # 0 <- THE WALL
268
+ sqlite3 $DB "SELECT source,COUNT(*),SUM(amount_credits) FROM credit_grants GROUP BY source;"
269
+
270
+ curl -s -X POST https://one.ie/api/storefront/checkout \
271
+ -H 'content-type: application/json' \
272
+ -d '{"workspace":"one","ppid":"price_jmujrzb8r7h9sy7c","rail":"card"}' | head -c 200
273
+ curl -s 'https://one.ie/api/pay/credits/quote?amountUsd=1' | grep -o '"chain":"SOL"[^}]*'
274
+ ```
275
+
276
+ **Known-stale in this file, fix before reusing:** engineering and finance are
277
+ NOT new departments — they already exist across five surfaces (`navigation.ts:4`,
278
+ `role-types.ts:37`, `urls/law.ts:62`, and live rooms). Only **design** and
279
+ **analytics** are new. And 29 agents fall into a `governance` sink because their
280
+ declared `domain:` is outside the union — reclassify those before adding more.
281
+
282
+ ---
283
+
284
+ ## 2 · Claim before you forage — no collisions
285
+
286
+ Two fleets independently built the same skill executor
287
+ (`execute-skill.ts` **and** `executor.ts`). That is duplicated *selection*, not a
288
+ file-write race — worktrees already prevent those. The fix already ships:
289
+ `tasks:claim` is an **evaporating lease**, `CLAIM_LEASE_TTL_MS = 45 min`
290
+ (`resolvers/tasks.ts:93`). A dead worker's claim expires; a mutex would deadlock.
291
+
292
+ ```
293
+ ant radio here
294
+ ─── ───── ────
295
+ deposit ───────────▶ transmit ────────▶ claim the region
296
+ read the trail ─────▶ carrier sense ──────▶ read claims first
297
+ evaporate ──────────▶ timeout ────────▶ 45-min lease TTL
298
+ alarm ───────────▶ jam ────────▶ warn the path
299
+ ```
300
+
301
+ For machine resources use `gate_lock` — `mkdir(2)` is atomic; a read-then-write
302
+ to D1 is not. **Exclusion for files and gates; stigmergy for task selection.**
303
+
304
+ ---
305
+
306
+ ## 3 · The fleet
307
+
308
+ ```
309
+ ┌── probe ──┐
310
+ │ ▼
311
+ [pack] ──▶ ┌─────────────────────────────────┐
312
+ │ security wallet keys │
313
+ │ skill analytics analyst │ ◀── same pack,
314
+ │ departments colony dev-env │ no conductor
315
+ └─────────────────────────────────┘
316
+
317
+
318
+ [ join → text/one.md ]
319
+ ```
320
+
321
+ | Fleet | Owns | Lands in |
322
+ |---|---|---|
323
+ | `security` | the gateway seam — anon spend, SOL rail | `text/auth-enforcement-todo.md` |
324
+ | `wallet` | the master ladder, paper that actually restores | `text/wallet-durability.md` |
325
+ | `keys` | `/w/keys`, devices, the adoption ceremony | `text/keys.md` |
326
+ | `skill-engine` | 87 bodies + one executor (dedupe first) | `text/skill-engine.md` |
327
+ | `analytics` | the 8-stage funnel, honest zeros | `text/journey-analytics.md` |
328
+ | `analyst` | reads every signal, fires workflows | `text/analyst.md` |
329
+ | `departments` | design + analytics only; drain `governance` | `text/departments.md` |
330
+ | `colony` | claim-lease selection | `text/colony.md` |
331
+ | `dev-env` | one passkey both hosts, redirects | `text/dev-environment.md` |
332
+
333
+ ---
334
+
335
+ ## 4 · The law
336
+
337
+ 1. **Probe before you read.** Every launch-blocking finding came from a probe.
338
+ Mint a real checkout. Read a D1 *count*. Probe an API *from where code runs*.
339
+ 2. **Synchronise by shared evidence, not orchestration.** One pack, verbatim, in
340
+ every prompt.
341
+ 3. **One fleet joins** — folds findings into `text/one.md`, which already says
342
+ *the specific doc wins, the spine reconciles*.
343
+ 4. **Default REFUTED; demand the quoted stopping line.** No line ⇒ not proven.
344
+ 5. **Two instances of one shape ⇒ fix the seam.**
345
+ 6. **Kill a fleet the moment its premise dies.**
346
+
347
+ Four prompt rules, each bought with a real mistake:
348
+
349
+ - **Never spend money to prove a point** — one audit billed ~$0.22 of DataForSEO.
350
+ - **Never simulate a run and report it as one.** Say so and STOP.
351
+ - **Give a "no change needed" exit**, or a fleet punches a hole in the payment
352
+ path to make a landing page prettier.
353
+ - **Name the forbidden sentence** for anything customer-facing.
354
+
355
+ **Index fix tasks by NAME, never positionally.** A `.filter(Boolean)` on scopes
356
+ shifted indices and handed each fix the wrong scope — both silently returned null
357
+ and the run reported "complete".
358
+
359
+ ---
360
+
361
+ ## 5 · Build and deploy — fast by construction
362
+
363
+ ```bash
364
+ DEV_SKIP_GATE=1 bash .claude/scripts/deploy-dev.sh # ~30s -> dev.one.ie
365
+ bash .claude/scripts/deploy-dev.sh # + fast lane
366
+ ./deploy # FULL gate -> one.ie
367
+ ```
368
+
369
+ Where the speed came from, measured:
370
+
371
+ | | before | after |
372
+ |---|---|---|
373
+ | `tsc --noEmit` | 60.0s | **8.7s** (`incremental` + `tsBuildInfoFile` + `skipLibCheck`) |
374
+ | dev deploy | — | 23s upload · 4s assets · 3s triggers |
375
+ | tests selected | 1,044 files | 35 pinned + `vitest related` |
376
+
377
+ The tests were never the bottleneck — a cold full typecheck on every pass was.
378
+
379
+ Two invariants the fast lane must keep: **an empty diff falls back to the FULL
380
+ suite** (never to a pass), and **the pins always run** — `vitest related` walks
381
+ the import graph, and config/parity/boundary gates import nothing from what they
382
+ guard. Take the FULL lane when the change touched `schema/`, `packages/sdk/`, or
383
+ auth — that is exactly where `related` misses.
384
+
385
+ `deploy-dev.sh` regenerates its config from the astro build output every run, so
386
+ it cannot drift from what production ships, and strips `triggers`/`crons` — the
387
+ dev worker shares production's D1 and KV, and the first deploy inherited six
388
+ prod schedules. **Dev observes prod data; it must never drive prod's clock.**
389
+
390
+ ---
391
+
392
+ ## 6 · Standing state — OPEN
393
+
394
+ A fix on main is not a fix in prod until the worker is redeployed.
395
+
396
+ | Open | Where | Whose call |
397
+ |---|---|---|
398
+ | `auth:"member"` enforced NOWHERE — gateway stamps trust on anon requests | `api/src/substrate-binding.ts:46` + `ask:276` | fleet |
399
+ | Anonymous DataForSEO spend | `seo.ts:73` | fleet |
400
+ | SOL advertised, cannot settle | `quote.ts:60-64`, `solana.ts:66` | fleet |
401
+ | 24 words import to a DIFFERENT, EMPTY address | `derive-multichain.ts` HKDF vs BIP-44 | fleet |
402
+ | Undecryptable vault envelope, globally mounted | `PasskeyUpgradePrompt.tsx:201` | fleet |
403
+ | Stripe in test mode in production | `wrangler.toml:110` | **operator** |
404
+ | Paper backup of the Sui deploy key | `~/sui-mainnet-deploy-key.txt` | **operator** |
405
+
406
+ **CLOSED this session:** the unauthenticated credit mint —
407
+ `neuterSelfBootstrapPayload` (`receiver-envelope.ts:207`) strips
408
+ parent/plan/credit/markup/cap/brand/agents from a self-bootstrap payload.
409
+
410
+ ---
411
+
412
+ ## Don't
413
+
414
+ - Don't launch while fleets are in flight. Land the board, don't widen it.
415
+ - Don't let a fleet deploy. That is the operator's call.
416
+ - Don't skip the join. Nine fleets that never reconcile are nine opinions.
417
+ - Don't run a raw `vitest` — it bypasses the governor and `hook:load-guard`
418
+ blocks it. Everything through `gate-run.sh`.
package/commands/see.md CHANGED
@@ -49,7 +49,7 @@ read — do not GET it.
49
49
  ### tasks
50
50
 
51
51
  1. `python3 .claude/scripts/do-rank.py` — the ranker reads `text/*-todo.md` directly and needs no dev server. Add `--tasks` for the tagged-signal view, `--json` for machine output, `--top N` to cap.
52
- - **The one exception to this file's no-side-effects rule.** The ranker refreshes a `text/task-paths.json` memo as it runs. It does **not** write `todo.md` — that is `hook:sync-priority-todo`, fired on Stop and SessionStart. No substrate write, no `mark()`/`warn()`.
52
+ - **The one exception to this file's no-side-effects rule.** The ranker refreshes a `text/task-paths.json` memo as it runs. It does **not** write `todo.md` — that is the hourly `fade-toxic.sh` launchd loop (since 2026-09-05 the only writer). No substrate write, no `mark()`/`warn()`.
53
53
  2. Filter by `$ARGUMENTS` if provided — tags or phase (e.g. `/see tasks build P0`, `/see tasks C1`)
54
54
  3. Report tasks sorted by effective priority (priority score + pheromone strength − resistance):
55
55
  - Name, id, priority formula (e.g. `90 = critical=30 + C1=40 + dev=20`)
package/commands/sync.md CHANGED
@@ -17,7 +17,7 @@ Reconcile substrate state — report the growth loops, fire the on-demand ones,
17
17
  | L6 know | channels cron `harden-tick` hourly (D1 strength≥10 → TypeDB hypotheses, via `rememberHypothesis`) | LIVE (cron only) | **no HTTP door** — `learning:know` is unregistered |
18
18
  | L7 frontier | read surface only — no detection job exists | READ-ONLY | `GET /api/frontiers` |
19
19
 
20
- **Not built (do not invoke, do not describe as live):** `GET /api/tick`, `POST /api/tasks/sync`, `src/engine/{doc-scan,task-parse,reusable-tasks}.ts`. The `sync-todo-docs.sh` hook still best-effort-POSTs `/api/tasks/sync` and silently no-ops known drift. If a tick aggregator is ever wanted, it's a `/do` cycle (thin web route composing `fade()` + `agents:evolve` + a harden receiver that must first be BUILT + frontiers read), not a doc edit.
20
+ **Not built (do not invoke, do not describe as live):** `GET /api/tick`, `POST /api/tasks/sync`, `src/engine/{doc-scan,task-parse,reusable-tasks}.ts`. The `sync-todo-docs.sh` hook that best-effort-POSTed `/api/tasks/sync` was removed 2026-09-05 (it only ever no-op'd). If a tick aggregator is ever wanted, it's a `/do` cycle (thin web route composing `fade()` + `agents:evolve` + a harden receiver that must first be BUILT + frontiers read), not a doc edit.
21
21
 
22
22
  ## Nouns
23
23
 
@@ -0,0 +1,222 @@
1
+ # /tasks
2
+
3
+ Take what someone wants and make it claimable. One pass: size it, say it in
4
+ human words, break it into the pieces its size implies, chain them so only the
5
+ first is ready, and hand each to the agent that answers for it.
6
+
7
+ ```
8
+ /tasks drain every untriaged row on the board
9
+ /tasks "<a sentence>" shape one captured thing
10
+ /tasks --dry show the writes, apply nothing
11
+ /tasks --rewrite <tid> re-say one existing row in human words
12
+ ```
13
+
14
+ **Nothing parses those.** This file is instructions to a model, not a CLI —
15
+ there is no `tasks.sh`, and the words above are shapes a reader types so the
16
+ model knows which leg to run. `--dry` means *pass `dryRun: true` to the
17
+ workflow*; `--rewrite <tid>` means *run the shape leg against one existing row
18
+ and skip the drain*. Where a flag IS parsed the authority is a script and this
19
+ file says so: `do-triage.sh` and `do-tier.sh` below both take real arguments and
20
+ both have a real `--self-test`.
21
+
22
+ Saying that plainly matters here more than usual. A declared interface with no
23
+ implementation is the defect this whole command exists to catch — see the
24
+ `tasks:bulk` note under **Don't**, which is advertised with a full schema and
25
+ answers `unknown_receiver`.
26
+
27
+ ---
28
+
29
+ ## The one rule
30
+
31
+ **A task is a Want.** Not a label, not a ticket, not a cycle number — the thing
32
+ someone wants that is not true yet, written so a stranger knows what changes
33
+ when it is done.
34
+
35
+ `schema/story.tql` makes this the one refusal it enforces: `story_has_want()`,
36
+ and its comment — *a story with no Want is a log*. A row that cannot state its
37
+ Want is not small, it is **unshaped**, and it goes to `shaping:` rather than to
38
+ an agent.
39
+
40
+ That is what "human sounding" means here, and it is not cosmetic. `lifecycle-human C0`
41
+ tells a puller nothing. *A wallet backed up twice loses its key* tells them what
42
+ is wrong, who it hurts and when they are finished.
43
+
44
+ ---
45
+
46
+ ## The pipeline
47
+
48
+ The workflow already exists — **`/tasks` does not reimplement it.**
49
+
50
+ ```
51
+ Workflow({ name: "triage", args: { dryRun: <bool>, tasks: [{title}] } })
52
+ ```
53
+
54
+ `.claude/workflows/triage.js`, four phases:
55
+
56
+ | phase | does | cost |
57
+ |---|---|---|
58
+ | `Untriaged` | `do-rank.py --board-check`, then rows whose notes lack `accept:` | haiku |
59
+ | `findPaths` | **`do-triage.sh` first — zero LLM.** A model names paths only if it comes back empty | bash, then haiku |
60
+ | `tier` | **`do-tier.sh` on the paths.** Never re-size in JS | bash |
61
+ | `reshape` | original words to `tasks:comment` **before** any rename; `accept:` into notes | haiku |
62
+
63
+ **That order is load-bearing.** The original sentence is preserved as a comment
64
+ before anything overwrites the title, because a rewrite that loses what the
65
+ person actually said is not a rewrite, it is a deletion.
66
+
67
+ ### What `/tasks` adds
68
+
69
+ `plannedWrites()` in `triage.js` today writes a comment and a note and **stops**
70
+ — it never renames, never makes a subtask, never assigns, never chains. The
71
+ workflow's own description says it renames; it does not. `/tasks` is that
72
+ missing half, and it runs only on rows the tier phase actually sized:
73
+
74
+ 5. **say** — `tasks:rename` to the Want, in human words
75
+ 6. **split** — `tasks:subtask` per piece, by tier (below)
76
+ 7. **chain** — `blockedBy` so exactly one sibling is ready
77
+ 8. **hand over** — `assignee` from the routing table (below)
78
+
79
+ A row that reaches step 5 unsized does not get steps 5–8. It gets
80
+ `shaping:` and waits for a person.
81
+
82
+ ---
83
+
84
+ ## Sizing decides the shape
85
+
86
+ `bash .claude/scripts/do-tier.sh --intent "<text>" <paths...>` is the authority.
87
+ Never guess a tier, and never let a model pick one.
88
+
89
+ | tier | subtasks | chained | who |
90
+ |---|---|---|---|
91
+ | `PATCH` | none — it is one piece | — | `implementer` |
92
+ | `FIX` | 2–3, only if they are separately checkable | yes | `implementer`, refuted by `review-engineer` |
93
+ | `FEATURE` | one per surface it touches | yes | `architect` writes the spec **first**, then `implementer` |
94
+ | `SCHEMA` | one per migration + one to prove it | yes | `architect`, W2 on Fable |
95
+ | `UNSIZED` | **none** | — | nobody — it goes to `shaping:` |
96
+
97
+ ### UNSIZED is a state, not a default
98
+
99
+ `do-tier.sh` exits **3** and returns `{"tier":"UNSIZED","spine":"recon"}` when it
100
+ is given no paths, and its own header says why:
101
+
102
+ > *Absence of recon must not read as simplicity.*
103
+
104
+ A new task is a sentence with no diff, so **every** fresh capture is UNSIZED
105
+ until recon finds files. Two real mis-sizings are on record from treating that as
106
+ PATCH (`text/learnings.md:485`, `text/remote-suspend-todo.md:5`). So the pipeline
107
+ is **capture → recon → size → agent**, never capture → size → agent. `/tasks`
108
+ reports UNSIZED as its own outcome and files nothing under it.
109
+
110
+ ---
111
+
112
+ ## Who answers for it
113
+
114
+ Routing is by what the work *is*, not by who is free. Category comes from the
115
+ paths `do-triage.sh` found.
116
+
117
+ | paths touch | agent |
118
+ |---|---|
119
+ | `schema/`, a receiver, an authority walk | `architect` — spec before code |
120
+ | a component, a route, a page | `implementer` |
121
+ | auth, keys, money, a bounded door | `security-auditor` |
122
+ | a gate, a ratchet, a proof | `test-engineer` |
123
+ | `text/` only | `tech-writer` |
124
+ | a deploy, a release, `.release/` | `release-manager` |
125
+ | a measurement, a budget, a clock | `perf-engineer` |
126
+ | prod is down | `incident-commander` |
127
+ | nothing matches | `cto` — ranks it into a rung and re-routes |
128
+
129
+ **Every row leaves `/tasks` with an assignee.** An unassigned row is the one that
130
+ sits — 219 of 452 rows on this board sat at priority 0 with empty notes and no
131
+ owner, and none of them moved. Assigning is not bureaucracy; it is the difference
132
+ between a row and a queue.
133
+
134
+ `agent` never means *autonomous*: `tool → skill → agent` is the autonomy ladder
135
+ (root `CLAUDE.md`). A money-moving or authority-changing row gets `human` in its
136
+ chain regardless of tier.
137
+
138
+ ---
139
+
140
+ ## Chaining: one ready sibling, not ten
141
+
142
+ `tasks:subtask` writes the row, its notes, its containment edge **and** its
143
+ `blockedBy` in one call — that is why it exists and why two calls are wrong. Its
144
+ own contract says it: *between the two calls the child sits on the board
145
+ claimable with an empty body and no ordering, and the factory will take it.*
146
+
147
+ So: subtask N is `blockedBy` subtask N−1, unless they are genuinely independent.
148
+ Ten unchained siblings is ten agents claiming the same ground.
149
+
150
+ Where a real chain already exists, mirror it rather than inventing one —
151
+ `lifecycle-human` is `C0 alone → C1 decides → C2 → C5/C6/C7`, with C3, C4 and C8
152
+ parallel throughout. That shape came from the plan, not from a rule.
153
+
154
+ ---
155
+
156
+ ## Story · promise · contract — the vocabulary, and what is not wired
157
+
158
+ The substrate already models this. Read it before inventing a fourth noun:
159
+
160
+ | word | is | where |
161
+ |---|---|---|
162
+ | **task** | a Want — what is not true yet | `story_tasks($origin)` |
163
+ | **story** | an origin plus its beats: world · cast · knock · want · way · turn · lesson | `story_members`, `story_missing` |
164
+ | **promise** | the frozen oath: terms plus exactly one checkable proof | `story_promise($origin)`, `text/promise.md` |
165
+ | **contract** | who may admit work here, and what facts are still missing | `contract-admissible`, `missing-facts` |
166
+
167
+ The arc is `promise → progress → payoff`, read off the promise rung's status
168
+ (`story_arc`). Tasks are the Wants between them; `story_next($origin)` picks the
169
+ next one the ant-colony way — strongest net trail (`strength − resistance`),
170
+ never toxic — and `story_unexplored` is what the colony explores when there is no
171
+ trail yet. Priority does not appear anywhere in that decision.
172
+
173
+ **None of it is wired, and `/tasks` must not pretend otherwise.** Measured
174
+ 2026-09-12:
175
+
176
+ - `schema/story.tql` has **no migration** and nothing loads it. Its own header
177
+ says blocks 3–5 are *NOT YET VALIDATED: no TypeDB was reachable from the
178
+ session that wrote them* — 35 functions, unchecked.
179
+ - Its only consumer is a **prompt**: `.claude/agents/storyteller.md`.
180
+ - The SDK registry carries four story receivers — `story:chain`, `story:demo`,
181
+ `story:event`, `story:view`. **Not one mints an origin or binds a task to a
182
+ story.**
183
+ - `story_tasks` matches `has tag $g; $g == $origin` — the binding is a **bare
184
+ tag**. So a renamed row keeps its story only if it still carries that tag, and
185
+ today no row carries one because nothing writes one.
186
+
187
+ So `/tasks` uses the vocabulary and files rows a story could later adopt. It does
188
+ **not** call a story function, and it does not claim a story exists. Wiring it
189
+ means: a migration, a receiver that mints an origin, and the 35 functions
190
+ validated against a reachable TypeDB — in that order, as its own plan.
191
+
192
+ ---
193
+
194
+ ## Don't
195
+
196
+ - **Don't set priority.** `triage.js` refuses to, on purpose. The board ranks by
197
+ learned weight where it has evidence; an authored number competes with a
198
+ measurement and usually wins for the wrong reason. This board had 219 rows at
199
+ priority 0 including *the ladder cannot be climbed* and *tasks:comment silently
200
+ truncates*, and a panel layout tweak at 1.00.
201
+ - **Don't rename before the original text is a comment.** `tasks:comment`
202
+ truncates at 4,000 bytes and returns `ok:true`, so a long capture must be split
203
+ and read back, not trusted.
204
+ - **Don't clear notes by omission.** `tasks:notes` with an absent `notes` key is
205
+ a silent DELETE returning `{ok:true, notes:null}`. Read-modify-write, always,
206
+ with the full body.
207
+ - **Don't reach for `tasks:bulk`.** It is advertised by the MCP server with a
208
+ full schema and answers `unknown_receiver` in production. One call per row.
209
+ - **Don't add a second sizing path or a second triage door.** `do-triage.sh` and
210
+ `do-tier.sh` are the two, and both have `--self-test`.
211
+ - **Don't size from a title.** `do-tier.sh` sizes a **diff**. "Add a null check"
212
+ and "add a settings page" share a verb.
213
+
214
+ ---
215
+
216
+ ## See also
217
+
218
+ - `.claude/workflows/triage.js` — the pipeline this command drives
219
+ - `.claude/scripts/do-triage.sh` · `do-tier.sh` — the two authorities, both `--self-test`
220
+ - `text/board-review-2026-09-12.md` — where the defects quoted above were measured
221
+ - `text/story-framework.md` · `schema/story.tql` — the vocabulary, unwired
222
+ - `.claude/commands/do.md` — what claims a shaped task and builds it