crewforth 0.0.1 → 3.0.0-rc.2

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 (169) hide show
  1. package/CHANGELOG.md +3805 -0
  2. package/LICENSE +21 -0
  3. package/README.md +37 -7
  4. package/VERSION +1 -0
  5. package/adopt.sh +1739 -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 +639 -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/skill-listing.awk +43 -0
  29. package/kit/eval/lib/star.sh +70 -0
  30. package/kit/eval/parser-conformance.sh +612 -0
  31. package/kit/eval/preflight.sh +186 -0
  32. package/kit/eval/routing-eval.sh +209 -0
  33. package/kit/eval/scan-skill.sh +162 -0
  34. package/kit/eval/smoke-test.sh +6736 -0
  35. package/kit/eval/update-guard.sh +81 -0
  36. package/kit/eval/utilization.sh +130 -0
  37. package/kit/hooks/board-sync.sh +106 -0
  38. package/kit/hooks/board.sh +962 -0
  39. package/kit/hooks/commit-msg +49 -0
  40. package/kit/hooks/context-usage.sh +353 -0
  41. package/kit/hooks/floor-blocklist.txt +124 -0
  42. package/kit/hooks/guard-bash.sh +1433 -0
  43. package/kit/hooks/guard-commit-scan.sh +511 -0
  44. package/kit/hooks/guard-write.sh +513 -0
  45. package/kit/hooks/pre-commit +577 -0
  46. package/kit/hooks/route-hint.sh +185 -0
  47. package/kit/hooks/secret-blocklist.txt +82 -0
  48. package/kit/hooks/session-guard.sh +149 -0
  49. package/kit/hooks/session-rehydrate.sh +41 -0
  50. package/kit/hooks/session-stats.sh +252 -0
  51. package/kit/hooks/session-update-check.sh +236 -0
  52. package/kit/hooks/skill-trust.sh +163 -0
  53. package/kit/hooks/trace-blocklist.txt +53 -0
  54. package/kit/settings.json +132 -0
  55. package/kit/skills/a11y/SKILL.md +44 -0
  56. package/kit/skills/adr/SKILL.md +74 -0
  57. package/kit/skills/api-design/SKILL.md +50 -0
  58. package/kit/skills/automode-policy/SKILL.md +91 -0
  59. package/kit/skills/automode-policy/references/policy.json +13 -0
  60. package/kit/skills/automode-policy/scripts/apply.sh +84 -0
  61. package/kit/skills/automode-policy/scripts/check.sh +102 -0
  62. package/kit/skills/backend-architecture/SKILL.md +103 -0
  63. package/kit/skills/brainstorm/SKILL.md +47 -0
  64. package/kit/skills/ci-pipeline/SKILL.md +38 -0
  65. package/kit/skills/commit-message/SKILL.md +82 -0
  66. package/kit/skills/commit-message/references/examples.md +8 -0
  67. package/kit/skills/confidence-check/SKILL.md +86 -0
  68. package/kit/skills/crew-board/SKILL.md +55 -0
  69. package/kit/skills/crew-brainstorm/SKILL.md +19 -0
  70. package/kit/skills/crew-code-review/SKILL.md +151 -0
  71. package/kit/skills/crew-code-review/references/history-search.md +19 -0
  72. package/kit/skills/crew-code-review/references/panel-mode.md +32 -0
  73. package/kit/skills/crew-code-review/references/receiving.md +23 -0
  74. package/kit/skills/crew-doctor/SKILL.md +46 -0
  75. package/kit/skills/crew-gates/SKILL.md +25 -0
  76. package/kit/skills/crew-handoff/SKILL.md +14 -0
  77. package/kit/skills/crew-plan/SKILL.md +18 -0
  78. package/kit/skills/crew-review/SKILL.md +26 -0
  79. package/kit/skills/crew-ship/SKILL.md +19 -0
  80. package/kit/skills/crew-skill/SKILL.md +62 -0
  81. package/kit/skills/crew-studio/SKILL.md +129 -0
  82. package/kit/skills/crew-update/SKILL.md +43 -0
  83. package/kit/skills/db-migration/SKILL.md +120 -0
  84. package/kit/skills/db-migration/references/backup-restore.md +33 -0
  85. package/kit/skills/db-migration/references/raw-sql.md +30 -0
  86. package/kit/skills/db-migration/references/tool-matrix.md +35 -0
  87. package/kit/skills/dependency-audit/SKILL.md +61 -0
  88. package/kit/skills/dependency-upgrade/SKILL.md +82 -0
  89. package/kit/skills/deploy/SKILL.md +100 -0
  90. package/kit/skills/deploy/references/proxy-ssl.md +56 -0
  91. package/kit/skills/deploy/references/rollback.md +18 -0
  92. package/kit/skills/deploy/references/scripts.md +9 -0
  93. package/kit/skills/deploy/references/topology-a.md +128 -0
  94. package/kit/skills/deploy/references/topology-b.md +44 -0
  95. package/kit/skills/docs-writer/SKILL.md +53 -0
  96. package/kit/skills/docs-writer/references/coauthoring.md +34 -0
  97. package/kit/skills/eval-grader/SKILL.md +75 -0
  98. package/kit/skills/eval-grader/references/method.md +51 -0
  99. package/kit/skills/frontend/SKILL.md +56 -0
  100. package/kit/skills/frontend/references/verify-contract.md +41 -0
  101. package/kit/skills/frontend-design/SKILL.md +71 -0
  102. package/kit/skills/frontend-design/references/design-review.md +34 -0
  103. package/kit/skills/frontend-rn-expo/SKILL.md +25 -0
  104. package/kit/skills/handoff/SKILL.md +71 -0
  105. package/kit/skills/handoff/references/cold-reader.md +51 -0
  106. package/kit/skills/i18n-integrity/SKILL.md +31 -0
  107. package/kit/skills/incident-runbook/SKILL.md +40 -0
  108. package/kit/skills/incident-runbook/references/postmortem.md +16 -0
  109. package/kit/skills/iterate/SKILL.md +40 -0
  110. package/kit/skills/mcp-builder/SKILL.md +54 -0
  111. package/kit/skills/mcp-builder/references/building.md +71 -0
  112. package/kit/skills/observability/SKILL.md +50 -0
  113. package/kit/skills/performance/SKILL.md +38 -0
  114. package/kit/skills/performance/references/bottlenecks.md +10 -0
  115. package/kit/skills/privacy-compliance/SKILL.md +75 -0
  116. package/kit/skills/red-team/SKILL.md +48 -0
  117. package/kit/skills/reflect/SKILL.md +57 -0
  118. package/kit/skills/release/SKILL.md +44 -0
  119. package/kit/skills/security-scan/SKILL.md +99 -0
  120. package/kit/skills/security-scan/references/ai-agents.md +107 -0
  121. package/kit/skills/security-scan/references/fronts.md +99 -0
  122. package/kit/skills/security-scan/references/prompting.md +23 -0
  123. package/kit/skills/security-scan/references/reporting.md +75 -0
  124. package/kit/skills/security-scan/references/verify.md +131 -0
  125. package/kit/skills/sonarqube-check/SKILL.md +108 -0
  126. package/kit/skills/sonarqube-check/references/local-engines.md +32 -0
  127. package/kit/skills/sonarqube-check/references/stand-up-server.md +25 -0
  128. package/kit/skills/spec-planning/SKILL.md +92 -0
  129. package/kit/skills/systematic-debugging/SKILL.md +57 -0
  130. package/kit/skills/systematic-debugging/references/techniques.md +44 -0
  131. package/kit/skills/teamboard/SKILL.md +88 -0
  132. package/kit/skills/teamboard/references/setup.md +37 -0
  133. package/kit/skills/testing/SKILL.md +49 -0
  134. package/kit/skills/testing/references/flaky-triage.md +51 -0
  135. package/kit/skills/threat-model/SKILL.md +57 -0
  136. package/kit/skills/threat-model/references/interview.md +51 -0
  137. package/kit/skills/threat-model/references/schema.md +42 -0
  138. package/kit/skills/token-budget/SKILL.md +51 -0
  139. package/kit/skills/trace-scan/SKILL.md +43 -0
  140. package/kit/skills/worktree/SKILL.md +40 -0
  141. package/kit/studio/README.md +266 -0
  142. package/kit/studio/ensure-node.sh +471 -0
  143. package/kit/studio/package.json +14 -0
  144. package/kit/studio/server/hooks/studio-gate.sh +169 -0
  145. package/kit/studio/server/index.js +902 -0
  146. package/kit/studio/server/lib/crew-env.js +11 -0
  147. package/kit/studio/server/lib/fleet.js +146 -0
  148. package/kit/studio/server/lib/graph.js +533 -0
  149. package/kit/studio/server/lib/instance.js +135 -0
  150. package/kit/studio/server/lib/kit-telemetry.js +182 -0
  151. package/kit/studio/server/lib/kit.js +158 -0
  152. package/kit/studio/server/lib/palette.js +118 -0
  153. package/kit/studio/server/lib/peers.js +72 -0
  154. package/kit/studio/server/lib/permissions.js +150 -0
  155. package/kit/studio/server/lib/projects.js +294 -0
  156. package/kit/studio/server/lib/roster.js +191 -0
  157. package/kit/studio/server/lib/session.js +309 -0
  158. package/kit/studio/server/lib/terminal.js +91 -0
  159. package/kit/studio/server/lib/transcript.js +100 -0
  160. package/kit/studio/web/app.js +1098 -0
  161. package/kit/studio/web/canvas.js +1179 -0
  162. package/kit/studio/web/chat.js +543 -0
  163. package/kit/studio/web/index.html +86 -0
  164. package/kit/studio/web/md.js +110 -0
  165. package/kit/studio/web/storage-migrate.js +23 -0
  166. package/kit/studio/web/style.css +1453 -0
  167. package/package.json +46 -8
  168. package/start.sh +764 -0
  169. package/bin/crewforth.js +0 -10
