@bongos/core 1.17.0 → 1.17.2

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 (230) hide show
  1. package/.bongos-core.json +363 -312
  2. package/.claude/skills/blocker-review/SKILL.md +1 -1
  3. package/.claude/skills/builder-claim/SKILL.md +2 -0
  4. package/.claude/skills/builder-exit/SKILL.md +2 -2
  5. package/.claude/skills/builder-redteam/SKILL.md +3 -3
  6. package/.claude/skills/builder-setup/SKILL.md +2 -2
  7. package/.claude/skills/builder-start/SKILL.md +1 -1
  8. package/.claude/skills/dev/SKILL.md +1 -1
  9. package/.claude/skills/idea-triage/SKILL.md +2 -2
  10. package/.claude/skills/ideate/SKILL.md +1 -1
  11. package/.claude/skills/merge-mode/SKILL.md +1 -1
  12. package/.claude/skills/new-project/SKILL.md +3 -0
  13. package/.claude/skills/paint/SKILL.md +1 -1
  14. package/CLAUDE.md +11 -238
  15. package/GOVERNANCE.md +1 -1
  16. package/README.md +1 -1
  17. package/bin/bongos.js +1 -0
  18. package/clients/bongos-client/README.md +4 -4
  19. package/clients/bongos-client/bongos-client.global.js +14 -1
  20. package/clients/bongos-client/index.cjs +14 -1
  21. package/clients/bongos-client/index.d.ts +19 -2
  22. package/clients/bongos-client/index.mjs +11 -1
  23. package/clients/bongos-client/package.json +1 -1
  24. package/docs/adr/0001-stack-choice-single-vps.md +1 -1
  25. package/docs/adr/0008-google-chat-oauth-user-auth.md +1 -1
  26. package/docs/adr/0019-red-team-bounty-payout-table.md +3 -3
  27. package/docs/adr/0020-security-model-public-stub.md +1 -1
  28. package/docs/adr/0023-kind-multipliers-and-idea-bonus.md +1 -1
  29. package/docs/adr/0024-cloneable-repo-local-first-memory.md +1 -1
  30. package/docs/adr/0026-bfg-memory-hygiene-and-cross-builder-learning.md +4 -4
  31. package/docs/adr/0027-bfg-session-inefficiency-evaluator.md +3 -3
  32. package/docs/adr/0030-builders-hall-live-updates.md +1 -1
  33. package/docs/adr/0031-cloud-dev-environments-for-builders.md +4 -4
  34. package/docs/adr/0032-discord-mirror-of-gds.md +2 -2
  35. package/docs/adr/0034-thetes-graduated-newcomer-rank.md +1 -1
  36. package/docs/adr/0044-mediterranean-palette-replacement.md +1 -1
  37. package/docs/adr/0044-per-box-live-game-preview.md +1 -1
  38. package/docs/adr/0054-session-token-reward-cost-plus.md +10 -10
  39. package/docs/adr/0057-container-cost-ledger.md +3 -3
  40. package/docs/adr/0062-medusa-instance-model-decoupling.md +4 -4
  41. package/docs/adr/0065-agpl-nonprofit-ai-first-governance.md +2 -2
  42. package/docs/adr/0085-remove-default-per-builder-spend-cap.md +1 -1
  43. package/docs/adr/0086-goal-scoped-work-hierarchy.md +1 -1
  44. package/docs/adr/0096-require-reward-before-workable.md +9 -9
  45. package/docs/adr/0097-retroactive-reward-backfill.md +3 -3
  46. package/docs/adr/0100-two-repo-instance-model.md +1 -1
  47. package/docs/adr/0101-goal-hierarchy-phase-5-judge-membership-reward.md +3 -3
  48. package/docs/adr/0103-core-first-extraction-cloud-bongos-trunk.md +3 -3
  49. package/docs/adr/0107-module-upstreaming-contribution-to-core-catalog.md +1 -1
  50. package/docs/adr/0120-pay-on-land-and-builder-owned-rebase-gate.md +6 -6
  51. package/docs/adr/0133-github-app-manifest-onboarding-signin.md +2 -0
  52. package/docs/adr/0134-private-first-npm-distribution.md +20 -6
  53. package/docs/adr/0135-module-upstream-submission-interim-queue.md +34 -0
  54. package/docs/adr/0136-update-channel-subscription-policy.md +51 -0
  55. package/docs/adr/0137-upstream-publish-policy-manual-owner-gated.md +40 -0
  56. package/docs/adr/0138-bundled-module-deps-declared-per-module.md +45 -0
  57. package/docs/adr/README.md +14 -10
  58. package/docs/api/openapi.json +315 -6
  59. package/docs/api-reference.md +10 -5
  60. package/docs/architecture.md +3 -3
  61. package/docs/branding-contract.md +5 -4
  62. package/docs/canonical-permissions.md +1 -1
  63. package/docs/design/vanilla-hall-ui-redesign-scope.md +1 -1
  64. package/docs/file-map.md +20 -19
  65. package/docs/handoff-template.md +2 -2
  66. package/docs/modules-contract.md +8 -1
  67. package/docs/onboarding/diagrams/README.md +7 -7
  68. package/docs/onboarding/drachmae-and-karma.md +18 -18
  69. package/docs/onboarding/primer.md +9 -9
  70. package/docs/recipes/audit-replay.md +2 -2
  71. package/docs/recipes/builder-box-lifecycle.md +2 -2
  72. package/docs/recipes/claude-design-loop.md +1 -1
  73. package/docs/recipes/instance-deploy.md +4 -4
  74. package/docs/recipes/instance-first-run.md +51 -0
  75. package/docs/recipes/ops-gotchas.md +1 -1
  76. package/docs/recipes/packaging-the-core.md +5 -5
  77. package/docs/recipes/private-npm-distribution.md +39 -12
  78. package/docs/recipes/self-host.md +1 -1
  79. package/docs/recipes/staging-environment.md +1 -1
  80. package/docs/recipes/upgrading-the-core.md +63 -8
  81. package/docs/research/cursor-competitive-analysis.md +1 -1
  82. package/docs/research/llm-model-agnostic-and-cheaper-grader.md +1 -1
  83. package/migrations/core_191_module_submissions.sql +45 -0
  84. package/modules/autonomy/CLAUDE.md +11 -45
  85. package/modules/builder-settings/CLAUDE.md +11 -54
  86. package/modules/dev-box/CLAUDE.md +11 -34
  87. package/modules/discord/CLAUDE.md +11 -46
  88. package/modules/discord/module.json +2 -1
  89. package/modules/economy/CLAUDE.md +11 -44
  90. package/modules/economy/achievements.js +9 -1
  91. package/modules/economy/credits.js +10 -1
  92. package/modules/grading/CLAUDE.md +11 -38
  93. package/modules/hall-ui/CLAUDE.md +11 -57
  94. package/modules/hall-ui/public/builders.js +71 -4
  95. package/modules/hall-ui/public/goal-inbox.js +191 -0
  96. package/modules/hall-ui/public/goals-page.js +227 -22
  97. package/modules/hall-ui/public/goals.html +16 -0
  98. package/modules/hall-ui/public/hall-widgets.js +14 -1
  99. package/modules/hall-ui/public/index.html +3 -0
  100. package/modules/hall-ui/public/new-project-wizard.js +6 -4
  101. package/modules/hall-ui/public/style.css +43 -0
  102. package/modules/ideas/CLAUDE.md +11 -33
  103. package/modules/lifecycle/CLAUDE.md +11 -59
  104. package/modules/lifecycle/routes/goals.js +80 -0
  105. package/modules/memory/CLAUDE.md +11 -36
  106. package/modules/onboarding/CLAUDE.md +11 -51
  107. package/modules/provisioning/CLAUDE.md +15 -0
  108. package/modules/provisioning/migrations/provisioning_001_tables.sql +160 -0
  109. package/modules/provisioning/migrations/provisioning_002_standalone_shape.sql +11 -0
  110. package/modules/provisioning/migrations/provisioning_003_github_app_manifest.sql +95 -0
  111. package/modules/provisioning/module.json +17 -0
  112. package/modules/provisioning/onboard-plan.js +37 -0
  113. package/modules/provisioning/provisioning.js +539 -0
  114. package/modules/provisioning/rate-limit.js +35 -0
  115. package/modules/provisioning/routes/provisioning.js +607 -0
  116. package/modules/provisioning/tests/provisioning.mjs +232 -0
  117. package/modules/provisioning/ui/.gitkeep +0 -0
  118. package/modules/security/CLAUDE.md +11 -40
  119. package/modules/security/secret-scrub.js +10 -0
  120. package/modules/sessions/CLAUDE.md +11 -35
  121. package/modules/status-ui/CLAUDE.md +11 -43
  122. package/package-lock.json +2 -2
  123. package/package.json +7 -2
  124. package/public-landing/create.html +58 -12
  125. package/public-landing/index.html +40 -21
  126. package/scripts/discord/README.md +1 -1
  127. package/scripts/gds/CLAUDE.md +11 -140
  128. package/scripts/gds/claim.js +98 -48
  129. package/scripts/gds/claude-materialize.js +174 -20
  130. package/scripts/gds/claude-md-template.js +84 -0
  131. package/scripts/gds/cli-lib.js +112 -2
  132. package/scripts/gds/cutover-codemod.js +241 -0
  133. package/scripts/gds/fitness.js +54 -0
  134. package/scripts/gds/gen-api-client.js +10 -10
  135. package/scripts/gds/init.js +112 -16
  136. package/scripts/gds/lint-infra-exec.js +70 -0
  137. package/scripts/gds/lint-workflow-exec.js +63 -0
  138. package/scripts/gds/migration-namespace.js +1 -1
  139. package/scripts/gds/mirror-lineage-check.js +14 -5
  140. package/scripts/gds/mirror-redact.js +8 -0
  141. package/scripts/gds/module.js +118 -4
  142. package/scripts/gds/npmrc.js +93 -0
  143. package/scripts/gds/onboard.js +17 -24
  144. package/scripts/gds/package-core.js +74 -17
  145. package/scripts/gds/provision.js +102 -17
  146. package/scripts/gds/publish-manifest.js +60 -2
  147. package/scripts/gds/run-routine.js +51 -13
  148. package/scripts/gds/run-unit-tests.js +4 -0
  149. package/scripts/gds/seed-adopt-tasks.js +1 -1
  150. package/scripts/gds/status.js +6 -1
  151. package/scripts/gds/task.js +166 -0
  152. package/scripts/gds/update-channel.js +186 -0
  153. package/scripts/gds/upgrade.js +172 -25
  154. package/src/bongos/CLAUDE.md +11 -60
  155. package/src/bongos/auth.js +24 -0
  156. package/src/bongos/module-submissions.js +56 -0
  157. package/src/bongos/route-rank-check.js +6 -0
  158. package/src/bongos/routes/CLAUDE.md +11 -39
  159. package/src/bongos/routes/auth.js +6 -1
  160. package/src/bongos/routes/modules.js +123 -21
  161. package/src/bongos/serve-internal.js +10 -1
  162. package/src/branding.js +1 -0
  163. package/src/instance-config.js +1 -1
  164. package/src/module-api.js +24 -1
  165. package/src/module-loader/loader.js +36 -4
  166. package/src/module-loader/manifest-schema.js +16 -1
  167. package/tests/branding.mjs +11 -0
  168. package/tests/claim_error_surface.mjs +107 -0
  169. package/tests/claude_materialize.mjs +125 -0
  170. package/tests/consumer_layout_boot.mjs +302 -0
  171. package/tests/cutover_codemod.mjs +184 -0
  172. package/tests/device_flow_start.mjs +96 -0
  173. package/tests/first_run_engine_check.mjs +79 -0
  174. package/tests/goal_membership_requests.mjs +33 -3
  175. package/tests/hook_core_resolve.mjs +125 -0
  176. package/tests/hook_user_agents.mjs +62 -0
  177. package/tests/infra_exec_paths.mjs +104 -0
  178. package/tests/init.mjs +106 -6
  179. package/tests/instance_mismatch_guard.mjs +101 -0
  180. package/tests/mirror_lineage_proof.mjs +14 -0
  181. package/tests/module_cli.mjs +130 -2
  182. package/tests/module_loader.mjs +42 -0
  183. package/tests/module_manifest.mjs +19 -0
  184. package/tests/module_submissions.mjs +135 -0
  185. package/tests/npmrc.mjs +105 -0
  186. package/tests/onboard.mjs +62 -0
  187. package/tests/package_core.mjs +76 -22
  188. package/tests/platform_boot.mjs +5 -2
  189. package/tests/provision.mjs +107 -8
  190. package/tests/provisioning_github_app_routes.mjs +44 -2
  191. package/tests/publish_manifest.mjs +52 -1
  192. package/tests/run_routine.mjs +26 -1
  193. package/tests/run_routine_two_root.mjs +77 -0
  194. package/tests/scrubber_corpus.mjs +17 -0
  195. package/tests/served_paths_shipped.mjs +2 -2
  196. package/tests/task_cli.mjs +99 -0
  197. package/tests/update_channel.mjs +186 -0
  198. package/tests/upgrade.mjs +220 -25
  199. package/tests/workflow_exec_paths.mjs +98 -0
  200. package/docs/design/container-exterior-tiles.md +0 -49
  201. package/docs/design/container-exterior.md +0 -81
  202. package/docs/design/container-interior.md +0 -77
  203. package/docs/design/world-map-scroll.md +0 -41
  204. package/docs/recipes/claude-gemini-bongos-doors.md +0 -155
  205. package/docs/recipes/cloudbongos-staging-gate.md +0 -139
  206. package/docs/recipes/cloudbongos-standup.md +0 -111
  207. package/docs/recipes/parallel-load-results-2026-05-30.md +0 -63
  208. package/docs/recipes/parallel-load-test.md +0 -32
  209. package/docs/recipes/pixel-art-pipeline.md +0 -411
  210. package/docs/recipes/staging-data.md +0 -50
  211. package/migrations/instance/018_pms_v3_planning_seed.sql +0 -131
  212. package/migrations/instance/080_gds_v4_planning_seed.sql +0 -75
  213. package/migrations/instance/110_medusa_planning_seed.sql +0 -70
  214. package/migrations/instance/120_bongos_v1_planning_seed.sql +0 -69
  215. package/migrations/instance/144_bongos_v1_module_system_criterion.sql +0 -26
  216. package/migrations/instance/159_bongos_v1_goal_hierarchy_criterion.sql +0 -29
  217. package/migrations/instance/172_v2_world_planning_seed.sql +0 -163
  218. package/migrations/instance/173_bongos_v1_c7_core_modularized.sql +0 -33
  219. package/migrations/instance/182_gdsv4_bongos_consolidation.sql +0 -132
  220. package/migrations/instance/183_gdsv4_carryover_themed_goals.sql +0 -116
  221. package/migrations/instance/186_bongos_v1_governance_planning_seed.sql +0 -69
  222. package/scripts/gds/art-stage.js +0 -152
  223. package/server.js +0 -212
  224. package/tests/art_key.mjs +0 -121
  225. package/tests/day_cycle.mjs +0 -197
  226. package/tests/snapshot_picker.mjs +0 -233
  227. package/tests/sprite_facing.mjs +0 -35
  228. package/tests/terrain_picker.mjs +0 -298
  229. package/tests/turn_in_place.mjs +0 -280
  230. package/tests/walkability.mjs +0 -188
