crewforth 0.0.1 → 3.0.0-rc.1

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 (168) hide show
  1. package/CHANGELOG.md +3784 -0
  2. package/LICENSE +21 -0
  3. package/README.md +37 -7
  4. package/VERSION +1 -0
  5. package/adopt.sh +1670 -0
  6. package/bin/cli.js +497 -0
  7. package/kit/AGENT_TEMPLATE.md +92 -0
  8. package/kit/CLAUDE.md +228 -0
  9. package/kit/README.md +107 -0
  10. package/kit/agents/crew-backend-expert.md +95 -0
  11. package/kit/agents/crew-commit-agent.md +96 -0
  12. package/kit/agents/crew-database-expert.md +84 -0
  13. package/kit/agents/crew-devops-expert.md +82 -0
  14. package/kit/agents/crew-frontend-expert.md +85 -0
  15. package/kit/agents/crew-performance-expert.md +78 -0
  16. package/kit/agents/crew-planner.md +60 -0
  17. package/kit/agents/crew-privacy-agent.md +71 -0
  18. package/kit/agents/crew-review-agent.md +95 -0
  19. package/kit/agents/crew-security-expert.md +73 -0
  20. package/kit/agents/crew-session-manager.md +77 -0
  21. package/kit/agents/crew-test-expert.md +64 -0
  22. package/kit/eval/doctor.sh +465 -0
  23. package/kit/eval/gate-report.sh +137 -0
  24. package/kit/eval/golden-holdout.txt +53 -0
  25. package/kit/eval/golden-routing.txt +199 -0
  26. package/kit/eval/lib/crew-env.sh +14 -0
  27. package/kit/eval/lib/settings-json.awk +154 -0
  28. package/kit/eval/lib/star.sh +70 -0
  29. package/kit/eval/parser-conformance.sh +612 -0
  30. package/kit/eval/preflight.sh +186 -0
  31. package/kit/eval/routing-eval.sh +209 -0
  32. package/kit/eval/scan-skill.sh +162 -0
  33. package/kit/eval/smoke-test.sh +6693 -0
  34. package/kit/eval/update-guard.sh +81 -0
  35. package/kit/eval/utilization.sh +130 -0
  36. package/kit/hooks/board-sync.sh +106 -0
  37. package/kit/hooks/board.sh +962 -0
  38. package/kit/hooks/commit-msg +49 -0
  39. package/kit/hooks/context-usage.sh +353 -0
  40. package/kit/hooks/floor-blocklist.txt +124 -0
  41. package/kit/hooks/guard-bash.sh +1431 -0
  42. package/kit/hooks/guard-commit-scan.sh +511 -0
  43. package/kit/hooks/guard-write.sh +513 -0
  44. package/kit/hooks/pre-commit +577 -0
  45. package/kit/hooks/route-hint.sh +185 -0
  46. package/kit/hooks/secret-blocklist.txt +82 -0
  47. package/kit/hooks/session-guard.sh +149 -0
  48. package/kit/hooks/session-rehydrate.sh +41 -0
  49. package/kit/hooks/session-stats.sh +252 -0
  50. package/kit/hooks/session-update-check.sh +236 -0
  51. package/kit/hooks/skill-trust.sh +150 -0
  52. package/kit/hooks/trace-blocklist.txt +53 -0
  53. package/kit/settings.json +132 -0
  54. package/kit/skills/a11y/SKILL.md +44 -0
  55. package/kit/skills/adr/SKILL.md +74 -0
  56. package/kit/skills/api-design/SKILL.md +50 -0
  57. package/kit/skills/automode-policy/SKILL.md +91 -0
  58. package/kit/skills/automode-policy/references/policy.json +13 -0
  59. package/kit/skills/automode-policy/scripts/apply.sh +84 -0
  60. package/kit/skills/automode-policy/scripts/check.sh +102 -0
  61. package/kit/skills/backend-architecture/SKILL.md +103 -0
  62. package/kit/skills/brainstorm/SKILL.md +47 -0
  63. package/kit/skills/ci-pipeline/SKILL.md +38 -0
  64. package/kit/skills/commit-message/SKILL.md +82 -0
  65. package/kit/skills/commit-message/references/examples.md +8 -0
  66. package/kit/skills/confidence-check/SKILL.md +86 -0
  67. package/kit/skills/crew-board/SKILL.md +55 -0
  68. package/kit/skills/crew-brainstorm/SKILL.md +19 -0
  69. package/kit/skills/crew-code-review/SKILL.md +151 -0
  70. package/kit/skills/crew-code-review/references/history-search.md +19 -0
  71. package/kit/skills/crew-code-review/references/panel-mode.md +32 -0
  72. package/kit/skills/crew-code-review/references/receiving.md +23 -0
  73. package/kit/skills/crew-doctor/SKILL.md +36 -0
  74. package/kit/skills/crew-gates/SKILL.md +25 -0
  75. package/kit/skills/crew-handoff/SKILL.md +14 -0
  76. package/kit/skills/crew-plan/SKILL.md +18 -0
  77. package/kit/skills/crew-review/SKILL.md +23 -0
  78. package/kit/skills/crew-ship/SKILL.md +19 -0
  79. package/kit/skills/crew-skill/SKILL.md +61 -0
  80. package/kit/skills/crew-studio/SKILL.md +129 -0
  81. package/kit/skills/crew-update/SKILL.md +43 -0
  82. package/kit/skills/db-migration/SKILL.md +120 -0
  83. package/kit/skills/db-migration/references/backup-restore.md +33 -0
  84. package/kit/skills/db-migration/references/raw-sql.md +30 -0
  85. package/kit/skills/db-migration/references/tool-matrix.md +35 -0
  86. package/kit/skills/dependency-audit/SKILL.md +61 -0
  87. package/kit/skills/dependency-upgrade/SKILL.md +82 -0
  88. package/kit/skills/deploy/SKILL.md +100 -0
  89. package/kit/skills/deploy/references/proxy-ssl.md +56 -0
  90. package/kit/skills/deploy/references/rollback.md +18 -0
  91. package/kit/skills/deploy/references/scripts.md +9 -0
  92. package/kit/skills/deploy/references/topology-a.md +128 -0
  93. package/kit/skills/deploy/references/topology-b.md +44 -0
  94. package/kit/skills/docs-writer/SKILL.md +53 -0
  95. package/kit/skills/docs-writer/references/coauthoring.md +34 -0
  96. package/kit/skills/eval-grader/SKILL.md +75 -0
  97. package/kit/skills/eval-grader/references/method.md +51 -0
  98. package/kit/skills/frontend/SKILL.md +56 -0
  99. package/kit/skills/frontend/references/verify-contract.md +41 -0
  100. package/kit/skills/frontend-design/SKILL.md +71 -0
  101. package/kit/skills/frontend-design/references/design-review.md +34 -0
  102. package/kit/skills/frontend-rn-expo/SKILL.md +25 -0
  103. package/kit/skills/handoff/SKILL.md +71 -0
  104. package/kit/skills/handoff/references/cold-reader.md +51 -0
  105. package/kit/skills/i18n-integrity/SKILL.md +31 -0
  106. package/kit/skills/incident-runbook/SKILL.md +40 -0
  107. package/kit/skills/incident-runbook/references/postmortem.md +16 -0
  108. package/kit/skills/iterate/SKILL.md +40 -0
  109. package/kit/skills/mcp-builder/SKILL.md +54 -0
  110. package/kit/skills/mcp-builder/references/building.md +71 -0
  111. package/kit/skills/observability/SKILL.md +50 -0
  112. package/kit/skills/performance/SKILL.md +38 -0
  113. package/kit/skills/performance/references/bottlenecks.md +10 -0
  114. package/kit/skills/privacy-compliance/SKILL.md +75 -0
  115. package/kit/skills/red-team/SKILL.md +48 -0
  116. package/kit/skills/reflect/SKILL.md +57 -0
  117. package/kit/skills/release/SKILL.md +44 -0
  118. package/kit/skills/security-scan/SKILL.md +99 -0
  119. package/kit/skills/security-scan/references/ai-agents.md +107 -0
  120. package/kit/skills/security-scan/references/fronts.md +99 -0
  121. package/kit/skills/security-scan/references/prompting.md +23 -0
  122. package/kit/skills/security-scan/references/reporting.md +75 -0
  123. package/kit/skills/security-scan/references/verify.md +131 -0
  124. package/kit/skills/sonarqube-check/SKILL.md +108 -0
  125. package/kit/skills/sonarqube-check/references/local-engines.md +32 -0
  126. package/kit/skills/sonarqube-check/references/stand-up-server.md +25 -0
  127. package/kit/skills/spec-planning/SKILL.md +92 -0
  128. package/kit/skills/systematic-debugging/SKILL.md +57 -0
  129. package/kit/skills/systematic-debugging/references/techniques.md +44 -0
  130. package/kit/skills/teamboard/SKILL.md +88 -0
  131. package/kit/skills/teamboard/references/setup.md +37 -0
  132. package/kit/skills/testing/SKILL.md +49 -0
  133. package/kit/skills/testing/references/flaky-triage.md +51 -0
  134. package/kit/skills/threat-model/SKILL.md +57 -0
  135. package/kit/skills/threat-model/references/interview.md +51 -0
  136. package/kit/skills/threat-model/references/schema.md +42 -0
  137. package/kit/skills/token-budget/SKILL.md +51 -0
  138. package/kit/skills/trace-scan/SKILL.md +43 -0
  139. package/kit/skills/worktree/SKILL.md +40 -0
  140. package/kit/studio/README.md +266 -0
  141. package/kit/studio/ensure-node.sh +471 -0
  142. package/kit/studio/package.json +14 -0
  143. package/kit/studio/server/hooks/studio-gate.sh +169 -0
  144. package/kit/studio/server/index.js +902 -0
  145. package/kit/studio/server/lib/crew-env.js +11 -0
  146. package/kit/studio/server/lib/fleet.js +146 -0
  147. package/kit/studio/server/lib/graph.js +533 -0
  148. package/kit/studio/server/lib/instance.js +135 -0
  149. package/kit/studio/server/lib/kit-telemetry.js +182 -0
  150. package/kit/studio/server/lib/kit.js +158 -0
  151. package/kit/studio/server/lib/palette.js +118 -0
  152. package/kit/studio/server/lib/peers.js +72 -0
  153. package/kit/studio/server/lib/permissions.js +150 -0
  154. package/kit/studio/server/lib/projects.js +294 -0
  155. package/kit/studio/server/lib/roster.js +191 -0
  156. package/kit/studio/server/lib/session.js +309 -0
  157. package/kit/studio/server/lib/terminal.js +91 -0
  158. package/kit/studio/server/lib/transcript.js +100 -0
  159. package/kit/studio/web/app.js +1098 -0
  160. package/kit/studio/web/canvas.js +1179 -0
  161. package/kit/studio/web/chat.js +543 -0
  162. package/kit/studio/web/index.html +86 -0
  163. package/kit/studio/web/md.js +110 -0
  164. package/kit/studio/web/storage-migrate.js +23 -0
  165. package/kit/studio/web/style.css +1453 -0
  166. package/package.json +46 -8
  167. package/start.sh +748 -0
  168. package/bin/crewforth.js +0 -10
