@jaggerxtrm/specialists 3.17.0 → 3.18.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 (255) hide show
  1. package/README.md +268 -134
  2. package/config/mandatory-rules/executor-delivery.md +4 -0
  3. package/config/mandatory-rules/json-only-final-output.md +13 -0
  4. package/config/mandatory-rules/service-skills-diff-scan-mandatory.md +26 -0
  5. package/config/mandatory-rules/service-skills-gitnexus-triage.md +5 -0
  6. package/config/mandatory-rules/test-runner-execution-scope.md +4 -0
  7. package/config/skills/setup-specialists/SKILL.md +556 -0
  8. package/config/skills/specialists-creator/SKILL.md +132 -4
  9. package/config/skills/specialists-creator/scripts/audit-spec-uniformity.mjs +1 -1
  10. package/config/skills/using-specialists-v3/SKILL.md +80 -20
  11. package/config/specialists/bare.specialist.json +3 -3
  12. package/config/specialists/changelog-drafter.specialist.json +5 -4
  13. package/config/specialists/changelog-keeper.specialist.json +7 -6
  14. package/config/specialists/debugger.specialist.json +2 -2
  15. package/config/specialists/executor.specialist.json +2 -2
  16. package/config/specialists/explorer.specialist.json +4 -4
  17. package/config/specialists/memory-processor.specialist.json +3 -3
  18. package/config/specialists/node-coordinator.specialist.json +3 -3
  19. package/config/specialists/obligations-scanner.specialist.json +67 -17
  20. package/config/specialists/overthinker.specialist.json +3 -3
  21. package/config/specialists/planner.specialist.json +4 -4
  22. package/config/specialists/quant-methodologist.specialist.json +145 -0
  23. package/config/specialists/quant-researcher.specialist.json +144 -0
  24. package/config/specialists/researcher.specialist.json +5 -5
  25. package/config/specialists/reviewer.specialist.json +1 -1
  26. package/config/specialists/seconder.specialist.json +2 -2
  27. package/config/specialists/security-auditor.specialist.json +2 -2
  28. package/config/specialists/service-skills-sync.specialist.json +90 -75
  29. package/config/specialists/specialists-creator.specialist.json +4 -4
  30. package/config/specialists/sync-docs.specialist.json +4 -4
  31. package/config/specialists/test-engineer.specialist.json +3 -3
  32. package/config/specialists/test-runner.specialist.json +7 -7
  33. package/config/specialists/transcriber.specialist.json +3 -3
  34. package/config/specialists/xt-merge.specialist.json +4 -4
  35. package/dist/asset-contract.json +22 -3
  36. package/dist/index.js +28711 -18517
  37. package/dist/lib.js +10020 -6150
  38. package/dist/types/cli/console/components.d.ts +83 -0
  39. package/dist/types/cli/console/components.d.ts.map +1 -0
  40. package/dist/types/cli/console/config-source.d.ts +58 -0
  41. package/dist/types/cli/console/config-source.d.ts.map +1 -0
  42. package/dist/types/cli/console/forensic.d.ts +11 -0
  43. package/dist/types/cli/console/forensic.d.ts.map +1 -0
  44. package/dist/types/cli/console/git.d.ts +28 -0
  45. package/dist/types/cli/console/git.d.ts.map +1 -0
  46. package/dist/types/cli/console/help.d.ts +2 -0
  47. package/dist/types/cli/console/help.d.ts.map +1 -0
  48. package/dist/types/cli/console/log.d.ts +13 -0
  49. package/dist/types/cli/console/log.d.ts.map +1 -0
  50. package/dist/types/cli/console/repo-config.d.ts +26 -0
  51. package/dist/types/cli/console/repo-config.d.ts.map +1 -0
  52. package/dist/types/cli/console/repo-discovery.d.ts +12 -0
  53. package/dist/types/cli/console/repo-discovery.d.ts.map +1 -0
  54. package/dist/types/cli/console/runtime.d.ts +12 -0
  55. package/dist/types/cli/console/runtime.d.ts.map +1 -0
  56. package/dist/types/cli/console/subscribe-prototype.d.ts +18 -0
  57. package/dist/types/cli/console/subscribe-prototype.d.ts.map +1 -0
  58. package/dist/types/cli/console/theme.d.ts +91 -0
  59. package/dist/types/cli/console/theme.d.ts.map +1 -0
  60. package/dist/types/cli/console/types.d.ts +231 -0
  61. package/dist/types/cli/console/types.d.ts.map +1 -0
  62. package/dist/types/cli/console/view-model.d.ts +252 -0
  63. package/dist/types/cli/console/view-model.d.ts.map +1 -0
  64. package/dist/types/cli/console.d.ts +2 -0
  65. package/dist/types/cli/console.d.ts.map +1 -0
  66. package/dist/types/cli/db.d.ts.map +1 -1
  67. package/dist/types/cli/doctor.d.ts.map +1 -1
  68. package/dist/types/cli/edit.d.ts.map +1 -1
  69. package/dist/types/cli/epic.d.ts.map +1 -1
  70. package/dist/types/cli/feed.d.ts.map +1 -1
  71. package/dist/types/cli/forensic.d.ts +2 -0
  72. package/dist/types/cli/forensic.d.ts.map +1 -0
  73. package/dist/types/cli/format-helpers.d.ts +4 -2
  74. package/dist/types/cli/format-helpers.d.ts.map +1 -1
  75. package/dist/types/cli/help.d.ts.map +1 -1
  76. package/dist/types/cli/init.d.ts +10 -0
  77. package/dist/types/cli/init.d.ts.map +1 -1
  78. package/dist/types/cli/list.d.ts.map +1 -1
  79. package/dist/types/cli/log.d.ts.map +1 -1
  80. package/dist/types/cli/merge.d.ts.map +1 -1
  81. package/dist/types/cli/metrics.d.ts +2 -0
  82. package/dist/types/cli/metrics.d.ts.map +1 -0
  83. package/dist/types/cli/ps.d.ts.map +1 -1
  84. package/dist/types/cli/result.d.ts.map +1 -1
  85. package/dist/types/cli/run.d.ts +20 -0
  86. package/dist/types/cli/run.d.ts.map +1 -1
  87. package/dist/types/cli/script.d.ts +3 -0
  88. package/dist/types/cli/script.d.ts.map +1 -1
  89. package/dist/types/cli/serve.d.ts.map +1 -1
  90. package/dist/types/cli/setup.d.ts +19 -1
  91. package/dist/types/cli/setup.d.ts.map +1 -1
  92. package/dist/types/cli/status.d.ts.map +1 -1
  93. package/dist/types/cli/version-check.d.ts +1 -0
  94. package/dist/types/cli/version-check.d.ts.map +1 -1
  95. package/dist/types/index.d.ts +1 -1
  96. package/dist/types/pi/session.d.ts +12 -1
  97. package/dist/types/pi/session.d.ts.map +1 -1
  98. package/dist/types/server.d.ts +15 -0
  99. package/dist/types/server.d.ts.map +1 -1
  100. package/dist/types/specialist/benchmarks.d.ts +37 -0
  101. package/dist/types/specialist/benchmarks.d.ts.map +1 -0
  102. package/dist/types/specialist/chain-identity.d.ts +7 -1
  103. package/dist/types/specialist/chain-identity.d.ts.map +1 -1
  104. package/dist/types/specialist/control.d.ts.map +1 -1
  105. package/dist/types/specialist/dead-job-audit.d.ts +20 -0
  106. package/dist/types/specialist/dead-job-audit.d.ts.map +1 -0
  107. package/dist/types/specialist/forensic-events.d.ts +138 -0
  108. package/dist/types/specialist/forensic-events.d.ts.map +1 -0
  109. package/dist/types/specialist/forensic-renderer.d.ts +34 -0
  110. package/dist/types/specialist/forensic-renderer.d.ts.map +1 -0
  111. package/dist/types/specialist/git-diff-evidence.d.ts +28 -0
  112. package/dist/types/specialist/git-diff-evidence.d.ts.map +1 -0
  113. package/dist/types/specialist/global-config.d.ts +389 -0
  114. package/dist/types/specialist/global-config.d.ts.map +1 -0
  115. package/dist/types/specialist/launch.d.ts +9 -0
  116. package/dist/types/specialist/launch.d.ts.map +1 -1
  117. package/dist/types/specialist/live-aggregates.d.ts +46 -0
  118. package/dist/types/specialist/live-aggregates.d.ts.map +1 -0
  119. package/dist/types/specialist/loader.d.ts +50 -1
  120. package/dist/types/specialist/loader.d.ts.map +1 -1
  121. package/dist/types/specialist/model-chain.d.ts +7 -0
  122. package/dist/types/specialist/model-chain.d.ts.map +1 -0
  123. package/dist/types/specialist/model-probes.d.ts +28 -0
  124. package/dist/types/specialist/model-probes.d.ts.map +1 -0
  125. package/dist/types/specialist/node-contract.d.ts +18 -18
  126. package/dist/types/specialist/node-supervisor.d.ts.map +1 -1
  127. package/dist/types/specialist/observability-db.d.ts +1 -1
  128. package/dist/types/specialist/observability-db.d.ts.map +1 -1
  129. package/dist/types/specialist/observability-sqlite.d.ts +101 -0
  130. package/dist/types/specialist/observability-sqlite.d.ts.map +1 -1
  131. package/dist/types/specialist/pr-drift-refresh.d.ts +17 -0
  132. package/dist/types/specialist/pr-drift-refresh.d.ts.map +1 -0
  133. package/dist/types/specialist/preset-resolver.d.ts +56 -0
  134. package/dist/types/specialist/preset-resolver.d.ts.map +1 -0
  135. package/dist/types/specialist/prometheus-projection.d.ts +25 -0
  136. package/dist/types/specialist/prometheus-projection.d.ts.map +1 -0
  137. package/dist/types/specialist/runner.d.ts +29 -1
  138. package/dist/types/specialist/runner.d.ts.map +1 -1
  139. package/dist/types/specialist/schema.d.ts +163 -54
  140. package/dist/types/specialist/schema.d.ts.map +1 -1
  141. package/dist/types/specialist/script-runner.d.ts +5 -1
  142. package/dist/types/specialist/script-runner.d.ts.map +1 -1
  143. package/dist/types/specialist/snapshot-diff.d.ts +8 -0
  144. package/dist/types/specialist/snapshot-diff.d.ts.map +1 -0
  145. package/dist/types/specialist/source-queue.d.ts +13 -0
  146. package/dist/types/specialist/source-queue.d.ts.map +1 -0
  147. package/dist/types/specialist/status-load.d.ts.map +1 -1
  148. package/dist/types/specialist/supervisor.d.ts +25 -1
  149. package/dist/types/specialist/supervisor.d.ts.map +1 -1
  150. package/dist/types/specialist/timeline-events.d.ts +70 -1
  151. package/dist/types/specialist/timeline-events.d.ts.map +1 -1
  152. package/dist/types/tools/specialist/resume_specialist.tool.d.ts +4 -4
  153. package/dist/types/tools/specialist/specialist_status.tool.d.ts +1 -1
  154. package/dist/types/tools/specialist/steer_specialist.tool.d.ts +4 -4
  155. package/dist/types/tools/specialist/use_specialist.tool.d.ts +16 -16
  156. package/docs/ARCHITECTURE.md +1176 -0
  157. package/docs/TODO.md +9 -0
  158. package/docs/architecture.md +11 -0
  159. package/docs/archive/2026-03-13-bd-decision-context-template-plan.md +96 -0
  160. package/docs/archive/AGENT-HANDOFF.md +351 -0
  161. package/docs/archive/PARITY-ANALYSIS.md +296 -0
  162. package/docs/archive/SPECIALISTS_REFACTOR.md.md +30 -0
  163. package/docs/archive/cc-programmatic.md +216 -0
  164. package/docs/archive/claude-agent-sdk.md +594 -0
  165. package/docs/archive/decision-specialist-directory.md +41 -0
  166. package/docs/archive/discoveries.md +148 -0
  167. package/docs/archive/executor-benchmark-protocol.md +198 -0
  168. package/docs/archive/future-features.md +66 -0
  169. package/docs/archive/gzrx-completion-critique.md +183 -0
  170. package/docs/archive/gzrx-research-notes.md +401 -0
  171. package/docs/archive/gzrx-tool-catalog.md +760 -0
  172. package/docs/archive/iron-review-hardening-qa-chain-substrate.md +322 -0
  173. package/docs/archive/iron-review-hardening.html +1004 -0
  174. package/docs/archive/issuetracking.md +312 -0
  175. package/docs/archive/qa-v3.0.2.md +220 -0
  176. package/docs/archive/restructure.md +231 -0
  177. package/docs/archive/script-specialists.md +1254 -0
  178. package/docs/archive/spec-v3.md +792 -0
  179. package/docs/archive/specialist-stats.md +127 -0
  180. package/docs/archive/specialists-friction-audit.md +1347 -0
  181. package/docs/archive/specialists-runtime-critique.md +170 -0
  182. package/docs/archive/specialists-service-evaluation.md +713 -0
  183. package/docs/archive/specialists-substrate-alignment.md +255 -0
  184. package/docs/archive/substrate-review.md +1288 -0
  185. package/docs/archive/test-writer-specialist.md +254 -0
  186. package/docs/archive/using-specialists-v3-improvements-2026-05-09.md +600 -0
  187. package/docs/archive/xtrm-specialists-analysis.md +314 -0
  188. package/docs/authoring.md +701 -0
  189. package/docs/background-jobs.md +203 -0
  190. package/docs/bare-specialists.md +83 -0
  191. package/docs/benchmarks/executor-benchmark-runner.md +66 -0
  192. package/docs/bootstrap.md +161 -0
  193. package/docs/cli-reference.md +1645 -0
  194. package/docs/deploying-alongside.md +155 -0
  195. package/docs/design/README.md +36 -0
  196. package/docs/design/darth-feedor-migration.md +290 -0
  197. package/docs/design/roadmap/README.md +32 -0
  198. package/docs/design/roadmap/chain-templates/README.md +146 -0
  199. package/docs/design/roadmap/chain-templates/code-quick.formula.json +27 -0
  200. package/docs/design/roadmap/chain-templates/code-standard.formula.json +126 -0
  201. package/docs/design/roadmap/chain-templates/code-with-advisors.formula.json +128 -0
  202. package/docs/design/roadmap/chain-templates/code-with-tests.formula.json +76 -0
  203. package/docs/design/roadmap/chain-templates/debug.formula.json +128 -0
  204. package/docs/design/roadmap/chain-templates/doc-sync.formula.json +28 -0
  205. package/docs/design/roadmap/chain-templates/memory-hygiene.formula.json +27 -0
  206. package/docs/design/roadmap/chain-templates/planning.formula.json +27 -0
  207. package/docs/design/roadmap/chain-templates/premortem.formula.json +26 -0
  208. package/docs/design/roadmap/chain-templates/release-prep.formula.json +36 -0
  209. package/docs/design/roadmap/chain-templates/research-only.formula.json +28 -0
  210. package/docs/design/roadmap/chain-templates/restitch.formula.json +125 -0
  211. package/docs/design/roadmap/chain-templates/security-deep.formula.json +161 -0
  212. package/docs/design/roadmap/chain-templates/test-only.formula.json +52 -0
  213. package/docs/design/roadmap/chain-templates/triage.formula.json +35 -0
  214. package/docs/design/roadmap/history/handoff-from-substrate-design.md +87 -0
  215. package/docs/design/roadmap/history/substrate-reconciliation.md +105 -0
  216. package/docs/design/roadmap/specialists-roadmap.md +1261 -0
  217. package/docs/design/sp-console-subscribe-via-materializer.md +231 -0
  218. package/docs/design/sp-console-tui-mock-v2.html +293 -0
  219. package/docs/design/sp-console-tui-mock.html +120 -0
  220. package/docs/design/sp-console-tui.md +340 -0
  221. package/docs/design/specialist-agentops-suite.md +323 -0
  222. package/docs/design/substrate/channels.md +14 -0
  223. package/docs/design/substrate/devops-platform-engineering-prd.md +446 -0
  224. package/docs/design/substrate/html-design-example.md +339 -0
  225. package/docs/design/xtrm-tiers-architecture.svg +132 -0
  226. package/docs/devops/dependency-verdict-materialization.md +46 -0
  227. package/docs/epic-readiness.md +75 -0
  228. package/docs/examples/mercury-atomic-summarizer.specialist.json +26 -0
  229. package/docs/examples/smoke-echo-text-expected-keys.specialist.json +25 -0
  230. package/docs/examples/smoke-echo.specialist.json +25 -0
  231. package/docs/features.md +1577 -0
  232. package/docs/hooks.md +81 -0
  233. package/docs/installation.md +142 -0
  234. package/docs/manifest.md +184 -0
  235. package/docs/mcp-servers.md +73 -0
  236. package/docs/mcp-tools.md +71 -0
  237. package/docs/nodes.md +231 -0
  238. package/docs/observability-metrics.md +152 -0
  239. package/docs/operator/sp-console-v2-walkthrough.md +410 -0
  240. package/docs/overrides-guide.md +306 -0
  241. package/docs/pi-rpc-boundary.md +118 -0
  242. package/docs/pi-session.md +195 -0
  243. package/docs/release.md +22 -0
  244. package/docs/skills.md +132 -0
  245. package/docs/specialists/handoff-schema.md +181 -0
  246. package/docs/specialists-catalog.md +99 -0
  247. package/docs/specialists-service-install.md +226 -0
  248. package/docs/specialists-service.md +363 -0
  249. package/docs/surface-ownership.md +138 -0
  250. package/docs/upgrade-notes/kan-90-global-user-config.md +114 -0
  251. package/docs/upgrade-notes/kan-91-expanded-overrides.md +261 -0
  252. package/docs/workflow.md +114 -0
  253. package/docs/worktree.md +71 -0
  254. package/docs/worktrees.md +309 -0
  255. package/package.json +7 -4