@@ -1,15 +1,15 @@
1
1
  # Recipe — private-first npm distribution (core + client)
2
2
 
3
- > Implements [ADR 0134](../adr/<redacted>.md). Pre-launch, `@cloudbongos/core` and `@cloudbongos/client` publish as **private, scoped** npm packages on a paid `cloudbongos` npm org; at launch they flip to public. The daily command is `bongos` regardless of package name.
3
+ > Implements [ADR 0134](../adr/<redacted>.md). Pre-launch, `@bongos/core` and `@bongos/client` publish as **private, scoped** npm packages on the owner's paid `bongos` npm org (the canonical brand); at launch they flip to public. The daily command is `bongos` regardless of package name.
4
4
  >
5
- > **Why private must be scoped:** on npm, *unscoped* names (like `cloudbongos`) are always public — only *scoped* names (`@cloudbongos/…`) can be private, and only on a paid plan. The repo already uses the `@cloudbongos` scope, so no rename is needed now.
5
+ > **Why private must be scoped:** on npm, *unscoped* names are always public — only *scoped* names (`@bongos/…`) can be private, and only on a paid plan. So the packages publish under the `@bongos` scope, which maps to the paid `bongos` org.
6
6
 
7
7
  ## The pieces
8
8
 
9
9
  | Package | What it is | Built by |
10
10
  |---|---|---|
11
- | `@cloudbongos/core` | the platform an instance installs + the `bongos` CLI (`bin`) | `bongos package-core` (`scripts/gds/package-core.js`) — synthesizes the package.json + a pruned lockfile, redacts, and packs a `.tgz` |
12
- | `@cloudbongos/client` | the generated typed API client | `node scripts/gds/gen-api-client.js` (regenerates `clients/bongos-client/`) |
11
+ | `@bongos/core` | the platform an instance installs + the `bongos` CLI (`bin`) | `bongos package-core` (`scripts/gds/package-core.js`) — synthesizes the package.json + a pruned lockfile, redacts, and packs a `.tgz` |
12
+ | `@bongos/client` | the generated typed API client | `node scripts/gds/gen-api-client.js` (regenerates `clients/bongos-client/`) |
13
13
 
14
14
  Both carry `publishConfig: { access: "restricted" }`, so **publishing them is private by default** — no public leak if a flag is forgotten.
15
15
 
@@ -17,8 +17,8 @@ Both carry `publishConfig: { access: "restricted" }`, so **publishing them is pr
17
17
 
18
18
  These involve payment and permanent, account-level actions. They are **not** done inside a build session.
19
19
 
20
- 1. **Put the `cloudbongos` npm org on a paid plan.** Private scoped publishing requires it. On npmjs.com → your org → Billing → upgrade to a plan that allows private packages (npm Teams, ~$7/member/month). Add as members only the people who need to publish or install during pre-launch — each is a billed seat.
21
- 2. **Create an access token.** npmjs.com → Access Tokens → *Generate New Token* → **Granular/Automation**, with **read-write** on the `@cloudbongos` packages (for publishing) — a **read-only** token is enough for machines that only install. Store it as an environment variable, never in a committed file:
20
+ 1. **Put the `bongos` npm org on a paid plan.** Private scoped publishing requires it. On npmjs.com → your org → Billing → upgrade to a plan that allows private packages (npm Teams, ~$7/member/month). Add as members only the people who need to publish or install during pre-launch — each is a billed seat.
21
+ 2. **Create an access token.** npmjs.com → Access Tokens → *Generate New Token* → **Classic → Automation** (bypasses 2FA, which npm requires to publish), with **read-write** on the `@bongos` packages — a **read-only** token is enough for machines that only install. Store it as an environment variable, never in a committed file:
22
22
  ```sh
23
23
  export NPM_TOKEN=<redacted>
24
24
  ```
