@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
@@ -38,7 +38,7 @@
38
38
  // carries a live credential verbatim, PRODUCE NOTHING — dist/ is never touched. The
39
39
  // in-memory pass makes the abort atomic (same discipline as the mirror export).
40
40
  // 5. Only when the whole set is clean: write the tree to
41
- // dist/cloudbongos-core-<version>/, the .tgz, and the pin MANIFEST.
41
+ // dist/bongos-core-<version>/, the .tgz, and the pin MANIFEST.
42
42
  //
43
43
  // THE VERSION STAMP is the platform version — src/module-api.js CORE_VERSION,
44
44
  // read via the SAME fail-soft accessor scripts/gds/module.js + bongos upgrade use
@@ -55,9 +55,9 @@
55
55
  // [--version <v>] [--droplet-ip <ip>] [--publish [--live]]
56
56
  // Defaults: --ref HEAD, --out-dir dist, --version = platform CORE_VERSION.
57
57
  // Outputs (nothing is committed — dist/ is gitignored):
58
- // dist/cloudbongos-core-<version>/ the redacted core tree (inspectable)
59
- // dist/cloudbongos-core-<version>.tgz the installable unit
60
- // dist/cloudbongos-core-<version>.manifest.json the PIN (tree hash + per-file hashes)
58
+ // dist/bongos-core-<version>/ the redacted core tree (inspectable)
59
+ // dist/bongos-core-<version>.tgz the installable unit
60
+ // dist/bongos-core-<version>.manifest.json the PIN (tree hash + per-file hashes)
61
61
  // --publish after building, `npm publish` the .tgz as a PRIVATE scoped
62
62
  // package (--access restricted). DRY-RUN unless --live is added
63
63
  // (task 2089 / ADR 0134). Private publish needs the cloudbongos
