@bongos/core 1.19.1075 → 1.19.1076

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 (72) hide show
  1. package/.bongos-core.json +85 -100
  2. package/.claude/skills/blocker-solve/SKILL.md +1 -1
  3. package/README.md +1 -1
  4. package/docs/adr/0031-cloud-dev-environments-for-builders.md +1 -1
  5. package/docs/adr/0035-builder-onboarding-three-paths.md +1 -1
  6. package/docs/adr/0044-per-box-live-game-preview.md +1 -1
  7. package/docs/adr/0045-devbox-desktop-app.md +1 -1
  8. package/docs/adr/0046-sandbox-first-review-gate.md +1 -1
  9. package/docs/adr/0052-sandbox-for-everyone-game-only-preview.md +1 -1
  10. package/docs/adr/0053-scoped-dev-box-session.md +1 -1
  11. package/docs/adr/0055-server-mediated-branch-publish.md +1 -1
  12. package/docs/adr/0057-container-cost-ledger.md +1 -1
  13. package/docs/adr/0059-single-approval-remove-devbox-approval-gate.md +1 -1
  14. package/docs/adr/0071-box-confirm-before-destroyed-and-drift-reconcile.md +1 -1
  15. package/docs/adr/0072-bongos-app-mac-signed-first-windows-deferred.md +1 -1
  16. package/docs/adr/0072-dev-box-code-staleness-visibility.md +1 -1
  17. package/docs/adr/0104-trust-gds-api-channel-in-auto-mode.md +1 -1
  18. package/docs/adr/0123-box-idle-sweep-autosave-before-destroy.md +1 -1
  19. package/docs/adr/0144-devbox-rehome-onto-cloudbongos-plane.md +1 -1
  20. package/docs/adr/0145-devbox-app-branding-driven-module.md +1 -1
  21. package/docs/adr/0148-task-scoped-box-source-access.md +2 -2
  22. package/docs/adr/0151-governance-permissions-as-atom-ranks-as-roles.md +1 -1
  23. package/docs/adr/0193-pause-task-scoped-box-slices.md +1 -1
  24. package/docs/adr/0277-a-box-is-in-use-only-while-a-human-is-attached.md +1 -1
  25. package/docs/adr/0346-dev-boxes-are-retired.md +69 -0
  26. package/docs/adr/README.md +1 -0
  27. package/docs/architecture.md +5 -6
  28. package/docs/branding-contract.md +2 -2
  29. package/docs/canonical-permissions.md +10 -18
  30. package/docs/copy-inventory.md +3 -3
  31. package/docs/copy-registry.json +3 -3
  32. package/docs/design/gate-navigation-direction.md +1 -1
  33. package/docs/design/hall-direction-v2.md +3 -3
  34. package/docs/design/modular-architecture/00-research-report.md +1 -1
  35. package/docs/design/modular-architecture/01-architecture.md +3 -3
  36. package/docs/design/modular-architecture/02-module-map.md +1 -2
  37. package/docs/design/modular-architecture/03-builder-flows.md +22 -20
  38. package/docs/design/modular-architecture/04-module-lifecycle.md +1 -1
  39. package/docs/design/modular-architecture/README.md +4 -2
  40. package/docs/design/reviews/hall-v2/README.md +2 -2
  41. package/docs/design/vanilla-hall-ui-redesign-scope.md +4 -4
  42. package/docs/file-map.md +5 -5
  43. package/docs/handoff-template.md +1 -1
  44. package/docs/module-api-changelog.md +6 -0
  45. package/docs/modules-contract.md +11 -14
  46. package/docs/page-readings.json +63 -63
  47. package/docs/recipes/bongos-cli-release.md +1 -2
  48. package/docs/recipes/multi-builder-merge.md +1 -1
  49. package/docs/recipes/ops-gotchas.md +0 -9
  50. package/docs/recipes/self-host.md +1 -1
  51. package/docs/recipes/windows-builders.md +1 -1
  52. package/migrations/core_258_drop_dev_box_tables.sql +3 -0
  53. package/modules/hall-ui/public/palette.js +143 -3
  54. package/package-lock.json +2 -2
  55. package/package.json +1 -1
  56. package/release-notes.json +22 -0
  57. package/scripts/gds/dev-box-guard.js +165 -0
  58. package/scripts/gds/fitness-lib.js +10 -0
  59. package/scripts/gds/fitness.js +2 -10
  60. package/scripts/gds/run-unit-tests.js +4 -0
  61. package/src/bongos/module-scope-map.js +1 -1
  62. package/src/module-api.js +1 -1
  63. package/tests/core_258_box_session_claims_db.mjs +180 -0
  64. package/tests/fitness.mjs +89 -0
  65. package/tests/hall_palette.mjs +224 -11
  66. package/tests/provisioning_recommendations.mjs +1 -1
  67. package/docs/design/reviews/hall-v2/harbor--archon.webp +0 -0
  68. package/docs/design/reviews/hall-v2/harbor--metic.webp +0 -0
  69. package/docs/design/reviews/hall-v2/harbor--xenos.webp +0 -0
  70. package/docs/design/reviews/hall-v2/pair--archon.webp +0 -0
  71. package/docs/design/reviews/hall-v2/pair--metic.webp +0 -0
  72. package/docs/design/reviews/hall-v2/pair--xenos.webp +0 -0
@@ -95,7 +95,6 @@ graph TD
95
95
  GA[game] --> K
96
96
  AR[art-pipeline] --> K
97
97
  DC[discord] --> K