@@ -32,7 +32,7 @@ Always preview with a dry-run first (no upload, no login needed):
32
32
  node scripts/gds/package-core.js --publish
33
33
  ```
34
34
 
35
- Look for `restricted access` and the `@cloudbongos/core@<version>` line. When it looks right, publish for real (this is **permanent** — npm can't delete a name after 72h):
35
+ Look for `restricted access` and the `@bongos/core@<version>` line. When it looks right, publish for real (this is **permanent** — npm can't delete a name after 72h):
36
36
 
37
37
  ```sh
38
38
  npm login # once per machine (+ 2FA)
@@ -47,6 +47,23 @@ npm pack ./clients/bongos-client --dry-run # token-free content preview
47
47
  npm publish ./clients/bongos-client # real (publishConfig makes it restricted; needs npm login)
48
48
  ```
49
49
 
50
+ ## Cutting a core release (the policy — [ADR 0137](../adr/<redacted>.md))
51
+
52
+ Publishing is a **manual, owner-gated step** — merges to `main` do **not** auto-publish (no npm write-token lives in CI). The update subscription ([ADR 0136](../adr/<redacted>.md)) consumes whatever the owner has published, so a release is exactly: bump → publish → the subscription picks it up on its next sweep.
53
+
54
+ 1. **Bump `CORE_VERSION`** in [`src/module-api.js`](../../src/module-api.js) (semver; a **patch** for a fix, **minor** for additive surface — a **major** is a deliberate, human-only event) and add a one-line changelog entry in the same file. This bump is a normal claimed task, not a release-tool side effect — the version's provenance stays in the git history + changelog.
55
+ 2. **Publish** (owner, from a clean checkout of the released commit):
56
+ ```sh
57
+ node scripts/gds/package-core.js --publish # DRY-RUN: runs the fail-closed no-leak gate, previews @bongos/core@<version>
58
+ npm login # once per machine (+ 2FA), or use a Classic Automation token
59
+ node scripts/gds/package-core.js --publish --live # permanent; the no-leak gate must pass or nothing is built/uploaded
60
+ ```
61
+ The no-leak / mirror-redact gate is **built into the build** — a leaking artifact is never produced, so `--publish` cannot upload one.
62
+ 3. **Tag the release** (optional but recommended — the deliberate, auditable marker): `git tag core-v<version> && git push origin core-v<version>`. The tag documents intent; it triggers no CI.
63
+ 4. **Done.** Subscribed instances on the `patch`/`minor` channel take it automatically on their next routine sweep; `pinned` instances wait for a manual `bongos upgrade`. A stale (un-bumped) version is rejected by npm as a duplicate — a natural guard.
64
+
65
+ > **Automating this** (a tag-triggered CI publish) is deferred to the managed-fleet epic ([#1948](https://example.com/builders#/task/1948)); revisit when the manual step becomes a real bottleneck. See [ADR 0137](../adr/<redacted>.md) "When to revisit".
66
+
50
67
  ## Install a private package (any consumer machine or instance)
51
68
 
52
69
  Add a one-line `.npmrc` (repo-root or `~/.npmrc`) that reads the token from the environment:
@@ -58,13 +75,23 @@ Add a one-line `.npmrc` (repo-root or `~/.npmrc`) that reads the token from the
58
75
  Then, with `NPM_TOKEN` set in the environment:
59
76
 
60
77
  ```sh
61
- npm install -g @cloudbongos/core # global → the `bongos` command, then `bongos init`
62
- npm install @cloudbongos/client # in a project that calls the API
78
+ npm install -g @bongos/core # global → the `bongos` command, then `bongos init`
79
+ npm install @bongos/client # in a project that calls the API
63
80
  ```
64
81
 
65
82
  Without a valid token + org membership the install 404s — that is the private gate working.
66
83
 
67
- > Provisioning still installs the core from a **vendored tarball** committed into each instance repo (task 2053) — that path is unchanged and needs no token. Wiring provisioning to pull the pinned core from the private registry instead is a tracked follow-up.
84
+ ## Provisioning: registry pull vs vendored tarball (task 2090)
85
+
86
+ Provisioning defaults to installing the core from a **vendored tarball** committed into each instance repo (task 2053) — offline, needs no token, and stays the default/fallback until the registry path is proven on a real greenfield standup. The registry pull is **opt-in and fail-soft**:
87
+
88
+ - **Turn it on** by setting `PROVISION_CORE_FROM_REGISTRY=1` in the control-plane runner's environment (e.g. `/etc/cloudbongos/box.env`) **and** providing a read-only `NPM_TOKEN` (a Classic **Automation** token — read-only — from the paid `bongos` org). With both present, the standalone scaffold pins `@bongos/core@<version>` from the registry and writes an env-fed `.npmrc` (`_authToken=<redacted> instead of vendoring a tarball; `npm ci` then pulls the private package (the token is inherited from the runner env — never committed).
89
+ - **Fail-soft**: if the flag is set but `NPM_TOKEN` is absent, provisioning logs a notice and **falls back to the vendored tarball**, so a tokenless standup still works.
90
+ - **Directly**: `bongos init --registry-core` scaffolds the registry shape (caret pin + `.npmrc`; generates the lockfile when `NPM_TOKEN` is set). `bongos upgrade --to <v> --registry` bumps a consumer to a registry version. Both are mutually exclusive with the vendored `--vendor-core` / `--from` inputs.
91
+
92
+ A tokenless registry `npm ci` 404s cleanly (`E404 … @bongos/core … could not be found or you do not have permission to access it`) — the expected pre-launch outcome.
93
+
94
+ > **Proven end-to-end (2026-07-08, task 2118 / blocker 71).** A real `bongos init --registry-core` scaffold, with a valid read-only token in `NPM_TOKEN`, resolved `@bongos/core@1.17.0` straight from `registry.npmjs.org` and generated a reproducible `package-lock.json`. Both legs are confirmed: the registry pull works with a token and fails closed (404) without one. Provisioning still defaults to the vendored tarball until an owner explicitly sets `PROVISION_CORE_FROM_REGISTRY=1` on a live runner.
68
95
 
69
96
  ## Going public at launch
70
97
 
@@ -72,8 +99,8 @@ Pick either — both keep the daily `bongos` command working:
72
99
 
73
100
  - **Flip the same scoped packages public** (simplest):
74
101
  ```sh
75
- npm access public @cloudbongos/core
76
- npm access public @cloudbongos/client
102
+ npm access public @bongos/core
103
+ npm access public @bongos/client
77
104
  ```
78
105
  (Or change `publishConfig.access` to `"public"` and republish.) Public installs need no token; the paid seats can be dropped.
