@bongos/core 1.19.1075 → 1.19.1077
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/.bongos-core.json +104 -114
- package/.claude/skills/blocker-solve/SKILL.md +1 -1
- package/README.md +1 -1
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +2 -0
- package/clients/bongos-client/index.cjs +2 -0
- package/clients/bongos-client/index.d.ts +2 -0
- package/clients/bongos-client/index.mjs +2 -0
- package/docs/adr/0031-cloud-dev-environments-for-builders.md +1 -1
- package/docs/adr/0035-builder-onboarding-three-paths.md +1 -1
- package/docs/adr/0044-per-box-live-game-preview.md +1 -1
- package/docs/adr/0045-devbox-desktop-app.md +1 -1
- package/docs/adr/0046-sandbox-first-review-gate.md +1 -1
- package/docs/adr/0052-sandbox-for-everyone-game-only-preview.md +1 -1
- package/docs/adr/0053-scoped-dev-box-session.md +1 -1
- package/docs/adr/0055-server-mediated-branch-publish.md +1 -1
- package/docs/adr/0057-container-cost-ledger.md +1 -1
- package/docs/adr/0059-single-approval-remove-devbox-approval-gate.md +1 -1
- package/docs/adr/0071-box-confirm-before-destroyed-and-drift-reconcile.md +1 -1
- package/docs/adr/0072-bongos-app-mac-signed-first-windows-deferred.md +1 -1
- package/docs/adr/0072-dev-box-code-staleness-visibility.md +1 -1
- package/docs/adr/0104-trust-gds-api-channel-in-auto-mode.md +1 -1
- package/docs/adr/0123-box-idle-sweep-autosave-before-destroy.md +1 -1
- package/docs/adr/0144-devbox-rehome-onto-cloudbongos-plane.md +1 -1
- package/docs/adr/0145-devbox-app-branding-driven-module.md +1 -1
- package/docs/adr/0145-free-hosted-project-tier-isolation-and-domain-separation.md +7 -0
- package/docs/adr/0148-task-scoped-box-source-access.md +2 -2
- package/docs/adr/0151-governance-permissions-as-atom-ranks-as-roles.md +1 -1
- package/docs/adr/0193-pause-task-scoped-box-slices.md +1 -1
- package/docs/adr/0277-a-box-is-in-use-only-while-a-human-is-attached.md +1 -1
- package/docs/adr/0346-dev-boxes-are-retired.md +69 -0
- package/docs/adr/README.md +1 -0
- package/docs/api/openapi.json +22 -1
- package/docs/api-reference.md +3 -2
- package/docs/architecture.md +5 -6
- package/docs/branding-contract.md +2 -2
- package/docs/canonical-permissions.md +10 -18
- package/docs/copy-inventory.md +3 -3
- package/docs/copy-registry.json +3 -3
- package/docs/design/gate-navigation-direction.md +1 -1
- package/docs/design/hall-direction-v2.md +3 -3
- package/docs/design/modular-architecture/00-research-report.md +1 -1
- package/docs/design/modular-architecture/01-architecture.md +3 -3
- package/docs/design/modular-architecture/02-module-map.md +1 -2
- package/docs/design/modular-architecture/03-builder-flows.md +22 -20
- package/docs/design/modular-architecture/04-module-lifecycle.md +1 -1
- package/docs/design/modular-architecture/README.md +4 -2
- package/docs/design/reviews/hall-v2/README.md +2 -2
- package/docs/design/vanilla-hall-ui-redesign-scope.md +4 -4
- package/docs/file-map.md +5 -5
- package/docs/handoff-template.md +1 -1
- package/docs/module-api-changelog.md +8 -0
- package/docs/modules-contract.md +11 -14
- package/docs/page-readings.json +63 -63
- package/docs/recipes/bongos-cli-release.md +1 -2
- package/docs/recipes/multi-builder-merge.md +1 -1
- package/docs/recipes/ops-gotchas.md +0 -9
- package/docs/recipes/self-host.md +1 -1
- package/docs/recipes/windows-builders.md +1 -1
- package/migrations/core_258_drop_dev_box_tables.sql +3 -0
- package/modules/hall-ui/public/palette.js +143 -3
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +28 -0
- package/scripts/gds/dev-box-guard.js +165 -0
- package/scripts/gds/fitness-lib.js +10 -0
- package/scripts/gds/fitness.js +2 -10
- package/scripts/gds/run-unit-tests.js +4 -0
- package/src/bongos/auth.js +8 -1
- package/src/bongos/middleware/rate-limit.js +1 -1
- package/src/bongos/module-scope-map.js +1 -1
- package/src/bongos/routes/auth.js +271 -73
- package/src/module-api.js +1 -1
- package/tests/core_258_box_session_claims_db.mjs +180 -0
- package/tests/fitness.mjs +89 -0
- package/tests/hall_palette.mjs +224 -11
- package/tests/hub_cookie_host_only.mjs +279 -0
- package/tests/landing_page.mjs +4 -1
- package/tests/provisioning_recommendations.mjs +1 -1
- package/tests/session_rename_fallback.mjs +19 -11
- package/tests/subdomain_auth.mjs +17 -15
- package/docs/design/reviews/hall-v2/harbor--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/harbor--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/harbor--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/pair--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/pair--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/pair--xenos.webp +0 -0
package/docs/modules-contract.md
CHANGED
|
@@ -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
|
|
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 `
|
|
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`, `
|
|
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": "
|
|
80
|
-
"title": "
|
|
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.
|
|
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": ["
|
|
98
|
+
"routes": ["discord"], // route-factory files in routes/ (one export = () => Router())
|
|
99
99
|
"rooms": ["WorldRoom"], // Colyseus room classes (game module only)
|
|
100
|
-
"pollers": ["
|
|
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": ["
|
|
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": ["
|
|
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; `
|
|
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` |
|