@jaggerxtrm/specialists 3.17.0 → 3.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +268 -134
- package/config/mandatory-rules/json-only-final-output.md +13 -0
- package/config/mandatory-rules/service-skills-diff-scan-mandatory.md +26 -0
- package/config/mandatory-rules/service-skills-gitnexus-triage.md +5 -0
- package/config/skills/setup-specialists/SKILL.md +556 -0
- package/config/skills/specialists-creator/SKILL.md +132 -4
- package/config/skills/specialists-creator/scripts/audit-spec-uniformity.mjs +1 -1
- package/config/specialists/bare.specialist.json +3 -3
- package/config/specialists/changelog-drafter.specialist.json +5 -4
- package/config/specialists/changelog-keeper.specialist.json +7 -6
- package/config/specialists/debugger.specialist.json +2 -2
- package/config/specialists/executor.specialist.json +2 -2
- package/config/specialists/explorer.specialist.json +4 -4
- package/config/specialists/memory-processor.specialist.json +3 -3
- package/config/specialists/node-coordinator.specialist.json +3 -3
- package/config/specialists/obligations-scanner.specialist.json +67 -17
- package/config/specialists/overthinker.specialist.json +3 -3
- package/config/specialists/planner.specialist.json +4 -4
- package/config/specialists/quant-methodologist.specialist.json +145 -0
- package/config/specialists/quant-researcher.specialist.json +144 -0
- package/config/specialists/researcher.specialist.json +5 -5
- package/config/specialists/reviewer.specialist.json +1 -1
- package/config/specialists/seconder.specialist.json +2 -2
- package/config/specialists/security-auditor.specialist.json +2 -2
- package/config/specialists/service-skills-sync.specialist.json +90 -75
- package/config/specialists/specialists-creator.specialist.json +4 -4
- package/config/specialists/sync-docs.specialist.json +4 -4
- package/config/specialists/test-engineer.specialist.json +3 -3
- package/config/specialists/test-runner.specialist.json +7 -7
- package/config/specialists/transcriber.specialist.json +3 -3
- package/config/specialists/xt-merge.specialist.json +4 -4
- package/dist/asset-contract.json +21 -2
- package/dist/index.js +25704 -16376
- package/dist/lib.js +9849 -6147
- package/dist/types/cli/console/components.d.ts +83 -0
- package/dist/types/cli/console/components.d.ts.map +1 -0
- package/dist/types/cli/console/config-source.d.ts +58 -0
- package/dist/types/cli/console/config-source.d.ts.map +1 -0
- package/dist/types/cli/console/forensic.d.ts +11 -0
- package/dist/types/cli/console/forensic.d.ts.map +1 -0
- package/dist/types/cli/console/git.d.ts +28 -0
- package/dist/types/cli/console/git.d.ts.map +1 -0
- package/dist/types/cli/console/help.d.ts +2 -0
- package/dist/types/cli/console/help.d.ts.map +1 -0
- package/dist/types/cli/console/log.d.ts +13 -0
- package/dist/types/cli/console/log.d.ts.map +1 -0
- package/dist/types/cli/console/repo-config.d.ts +26 -0
- package/dist/types/cli/console/repo-config.d.ts.map +1 -0
- package/dist/types/cli/console/repo-discovery.d.ts +12 -0
- package/dist/types/cli/console/repo-discovery.d.ts.map +1 -0
- package/dist/types/cli/console/runtime.d.ts +12 -0
- package/dist/types/cli/console/runtime.d.ts.map +1 -0
- package/dist/types/cli/console/subscribe-prototype.d.ts +18 -0
- package/dist/types/cli/console/subscribe-prototype.d.ts.map +1 -0
- package/dist/types/cli/console/theme.d.ts +91 -0
- package/dist/types/cli/console/theme.d.ts.map +1 -0
- package/dist/types/cli/console/types.d.ts +231 -0
- package/dist/types/cli/console/types.d.ts.map +1 -0
- package/dist/types/cli/console/view-model.d.ts +252 -0
- package/dist/types/cli/console/view-model.d.ts.map +1 -0
- package/dist/types/cli/console.d.ts +2 -0
- package/dist/types/cli/console.d.ts.map +1 -0
- package/dist/types/cli/db.d.ts.map +1 -1
- package/dist/types/cli/doctor.d.ts.map +1 -1
- package/dist/types/cli/edit.d.ts.map +1 -1
- package/dist/types/cli/epic.d.ts.map +1 -1
- package/dist/types/cli/feed.d.ts.map +1 -1
- package/dist/types/cli/forensic.d.ts +2 -0
- package/dist/types/cli/forensic.d.ts.map +1 -0
- package/dist/types/cli/format-helpers.d.ts +4 -2
- package/dist/types/cli/format-helpers.d.ts.map +1 -1
- package/dist/types/cli/help.d.ts.map +1 -1
- package/dist/types/cli/init.d.ts +10 -0
- package/dist/types/cli/init.d.ts.map +1 -1
- package/dist/types/cli/list.d.ts.map +1 -1
- package/dist/types/cli/log.d.ts.map +1 -1
- package/dist/types/cli/metrics.d.ts +2 -0
- package/dist/types/cli/metrics.d.ts.map +1 -0
- package/dist/types/cli/ps.d.ts.map +1 -1
- package/dist/types/cli/result.d.ts.map +1 -1
- package/dist/types/cli/run.d.ts +1 -0
- package/dist/types/cli/run.d.ts.map +1 -1
- package/dist/types/cli/script.d.ts +3 -0
- package/dist/types/cli/script.d.ts.map +1 -1
- package/dist/types/cli/serve.d.ts.map +1 -1
- package/dist/types/cli/setup.d.ts +19 -1
- package/dist/types/cli/setup.d.ts.map +1 -1
- package/dist/types/cli/status.d.ts.map +1 -1
- package/dist/types/cli/version-check.d.ts +1 -0
- package/dist/types/cli/version-check.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/pi/session.d.ts +11 -1
- package/dist/types/pi/session.d.ts.map +1 -1
- package/dist/types/server.d.ts +15 -0
- package/dist/types/server.d.ts.map +1 -1
- package/dist/types/specialist/benchmarks.d.ts +37 -0
- package/dist/types/specialist/benchmarks.d.ts.map +1 -0
- package/dist/types/specialist/chain-identity.d.ts +7 -1
- package/dist/types/specialist/chain-identity.d.ts.map +1 -1
- package/dist/types/specialist/control.d.ts.map +1 -1
- package/dist/types/specialist/forensic-events.d.ts +138 -0
- package/dist/types/specialist/forensic-events.d.ts.map +1 -0
- package/dist/types/specialist/forensic-renderer.d.ts +34 -0
- package/dist/types/specialist/forensic-renderer.d.ts.map +1 -0
- package/dist/types/specialist/git-diff-evidence.d.ts +28 -0
- package/dist/types/specialist/git-diff-evidence.d.ts.map +1 -0
- package/dist/types/specialist/global-config.d.ts +389 -0
- package/dist/types/specialist/global-config.d.ts.map +1 -0
- package/dist/types/specialist/launch.d.ts +1 -0
- package/dist/types/specialist/launch.d.ts.map +1 -1
- package/dist/types/specialist/live-aggregates.d.ts +46 -0
- package/dist/types/specialist/live-aggregates.d.ts.map +1 -0
- package/dist/types/specialist/loader.d.ts +50 -1
- package/dist/types/specialist/loader.d.ts.map +1 -1
- package/dist/types/specialist/model-chain.d.ts +7 -0
- package/dist/types/specialist/model-chain.d.ts.map +1 -0
- package/dist/types/specialist/model-probes.d.ts +28 -0
- package/dist/types/specialist/model-probes.d.ts.map +1 -0
- package/dist/types/specialist/node-contract.d.ts +18 -18
- package/dist/types/specialist/node-supervisor.d.ts.map +1 -1
- package/dist/types/specialist/observability-db.d.ts +1 -1
- package/dist/types/specialist/observability-db.d.ts.map +1 -1
- package/dist/types/specialist/observability-sqlite.d.ts +25 -0
- package/dist/types/specialist/observability-sqlite.d.ts.map +1 -1
- package/dist/types/specialist/preset-resolver.d.ts +56 -0
- package/dist/types/specialist/preset-resolver.d.ts.map +1 -0
- package/dist/types/specialist/prometheus-projection.d.ts +25 -0
- package/dist/types/specialist/prometheus-projection.d.ts.map +1 -0
- package/dist/types/specialist/runner.d.ts +26 -1
- package/dist/types/specialist/runner.d.ts.map +1 -1
- package/dist/types/specialist/schema.d.ts +163 -54
- package/dist/types/specialist/schema.d.ts.map +1 -1
- package/dist/types/specialist/script-runner.d.ts +5 -1
- package/dist/types/specialist/script-runner.d.ts.map +1 -1
- package/dist/types/specialist/snapshot-diff.d.ts +8 -0
- package/dist/types/specialist/snapshot-diff.d.ts.map +1 -0
- package/dist/types/specialist/source-queue.d.ts +13 -0
- package/dist/types/specialist/source-queue.d.ts.map +1 -0
- package/dist/types/specialist/supervisor.d.ts +15 -1
- package/dist/types/specialist/supervisor.d.ts.map +1 -1
- package/dist/types/specialist/timeline-events.d.ts +68 -1
- package/dist/types/specialist/timeline-events.d.ts.map +1 -1
- package/dist/types/tools/specialist/resume_specialist.tool.d.ts +4 -4
- package/dist/types/tools/specialist/specialist_status.tool.d.ts +1 -1
- package/dist/types/tools/specialist/steer_specialist.tool.d.ts +4 -4
- package/dist/types/tools/specialist/use_specialist.tool.d.ts +16 -16
- package/docs/ARCHITECTURE.md +1176 -0
- package/docs/TODO.md +9 -0
- package/docs/architecture.md +11 -0
- package/docs/archive/2026-03-13-bd-decision-context-template-plan.md +96 -0
- package/docs/archive/AGENT-HANDOFF.md +351 -0
- package/docs/archive/PARITY-ANALYSIS.md +296 -0
- package/docs/archive/SPECIALISTS_REFACTOR.md.md +30 -0
- package/docs/archive/cc-programmatic.md +216 -0
- package/docs/archive/claude-agent-sdk.md +594 -0
- package/docs/archive/decision-specialist-directory.md +41 -0
- package/docs/archive/discoveries.md +148 -0
- package/docs/archive/executor-benchmark-protocol.md +198 -0
- package/docs/archive/future-features.md +66 -0
- package/docs/archive/gzrx-completion-critique.md +183 -0
- package/docs/archive/gzrx-research-notes.md +401 -0
- package/docs/archive/gzrx-tool-catalog.md +760 -0
- package/docs/archive/iron-review-hardening-qa-chain-substrate.md +322 -0
- package/docs/archive/iron-review-hardening.html +1004 -0
- package/docs/archive/issuetracking.md +312 -0
- package/docs/archive/qa-v3.0.2.md +220 -0
- package/docs/archive/restructure.md +231 -0
- package/docs/archive/script-specialists.md +1254 -0
- package/docs/archive/spec-v3.md +792 -0
- package/docs/archive/specialist-stats.md +127 -0
- package/docs/archive/specialists-friction-audit.md +1347 -0
- package/docs/archive/specialists-runtime-critique.md +170 -0
- package/docs/archive/specialists-service-evaluation.md +713 -0
- package/docs/archive/specialists-substrate-alignment.md +255 -0
- package/docs/archive/substrate-review.md +1288 -0
- package/docs/archive/test-writer-specialist.md +254 -0
- package/docs/archive/using-specialists-v3-improvements-2026-05-09.md +600 -0
- package/docs/archive/xtrm-specialists-analysis.md +314 -0
- package/docs/authoring.md +701 -0
- package/docs/background-jobs.md +203 -0
- package/docs/bare-specialists.md +83 -0
- package/docs/benchmarks/executor-benchmark-runner.md +66 -0
- package/docs/bootstrap.md +161 -0
- package/docs/cli-reference.md +1645 -0
- package/docs/deploying-alongside.md +155 -0
- package/docs/design/README.md +36 -0
- package/docs/design/darth-feedor-migration.md +290 -0
- package/docs/design/roadmap/README.md +32 -0
- package/docs/design/roadmap/chain-templates/README.md +146 -0
- package/docs/design/roadmap/chain-templates/code-quick.formula.json +27 -0
- package/docs/design/roadmap/chain-templates/code-standard.formula.json +126 -0
- package/docs/design/roadmap/chain-templates/code-with-advisors.formula.json +128 -0
- package/docs/design/roadmap/chain-templates/code-with-tests.formula.json +76 -0
- package/docs/design/roadmap/chain-templates/debug.formula.json +128 -0
- package/docs/design/roadmap/chain-templates/doc-sync.formula.json +28 -0
- package/docs/design/roadmap/chain-templates/memory-hygiene.formula.json +27 -0
- package/docs/design/roadmap/chain-templates/planning.formula.json +27 -0
- package/docs/design/roadmap/chain-templates/premortem.formula.json +26 -0
- package/docs/design/roadmap/chain-templates/release-prep.formula.json +36 -0
- package/docs/design/roadmap/chain-templates/research-only.formula.json +28 -0
- package/docs/design/roadmap/chain-templates/restitch.formula.json +125 -0
- package/docs/design/roadmap/chain-templates/security-deep.formula.json +161 -0
- package/docs/design/roadmap/chain-templates/test-only.formula.json +52 -0
- package/docs/design/roadmap/chain-templates/triage.formula.json +35 -0
- package/docs/design/roadmap/history/handoff-from-substrate-design.md +87 -0
- package/docs/design/roadmap/history/substrate-reconciliation.md +105 -0
- package/docs/design/roadmap/specialists-roadmap.md +1193 -0
- package/docs/design/sp-console-subscribe-via-materializer.md +231 -0
- package/docs/design/sp-console-tui-mock-v2.html +293 -0
- package/docs/design/sp-console-tui-mock.html +120 -0
- package/docs/design/sp-console-tui.md +340 -0
- package/docs/design/specialist-agentops-suite.md +323 -0
- package/docs/design/substrate/channels.md +14 -0
- package/docs/design/substrate/devops-platform-engineering-prd.md +446 -0
- package/docs/design/substrate/html-design-example.md +339 -0
- package/docs/design/xtrm-tiers-architecture.svg +132 -0
- package/docs/devops/dependency-verdict-materialization.md +46 -0
- package/docs/epic-readiness.md +75 -0
- package/docs/examples/mercury-atomic-summarizer.specialist.json +26 -0
- package/docs/examples/smoke-echo-text-expected-keys.specialist.json +25 -0
- package/docs/examples/smoke-echo.specialist.json +25 -0
- package/docs/features.md +1577 -0
- package/docs/hooks.md +81 -0
- package/docs/installation.md +142 -0
- package/docs/manifest.md +184 -0
- package/docs/mcp-servers.md +73 -0
- package/docs/mcp-tools.md +71 -0
- package/docs/nodes.md +231 -0
- package/docs/observability-metrics.md +152 -0
- package/docs/operator/sp-console-v2-walkthrough.md +410 -0
- package/docs/overrides-guide.md +306 -0
- package/docs/pi-rpc-boundary.md +118 -0
- package/docs/pi-session.md +195 -0
- package/docs/release.md +22 -0
- package/docs/skills.md +132 -0
- package/docs/specialists/handoff-schema.md +181 -0
- package/docs/specialists-catalog.md +99 -0
- package/docs/specialists-service-install.md +226 -0
- package/docs/specialists-service.md +363 -0
- package/docs/surface-ownership.md +138 -0
- package/docs/upgrade-notes/kan-90-global-user-config.md +114 -0
- package/docs/upgrade-notes/kan-91-expanded-overrides.md +261 -0
- package/docs/workflow.md +114 -0
- package/docs/worktree.md +71 -0
- package/docs/worktrees.md +309 -0
- package/package.json +6 -3
|
@@ -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.
|