79
106
  - **Also publish the unscoped vanity name** for `npm install -g cloudbongos` — that is [task 2025](https://example.com/builders#/task/2025) (rename in `package-core.js`/`upgrade.js` + docs), done at launch.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Bring up a vanilla Cloud Bongos instance — the build platform + builders' hall + status dashboard, with no game — on any machine with Docker. Shipped by V4.R63 ([task #1202](https://example.com/builders#/task/1202), [ADR 0062](../adr/<redacted>.md)).
4
4
 
5
- > **Relation to configurable-root ([ADR 0108](../adr/<redacted>.md)):** this is the **single-checkout** self-host shape — the whole repo (core + config) is baked into one image, so `resolveCoreRoot()` and `resolveInstanceRoot()` ([`src/instance-config.js`](../../src/instance-config.js)) both resolve to `/app` inside the container. ADR 0108 does not deprecate this path — it stays the cheap, supported shape for a quick reskin (this is how `cloudbongos.com` runs). The *installed-as-a-dependency* shape (a consumer repo running `npm install @cloudbongos/core`) is the separate, heavier path ADR 0108 targets for a project that wants its own repo and its own upgrade cadence — see [`docs/recipes/packaging-the-core.md`](packaging-the-core.md).
5
+ > **Relation to configurable-root ([ADR 0108](../adr/<redacted>.md)):** this is the **single-checkout** self-host shape — the whole repo (core + config) is baked into one image, so `resolveCoreRoot()` and `resolveInstanceRoot()` ([`src/instance-config.js`](../../src/instance-config.js)) both resolve to `/app` inside the container. ADR 0108 does not deprecate this path — it stays the cheap, supported shape for a quick reskin (this is how `cloudbongos.com` runs). The *installed-as-a-dependency* shape (a consumer repo running `npm install @bongos/core`) is the separate, heavier path ADR 0108 targets for a project that wants its own repo and its own upgrade cadence — see [`docs/recipes/packaging-the-core.md`](packaging-the-core.md).
6
6
 
7
7
  ## One command
8
8
 
@@ -65,7 +65,7 @@ If `*.example.com` is **not** in the output:
65
65
  The prod OAuth app points its callback at `example.com/api/gds/auth/web/callback`. Staging needs its own:
66
66
 
67
67
  1. github.com → Settings → Developer settings → OAuth Apps → New OAuth App.
68
- 2. Application name: `Off the Boats — staging`.
68
+ 2. Application name: `Example — staging`.
69
69
  3. Homepage URL: `https://staging.example.com`.
70
70
  4. Authorization callback URL: `https://staging.example.com/api/gds/auth/web/callback`.
71
71
  5. Note the **Client ID** and **Client Secret** — they go into `/home/lars/example-staging/.env` (see step 4 of the provisioning script).
@@ -1,18 +1,19 @@
1
1
  # Recipe — upgrading a consumer instance's Cloud Bongos core (`bongos upgrade`)
2
2
 
3
- > The R86 update-consumption channel ([ADR 0100](../adr/<redacted>.md) §2, [ADR 0103](../adr/<redacted>.md) §4, task [#1690](https://example.com/builders#/task/1690)). How a **two-repo consumer instance** — one that installs `@cloudbongos/core` as a vendored-tarball dependency — pulls the core from version N → N+1. Tooling: [`scripts/gds/upgrade.js`](../../scripts/gds/upgrade.js) (`bongos upgrade`). First proven live on emersonian-circles 1.15.0 → 1.16.0 (task [#1976](https://example.com/builders#/task/1976)).
3
+ > The R86 update-consumption channel ([ADR 0100](../adr/<redacted>.md) §2, [ADR 0103](../adr/<redacted>.md) §4, task [#1690](https://example.com/builders#/task/1690)). How a **two-repo consumer instance** — one that installs `@bongos/core` as a vendored-tarball dependency — pulls the core from version N → N+1. Tooling: [`scripts/gds/upgrade.js`](../../scripts/gds/upgrade.js) (`bongos upgrade`). First proven live on emersonian-circles 1.15.0 → 1.16.0 (task [#1976](https://example.com/builders#/task/1976)).
4
4
 
5
5
  ## What the channel does
6
6
 
7
7
  `bongos upgrade --to <version> --from <tgz>` runs, from a consumer instance root:
8
8
 
9
9
  1. **pre-flight** — module-compat vs the target core + a clean git tree (skip with `--force`).
10
- 2. **bump the pin** — vendor the new `cloudbongos-core-<version>.tgz` and rewrite the `"@cloudbongos/core": "file:vendor/…"` dependency.
11
- 3. **`npm install`** — `node_modules/@cloudbongos/core` becomes the new version.
10
+ 2. **bump the pin** — vendor the new `bongos-core-<version>.tgz` and rewrite the `"@bongos/core": "file:vendor/…"` dependency.
11
+ 3. **`npm install`** — `node_modules/@bongos/core` becomes the new version.
12
12
  4. **`npm run migrate`** — the core's `migrate.sh` applies additive `core_*` migrations (merged three-root: core + instance + modules).
13
13
  5. **materialize `.claude/`** — refresh skills/settings/hooks from the new core (`materializeClaude`), rewriting invocations to the `bongos` bin.
14
14
  6. **restart** — `--service <unit>` or `--restart-cmd "<cmd>"`.
15
15
  7. **verify** — installed version == target (+ optional `--health-url`).
16
+ 8. **auto-rollback on failure** (task [#2149](https://example.com/builders#/task/2149), default ON) — if `npm install`/`migrate` fails or the step-7 health check fails, revert the pin → reinstall the previous core → restart → re-verify → write a `rolled_back:` ledger row. Opt out with `--no-rollback-on-failure`. See the section below.
16
17
 
17
18
  Run bare (`bongos upgrade`, no `--to`) it stays the module-compat **pre-check** only.
18
19
 
@@ -21,8 +22,8 @@ Run bare (`bongos upgrade`, no `--to`) it stays the module-compat **pre-check**
21
22
  The channel ships *in* the core. On the FIRST bump, the consumer's installed core is the OLD version (whose `bongos upgrade` may be the pre-check stub or lack a fix). So drive the first bump with the **new version's** `upgrade.js`, run out of its extracted package against `--instance <consumer>`:
22
23
 
23
24
  ```bash
24
- cd /tmp && rm -rf pkg && mkdir pkg && tar xzf cloudbongos-core-<version>.tgz -C pkg
25
- node /tmp/pkg/package/scripts/gds/upgrade.js --to <version> --from /tmp/cloudbongos-core-<version>.tgz --instance <consumer-root> …
25
+ cd /tmp && rm -rf pkg && mkdir pkg && tar xzf bongos-core-<version>.tgz -C pkg
26
+ node /tmp/pkg/package/scripts/gds/upgrade.js --to <version> --from /tmp/bongos-core-<version>.tgz --instance <consumer-root> …
26
27
  ```
27
28
 
28
29
  Once a consumer is on a core that carries the channel, its own `bongos upgrade` drives later bumps.
@@ -33,15 +34,15 @@ The instance runs on the droplet (co-tenant): systemd `emersonian-circles.servic
33
34
 
34
35
  1. **Cut the canonical tarball from `main`** (after the core change has merged, so the pin is a real release):
35
36
  ```bash
36
- node scripts/gds/package-core.js --version <version> # → dist/cloudbongos-core-<version>.tgz (+ manifest)
37
+ node scripts/gds/package-core.js --version <version> # → dist/bongos-core-<version>.tgz (+ manifest)
37
38
  ```
38
- `package-core` archives committed `HEAD`, **not the working tree** — commit + merge first, then verify the artifact (`ls dist/cloudbongos-core-<version>/…`).
39
+ `package-core` archives committed `HEAD`, **not the working tree** — commit + merge first, then verify the artifact (`ls dist/bongos-core-<version>/…`).
39
40
  2. **Back up the instance DB** — `pg_dump emersonian_circles | gzip > /tmp/…sql.gz`.
40
41
  3. **`scp` the tarball to the droplet**, verify `sha256sum` matches.
41
42
  4. **`--dry-run` first**, then the real run — extracted-package bootstrap, with the instance DB pinned:
42
43
  ```bash
43
44
  PGDATABASE=emersonian_circles CLOUDBONGOS_INSTANCE_ROOT=/home/lars/emersonian-circles \
44
- node /tmp/pkg/package/scripts/gds/upgrade.js --to <version> --from /tmp/cloudbongos-core-<version>.tgz \
45
+ node /tmp/pkg/package/scripts/gds/upgrade.js --to <version> --from /tmp/bongos-core-<version>.tgz \
45
46
  --instance /home/lars/emersonian-circles \
46
47
  --restart-cmd "sudo systemctl restart emersonian-circles.service" \
47
48
  --health-url http://127.0.0.1:3004/healthz
@@ -50,6 +51,60 @@ The instance runs on the droplet (co-tenant): systemd `emersonian-circles.servic
50
51
  6. **Update the repo of record** — run the channel on the laptop clone (`--skip-migrate`, no DB there), commit the pin bump (drop the superseded tarball), `git push origin`.
51
52
  7. **Align the droplet checkout** — the droplet has no deploy key (`git pull` fails; idea 509), so `git bundle` the new commit on the laptop, `scp`, `git fetch <bundle> && git reset --hard FETCH_HEAD`. `node_modules` is already the new version, so no re-`npm ci`; a final restart makes `/version` report the new commit.
52
53
 
54
+ ## Auto-rollback on failure (task 2149)
55
+
56
+ By default (`--rollback-on-failure`, ON unless `--no-rollback-on-failure`) the channel self-heals a failed bump. If **`npm install` fails**, **`npm run migrate` fails**, or the **post-restart health check fails**, `bongos upgrade` automatically:
57
+
58
+ 1. reverts the `@bongos/core` pin to the exact pre-upgrade dep string (snapshotted the instant the pin moved),
59
+ 2. `npm install`s the previous core back,
60
+ 3. restarts the service,
61
+ 4. re-verifies (installed == previous, health recovers),
62
+ 5. records a `rolled_back: <reason> (attempted N → N+1, restored N)` row in `core_upgrades`.
63
+
64
+ **The DB is NOT rolled back — only the code pin.** Core migrations are additive + forward-safe (the core migration rule), so an already-applied migration is left in place; a *failed* migration is never recorded in `schema_migrations`, so a retry re-runs it cleanly. The reversal is recorded via the always-present `note` column (not a new `outcome` column) so it lands even in the failed-migrate path — where a newer column wouldn't yet exist on that instance.
65
+
66
+ **Proven live on demo.cloudbongos.com** (task [#2157](https://example.com/builders#/task/2157)): demo, on rollback-capable 1.17.3, was upgraded to a canary carrying a deliberately-failing migration. Migrate raised → the channel auto-reverted the pin to 1.17.3, reinstalled + restarted it, `/healthz` stayed 200 (**zero downtime** — the failure was at migrate, before the restart), and a `rolled_back` ledger row was written. This is the safety gate the unattended patch-only auto-upgrade subscription (task [#2150](https://example.com/builders#/task/2150)) depends on.
67
+
68
+ ## Subscribing to updates — unattended patch-only auto-upgrade (task 2150 / ADR 0136)
69
+
70
+ The sections above are the *manual* `bongos upgrade`. The **subscription** runs it for you, on a cadence, safely — the "subscribe to regular updates" experience. Policy: **patch-only by default, health-gated with auto-rollback, opt-in, autonomy-gated** (full rationale in [ADR 0136](../adr/<redacted>.md)).
71
+
72
+ **Per-instance channel** bounds how far an unattended upgrade may jump:
73
+
74
+ | channel | takes | example (from `1.17.1`) |
75
+ |---|---|---|
76
+ | `pinned` | nothing (manual only) | — |
77
+ | `patch` *(default)* | higher patch, same `x.y` | `→ 1.17.4`, never `1.18.0` |
78
+ | `minor` | higher minor, same major | `→ 1.18.0`, never `2.0.0` |
79
+
80
+ A **major** is never automatic; prereleases are never auto-targeted.
81
+
82
+ **Enrolling an instance** — add it to [`config/update-subscriptions.json`](../../config/update-subscriptions.json) (ships empty). `env` carries per-instance vars merged into the upgrade child — set `PGDATABASE` so `migrate` hits the right DB (see the Gotchas):
83
+
84
+ ```json
85
+ {
86
+ "defaultChannel": "patch",
87
+ "instances": [
88
+ { "slug": "demo", "dir": "/srv/cloudbongos/demo", "service": "demo.service",
89
+ "healthUrl": "https://demo.cloudbongos.com/healthz", "channel": "patch",
90
+ "env": { "PGDATABASE": "demo" } }
91
+ ]
92
+ }
93
+ ```
94
+
95
+ **Preview vs run** — dry-run is the default; the scheduled step passes `--apply`:
96
+
97
+ ```bash
98
+ node .claude/scheduled-tasks/core-update-subscription/subscribe.js # plan only
99
+ node .claude/scheduled-tasks/core-update-subscription/subscribe.js --apply # upgrade
100
+ ```
101
+
102
+ Each subscribed instance: read its installed core → ask the registry (`npm view`, needs `NPM_TOKEN`) → resolve the newest version its channel permits → if newer, `bongos upgrade --to <v> --registry` with **auto-rollback ON**. It prints one line per instance plus a tally; a non-zero exit means an upgrade failed (already auto-reverted).
103
+
104
+ **Triple-gated, so nothing moves by accident:** the `core-update-subscription` routine is `requiresAutonomy: true` + **default OFF** in [`config/scheduled-routines.json`](../../config/scheduled-routines.json), the roster ships empty, and every upgrade is health-gated. Arm it by enabling the routine's timer on the control plane once autonomy is on.
105
+
106
+ **Not covered:** multi-host / SSH orchestration across a real fleet (the deferred fleet-control-plane epic, task [#1948](https://example.com/builders#/task/1948)); and *publishing* new patches, which stays a gated owner step (ADR 0134) — a follow-up task decides whether merges auto-publish.
107
+
53
108
  ## Gotchas
54
109
 
55
110
  - **`PGDATABASE` is load-bearing on a co-tenant droplet.** `migrate.sh` defaults `PGDATABASE` to `example` — **production**. Always set `PGDATABASE=<instance-db>` explicitly, or you migrate the wrong database.
@@ -1,6 +1,6 @@
1
1
  # Cursor (Anysphere) — Competitive-Threat Analysis for Cloud Bongos
2
2
 
3
- **A competitor-research document for Cloud Bongos / Off the Boats**
3
+ **A competitor-research document for Cloud Bongos / Example**
4
4
  Prepared 2026-06-22 · the **first committed competitor doc** in this repo · companion to the (uncommitted) `component-based-dev-research.md` deep-research doc · task [#1403](https://example.com/builders#/task/1403)
5
5
 
6
6
  ---
@@ -1,6 +1,6 @@
1
1
  # LLM Model-Agnostic Platform + Cheaper Grader — Tools Audit & Architecture Path
2
2
 
3
- **A research/architecture spike for Cloud Bongos / Off the Boats**
3
+ **A research/architecture spike for Cloud Bongos / Example**
4
4
  Prepared 2026-06-28 · task [#1069](https://example.com/builders#/task/1069) · GDS-V4 · track `internal`
5
5
 
6
6
  ---
@@ -0,0 +1,45 @@
1
+ -- core_191_module_submissions.sql — the ADR 0107 §1 upstreaming review queue.
2
+ --
3
+ -- task 1770: `bongos module submit <key>` packages a module (manifest +
4
+ -- attribution + file contents) + its DCO-style sign-off and files it into a
5
+ -- rank-gated review queue. Real cross-repo submission (an instance filing into
6
+ -- the CORE repo's own review process) is not wired up yet — the extracted core
7
+ -- (github.com/lars589/cloud-bongos, private) has no reachable submission API
8
+ -- today, and R85 (the forcing-function second consumer) was abandoned in favor
9
+ -- of the already-proven two-repo model (see task 1689's value_summary). So this
10
+ -- table is the interim, buildable-now queue: it lives in THIS instance's own
11
+ -- Bongos DB (the same DB the module was built against), rank-gated identically
12
+ -- to the eventual core-side surface. Task 1771 (core-side review & accept flow)
13
+ -- reviews rows here; if/when a live cross-repo core endpoint exists, filing
14
+ -- becomes a network hop instead of a local INSERT with no schema change to the
15
+ -- caller. See docs/adr/0135-module-upstream-submission-interim-queue.md.
16
+ --
17
+ -- files jsonb = [{ path, contentBase64, bytes }, ...] — a full snapshot of the
18
+ -- module tree at submit time (ADR 0107 §1 "packages the module + ... into a
19
+ -- ... queue"), so a reviewer (task 1771) can inspect the submitted code without
20
+ -- needing network/filesystem access to the submitting instance's repo.
21
+ --
22
+ -- Idempotent: safe to re-run.
23
+
24
+ CREATE TABLE IF NOT EXISTS module_submissions (
25
+ id bigserial PRIMARY KEY,
26
+ module_key text NOT NULL,
27
+ submitted_by bigint NOT NULL REFERENCES builders(id),
28
+ manifest jsonb NOT NULL,
29
+ files jsonb NOT NULL,
30
+ sign_off jsonb NOT NULL,
31
+ precheck_passed_at timestamptz NOT NULL,
32
+ source_repo text,
33
+ status text NOT NULL DEFAULT 'pending'
34
+ CHECK (status IN ('pending', 'accepted', 'rejected')),
35
+ reviewed_by bigint REFERENCES builders(id),
36
+ reviewed_at timestamptz,
37
+ review_notes text,
38
+ submitted_at timestamptz NOT NULL DEFAULT now()
39
+ );
40
+
41
+ CREATE INDEX IF NOT EXISTS idx_module_submissions_status ON module_submissions (status, submitted_at DESC);
42
+ CREATE INDEX IF NOT EXISTS idx_module_submissions_key ON module_submissions (module_key, submitted_at DESC);
43
+
44
+ INSERT INTO schema_migrations (version) VALUES ('core_191_module_submissions')
45
+ ON CONFLICT (version) DO NOTHING;
@@ -1,49 +1,15 @@
1
- # `autonomy` module — the Multi-Agent System (conductor · architect · gate · routine timers)
1
+ # @bongos/core — installed platform dependency (not your project's CLAUDE.md)
2
2
 
3
- > A CORE-domain carve (BV1.R83, [ADR 0093](../../docs/adr/<redacted>.md) §1) — the eighth tranche-2 domain extracted from the GDS core, after sessions (R82). `default: true` — the autonomy machinery + the durable in-process routine timer ship to every instance (both inert/no-op until armed or the pool is reachable), so it mounts unconditionally unless an instance disables it.
3
+ This file is a placeholder shipped inside the **@bongos/core** package. The core's own
4
+ internal agent notes are intentionally omitted from the published artifact so they cannot
5
+ load into your instance's context.
4
6
 
5
- Owns the **Multi-Agent System** surfaces ([ADR 0024](../../docs/adr/<redacted>.md)):
6
- - the **autonomy gate** (System 3, task 1351) — the $0 deterministic precheck that decides go/no-go before any model boots; a precheck HTTP route + the gate CLI, **inert until `OTB_AUTONOMY_ENABLED=1`**;
7
- - the **routine timers** (System 4 / [ADR 0078](../../docs/adr/<redacted>.md) amendment, task 1382) — the in-process weekly **peer-vote-tally** poller (no model, no external cron);
8
- - the **Conductor** mid-flight dispatch CLI (Phase 4, task 439) and the **Architect** bounded first-principles `--scope` audit CLI (Phase 5, task 459) — domain commands.
7
+ **It does not govern this repository.** Your own root `CLAUDE.md`, your `.claude/`
8
+ directory, and the live Bongos database are the source of truth for how work happens here
9
+ and who may do what.
9
10
 
10
- ## The boundary (the one rule)
11
+ You are seeing this only because an agent opened a file under `node_modules/@bongos/core/`.
12
+ Nothing in here needs to be read to use the platform — run `bongos help` for commands.
11
13
 
12
- The module's `src/`-scanned files (`db.js`, `pollers/`, `routes/`) reach core **only** through the published doorway `../../src/module-api.js` (`coreVersion ^1.11.0`). They must **never** `require()` a core internal (`../../src/bongos/db`, `../../src/bongos/auth`, …) directly, and **never** another module. Core, in turn, must never `require()` a file in here — the route mount + the timer-start both left `src/bongos/`/`server.js`; the loader (`mountModuleRoutes` + `startModulePollers`) wires them now. Both directions are enforced by the BV1.R44/R45 fitness checks.
13
-
14
- ## Cross-cutting: it OBSERVES lifecycle (the seams)
15
-
16
- This is the cross-cutting domain the carve sequence flagged. Two inbound core→autonomy edges existed; each was inverted so the module is wired, not imported:
17
-
18
- 1. **The routine timer** (was `routineTimers.start()` in `server.js`) → now a **POLLER** (`contributes.pollers:["routine-timers"]`). The loader's `startModulePollers` requires `pollers/routine-timers.js` and calls `start()` at boot / `stop()` at shutdown — the module-agnostic successor to the hardcoded block (the Discord-bot-poller pattern, BV1.R47). server.js is the only `startModulePollers` caller (not `src/platform-server.js`), so a second always-on instance can't double-run. The timer's work is the lifecycle **`tallyPeerVotes`** capability (the SAME transaction `POST /tasks/peer-votes/tally` runs — route + timer share ONE path), reached through the **doorway** (`api.tallyPeerVotes`, a tracked lifecycle leak — it writes karma_log/peer_votes/tasks, all core-owned; relocates behind a `lifecycle.*` port at R86), never a core require.
19
- 2. **The autonomy precheck route** (was mounted in `src/bongos/routes.js`) → now a **module route** (`contributes.routes:["autonomy"]`, mounted by `mountModuleRoutes`). `GET /autonomy/precheck` (Archon-gated) calls the gate's `precheck`.
20
-
21
- ## No port (the sessions/memory shape)
22
-
23
- Like `sessions`/`memory`, autonomy registers **no kernel port** (`provides: []`) — **core never calls back into it.** The timer is a loader-started poller, the precheck a module route, and the gate/conductor/architect are CLIs. There is nothing for a port to expose. (`consumes: []` too — `tallyPeerVotes` is a doorway export, not a seam port.)
24
-
25
- ## Files
26
-
27
- | File | What |
28
- |---|---|
29
- | `db.js` | the `autonomy_runs` db slice — `recordAutonomyRun` (audit each precheck decision) + `lastAutonomyHead` (the stored last-`go` head the no-signal check compares origin/main against). Reaches Postgres through the doorway `pool`. |
30
- | `pollers/routine-timers.js` | the in-process weekly **peer-vote-tally** timer (the loader's poller entry — `start`/`stop`). `runPeerVoteTally` resolves the lifecycle `tallyPeerVotes` via the doorway; pure w.r.t. injected `deps` (tests pass `deps.db`). Kill-switch `ROUTINE_TIMERS_DISABLED`; unref'd, best-effort. |
31
- | `routes/autonomy.js` | `GET /autonomy/precheck` (Archon-gated) — the autonomy precheck over HTTP; wraps the gate CLI's `precheck`. Inert (always `go`) until `OTB_AUTONOMY_ENABLED=1`. |
32
-
33
- ## NOT in this module (the domain CLIs travel with the domain but stay under `scripts/`)
34
-
35
- A command travels with its domain but stays a CLI (design 02§1; the sessions/memory precedent). These live under `scripts/gds/` — **outside** the kernel boundary (fitness scans `src/` + `modules/`, not `scripts/`), so they may still read the ideas/economy/lifecycle signals + the grader directly, which a `modules/` file may not:
36
-
37
- - **`scripts/gds/autonomy-gate.js`** — the gate CLI (Step 0 of the nightly routines). Its pure decision logic (`decide`, `autofixAllowed`) is `$0`; its `gatherSignals` reads claimable tasks (core db), open ideas (`modules/ideas`), autonomous MTD spend (`modules/economy`), and the autonomy_runs head/record (**this module's `db.js`**). The precheck route + scheduled tasks invoke it.
38
- - **`scripts/gds/conductor-dispatch.js`** — the Conductor mid-flight dispatch (runs grader specialists on the current diff; reuses `modules/grading/grader` + `src/bongos/sensitive-surfaces` + `src/bongos/path-match`).
39
- - **`scripts/gds/architect-audit.js`** — the Architect's bounded `--scope` audit → `docs/audits/` + seed ideas (reuses the grader + `src/bongos/llm-cache`).
40
- - **`scripts/gds/run-routine.js`** — the deterministic-first cron dispatcher (parses a routine's SKILL.md, runs steps at the cheapest sufficient tier).
41
- - **`.claude/scheduled-tasks/`** — the cron routine SKILL.md files that invoke these CLIs (re-pointed at the moved gate; the scripts they call are unchanged paths).
42
-
43
- ## Tables (owned, not moved)
44
-
45
- `autonomy_runs` (migration 126) was created before the module system and stays in core `migrations/` (the shared-schema additive rule the sessions/onboarding carves established). The module owns the *queries*; any **new** autonomy migration belongs in `modules/autonomy/migrations/` namespaced `autonomy_*`.
46
-
47
- ## Tests
48
-
49
- `tests/autonomy_gate.mjs` (the pure gate decision — DB-free), `tests/routine_timers.mjs` (the peer-vote timer — pure w.r.t. injected deps), `tests/conductor.mjs`, `tests/architect.mjs`, `tests/run_routine.mjs` exercise the CLIs (which import from `scripts/gds/…`). The carve discovery-key membership is asserted in `tests/fitness.mjs` / `tests/module_loader.mjs` / `tests/modules.mjs`; the doorway `tallyPeerVotes` export in `tests/module_api.mjs`.
14
+ _To work ON the platform core itself, use the standalone @bongos/core source repository,
15
+ not this vendored copy._
@@ -1,58 +1,15 @@
1
- # `builder-settings` module — per-builder prefs + builder-needs + the `builder-settings` kernel port
1
+ # @bongos/core — installed platform dependency (not your project's CLAUDE.md)
2
2
 
3
- > The **sixth CORE-domain** carved into a module (BV1.R80, [ADR 0093](../../docs/adr/<redacted>.md) §1) — after memory (R72), grading (R73), economy (R77), ideas (R78), and security (R79). A clean slice: the five pref libs + builder-needs were already standalone PURE files (zero core `require()`), so the carve is a git-move + a `db.js`-slice extraction + a route SPLIT + a port re-point — OTB byte-identical. `default: true` in `module.json` — every instance configures its own builders.
3
+ This file is a placeholder shipped inside the **@bongos/core** package. The core's own
4
+ internal agent notes are intentionally omitted from the published artifact so they cannot
5
+ load into your instance's context.
4
6
 
5
- Owns the **per-builder preference domain** and **builder-needs**:
7
+ **It does not govern this repository.** Your own root `CLAUDE.md`, your `.claude/`
8
+ directory, and the live Bongos database are the source of truth for how work happens here
9
+ and who may do what.
6
10
 
7
- - **wandering** ([`wandering-prefs.js`](wandering-prefs.js)) — how readily the agent opens a NEW THREAD of work (tangent / investigation / unsolicited suggestion) vs. staying on the claimed task. Rank-clamped server-side (Xenos → Locked, Thetes → Focused, Metic+ free). Stored in the `behavior_prefs` jsonb.
8
- - **interaction** ([`interaction-prefs.js`](interaction-prefs.js)) — the per-builder INTERACTION PROFILE (task 2010): tone / technical level / local-toolchain familiarity — the old CLAUDE.md §2 "The Prompter" owner-defaults, reframed as a per-builder profile (an owner is just a builder with a profile). Resolved over the portable defaults; the effective `contract` is surfaced on `/me` and injected each session (the wandering pattern). Stored in the `behavior_prefs` jsonb; `GET`/`PATCH /me/interaction`.
9
- - **skill** ([`skill-prefs.js`](skill-prefs.js)) — the per-skill model ceiling a spawn is clamped to (`skill_model_prefs` jsonb, migration 037).
10
- - **model-allocation** ([`model-alloc-prefs.js`](model-alloc-prefs.js)) — the subagent model-routing policy (task 2011): the tier for main / subagent-default / routine-plumbing slots. Resolved builder override → instance default (`branding.models`) → code default (`opus`/`opus`/`haiku`); surfaced on `/me` (`model_allocation.effective`) + `GET`/`PATCH /me/model-allocation`. Replaces the hardcoded CLAUDE.md §2 routing table. PURE lib (instance default passed in). Stored in `behavior_prefs`.
11
- - **sound** ([`sound-prefs.js`](sound-prefs.js)) + **event-sound** ([`event-sound-prefs.js`](event-sound-prefs.js)) — per-sound on/off + volume (`sound_prefs`, migration 075) and per-event sound-variant selection (`event_sound_prefs`, migration 164). The local `.claude/sounds/play.js` reads a mirror written by `scripts/gds/fetch-sound-prefs.js`.
12
- - **render** ([`render-prefs.js`](render-prefs.js)) — the "render the deterministic session cards as a rich HTML widget vs. plain text" toggle (shares `behavior_prefs`, migration 119).
13
- - **builder-needs** ([`builder-needs.js`](builder-needs.js)) — the consistent "the system needs an input from you" list (today: the image-generation key).
11
+ You are seeing this only because an agent opened a file under `node_modules/@bongos/core/`.
12
+ Nothing in here needs to be read to use the platform — run `bongos help` for commands.
14
13
 
15
- ## The boundary (the one rule)
16
-
17
- This module reaches core **only** through the published doorway [`../../src/module-api.js`](../../src/module-api.js) (`coreVersion ^1.8.0`). It must **never** `require()` a core internal directly, and never another module. Core, in turn, must never `require()` a file in here — it reaches the prefs/needs read surface only through the `builder-settings` port (below). Both directions are enforced by the BV1.R44/R45 fitness checks.
18
-
19
- ## The `me`/`public` facade call (02-module-map §2)
20
-
21
- [02-module-map §2](../../docs/design/modular-architecture/02-module-map.md) flags `me` as a cross-domain read-aggregator that becomes a **thin facade** when its domains carve out. This carve realizes that for the prefs/needs slices:
22
-
23
- - **The five `/me/*-prefs` ROUTES moved here** ([`routes/settings.js`](routes/settings.js)) — `GET`/`PATCH` for `/me/skill-prefs`, `/me/sound-prefs`, `/me/event-sound-prefs`, `/me/wandering`, `/me/render`. They keep their **exact `/me/*` paths** (the loader mounts this router on the same `/api/gds` router, BEFORE the public catch-all), so the API is byte-identical — only the `require()` paths changed (auth/`getBuilderById` reach the doorway; the pref libs + the db slice are intra-module).
24
- - **The `GET /me` AGGREGATOR stayed in core `routes/me.js`** as a thin facade. It builds the `wandering` / `render` / `needs` slices of the profile payload inline (alongside the economy `reward`-port + discord/box/art seam slices it already resolves) by resolving the `builder-settings` port — never importing the module.
25
- - **`public.js` has NO builder-settings edge** — the §2 graph's `public → grader, security` is the real public coupling; prefs/needs are a `me`-only domain. `public.js` is untouched by this carve.
26
-
27
- ## The `builder-settings` kernel PORT
28
-
29
- - **Provides — port `builder-settings`** → the read surface in [`settings.js`](settings.js): `{ getBuilderBehaviorPrefs, describeWandering, describeRender, computeNeeds, skillCeiling }`. Registered in [`routes/settings.js`](routes/settings.js)'s factory (the loader runs it at boot, and again whenever a test rebuilds the GDS router — `hasProvider`-guarded so re-instantiation never trips the single-provider guard). Mirrors `modules/economy/routes/reward.js`.
30
- - **The TWO core consumers resolve it WITHOUT importing this module:**
31
- - `routes/me.js` — the `GET /me` aggregator (`getBuilderBehaviorPrefs` once, then `describeWandering`/`describeRender`/`computeNeeds` off the same blob).
32
- - `src/bongos/cascade-dispatch.js` — the dormant System-3 cascade router clamps a spawn to the builder's model ceiling (`skillCeiling`, the former `skillPrefs.getForBuilder`).
33
- - Both degrade gracefully when the module is off (a vanilla instance): me.js's slices are best-effort; cascade's ceiling falls back to `'opus'` (its existing `|| 'opus'` default). No `CORE_VERSION` bump — the carve adds no doorway export (the port rides the already-exported seam registry, the security precedent).
34
-
35
- ## Files
36
-
37
- | File | What |
38
- |---|---|
39
- | `db.js` | the builder-prefs db slice — the eight verbatim `get/set BuilderSkillPrefs / SoundPrefs / BehaviorPrefs / EventSoundPrefs` helpers carved out of core `db.js`. Reaches the shared pool through the doorway. |
40
- | `skill-prefs.js` · `sound-prefs.js` · `event-sound-prefs.js` · `wandering-prefs.js` · `render-prefs.js` | the pure shapers (`validatePatch`/`applyPatch`/`listEffective`/`describeForApi`/constants) that turn a raw jsonb blob into effective values. Moved verbatim (they were already core-`require()`-free). |
41
- | `builder-needs.js` | `computeNeeds(ctx)` — the "the system needs an input from you" list (the image-generation-key item). |
42
- | `settings.js` | the `builder-settings` port provider surface — DELEGATES (does not spread) to `db`/the pref libs so test stubs bite at call time. |
43
- | `routes/settings.js` | the five `/me/*-prefs` GET/PATCH endpoints (above) + the port registration. |
44
-
45
- ## NOT in this module (deliberately left in core)
46
-
47
- - **The `GET /me` aggregator + every non-prefs `/me/*` route** — `routes/me.js` stays core (it's the cross-domain profile/identity surface; only the self-contained pref routes left). It resolves this module's port for its prefs/needs slices.
48
- - **The per-builder Gemini KEY** (`getBuilderGeminiKeyRow` / `setBuilderGeminiKey` / `clearBuilderGeminiKey`, `gemini_key_*` columns) — stays core `db.js` + the doorway (`api.getBuilderGeminiKeyRow`). It's art-pipeline credential infra (the `/me/art-key` delivery + the `art.sharedKeyConfigured` seam), read by `computeNeeds`'s caller as `ownKeySet`, not owned by builder-settings.
49
- - **`cascade-dispatch.js`** — the dormant System-3 cascade router stays a CORE lib (it belongs to the grading/autonomy plane, not builder-settings); it RESOLVES this module's `skillCeiling` port instead of importing `skill-prefs`.
50
- - **The pref-mirroring CLIs** — `scripts/gds/fetch-sound-prefs.js` + `scripts/gds/session-eval.js` (which reads `wandering-prefs`) travel with the domain but stay under `scripts/` and `require('../../modules/builder-settings/…')` directly (scripts are outside the kernel boundary — the memory/economy-carve precedent).
51
-
52
- ## Tables
53
-
54
- None owned. The five jsonb columns (`skill_model_prefs` 037, `sound_prefs` 075, `behavior_prefs` 119, `event_sound_prefs` 164) live on the CORE `builders` table and stay in core `migrations/`. This module owns the *prefs queries*; any **new** builder-settings migration belongs in `modules/builder-settings/migrations/` namespaced `builder_settings_*` (the additive rule).
55
-
56
- ## Tests
57
-
58
- `tests/skill_prefs.mjs`, `tests/sound_prefs.mjs`, `tests/wandering_prefs.mjs`, `tests/render_prefs.mjs`, and `tests/builder_needs.mjs` import the pure shapers from `modules/builder-settings/…`. The doorway/boundary checks (`tests/fitness.mjs`, `tests/module_loader.mjs`, `tests/modules.mjs`) discover `builder-settings` as a module. See [ADR 0093](../../docs/adr/<redacted>.md).
14
+ _To work ON the platform core itself, use the standalone @bongos/core source repository,
15
+ not this vendored copy._
@@ -1,38 +1,15 @@
1
- # `dev-box` module — per-builder cloud dev environments
1
+ # @bongos/core — installed platform dependency (not your project's CLAUDE.md)
2
2
 
3
- > The **first** module extracted from core (BV1.R43, [ADR 0083](../../docs/adr/<redacted>.md)). It is the **template** every later module move copies — keep it clean.
3
+ This file is a placeholder shipped inside the **@bongos/core** package. The core's own
4
+ internal agent notes are intentionally omitted from the published artifact so they cannot
5
+ load into your instance's context.
4
6
 
5
- Optional feature module: per-builder DigitalOcean droplets + Cloudflare tunnels, the sandbox game preview, and server-mediated branch publish. Gated by `config/modules.json` (`dev-box: true` for the OTB instance; off on a vanilla Cloud Bongos boot). The loader (`src/module-loader/loader.js`) discovers this dir via `module.json` and mounts the route factory.
7
+ **It does not govern this repository.** Your own root `CLAUDE.md`, your `.claude/`
8
+ directory, and the live Bongos database are the source of truth for how work happens here
9
+ and who may do what.
6
10
 
7
- ## The boundary (the one rule)
11
+ You are seeing this only because an agent opened a file under `node_modules/@bongos/core/`.
12
+ Nothing in here needs to be read to use the platform — run `bongos help` for commands.
8
13
 
9
- This module reaches core **only** through the published doorway `../../src/module-api.js` (the semver'd contract; this module needs `coreVersion ^1.2.0`). It must **never** `require()` a core internal (`../../src/bongos/auth`, `../../src/bongos/db`, …) directly, and never another module. Core, in turn, must never `require()` a file in here — that's the forbidden core→module edge this extraction removed. (The fitness check that *enforces* this is BV1.R44/R45; until then it's WARN-mode, but the template models the right pattern.)
10
-
11
- ## Files
12
-
13
- | File | What |
14
- |---|---|
15
- | `routes/box.js` | the HTTP surface — `/box/*` (own box; some `allowBoxScope`) + `/boxes/*` (Archon roster). The loader mounts this; its factory also **registers this module's seams** (idempotent). |
16
- | `boxes.js` | box lifecycle logic + cost ledger. Pure-ish: `pool` is passed in (DI), so it has no core require. |
17
- | `box-access.js` | source-access clawback (`flagBoxReconcileForBuilder`, `decideSourceAccess`). |
18
- | `box-credential.js` | per-box credential provider. |
19
- | `box-onboard.js` | SSH-key validation + connect/settings renderers. |
20
- | `db.js` | the module's data slice — owns `setBuilderBoxBlocked` (the box-blocked write), reached through the doorway `pool`. Lifted out of core `db.js` in BV1.R68 ([ADR 0091](../../docs/adr/<redacted>.md)); box-blocked is cleanly dev-box-owned (this module is its only writer + reader). |
21
-
22
- ## Seams (how core and this module talk without importing each other)
23
-
24
- - **Provides — port `box.hasEverConnected`** `(builderId) → Promise<bool>`. Core (`routes/me.js`, `routes/builders.js`) reads it via `resolveOptional('box.hasEverConnected', async () => false)` so onboarding's `box_connect` step auto-clears when a box is on, and degrades to `false` on a box-less instance.
25
- - **Listens — event `builder.box-reconcile-needed`** `{ builderId, rank, status, actor }`. Core `db.js` emits it (via `emitAsync`) after a rank change / deactivate / auto-graduation; this module flags the droplet reconcile. Replaces the old `db.js → box-access` direct call.
26
-
27
- Registration happens in `routes/box.js`'s factory (the loader runs it at boot, already module-gated), guarded by `hasProvider` so re-instantiation in tests can't double-register.
28
-
29
- ## NOT in this module
30
-
31
- - **The network clients** — `scripts/gds/do-api.js` (DigitalOcean), `scripts/gds/cf-tunnel.js` (Cloudflare tunnel), and their shared `scripts/gds/http-api-client.js`. They were operator-CLI-only (never the web process), so they moved OUT to the control-plane tier in BV1 task [#1943](https://example.com/builders#/task/1943) ([ADR 0111](../../docs/adr/<redacted>.md) §2) — the DO client is now shared by `box.js` AND the instance-provisioning runner `provision.js`, which a module→module import could never allow.
32
- - **`scripts/gds/box.js`** — the operator control-plane CLI (sole holder of `DO_API_TOKEN`/`CF_API_TOKEN`, ADR 0031 §9.4). It *requires* this module's `boxes`/`box-access`/`box-onboard` (module data/logic) plus the shared `scripts/gds/do-api`/`cf-tunnel` clients, but it is core ops tooling and stays in `scripts/gds/`.
33
- - **The hall UI** (`modules/hall-ui/public/`: `box-panel.js`, `harbor.js`, the `watch.js` cost section, gated mounts in `builders.js`/`settings.js`). Per-module UI sections are design **phase 6**, not this move; they stay in the hall-ui module (carved in BV1.R85), already gated by `window.__MODULES__.enabled['dev-box']`.
34
- - **`secret-box.js`** — unrelated per-builder secrets crypto; stays in core despite the name.
35
-
36
- ## Tests
37
-
38
- `scripts/gds/smoke-box.sh` + `tests/box*.mjs` (boxes, box_access, box_onboard, box_host_keys, box_cost, box_code_staleness, box_terminal_ssrf, box_connect_e2e, cf_tunnel). They import from `modules/dev-box/…` — except the moved network clients (`tests/boxes.mjs`'s `do-api` import + `tests/cf_tunnel.mjs`) now import from `scripts/gds/…` ([#1943](https://example.com/builders#/task/1943)).
14
+ _To work ON the platform core itself, use the standalone @bongos/core source repository,
15
+ not this vendored copy._
@@ -1,50 +1,15 @@
1
- # `discord` module — the Discord mirror (bot + broadcast + link/role)
1
+ # @bongos/core — installed platform dependency (not your project's CLAUDE.md)
2
2
 
3
- Optional feature module: the outbound `#ship-news`/`#ship-feed` broadcast, the inbound `#ideas`/`#bugs` bot, ship-feed applause, role-sync, channel management, and the account-link state the hall reads. **Discord is a one-way mirror of the GDS — never authority** ([ADR 0033](../../docs/adr/<redacted>.md)). Gated by `config/modules.json` (`discord: true` for the OTB instance; off on a vanilla Cloud Bongos boot). The loader (`src/module-loader/loader.js`) discovers this dir via `module.json`, mounts the route factories, and starts the bot poller. Extracted from core in BV1.R47 ([task 1416](https://example.com/builders#/task/1416)).
3
+ This file is a placeholder shipped inside the **@bongos/core** package. The core's own
4
+ internal agent notes are intentionally omitted from the published artifact so they cannot
5
+ load into your instance's context.
4
6
 
5
- ## The boundary (the one rule)
7
+ **It does not govern this repository.** Your own root `CLAUDE.md`, your `.claude/`
8
+ directory, and the live Bongos database are the source of truth for how work happens here
9
+ and who may do what.
6
10
 
7
- This module reaches core **only** through the published doorway `../../src/module-api.js` (the semver'd contract; this module needs `coreVersion ^1.4.0`). It must **never** `require()` a core internal (`../../src/bongos/db`, `../../src/bongos/auth`, `../../scripts/discord/lib`, …) directly, and never another module. Core, in turn, must never `require()` a file in here — that's the forbidden core→module edge this extraction removed (enforced by the BV1.R44/R45 fitness checks).
11
+ You are seeing this only because an agent opened a file under `node_modules/@bongos/core/`.
12
+ Nothing in here needs to be read to use the platform — run `bongos help` for commands.
8
13
 
9
- ## Files
10
-
11
- | File | What |
12
- |---|---|
13
- | `routes/discord.js` | Archon-only `/discord/channels/{plan,reconcile}` (ADR 0037). Its factory also **registers this module's seams** (port + listener; idempotent). |
14
- | `routes/bug-attachments.js` | serves `GET /bug-attachments/:name` (images attached to `#bugs` reports). Moved with the lib it reads. |
15
- | `discord-bot.js` | the gateway client (reactions, inbound, role-sync timer). Started/stopped via `pollers/discord-bot.js`. |
16
- | `discord-reaction.js` · `discord-inbound.js` · `discord-bugs.js` · `discord-approvals.js` | the passive bot features: 👍 applause, `#ideas` → idea_inbox, `#bugs` → task, member-approval reactions. |
17
- | `discord-role-sync.js` · `discord-channels.js` | rank→role badge reconcile + channel/topic/view management from `docs/discord/channels.json`. |
18
- | `discord-message-buffer.js` · `discord-audit.js` · `bug-attachments.js` | message-pair aggregator, bot-action audit helper, attachment persistence (pure). |
19
- | `ship-broadcast.js` | the server-side ship poster — fired by the `task.shipped` seam listener, not a core import. |
20
- | `db.js` | the module's data layer — owns the `discord_links`/`discord_applause` queries (via the doorway `pool`) + re-exports kernel db helpers. |
21
- | `auth.js` · `webhook.js` | **vendored twins** of core helpers (see below). |
22
- | `pollers/discord-bot.js` | the loader's web-process poller entry — `start()`/`stop()` over the bot. |
23
-
24
- ## Seams (how core and this module talk without importing each other)
25
-
26
- - **Provides — port `discord.isLinked`** `(builderId) → Promise<bool>`. Core (`routes/me.js`, `routes/builders.js`) reads it via `resolveOptional('discord.isLinked', async () => false)` so the hall renders Connect/Unlink and onboarding's discord step auto-clears; degrades to `false` on a discord-less instance. (`discord.configured` — does the server hold OAuth creds — stays **core**: the account-LINK flow in `routes/auth.js` is not part of this module.)
27
- - **Listens — event `task.shipped`** `(shippedTaskRow)`. Core (`publish-reconciler.js`, `routes/tasks.js`) emits it on the confirmed→shipped transition; this module posts the `#ship-news`/`#ship-feed` broadcast. Replaces the old `require('./ship-broadcast')` core→discord import.
28
- - No consumed ports.
29
-
30
- Registration happens in `routes/discord.js`'s factory (the loader runs it at boot, already module-gated): the port is `hasProvider`-guarded; the `task.shipped` listener is off→on replaced so a test re-instantiating the router never accumulates duplicates.
31
-
32
- ## Vendored twins (boundary-forced — keep in sync)
33
-
34
- The kernel doorway must stay module-agnostic (the "core carries no module code" fitness check forbids naming a module in `src/module-api.js`), and a module can't require core/scripts. So three small helpers are **copied** here, with their core originals kept for the parts of Discord that stay core:
35
-
36
- - **`auth.js`** — `isValidDiscordUserId` + `loadDiscordBotToken`. Core `src/bongos/auth.js` keeps its copies for the OAuth account-LINK flow (`routes/auth.js`).
37
- - **`webhook.js`** — `postWebhook`/`loadWebhooks`/`CHANNELS`, a twin of `scripts/discord/lib.js` (which stays for core `approval-broadcast.js` + the `scripts/discord/post.js` CLI).
38
- - **`db.js`** — `getDiscordLink`/`recordApplause` are also defined in core `src/bongos/db.js` (still used by the link flow / a seed); the others (`getBuilderByDiscordUserId`, `listDiscordLinks`, `countRecentDiscordBugFilings`) are owned here.
39
-
40
- ## NOT in this module
41
-
42
- - **The OAuth account-link flow** — `routes/auth.js` + the Discord OAuth helpers in `src/bongos/auth.js` (`discordConfigured`, `addDiscordGuildMember`, …). Linking writes a core `builders`-adjacent row; it stays core. This module only surfaces the resulting *state* via the `discord.isLinked` port.
43
- - **`migrations/<redacted>.sql`** — stays in **core** `migrations/`. It also `ALTER`s core tables (`builders.system_role`, `audit_log.surface`) and seeds the `discord_bot` principal, so the module-migration namespacing rule (which forbids a module migration touching non-`discord_` objects) can't host it. Any *future* discord migration that touches only `discord_*` objects can live in `modules/discord/migrations/`.
44
- - **`ship-card.js`** — the CLI lifecycle card (claimed→shipped) used by `claim.js`/`ship.js` on every instance; not a Discord concern, stays in `src/bongos/`.
45
- - **`approval-broadcast.js` · `scripts/discord/{lib,post}.js`** — core/CLI Discord posters (see Vendored twins).
46
- - **The hall UI** (`modules/hall-ui/public/`, carved in BV1.R85) — per-module client UI is a later design phase; it stays gated by `window.__MODULES__.enabled['discord']`.
47
-
48
- ## Tests
49
-
50
- `tests/discord_*.mjs` + `tests/bug_attachments.mjs` import from `modules/discord/…`. `scripts/discord/smoke*.sh` (if present) exercises the outbound poster.
14
+ _To work ON the platform core itself, use the standalone @bongos/core source repository,
15
+ not this vendored copy._
@@ -10,5 +10,6 @@
10
10
  "uiSections": []
11
11
  },
12
12
  "provides": ["discord.isLinked"],
13
- "consumes": ["ideas.capture"]
13
+ "consumes": ["ideas.capture"],
14
+ "dependencies": { "discord.js": "^14.26.4" }
14
15
  }