@@ -0,0 +1,410 @@
1
+ # `sp console` v2 — operator E2E walkthrough
2
+
3
+ > Bead: `unitAI-ctb4u.18` — operator E2E walkthrough + debug guide.
4
+ > Subject: the compiled binary at `./sp`, not `bunx tsx src/index.ts`.
5
+ > Time budget: ~30 min, single operator, this repo.
6
+ > Filling instructions: each section has **Expected** (derived from the v2 source) and **Observed** (you fill, marking PASS or FAIL). Any FAIL → file a bead with `discovered-from:unitAI-ctb4u.18` and paste the bd id at the bottom of the section.
7
+
8
+ ---
9
+
10
+ ## §1 Build + launch
11
+
12
+ ### Setup
13
+
14
+ ```bash
15
+ cd /home/dawid/dev/specialists/.worktrees/ctb4u-rebase
16
+ bun build --compile --target=bun src/index.ts --outfile=./sp
17
+ ls -lh ./sp
18
+ file ./sp
19
+ ```
20
+
21
+ ### Expected
22
+
23
+ - `bun build` reports `bundle <N> modules` then `compile ./sp` and exits 0.
24
+ - `./sp` is ~100 MB (Bun-runtime binary), ELF64 LSB executable.
25
+ - `./sp --help` lists `console` (line: "operator TUI…").
26
+ - `./sp console --help` exits 0 and prints a key listing.
27
+
28
+ ### Observed
29
+
30
+ - [x] PASS — bundle + compile exits 0; size ≈ **103 MB** (verified `2026-06-17` on this worktree)
31
+ - [x] PASS — `./sp --help` lists `console`
32
+ - [x] PASS — `./sp console --help` exits 0 (but text is v1; see drift below)
33
+ - **Known drift (filed):** `./sp console --help` text is v1, missing `b` / `d` / `g` / `t` / `e` / `u` / `[` / `]` / `f` keys. → **unitAI-ctb4u.23**
34
+
35
+ Follow-up beads: unitAI-ctb4u.23
36
+
37
+ ---
38
+
39
+ ## §2 ProcessView at 80 / 120 / 160 (resize sweep)
40
+
41
+ Phase contract: `.4` (ProcessView), `.5` (perf/throttling), theme.ts (column widths).
42
+
43
+ ### Setup
44
+
45
+ Open three terminals (or use tmux split) at widths 80, 120, 160 cols. In each:
46
+
47
+ ```bash
48
+ ./sp console
49
+ ```
50
+
51
+ ### Expected
52
+
53
+ - ProcessView is the default view; top chrome = 4 rows (tabs / meters / viewtag / header), bottom = 2 rows (StatsLine + KeyBar). Zero blank lines in the middle ⇒ `fillerLine(width)` space-pads when no job rows exist.
54
+ - 80 cols: column drop-order kicks in. `title` drops first, then `next`, then `bead`, then `payloadTok`, etc. (see `theme.ts:selectJobColumns`).
55
+ - 120 cols: all standard columns visible (`id`, `spec`, `status`, `ctxPct`, `elapsed`, `payloadKb`, `payloadTok`, `bead`, `next`, `title`).
56
+ - 160 cols: extra horizontal padding; all columns still aligned.
57
+ - StatsLine is **exactly one line** at every width; priority truncation per §8.1 drops least-important tokens (worktrees, nodes, …) first.
58
+ - Resize sweep: drag the terminal smaller → SIGWINCH → frame redraws within ~50 ms without flicker (50 ms coalesce timer, `theme.ts:fitFrame`).
59
+
60
+ ### Observed
61
+
62
+ - [ ] PASS / [ ] FAIL — 80 cols: title column dropped, no truncation overflow
63
+ - [ ] PASS / [ ] FAIL — 120 cols: all default columns visible
64
+ - [ ] PASS / [ ] FAIL — 160 cols: aligned, no trailing whitespace artifacts
65
+ - [ ] PASS / [ ] FAIL — StatsLine one line at every width
66
+ - [ ] PASS / [ ] FAIL — SIGWINCH resize redraws cleanly (no flicker / no orphaned rows)
67
+ - [ ] PASS / [ ] FAIL — Zero blank rows in any frame (visual check: highlight whitespace)
68
+
69
+ Follow-up beads: _____
70
+
71
+ ---
72
+
73
+ ## §3 BeadView (`b`) against a real bead
74
+
75
+ Phase contract: `.3` (BeadView), `.5` (NDJSON log on `bd_show` failure).
76
+
77
+ ### Setup
78
+
79
+ Pick a real bead from this epic that has accumulated notes:
80
+
81
+ ```bash
82
+ bd show unitAI-ctb4u.6 | head -10 # confirm bead has notes
83
+ ```
84
+
85
+ Launch console; in ProcessView, ↑↓ to select any visible job (or open with no selection — BeadView will require a job). If no jobs are visible: open via the `i` (Inspect) path on a historical row or fall back to direct CLI test (see §3 fallback below).
86
+
87
+ In ProcessView with a selected job, press `b` → BeadView opens for the selected job's `bead_id`.
88
+
89
+ ### Expected
90
+
91
+ - Header switches to `bead · <name> · <path>`.
92
+ - Body: 12-wide padded keys (status, type, priority, parent, etc.) then dim "── notes ──" section title, then notes wrapped to terminal width.
93
+ - KeyBar reads: `↑↓ scroll PgUp/PgDn page ⌫ back g/G top/end q quit`.
94
+ - `j`/`k` scroll one line; PgUp/PgDn scroll one viewport; `g`/`G` jump to top/end.
95
+ - `⌫` (Backspace) → return to ProcessView **with the same row selected and scroll position preserved** (per `view-model.ts:back`).
96
+ - On `bd show` failure (kill bd or rename a bead mid-poll): the view stays rendered but a single NDJSON line lands on stderr — `op:'bd_show'`, `errorClass:<code>`, **no payload, no bead text**. Rate-limited to one line per session per (view, op, errorClass).
97
+
98
+ ### §3 fallback: invalid bead id
99
+
100
+ In ConfigView (`g` from ProcessView), the BeadView path is not reachable directly. If you cannot get a job with a `bead_id` populated, smoke-test the regex guard another way: invoke an internal codepath that calls `bd show` with an obviously bad id. Tests already cover this — record this as "covered by `tests/unit/cli/console-bead-view.test.ts`" if no live repro is reachable.
101
+
102
+ ### Observed
103
+
104
+ - [ ] PASS / [ ] FAIL — Header shows correct bead id
105
+ - [ ] PASS / [ ] FAIL — Section title `── notes ──` renders dim
106
+ - [ ] PASS / [ ] FAIL — `↑↓` scroll one line
107
+ - [ ] PASS / [ ] FAIL — `PgUp/PgDn` page through
108
+ - [ ] PASS / [ ] FAIL — `g`/`G` jump to top/end
109
+ - [ ] PASS / [ ] FAIL — `⌫` returns to ProcessView, row + scroll preserved
110
+ - [ ] PASS / [ ] FAIL — On bd failure, single NDJSON line on stderr, no payload
111
+
112
+ Follow-up beads: _____
113
+
114
+ ---
115
+
116
+ ## §4 FeedView + FeedSource toggle
117
+
118
+ Phase contract: `.3` (forensic source default), `.5` (NDJSON `subscribe_feed`).
119
+
120
+ ### Setup
121
+
122
+ In ProcessView, select a job with active output. Press `↵` (Enter) → FeedView opens.
123
+
124
+ ### Expected
125
+
126
+ - FeedView defaults to **forensic** source (`feedSource === 'forensic'`).
127
+ - KeyBar reads: `↑↓ scroll PgUp/PgDn page f follow:<on|off> t legacy ⌫ back g/G top/end q quit`. The label after `t` is the **next** source (i.e. shows `legacy` while forensic is active, shows `forensic` while sp_feed is active).
128
+ - Press `t` → source flips to `sp_feed`. KeyBar updates to `t forensic`. Existing rows wiped, scroll = 0.
129
+ - Press `t` again → back to `forensic`.
130
+ - Press `f` → follow toggles. New rows auto-scroll to bottom while follow is on.
131
+ - Rows render via `forensicEventToFeedRow` / payload is `pickAllowedLabels`-filtered (max 5 fields × 32 chars each). No raw JSON quoted strings (e.g. `"role":`, `"tool_call_id":`).
132
+ - On `subscribe_feed` failure: rate-limited single NDJSON line, no payload.
133
+
134
+ ### Observed
135
+
136
+ - [ ] PASS / [ ] FAIL — Default source = forensic
137
+ - [ ] PASS / [ ] FAIL — `t` flips to sp_feed; KeyBar label updates
138
+ - [ ] PASS / [ ] FAIL — `t` flips back; rows + scroll reset on each toggle
139
+ - [ ] PASS / [ ] FAIL — `f` toggles follow; new rows auto-scroll
140
+ - [ ] PASS / [ ] FAIL — Payload column contains no raw JSON tokens (`"role":`, etc.)
141
+ - [ ] PASS / [ ] FAIL — Subscribe failure logs single NDJSON line
142
+
143
+ Follow-up beads: _____
144
+
145
+ ---
146
+
147
+ ## §5 DiffView (`d`) against a worktree with real changes
148
+
149
+ Phase contract: `.5` (git wrappers, `parseNumstat`, `parseUnifiedDiff`).
150
+
151
+ ### Setup
152
+
153
+ Make sure the selected job's worktree has unstaged changes (or open the console from this worktree which already has uncommitted scaffolding for the doc itself).
154
+
155
+ In ProcessView, select a job whose worktree you can identify; press `d` → DiffView opens.
156
+
157
+ ### Expected
158
+
159
+ - Header switches to `diff · <repo> · <worktree path>`.
160
+ - Summary list: one row per changed file with status code (`M`/`A`/`D`/`R`/`?`), `+adds`, `-dels`, path. Binary files show `bin` marker instead of counts. Untracked files surface from porcelain status.
161
+ - KeyBar reads: `↑↓ nav ↵ open file r refresh ⌫ back q quit`.
162
+ - `↵` / `l` / `→` → open file view; shows hunks with @@ header (dim) and color-coded lines (add = green-ish, del = red-ish, context = dim, meta = dim).
163
+ - `r` → refresh re-runs `git diff --numstat` + `git status --porcelain`.
164
+ - `⌫` returns to summary list (when inside a file) or to ProcessView (when at summary list).
165
+ - HUNK_DISPLAY_CEILING = 5000 lines per file; beyond that, view truncates.
166
+ - Git failure → NDJSON line with `op:'git_diff'` | `'git_numstat'` | `'git_status'` | `'merge_base'`, no path/diff content in log.
167
+
168
+ ### Observed
169
+
170
+ - [ ] PASS / [ ] FAIL — Summary lists this worktree's changed files (incl. docs/operator/*)
171
+ - [ ] PASS / [ ] FAIL — Status codes (M/A/D/?) accurate
172
+ - [ ] PASS / [ ] FAIL — Binary file shows `bin` marker (test with adding any *.png)
173
+ - [ ] PASS / [ ] FAIL — `↵` opens file; hunks render with @@ headers
174
+ - [ ] PASS / [ ] FAIL — Add/del lines color-distinct from context
175
+ - [ ] PASS / [ ] FAIL — `r` refresh picks up new edits
176
+ - [ ] PASS / [ ] FAIL — `⌫` from file → summary; second `⌫` → ProcessView
177
+ - [ ] PASS / [ ] FAIL — No file paths in stderr NDJSON on simulated git failure
178
+
179
+ Follow-up beads: _____
180
+
181
+ ---
182
+
183
+ ## §6 ConfigView (`g`) read-only against real `user.json`
184
+
185
+ Phase contract: `.6` (config-source, schema introspection), `.7` (inline edit), `.5` (NDJSON `read_global_config`).
186
+
187
+ ### Setup
188
+
189
+ Confirm the operator's global config exists:
190
+
191
+ ```bash
192
+ ls -lh ~/.config/specialists/user.json
193
+ ```
194
+
195
+ Launch console, press `g` → ConfigView opens.
196
+
197
+ ### Expected
198
+
199
+ - Header line: `~/.config/specialists/user.json` (HOME → `~` substitution; **never** raw `/home/<user>/…`).
200
+ - Specialist list on first row: `●` if override exists, `○` if no override. Selected specialist name in bright SGR.
201
+ - Field table: 28-wide `path` column, `value` column, dim allowed-input hint right-aligned to width.
202
+ - `execution.thinking_level` hint reads: `enum: off|low|medium|high | null`
203
+ - `skills.paths` hint: `string[]` (no `| null` suffix — non-nullable array)
204
+ - `execution.fallback_models` hint: `string[] | null`
205
+ - Inherit values display as `inherit`, null as `inherit`.
206
+ - KeyBar reads: `↑↓ field [/] specialist e edit u undo b $EDITOR r refresh ⌫ back q quit`.
207
+ - `[` / `]` cycles specialist (wraps at boundaries).
208
+ - `↑↓` cycles fields within the selected specialist.
209
+ - `r` reloads the file (picks up external edits).
210
+ - On parse error: validation errors list rendered dim; no values logged.
211
+
212
+ ### Observed
213
+
214
+ - [ ] PASS / [ ] FAIL — Header path shows `~/.config/specialists/user.json` (NO `/home/`)
215
+ - [ ] PASS / [ ] FAIL — `●` / `○` glyphs distinguish override vs inherit specialists
216
+ - [ ] PASS / [ ] FAIL — `[`/`]` cycle specialists
217
+ - [ ] PASS / [ ] FAIL — `↑↓` cycle fields
218
+ - [ ] PASS / [ ] FAIL — `thinking_level` hint format matches `enum: off|low|medium|high | null`
219
+ - [ ] PASS / [ ] FAIL — `skills.paths` hint = `string[]` (no `| null`)
220
+ - [ ] PASS / [ ] FAIL — `inherit` rendered for null/unset values
221
+ - [ ] PASS / [ ] FAIL — `r` refresh works
222
+ - [ ] PASS / [ ] FAIL — No raw `/home/<user>/` substring anywhere in view
223
+
224
+ Follow-up beads: _____
225
+
226
+ ---
227
+
228
+ ## §7 ConfigView inline edit — safe field round-trip
229
+
230
+ Phase contract: `.7` (edit + undo + mtime preflight), `.5` (NDJSON `write_global_config`).
231
+
232
+ **Safe target field:** `executor.notes_mode` (enum: `full-trail` | `final-only` | `null`). Picked because (a) enum, easy to verify, (b) cheap to flip back-and-forth without bricking any other surface. **AVOID** `execution.model` — flipping the global model can break all specialists.
233
+
234
+ ### Setup
235
+
236
+ Snapshot current value before editing (for restore safety):
237
+
238
+ ```bash
239
+ cp ~/.config/specialists/user.json /tmp/user-pre-walkthrough.json
240
+ jq '.specialists.executor.notes_mode' ~/.config/specialists/user.json
241
+ ```
242
+
243
+ ### Walkthrough
244
+
245
+ 1. `g` → ConfigView, `[/]` to executor, `↑↓` to the `notes_mode` field.
246
+ 2. Press `e` → edit prompt appears: ` edit > _`.
247
+ 3. Type `final-only` and press `↵`.
248
+ 4. Confirm file changed:
249
+ ```bash
250
+ jq '.specialists.executor.notes_mode' ~/.config/specialists/user.json
251
+ ```
252
+ 5. Press `u` → undo pushes previous raw back. Confirm:
253
+ ```bash
254
+ jq '.specialists.executor.notes_mode' ~/.config/specialists/user.json
255
+ ```
256
+ 6. Press `e` again, type invalid value (e.g. `nonsense`), press `↵`. Expect error line ` ! <message>` to render below the field row; file on disk unchanged.
257
+ 7. `Esc` cancels edit; buffer cleared.
258
+ 8. Press `b` → spawns `$EDITOR ~/.config/specialists/user.json` (or `vi` fallback). Quit editor, console resumes.
259
+
260
+ ### Expected
261
+
262
+ - Empty / `null` / `inherit` → field value cleared to null.
263
+ - `true`/`false` → boolean coerce.
264
+ - Integer/float → numeric coerce.
265
+ - Enum match → exact-match required.
266
+ - Comma- or bracket-list → array coerce.
267
+ - mtime preflight: if file changed on disk between read and write → returns `{ok:false, errorClass:'mtime_mismatch'}`; console renders the error inline.
268
+ - Undo stack capped at 5; oldest discarded.
269
+ - All write failures → single NDJSON line on stderr: `op:'write_global_config'`, `errorClass:<code>`, **no value, no path beyond `~/.config/…`**.
270
+
271
+ ### Observed
272
+
273
+ - [ ] PASS / [ ] FAIL — `e` opens edit prompt
274
+ - [ ] PASS / [ ] FAIL — Enum value commits to disk (verify with `jq`)
275
+ - [ ] PASS / [ ] FAIL — `u` reverts to prior value (verify with `jq`)
276
+ - [ ] PASS / [ ] FAIL — Invalid value shows `! <message>`, no on-disk change
277
+ - [ ] PASS / [ ] FAIL — `Esc` cancels edit
278
+ - [ ] PASS / [ ] FAIL — `b` opens `$EDITOR` and resumes after quit
279
+ - [ ] PASS / [ ] FAIL — No raw value text in stderr NDJSON
280
+
281
+ ### Restore safety check
282
+
283
+ ```bash
284
+ diff -u /tmp/user-pre-walkthrough.json ~/.config/specialists/user.json
285
+ ```
286
+
287
+ If diff is non-empty after walking through, copy back:
288
+
289
+ ```bash
290
+ cp /tmp/user-pre-walkthrough.json ~/.config/specialists/user.json
291
+ ```
292
+
293
+ Follow-up beads: _____
294
+
295
+ ---
296
+
297
+ ## §8 KeyBar context-sensitivity + SIGWINCH sweep
298
+
299
+ Phase contract: `theme.ts:renderKeyBar`, `components.ts` key dispatch.
300
+
301
+ ### Walkthrough
302
+
303
+ Visit each view in turn and confirm the KeyBar matches the advertised keys.
304
+
305
+ | View | Expected KeyBar (from `theme.ts:341`) |
306
+ |---|---|
307
+ | ps | `↑↓ nav ↵ feed r result i inspect b bead d diff g config h history a all / filter tab repo q quit` |
308
+ | feed | `↑↓ scroll PgUp/PgDn page f follow:<on\|off> t <legacy\|forensic> ⌫ back g/G top/end q quit` |
309
+ | bead | `↑↓ scroll PgUp/PgDn page ⌫ back g/G top/end q quit` |
310
+ | diff | `↑↓ nav ↵ open file r refresh ⌫ back q quit` |
311
+ | config | `↑↓ field [/] specialist e edit u undo b $EDITOR r refresh ⌫ back q quit` |
312
+ | job / result / other | `↑↓ scroll ⌫ back g/G top/end q quit` |
313
+
314
+ Then trigger a SIGWINCH-driven resize (drag terminal). KeyBar should re-truncate to fit width via `truncateToWidth`.
315
+
316
+ ### Observed
317
+
318
+ - [ ] PASS / [ ] FAIL — ps KeyBar matches
319
+ - [ ] PASS / [ ] FAIL — feed KeyBar matches; follow label flips with `f`
320
+ - [ ] PASS / [ ] FAIL — feed `t` label flips with current source
321
+ - [ ] PASS / [ ] FAIL — bead KeyBar matches
322
+ - [ ] PASS / [ ] FAIL — diff KeyBar matches
323
+ - [ ] PASS / [ ] FAIL — config KeyBar matches
324
+ - [ ] PASS / [ ] FAIL — Resize re-truncates KeyBar without overflow
325
+
326
+ Follow-up beads: _____
327
+
328
+ ---
329
+
330
+ ## §9 NDJSON stderr sweep — forbidden-substring grep
331
+
332
+ Phase contract: `.5` (NDJSON envelope), `.11` (telemetry redaction matrix).
333
+
334
+ ### Setup
335
+
336
+ Launch console with stderr captured. Drive through every view (ps → feed → t toggle → ⌫ → bead → ⌫ → diff → drill into a file → ⌫ → config → cycle a few specialists → quit). Force at least one failure path if possible (e.g. rename `bd` on PATH transiently, or pass an unreadable file to `~/.config/specialists/user.json`).
337
+
338
+ ```bash
339
+ ./sp console 2>/tmp/sp-console-stderr.ndjson
340
+ # Quit with q
341
+ ls -lh /tmp/sp-console-stderr.ndjson
342
+ ```
343
+
344
+ ### Forbidden substring grep
345
+
346
+ ```bash
347
+ echo "== forbidden substrings =="
348
+ for tok in '/home/' '/Users/' 'anthropic/' 'openai-codex/' 'payload' 'stdout' 'stderr' 'prompt' 'model_output' 'tool_call_id' 'raw_command'; do
349
+ hits=$(grep -c "$tok" /tmp/sp-console-stderr.ndjson 2>/dev/null || echo 0)
350
+ echo "$tok: $hits"
351
+ done
352
+ ```
353
+
354
+ ### Expected
355
+
356
+ - All counts = 0 (PASS).
357
+ - Every line is valid JSON with allowed keys ONLY: `{ts, component:'sp-console', view, op, exitCode, durationMs, errorClass}`.
358
+ - Duplicate (view, op, errorClass) tuples rate-limited to one line per session.
359
+
360
+ ### Verification
361
+
362
+ ```bash
363
+ echo "== shape =="
364
+ jq -c 'keys|sort' /tmp/sp-console-stderr.ndjson 2>/dev/null | sort -u
365
+ # All rows should print: ["component","durationMs","errorClass","exitCode","op","ts","view"]
366
+ ```
367
+
368
+ ### Observed
369
+
370
+ - [x] PASS — **happy-path automated probe verified on `2026-06-17`**. Command: `echo -n "q" | timeout 2 ./sp console 2>/tmp/sp-console-stderr.ndjson`. Resulting stderr = **0 bytes**. All 11 forbidden substrings = 0 hits. Exit code 0.
371
+ - [ ] OPERATOR — Every line parses as JSON (vacuously true on empty file; operator pass should drive a failure path to populate at least one line and re-verify)
372
+ - [ ] OPERATOR — Every line has only the 7 allowed keys (idem)
373
+ - [ ] OPERATOR — Duplicate errorClass rate-limited (operator: rename `bd` on PATH transiently, force `bd_show` failure, drive `b` 50× and confirm exactly one line lands)
374
+
375
+ Follow-up beads: _____
376
+
377
+ ---
378
+
379
+ ## Walkthrough summary
380
+
381
+ | Section | PASS / FAIL | Follow-up beads |
382
+ |---|---|---|
383
+ | §1 Build + launch | **PASS** (programmatic) | unitAI-ctb4u.23 (help-text drift) |
384
+ | §2 ProcessView resize | OPERATOR | |
385
+ | §3 BeadView | OPERATOR | |
386
+ | §4 FeedView + FeedSource | OPERATOR | |
387
+ | §5 DiffView | OPERATOR | |
388
+ | §6 ConfigView read | OPERATOR | |
389
+ | §7 ConfigView edit | OPERATOR | |
390
+ | §8 KeyBar sweep | OPERATOR | |
391
+ | §9 NDJSON redaction | **PASS** (happy path) / OPERATOR (failure paths) | |
392
+
393
+ **Overall verdict:** [ ] PASS / [ ] FAIL — _operator to fill after interactive pass_
394
+
395
+ **Filed regressions (discovered-from `unitAI-ctb4u.18`):**
396
+
397
+ - `unitAI-ctb4u.23` — `sp console --help` text is v1, missing v2 keys b/d/g/t/e/u/[/]/f.
398
+
399
+ **Operator name + date:** _____
400
+
401
+ ---
402
+
403
+ ## What the bead author verified (automated portion)
404
+
405
+ The author of this doc (`unitAI-ctb4u.18` claimant) programmatically verified:
406
+
407
+ 1. **§1 Build + launch.** `bun build --compile --target=bun src/index.ts --outfile=./sp` → 103 MB ELF64. `./sp --help` lists `console`. `./sp console --help` exits 0 with stale v1 text → filed as `unitAI-ctb4u.23`.
408
+ 2. **§9 NDJSON happy path.** `echo -n "q" | timeout 2 ./sp console 2>/tmp/sp-console-stderr.ndjson` → stderr 0 bytes, exit 0. All 11 forbidden substrings (`/home/`, `/Users/`, `anthropic/`, `openai-codex/`, `payload`, `stdout`, `stderr`, `prompt`, `model_output`, `tool_call_id`, `raw_command`) = 0 hits.
409
+
410
+ The remaining sections (§2 — §8 and §9 failure paths) require an interactive TTY drive: real arrow-key sweeps, real terminal resize (SIGWINCH), real `$EDITOR` spawn, and a deliberate `bd_show`/`git_diff` failure injection. These are listed as OPERATOR in the summary table above and are the responsibility of the operator pass that closes the bead's full SUCCESS contract.