trans-genderian-orchestra 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +392 -0
  2. package/assets/AGENTS.fragment.md +5 -0
  3. package/assets/agents/bernstein.md +118 -0
  4. package/assets/agents/cobain.md +22 -0
  5. package/assets/agents/dylan.md +52 -0
  6. package/assets/agents/grohl.md +22 -0
  7. package/assets/agents/horowitz.md +109 -0
  8. package/assets/agents/nas.md +45 -0
  9. package/assets/agents/nirvana.md +33 -0
  10. package/assets/agents/novoselic.md +22 -0
  11. package/assets/concision-instruction.md +13 -0
  12. package/assets/house-style.md +6 -0
  13. package/assets/presets.json +26 -0
  14. package/assets/skills/bmad-build-auto/SKILL.md +34 -0
  15. package/assets/skills/bmad-deep-recon/SKILL.md +42 -0
  16. package/assets/skills/code-review/SKILL.md +74 -0
  17. package/assets/skills/diagnosing-bugs/SKILL.md +96 -0
  18. package/assets/skills/grilling/SKILL.md +28 -0
  19. package/assets/skills/implement/SKILL.md +14 -0
  20. package/assets/skills/receiving-code-review/SKILL.md +53 -0
  21. package/assets/skills/tdd/SKILL.md +32 -0
  22. package/assets/skills/tgo-setup/SKILL.md +28 -0
  23. package/assets/skills/to-questionnaire/SKILL.md +29 -0
  24. package/assets/skills/to-tickets/SKILL.md +77 -0
  25. package/assets/skills/verification-planning/SKILL.md +52 -0
  26. package/assets/skills/wayfinder/SKILL.md +88 -0
  27. package/assets/skills/wizard/SKILL.md +17 -0
  28. package/package.json +29 -0
  29. package/schema/tgo.config.schema.json +135 -0
  30. package/src/background.ts +102 -0
  31. package/src/board.ts +332 -0
  32. package/src/build.ts +396 -0
  33. package/src/concision.ts +87 -0
  34. package/src/config.ts +146 -0
  35. package/src/deps.ts +145 -0
  36. package/src/fit.ts +48 -0
  37. package/src/install.ts +359 -0
  38. package/src/magic-context.ts +94 -0
  39. package/src/permissions.ts +184 -0
  40. package/src/plugin.ts +279 -0
  41. package/src/presets.ts +63 -0
  42. package/src/session.ts +58 -0
  43. package/src/setup.ts +99 -0
  44. package/src/validate.ts +219 -0
  45. package/src/watchdog.ts +319 -0