@@ -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.
@@ -0,0 +1,43 @@
1
+ ---
2
+ name: trace-scan
3
+ description: |
4
+ Trace scan (§4.1/§4.2): before a commit, scans the staged changes and the message for AI traces (co-author
5
+ trailers, footers, robot emoji, tool names) and vendor template names. The git hooks apply it automatically.
6
+ ---
7
+
8
+ # Trace Scan (trace-scan)
9
+
10
+ <!-- routing-eval reads the next line; why it sits in the body: AGENT_TEMPLATE.md -->
11
+ Trigger phrases: "scan traces", "trace scan", "AI trace", "check vendor name", "pre-commit audit"
12
+
13
+ Purpose: to bind §4.1/§4.2 to a *gate* rather than to *memory*. If the rule lives only in text,
14
+ a trace leaks sooner or later; this skill + the hooks stop the leak at commit time.
15
+
16
+ ## When
17
+ - Before every commit (automatic: `pre-commit` + `commit-msg` hooks).
18
+ - Before crew-commit-agent proposes a message (manual verification).
19
+
20
+ ## How
21
+ Pattern list: `./.claude/hooks/trace-blocklist.txt` (grep -iE, one pattern per line).
22
+ - **Defaults are high-hit:** co-author trailers, auto-generation footers, robot emoji, and AI-assistant/tool
23
+ brand names. Standalone words that occur too often (model/assistant) are DELIBERATELY excluded. See trace-blocklist.txt for the exact list.
24
+ - **Vendor name is project-specific:** ADD the name of the third-party template in use to the list (§4.2).
25
+
26
+ Manual scan (a quick look without the hook):
27
+ ```bash
28
+ git diff --cached --unified=0 | grep -E '^\+' | grep -Ev '^\+\+\+' \
29
+ | grep -iEf .claude/hooks/trace-blocklist.txt
30
+ ```
31
+
32
+ ## Hook setup
33
+ `start.sh` sets `git config core.hooksPath .claude/hooks` (if there is a git repo). The hooks live
34
+ under `.claude` → they are in gitignore and stay local (§4.3). To do it later for a repo:
35
+ ```bash
36
+ git config core.hooksPath .claude/hooks
37
+ chmod +x .claude/hooks/pre-commit .claude/hooks/commit-msg
38
+ ```
39
+
40
+ ## Rules
41
+ - If there is a finding, the commit STOPS; the phrase is removed and the real rationale is written in the project's commit language (CLAUDE.md).
42
+ - Skipping with `--no-verify` only on an EXPLICIT request (§4.5); the hook is not skipped silently.
43
+ - On a false positive, narrow/remove the pattern — the list is set up by the project owner.
@@ -0,0 +1,40 @@
1
+ ---
2
+ name: worktree
3
+ description: |
4
+ Isolate risky or parallel file-mutating work in a git worktree so the main tree's uncommitted changes are never
5
+ clobbered. For fan-out agents that edit files, throwaway experiments, or any change you may want to discard cleanly.
6
+ ---
7
+
8
+ # Worktree Isolation
9
+
10
+ <!-- routing-eval reads the next line; why it sits in the body: AGENT_TEMPLATE.md -->
11
+ Trigger phrases: "worktree", "git worktree", "isolate the changes", "sandbox this work", "parallel file edits"
12
+
13
+ One rule: **never let risky or parallel work run on top of uncommitted changes in the shared tree.** A git worktree
14
+ gives a second working copy of the same repo on its own branch — you experiment or fan out agents there, and the main
15
+ tree (with your in-progress edits) is physically untouched. Throw the worktree away and nothing you cared about is lost.
16
+
17
+ > **Crewforth adaptation (local, .claude/):** this exists because verification/fan-out subagents have discarded a session's
18
+ > **uncommitted** work by running a destructive git command over the shared tree. Those commands (`reset --hard`,
19
+ > `clean -f`, `checkout -- .`, `restore`) are §4.5-gated — but the real fix is to not put them near unsaved work.
20
+ > The Agent tool's `isolation: "worktree"` does this automatically for parallel mutating agents; reach for it there.
21
+
22
+ ## When to isolate
23
+ - **Fan-out that writes files** — two+ agents editing the same repo in parallel would collide; give each its own worktree.
24
+ - **A throwaway experiment** — you might keep it or bin it; a worktree makes "bin it" a one-liner, not a `reset --hard`.
25
+ - **A dirty tree you can't commit yet** — you have unsaved work but need to try something risky; isolate rather than stash-and-pray.
26
+ - Skip it for a single, in-place edit on a clean tree — a worktree is overhead there.
27
+
28
+ ## How
29
+ 1. **Detect** — are you already in a worktree? `[ "$(git rev-parse --git-dir)" != "$(git rev-parse --git-common-dir)" ]` is true inside one; don't nest.
30
+ 2. **Create** — `git worktree add ../wt-<name> -b <branch>` (new branch) or `git worktree add ../wt-<name> <existing>`. It shares the object store, so it's cheap.
31
+ 3. **Work there** — cd into it; edits, builds, and agent runs stay local to that copy.
32
+ 4. **Fold back or discard** — keep: commit on its branch, then merge. Discard: `git worktree remove ../wt-<name>` (add `--force` only if you mean to drop its changes).
33
+ 5. **Clean up** — `git worktree prune` removes stale entries. Never leave orphaned worktrees around.
34
+
35
+ ## Invariant rules
36
+ 1. **Isolate before risk, don't revert after** — a worktree replaces "run `checkout -- .` to undo"; the undo is `worktree remove`.
37
+ 2. **One worktree per parallel writer** — never two agents mutating the same tree at once.
38
+ 3. **Don't nest** — creating a worktree from inside a worktree; detect first.
39
+ 4. **Commit or isolate before delegating file-mutating work** — a subagent must never be able to discard the main tree's unsaved changes.
40
+ 5. **Remove what you add** — no orphaned worktrees; `remove` + `prune` when done.
@@ -0,0 +1,266 @@
1
+ # Crewforth Studio
2
+
3
+ A visual orchestration panel for Claude Code: which agent is running, what it is
4
+ doing right now, what it has spent, and which gates fired.
5
+
6
+ Studio **is installed into your project**, because it lives inside the payload:
7
+ this directory is `kit/studio/`, and `kit/` is what every
8
+ channel already ships. `start.sh` and `adopt.sh` copy it to `.claude/studio/`,
9
+ beside `agents`, `skills`, `commands`, `hooks` and `eval` — the sixth of six.
10
+
11
+ That was the other way round until a real project updated with `/crew-update`,
12
+ ran the documented command and got ENOENT: the project had no `package.json`,
13
+ and nothing had ever installed the panel into it. Excluding it from every
14
+ channel was a decision; a documented command that cannot work is a defect.
15
+
16
+ ## Run
17
+
18
+ From any project that has Crewforth:
19
+
20
+ ```bash
21
+ /crew-studio # the command; probes node, starts it, reports the URL
22
+ node .claude/studio/server/index.js --open # the same thing without the picker
23
+ ```
24
+
25
+ **`node` may not be on your PATH, and that is on purpose.** When Crewforth fetched the runtime for you
26
+ (`ensure-node.sh --install`), it promised to touch nothing outside `~/.claude/studio-runtime` — no PATH edit,
27
+ no shell profile, no admin rights. Measured on a stock Windows 11 machine: after a successful install
28
+ `node --version` reports v24.21.0 through the full path while `command -v node` finds nothing, which is the
29
+ promise being kept rather than a broken install. So every `node …` line on this page means "the node Crewforth
30
+ can find". Ask for it instead of assuming it:
31
+
32
+ ```bash
33
+ NODE="$(bash .claude/studio/ensure-node.sh)" # prints an absolute path, exits 1 if there is none
34
+ "$NODE" .claude/studio/server/index.js --open
35
+ ```
36
+
37
+ `/crew-studio` does exactly this for you, which is why it is the first line above and not the second.
38
+
39
+ Other flags, same file:
40
+
41
+ ```bash
42
+ node .claude/studio/server/index.js --port 8080
43
+ node .claude/studio/server/index.js --selftest # offline checks, no browser
44
+ ```
45
+
46
+ **Started per project, scoped to the machine.** Studio reads
47
+ `~/.claude/projects`, which holds every session on this machine. The count is
48
+ whatever that directory holds; the panel prints it rather than claiming it here,
49
+ because a number measured on one machine describes only that machine. So a
50
+ running panel already sees a kit-installed project without being started inside
51
+ it, and the working directory only decides which project the panel opens on.
52
+ Run it from wherever is convenient, or run it once and leave it up.
53
+
54
+ `--open` exists so the URL is not copied by hand: the token is generated per run
55
+ and the panel refuses requests without it. When a browser cannot be opened — over
56
+ SSH, or headless — the server says so rather than looking like it worked, and
57
+ `/crew-studio` reports the URL either way.
58
+
59
+ **Both editions carry the panel, in different places.** A full install has it
60
+ at `.claude/studio/`; the plugin edition has it at `studio/` in the plugin's own
61
+ root. One `/crew-studio` file serves both, and its first step tells them apart
62
+ by reading `${CLAUDE_PLUGIN_ROOT}/studio/server/index.js` literally: Claude Code
63
+ replaces that placeholder before the command is read, and only when the command
64
+ came from the plugin. A real absolute path is the plugin's panel; the
65
+ placeholder left standing means a full install. Neither path on disk means an
66
+ install older than the panel, which `/crew-update` brings up to date.
67
+ In the plugin the command is namespaced: `/crewforth:crew-studio`.
68
+
69
+ **What the plugin edition cannot show.** A plugin install puts no
70
+ `.claude/VERSION`, `kit.conf` or Crewforth scripts into a project. That project's row
71
+ in the list has no version badge, and for the project the panel was opened from, the
72
+ inspector's gates, stats and board tabs say "Not measured" with the reason rather
73
+ than zero. The gates tab can still list what the gate log observed: the plugin's
74
+ Bash guard records its blocks, approval prompts and pre-authorised git actions,
75
+ and its gate-file write guard its blocks, in `.claude/gate-log.tsv` when the
76
+ project has a `.claude/` directory, the file is git-ignored or the project is
77
+ not a repo, and `CREW_GATE_LOG` does not send the log elsewhere.
78
+ Everything else — the live
79
+ agent graph, owned sessions, the permission bridge — works the same in both
80
+ editions.
81
+
82
+ **The suite is not here.** It lives in `packaging/studio-test/`, beside the
83
+ repo's other gates, and asserts things about this *repository* — the root
84
+ `package.json`, the payload beside it — which an installed project does not
85
+ have. Keeping it under `kit/` would also have shipped 104 KB of test
86
+ code through all four channels only for the installer to delete it on arrival.
87
+ The installed diagnostic is `--selftest`, which lives in `server/index.js`.
88
+
89
+ There is no install step. Studio has **zero dependencies** — `node:http` and
90
+ `node:child_process` are the whole stack, matching Crewforth's own promise. If
91
+ `node_modules` ever appears here, something has gone wrong.
92
+
93
+ Requires Node 18+. In Crewforth's own repository `bash packaging/verify.sh studio`
94
+ runs the same checks CI runs; a machine without node reports a skip rather than a
95
+ pass, and a missing `kit/studio/` is a failure rather than a skip.
96
+
97
+ ## What it does
98
+
99
+ **Watches.** The delegation graph of any session on this machine, live: one node
100
+ per agent, what it is doing right now, what it has spent, what it reported.
101
+ Nodes are draggable and their positions are remembered; a workflow run is a
102
+ container you can fold.
103
+
104
+ **Talks.** Sessions the panel starts are driven over stdin/stdout, so you can
105
+ write to one and watch its agents appear beneath it. They are given a session id
106
+ up front, which means their transcripts land where every other session's do and
107
+ the graph reads them without a special case.
108
+
109
+ **Shows every conversation, drives only its own.** Selecting any session opens
110
+ what was said in it, read from the transcript. A session the panel did not start
111
+ has no channel to write to, so that pane says so and offers the two things that
112
+ do work: continue it here, or open it in a real terminal.
113
+
114
+ **Asks before it acts.** Every tool call in an owned session is parked by a
115
+ PreToolUse hook and shown in the panel — the command itself, not just the tool's
116
+ name — until you allow it, allow that tool for the session, or deny it.
117
+
118
+ **Runs several at once.** Each session the panel starts is a tab that keeps its
119
+ own stream open whether or not it is on screen, so work continuing in the
120
+ background is continuing, not replayed when you look back.
121
+
122
+ **Hands a session to a real terminal.** The panel cannot drive a session it did
123
+ not start, so for an observed one it offers the only thing that is true: a
124
+ button that opens it where it can be driven. What it will run is shown before
125
+ anything launches.
126
+
127
+ **Reaches other machines.** Transcripts are local files and nothing enumerates
128
+ another machine's sessions, so a peer is another Studio.
129
+
130
+ ## What it reads
131
+
132
+ | Source | What it gives |
133
+ |---|---|
134
+ | `claude agents --json` | Live sessions on this machine: name, cwd, busy/waiting/idle, what it is waiting for |
135
+ | `<session>.jsonl` and `<session>/subagents/` | The delegation graph, nested workflow runs included |
136
+ | `.claude/VERSION` per project | Which projects run an old Crewforth, against the npm dist-tags feed |
137
+
138
+ That call spawns a process, so it is cached rather than repeated. The browser
139
+ polls every 2 s and the server caches for 1 s, which bounds the cost at one
140
+ spawn per poll. What the spawn costs is a property of the machine, not of this
141
+ file — two machines here measured 131 ms and 164 ms medians — so `--selftest`
142
+ measures it wherever it runs and prints that number instead of quoting one.
143
+
144
+ More sources land in later sprints: the transcript tree (per-agent live JSONL),
145
+ the owned-session event stream, `gate-log.tsv`, and the team board.
146
+
147
+ ## Two honesty rules
148
+
149
+ These are load-bearing, not stylistic.
150
+
151
+ **"Not measured" is never drawn as zero.** If the `claude` CLI is missing or a
152
+ read fails, the panel says so and names the reason. An empty list would read as
153
+ a quiet, healthy machine — which is the kind of lie this panel exists to stop
154
+ telling.
155
+
156
+ **Unknown data is never coerced into something familiar.** An unrecognised
157
+ status keeps a neutral ring; an unrecognised field is carried through untouched
158
+ rather than dropped. Claude Code's event shapes are undocumented and move with
159
+ the version, so the panel is built to notice that rather than to guess.
160
+
161
+ ## Sessions on other machines
162
+
163
+ The fleet lists them under **Reachable elsewhere**, with the time they were
164
+ seen. That wording is the whole of it: this is a snapshot, not a feed.
165
+
166
+ Only a session connected to Remote Control can see peers on other machines.
167
+ Measured: a headless session's `ListAgents` returns the local peers where a
168
+ connected one returns those plus five remote, and passing `--remote-control` to
169
+ a headless session does not change that — the flag starts an *interactive*
170
+ session. There is no documented API or non-interactive command that enumerates
171
+ them; `/list-agents` is an in-session tool, `--cloud` refuses without a TTY, and
172
+ the Claude API's `/v1/sessions` belongs to Managed Agents, a different product.
173
+
174
+ So the panel does not try to be that session. It reads what one already wrote:
175
+ a connected session's `ListAgents` result lands in its transcript as structured
176
+ text, and that is where this comes from. When no session here has ever asked,
177
+ that is reported as not measured — which is not the same as having no peers.
178
+
179
+ Listed, not opened. Those sessions' transcripts are on those machines' disks,
180
+ so the panel can name them but cannot draw their graphs. For that, run Studio
181
+ there too:
182
+
183
+ ## Other machines
184
+
185
+ ```bash
186
+ # on the other machine
187
+ node .claude/studio/server/index.js
188
+
189
+ # here — forward its port, then point at the forwarded one
190
+ ssh -N -L 7778:127.0.0.1:7777 other-machine
191
+ node .claude/studio/server/index.js --peer http://127.0.0.1:7778 --name mac
192
+ ```
193
+
194
+ Sessions, projects, graphs and agent reports from a peer appear alongside local
195
+ ones, tagged with the machine they came from. A peer that cannot be reached is
196
+ reported as unreachable, never as empty.
197
+
198
+ Nothing listens on a network interface in this arrangement: both Studios stay on
199
+ loopback and the tunnel does the crossing.
200
+
201
+ ## What Crewforth already measured
202
+
203
+ The panel does not recompute any of it. Selecting the session node opens what
204
+ Crewforth's own tools say, including when they say they cannot answer:
205
+
206
+ | Tab | Source |
207
+ |---|---|
208
+ | gates | `gate-report.sh --json` for the rule inventory, `.claude/gate-log.tsv` for what fired |
209
+ | stats | `session-stats.sh --raw` — fifteen metrics over this transcript |
210
+ | board | `board.sh status` |
211
+
212
+ One distinction is carried all the way to the screen. A gate event from a
213
+ session the panel started arrives through `--include-hook-events` and carries
214
+ the moment it happened, so it is listed under **Happened**. A line in
215
+ `gate-log.tsv` does not — that format has no timestamp column — so those are
216
+ listed under **Observed**, with the reason written out. Drawing the second as
217
+ the first would be the first untrue thing in this panel.
218
+
219
+ `gate-report.sh` finds the hooks relative to where it runs: `./.claude/hooks`
220
+ in an installed project, `./hooks` otherwise. Both layouts are handed what they
221
+ expect rather than the script being asked to guess. Where it still cannot
222
+ answer — a directory with no Crewforth install, a project with no log — that is reported as
223
+ not measured, never as zero.
224
+
225
+ ## The permission gate
226
+
227
+ A hook injected through `--settings` parks each tool call, writes it into a
228
+ spool, and waits for the panel's answer. Exit 0 allows, exit 2 blocks.
229
+
230
+ It answers at 45 seconds against a 90-second harness timeout, and that gap is
231
+ the whole design. Measured here: a hook killed at its timeout emits nothing and
232
+ **the tool proceeds** — `permission_denials` came back 0 and the command ran. A
233
+ hook the harness never has to kill fails closed instead, so a shut panel is a
234
+ denial rather than an opening.
235
+
236
+ The waiting costs no processes. A bounded read on a fifo held open read-write
237
+ blocks for its timeout and never sees EOF; the alternative, a `sleep` per poll,
238
+ spends seconds of fork overhead on Git Bash. Both the fifo and the shell's
239
+ support for fractional timeouts are probed with exactly what the loop will run —
240
+ bash 3.2 ignores a fractional `-t` and turns the poll into a hot spin, which is
241
+ how the first version passed while spinning 185,000 times in five seconds.
242
+
243
+ Interactive prompts have a limit worth stating: `AskUserQuestion`, `ExitPlanMode`
244
+ and `EnterPlanMode` are absent from a headless session's 78-tool list, in every
245
+ permission mode, while an interactive session has them. So there is no
246
+ structured choice to render. When a reply offers options in prose the panel
247
+ makes them clickable, which sends that text — a shortcut for typing it, not a
248
+ channel that does not exist.
249
+
250
+ ## Security
251
+
252
+ The server binds to `127.0.0.1` only, and the host is deliberately not
253
+ configurable — it reads a developer's live sessions and can start new ones.
254
+
255
+ A token is always required for `/api/`. Supply one, or let the server generate
256
+ one and print it with the URL:
257
+
258
+ ```bash
259
+ CREW_STUDIO_TOKEN=$(uuidgen) node .claude/studio/server/index.js
260
+ ```
261
+
262
+ Anything that changes state needs, on top of the token, a header no cross-origin
263
+ page can attach without a preflight this server never answers. Permission modes
264
+ are an allow-list — `plan` (the default), `acceptEdits`, `default` — so a mode
265
+ that skips Crewforth's gates cannot be requested, and the panel never has to name
266
+ one to refuse it.