98
- DB[dev-box] --> K
99
98
  ```
100
99
 
101
100
  | Module | Owns |
@@ -111,6 +110,6 @@ graph TD
111
110
  | autonomy/MAS | conductor dispatch · architect audits · autonomy-gate · scheduled routines |
112
111
  | security | red-team reports · bounty (rank-gated Metic+) |
113
112
  | hall-UI · status-UI | the two web surfaces |
114
- | game · art-pipeline · discord · dev-box | feature modules |
113
+ | game · art-pipeline · discord | feature modules |
115
114
 
116
115
  > **~16 is the target ceiling, not a day-one requirement.** Start coarser; split as the coupling scan + fitness demand. Every one is a real cohesive cluster (the scan proved it), but a small team should be "as modular as the evidence supports, no finer." Merging two modules is cheap; the fitness ratchet makes splitting them safe — you're never locked into the first cut.
@@ -4,26 +4,26 @@ How a person works once the code is in modules. **Nothing you do is blocked —
4
4
 
5
5
  ## The one idea: two kinds of "access"
6
6
 
7
- - **Platform capabilities** — claim, start, ship, file an idea, recall, see your box. These are **kernel endpoints over HTTP, gated only by your rank.** The module structure never touches them. Available everywhere, always.
8
- - **Code-write scope** — which files a *single claimed task* may change. The **only** thing the structure bounds; it lives at the **worktree** level (not you, not your box); escaped by seeding a new task (itself a kernel capability).
7
+ - **Platform capabilities** — claim, start, ship, file an idea, recall. These are **kernel endpoints over HTTP, gated only by your rank.** The module structure never touches them. Available everywhere, always.
8
+ - **Code-write scope** — which files a *single claimed task* may change. The **only** thing the structure bounds; it lives at the **worktree** level (not you, not your checkout); escaped by seeding a new task (itself a kernel capability).
9
9
 
10
- **The wall is around each task's worktree — not around you, and not around your dev box.**
10
+ **The wall is around each task's worktree — not around you, and not around your checkout.**
11
11
 
12
- ## 1. What the dev box has access to
12
+ ## 1. What your checkout has access to
13
13
 
14
- The dev box is your machine — a persistent environment, **not** module-scoped. Scoping happens one level down, per claim.
14
+ Your checkout is your own copy of the project repo on your own machine — a persistent environment, **not** module-scoped. Scoping happens one level down, per claim.
15
15
 
16
16
  | Layer | Scope | Governed by |
17
17
  |---|---|---|
18
- | Dev box (your environment) | full repo, all modules readable, whole CLI, the API, the preview | nothing — it's yours |
18
+ | Your checkout (your machine) | full repo, all modules readable, whole CLI, the API, the preview | nothing — it's yours |
19
19
  | Kernel capabilities (claim/ship/capture/…) | everything the platform can do | **your rank** (server-enforced) — never a module |
20
20
  | A claim's worktree | write = its one module; read = that module + the kernel doorway | the task's **module label** + the ship-time diff check |
21
21
 
22
- ## 2. Flow: open a dev box → ship a task
22
+ ## 2. Flow: open your checkout → ship a task
23
23
 
24
24
  ```mermaid
25
25
  graph LR
26
- A["Open dev box<br/>(box)"] --> B["/builder-start<br/>lists ALL modules<br/>(kernel)"]
26
+ A["Open your checkout<br/>(local)"] --> B["/builder-start<br/>lists ALL modules<br/>(kernel)"]
27
27
  B --> C["/builder-claim N<br/>a game task<br/>(kernel)"]
28
28
  C --> D["worktree spun:<br/>modules/game + RO kernel<br/>(module-scoped)"]
29
29
  D --> E["agent edits game only<br/>(module-scoped)"]
@@ -31,7 +31,7 @@ graph LR
31
31
  F --> G["live ✓<br/>worktree reaped"]
32
32
  ```
33
33
 
34
- Five of seven steps are kernel/box capabilities; only the worktree + the edits are module-scoped. The only *new* thing is a silent check inside `/builder-ship` (diff ⊆ declared module) that in-scope work never notices.
34
+ Five of seven steps are kernel/local capabilities; only the worktree + the edits are module-scoped. The only *new* thing is a silent check inside `/builder-ship` (diff ⊆ declared module) that in-scope work never notices.
35
35
 
36
36
  ## 3. Flow: claim a task in a different module
37
37
 
@@ -39,14 +39,14 @@ You're never "in" a module — each *claim* is. A second claim just makes a seco
39
39
 
40
40
  ## 4. Flow: see an idea — and seed a cross-module task
41
41
 
42
- Browsing ideas, filing an idea, and **seeding a task for another module** are all kernel operations — they need no access to the other module's code, so they work from anywhere. An agent in a game worktree can't *write* dev-box code, but it can always *file the task* for it (one command), then continue or hand off; a dependency link orders them if needed.
42
+ Browsing ideas, filing an idea, and **seeding a task for another module** are all kernel operations — they need no access to the other module's code, so they work from anywhere. An agent in a game worktree can't *write* discord code, but it can always *file the task* for it (one command), then continue or hand off; a dependency link orders them if needed.
43
43
 
44
44
  ## 5. "Could this block me?" — every worry
45
45
 
46
46
  | Worry | Why it isn't a block |
47
47
  |---|---|
48
48
  | Claim a task in a module I'm not "in"? | You're never "in" a module. Claiming is kernel; each claim makes its own scoped worktree. |
49
- | Does my box only have one module's code? | No — the box has the full repo. Only each per-claim worktree is scoped. |
49
+ | Does my checkout only have one module's code? | No — the checkout has the full repo. Only each per-claim worktree is scoped. |
50
50
  | Agent needs another module mid-task — stuck? | No — it seeds a task for it (kernel op, needs no access to that code); a dep orders them. |
51
51
  | Filing an idea about module X needs X access? | No — capture/inbox is kernel; file from anywhere. |
52
52
  | Is shipping gated by my module? | No — ship is kernel; the only module check is "diff ⊆ module," which passes for normal work. |
@@ -60,7 +60,7 @@ A Claude Code session is **not** welded to one worktree. The session is a **cond
60
60
  graph TD
61
61
  S["long autonomous SESSION = <redacted> repo · full mobility · no module binding"]
62
62
  S --> A["task A (game) → worktree A → its own PR → ship"]
63
- S --> B["task B (dev-box) → worktree B → its own PR → ship"]
63
+ S --> B["task B (discord) → worktree B → its own PR → ship"]
64
64
  S --> C["task C (memory) → worktree C → its own PR → ship"]
65
65
  ```
66
66
 
@@ -69,34 +69,36 @@ graph TD
69
69
 
70
70
  The session has full mobility across modules; only each *task's worker* is module-isolated. This is the orchestrator-worker pattern (ADR 0024), and Bongos already assigns a per-claim worktree.
71
71
 
72
- ## 7. Limiting what the box holds — the jailbreak blast radius
72
+ ## 7. Limiting what a sandbox holds — the jailbreak blast radius
73
73
 
74
- The split lets the box hold **far less**: only the claimed module (read/write) + the kernel's **safe contract** (signatures, read-only) + client plumbing + a scoped token. The kernel **implementation** (auth, rank, ship, grade) never leaves the server.
74
+ *This section was written for the dev box, which has since been retired ([ADR 0346](../../adr/0346-dev-boxes-are-retired.md)). The reasoning holds for any sandboxed environment a session might run in, such as a future cloud session. Today's path, a local checkout, holds the full repo by design (§1).*
75
+
76
+ The split lets a sandbox hold **far less**: only the claimed module (read/write) + the kernel's **safe contract** (signatures, read-only) + client plumbing + a scoped token. The kernel **implementation** (auth, rank, ship, grade) never leaves the server.
75
77
 