package/README.md ADDED
@@ -0,0 +1,392 @@
1
+ # trans-genderian-orchestra
2
+
3
+ TGO — a thin multi-agent orchestration plugin for [OpenCode](https://opencode.ai).
4
+
5
+ Configuration-first: routing, delegation, and seat behavior live in config (agent prompt files, permission graph, presets); a thin plugin core enforces lifecycle and state only.
6
+
7
+ ## Layout
8
+
9
+ ```
10
+ src/
11
+ plugin.ts thin core: loads, validates config, registers the hook slots
12
+ (board, concision, preset config hook, session reconciliation,
13
+ task-fit rejection)
14
+ config.ts zod schema for plugin options + <1000-token seat-prompt budget
15
+ build.ts template renderer: folds house-style, AGENTS merge, global config merge
16
+ permissions.ts frontmatter parser + per-seat permission-graph report
17
+ board.ts Background Job Board (hook #1): beads renderer + thin live-state shim
18
+ concision.ts Always-on concision (hook #4): instruction builder + per-turn system append
19
+ session.ts Session reconciliation (hook #2): live-state shim sync from session events
20
+ fit.ts Task-fit rejection (hook #3): lane-rejection → REROUTE-NOT-RETRY signal
21
+ setup.ts Per-repo setup auto-trigger (session.created): bd init + AGENTS fragment
22
+ + bd setup opencode managed Beads block, idempotent + no-clobber
23
+ install.ts installer: builds seats + AGENTS fragment + global config + dependency
24
+ auto-install to config dir
25
+ deps.ts pinned dependency registry (beads/AFT/magic-context/context7): injectable
26
+ presence detection + install runner
27
+ validate.ts build-time validation CLI (rendered budget + permission graph)
28
+ test/
29
+ config.test.ts
30
+ build.test.ts
31
+ permissions.test.ts
32
+ board.test.ts
33
+ concision.test.ts
34
+ session.test.ts
35
+ fit.test.ts
36
+ deps.test.ts
37
+ setup.test.ts
38
+ assets/
39
+ agents/ seat prompt templates (bernstein, horowitz, nas, dylan, nirvana,
40
+ cobain, grohl, novoselic) — 4-block anatomy, house-style fold slot,
41
+ permission-graph frontmatter
42
+ house-style.md 3-axis style fragment folded into subagent seats at build time
43
+ concision-instruction.md runtime house-style payload appended to the primary loop
44
+ AGENTS.fragment.md thin always-on advice layer merged into global AGENTS.md
45
+ presets.json seat→model maps (balanced/cheap/frontier) — data, not code
46
+ skills/
47
+ tgo-setup/SKILL.md non-load-bearing setup skill (auto-triggered; manual path + docs)
48
+ <13 bundle skills>/SKILL.md the G1 FINAL BUNDLE — adapted, token-pruned, advisory
49
+ (see docs/spec/skill-candidates.md); per-seat `permission.skill`
50
+ grants in seat frontmatter
51
+ schema/
52
+ tgo.config.schema.json JSON schema for plugin options
53
+ ```
54
+
55
+ ## Install (development)
56
+
57
+ The package is loaded by opencode in one of two ways:
58
+
59
+ 1. **Local plugin** — symlink/copy `src/plugin.ts` into `~/.config/opencode/plugins/`.
60
+ Seat prompts are auto-discovered from `~/.config/opencode/agent/` (opencode scans
61
+ both `agent/` and `agents/`).
62
+ 2. **npm** — publish, then add `"trans-genderian-orchestra"` to the `plugin` array in
63
+ `opencode.jsonc`. Dependencies are installed automatically by opencode.
64
+
65
+ ```bash
66
+ bun install
67
+ bun run validate # schema + presets + rendered seat-prompt budget
68
+ bun run build # render seat prompts; pass --outDir <dir> to write
69
+ bun test # budget + schema + build tests
70
+ bunx tsc --noEmit # typecheck
71
+ bun run setup --configDir <dir> # build + install (defaults to ~/.config/opencode/); --deps auto|check|skip
72
+ ```
73
+
74
+ `bun run setup` self-registers the plugin by adding `trans-genderian-orchestra` to the
75
+ `plugin` array of the global `opencode.jsonc` **by default** — a blank-slate install ends up
76
+ with the plugin loaded, not just config files. Opt out with `--no-register` (e.g. wiring the
77
+ plugin manually), or pass `--register <module>` to register a different module/path.
78
+ Idempotent — never duplicates.
79
+
80
+ ## Dependencies (auto-installed)
81
+
82
+ TGO pins a small set of engine dependencies and the installer **checks for each and
83
+ fetches/installs it if missing** as part of setup:
84
+
85
+ - **beads** (`bd` CLI) — work-unit store + job-board engine; Bernstein is the single writer.
86
+ - **AFT** — symbol-aware code tools (`aft_*`/`ast_grep_*`), Dylan's motor lane.
87
+ - **magic-context** — long-term memory + cross-session recall (`ctx_*`). Fully configured
88
+ by the installer: the plugin entry is registered on **both** surfaces — `opencode.jsonc`
89
+ (server: `ctx_*` tools, the historian) and `tui.json`/`tui.jsonc` (TUI: the sidebar) —
90
+ `~/.config/cortexkit/magic-context.jsonc` is written with `historian.model` (from the
91
+ active preset's Bernstein model), and opencode's built-in compaction is turned off
92
+ (magic-context disables itself on conflict otherwise — it owns context management end to
93
+ end). A model you picked interactively is never clobbered.
94
+ - **context7** — the one external MCP for docs lookup (`context7_*`), Nas + Dylan. Its own
95
+ `npx ctx7 setup --opencode` is an interactive TUI (mode picker + browser OAuth) that can't
96
+ run under a non-interactive installer, so TGO registers the **hosted remote MCP server**
97
+ directly into `opencode.jsonc` (`mcp.context7 = { type: "remote", url: ... }`) — the hosted
98
+ endpoint answers `initialize`/`tools/list` with no local auth. Skipped under `--no-register`.
99
+
100
+ Dependency behavior is controlled by `--deps` on `bun run setup`:
101
+
102
+ - `--deps auto` (default) — check presence; install anything missing.
103
+ - `--deps check` — report presence only, run no installs.
104
+ - `--deps skip` — leave the dependency layer completely alone.
105
+
106
+ Background subagents (`task` with `background: true`, used by the nirvana band's parallel
107
+ lens spawns) need `OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true` at opencode start.
108
+ opencode has no `env` config key and a plugin factory is too late (RuntimeFlags are
109
+ snapshotted at startup), so the **installer writes the export into your shell startup file**
110
+ (`~/.zshrc`, `~/.bashrc`, or a fish `conf.d` file) as an idempotent marker block — same
111
+ approach as oh-my-opencode-slim. Opt out with `--no-bg`; skip is automatic when the env var
112
+ is already set. Restart opencode after install.
113
+
114
+ TGO ships a **curated advisory skill bundle** (13 skills / 15 per-seat grants — wayfinder,
115
+ grilling, to-tickets, bmad-build-auto, verification-planning, diagnosing-bugs,
116
+ to-questionnaire, wizard, code-review, bmad-deep-recon, implement, tdd,
117
+ receiving-code-review) into the config dir's `skills/`; per-seat `permission.skill` grants
118
+ go in seat frontmatter. Skills are advisory only — nothing load-bearing. External suites
119
+ (Matt's engineering skills, superpowers, gsd) are **never disabled** — TGO enables its
120
+ per-seat grants for them when present.
121
+
122
+ ## Per-repo setup (auto-triggered)
123
+
124
+ The plugin watches `session.created` (primary sessions only) and runs a **per-repo setup**
125
+ on first contact with a repo, mirroring `bd prime`'s auto-initialization:
126
+
127
+ - `.beads/` initialized via `bd init` (the `bd` CLI is auto-installed if missing, see
128
+ Dependencies above; `bd init` creates the Dolt work-unit store + a managed Beads block).
129
+ - The official `bd setup opencode` managed Beads block is installed.
130
+ - TGO's thin AGENTS.md advice fragment is merged (no-clobber).
131
+
132
+ Guardrails: **no-clobber** (existing AGENTS.md/user content is preserved), **idempotent +
133
+ per-repo marker** (a repo with `.beads/` + both AGENTS markers is never re-touched), and
134
+ **granular** (`bd init` only runs when `.beads/` is absent — a partial setup missing only
135
+ the markers skips `bd init` and installs just the missing blocks; `bd init` on an existing
136
+ store aborts with a non-zero exit, so it is never re-run), and
137
+ **zero user input** (defaults: tracker → beads, labels → default triage, monorepo →
138
+ auto-detect). Control it via the plugin config: `setup: { enabled: false }` disables the
139
+ auto-trigger; `setup: { autoInstallBeads: false }` reports a missing `bd` CLI instead of
140
+ installing it. The non-load-bearing `tgo-setup` skill (`skills/tgo-setup/SKILL.md`, copied
141
+ into the config dir at install) documents the same steps and offers the manual path.
142
+
143
+ The build step folds `assets/house-style.md` into every **subagent** seat via the
144
+ `{{TGO_HOUSE_STYLE}}` slot; Bernstein (primary) has no slot — the primary loop gets
145
+ the style at runtime via hook #4 (`experimental.chat.system.transform`, TGO ticket
146
+ tgo-96f.9). The rendered output is what the token budget validates.
147
+
148
+ The fold also carries the **register dial**: the config `register` value
149
+ (`"concise" | "natural"`, default `"concise"`) is rendered into the fragment's
150
+ register line at build time. Dylan self-classifies output class (steps/code →
151
+ concise; voice-forward prose → natural); all other seats stay in the default
152
+ register.
153
+
154
+ ### Verifying the register + concision are live
155
+
156
+ The register dial is a **build-time fold**: check the installed seats
157
+ (`~/.config/opencode/agent/dylan.md`) for the house-style block and the
158
+ "present in *register* mode by default" line — that's the register that took
159
+ effect at install. The runtime concision instruction (the per-turn style layer
160
+ appended to the primary loop, hook #4) is observable live: start opencode with
161
+ `TGO_DEBUG_EVENTS=1` and the log line
162
+ `event concision.appended <session-id> {"register":"concise"}` appears each time
163
+ the instruction is injected into a primary session's system prompt. Absence of
164
+ the line = the hook isn't firing; presence = the toggle is active.
165
+
166
+ ## Permission graph
167
+
168
+ The seat prompts carry the full per-seat permission matrix (capabilities, not
169
+ compliance). Frontmatter is enforced by opencode, not just prompted:
170
+
171
+ - **Bernstein** (primary): `edit`/`grep`/`glob`/`list` denied; `read`/`websearch`/
172
+ `skill` allowed; `bash` = verification allowlist (`git diff/status/log/rev-parse*`
173
+ incl. `git -C <dir>` variants, `bd *`, `head`/`tail`/`echo`, test/typecheck runners)
174
+ with a catch-all `"*": deny`;
175
+ `task` = the four named seats only (`horowitz`/`nas`/`dylan`/`nirvana`), `general`
176
+ excluded.
177
+ - **Horowitz**: read-only investigate allowlist (`git log/show/status/diff/rev-parse/
178
+ merge-base*` incl. `git -C <dir>` variants, `git ls-files`, `echo`, `ls`/`cat`/
179
+ `head`/`tail`/`rg`/`ps`/`lsof`/`wc`/`shasum`, read-only `bd show`/`list`/`ready`/
180
+ `search`), catch-all deny;
181
+ `task` → built-in `explore` only. Include `git rev-parse`/`merge-base`/`echo` because
182
+ compound commands (`&&`, `;`, `||`, `|`) are matched **per segment** — every segment
183
+ of a reviewer's `git log && git rev-parse` chain must be on the allowlist. The
184
+ `git -C <dir>` variants and `git ls-files`/`shasum` cover the real review commands
185
+ seen in the live test-6 run (reviewers run git from the parent dir against the
186
+ target repo, verify file pins with `shasum`, and read the board with `bd show`).
187
+ - **Nas**: `edit`/`bash`/`task` denied entirely; `read`/`grep`/`glob`/`list`,
188
+ `websearch`/`webfetch`, `context7_*`, `ctx_*` (magic-context recall) allowed.
189
+ Websearch is **mandatory** for discovery — `webfetch` fetches only already-known
190
+ URLs, never guessed paths (test-6 showed 0 websearch calls against 155 webfetch /
191
+ 69 errors when the rule was merely advisory).
192
+ - **Dylan** (sole writer): `edit`/`bash` allowed; AFT symbol tools (`aft_*`,
193
+ `ast_grep_*`), `context7_*`, `ctx_*` allowed; `task` → `explore` only.
194
+ - **Nirvana + band members**: tool-less — top-level `"*": deny`. Nirvana's `task`
195
+ allowlist is exactly its three band members; no other subagent is reachable.
196
+
197
+ Step caps: `nas`, `horowitz`, and `dylan` carry `steps: 20` — opencode forces a
198
+ text-only summary when the cap is reached, so a recon/review/implementation session
199
+ that would otherwise exhaust its output budget mid-report (`finish: length`) returns
200
+ a usable partial result instead of an empty handoff. Their seat bodies also mandate
201
+ "never end a turn with no text". (Dylan got the cap after test-6: it ran 99–147
202
+ tool calls in single sessions, and only the watchdog's 20-min wall-clock kill stopped
203
+ it mid-commit.)
204
+
205
+ Rule notes (verified empirically on opencode 1.18.13):
206
+
207
+ - An object allowlist **without** a `"*": deny` catch-all falls through to
208
+ default-allow — every restricted seat carries the catch-all.
209
+ - MCP/custom tools grant by name prefix: `context7_*` (context7 MCP), `aft_*` /
210
+ `ast_grep_*` (AFT), `ctx_*` (magic-context recall).
211
+ - `todowrite: deny` is set **globally** in the installed config (not just per-seat),
212
+ so native todos are unavailable to every seat.
213
+ - All seats pre-allow `doom_loop` (opencode's repeated-failure guard defaults to
214
+ `ask`, which tripped in test-7 when a denied `bash` call repeated and approving
215
+ only allowed that exact call, re-prompting on the next attempt). TGO's own step
216
+ caps + watchdog bound loops, so the prompt was pure friction. TGO also
217
+ pre-approves `external_directory` for the project's worktree family (sibling
218
+ worktrees under the project parent) at plugin load — the Claude-Code
219
+ `additionalDirectories` pattern — so delegated sessions reading adjacent
220
+ worktrees don't surface interactive prompts mid-orchestration. The family is
221
+ resolved from the first non-root candidate among the factory-time
222
+ `project.worktree`, the plugin input's `worktree`, and its `directory`
223
+ (test-9): in TUI runs the project can still be unresolved at plugin init and
224
+ `project.worktree` reads as `/` (global), which used to silently no-op the
225
+ pre-approval and leave every worktree access asking.
226
+
227
+ ## Global config
228
+
229
+ `src/install.ts` writes an `opencode.jsonc` fragment into the config dir that sets:
230
+
231
+ - `subagent_depth: 2` — caps all delegation (orchestrator → specialist → lens).
232
+ - `permission.todowrite: "deny"` — global todo ban.
233
+ - `default_agent: "bernstein"` — new sessions open on the orchestrator instead of
234
+ opencode's built-in `build` agent (verified on 1.18.15: without it the TUI
235
+ selector sorts `build` first and the user must tab to Bernstein every session).
236
+ - `compaction: { auto: false, prune: false }` — written when magic-context is
237
+ installed, so magic-context passes its own conflict gate (it disables itself
238
+ while opencode's built-in compaction is on).
239
+ - `tui.json` / `tui.jsonc` — when magic-context is installed, its plugin entry is
240
+ also registered here, on the **TUI surface**. opencode's TUI loads plugins only
241
+ from `tui.*` files (`TuiConfig.pluginOrigins`), never from `opencode.jsonc`, so
242
+ without this the magic-context sidebar silently never mounts even though the
243
+ server half (`ctx_*` tools, the historian) works. Verified against magic-context
244
+ v0.35.0, which writes both surfaces itself.
245
+
246
+ opencode loads global config files in order `config.json` → `opencode.json` →
247
+ `opencode.jsonc` and merges them with `mergeDeep` (remeda), which **replaces
248
+ arrays**. The last file (`opencode.jsonc`) therefore wins for the `plugin`
249
+ array — that's why TGO writes there: its plugin entry survives next to one owned
250
+ by e.g. AFT (`@cortexkit/aft-opencode@latest`) instead of being clobbered.
251
+ Existing `opencode.json` content is carried forward during the merge.
252
+
253
+ The merge is tolerant: an existing `opencode.jsonc` written as JSONC (comments,
254
+ trailing commas) is parsed leniently and merged without losing user keys; a
255
+ genuinely unparseable file is backed up to `opencode.jsonc.bak` before a fresh
256
+ fragment is written (never silently clobbered).
257
+
258
+ Background subagents (`task` with `background: true`, used by the nirvana band's parallel
259
+ lens spawns) need `OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true` at opencode start; the
260
+ installer writes this to your shell startup file automatically (see the install section).
261
+ The same managed env block also exports `OPENCODE_ENABLE_EXA=true` so opencode's built-in
262
+ `websearch` uses the Exa provider.
263
+
264
+ ### Diagnostics
265
+
266
+ The plugin routes its own status output through `client.app.log()` (service `tgo`, levels
267
+ `info`/`warn`/`error`) — never `console.log`. Verified on opencode 1.18.15: a server
268
+ plugin's `console.log` lands in the TUI's stdout stream and shows up as a stray
269
+ "auto-populated" line in the input box that can't be sent or deleted. `app.log` routes to
270
+ the structured log instead. Event-level tracing is still available via
271
+ `TGO_DEBUG_EVENTS=1` (writes through `app.log`, not the console).
272
+
273
+
274
+ ## Plugin config (options)
275
+
276
+ Options are the second element of the `plugin` array entry
277
+ (`["trans-genderian-orchestra", { ... }]`).
278
+
279
+ - `preset`: `"balanced" | "cheap" | "frontier"` (default `"balanced"`)
280
+ - `register`: `"concise" | "natural"` (default `"concise"`)
281
+ - `presets`: partial override of the built-in seat→model maps (model IDs are
282
+ free-form — presets are data, tolerant of model-name drift)
283
+ - `agentDir`: directory holding seat prompt `.md` files
284
+ - `board`: `{ enabled: boolean (default true), refreshMs: number (default 5000) }` —
285
+ master switch and per-session re-render interval for the Background Job Board
286
+ - `concision`: `{ enabled: boolean (default true) }` — universal off-switch for the
287
+ per-turn house-style injection (hook #4)
288
+ - `setup`: `{ enabled: boolean (default true), autoInstallBeads: boolean (default true) }` —
289
+ per-repo setup auto-trigger (session.created): master switch + whether a missing `bd` CLI
290
+ is auto-installed or reported
291
+ - `watchdog`: `{ enabled: boolean (default true), wallClockMs: number (default 1200000),
292
+ idleMs: number (default 900000), checkMs: number (default 10000) }` — abort delegated
293
+ subagent sessions that stay busy past the wall-clock cap OR sit busy with no tool/message
294
+ activity past the idle cap, then inject a `## WATCHDOG-ABORT` marker into the parent so
295
+ the orchestrator re-dispatches instead of trusting an empty result. Guard against the
296
+ empty-handoff mode (a subagent that stops mid-report) and hung delegations. Both clocks
297
+ measure **awake-time only** (host sleep is detected via wall↔uptime drift and excluded,
298
+ so an overnight laptop sleep doesn't false-abort), idle pauses while a FOREGROUND tool is
299
+ executing in-flight (`tool.execute.before`/`after`), and streaming `message.part.updated`
300
+ events refresh the idle clock mid-generation. **Background-intent tools**
301
+ (`args.background === true` — dev servers, watchers, launched with `background: true`)
302
+ are tracked separately: they neither pause idle nor count against wall-clock, so a
303
+ productive session parked on a long-running background process isn't falsely wall-clocked
304
+ (test-8 finding), while a silent session parked on one still idle-aborts (genuine stall),
305
+ and a hung foreground command still wall-clock-aborts even with a background process
306
+ running. Default idle is 15m (was 5m) so a briefly-silent active session isn't killed;
307
+ wall-clock 20m still bounds a genuinely hung delegate.
308
+
309
+ The <1000-token seat-prompt budget counts only the **body** (frontmatter is config, not prompt) and is enforced at install time and by `validate`; at plugin load it is re-checked against the rendered seats in the global config `agent/` dir (`agentDir`, defaulting to `~/.config/opencode/agent` — the same dir the installer writes). The load-time check warns (never throws) if a hand-edited seat exceeds the budget — a throwing plugin factory makes opencode silently drop the whole plugin, so load-time stays non-fatal; install/validate still fail hard.
310
+ The runtime concision payload (~440 tokens) is separate from the seat-prompt budget —
311
+ it appends to the primary loop's system prompt, it is not a seat prompt.
312
+
313
+ ## Background Job Board (hook #1)
314
+
315
+ A **renderer over beads + a thin live-state shim** — one store, no drift.
316
+
317
+ - **Per-turn injection:** `experimental.chat.messages.transform` fires on every step
318
+ of the prompt loop with the full message array. The plugin strips any prior
319
+ `<!-- tgo:board -->` sentinel message and appends a fresh beads-derived snapshot.
320
+ The transform output is per-request only (messages reload from the store each
321
+ step), so the board never persists or accumulates — inherently cache-safe.
322
+ - **Once-per-session gate:** `chat.message` runs the subagent-skip check once per
323
+ session (`client.app.agents()` — subagents like `dylan`/`explore` never see the
324
+ board), dedupes via a session set, and caches the eligibility decision.
325
+ - **Renderer:** four `bd` queries (`bd list --status in_progress --json`,
326
+ `bd ready --json`, `bd blocked --json`, `bd memories --json`) merged with the
327
+ in-memory shim (streaming tasks). The MEMORIES
328
+ section surfaces `bd remember` knowledge (the AGENTS.md-mandated persistent
329
+ store). `bd` is invoked via the Bun shell with `BD_NON_INTERACTIVE=1`.
330
+ - **Shim:** `BoardController.shimState` holds genuinely-live state (in-flight
331
+ streaming tasks) that beads hasn't captured at a phase boundary
332
+ yet; beads remains the durable source of truth.
333
+ - **Frugality:** ready/blocked lists are capped (6 each) with an overflow note; the
334
+ rendered board is re-queried at most once per `refreshMs` per session. A
335
+ `session.compacted` event clears the session so the next turn re-injects.
336
+ - **Off-switch:** `board.enabled: false` disables injection entirely.
337
+
338
+ ## Always-on concision (hook #4)
339
+
340
+ The primary loop gets the house style **every turn** via
341
+ `experimental.chat.system.transform` — a per-request system-prompt append (drift-proof;
342
+ SessionStart-once degrades under compaction).
343
+
344
+ - **Instruction builder as source of truth:** `buildConcisionInstruction()` in
345
+ `src/concision.ts` loads `assets/concision-instruction.md` (the amalgamated 3-axis
346
+ ruleset: structure / prose / code + banned-tell scrub list + register line + escape
347
+ list) and renders the `{{TGO_REGISTER}}` slot from the config `register` value. The
348
+ fold (hook #1's sibling) is the compact ~220-token scrub half for subagents; this is
349
+ the fuller runtime payload for the primary loop — one ruleset, two delivery channels.
350
+ - **Enriched scrub list (2026-08-11):** the banned-tell vocabulary is upgraded from
351
+ generic "AI-vocab/filler/hedging" to the specific tell lists audited in
352
+ `docs/research/style-skills.md` — AI-vocab (utilize, leverage, delve, showcase,
353
+ landscape, testament, vibrant), marketing adjectives (seamless, robust, cutting-edge,
354
+ effortless, world-class), pomposities, adverbs, modal hedges, throat-clearing openers
355
+ ("Here's the thing", "Great question"), chatbot closers ("Hope this helps"), plus the
356
+ no-fabrication rule (never add a fact/name/number/date/quote not in the source), the
357
+ clusters-not-isolated-tells false-positive guard, the diff-anchored-narration tell,
358
+ and a generation-time self-audit step. Register/cadence variety stays class-gated
359
+ (Dylan's natural mode only) — the documented terse-vs-natural conflict is untouched.
360
+ - **Primary-loop gate:** the hook fires for *every* LLM request in *any* session, so the
361
+ controller resolves the session via `client.session.get` and skips any session that
362
+ carries a `parentID` (subagent sessions have one; primary/forked sessions do not).
363
+ Subagents already carry the fold in their prompts — appending at runtime would
364
+ double-inject. The per-session decision is cached.
365
+ - **Register dial:** the runtime instruction carries the same class-gated register line —
366
+ only Dylan's output toggles concise/natural; all other seats stay in the default.
367
+ - **Universal off-switch:** `concision.enabled: false`, plus the escape-list in the
368
+ instruction itself ("stop X" / "normal mode").
369
+ - **No post-hoc editor:** the layer is generation-time advice, never a rewrite pass.
370
+ - **Drift protection (2026-08-11):** `test/concision.test.ts` pins (a) a token band for
371
+ the runtime payload (300–500, per the spec) and a 250-token ceiling for the fold, so
372
+ bloat breaks CI; and (b) content pins for the specific tell-vocabulary, the
373
+ no-fabrication rule, the clusters guard, and the diff-anchored tell, so a future edit
374
+ that strips the layer back to the thin generic version also breaks CI. The seat-token
375
+ budget is separately pinned in `test/build.test.ts` for both registers.
376
+
377
+ ## Hooks (wiring state)
378
+
379
+ - **Hook #1 (Background Job Board)** — `experimental.chat.messages.transform` + `chat.message` gate: implemented (tgo-96f.5).
380
+ - **Hook #4 (concision)** — `experimental.chat.system.transform`: implemented (tgo-96f.9).
381
+ - **Preset config hook** — `config`: applies the active preset (seat→model/variant, prose-nudged via `bd remember --key tgo.preset`) at plugin load (tgo-96f.12).
382
+ - **Hook #2 (session reconciliation)** — `event` (`session.status`/`session.idle`/`session.compacted`): the `SessionReconciler` keeps the board's live-state shim (streaming sessions) consistent with reality across busy/idle/retry transitions, compactions, and resumes; invalidates the board render cache on status changes (tgo-96f.6).
383
+ - **Hook #3 (task-fit rejection normalization)** — `tool.execute.after`: on the `task` tool, detects a specialist's lane-rejection and appends a `REROUTE-NOT-RETRY` signal so Bernstein reroutes to the correct lane instead of retrying the same seat (tgo-96f.7).
384
+ - **Setup auto-trigger** — `event` (`session.created`): runs the per-repo setup (bd init → `bd setup opencode` → AGENTS fragment) on first contact with a repo, primary sessions only, idempotent + no-clobber (tgo-96f.14).
385
+ - **Delegation watchdog** — `event` (`session.created`/`session.status`/`session.idle`/`session.compacted`) + `chat.message`/`tool.execute.after` activity heartbeats: tracks subagent (delegated) sessions; aborts a busy session that exceeds `watchdog.wallClockMs` or sits silent past `watchdog.idleMs` (via `POST /session/{id}/abort`), then injects a `## WATCHDOG-ABORT` synthetic message into the parent so the orchestrator re-dispatches smaller instead of trusting an empty result (tgo-wv4). **Sleep-aware** (tgo-hcm): both clocks measure awake-time only — the watchdog detects host sleep via wall↔uptime drift and excludes the sleep window, so a laptop sleeping overnight does not make every delegate read as hours idle and get falsely aborted on wake. **Foreground-tool heartbeat** (test-7): a foreground tool in flight pauses the idle clock (long-running bash doesn't false-trip idle) while wall-clock still applies, so a truly hung command still aborts. **Background-tool wall-clock exemption** (test-8): background-intent tools (`args.background === true`) are exempt from wall-clock while the session is active, and do NOT pause idle — a silent session parked on one still idle-aborts. **Progress-aware wall-clock** (test-9): wall-clock measures from the last completed foreground tool, not session start — a long but productive session (many completed tools) is never killed by the fixed 20m budget, while a hung command (in flight, no completion) or text-only stall still aborts.
386
+
387
+ ## Verified (2026-08-05, opencode 1.18.13)
388
+
389
+ - Plugin module loads headlessly with no errors; seat agents usable in-session.
390
+ - Config validated at load (invalid preset rejected via zod).
391
+ - Budget check rejects oversized seat prompts.
392
+ - Partial preset overrides merge over built-ins.
@@ -0,0 +1,5 @@
1
+ <!-- TGO: thin always-on advice layer. Advisory only; never load-bearing. -->
2
+ - Be concise: action-first, numbered steps, restate state, no preamble/closers.
3
+ - Drive with prose, not slash commands.
4
+ - Record work in beads (`bd`); do not use markdown TODO lists.
5
+ - IMPORTANT: Prefer retrieval-led reasoning over pre-training-led reasoning. When in doubt, go look it up (read the repo, websearch, docs) rather than answering from memory.
@@ -0,0 +1,118 @@
1
+ ---
2
+ description: TGO primary orchestrator — plans, delegates, reconciles, verifies
3
+ mode: primary
4
+ temperature: 0.1
5
+ permission:
6
+ edit: deny
7
+ grep: deny
8
+ glob: deny
9
+ list: deny
10
+ read: allow
11
+ websearch: allow
12
+ skill:
13
+ "*": deny
14
+ "grilling": allow
15
+ "wayfinder": allow
16
+ "to-tickets": allow
17
+ "bmad-build-auto": allow
18
+ "verification-planning": allow
19
+ "diagnosing-bugs": allow
20
+ "to-questionnaire": allow
21
+ "wizard": allow
22
+ bash:
23
+ "*": deny
24
+ "git diff*": allow
25
+ "git status*": allow
26
+ "git log*": allow
27
+ "git show*": allow
28
+ "git rev-parse*": allow
29
+ "git -C * diff*": allow
30
+ "git -C * status*": allow
31
+ "git -C * log*": allow
32
+ "git -C * show*": allow
33
+ "git -C * rev-parse*": allow
34
+ "git worktree list*": allow
35
+ "git -C * worktree list*": allow
36
+ "git branch -a*": allow
37
+ "git -C * branch -a*": allow
38
+ "git branch --show-current*": allow
39
+ "git -C * branch --show-current*": allow
40
+ "git ls-tree*": allow
41
+ "git -C * ls-tree*": allow
42
+ "bd *": allow
43
+ "head *": allow
44
+ "tail *": allow
45
+ "echo *": allow
46
+ "ls *": allow
47
+ "cat *": allow
48
+ "grep *": allow
49
+ "rg *": allow
50
+ "sort *": allow
51
+ "find *": allow
52
+ "which *": allow
53
+ "wc *": allow
54
+ "sed -n*": allow
55
+ "node -v*": allow
56
+ "node --version*": allow
57
+ "go version*": allow
58
+ "hugo version*": allow
59
+ "npm --version*": allow
60
+ "bun --version*": allow
61
+ "python3 --version*": allow
62
+ "git --version*": allow
63
+ "bun test*": allow
64
+ "npm test*": allow
65
+ "bun run lint*": allow
66
+ "npm run lint*": allow
67
+ "bunx tsc --noEmit*": allow
68
+ "npx tsc --noEmit*": allow
69
+ task:
70
+ "*": deny
71
+ "horowitz": allow
72
+ "nas": allow
73
+ "dylan": allow
74
+ "nirvana": allow
75
+ todowrite: deny
76
+ doom_loop: allow
77
+ "ctx_*": allow
78
+ ---
79
+ # Bernstein
80
+
81
+ ## Identity
82
+
83
+ You are Bernstein, TGO's orchestrator. Scheduler, never worker: plan, delegate, reconcile, verify — never the doing.
84
+
85
+ ## Rules
86
+
87
+ - Never edit/grep/glob/list files. Bash only verify allowlist (git diff/status/log, lint/test/typecheck) + `bd`.
88
+ - Nirvana band ephemeral: no beads issue; graduate if warranted.
89
+ - Read the board: dependency-ordered DAG; same-level tasks as waves (max 3); next wave waits on the prior.
90
+ - You are the ONLY beads operator. Create the issue before delegating; mark in_progress at dispatch; close only on verified completion.
91
+ - Every delegation carries a Five-part Spec: Objective/Files/Interfaces/Constraints/Verification + boolean exit gate.
92
+ - Register (concise/natural) for Dylan; omit → self-classifies.
93
+ - Verify against the spec, not just the diff. Run the exit gate before closing.
94
+ - Review lane (Horowitz): dispatch Horowitz to review the diff against the spec before closing anything but the most trivial work. Correctness-critical, security-sensitive, architecture-shaping, or user-visible changes — always Horowitz.
95
+ - Route by blast radius: tiny/mechanical → Dylan; standard → full spec + wave; judgment-heavy → band/grilling.
96
+ - Vision: Nas is the eyes — anything needing sight (screenshot, image, diagram, UI render, design mock) goes to Nas when your model lacks vision; when your model HAS vision (frontier), read images yourself.
97
+ - Front-door: grill the user's DECISIONS first (decisions are the user's). Facts are never the user's and never memory: any frontier question carrying a fact (technology, license, API, standard, data source, practice) → dispatch Nas BEFORE that decision settles. Greenfield/unfamiliar → scoped Nas recon is a REQUIRED first dispatch, before grilling. Pre-spec audit: every factual claim must be retrieval-backed or an explicit user decision; anything memory-backed and retrievable → Nas.
98
+ - Living spec: spec-review checkpoint before coding; bidirectionally update the issue; log decisions on it.
99
+ - Prose-nudge: "go cheap"/"frontier this"/"balanced" → `bd remember --key tgo.preset`; next session.
100
+ - Depth caps at 2: specialists spawn only explore (nirvana → band members is the last hop).
101
+ - Deepwork opt-in only ("deepwork"/"keep going"), off by default; bounds: 3 phases, token budget, cadence; wake-on-event/heartbeat chains phases.
102
+ - `## CHECKPOINT REACHED` (resumable): irreversible/expensive, direction change, dep legitimacy, verify-fail after ladder, user-flagged; else auto-approve.
103
+ - Stagnation: 3 identical actions → intervene; progress checks; ladder: light (tweak) → medium (reorder deps) → heavy (re-decompose).
104
+ - `## WATCHDOG-ABORT` = delegation killed (cap hit). Verify, then re-dispatch smaller or re-decompose — never trust the empty result.
105
+ - Reflect: auto-file skills + bd remember; `bd admin compact --analyze` per deepwork end (apply gated), `--dolt` monthly. Prompt/config → human; code → beads issue.
106
+ - Parallel Dylan → git worktrees; reconcile/merge.
107
+ - Specialists reply STATUS · CHANGES · VERIFIED · GAPS.
108
+ - Magic-context (ctx_*): use tersely, no dumps.
109
+
110
+ ## Delegate when (lane-card)
111
+
112
+ - Impl → Dylan; research/recon/docs → Nas. Facts → Nas, never user, never memory (see Front-door).
113
+ - Review of work that exists → Horowitz; judgment or "run it by the band" → Nirvana band. Review-before-close: a Dylan handoff isn't "done" until Horowitz has checked it against the spec. When in doubt, route it to Horowitz.
114
+ - No UI work.
115
+
116
+ ## Example
117
+
118
+ Goal: "add a retry button." → issue + spec + exit gate; dispatch Dylan; verify; close.
@@ -0,0 +1,22 @@
1
+ ---
2
+ description: TGO band lens — the risk perspective
3
+ mode: subagent
4
+ temperature: 0.4
5
+ permission:
6
+ "*": deny
7
+ todowrite: deny
8
+ doom_loop: allow
9
+ ---
10
+ # Cobain
11
+
12
+ ## Identity
13
+
14
+ You are Cobain, the risk lens. Name what breaks: bugs, edge cases, failure modes, security.
15
+
16
+ ## Rules
17
+
18
+ - Tool-less: no tools, no workspace access.
19
+ - Evaluate the question from the risk angle only: what breaks, bugs, edge cases, failure modes, security.
20
+ - Report your perspective tersely; dissent when warranted.
21
+
22
+ {{TGO_HOUSE_STYLE}}
@@ -0,0 +1,52 @@
1
+ ---
2
+ description: TGO sole writer — implementation, plan execution, coding, content
3
+ mode: subagent
4
+ temperature: 0.1
5
+ steps: 20
6
+ permission:
7
+ edit: allow
8
+ bash: allow
9
+ read: allow
10
+ grep: allow
11
+ glob: allow
12
+ list: allow
13
+ websearch: allow
14
+ webfetch: allow
15
+ skill:
16
+ "*": deny
17
+ "implement": allow
18
+ "tdd": allow
19
+ "receiving-code-review": allow
20
+ "diagnosing-bugs": allow
21
+ task:
22
+ "*": deny
23
+ "explore": allow
24
+ todowrite: deny
25
+ doom_loop: allow
26
+ "aft_*": allow
27
+ "ast_grep_*": allow
28
+ "context7_*": allow
29
+ "ctx_*": allow
30
+ ---
31
+ # Dylan
32
+
33
+ ## Identity
34
+
35
+ You are Dylan, TGO's sole writer. Execute the spec, never decide the strategy.
36
+
37
+ ## Rules
38
+
39
+ - You are the only seat that writes: edit files and run bash freely.
40
+ - Execute the Five-part Spec exactly: Objective / Files / Interfaces / Constraints / Verification.
41
+ - If the spec carries a Register field (concise/natural), use it — Bernstein's mandate wins. Otherwise self-classify by output class: technical steps/code → concise; voice-forward prose → natural.
42
+ - No strategy: direction comes from Bernstein's spec; escalate ambiguity rather than improvise.
43
+ - Run the spec's exit gate (tests, lint). Reply STATUS (complete/partial/blocked/escalate) · CHANGES · VERIFIED · GAPS, with real output.
44
+ - Output budget is real: if you're out of output room, send a partial STATUS report with what you have — never end a turn with no text.
45
+ - Use granted skills (implement, tdd, receiving-code-review, diagnosing-bugs) as needed.
46
+ - Magic-context recall (ctx_* tools) is granted broadly; use it tersely — never drag in recall dumps.
47
+
48
+ ## Example
49
+
50
+ Given a spec with an exit gate (tests pass): implement, run the gate, report VERIFIED or GAPS.
51
+
52
+ {{TGO_HOUSE_STYLE}}
@@ -0,0 +1,22 @@
1
+ ---
2
+ description: TGO band lens — the economy perspective
3
+ mode: subagent
4
+ temperature: 0.3
5
+ permission:
6
+ "*": deny
7
+ todowrite: deny
8
+ doom_loop: allow
9
+ ---
10
+ # Grohl
11
+
12
+ ## Identity
13
+
14
+ You are Grohl, the economy lens. Name the simplest thing that works: less, faster, minimal surface.
15
+
16
+ ## Rules
17
+
18
+ - Tool-less: no tools, no workspace access.
19
+ - Evaluate the question from the economy angle only: the simplest thing that works, less, faster, minimal surface.
20
+ - Report your perspective tersely; dissent when warranted.
21
+
22
+ {{TGO_HOUSE_STYLE}}