@@ -81,7 +81,7 @@ const { collectEnvSecrets } = require(path.join(REPO_ROOT, 'modules/security/sec
81
81
  const { redactBlob, parseLsTree } = require(path.join(REPO_ROOT, 'scripts/public-mirror-export.js'));
82
82
 
83
83
  const MANIFEST_SCHEMA = 1;
84
- const ARTIFACT_NAME = 'cloudbongos-core';
84
+ const ARTIFACT_NAME = 'bongos-core';
85
85
  // The tar internal root MUST be `package/` — that is the one hardcoded npm
86
86
  // convention for an installable tarball (`npm install ./x.tgz` / `npm pack`
87
87
  // output both use it; npm does not read the directory name to find package.json,
@@ -92,7 +92,7 @@ const TAR_ROOT = 'package/';
92
92
  // The self-describing manifest carried INSIDE the artifact (minus tarball.* — a
93
93
  // file cannot contain its own hash). The authoritative PIN is the side-car next
94
94
  // to the .tgz, which adds tarball.{sha256,bytes}.
95
- const INNER_MANIFEST = `${TAR_ROOT}.cloudbongos-core.json`;
95
+ const INNER_MANIFEST = `${TAR_ROOT}.bongos-core.json`;
96
96
 
97
97
  // ---------------------------------------------------------------------------
98
98
  // The platform version — read CORE_VERSION via the doorway, lazily + fail-soft,
@@ -136,6 +136,38 @@ function sha256hex(buf) {
136
136
  const DOC_RE = /\.(md|markdown)$/i;
137
137
  function isDocPath(p) { return DOC_RE.test(String(p || '')); }
138
138
 
139
+ // ---------------------------------------------------------------------------
140
+ // Agent-doc STUB (task 2121; surfaced by the 2026-07-08 demo task-creation audit).
141
+ // Claude Code AUTO-LOADS the nearest file named CLAUDE.md (or AGENTS.md) into the
142
+ // live session whenever an agent opens a sibling file. In a CONSUMER instance the
143
+ // core installs at node_modules/@bongos/core/, so the core repo's OWN CLAUDE.md tree
144
+ // (root + scripts/gds + src/bongos + every module) would silently inject the
145
+ // platform's project memory — wrong project title, hundreds of lines, dangling links
146
+ // — into the instance's context the moment an agent reads any core file.
147
+ // The PUBLIC MIRROR deliberately publishes CLAUDE.md as the portable methodology
148
+ // (ADR 0065 §4), so this cannot live in the shared publish-manifest — it is a
149
+ // package-core-only transform. We keep the files PRESENT (nothing that probes for
150
+ // them by path breaks) but replace their body with a tiny, brand-free stub, turning
151
+ // the auto-load into a harmless "this doesn't govern you" redirect.
152
+ const AGENT_DOC_RE = /(^|\/)(CLAUDE|AGENTS)\.md$/i;
153
+ function isAgentDoc(p) { return AGENT_DOC_RE.test(String(p || '')); }
154
+ const CORE_AGENT_DOC_STUB = `# @bongos/core — installed platform dependency (not your project's CLAUDE.md)
155
+
156
+ This file is a placeholder shipped inside the **@bongos/core** package. The core's own
157
+ internal agent notes are intentionally omitted from the published artifact so they cannot
158
+ load into your instance's context.
159
+
160
+ **It does not govern this repository.** Your own root \`CLAUDE.md\`, your \`.claude/\`
161
+ directory, and the live Bongos database are the source of truth for how work happens here
162
+ and who may do what.
163
+
164
+ You are seeing this only because an agent opened a file under \`node_modules/@bongos/core/\`.
165
+ Nothing in here needs to be read to use the platform — run \`bongos help\` for commands.
166
+
167
+ _To work ON the platform core itself, use the standalone @bongos/core source repository,
168
+ not this vendored copy._
169
+ `;
170
+
139
171
  // Fail-loud gate for a FUNCTIONAL file: only an exact live-credential value (an env-secret
140
172
  // VALUE present verbatim, >= 8 chars) is a real leak. The sample is withheld (it's a secret).
141
173
  function functionalSecretLeaks(view, envSecrets) {
@@ -154,6 +186,12 @@ function functionalSecretLeaks(view, envSecrets) {
154
186
  // `advisories` = brand-identity substrings + public IPs that ship as-is (non-fatal, for
155
187
  // human awareness) — REUSES findLeaks so the detector is defined once.
156
188
  function processCoreFile({ pathRel, raw, rules, sensitiveLiterals, envSecrets }) {
189
+ // An auto-loaded agent doc (CLAUDE.md/AGENTS.md) → ship a brand-free stub, never the
190
+ // core's own project memory (task 2121). The stub is brand-free by construction, so it
191
+ // needs no redaction and can never leak — it short-circuits ahead of the doc path.
192
+ if (isAgentDoc(pathRel)) {
193
+ return { buf: Buffer.from(CORE_AGENT_DOC_STUB, 'utf8'), leaks: [], advisories: [], kind: 'stub' };
194
+ }
157
195
  if (isDocPath(pathRel)) {
158
196
  const r = redactBlob({ buf: raw, rules, sensitiveLiterals, envSecrets });
159
197
  const leaks = r.leaks.map((l) => ({ label: `doc:${l.label}`, sample: l.sample }));
@@ -174,7 +212,7 @@ function processCoreFile({ pathRel, raw, rules, sensitiveLiterals, envSecrets })
174
212
  //
175
213
  // The source repo's package.json/package-lock.json (isPublishable() includes
176
214
  // both) are GAME-heavy — colyseus/phaser/sharp/discord.js plus the repo's own
177
- // name/version — and are not what a downstream `npm install @cloudbongos/core`
215
+ // name/version — and are not what a downstream `npm install @bongos/core`
178
216
  // should see. These two files are SYNTHESIZED here (never copied verbatim from
179
217
  // git) and staged in their place. Everything else still ships through the
180
218
  // normal isPublishable()/processCoreFile path.
@@ -195,27 +233,42 @@ function buildPackageJson({ version, sourceDeps, sourceOverrides }) {
195
233
  dependencies[name] = range;
196
234
  }
197
235
  const pkg = {
198
- name: '@cloudbongos/core',
236
+ name: '@bongos/core',
199
237
  version,
200
238
  description: 'Cloud Bongos — the AI-first build platform core (GDS + platform surfaces + module system), installed as a versioned dependency (ADR 0108).',
201
239
  license: 'AGPL-3.0-or-later',
202
240
  main: 'src/platform-server.js',
203
241
  bin: { bongos: 'bin/bongos.js' },
204
242
  // Named exports a consumer imports directly, alongside the default entry
205
- // (buildPlatformApp, from `main`): mountInternalSurfaces (the shared
206
- // host-routing surface both server.js and platform-server.js call) and the
207
- // module-api doorway a module's routes/seams are authored against.
243
+ // (buildPlatformApp, from `main`). Two groups:
244
+ // • the platform surface — serve-internal (the shared host-routing surface
245
+ // both server.js and platform-server.js call) + the module-api doorway a
246
+ // module's routes/seams are authored against.
247
+ // • the GAME-HOST KIT (rehearsal F3, task 2161) — the core internals a
248
+ // game-bearing instance's own entrypoint (server.js, kept host per task
249
+ // 2134) wires directly: the API-404 shaping, the uptime poller, the module
250
+ // loader, the enabled-module gate, and the seam registry. A game-less
251
+ // instance boots via `.`/platform-server.js and never imports these; a game
252
+ // instance's server.js requires them, and the cutover codemod
253
+ // (scripts/gds/cutover-codemod.js) rewrites its relative `./src/*` requires
254
+ // to exactly these subpaths. Every subpath the codemod's CORE_INTERNAL_MAP
255
+ // targets MUST appear here or the rewritten require won't resolve.
208
256
  exports: {
209
257
  '.': './src/platform-server.js',
210
258
  './serve-internal': './src/bongos/serve-internal.js',
211
259
  './module-api': './src/module-api.js',
260
+ './bongos/api-path-404': './src/bongos/api-path-404.js',
261
+ './bongos/uptime-poller': './src/bongos/uptime-poller.js',
262
+ './module-loader/loader': './src/module-loader/loader.js',
263
+ './modules': './src/modules.js',
264
+ './module-seams': './src/module-seams.js',
212
265
  },
213
266
  engines: { node: '>=22' },
214
267
  // Pre-launch distribution posture (task 2089 / ADR 0134): publish PRIVATE by
215
268
  // default. `access:"restricted"` makes a scoped package private on publish, so a
216
269
  // paid npm org can ship it where only members can install — no accidental public
217
270
  // leak if someone forgets the CLI flag. Going public at launch is one step:
218
- // `npm access public @cloudbongos/core` (or flip this to "public"). The name must
271
+ // `npm access public @bongos/core` (or flip this to "public"). The name must
219
272
  // stay SCOPED to be private at all — unscoped npm names are always public.
220
273
  publishConfig: { access: 'restricted' },
221
274
  dependencies,
@@ -481,7 +534,7 @@ function publishTarball({ tgzPath, live }) {
481
534
  if (!live) {
482
535
  console.error(' Dry-run: nothing is uploaded. To publish for real: re-run with --publish --live.');
483
536
  console.error(' That is PERMANENT and requires `npm login` + the cloudbongos npm org on a paid plan');
484
- console.error(' (private scoped publish needs one). Going public later: `npm access public @cloudbongos/core`.');
537
+ console.error(' (private scoped publish needs one). Going public later: `npm access public @bongos/core`.');
485
538
  }
486
539
  const r = spawnSync(NPM_BIN, args, { cwd: REPO_ROOT, stdio: ['inherit', process.stderr, 'inherit'] });
487
540
  if (r.error || r.status !== 0) {
@@ -489,7 +542,7 @@ function publishTarball({ tgzPath, live }) {
489
542
  if (live) console.error(' Common causes: not logged in (`npm login`), the org isn’t on a paid plan (private scoped publish requires one), or 2FA.');
490
543
  process.exit(r.status || 1);
491
544
  }
492
- console.error(`[package-core] npm publish ${live ? 'succeeded — @cloudbongos/core is live (private).' : 'dry-run OK — the tarball is publishable.'}`);
545
+ console.error(`[package-core] npm publish ${live ? 'succeeded — @bongos/core is live (private).' : 'dry-run OK — the tarball is publishable.'}`);
493
546
  }
494
547
 
495
548
  function main() {
@@ -520,7 +573,7 @@ function main() {
520
573
 
521
574
  // 2b. Synthesize the core's own package.json + pruned package-lock.json from the
522
575
  // SOURCE files at this ref (never the live working tree, so --ref stays
523
- // reproducible) — express+pg only, name @cloudbongos/core, version = the
576
+ // reproducible) — express+pg only, name @bongos/core, version = the
524
577
  // platform version being packaged.
525
578
  const pkgJsonBlob = entries.find((e) => e.path === 'package.json');
526
579
  const pkgLockBlob = entries.find((e) => e.path === 'package-lock.json');
@@ -557,6 +610,7 @@ function main() {
557
610
  const advisories = []; // { path, label, sample } — non-fatal (brand/IP that ships verbatim)
558
611
  let docCount = 0;
559
612
  let funcCount = 0;
613
+ let stubCount = 0; // agent docs (CLAUDE.md/AGENTS.md) replaced with the brand-free stub (task 2121)
560
614
  for (const e of publishable) {
561
615
  let raw;
562
616
  try { raw = gitBuf(['cat-file', 'blob', e.sha]); }
@@ -565,7 +619,7 @@ function main() {
565
619
  processCoreFile({ pathRel: e.path, raw, rules, sensitiveLiterals, envSecrets });
566
620
  for (const l of fileLeaks) leaks.push({ path: e.path, label: l.label, sample: l.sample });
567
621
  for (const a of fileAdvisories) advisories.push({ path: e.path, label: a.label, sample: a.sample });
568
- if (kind === 'doc') docCount++; else funcCount++;
622
+ if (kind === 'doc') docCount++; else if (kind === 'stub') stubCount++; else funcCount++;
569
623
  filesMeta.push({ path: e.path, mode: e.mode, sha256: sha256hex(buf) });
570
624
  staged.push({ name: TAR_ROOT + e.path, mode: parseInt(normalizeMode(e.mode), 8), buf });
571
625
  }
@@ -593,7 +647,7 @@ function main() {
593
647
  console.error(' for a live-credential leak, remove the secret at SOURCE (it should never be committed). Then re-run. dist/ was NOT touched.');
594
648
  process.exit(1);
595
649
  }
596
- console.error(`[package-core] no-leak gate PASSED — ${staged.length} files clean (${docCount} docs redacted, ${funcCount} functional verbatim).`);
650
+ console.error(`[package-core] no-leak gate PASSED — ${staged.length} files clean (${docCount} docs redacted, ${stubCount} agent-docs stubbed, ${funcCount} functional verbatim).`);
597
651
 
598
652
  // Advisory: brand-identity + public-IP literals that ship VERBATIM inside functional
599
653
  // files. Not a leak (these are public, not secrets; a downstream rebrands via config) —
@@ -614,6 +668,7 @@ function main() {
614
668
  redaction: {
615
669
  model: 'docs-redacted+functional-verbatim', // task 1824
616
670
  docs_redacted: docCount,
671
+ agent_docs_stubbed: stubCount, // CLAUDE.md/AGENTS.md → brand-free stub (task 2121)
617
672
  functional_verbatim: funcCount,
618
673
  rules: rules.length,
619
674
  gate_literals: sensitiveLiterals.length,
@@ -675,6 +730,8 @@ module.exports = {
675
730
  octal, tarChecksum, ustarHeader, splitUstarName, buildTar,
676
731
  // task 1824 — the consumer-core file-classification layer (pure; unit-tested)
677
732
  isDocPath, functionalSecretLeaks, processCoreFile,
733
+ // task 2121 — agent-doc (CLAUDE.md/AGENTS.md) stub so a consumer's node_modules can't auto-load core memory
734
+ isAgentDoc, CORE_AGENT_DOC_STUB,
678
735
  // task 1882 (ADR 0108 §2) — the real installable npm package
679
736
  CORE_DEP_NAMES, buildPackageJson, resolveLockDep, lockfileClosure, prunePackageLock,
680
737
  // task 2089 (ADR 0134) — private-by-default npm publish
@@ -56,6 +56,12 @@ const REPO_ROOT = path.resolve(__dirname, '..', '..');
56
56
  // plain require (its require.main guard means importing it runs no CLI).
57
57
  const oauthSecret = require('./oauth-secret');
58
58
 
59
+ // The registry-install gates + env-fed .npmrc (ADR 0134, task 2090). Lets the
60
+ // standalone scaffold OPT IN to pulling the PRIVATE @bongos/core from the npm
61
+ // registry (PROVISION_CORE_FROM_REGISTRY=1) instead of vendoring a tarball, with a
62
+ // fail-soft fallback to the vendored path when no NPM_TOKEN is present.
63
+ const { registryCoreRequested, hasNpmToken } = require('./npmrc');
64
+
59
65
  // The HTTP User-Agent the manifest conversion stamps its GitHub call with (GitHub
60
66
  // requires a UA). Overridable so a fork can identify itself; not secret.
61
67
  const MANIFEST_UA = process.env.PROVISION_GITHUB_UA || 'cloudbongos-provisioner';
@@ -118,7 +124,7 @@ const CONFIG = {
118
124
  // since the control plane and the run box are then the same machine.
119
125
  controlPlaneIp: process.env.PROVISION_CONTROL_PLANE_IP || null,
120
126
  // Parent dir for a STANDALONE instance's OWN repo checkout (hosting_shape='standalone',
121
- // ADR 0108): each lives at <standaloneBase>/<slug> with @cloudbongos/core installed as
127
+ // ADR 0108): each lives at <standaloneBase>/<slug> with @bongos/core installed as
122
128
  // an npm dep. Distinct from co-tenant (which shares THIS control-plane checkout).
123
129
  standaloneBase: process.env.PROVISION_STANDALONE_BASE || '/srv/cloudbongos',
124
130
  // ── Privilege escalation (task 2066, ADR 0128) ───────────────────────────
@@ -207,13 +213,45 @@ function migrateCmd(inst, { privileged = false } = {}) {
207
213
  : `PGDATABASE=${dbName(inst)} MEDUSA_GDS_ONLY=1 ./scripts/migrate.sh`;
208
214
  }
209
215
 
216
+ // Seed the instance's FIRST version so it can take tasks from minute one (task 2119,
217
+ // goal 35). A freshly-migrated instance DB comes up with an EMPTY versions table —
218
+ // migrate runs instance-seeds-off (ADR 0105) and `bongos init` ran --no-seed — yet
219
+ // every task requires a version (tasks.version_id NOT NULL) and POST /versions is
220
+ // Archon-only (no Archon exists until first sign-in). Without a seed here, a brand-new
221
+ // project has NOWHERE to file a task. This runs on the box's DB path (no rank gate),
222
+ // ONLY IF the versions table is empty: idempotent, safe to re-run, and it never
223
+ // disturbs a project that already has versions. Mirrors seedViaApi's shape — V1
224
+ // (status 'building') + one done-when criterion so /status has a finish line from day
225
+ // one. `track` is set EXPLICITLY: versions.track is NOT NULL with no default (mig 112
226
+ // dropped the CHECK), and 'product' matches the canonical V1 seed in 003_pms.sql.
227
+ //
228
+ // The id/name/done_when come from instanceInitSpec so the starter version has ONE
229
+ // source of truth (the same spec the greenfield `bongos init` seed uses). SQL string
230
+ // literals are DOLLAR-QUOTED ($v$…$v$) so the whole -c argument is single-quoted —
231
+ // the one form that is safe UNCHANGED across all three executors: inline (/bin/sh),
232
+ // over SSH (bash -s), AND embedded in a dedicated droplet's cloud-init (bash -lc "…"),
233
+ // with no nested-quote or $-expansion hazard.
234
+ function seedFirstVersionCmd(inst, { privileged = false } = {}) {
235
+ const v = instanceInitSpec(inst).version;
236
+ const q = (s) => `$v$${s}$v$`; // dollar-quoted literal (no value contains a single quote or $)
237
+ const sql =
238
+ `INSERT INTO versions (id, name, track, status, done_when) ` +
239
+ `SELECT ${q(v.id)}, ${q(v.name)}, $v$product$v$, $v$building$v$, ${q(v.done_when)} ` +
240
+ `WHERE NOT EXISTS (SELECT 1 FROM versions); ` +
241
+ `INSERT INTO done_when_criteria (version_id, criterion_id, criterion_md, sort_order) ` +
242
+ `SELECT ${q(v.id)}, $v$first-goal$v$, ${q(v.done_when)}, 10 ` +
243
+ `WHERE EXISTS (SELECT 1 FROM versions WHERE id = ${q(v.id)}) ` +
244
+ `AND NOT EXISTS (SELECT 1 FROM done_when_criteria WHERE version_id = ${q(v.id)} AND criterion_id = $v$first-goal$v$);`;
245
+ return asPostgres(`psql -v ON_ERROR_STOP=1 -d ${dbName(inst)} -c '${sql}'`, privileged);
246
+ }
247
+
210
248
  // ── STANDALONE shape (hosting_shape='standalone', ADR 0108, task 1978) ────────
211
249
  // A standalone instance runs from its OWN repo checkout (host content: config/,
212
- // migrations/instance/, the core PIN in package.json) with @cloudbongos/core installed
250
+ // migrations/instance/, the core PIN in package.json) with @bongos/core installed
213
251
  // as an npm DEPENDENCY — NOT the shared control-plane checkout the co-tenant shape uses.
214
252
  // It is the ADR 0108 DESTINATION model; these generators make provision.js drive the
215
253
  // scripts/deploy/deploy-instance.sh runbook API-driven instead of by hand.
216
- const CORE_PKG_DIR = 'node_modules/@cloudbongos/core';
254
+ const CORE_PKG_DIR = 'node_modules/@bongos/core';
217
255
  function standaloneRoot(inst, { base = CONFIG.standaloneBase } = {}) { return path.posix.join(base, inst.slug); }
218
256
  // Sync the instance's own repo (host content + the core pin). Mirrors deploy-instance.sh
219
257
  // step 1 — assumes the repo is already cloned at standaloneRoot (initial clone is a
@@ -281,7 +319,7 @@ function instanceInitSpec(inst, { ownerLogin } = {}) {
281
319
  const INSTANCE_GITIGNORE = ['node_modules/', 'dist/', '.env', '.env.local', '*.log', ''].join('\n');
282
320
 
283
321
  // Clone the (empty) target_ref → standaloneRoot → materialize config/ + .claude/ + a
284
- // file:-pinned @cloudbongos/core + lockfile (via `bongos init --vendor-core`, task 2053)
322
+ // file:-pinned @bongos/core + lockfile (via `bongos init --vendor-core`, task 2053)
285
323
  // → commit + push. Idempotent (skips once the repo carries a package.json) and dry-run
286
324
  // safe (every mutation goes through the injected exec/writeFile). ADR 0108 / 0125.
287
325
  async function scaffoldStandaloneRepo(inst, deps) {
@@ -327,23 +365,44 @@ async function scaffoldStandaloneRepo(inst, deps) {
327
365
  }
328
366
  exec(`git -C ${root} checkout -B main`);
329
367
 
330
- // 2. build the installable core tarball from THIS control-plane checkout (the core source).
331
- exec(`node scripts/gds/package-core.js`); // cwd = REPO_ROOT → dist/cloudbongos-core-<v>.tgz
332
- const tgz = path.join(REPO_ROOT, 'dist', `cloudbongos-core-${coreV}.tgz`);
368
+ // Core-install path (ADR 0134, task 2090). DEFAULT = vendor a tarball built from THIS
369
+ // control-plane checkout (offline, proven — task 2053). OPT-IN = pull the PRIVATE
370
+ // @bongos/core from the npm registry (PROVISION_CORE_FROM_REGISTRY=1). The registry
371
+ // path needs NPM_TOKEN at `npm ci` time; if the flag is set but no token is present we
372
+ // FAIL SOFT to the vendored path so a tokenless standup still works (never a broken
373
+ // instance). The env is injectable for tests; the runner falls back to process.env.
374
+ const env = deps.env || process.env;
375
+ const wantRegistry = registryCoreRequested(env);
376
+ const useRegistry = wantRegistry && hasNpmToken(env);
377
+ if (wantRegistry && !useRegistry) {
378
+ log(' [scaffold] PROVISION_CORE_FROM_REGISTRY set but no NPM_TOKEN in env — falling back to the vendored-tarball core (ADR 0134 fail-soft).');
379
+ }
333
380
 
334
- // 3. materialize config/ + .claude/ + a file:-pinned package.json + lockfile via `bongos init`
335
- // (--vendor-core, task 2053). --no-seed: the instance's own DB is seeded by migrate, not here.
381
+ // materialize config/ + .claude/ + a pinned package.json + lockfile via `bongos init`.
382
+ // --no-seed: the instance's own DB is seeded by migrate, not here. Two mutually
383
+ // exclusive core-resolution shapes:
384
+ // registry (--registry-core): caret pin + env-fed .npmrc; `npm ci` pulls from the
385
+ // registry. init generates the lockfile (NPM_TOKEN is present — we gated on it).
386
+ // vendored (--vendor-core, default): a tarball built from this checkout, file:-pinned.
336
387
  const spec = instanceInitSpec(inst, { ownerLogin });
337
388
  const specPath = path.join(os.tmpdir(), `bongos-init-${inst.slug}.json`);
338
389
  writeFile(specPath, JSON.stringify(spec, null, 2));
339
- exec(`node scripts/gds/init.js --from ${specPath} --dir ${root} --no-seed --force --vendor-core ${tgz}`);
390
+ if (useRegistry) {
391
+ log(` [scaffold] core install: registry — PRIVATE @bongos/core@${coreV} via env-fed NPM_TOKEN (ADR 0134)`);
392
+ exec(`node scripts/gds/init.js --from ${specPath} --dir ${root} --no-seed --force --registry-core`);
393
+ } else {
394
+ log(` [scaffold] core install: vendored tarball (offline default)`);
395
+ exec(`node scripts/gds/package-core.js`); // cwd = REPO_ROOT → dist/bongos-core-<v>.tgz
396
+ const tgz = path.join(REPO_ROOT, 'dist', `bongos-core-${coreV}.tgz`);
397
+ exec(`node scripts/gds/init.js --from ${specPath} --dir ${root} --no-seed --force --vendor-core ${tgz}`);
398
+ }
340
399
 
341
400
  // 4. commit + push the scaffold to the instance's own main (keep node_modules out).
342
401
  writeFile(path.join(root, '.gitignore'), INSTANCE_GITIGNORE);
343
402
  exec(`git -C ${root} config user.name "Cloud Bongos"`);
344
403
  exec(`git -C ${root} config user.email "bot@cloudbongos.com"`);
345
404
  exec(`git -C ${root} add -A`);
346
- exec(`git -C ${root} commit -m "chore: scaffold ${inst.slug} on a pinned @cloudbongos/core ${coreV} (provision.js, ADR 0108)"`, { allowFail: true });
405
+ exec(`git -C ${root} commit -m "chore: scaffold ${inst.slug} on a pinned @bongos/core ${coreV} (provision.js, ADR 0108)"`, { allowFail: true });
347
406
  exec(`git -C ${root} push -u origin main`);
348
407
  log(` [scaffold] pushed initial scaffold to ${repo.owner}/${repo.name}@main`);
349
408
  return { ok: true, scaffolded: true };
@@ -446,11 +505,25 @@ ${prefix}_OAUTH_ORIGIN=${origin}
446
505
  # GitHub App Manifest flow (ADR 0133) — the owner clicked one link; no secret was pasted.`
447
506
  : `# Provisioned by scripts/gds/provision.js (ADR 0111). Fill the OAuth app creds via the
448
507
  # one-click GitHub App Manifest flow (ADR 0133), or manually (oauth-secret.js place):`;
508
+ // The founding owner (firstAdmin): the GitHub login src/bongos/auth.js seats as the
509
+ // instance's first Archon on first sign-in (maybeSeatFirstAdmin checks
510
+ // <prefix>_FIRST_ADMIN before branding.firstAdmin). WITHOUT it a provisioned instance
511
+ // has NO owner — first sign-in is refused / lands rankless and the owner can never
512
+ // claim their own instance (goal 35 / criterion 165 regression, caught live 2026-07-07:
513
+ // demo had every origin override but no FIRST_ADMIN, so lars589 could not be seated).
514
+ // Derived from the instance repo owner (target_ref = "<owner>/<repo>"), the SAME source
515
+ // instanceInitSpec uses for the scaffold's branding.firstAdmin — so this env override and
516
+ // the scaffolded config/branding.json agree. (Org-owned repo: the org login is not a
517
+ // sign-in identity, so it is left unset; the owner sets <prefix>_FIRST_ADMIN by hand.)
518
+ const ownerRepo = parseTargetRef(inst.target_ref);
519
+ const firstAdminLine = ownerRepo && ownerRepo.owner
520
+ ? `${prefix}_FIRST_ADMIN=${ownerRepo.owner}\n`
521
+ : '';
449
522
  return `# /etc/${inst.slug}/web.env — per-instance secrets (chmod 600, OUTSIDE the repo).
450
523
  ${credComment}
451
524
  ${prefix}_GITHUB_CLIENT_ID=${clientId || ''}
452
525
  ${prefix}_GITHUB_CLIENT_SECRET=${clientSecret || ''}
453
- GDS_BRANDING_FILE=${PROVISIONED_BRANDING_FILE}
526
+ ${firstAdminLine}GDS_BRANDING_FILE=${PROVISIONED_BRANDING_FILE}
454
527
  ${originLines}PORT=${inst.port}
455
528
  PGDATABASE=${dbName(inst)}
456
529
  `;
@@ -808,7 +881,7 @@ async function provisionInstance(inst, deps) {
808
881
  // Co-tenant OR standalone: a process bound to an allocated port on the box it runs
809
882
  // on. Co-tenant shares that box's checkout ($0, cloudbongos.com model — under
810
883
  // remote-exec, the co-hosting box); standalone (ADR 0108) runs from its OWN repo
811
- // dir with a pinned @cloudbongos/core (synced in step 2) on the CONTROL PLANE.
884
+ // dir with a pinned @bongos/core (synced in step 2) on the CONTROL PLANE.
812
885
  // Allocate against the ports of whichever box it runs on (boxExec: remote for a
813
886
  // co-tenant, local for a standalone — task 2074), then run the rest there.
814
887
  if (!inst.port) {
@@ -838,11 +911,16 @@ async function provisionInstance(inst, deps) {
838
911
  // ── step 2: code sync (standalone) + database ─────────────────────────────
839
912
  if (local && standalone) {
840
913
  // Standalone (ADR 0108 / deploy-instance.sh steps 1-2): sync the instance's own
841
- // repo + install the pinned @cloudbongos/core, so the migrate + service below run
914
+ // repo + install the pinned @bongos/core, so the migrate + service below run
842
915
  // from the INSTANCE root, not this control-plane checkout. cwd = standaloneRoot.
843
916
  // boxExec = the control plane (where scaffoldStandaloneRepo just created the dir).
917
+ // REGISTRY CORE (ADR 0134): when the scaffold pinned the registry core, the committed
918
+ // .npmrc reads `_authToken=${NPM_TOKEN}` — so `npm ci` resolves the PRIVATE package
919
+ // only if NPM_TOKEN is in this runner's env (makeExec inherits process.env). The
920
+ // scaffold already gated on the token, so it is present; the VENDORED default needs
921
+ // no token (the tarball is committed). A tokenless registry `npm ci` 404s cleanly.
844
922
  const root = standaloneRoot(inst);
845
- log(' [code] standalone — pull instance repo + npm ci (pinned @cloudbongos/core)');
923
+ log(' [code] standalone — pull instance repo + npm ci (pinned @bongos/core)');
846
924
  boxExec(standalonePullCmd(), { cwd: root });
847
925
  boxExec(standaloneInstallCmd(), { cwd: root });
848
926
  }
@@ -851,7 +929,13 @@ async function provisionInstance(inst, deps) {
851
929
  boxExec(dbCreateCmd(inst, { privileged }), { allowFail: true }); // "already exists" is fine
852
930
  if (standalone) boxExec(standaloneMigrateCmd(inst, { privileged }), { cwd: standaloneRoot(inst) }); // instance-root migrate
853
931
  else boxExec(migrateCmd(inst, { privileged }));
854
- } else { log(' (runs via cloud-init on the droplet)'); }
932
+ // Seed the first version so the instance can take tasks from minute one (task 2119,
933
+ // goal 35). Only fires if the versions table is empty — idempotent, never disturbs an
934
+ // existing project. NOT allowFail: a re-run is a clean 0-row no-op, so a real failure
935
+ // here should surface. Dedicated bakes the same step into cloud-init (dedicatedUserData).
936
+ log(' [seed] first version (only if versions is empty)');
937
+ boxExec(seedFirstVersionCmd(inst, { privileged }));
938
+ } else { log(' (db create + migrate + first-version seed run via cloud-init on the droplet)'); }
855
939
 
856
940
  // ── step 3: config + per-instance secrets ─────────────────────────────────
857
941
  log(' [config] per-instance web.env');
@@ -929,6 +1013,7 @@ function dedicatedUserData(inst) {
929
1013
  runcmd:
930
1014
  - [ bash, -lc, "${dbCreateCmd(i)} || true" ]
931
1015
  - [ bash, -lc, "cd ${REPO_ROOT} && ${migrateCmd(i)}" ]
1016
+ - [ bash, -lc, "${seedFirstVersionCmd(i)}" ]
932
1017
  - [ bash, -lc, "systemctl daemon-reload && systemctl enable --now ${i.slug}" ]
933
1018
  `;
934
1019
  }
@@ -1310,7 +1395,7 @@ if (require.main === module) main();
1310
1395
  module.exports = {
1311
1396
  CONFIG, MAX_INTENT_ATTEMPTS,
1312
1397
  // pure step generators (tested directly)
1313
- dbName, dbCreateCmd, migrateCmd, serviceUnit, serviceUnitPath, webEnvBody, webEnvPath,
1398
+ dbName, dbCreateCmd, migrateCmd, seedFirstVersionCmd, serviceUnit, serviceUnitPath, webEnvBody, webEnvPath,
1314
1399
  standaloneRoot, standalonePullCmd, standaloneInstallCmd, standaloneMigrateCmd,
1315
1400
  // standalone scaffold (ADR 0108 / 0125, task 2055)
1316
1401
  parseTargetRef, instanceRepoRemote, instanceInitSpec, scaffoldStandaloneRepo, coreVersionSafe,
@@ -44,7 +44,9 @@ const PUBLISH_ALLOWLIST = [
44
44
  'src/', // platform engine + GDS core (the game residue is denied below)
45
45
  'scripts/', // build + methodology tooling (deploy is denied below)
46
46
  'bin/', // the `cloudbongos`/`bongos` CLI entrypoint
47
- 'server.js', // the single-process app entry
47
+ // NB: repo-root server.js is the GAME+platform entry (top-level require('colyseus'),
48
+ // a pruned core dep) — HOST-excluded in CONTENT_EXCLUDE below; the core boots
49
+ // game-less via src/platform-server.js (package-core sets that as `main`). task 2134.
48
50
  // --- the build system's shared schema + its tests ---
49
51
  'migrations/',
50
52
  'tests/',
@@ -63,6 +65,7 @@ const PUBLISH_ALLOWLIST = [
63
65
  'modules/status-ui/',
64
66
  'modules/dev-box/',
65
67
  'modules/discord/',
68
+ 'modules/provisioning/', // instance-hosting control plane — CORE like its sibling dev-box (same do-api/cf-tunnel toolchain, all core). Reclassified IN so the core CLI scripts/gds/provision.js resolves it from the core package post-split, not a MODULE_NOT_FOUND (task 2135). default:false — shipped ≠ enabled.
66
69
  // --- neutral (customer-0) config starters + their schemas (the filled-in *.json twins are denied) ---
67
70
  'config/branding.neutral.json',
68
71
  'config/modules.neutral.json',
@@ -77,7 +80,7 @@ const PUBLISH_ALLOWLIST = [
77
80
  'CONTRIBUTING.md',
78
81
  'CODE_OF_CONDUCT.md',
79
82
  'docs/adr/', // sanitized — ADR 0065 §4 "docs/ADRs (sanitized)"
80
- 'docs/recipes/',
83
+ 'docs/recipes/', // portable METHODOLOGY recipes only; project-specific ones (art/staging/load-test/standup/decouple) are denied below — task 2153
81
84
  'docs/design/',
82
85
  'docs/research/',
83
86
  'docs/architecture.md',
@@ -85,6 +88,11 @@ const PUBLISH_ALLOWLIST = [
85
88
  // renders broken onboarding + API-reference pages (task 2078). Redacted like the
86
89
  // rest of this docs section; the diagrams' .png/.svg regenerate on the box.
87
90
  'docs/onboarding/', // primer.md + drachmae-and-karma.md + diagram sources (/builders/primer · /drachmae · /diagrams)
91
+ // API artifacts (classification settled, task 2141): CORE-shipped STARTERS so a fresh
92
+ // hall/docs render before first regen — but per-instance GENERATED. init + `bongos
93
+ // upgrade` regenerate them INTO the instance; the instance-root fitness gate
94
+ // (gen-api-docs --check) + tests/api_client.mjs guard drift. They ship; they are not a
95
+ // monolith-only artifact.
88
96
  'docs/api/openapi.json', // the generated OpenAPI 3.1 spec served at /docs/openapi.json
89
97
  'docs/api-reference.md', // the markdown API reference
90
98
  'docs/modules-contract.md',
@@ -161,12 +169,33 @@ const CONTENT_EXCLUDE = [
161
169
  'src/world/',
162
170
  'src/rooms/',
163
171
  'src/preview-server.js',
172
+ 'server.js', // repo-root game+platform entry: top-level require('colyseus') (a pruned core dep) → un-runnable in the game-less package; the core boots via src/platform-server.js. Mirrors src/preview-server.js. (task 2134)
164
173
  // the art feature's CLI tooling lives under scripts/ (legacy top-level) but belongs
165
174
  // to the excluded art module — exclude it with the feature it serves.
166
175
  'scripts/art/',
176
+ 'scripts/gds/art-stage.js', // art sandbox-staging CLI: requires modules/art-pipeline's build_tilesheet.py; excluded with the art feature it serves so a core file never requires an excluded module (task 2135)
167
177
  'scripts/tile-add.js',
168
178
  'scripts/tile-find.js',
169
179
  'scripts/tile-recommend.js',
180
+ // The art pipeline's operational RECIPE — belongs to the excluded art module; exclude it
181
+ // with the feature it serves (mirrors scripts/art/ above). docs/recipes/ is allowlisted
182
+ // wholesale, so this deny is what keeps the game-art recipe out of a non-art core. (task 2153)
183
+ 'docs/recipes/pixel-art-pipeline.md',
184
+ // Host-feature TESTS that statically import an EXCLUDED module's source. tests/ is
185
+ // allowlisted (the platform/methodology suite is core), but these cover the game/art
186
+ // HOST modules and import their source directly — so package-core (which selects via
187
+ // isPublishable) would ship them WITHOUT the module they need → MODULE_NOT_FOUND when a
188
+ // core CI/consumer runs them, and the R89 cutover would DELETE OTB's own game/art tests
189
+ // (they cover kept host modules; they cannot live in core). Exclude each with the feature
190
+ // it serves — mirrors scripts/gds/art-stage.js above. The guard in tests/publish_manifest.mjs
191
+ // derives this set from disk and fails if a new host-module test is added but not listed. (task 2147)
192
+ 'tests/walkability.mjs', // → modules/game/world
193
+ 'tests/terrain_picker.mjs', // → modules/game/public/game/world
194
+ 'tests/snapshot_picker.mjs', // → modules/game/public/game/world
195
+ 'tests/sprite_facing.mjs', // → modules/game/public/game/player
196
+ 'tests/turn_in_place.mjs', // → modules/game/public/game/player
197
+ 'tests/day_cycle.mjs', // → modules/game/public/game/fx
198
+ 'tests/art_key.mjs', // → modules/art-pipeline
170
199
  ];
171
200
 
172
201
  // (4) INSTANCE IDENTITY + HISTORY — this host's literals, ops config, build history, and
@@ -178,6 +207,11 @@ const INSTANCE_EXCLUDE = [
178
207
  'config/devbox-app.json',
179
208
  'config/hierarchy.json',
180
209
  'CODEOWNERS', // names the owner (a protected surface, excluded as identity)
210
+ // instance SEED migrations — this host's scope-truth SQL (planning seeds, world data).
211
+ // ADR 0105: a consumer's core must not carry them; migrate.sh reads instance seeds from
212
+ // resolveInstanceRoot() (SEED_INSTANCE), so the consumer repo owns them. Core migrations
213
+ // (migrations/core_NNN_*.sql + bare legacy migrations/NNN_*.sql) still publish. (task 2140)
214
+ 'migrations/instance/',
181
215
  // instance-specific docs + project history
182
216
  'docs/project-context.md',
183
217
  'docs/lore/',
@@ -192,6 +226,30 @@ const INSTANCE_EXCLUDE = [
192
226
  'docs/graphics-stress-test-plan.md',
193
227
  'docs/security-baseline.md',
194
228
  'docs/routes-permissions.md',
229
+ // instance-specific OPERATIONAL recipes — this host's staging + load-test artifacts, its
230
+ // specific control-plane / vanity-door standups, and its one-time monolith-decouple runbook.
231
+ // docs/recipes/ is allowlisted wholesale for the PORTABLE methodology recipes; these teach
232
+ // nothing a different instance would use, so they stay in this repo and never ship in the
233
+ // core (mirrors migrations/instance above). Redaction only de-brands them — this stops the
234
+ // irrelevant-noise at the source. The module-owned RECIPE redesign is deferred (idea 536). (task 2153)
235
+ 'docs/recipes/staging-data.md',
236
+ 'docs/recipes/parallel-load-test.md',
237
+ 'docs/recipes/parallel-load-results-2026-05-30.md',
238
+ 'docs/recipes/claude-gemini-bongos-doors.md',
239
+ 'docs/recipes/cloudbongos-standup.md',
240
+ 'docs/recipes/cloudbongos-staging-gate.md',
241
+ 'docs/recipes/amazonprimea-decouple-r89.md',
242
+ 'docs/recipes/amazonprimea-decouple-rollback-r89.md',
243
+ // instance-specific GAME-DESIGN specs — this host's pixel-art / level briefs (the container
244
+ // buildings, its palette, the world-map scroll). docs/design/ is allowlisted wholesale for the
245
+ // PORTABLE design docs (modular-architecture/*, the vanilla-hall-ui redesign scope); these four
246
+ // describe THIS instance's game and genericize to nothing, so they stay in this repo and never
247
+ // ship in the core. Redaction only de-brands NAMES — the world-narrative prose in them is not a
248
+ // name and survives redaction, so exclude at the source (mirrors the recipe carve-out above). (task 2155)
249
+ 'docs/design/container-exterior.md',
250
+ 'docs/design/container-exterior-tiles.md',
251
+ 'docs/design/container-interior.md',
252
+ 'docs/design/world-map-scroll.md',
195
253
  'blockers/',
196
254
  'limitations/',
197
255
  'generative-ideas.md',