76
78
  ```mermaid
77
79
  graph LR
78
- subgraph Box["DEV BOX · one claim (= jailbreak blast radius)"]
80
+ subgraph Sbx["SANDBOX · one claim (= jailbreak blast radius)"]
79
81
  M["modules/&lt;key&gt;/ — read/write"]
80
82
  KC["kernel CONTRACT — signatures + docs only (RO)"]
81
83
  CLI["CLI plumbing (cli-lib)"]
82
84
  TOK["scoped, claim-scoped token (not full-repo)"]
83
85
  end
84
86
  subgraph Server["SERVER · the trusted side"]
85
- KI["KERNEL IMPL — auth · rank · ship · grade<br/>(never on the box)"]
87
+ KI["KERNEL IMPL — auth · rank · ship · grade<br/>(never in the sandbox)"]
86
88
  OM[every other module's source]
87
89
  FR[full repo + history]
88
90
  EN["ENFORCES the rank ladder, live per request (ADR 0016)"]
89
91
  end
90
- Box -->|"privileged ops = HTTP call<br/>(box can't push main)"| Server
92
+ Sbx -->|"privileged ops = HTTP call<br/>(sandbox can't push main)"| Server
91
93
  ```
92
94
 
93
- **The trap to avoid:** reducing what's *on disk* is not reducing *access* — a box holding a full-repo credential re-fetches. The real lever is **scoping the box's credential + fetch to the claimed module** (and module access can be **rank-gated** too, since the server mediates every fetch). The primary boundary always remains the **server-enforced rank ladder**; on-disk minimization is defense-in-depth on top.
95
+ **The trap to avoid:** reducing what's *on disk* is not reducing *access* — a sandbox holding a full-repo credential re-fetches. The real lever is **scoping the sandbox's credential + fetch to the claimed module** (and module access can be **rank-gated** too, since the server mediates every fetch). The primary boundary always remains the **server-enforced rank ladder**; on-disk minimization is defense-in-depth on top.
94
96
 
95
97
  | Approach | Efficiency | Real confidentiality boundary? |
96
98
  |---|---|---|
97
99
  | Sparse-checkout only | ✓ smaller tree | ✗ — `.git` still has everything |
98
- | Partial clone + sparse | ✓✓ | ~ — box can lazily re-fetch with its token |
99
- | **Server-mediated, claim-scoped fetch** | ✓✓ | **✓ — box never holds a full-repo remote or kernel source** |
100
+ | Partial clone + sparse | ✓✓ | ~ — sandbox can lazily re-fetch with its token |
101
+ | **Server-mediated, claim-scoped fetch** | ✓✓ | **✓ — sandbox never holds a full-repo remote or kernel source** |
100
102
  | Per-module repos | ✓✓ | ✓✓ strongest — but contradicts single-repo (ADR 0080 rejected package-modules for v1) |
101
103
 
102
104
  ## 8. Two boundaries that compose (no new friction)