@@ -0,0 +1,92 @@
1
+ ---
2
+ name: spec-planning
3
+ description: |
4
+ Spec-first planning: task breakdown, measurable acceptance criteria, dependency order, risk priority.
5
+ crew-planner applies it; the plan goes to docs/PLAN.md.
6
+ Use when the scope is unclear or the work spans more than one change.
7
+ ---
8
+
9
+ # Spec-First Planning
10
+
11
+ <!-- routing-eval reads the next line; why it sits in the body: AGENT_TEMPLATE.md -->
12
+ Trigger phrases: "plan", "spec", "task breakdown", "acceptance criteria", "roadmap", "how do we split this"
13
+
14
+ Before writing code: what will be done, how it counts as "done", and in what order to proceed become clear.
15
+
16
+ ## Steps
17
+ 1. **Purpose & scope:** the problem being solved in a single sentence; also write the out-of-scope explicitly (prevent scope creep).
18
+ 2. **Split into vertical slices:** the smallest end-to-end working pieces (not horizontal layers). Each slice delivers value on its own.
19
+ 3. **A contract for every task:** input · output · **measurable acceptance criterion** (testable) · estimated risk.
20
+ 4. **Dependency graph:** which task waits on what; no cycles. **Bring the riskiest/most-unknown to the front** (fail-fast).
21
+ 5. **Uncertainties:** assumption list + open questions; do not fill ambiguous spots with a guess, ask with explicit options.
22
+
23
+ ## Output (docs/PLAN.md)
24
+ ```
25
+ # <Feature> — Plan
26
+ ## Acceptance criteria
27
+ - [ ] AC-1: <measurable outcome>
28
+ - [ ] AC-2: <measurable outcome>
29
+ ## Tasks (order)
30
+ 1. <task> — satisfies: AC-1 — dependency: <none/#n> — risk: <low/medium/high>
31
+ ## Assumptions / Open questions
32
+ - ...
33
+ ```
34
+
35
+ **Every criterion carries a stable id, and every task names the ids it satisfies.** The id is what makes the plan
36
+ checkable later: "AC-2 is only partly built" can be said, argued about and tracked; "the second checkbox" cannot,
37
+ and renumbering a list silently re-points every reference to it. Never reuse or renumber an id — a dropped
38
+ criterion keeps its id with a strike-through and a one-line reason. A criterion no task satisfies, and a task that
39
+ satisfies no criterion, are both findings before a line of code is written.
40
+
41
+ ## Mark what you do not know — do not fill it in
42
+ Where a requirement admits more than one reading, write the marker **`[NEEDS CLARIFICATION: <the question>]`** at
43
+ that exact spot in the plan. Do not resolve it with the likeliest interpretation and move on.
44
+
45
+ This is the difference between a discipline and a hope. "Stop and ask when unsure" (§1) depends on noticing the
46
+ uncertainty in the moment; a marker survives into the artifact, where the user, a reviewer and a later session
47
+ can all see it. A plausible assumption silently written into a spec is indistinguishable from a decision, and
48
+ that is exactly how the wrong feature gets built correctly.
49
+
50
+ Rules that keep it honest:
51
+ - The marker carries the **question**, not the label. `[NEEDS CLARIFICATION: does an expired invite count as
52
+ used, or can it be re-sent?]` is actionable; `[NEEDS CLARIFICATION: invites]` is noise.
53
+ - A plan may ship with markers — that is the point. It may **not** ship with a marker inside an acceptance
54
+ criterion: a criterion nobody can evaluate is not a criterion.
55
+ - Resolve by asking, never by choosing. When the user answers, replace the marker with the answer *and* record
56
+ which reading was rejected — the alternative is what a future reader needs.
57
+ - Zero markers on a genuinely ambiguous brief is a smell, not a win.
58
+
59
+ ## Converge — before the work is called done, hold the code up against the plan
60
+
61
+ Tests prove the code does what the tests say. Nothing so far proves it does what the PLAN said: a criterion can be
62
+ quietly half-built with every test green, and code nobody asked for can ride along unremarked. So when a plan
63
+ exists, closing the work includes one pass that reads each criterion against the code as it now stands.
64
+
65
+ Bound the pass to what the plan names — the criteria, the tasks, and the files and components they point at. Do not
66
+ widen the audit into the rest of the codebase. For each `AC-n`, look at the code in that scope and record a finding
67
+ **only where there is a gap**, classified as exactly one of:
68
+
69
+ | Gap | Means |
70
+ |---|---|
71
+ | **missing** | nothing in the code implements the criterion |
72
+ | **partial** | something does, but not all of what the criterion states |
73
+ | **contradicts** | the code does something that conflicts with the criterion or a plan decision |
74
+ | **unrequested** | the code contains work no criterion or task called for |
75
+
76
+ `unrequested` is the one that is easy to skip and should not be: it is scope creep made visible (principle 3,
77
+ "surgical change"). It is surfaced, never deleted by this pass — the user decides whether it stays, and if it
78
+ does, it gets a criterion.
79
+
80
+ Report it as a table — `AC-n | gap | evidence (file/area) | remaining work` — then either:
81
+ - **Converged:** zero findings. Say so in one line, with how many criteria were checked.
82
+ - **Not converged:** append each remaining item to the plan as a task that names its `AC-n`, and go back to
83
+ producing. Repeat the pass after that work, until it converges or the user accepts a named gap explicitly.
84
+
85
+ This is model discipline, not a gate: no exit code can judge "partially built". What makes it hold is the table —
86
+ a pass that produced no table did not run.
87
+
88
+ ## DoD (this skill's contribution)
89
+ - Every task's "done" is testable; ordering and dependencies are visible; the riskiest work has been brought to the front.
90
+ - Every unresolved ambiguity carries a `[NEEDS CLARIFICATION: …]` marker; no acceptance criterion contains one.
91
+ - Every criterion has a stable `AC-n` id and at least one task that satisfies it; at close, a converge pass
92
+ has run and either reported **Converged** or left its remaining items in the plan as tasks.
@@ -0,0 +1,57 @@
1
+ ---
2
+ name: systematic-debugging
3
+ description: |
4
+ Root-cause a bug before touching a fix: reproduce, isolate, form and test a hypothesis, confirm the cause,
5
+ then fix and verify. Stops guess-driven patching. For persistent, intermittent, or "already tried a few things" bugs.
6
+ ---
7
+
8
+ # Systematic Debugging
9
+
10
+ <!-- routing-eval reads the next line; why it sits in the body: AGENT_TEMPLATE.md -->
11
+ Trigger phrases: "debug", "root cause", "why is this failing", "intermittent bug", "can't reproduce", "is broken", "crashes"
12
+
13
+ One rule holds the whole skill together: **no fix without a confirmed root cause.** A patch that makes the symptom
14
+ disappear without a proven cause is not a fix — it's a coin flip that hides the bug until it returns somewhere worse.
15
+ This skill is the discipline that turns "try things until it works" into "understand, then change one thing."
16
+
17
+ > **Crewforth adaptation (local, .claude/):** Distinct from `iterate` (a self-correction loop over a *task*) and `reflect`
18
+ > (meta-review of an approach) — this skill is for a *defect*. §4 Prohibitions apply; a fix still goes through the
19
+ > project's review/test gates. Don't disable a test or a gate to make a symptom pass (that is masking, not fixing).
20
+
21
+ ## The loop (do them in order — skipping a step is why bugs come back)
22
+ 1. **Reproduce** — a reliable, minimal repro. Can't reproduce → that IS the first problem; see `references/techniques.md` (intermittent/heisenbug).
23
+ 2. **Isolate** — shrink the surface until the failure is in the smallest possible slice (bisect commits, halve the input, disable half the system).
24
+ 3. **Hypothesize** — state ONE falsifiable cause: "X fails because Y." Write it down. A vague hunch is not a hypothesis.
25
+ 4. **Test the hypothesis** — the cheapest observation that would *disprove* it (a log, a breakpoint, a probe). If it survives, you have the cause; if not, back to 3.
26
+ 5. **Confirm the root cause** — you can explain the full chain symptom←…←cause, and you can turn the bug on and off by touching the cause.
27
+ 6. **Fix** — the smallest change at the cause (not the symptom). Consider what else shares that cause.
28
+ 7. **Verify** — the original repro now passes, a regression test locks it, and nothing nearby broke.
29
+
30
+ ## Checklist
31
+ - [ ] Reliable repro captured (exact steps/input/env)
32
+ - [ ] Failure isolated to the smallest slice
33
+ - [ ] One falsifiable hypothesis written down
34
+ - [ ] Hypothesis tested by observation (not by applying a fix and seeing)
35
+ - [ ] Root cause confirmed (can toggle the bug via the cause; full chain explained)
36
+ - [ ] Fix at the cause + regression test added
37
+ - [ ] Original repro passes; no new failures
38
+
39
+ ## Anti-patterns (each is guess-driven patching wearing a disguise)
40
+ - **Shotgun debugging** — changing several things at once; now you can't tell what mattered. One change at a time.
41
+ - **Symptom patching** — a `try/catch`, a null-guard, a retry that swallows the failure without explaining it.
42
+ - **"It works now"** without knowing *why* it broke — the bug is dormant, not dead.
43
+ - **Blaming the environment/flake** before isolating — sometimes true, but only *after* step 2, never as the first move.
44
+ - **Deleting/skipping the failing test** to go green — that is masking; the gate exists to catch exactly this.
45
+
46
+ ---
47
+
48
+ ## Techniques by symptom
49
+ Bisecting (git + input + system), instrumentation vs. debugger, intermittent/heisenbugs (timing, state, ordering,
50
+ resource), the hypothesis log, and when to stop and ask for a second pair of eyes: **`references/techniques.md`**.
51
+
52
+ ## Invariant rules
53
+ 1. **No fix without a confirmed root cause** — the one rule; everything else serves it.
54
+ 2. **One change at a time** — isolate cause and effect; never shotgun.
55
+ 3. **Fix the cause, not the symptom** — a guard that hides the failure is not a fix.
56
+ 4. **Lock it with a regression test** — the repro becomes a test so it can't silently return.
57
+ 5. **Never mask to go green** — don't disable a test/gate/assertion to make the symptom pass.
@@ -0,0 +1,44 @@
1
+ # Debugging techniques by symptom
2
+
3
+ Loaded on demand — the SKILL.md loop is the method; this is the toolbox for a specific kind of bug.
4
+
5
+ ## Isolation: how to shrink the surface (step 2)
6
+
7
+ - **git bisect** — a regression that "used to work". `git bisect start; git bisect bad; git bisect good <rev>` then let it binary-search the commit that introduced it. Automate with `git bisect run <cmd>` where `<cmd>` exits 0 on good, non-zero on bad.
8
+ - **Binary-search the input** — halve the failing input until the smallest reproducing case remains. A 10k-row file that fails narrows to the one row; a 500-line config to the one key.
9
+ - **Halve the system** — disable half the middleware / feature flags / plugins. Failure gone → it's in the disabled half. Repeat.
10
+ - **Minimal repro** — rebuild the failure in isolation (a scratch script, a single failing unit test). If it won't reproduce in isolation, the cause is in the *environment/state* you left out — that's a finding, not a dead end.
11
+
12
+ ## Instrumentation vs. debugger
13
+
14
+ - **Logging/print** — best for intermittent, timing, production, and "can't attach" cases; leaves a trace across runs. Log the *hypothesis-relevant* value, not everything. Remove or gate the probes before committing.
15
+ - **Debugger/breakpoint** — best for a reliable, local repro where you want to inspect live state and step. Conditional breakpoints (`x == badValue`) skip the noise.
16
+ - **Assertions/invariants** — add a check that *should* always hold; the point it fires is upstream of the symptom.
17
+ - **Bisect on values** — binary-search *when* a value goes wrong: log at start/middle/end of the pipeline, then narrow.
18
+
19
+ ## Intermittent / heisenbugs (can't reliably reproduce)
20
+
21
+ The cause is almost always one of:
22
+ - **Timing / races** — order of concurrent operations; add delays/logging to widen the window and expose it. A bug that vanishes when you add a log is a timing bug (the log changed the timing).
23
+ - **Shared/leaked state** — a previous test/run left state behind; run the case in full isolation and in a different order (`--shuffle`).
24
+ - **Ordering dependence** — passes alone, fails in the suite → cross-test coupling. Bisect the test order.
25
+ - **Resource / environment** — memory pressure, disk, clock, locale, network flake, an unpinned dependency version. Pin and compare.
26
+ - **Uninitialized / nondeterministic** — reads of uninitialized memory, map iteration order, unseeded randomness, `Date.now()`.
27
+
28
+ Make it reproducible *first* (loop the case 100×, add stress, shuffle). An intermittent bug you can't trigger on demand can't be confirmed fixed.
29
+
30
+ ## The hypothesis log
31
+
32
+ For a bug that resists a few rounds, write it down — it stops you from re-testing the same dead hypothesis and reveals patterns:
33
+
34
+ ```
35
+ Symptom: <exact observable failure>
36
+ Repro: <steps / input / env>
37
+ H1: <cause> → test: <observation> → RESULT: disproved (saw X, not Y)
38
+ H2: <cause> → test: <observation> → RESULT: CONFIRMED (toggles bug)
39
+ Root cause: <the confirmed chain> Fix: <change at cause> Test: <regression test>
40
+ ```
41
+
42
+ ## When to stop and get a second pair of eyes
43
+
44
+ After ~3 disproved hypotheses with no new information, or when you've been staring at the same 20 lines — you likely hold a wrong assumption you can't see. Escalate: hand over the hypothesis log (not "it's broken") so the next person starts from what's *already ruled out*, not from zero. In Crewforth, that handover is the `handoff` skill.
@@ -0,0 +1,88 @@
1
+ ---
2
+ name: teamboard
3
+ description: |
4
+ Experimental: a shared team board. Claim a work item, hand it over, finish it; the claim is a git-ref
5
+ lock, so two people cannot take the same item.
6
+ metadata:
7
+ experimental: true
8
+ ---
9
+
10
+ # Team Board (shared claims + shared item memory)
11
+
12
+ <!-- routing-eval reads the next line; why it sits in the body: AGENT_TEMPLATE.md -->
13
+ Trigger phrases: "team board", "who is working on", "claim", "take this item", "pick up a task", "sprint item", "release the item", "hand the item over", "is anyone on", "board", "of us are working", "stepping on each other", "who is doing what", "who else is working"
14
+
15
+ ## The problem this closes
16
+ Every teammate runs Crewforth **locally**. `docs/PLAN.md` and `docs/SESSION_STATE.md` are gitignored, so the fact
17
+ that Ali started item #1 two hours ago exists nowhere the other sessions can see. Two people start the same item;
18
+ a blocked item gets picked up before its dependency lands; whoever inherits half-finished work rebuilds the
19
+ context from scratch. The board makes those three facts shared.
20
+
21
+ ## The engine (all commands go through it)
22
+ `bash .claude/hooks/board.sh <cmd>` — `status` · `show <id>` · `claim <id>` · `done <id> [note]` ·
23
+ `drop <id> <note>` · `note <id> <text>` · `add <id> <title> [deps] [external]` · `init` · `sync`.
24
+ Never hand-edit the board; every write must go through the engine or it loses its atomicity.
25
+
26
+ ## Why a claim is a real lock, not a convention
27
+ The board lives on a git ref (`refs/crew/board`), not in the worktree. A claim is a commit pushed to that ref, and
28
+ `git push` is fast-forward-only: when two people claim the same item from the same base, **one push is rejected**
29
+ and that session re-reads the board and refuses. This is an atomic compare-and-swap with no server, no token and
30
+ no daemon. The engine builds its commits with git plumbing, so claiming **never touches your working tree,
31
+ index, branch or stash** — you can claim mid-feature with dirty files.
32
+
33
+ ## Off by default; on when a team asks for it
34
+ A repo that never ran `init` **has no board and no gates** — no claim, no commit gate, no edit gate, nothing at
35
+ session start. Solo work is unchanged, and so is every project that installed Crewforth before this existed. Do not
36
+ create a board because a repo merely has more than one contributor; create one when the user says the team keeps
37
+ colliding. Creating one, choosing between its three levels and the ref-namespace fallback: **`references/setup.md`**
38
+ — one person runs it once, and everybody else configures nothing.
39
+
40
+ Already have a board and want it out of the way? `/crew-board off` (add `--global` for every repo) releases **all
41
+ three** gates and leaves the board itself intact; `/crew-board on` restores it. `CREW_NO_BOARD=1` does the same for
42
+ one session. This half stays here on purpose: someone a gate has just stopped needs the answer without opening a
43
+ second file.
44
+
45
+ ## The rules
46
+ 1. **Claim before you touch code.** `claim <id>` fails if someone else holds it, if it is done, or if a
47
+ dependency is unfinished — with the reason and the list of what *is* claimable. Do not argue with a refusal;
48
+ take a free item.
49
+ 2. **Two gates, not one, and the early one is the point.** The first file edit is refused while you hold no item
50
+ (`guard-write.sh`) — unclaimed work is caught at minute one, not at commit time after an afternoon of it. The
51
+ commit then has to carry `[#<id>]` for an item you hold and that is `in_progress`, or `[chore]` for work
52
+ belonging to no item. In a repo with no board neither gate exists. `CREW_NO_BOARD=1` disables both for a
53
+ session; say so out loud if you set it.
54
+ 3. **Never release silently.** `drop` REQUIRES a handover note, because the whole cost of a handover is the
55
+ context the next person does not have: where exactly it stands, which files, and *why* the rejected approach
56
+ was rejected. `done` takes a completion note (what shipped, commit/PR).
57
+ 4. **Never steal a stale claim.** A claim with no heartbeat for `stale_hours` (default 8) is reported as STALE.
58
+ Stale means *ask the owner*, not *take it*. Surface it to the user and let them decide.
59
+ 5. **Read before you plan.** At session start the board summary is injected automatically. Before proposing what
60
+ to work on, run `status` — recommending an item somebody already holds is the failure this exists to prevent.
61
+
62
+ ## Redaction — the board is shared
63
+ Everything written here is pushed to a remote the whole team reads. `handoff`'s `<private>…</private>` rule
64
+ applies unchanged: strip secrets, tokens, credentials and personal notes, leave `[redacted]`, and point at
65
+ *where* a value lives (env var, secret manager, the person to ask) rather than the value.
66
+
67
+ ## Filling the board
68
+ Items come from either direction, and both end at `add`:
69
+ - **From a plan:** `crew-planner` + `spec-planning` produce `docs/PLAN.md` with measurable acceptance criteria and
70
+ a dependency order; each task becomes one `add <id> <title> <deps>`. Keep the plan's dependency edges — they
71
+ are what makes `claim` able to refuse blocked work.
72
+ - **By hand:** the user dictates the items.
73
+
74
+ ## Tracker link (honest boundary)
75
+ Teams use Jira, Trello, Linear, GitHub Issues or nothing, so Crewforth **binds to none of them**. An item carries an
76
+ optional `external:` field, which is a link and nothing more — no sync, no import, no write-back. A team that
77
+ wants two-way sync writes an executable `.crew/board-adapter.sh` answering two verbs: `import` (emit
78
+ `<id>|<title>|<deps>|<external>` lines to be fed to `add`) and `export <id> <status>` (push the state outward).
79
+ Crewforth ships no adapter; do not claim integration Crewforth does not have.
80
+
81
+ ## When the remote is unreachable
82
+ Claims stay local and are labelled `UNSHARED` — meaning **the team cannot see them**, so the lock is not in force.
83
+ Say that plainly rather than reporting success, and re-run `sync` once the network is back.
84
+
85
+ ## DoD
86
+ - Work started only on an item held by this user; the board shows it `in_progress`.
87
+ - An item left for any reason carries a handover note a stranger could resume from.
88
+ - `done` recorded with what shipped, and the dependents it unblocked named to the user.
@@ -0,0 +1,37 @@
1
+ # Setting a board up — one person, one command
2
+
3
+ Read this only when a board is being created or its level changed. Claiming, dropping and finishing an item never
4
+ need it: a teammate who clones the repo configures nothing.
5
+
6
+ ## Who runs what
7
+
8
+ - **Whoever starts it:** `/crew-board init`, then add the items. It probes what the server accepts, creates the
9
+ board on the code repo's own `origin`, and that is the whole setup — no account, no token, no service.
10
+ - **A separate board repository:** `/crew-board init --remote <url>` (or an existing remote's name). Use it when
11
+ the board is shared across several repos, or when people who must claim work cannot push to the code repo. It
12
+ gets its own `crew-board` remote and never touches `origin`.
13
+ - **Everyone else: nothing.** They clone as usual. Session start fetches the board on its own (detached), the
14
+ ref namespace is auto-detected including the orphan-branch fallback, and `/crew-board` fetches on the spot if
15
+ the background refresh has not landed yet. Never tell a teammate to run `init` — a second `init` is how a team
16
+ ends up with two boards.
17
+
18
+ ## The ref namespace, and the fallback
19
+
20
+ `init` first probes whether the server accepts a custom ref namespace (`refs/crew/board`); if it does not, it
21
+ falls back to the orphan branch `refs/heads/crew-board`, which every server accepts and which enforces the same
22
+ fast-forward rule. Do not merge that branch into code.
23
+
24
+ ## Which level to create
25
+
26
+ Do not create a board because a repo merely has more than one contributor; create one when the user says the team
27
+ keeps colliding. Three levels, and the user picks:
28
+
29
+ | | Effect |
30
+ |---|---|
31
+ | no board (default) | nothing at all |
32
+ | `require_item: referenced` in the board's `config` | claims and the shared memory, but no gate: a commit is only checked when it names an item |
33
+ | `require_item: all` (what `init` writes) | claim before you edit, and every commit names an item or `[chore]` |
34
+
35
+ A board with no remote is fine too — you get the item list, the dependency order and the gates, just nothing
36
+ shared. Turning the gates off on an existing board is in SKILL.md, not here: someone a gate has just stopped
37
+ needs that answer without opening a second file.
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: testing
3
+ description: |
4
+ The how of testing: pyramid, AAA, isolation, risk coverage, determinism. Guarantees the DoD's "tests are
5
+ green". crew-test-expert applies it.
6
+ Use when writing or changing tests, or when a suite is flaky, slow or green for the wrong reason.
7
+ ---
8
+
9
+ # Testing Discipline
10
+
11
+ <!-- routing-eval reads the next line; why it sits in the body: AGENT_TEMPLATE.md -->
12
+ Trigger phrases: "write a test", "run the tests", "coverage", "are the tests green", "unit test", "integration test", "tests pass locally", "flaky test", "test is flaky"
13
+
14
+ Goal: **behavior correctness** — test real behavior without breaking product code just to make a test pass.
15
+
16
+ ## Principles
17
+ - **Pyramid:** many unit, fewer integration, few end-to-end (e2e). Limit e2e to critical flows.
18
+ - **AAA:** Arrange-Act-Assert; **one test = one behavior**.
19
+ - **Isolation & determinism:** external dependencies are mocked/faked; time and randomness are fixed; test order is independent.
20
+ - **Risk-coverage:** risk, not metrics. Critical path + **boundary** + **negative** + **authorization (IDOR/404)** scenarios.
21
+ - **Naming:** `what_it_tests_under_which_condition_what_it_expects` — on failure it is clear what broke.
22
+ - **Red-green:** first a failing test, then the implementation.
23
+
24
+ ## Watch out
25
+ - **Flaky = bug:** an occasionally failing test is not tolerated; it is fixed at the root.
26
+ - In snapshot/golden-file tests, avoid needless brittleness (assert only the meaningful output).
27
+
28
+ ## Tests that cannot fail
29
+
30
+ Green is evidence only if the test could have gone red. Shapes that check nothing:
31
+ - **Assertion restates the code:** it recomputes the implementation's own expression, so it moves with every change.
32
+ - **Setup guarantees the result:** arrange plants the value the assert reads back; it holds even if the act never ran.
33
+ - **Expected value derived the way the code derives it:** same formula, query or parser — the same wrong assumption on
34
+ both sides still matches.
35
+ - **A double asserted against its own stub:** the fake is told to return X and the test asserts X; only the fake runs.
36
+ - **No assertion:** it passes because nothing threw. If *not throwing* is the behavior under test, assert that.
37
+
38
+ **Prove it can fail:** break what the test covers — invert a condition, return a wrong constant — confirm it goes red,
39
+ then restore. Still green means the test is documentation, not a gate: fix it or delete it, never count it as coverage.
40
+
41
+ ## Flaky triage
42
+ An intermittent failure gets exactly one outcome, decided the day it is seen: **fix** it, **quarantine** it (out of
43
+ the gating lane, never out of the suite, with an owner and a date), or **escalate** it as the product defect it
44
+ signals. Infrastructure flakes may get a bounded, logged retry; product flakes never do. Classifying them, the retry
45
+ rule, and what a quarantine entry must carry: **`references/flaky-triage.md`**.
46
+
47
+ ## DoD (this skill's contribution)
48
+ - The project's own test command is green — read it off the manifest/CI (`dotnet test` · `npm test` · `pytest` ·
49
+ `go test ./...`), don't assume one; critical paths are covered; no empty/meaningless tests.
@@ -0,0 +1,51 @@
1
+ # Flaky test triage
2
+
3
+ Loaded on demand — SKILL.md holds the rule (`Flaky = bug`); this is the decision procedure for one that has already
4
+ failed intermittently. A test that passes and fails on the same commit gates nothing, and every red run it produces
5
+ teaches the team to ignore red runs. Triage it the day it is seen and record the outcome.
6
+
7
+ ## 1 · Classify first: infrastructure or product
8
+ The two kinds get opposite treatment, so this call comes before the outcome.
9
+
10
+ - **Infrastructure flake** — fails the same way regardless of the test's logic, and clusters in time. Signals:
11
+ identical error text across unrelated tests (connection refused, image pull, no disk, name resolution); a whole
12
+ run or one machine fails and the next run passes with no code change; the assertion is never reached.
13
+ - **Product flake** — follows the data or the ordering. Signals: it tracks one case, fixture or seed; it appears
14
+ only under randomized order or parallel execution; it reproduces in a loop on one machine; the assertion *is*
15
+ reached and the value is wrong.
16
+ - Cannot tell yet → treat it as a product flake. Guessing "infrastructure" is how a real race gets a retry put
17
+ around it.
18
+
19
+ ## 2 · Retry policy follows that classification
20
+ - **Infrastructure: a bounded retry is allowed** — a fixed cap decided once and written down, applied where the
21
+ resource is owned (readiness wait, fixture setup, the job step), never around an assertion. Log every retry that
22
+ fires: a retry nobody can see is a failure nobody counts, and a rising count means the label was wrong.
23
+ - **Product: never retry.** A retry there turns a real bug into a slower green — the defect ships and the suite
24
+ reports success. Widening a timeout and sleeping until it passes are the same move under another name.
25
+
26
+ ## 3 · Three outcomes — pick exactly one, in writing
27
+ | Outcome | Use when | What it requires |
28
+ |---|---|---|
29
+ | **Fix** | the test or the code under it is genuinely wrong: unfrozen clock, unseeded randomness, shared state, order dependence, an assertion on something unordered | the change, plus a run that reproduced the old failure (loop, shuffle, parallel) and now holds |
30
+ | **Quarantine** | the failure is real but not yet understood, and blocking every other change on it costs more than the coverage it holds | a named owner, a date, a linked issue — and the test still executing |
31
+ | **Escalate** | the flake is a symptom, not a test defect: a race, a leak, a resource limit, an unsafe ordering in the code under test | hand it over as a product defect and root-cause it (`systematic-debugging`) |
32
+
33
+ Escalate means the change lands in product code. Rewriting the test to step around the race deletes the only
34
+ evidence that the race exists, and it resurfaces in production instead of in CI.
35
+
36
+ ## 4 · Quarantine has a shape, or it is deletion
37
+ - **Scoped, not removed.** The test leaves the *gating* lane, not the suite: it keeps running in a non-gating or
38
+ scheduled job, so its failure rate stays visible and the fix can be proven.
39
+ - **Owner and date, always** — both stored next to the test (marker, tag, or an explicit list the gating job filters
40
+ on) and re-read on that date. If nobody will own it and no date fits, the honest outcome was Fix or Escalate.
41
+ - **Re-decide on the date**, choosing again from the three. A quarantined test nobody returns to is worse than a
42
+ deleted one: it reports coverage that is not being checked.
43
+ - Deleting the test deliberately, with the reason recorded, is a legitimate end state. Silent expiry is not.
44
+ - Quarantine is not a way to go green for a release; an escalate-class flake blocks the release it belongs to.
45
+
46
+ ## Boundary with the rest of the discipline
47
+ - Disabling or skipping a red test to finish a task is masking, not quarantine: masking removes the signal,
48
+ quarantine relocates it and puts a date on it.
49
+ - Making an intermittent failure reproduce on demand — loop the case, randomize order, add stress, widen the timing
50
+ window — is `systematic-debugging/references/techniques.md`. Triage without a repro is a guess.
51
+ - The quarantine list is a debt list. If it only grows, nothing is being fixed: report the count and the oldest entry.
@@ -0,0 +1,57 @@
1
+ ---
2
+ name: threat-model
3
+ description: |
4
+ Scope a security audit BEFORE scanning, to cut false positives: map assets, entry points, trust boundaries
5
+ and 5-8 domain-specific attack classes into a parseable THREAT_MODEL.md. A threat survives a patch; a
6
+ vulnerability is only evidence for one. Feeds security-scan.
7
+ ---
8
+
9
+ # Threat Model
10
+
11
+ <!-- routing-eval reads the next line; why it sits in the body: AGENT_TEMPLATE.md -->
12
+ Trigger phrases: "threat model", "attack surface", "scope the audit", "trust boundary"
13
+
14
+ Scope first, scan second. A security scan with no map produces noise; a threat model tells the scanner (and
15
+ `security-scan`) **where to look and what matters** — the single biggest lever on false positives.
16
+
17
+ The one idea to keep — the litmus test: **if patching one line of code makes an entry disappear, it was a
18
+ vulnerability, not a threat.** Threats survive patching (they name *what an attacker wants and the surface they
19
+ arrive through*); a vulnerability is only **evidence** that raises a threat's likelihood.
20
+
21
+ > **Crewforth adaptation (local, .claude/):** `crew-security-expert` runs this to scope before `security-scan`. Output
22
+ > `docs/THREAT_MODEL.md` is internal (§4.3). Stack-agnostic. §4 Prohibitions apply.
23
+
24
+ ## When
25
+ - Before a first `security-scan` of a system, or when scan output is noisy / unscoped.
26
+ - After a significant new surface — a new API, a new integration, a new trust boundary.
27
+
28
+ ## Two modes
29
+ - **interview** — the owner is available: ask the four questions below, one at a time.
30
+ - **bootstrap** — no owner: derive the model from code + past advisories, then flag what only the owner can confirm.
31
+
32
+ ## Method — the four questions (Shostack), one at a time
33
+ Never dump a questionnaire; ask, capture into the schema, move on. Mirror the user's language.
34
+ 1. **What are we building?** system context, assets worth protecting, entry points and trust boundaries.
35
+ 2. **What can go wrong?** open-ended first; then, per entry point, fall back to **STRIDE**; derive **5-8
36
+ domain-specific attack classes** at the right granularity — "IDOR on dataset rows", "integer overflow on
37
+ length fields" — not "web vulnerabilities".
38
+ 3. **What are we doing about it?** impact · residual likelihood · status · controls per threat; "accept the
39
+ risk, with a written reason" (`risk_accepted`) is a valid answer.
40
+ 4. **Did we do a good job?** read the ranked table back; coverage-check that every entry point appears.
41
+
42
+ Tag every fact **`[Code-verified]`** or **`[Owner-states]`**; each owner claim that moves a score becomes an
43
+ open question with a "Verify by:" note.
44
+
45
+ ## Output
46
+ Write `docs/THREAT_MODEL.md` to the parseable contract in **`references/schema.md`** (fixed sections; a threats
47
+ table with enumerated columns; residual-likelihood scoring; class-level mitigations). The interview flow, the
48
+ STRIDE table, and the bootstrap steps live in **`references/interview.md`**.
49
+
50
+ ## Principles
51
+ - **Evidence raises likelihood; it is not the threat.** Score the *residual* likelihood after current controls;
52
+ a stated-but-unverified control does not lower it — it becomes an open question.
53
+ - **Prefer a control that survives the next bug** over a patch for the last one (class-level mitigations).
54
+ - **Feeds forward:** `security-scan` reads `THREAT_MODEL.md` to scope its fronts and bias severity.
55
+
56
+ ## DoD
57
+ - `docs/THREAT_MODEL.md` exists; every entry point covered; each threat scored; provenance tagged; scope handed to `security-scan`.
@@ -0,0 +1,51 @@
1
+ # Threat-model interview + bootstrap
2
+
3
+ ## Interview mode — Shostack four questions, ONE at a time
4
+ Never present a questionnaire. Ask, capture into the schema, move on. Mirror the user's language.
5
+
6
+ ### 1 · What are we building?
7
+ System context, assets, entry points, trust boundaries. Draw the boundary explicitly: *"untrusted input crosses
8
+ into trusted code HERE."* List every entry point — this becomes section 3 and the coverage checklist.
9
+
10
+ ### 2 · What can go wrong?
11
+ Open-ended first ("what would hurt most if it broke?"). Then, per entry point with nothing yet, walk **STRIDE**:
12
+
13
+ | STRIDE | asks |
14
+ |---|---|
15
+ | **S**poofing | can someone pretend to be another principal? |
16
+ | **T**ampering | can data / requests be modified in transit or at rest? |
17
+ | **R**epudiation | can an action be denied, or does it go unlogged? |
18
+ | **I**nformation disclosure | can data leak across a trust boundary? |
19
+ | **D**enial of service | can availability be exhausted (beyond plain volumetric floods)? |
20
+ | **E**levation of privilege | can a lower role reach a higher-privilege action? |
21
+
22
+ Derive **5-8 domain-specific attack classes** at the right granularity — "IDOR on dataset rows", "integer
23
+ overflow on length fields", "tenant bleed via a missing scope check" — **not** "web vulnerabilities". Granularity
24
+ test: a class should name *a surface + a mechanism*, so the scanner knows exactly what to grep for.
25
+
26
+ ### 3 · What are we doing about it?
27
+ For each threat: `impact`, residual `likelihood`, `status`, `controls`. "Accept the risk, with a written reason"
28
+ (`risk_accepted`) is a legitimate status — record the reason verbatim in section 6.
29
+
30
+ ### 4 · Did we do a good job?
31
+ Read the ranked table back to the owner. **Coverage check:** every entry point from Q1 appears in ≥1 threat's
32
+ `surface`. Add anything missing before you emit.
33
+
34
+ **Provenance discipline:** tag every fact **`[Code-verified]`** (you read it) or **`[Owner-states]`** (they said
35
+ it). Every owner claim that changes a score becomes an open question in section 6 with **"Verify by: <how>."**
36
+
37
+ ## Bootstrap mode — no owner available
38
+ 1. **Map** (in parallel where the codebase is large): docs, the entry-point surface, infra / IAM, the assets,
39
+ and past advisories — `git log --all -i --grep=<stack keywords>`, `gh api repos/<o>/<r>/security-advisories`.
40
+ 2. **Generalize** each past vulnerability into a *threat*: cluster by `(entry point, bug class, asset reached)`.
41
+ Run a **variant scan** — grep for siblings of each vulnerable pattern — to estimate how much of the surface
42
+ shares it (more siblings → higher likelihood; sibling locations become **scan leads, not evidence**).
43
+ 3. **Gap-fill with STRIDE** for every entry point that still has no threat ("past vulnerabilities are biased
44
+ toward what has already been found"). Invariant: the final table must contain **≥1 threat with empty
45
+ evidence**, or the gap-fill step did not actually run.
46
+ 4. **Flag** every scored owner-would-know claim as an open question, so a later 10-minute interview closes it.
47
+
48
+ ## Handing scope to security-scan
49
+ `security-scan` reads `docs/THREAT_MODEL.md`: section 3 (entry points) and section 5 (attack classes) become its
50
+ focus areas; the threat `impact`/`likelihood` bias which findings it treats as high severity. No threat model →
51
+ `security-scan` falls back to its own Front 0 discovery.
@@ -0,0 +1,42 @@
1
+ # THREAT_MODEL.md — parseable contract
2
+
3
+ A **map, not a bug list.** Fixed sections in this order so `security-scan` and a reviewer can parse it.
4
+
5
+ ## Sections
6
+ 1. **System** — one paragraph: what it does, who uses it, where it runs.
7
+ 2. **Assets** — what is worth protecting (data · money · availability · reputation/trust), each with a *why*.
8
+ 3. **Entry points & trust boundaries** — every place untrusted input crosses into more-trusted code
9
+ (route · API · form · file upload · CLI arg · queue message · webhook · IAM/role boundary). This is the surface.
10
+ 4. **Threats** — the ranked table (below).
11
+ 5. **Attack classes** — the 5-8 domain-specific classes derived, each mapped to the entry points it applies to.
12
+ 6. **Open questions** — owner claims still to verify, each with a "Verify by: <how>".
13
+ 7. **Mitigations** — class-level controls (table below).
14
+ 8. **Coverage** — assert every section-3 entry point appears in ≥1 threat's `surface`.
15
+
16
+ ## Threats table
17
+ Pipe-separated columns:
18
+
19
+ `id | threat | actor | surface | asset | impact | likelihood | status | controls | evidence`
20
+
21
+ Enumerated value sets (keep parseable):
22
+ - **actor** ∈ `external-anon · external-auth · insider · supply-chain · operator · automated · physical`
23
+ - **impact** ∈ `low · moderate · high · severe · existential`
24
+ - **likelihood** ∈ `very_rare · rare · possible · likely · almost_certain`
25
+ - **status** ∈ `unmitigated · partial · mitigated · risk_accepted`
26
+
27
+ Rules:
28
+ - Sort by `(impact, likelihood)` descending — worst first.
29
+ - **`evidence` raises `likelihood`; it is not the threat.** A row may have empty evidence (a threat with no
30
+ found vulnerability yet is still real). Score the **residual** likelihood *after* current `controls`.
31
+ - `risk_accepted` requires a reason recorded verbatim in section 6.
32
+
33
+ ## Scoring guide
34
+ | axis | how to score |
35
+ |---|---|
36
+ | **impact** | realistic worst case for *this* asset. `low`=cosmetic · `moderate`=recoverable loss · `high`=serious breach/outage · `severe`=major data/financial loss · `existential`=business-ending. |
37
+ | **likelihood** | *after* current controls (residual). A control the owner *states* but that is not code-verified does **not** lower it — record it as an open question instead. |
38
+
39
+ ## Mitigations table
40
+ `mitigation | threat_ids | closes_class (yes/no) | effort`
41
+
42
+ Prefer a control that **closes a whole class** (`closes_class = yes`) over a one-line patch for the last bug.
@@ -0,0 +1,51 @@
1
+ ---
2
+ name: token-budget
3
+ description: |
4
+ Context/token discipline: subagent isolation, output = summary, move-to-file, delegation threshold, lean skills.
5
+ ---
6
+
7
+ # Token & Context Discipline
8
+
9
+ <!-- routing-eval reads the next line; why it sits in the body: AGENT_TEMPLATE.md -->
10
+ Trigger phrases: "token budget", "token cost", "context window", "context management", "context is full", "clear context", "running out of context"
11
+
12
+ A subagent exists for context management: it runs in its own window and returns **only its summary**
13
+ to the main thread — intermediate noise (file reads, searches, logs) never enters the main context.
14
+
15
+ **Warning — measured, not guessed.** Each subagent re-pays its **full context from scratch**: in a real
16
+ transcript the first turn was `cache_read=0`, every token `cache_creation` — nothing is shared with the main
17
+ thread's cache. A **no-op** subagent (task = "reply DONE") already cost **~10k tokens with restricted tools and
18
+ ~16k with full tool access**; that floor is base system prompt + tool schemas, paid fresh every time. Of the
19
+ always-on material only the **skill listing (~2.5–3k tokens) is inherited** by a subagent — the discipline
20
+ (`DISCIPLINE.md`/CLAUDE.md) and the agent descriptions are **not** injected into it. So a delegation is worth it
21
+ for **isolation / parallelism / a clean window**, or when the isolated work would otherwise cost the main thread
22
+ **more than that ~10–16k floor** — never by default.
23
+
24
+ ## Rules
25
+ 1. **Output = summary.** The agent returns a short, structured summary to the main thread; it does **not** return raw logs / file dumps / long code.
26
+ 2. **Move to a file.** Heavy output (a plan, scan report, inventory) is written to `docs/*.md`; a **summary + pointer** comes back. (local, in gitignore)
27
+ 3. **Delegation threshold.** Noisy/heavy work (reading many files, scanning, research) → subagent. A single tool-call / small work → **main thread**. Concretely: if the isolated work won't save the main thread more than the **~10–16k fresh-context floor** a subagent costs, keep it on the main thread — delegate for isolation, not to shave a few reads.
28
+ 4. **A RESUMED agent re-pays its GROWN context, not its floor.** Continuing an agent that already ran keeps its
29
+ whole history, so the next turn starts from wherever it got to. Measured across four turns of one agent:
30
+ 167k → 187k → 207k → **211k tokens**, and that last turn was a single word of seed text. The floor in rule 3
31
+ is the cost of a FRESH agent; a long-running one passes it many times over. Continue it for the context it
32
+ holds — a running verification, a migration it is mid-way through — and open a fresh one, or stay on the main
33
+ thread, for a small correction that does not need any of that history.
34
+ 5. **Built-in agents are on this budget too.** `Explore`, `general-purpose` and the rest cost exactly what a Crewforth
35
+ agent costs; one repo-mapping `Explore` measured 520 s and ~150k tokens. Crewforth owns no search agent, so
36
+ reaching for a built-in is correct — just size the request the way rule 3 sizes any other delegation.
37
+ 6. **Least tooling.** An agent holds only the tools it needs; extras accidentally pollute the context + burn the limit.
38
+ 7. **Lean SKILL.md.** Skills load into the main context; heavy reference goes to a separate file, only when needed.
39
+ 8. **Targeted reading.** Instead of reading a whole file, pinpoint with Grep/Glob.
40
+ 9. **Measure fill, don't guess.** `bash .claude/hooks/context-usage.sh` reads it from the transcript; crew-session-manager recommends continue or handoff+clear; the user runs `/clear` at a phase boundary.
41
+ 10. **Bound what a command hands back.** All of the rules above govern the context's own footprint; none of them
42
+ govern what a single `Bash` call dumps into it. A `find` over a monorepo, an unfiltered log, a full test run —
43
+ each returns everything to the main thread whether or not any of it is read. Ask for the answer, not the
44
+ corpus: `grep -c` over `grep`, `| tail -20` over the whole file, `--quiet`/`--porcelain` where the tool has
45
+ one, and a redirect to a file plus a pointer when the output is genuinely needed later (rule 2).
46
+ 11. **Cut what nothing reaches — with evidence, not a hunch.** Every installed skill spends its name and
47
+ description in EVERY session, forever. `bash .claude/eval/utilization.sh` reports which skills actually fired
48
+ in this project's transcripts and how many bytes the cold ones cost, which is the list `doctor.sh` §4a's
49
+ `skillOverrides: name-only` advice needs and never had. Read it as evidence, not a verdict: a skill that only
50
+ fires during an incident is doing its job by existing. `--all-projects` widens the scope; by default it reads
51
+ this project only and prints names and counts, never paths or content.