@@ -8,7 +8,7 @@ The one-way rule forbids a module importing another. But the **lifecycle** (whic
8
8
 
9
9
  - **Ports** (a *required, single-provider* capability): the economy module registers a `reward` provider; at ship, the lifecycle asks the kernel to resolve `reward` and calls it. **Economy owns the formula *and* the ledger**; the lifecycle only supplies the session and delivers the result.
10
10
  - **Events** (an *optional* reaction): the lifecycle emits `task.shipped`; the discord module reacts if it cares.
11
- - **Contributions** (an *accumulating extension point*): zero-or-more modules each add a piece to a named point and the kernel hands the whole set to a core consumer — how a module adds its own slice to a shared core surface without core hardcoding it. The `profile.fields` point lets dev-box/discord/art add their slice to the `GET /me` payload (and its browser twin, `window.OTB.contributeSettingsPanel`, adds a Settings panel) instead of those being baked into `routes/me.js` + `settings.js` (BV1.R42 / task 1411 — the strangler prerequisite for those three moves; game has no such coupling). Add-only: a contribution may introduce keys, never overwrite a core one.
11
+ - **Contributions** (an *accumulating extension point*): zero-or-more modules each add a piece to a named point and the kernel hands the whole set to a core consumer — how a module adds its own slice to a shared core surface without core hardcoding it. The `profile.fields` point lets discord/art add their slice to the `GET /me` payload (and its browser twin, `window.OTB.contributeSettingsPanel`, adds a Settings panel) instead of those being baked into `routes/me.js` + `settings.js` (BV1.R42 / task 1411 — the strangler prerequisite for those moves; game has no such coupling). Add-only: a contribution may introduce keys, never overwrite a core one.
12
12
 
13
13
  ```mermaid
14
14
  graph LR
@@ -4,17 +4,19 @@ Five reports from the **2026-06-21 modular-architecture design session**, filed
4
4
 
5
5
  > **Status: pre-red-team draft.** These are research/design reports, not a decision record. A formal numbered ADR follows once they've been red-teamed. Filed under `docs/design/` (not `docs/adr/`) on purpose — the ADR numbering is in flux (0079→0081 collisions), so the number is assigned later on an up-to-date worktree.
6
6
 
7
+ > **Since filing:** the dev box module that these reports use as their first example was retired on 2026-09-28 ([ADR 0346](../../adr/0346-dev-boxes-are-retired.md)). Where a report still names it (the code-size table, the import-graph findings, the migration plan), that is the tree as it stood at filing.
8
+
7
9
  | # | Doc | What it answers |
8
10
  |---|-----|-----------------|
9
11
  | 00 | [Research report](00-research-report.md) | Industry best practice on packaging, plugins, theming, and AI-agent scoping (cited) |
10
12
  | 01 | [Architecture](01-architecture.md) | The concrete core+modules design; why not a rewrite; the migration path |
11
13
  | 02 | [Module map](02-module-map.md) | Where the ~95k LOC live; how finely to cut the core; the decided roster |
12
- | 03 | [Builder flows](03-builder-flows.md) | What the dev box can access; why the structure never blocks a builder |
14
+ | 03 | [Builder flows](03-builder-flows.md) | What a builder's checkout can access; why the structure never blocks a builder |
13
15
  | 04 | [Module lifecycle & maintenance](04-module-lifecycle.md) | How modules interact (seams) and stay healthy as code grows |
14
16
 
15
17
  ## The decided model (one paragraph)
16
18
 
17
- A small **kernel** (auth, rank, db-pool, the loader, the seam registry, trust primitives, config/identity, analytics, the trusted publish path) plus **~16 modules** (lifecycle, economy, grading, memory, onboarding, ideas, builder-settings, sessions/BFG, autonomy/MAS, security, hall-UI, status-UI + game/art-pipeline/discord/dev-box). Modules **never import each other** — they interact through **kernel-mediated seams** (ports + events). Boundaries are held by **CI fitness functions** so the structure can't rot as it grows. It stays **single-package, single-process, no-bundler** — modularity is a separate axis from packaging/runtime/build. It is built via an incremental **strangler migration**, not a ground-up rewrite.
19
+ A small **kernel** (auth, rank, db-pool, the loader, the seam registry, trust primitives, config/identity, analytics, the trusted publish path) plus **~16 modules** (lifecycle, economy, grading, memory, onboarding, ideas, builder-settings, sessions/BFG, autonomy/MAS, security, hall-UI, status-UI + game/art-pipeline/discord). Modules **never import each other** — they interact through **kernel-mediated seams** (ports + events). Boundaries are held by **CI fitness functions** so the structure can't rot as it grows. It stays **single-package, single-process, no-bundler** — modularity is a separate axis from packaging/runtime/build. It is built via an incremental **strangler migration**, not a ground-up rewrite.
18
20
 
19
21
  ## How the boundaries were drawn
20
22
 
@@ -19,6 +19,8 @@ The 26 pages that carry a `*.states.json` (`modules/hall-ui/public/`), each rend
19
19
 
20
20
  Sheets: `<page>--<rank>.webp`, one per page-lane — dark rows above light, 1440 → 390 → 320 left to right, one tile per state. (The atlas sheets are from the second run, with `atlas.json` generated.)
21
21
 
22
+ The `harbor` and `pair` sheets were deleted when those two pages were removed with the dev box ([ADR 0346](../../../adr/0346-dev-boxes-are-retired.md)). The counts and lists below are as walked on 2026-09-02, with both pages in them.
23
+
22
24
  ## Page × rank
23
25
 
24
26
  | page | xenos | metic | archon |
@@ -31,13 +33,11 @@ Sheets: `<page>--<rank>.webp`, one per page-lane — dark rows above light, 1440
31
33
  | gate | 12 · refused (metic+) | 12 · clean | 18 · clean |
32
34
  | goals | 20 · clean | 20 · clean | 30 · clean |
33
35
  | government | 20 · refused (permissions view is archon) | 20 · refused (same) | 30 · clean |
34
- | harbor | 12 · refused (metic+) | 12 · clean | 18 · clean |
35
36
  | idea | 8 · clean | 8 · clean | 12 · clean |
36
37
  | ideas | 8 · clean | 8 · clean | 12 · clean |
37
38
  | index | 16 · clean | 16 · clean | 24 · clean |
38
39
  | modules | 20 · clean | 20 · clean | 30 · clean |
39
40
  | not-ready | 8 · clean | 8 · clean | 12 · clean |
40
- | pair | 8 · clean | 8 · clean | 12 · clean |
41
41
  | people | 12 · clean | 12 · clean | 18 · clean |
42
42
  | primer | 12 · harness (sign-in redirect) | 12 · harness | 18 · harness |
43
43
  | profile | 20 · **defect 1003497** (signed-out links) | 20 · **defect 1003497** | 30 · **defect 1003497** |
@@ -38,7 +38,7 @@ The current hall is **one long single-column page** (`index.html`, `<main>` capp
38
38
 
39
39
  The eleven core widgets (from `hall-widgets.js`, by mount order): **Welcome, Path (onboarding), Standing (profile), Honours (8 laurels), Karma, Acclaim, Works (ships), Marks (grades), Curve (analytics), Bounty (red-team rewards), Roll (leaderboard)** — plus a **Goals** widget (`goals.js`).
40
40
 
41
- Separate full pages behind header links: **Work Board, Primer, Diagrams, Repo Atlas, Ranks, Settings, Pair**, plus Archon-only **Watch, Harbor, Gate**.
41
+ Separate full pages behind header links: **Work Board, Primer, Diagrams, Repo Atlas, Ranks, Settings**, plus Archon-only **Watch, Gate**.
42
42
 
43
43
  The data and the registry seam stay. The redesign changes the **frame** the widgets live in.
44
44
 
@@ -99,7 +99,7 @@ Seven primary destinations plus a gated Admin group. Today's eleven scrolls coll
99
99
  | **Leaderboard** | Roll of the Foremost | Table view | signed-in |
100
100
  | **Docs** | Primer, Diagrams/maps, Repo Atlas | Doc pages + TOC | signed-in |
101
101
  | **Settings** | Settings (all panels) | Sub-nav + panels | signed-in |
102
- | **Admin ▾** | Watch, Harbor, Gate | Grouped, collapsed | **Archon only** |
102
+ | **Admin ▾** | Watch, Gate | Grouped, collapsed | **Archon only** |
103
103
 
104
104
  > Rank/permission gating is **unchanged** — Xenos still don't see Work until graduation; Admin only unhides at `rank=archon`. The redesign moves *where* those links render (into the sidebar), not *whether* they gate.
105
105
 
@@ -152,7 +152,7 @@ Kept close to today's three-section structure (in-progress, claimable, history),
152
152
 
153
153
  ## 7. Surface · Settings — grouped panels
154
154
 
155
- Settings has the most sections today (~15: connections, dev box, box app, craft, display name, wandering, render, art key, CLI, voices, sounds, event sounds…). It gets its own left sub-nav so each group is a focused panel.
155
+ Settings has the most sections today (~13: connections, craft, display name, wandering, render, art key, CLI, voices, sounds, event sounds…). It gets its own left sub-nav so each group is a focused panel.
156
156
 
157
157
  | Component | Type | Placement | Size |
158
158
  |---|---|---|---|
@@ -251,7 +251,7 @@ Not layout, but it rides along. Most of this already flows through the brand pac
251
251
  - Neutral default voice
252
252
 
253
253
  **Deferred**
254
- - Archon pages — Watch, Harbor, Gate (inherit shell only; internal layout unchanged)
254
+ - Archon pages — Watch, Gate (inherit shell only; internal layout unchanged)
255
255
  - Rank-name copy decision
256
256
  - Public apex landing page (separate surface)
257
257
 
package/docs/file-map.md CHANGED
@@ -94,7 +94,7 @@
94
94
  │ ├── <redacted>.sql ← /builder-exit: deactivated builders drop to 'xenos'
95
95
  │ ├── <redacted>.sql ← builders.preferred_disciplines column (enum renamed by mig 086)
96
96
  │ ├── 029_rank_three_live.sql ← #360/ADR 0018: rank default thetes→xenos + tasks.xenos_claimable (three-rank model live)
97
- │ ├── 067_builder_boxes.sql ← #598/ADR 0031: builder_boxes (per-builder dev box lifecycle state) + box_events ledger
97
+ │ ├── 067_builder_boxes.sql ← #598/ADR 0031: the per-builder dev box lifecycle tables; dropped by core_258 (ADR 0346)
98
98
  │ └── <redacted>.sql ← task 615: rename disciplines engineering→engineer, creative→artist|ideator; swaps both CHECK constraints + backfills tasks.discipline & builders.preferred_disciplines
99
99
  ├── modules/ ← self-contained optional feature modules (ADR 0083 / docs/modules-contract.md). Each `modules/<key>/` is a full vertical slice — routes, migrations, skills, seam registrations — reached only through src/module-api.js. The loader discovers them at boot; no core file changes to add one.
100
100
  │ ├── game/ ← the playable Example world — Phaser client, Colyseus rooms (WorldRoom/QueueRoom), world/terrain model, game DB tables, static assets. Moved BV1.R49 (task 1418). CLAUDE.md, module.json, routes/game.js, rooms/, world/, public/, migrations/.
@@ -149,7 +149,7 @@
149
149
  │ ├── gen-file-map.js ← ADR 0066 ([#1276](https://example.com/builders#/task/1276)): generates the `.claude/skills/` + `.claude/scheduled-tasks/` sections of docs/file-map.md from disk; per-entry notes come from docs/file-map.notes.json; `--check` fails on drift OR a skill/routine with no note (CI gate via fitness.js); regenerated on deploy by ship.js regenerateFileMap()
150
150
  │ ├── spike-task-map.js ← (task 1003282, goal 1000072) the task-network-map spike harness: builds a ~1,357-task graph across a swept dependency density, lays it out for real (<redacted> + Barnes-Hut), counts what decides readability (isolated nodes, components, distinguishable marks / overplot, crossings, ink budget, payload) and renders PNGs with a hand-rolled encoder. Zero deps, no DB. `--from <tasks.json>` measures the REAL corpus instead of the model. Verdict: docs/research/task-network-map-readability.md
151
151
  │ ├── fitness.js ← Path C (ADR 0062 §9, [#1225](https://example.com/builders#/task/1225)): architecture fitness functions — core↔host import boundary (zero grandfathered exceptions as of R52/#1191), CLAUDE.md budget + nested-doc presence (ADR 0061), no route bypasses rank checks (reuses route-rank-check), repo-map freshness. Enforced in CI via tests/fitness.mjs (the `unit` gate). `node scripts/gds/fitness.js`
152
- │ ├── ship.js ← resolve claim as shipped, award credits (`/builder-ship`); also uploads a secret-scrubbed session digest to the corpus (6D.1, ADR 0027); on a dev box runs the sandbox-first review gate before resolving (#927, ADR 0046)
152
+ │ ├── ship.js ← resolve claim as shipped, award credits (`/builder-ship`); also uploads a secret-scrubbed session digest to the corpus (6D.1, ADR 0027); runs the sandbox-first review gate before resolving when the checkout has a local game preview (#927, ADR 0046)
153
153
  │ ├── ship-visual.js ← the OPTIONAL `--visual <image> [--visual-alt "…"]` leg of a ship (task 1003109): screens the file BEFORE the claim resolves (bad input costs no claim), uploads it AFTER (a failed picture never fails a ship)
154
154
  │ ├── package-core.js ← package the core as a versioned, installable artifact + pin manifest (`bongos package-core`; R84, ADR 0100 §1, [#1688](https://example.com/builders#/task/1688)): isPublishable() selection + mirror redaction + fail-closed no-leak gate → dist/bongos-core-<version>.{tgz,manifest.json}; version = src/module-api CORE_VERSION. Recipe: docs/recipes/packaging-the-core.md
155
155
  │ ├── release-notes.js ← what each core release brought in (task 1004218): generated at pack time from the ref's HISTORY into the package's release-notes.json (exact per-release ranges, 1 MiB bound; package-core redacts its prose like a doc), read back by the upgrade runner for a from→to range; home of the one merge-summary parser
@@ -208,7 +208,7 @@
208
208
  │ │ ├── catalog.js ← the browsable module catalog model (ADR 0167 / ADR 0107 §2/§3): `source` (which TREE ships it — core package vs instance, read off the loader's discovery root) + resolved author/origin `credit` with an `inferred` flag. The ONE builder behind both `GET /api/bongos/modules` and `bongos module list --catalog`, so the hall + CLI can't drift.
209
209
  │ │ └── semver.js ← minimal semver `satisfies(version, range)` used by the loader (no npm dep).
210
210
  │ ├── platform-server.js ← BONGOS-ONLY entrypoint (ADR 0062 R51, task 1190): boots Express + the shared internal surface (API + hall + status) with NO game in the process; the inverse of preview-server.js. `node src/platform-server.js`
211
- │ ├── preview-server.js ← GAME-ONLY entrypoint for the per-box sandbox (ADR 0052): Phaser/Colyseus + tiles, NO /api/bongos
211
+ │ ├── preview-server.js ← GAME-ONLY entrypoint for the local preview that `/builder-stage` runs (ADR 0052): Phaser/Colyseus + tiles, NO /api/bongos
212
212
  │ ├── seats.js ← in-process seat counter + EventEmitter
213
213
  │ ├── rooms/
214
214
  │ │ ├── WorldRoom.js ← singleton room: move + interact + identity
@@ -221,8 +221,8 @@
221
221
  │ │ ├── routes.js ← thin mounter — imports each routes/* sub-router + every enabled module's routes and stitches them behind kernel-composed auth
222
222
  │ │ ├── api-prefix.js ← API_PREFIX ('/api/bongos') + LEGACY_API_PREFIXES ('/api/gds' permanent alias) + API_VERSION
223
223
  │ │ ├── api-path-404.js ← recognize Bongos-API-shaped paths that missed the mount → JSON 404 + corrective hint (server.js catch-all; V4.R14, [#952](https://example.com/builders#/task/952))
224
- │ │ ├── serve-internal.js ← (ADR 0062 R51, task 1190) the SHARED internal web surface: mountInternalSurfaces(app) wires /healthz + /version + /api/bongos + the Dev Box downloads + the status & builders hosts; called by BOTH server.js (game boot) and platform-server.js (Bongos-only) so the two never drift. Also injects clientBranding() as window.__BRANDING__ into the served hall/status HTML
225
- │ │ ├── routes/ ← one file per KERNEL feature so parallel branches stop colliding on routes.js — the domain routes (tasks/claims/versions/cost/leaderboard/memory/learnings/box/inbox/blockers/search/gate-approvals/discord/…) graduated with their domains into `modules/<key>/routes/`, reached only through the loader
224
+ │ │ ├── serve-internal.js ← (ADR 0062 R51, task 1190) the SHARED internal web surface: mountInternalSurfaces(app) wires /healthz + /version + /api/bongos + the `bongos` CLI downloads + the status & builders hosts; called by BOTH server.js (game boot) and platform-server.js (Bongos-only) so the two never drift. Also injects clientBranding() as window.__BRANDING__ into the served hall/status HTML
225
+ │ │ ├── routes/ ← one file per KERNEL feature so parallel branches stop colliding on routes.js — the domain routes (tasks/claims/versions/cost/leaderboard/memory/learnings/inbox/blockers/search/gate-approvals/discord/…) graduated with their domains into `modules/<key>/routes/`, reached only through the loader
226
226
  │ │ │ ├── _helpers.js ← validateOrRespond, parseId, LIMITS, asyncHandler, publicOrigin, corsPublicGet, parseCookie
227
227
  │ │ │ ├── healthz.js, auth.js, me.js, builders.js, instance.js
228
228
  │ │ │ ├── my-sessions.js ← GET /me/sessions + POST /me/sessions/revoke{,-all} — the OWN-scoped session self-service (task 1003341, ADR 0206): see and kill your own sessions without an Archon. Kept apart from auth.js's admin-gated cross-builder pair so the no-caller-named-owner rule holds over a WHOLE file (tests/own_session_revoke.mjs)
@@ -65,7 +65,7 @@ If even one of these is false, the claim is `[verified-smoke]` or `[implemented-
65
65
 
66
66
  ### Diagram backstop (task [#357](https://example.com/builders#/task/357); conceptual diagrams auto-generated [#436](https://example.com/builders#/task/436))
67
67
 
68
- If your change touched anything the onboarding diagrams describe — the **rank enum or which ranks are wired** (`requireRank`, `builders.rank` default, exit/assign paths), the **task-status set**, the **versions** (id/track/status), or the **complete-architecture** (the ADR 0024 memory chain + the dev-box → production ship flow) **/ example-karma** models (which now flip per the **shipped** status of their backing tasks) — then before shipping:
68
+ If your change touched anything the onboarding diagrams describe — the **rank enum or which ranks are wired** (`requireRank`, `builders.rank` default, exit/assign paths), the **task-status set**, the **versions** (id/track/status), or the **complete-architecture** (the ADR 0024 memory chain + the machine → production ship flow) **/ example-karma** models (which now flip per the **shipped** status of their backing tasks) — then before shipping:
69
69
 
70
70
  - **All five diagrams are auto-generated** by `scripts/gds/gen-diagrams.js` — run it (`node scripts/gds/gen-diagrams.js`) and confirm the result looks right; **do not hand-edit any `.mmd`**. The mechanical three (`01-task-lifecycle`, `02-rank-ladder`, `05-versioning`) regenerate from migrations + the public version API. The conceptual two (`03-example-karma`, `04-architecture`) regenerate from the **authenticated** `/tasks/:id` status of their backing tasks (and 03's seeded-achievement count); if no session is present the generator skips them cleanly. Rendering produces both `.svg` (the pannable viewer asset) and `.png` (fallback).
71
71
  - To change a diagram's **layout or wording**, edit the matching template function in `gen-diagrams.js` — not the `.mmd`. `assertions.json` is rebuilt by the generator in lockstep, so you don't hand-maintain it.
@@ -2637,5 +2637,11 @@ is load-bearing: the script throws rather than guess if it is missing, and
2637
2637
  landed since 1.19.1073 with no explicit bump. run 36510198162. (task 1002620)
2638
2638
  1.19.1075 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
2639
2639
  landed since 1.19.1074 with no explicit bump. run 36512197709. (task 1002620)
2640
+ (note, no bump) — auth.allowBoxScope is now a deprecated no-op (task 1003894).
2641
+ The narrowing session scope it opted a route into, and the three box.*
2642
+ permissions, were removed with the dev box (ADR 0346). The export is kept so
2643
+ the doorway loses nothing inside 1.x; it goes at the next MAJOR.
2644
+ 1.19.1076 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
2645
+ landed since 1.19.1075 with no explicit bump. run 36523068301. (task 1002620)
2640
2646
  ---------------------------------------------------------------------------
2641
2647
  ```
@@ -1,7 +1,7 @@
1
1
  # The module plugin-API contract (`src/module-api.js` + `modules/*/`)
2
2
 
3
3
  > **Decision record:** [ADR 0083](adr/0083-modular-architecture-strangler-build-plan.md) — the build plan.
4
- > **Live state:** the shipped modules under `modules/` are the four feature modules `dev-box`, `game`, `discord`, `art-pipeline` (+ `character-anim`, declaration-only; ADR 0088) and the carved core-domain modules `memory` (R72), `grading` (R73), `economy` (R77), `ideas` (R78), `security` (R79), `builder-settings` (R80), `onboarding` (R81), and `sessions` (R82) — see [ADR 0093](adr/0093-tranche-2-core-carve-sequence.md) for the remaining carve sequence.
4
+ > **Live state:** the shipped modules under `modules/` are the three feature modules `game`, `discord`, `art-pipeline` (+ `character-anim`, declaration-only; ADR 0088) and the carved core-domain modules `memory` (R72), `grading` (R73), `economy` (R77), `ideas` (R78), `security` (R79), `builder-settings` (R80), `onboarding` (R81), and `sessions` (R82) — see [ADR 0093](adr/0093-tranche-2-core-carve-sequence.md) for the remaining carve sequence.
5
5
  > **Author a new module:** jump to [the module-author recipe](#module-author-recipe).
6
6
 
7
7
  The module system turns optional features into self-contained directories. Adding a feature is "drop `modules/<key>/`"; the loader discovers, validates, and mounts it — no core file changes. The **one-way rule** is the load-bearing invariant:
@@ -19,7 +19,7 @@ Two fitness checks enforce it on every build — a violation is a red CI gate, n
19
19
  ## The cut: core vs modules
20
20
 
21
21
  - **Core** is the trust kernel + the lifecycle state machine + the domains not yet carved: auth/identity/audit/rank (the kernel, [ADR 0091](adr/0091-bounding-the-kernel-and-db-carve.md) §1), the lifecycle (tasks, claims, versions, done-when, ship — never split), and the still-core domains (autonomy/MAS, the two web UIs) plus always-on infra (analytics, audit-log, gate-approvals, healthz, public). The remaining tranche-2 domains carve out per [ADR 0093](adr/0093-tranche-2-core-carve-sequence.md) §1; the lifecycle stays core. (Sessions/BFG — the `session_records` corpus + data plane + the BFG scorer + session-pulse — carved to `modules/sessions/` at R82; like `memory` it registers no port and core never calls back in. The per-claim `session_logs` ship LOG + `builder_sessions` auth tokens stay core.)
22
- - **Modules** are optional features an instance turns on via `config/modules.json` or env (the feature modules `dev-box`, `game`, `discord`, `art-pipeline`, `character-anim`), plus the **core-domain modules** that are `default: true` (always on unless disabled): `memory` (R72), `grading` (R73), `economy` — credits/cost/streaks/achievements/leaderboard (R77), `ideas` — inbox/capture/triage/blockers (R78), `security` — red-team reports + bounty (R79), `builder-settings` — wandering/skill/sound/render prefs + builder-needs (R80), `onboarding` — admission/onboarding-state/newcomer-restock (R81), and `sessions` — session_records corpus + BFG + session-pulse (R82). Each is a self-contained directory under `modules/<key>/`.
22
+ - **Modules** are optional features an instance turns on via `config/modules.json` or env (the feature modules `game`, `discord`, `art-pipeline`, `character-anim`), plus the **core-domain modules** that are `default: true` (always on unless disabled): `memory` (R72), `grading` (R73), `economy` — credits/cost/streaks/achievements/leaderboard (R77), `ideas` — inbox/capture/triage/blockers (R78), `security` — red-team reports + bounty (R79), `builder-settings` — wandering/skill/sound/render prefs + builder-needs (R80), `onboarding` — admission/onboarding-state/newcomer-restock (R81), and `sessions` — session_records corpus + BFG + session-pulse (R82). Each is a self-contained directory under `modules/<key>/`.
23
23
 
24
24
  ---
25
25
 
@@ -34,7 +34,7 @@ The **only** core file a module may `require`. It re-exports the kernel capabili
34
34
  | `allowBoxScope` | **Deprecated no-op** (task 1003894): the narrowing session scope it opted a route into was retired, and a session of an undeclared source is now denied on every route regardless. Kept so the doorway loses no export inside 1.x; drop at the next MAJOR. |
35
35
  | `pool` | The shared Postgres pool. A module owns its `<key>_*` tables via its migrations. |
36
36
  | `instanceDbName` | The resolved DB name (from branding). |
37
- | `db` | Kernel-managed DB helpers (`getBuilderById`, `setBuilderBoxBlocked`, `getBuilderGeminiKeyRow`, `setBuilderGeminiKey`, `clearBuilderGeminiKey`, `insertAuditLog`, `createTask`). Grow this additive-only. |
37
+ | `db` | Kernel-managed DB helpers (`getBuilderById`, `getBuilderGeminiKeyRow`, `setBuilderGeminiKey`, `clearBuilderGeminiKey`, `insertAuditLog`, `createTask`). Grow this additive-only. |
38
38
  | `branding` | The branding contract resolver — the resolved instance strings. |
39
39
  | `instanceConfig` | Module enablement config + env override resolution. |
40
40
  | `seams` | The seam registry (`registerProvider`, `hasProvider`, `resolve`, `resolveOptional`, `emit`, `on`) — how modules cooperate without importing each other. |
@@ -76,12 +76,12 @@ Every module must have a `module.json` at its root (`modules/<key>/module.json`)
76
76
 
77
77
  ```jsonc
78
78
  {
79
- "key": "dev-box", // REQUIRED. ^[a-z][a-z0-9-]*$ — must match the dir name.
80
- "title": "Dev boxes", // REQUIRED. Human label.
79
+ "key": "discord", // REQUIRED. ^[a-z][a-z0-9-]*$ — must match the dir name.
80
+ "title": "Discord", // REQUIRED. Human label.
81
81
  "description": "…", // REQUIRED. One sentence.
82
82
  "version": "1.0.0", // REQUIRED. The module's OWN exact version "X.Y.Z" (not a range) —
83
83
  // what update, rollout channels and re-assessment name (task 1003781).
84
- "coreVersion": "^1.2.0", // REQUIRED. semver range of CORE_VERSION this module supports.
84
+ "coreVersion": "^1.4.0", // REQUIRED. semver range of CORE_VERSION this module supports.
85
85
  "default": false, // OPTIONAL (default false). Fail-safe when no config names it.
86
86
  "author": "…", // OPTIONAL. Attribution (ADR 0107 §2) — portable, not a cross-Bongos FK.
87
87
  "origin": "…", // OPTIONAL. Origin instance/project this module was built in.
@@ -95,12 +95,12 @@ Every module must have a `module.json` at its root (`modules/<key>/module.json`)
95
95
  "note": "…" // OPTIONAL. The path out, in one sentence.
96
96
  },
97
97
  "contributes": { // REQUIRED object (may be empty {}).
98
- "routes": ["box"], // route-factory files in routes/ (one export = () => Router())
98
+ "routes": ["discord"], // route-factory files in routes/ (one export = () => Router())
99
99
  "rooms": ["WorldRoom"], // Colyseus room classes (game module only)
100
- "pollers": ["box-lifecycle"], // background pollers (start/stop lifecycle)
100
+ "pollers": ["discord-bot"], // background pollers (start/stop lifecycle)
101
101
  "disciplines": ["artist"], // builder disciplines this module adds
102
102
  "skills": ["otb-tile-generate"], // slash-command skills it ships
103
- "uiSections": ["boxes"], // hall/status UI sections gated by window.__MODULES__. Ship public/hall-widget.js
103
+ "uiSections": ["task-where"], // hall/status UI sections gated by window.__MODULES__. Ship public/hall-widget.js
104
104
  // and it is injected into the hall index; ship public/task-widget.js and it
105
105
  // is injected into a task's page before task.js, to fill #task-contrib on
106
106
  // `otb:task-shown` (task 1004301). The page itself names no module.
@@ -109,7 +109,7 @@ Every module must have a `module.json` at its root (`modules/<key>/module.json`)
109
109
  // apex root (ADR 0218). One or the other, never both.
110
110
  "migrations": true // true → modules/<key>/migrations/*.sql applied if enabled
111
111
  },
112
- "provides": ["box.hasEverConnected"], // OPTIONAL. Seam PORTS this module registers a provider for.
112
+ "provides": ["discord.isLinked"], // OPTIONAL. Seam PORTS this module registers a provider for.
113
113
  "consumes": [], // OPTIONAL. Seam ports this module resolves (required caps).
114
114
  "prerequisites": { "modules": [] }, // OPTIONAL. Other modules that must be enabled first.
115
115
  "spend": { "requiresPayer": true }, // OPTIONAL. This module spends MONEY for whoever calls it.
@@ -196,7 +196,7 @@ The loader is safe-by-construction: with no `modules/` dir it returns empty and
196
196
  env override → config/modules.json → config/modules.neutral.json → manifest.default (false)
197
197
  ```
198
198
 
199
- Env override key: `<envPrefix>_MODULE_<NAME>` (`NAME` = upper-snake of the key; `dev-box` → `DEV_BOX`). Example: `OTB_MODULE_DISCORD=0`.
199
+ Env override key: `<envPrefix>_MODULE_<NAME>` (`NAME` = upper-snake of the key; `npm-release` → `NPM_RELEASE`). Example: `OTB_MODULE_DISCORD=0`.
200
200
 
201
201
  A fresh instance with **no** config resolves to **vanilla**: every module off (fail-to-vanilla).
202
202
 
@@ -218,7 +218,6 @@ A module calls `api.seams.emit(eventName, payload)` to broadcast. Any module tha
218
218
 
219
219
  | Port / Event | Provider | Consumer(s) | Contract |
220
220
  |---|---|---|---|
221
- | Port: `box.hasEverConnected` | `dev-box` | core `routes/me.js`, `routes/builders.js` | `(builderId) → Promise<bool>` — whether the builder's box has ever connected. Core reads via `resolveOptional(…, async () => false)` so onboarding degrades cleanly on a box-less instance. |
222
221
  | Port: `game.staticRoot` | `game` | `server.js` static-serve | `() → string` — absolute path to the game's static root. |
223
222
  | Port: `game.registerRooms` | `game` | `server.js` Colyseus setup | `(matchMaker) → void` — registers WorldRoom + QueueRoom. |
224
223
  | Port: `game.precreateWorldRoom` | `game` | `server.js` pre-create step | `(matchMaker) → Promise<void>` — pre-creates the singleton room. |
@@ -230,7 +229,6 @@ A module calls `api.seams.emit(eventName, payload)` to broadcast. Any module tha
230
229
  | Port: `security` | `security` (R79) | core `routes/public.js` (`/public/bounty-table`) | `{ bountyTableDetailed(), bountyTable() }` — the env-aware red-team bounty payout schedule. Core reads via `resolveOptional('security').bountyTableDetailed()` instead of importing the module (security is default-on; only <redacted> moved — [ADR 0093](adr/0093-tranche-2-core-carve-sequence.md) §1, [02-module-map §5](design/modular-architecture/02-module-map.md)). |
231
230
  | Port: `builder-settings` | `builder-settings` (R80) | core `routes/me.js` (`GET /me`) + `cascade-dispatch.js` | `{ getBuilderBehaviorPrefs, describeWandering, describeRender, computeNeeds, skillCeiling }` — the per-builder prefs read surface. The `GET /me` aggregator resolves it for its wandering/render/needs slices; the dormant cascade router for the skill ceiling. Default-on; degrades gracefully when off ([ADR 0093](adr/0093-tranche-2-core-carve-sequence.md) §1, [02-module-map §2](design/modular-architecture/02-module-map.md)). |
232
231
  | Port: `onboarding` | `onboarding` (R81) | the lifecycle (`db.js` claim/ship — transaction-participant `markStage`) + `auth.js` + `routes/me.js`/`builders.js`/`tasks.js`/`claims.js` | `{ getState, shapeForApi, safeMarkStage, markStage, broadcastGraduation, restockForClaim, restockAll, SOURCE_TAG }` — the onboarding state-machine + newcomer-restock surface. The FIRST core→module port the lifecycle ticks inside its own txn (alongside `reward`). Default-on; degrades to best-effort no-ops when off ([ADR 0093](adr/0093-tranche-2-core-carve-sequence.md) §1). |
233
- | Event: `builder.box-reconcile-needed` | core `db.js` (on rank change / deactivate / auto-graduation) | `dev-box` | `{ builderId, rank, status, actor }` — flags the box for reconciliation. |
234
232
  | Event: `builder.secrets-scrub-needed` | core `db.js` (`deactivateBuilder`) | `art-pipeline` (when installed) | `{ builderId, actor }` — task 1003338 / [ADR 0332](adr/0332-offboarding-secret-scrub-semantics.md): best-effort teardown port for a MODULE-owned builder-keyed secret (today: the Gemini BYOK key, `gemini_key_enc`/`last4`/`set_at`). Core does not write those columns directly (ADR 0102) — the module listens and clears its own store. `github_oauth_tokens` (core-owned) is deleted synchronously inside `deactivateBuilder`'s transaction instead, no event needed. |
235
233
 
236
234
  ---
@@ -264,7 +262,6 @@ Rules (enforced by the `BV1.R45` fitness check):
264
262
 
265
263
  | Module | `contributes` | Seam ports | `coreVersion` |
266
264
  |---|---|---|---|
267
- | **`dev-box`** | routes: `box`; pollers: `box-lifecycle`; uiSections: `boxes` | provides `box.hasEverConnected`; listens `builder.box-reconcile-needed` | `^1.2.0` |
268
265
  | **`game`** | routes: `game`; rooms: `WorldRoom`/`QueueRoom` | provides `game.staticRoot`, `game.registerRooms`, `game.precreateWorldRoom` | `^1.4.0` |
269
266
  | **`discord`** | routes: `discord`, `bug-attachments`; pollers: `discord-bot` | provides `discord.isLinked`; consumes `ideas.capture` | `^1.4.0` |
270
267
  | **`art-pipeline`** | routes: `art-key`; disciplines: `artist`; skills: `otb-tile-generate` etc.; uiSections: `art` | provides `art.sharedKeyConfigured` | `^1.3.0` |