@bongos/core 1.19.803 → 1.19.805

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 (235) hide show
  1. package/.bongos-core.json +261 -236
  2. package/.claude/skills/ask-for-help/SKILL.md +6 -6
  3. package/.claude/skills/backlog-review/SKILL.md +1 -1
  4. package/.claude/skills/blocker-review/SKILL.md +7 -7
  5. package/.claude/skills/blocker-solve/SKILL.md +5 -5
  6. package/.claude/skills/bug-triage/SKILL.md +7 -7
  7. package/.claude/skills/builder-claim/SKILL.md +3 -3
  8. package/.claude/skills/builder-cost/SKILL.md +2 -2
  9. package/.claude/skills/builder-end/SKILL.md +2 -2
  10. package/.claude/skills/builder-exit/SKILL.md +7 -7
  11. package/.claude/skills/builder-key/SKILL.md +2 -2
  12. package/.claude/skills/builder-reauth/SKILL.md +2 -2
  13. package/.claude/skills/builder-redteam/SKILL.md +7 -7
  14. package/.claude/skills/builder-release/SKILL.md +2 -2
  15. package/.claude/skills/builder-sequence/SKILL.md +1 -1
  16. package/.claude/skills/builder-setup/SKILL.md +3 -3
  17. package/.claude/skills/builder-ship/SKILL.md +1 -1
  18. package/.claude/skills/builder-stage/SKILL.md +1 -1
  19. package/.claude/skills/builder-start/SKILL.md +1 -1
  20. package/.claude/skills/fix-task/SKILL.md +4 -4
  21. package/.claude/skills/goal-create/SKILL.md +18 -18
  22. package/.claude/skills/goal-review/SKILL.md +7 -7
  23. package/.claude/skills/grade-audit/SKILL.md +5 -5
  24. package/.claude/skills/grade-recover/SKILL.md +4 -4
  25. package/.claude/skills/grader-health/SKILL.md +6 -6
  26. package/.claude/skills/idea-triage/SKILL.md +14 -14
  27. package/.claude/skills/merge-mode/SKILL.md +3 -3
  28. package/.claude/skills/planning-session/SKILL.md +20 -20
  29. package/.claude/skills/priority-session/SKILL.md +10 -10
  30. package/.claude/skills/recall/SKILL.md +1 -1
  31. package/.claude/skills/scan-before-install/SKILL.md +3 -3
  32. package/.claude/skills/status/SKILL.md +2 -2
  33. package/.claude/skills/strand-fix/SKILL.md +2 -2
  34. package/clients/bongos-client/README.md +1 -1
  35. package/clients/bongos-client/bongos-client.global.js +2 -0
  36. package/clients/bongos-client/index.cjs +2 -0
  37. package/clients/bongos-client/index.d.ts +2 -0
  38. package/clients/bongos-client/index.mjs +2 -0
  39. package/docs/api/openapi.json +45 -11
  40. package/docs/api-reference.md +11 -10
  41. package/docs/module-api-changelog.md +4 -0
  42. package/modules/builder-settings/profile-nudge-prefs.js +1 -1
  43. package/modules/builder-settings/render-prefs.js +1 -1
  44. package/modules/dev-box/app/README.md +1 -1
  45. package/modules/dev-box/app/src/gds-client.js +11 -9
  46. package/modules/dev-box/app/src/vendor/bongos-client.cjs +2 -0
  47. package/modules/dev-box/app/test/unit.mjs +13 -13
  48. package/modules/dev-box/box-access.js +3 -3
  49. package/modules/dev-box/box-onboard.js +7 -7
  50. package/modules/discord/bug-attachments.js +1 -1
  51. package/modules/economy/cost-classify.js +6 -6
  52. package/modules/grading/grader-rubric.json +1 -1
  53. package/modules/grading/grader-score.js +1 -1
  54. package/modules/hall-ui/module.json +1 -1
  55. package/modules/hall-ui/public/drachmae.js +3 -3
  56. package/modules/hall-ui/public/idea.js +1 -1
  57. package/modules/hall-ui/public/md-reader.js +1 -1
  58. package/modules/hall-ui/public/people.html +5 -1
  59. package/modules/hall-ui/public/people.js +44 -5
  60. package/modules/hall-ui/public/primer.js +4 -4
  61. package/modules/hall-ui/public/roster.js +1 -1
  62. package/modules/hall-ui/public/shell.js +1 -1
  63. package/modules/hall-ui/public/task.js +1 -1
  64. package/modules/ideas/inbox.js +2 -2
  65. package/modules/lifecycle/db-analytics.js +1 -1
  66. package/modules/lifecycle/done-when.js +4 -4
  67. package/modules/lifecycle/version-close.js +1 -1
  68. package/modules/memory/learnings.js +2 -2
  69. package/modules/memory/memory.js +1 -1
  70. package/modules/onboarding/onboarding.js +1 -1
  71. package/modules/platform-identity/routes/my-projects.js +1 -1
  72. package/modules/platform-identity/routes/sso.js +2 -2
  73. package/modules/public-landing/public/index.html +2 -2
  74. package/modules/public-landing/public/projects-floor.states.json +1 -1
  75. package/modules/public-landing/public/projects.html +1 -1
  76. package/modules/public-landing/public/projects.states.json +1 -1
  77. package/modules/sessions/db.js +120 -0
  78. package/modules/sessions/module.json +2 -2
  79. package/modules/sessions/pollers/session-upload-health.js +111 -0
  80. package/modules/sessions/pulse.js +2 -2
  81. package/modules/sessions/routes/sessions.js +46 -0
  82. package/modules/sessions/upload-health.js +197 -0
  83. package/modules/status-ui/module.json +1 -1
  84. package/modules/status-ui/public/explore.js +1 -1
  85. package/package-lock.json +2 -2
  86. package/package.json +1 -1
  87. package/scripts/gds/agent-invoke.js +3 -3
  88. package/scripts/gds/api.js +4 -4
  89. package/scripts/gds/api.sh +1 -1
  90. package/scripts/gds/architect-audit.js +1 -1
  91. package/scripts/gds/artifact-audit.js +2 -2
  92. package/scripts/gds/audit-ships.js +2 -2
  93. package/scripts/gds/backfill-cost.js +1 -1
  94. package/scripts/gds/backfill-sessions.js +1 -1
  95. package/scripts/gds/backfill-subagent-rewards.js +1 -1
  96. package/scripts/gds/backfill-task-rewards.js +2 -2
  97. package/scripts/gds/box-auth-check.js +1 -1
  98. package/scripts/gds/box-sync.js +3 -3
  99. package/scripts/gds/box.js +10 -10
  100. package/scripts/gds/build-cli-package.js +3 -3
  101. package/scripts/gds/capture.js +2 -2
  102. package/scripts/gds/ci-grade.js +1 -1
  103. package/scripts/gds/claim-recall.js +2 -2
  104. package/scripts/gds/cli-lib.js +3 -3
  105. package/scripts/gds/context-pack.js +1 -1
  106. package/scripts/gds/copy-apply.js +2 -2
  107. package/scripts/gds/dev-lib.js +2 -2
  108. package/scripts/gds/fetch-art-key.js +2 -2
  109. package/scripts/gds/fetch-sound-prefs.js +3 -3
  110. package/scripts/gds/grade-smoke.js +1 -1
  111. package/scripts/gds/hooks/pre-push.js +1 -1
  112. package/scripts/gds/init.js +9 -9
  113. package/scripts/gds/key-card.js +1 -1
  114. package/scripts/gds/learning-capture.js +2 -2
  115. package/scripts/gds/linkify-refs.js +2 -2
  116. package/scripts/gds/local-preview-lib.js +1 -1
  117. package/scripts/gds/login.js +11 -10
  118. package/scripts/gds/main-audit.js +1 -1
  119. package/scripts/gds/newcomer-floor.config.json +1 -1
  120. package/scripts/gds/newcomer-floor.js +2 -2
  121. package/scripts/gds/newcomer-floor.templates.json +2 -2
  122. package/scripts/gds/onboarding-ship.js +1 -1
  123. package/scripts/gds/paste-token.js +3 -3
  124. package/scripts/gds/portability-smoke-memory.sh +5 -5
  125. package/scripts/gds/prove-strict-versioning.js +2 -2
  126. package/scripts/gds/provision-net.js +2 -2
  127. package/scripts/gds/provision-units.js +3 -3
  128. package/scripts/gds/pulse.js +2 -2
  129. package/scripts/gds/push-path-brief.js +2 -2
  130. package/scripts/gds/reauth.js +1 -1
  131. package/scripts/gds/recall.js +1 -1
  132. package/scripts/gds/redteam-patrol.js +3 -3
  133. package/scripts/gds/render-ideas.js +5 -5
  134. package/scripts/gds/repo-metrics.js +1 -1
  135. package/scripts/gds/sandbox-stage.js +3 -3
  136. package/scripts/gds/seed-adopt-tasks.js +3 -3
  137. package/scripts/gds/seed-board-room-tasks.js +1 -1
  138. package/scripts/gds/seed-bongos-app-tasks.js +2 -2
  139. package/scripts/gds/seed-bongos-coreB-tranche1-tasks.js +3 -3
  140. package/scripts/gds/seed-bongos-coreB-tranche2-tasks.js +4 -4
  141. package/scripts/gds/seed-bongos-tasks.js +5 -5
  142. package/scripts/gds/seed-bongos-v1-idea-routing-tasks.js +1 -1
  143. package/scripts/gds/seed-bongos-v1-seo-tasks.js +1 -1
  144. package/scripts/gds/seed-bv1-community-tasks.js +1 -1
  145. package/scripts/gds/seed-bv1-privacy-invites-tasks.js +1 -1
  146. package/scripts/gds/seed-bv1-profile-page-tasks.js +1 -1
  147. package/scripts/gds/seed-bv1-profiles-tasks.js +1 -1
  148. package/scripts/gds/seed-bv1-r01-delta-tasks.js +1 -1
  149. package/scripts/gds/seed-gds-v4-tasks.js +3 -3
  150. package/scripts/gds/seed-medusa-tasks.js +1 -1
  151. package/scripts/gds/seed-productization-tasks.js +1 -1
  152. package/scripts/gds/seed-project-admin-console-tasks.js +1 -1
  153. package/scripts/gds/seed-provisioning-tasks.js +2 -2
  154. package/scripts/gds/seed-strict-versioning-tasks.js +3 -3
  155. package/scripts/gds/seed-v2-world-tasks.js +2 -2
  156. package/scripts/gds/seed-verify-criteria.js +1 -1
  157. package/scripts/gds/session-digest.js +1 -1
  158. package/scripts/gds/session.js +2 -2
  159. package/scripts/gds/setup.js +7 -7
  160. package/scripts/gds/ship-flow.js +3 -3
  161. package/scripts/gds/ship-grade-steps.js +3 -3
  162. package/scripts/gds/ship-memory-sync.js +1 -1
  163. package/scripts/gds/ship-session-upload.js +3 -3
  164. package/scripts/gds/smoke-batch-claim.sh +10 -10
  165. package/scripts/gds/smoke-batch-release.sh +14 -14
  166. package/scripts/gds/smoke-claim-consistency.sh +19 -19
  167. package/scripts/gds/smoke-dependencies.sh +9 -9
  168. package/scripts/gds/smoke-write.sh +11 -11
  169. package/scripts/gds/start.js +1 -1
  170. package/scripts/gds/status.js +2 -2
  171. package/scripts/gds/strand-watch.js +1 -1
  172. package/scripts/gds/triage.js +4 -4
  173. package/scripts/gds/version-close.js +2 -2
  174. package/scripts/hall-preview/README.md +1 -1
  175. package/scripts/hall-preview/server.js +1 -1
  176. package/src/bongos/auth-admission.js +3 -3
  177. package/src/bongos/auth-idp.js +2 -2
  178. package/src/bongos/auth.js +3 -3
  179. package/src/bongos/db.js +2 -2
  180. package/src/bongos/llm-cache.js +2 -2
  181. package/src/bongos/metrics.js +1 -1
  182. package/src/bongos/middleware/audit.js +3 -3
  183. package/src/bongos/middleware/rate-limit.js +1 -1
  184. package/src/bongos/platform-visibility-gate.js +2 -2
  185. package/src/bongos/routes/_helpers.js +1 -1
  186. package/src/bongos/routes/audit-log.js +1 -1
  187. package/src/bongos/routes/auth.js +5 -5
  188. package/src/bongos/routes/backup.js +1 -1
  189. package/src/bongos/routes/builders.js +1 -1
  190. package/src/bongos/routes/instance.js +1 -1
  191. package/src/bongos/routes/live.js +1 -1
  192. package/src/bongos/routes/me.js +2 -2
  193. package/src/bongos/routes/modules.js +2 -2
  194. package/src/bongos/routes/public.js +1 -1
  195. package/src/bongos/routes/security.js +4 -4
  196. package/src/bongos/routes.js +1 -1
  197. package/src/bongos/serve-internal.js +6 -6
  198. package/src/branding.js +1 -1
  199. package/src/module-api.js +1 -1
  200. package/src/module-seams.js +2 -2
  201. package/src/platform-server.js +2 -2
  202. package/tests/api_alias_exceptions.mjs +67 -0
  203. package/tests/application_echo.mjs +12 -12
  204. package/tests/artifact_audit.mjs +1 -1
  205. package/tests/auth_page_gate.mjs +4 -4
  206. package/tests/auth_web_recovery.mjs +11 -11
  207. package/tests/bongos_login.mjs +7 -4
  208. package/tests/box_env.mjs +6 -6
  209. package/tests/bug_attachments.mjs +1 -1
  210. package/tests/cli_sessions.mjs +1 -1
  211. package/tests/dev_lib.mjs +1 -1
  212. package/tests/discord_bugs.mjs +2 -2
  213. package/tests/discord_inbound.mjs +2 -2
  214. package/tests/explore_visible_states.mjs +1 -1
  215. package/tests/government_page_gates.mjs +1 -1
  216. package/tests/hall_reference_world.mjs +1 -1
  217. package/tests/idea_ideate_full.mjs +1 -1
  218. package/tests/idp_federation.mjs +2 -2
  219. package/tests/llm-cache.mjs +1 -1
  220. package/tests/manage_manifest_shared_read.mjs +3 -3
  221. package/tests/people_directory_clip.mjs +219 -0
  222. package/tests/planning_session_skill.mjs +1 -1
  223. package/tests/platform_visibility_gate.mjs +15 -15
  224. package/tests/profile_route.mjs +37 -26
  225. package/tests/projects_hub.mjs +2 -2
  226. package/tests/provision.mjs +2 -2
  227. package/tests/provision_settings_apply.mjs +4 -4
  228. package/tests/sandbox_stage.mjs +8 -8
  229. package/tests/scouting_owner_access_and_reach.mjs +3 -3
  230. package/tests/session_upload_health.mjs +329 -0
  231. package/tests/setup_device_flow_fallback.mjs +1 -1
  232. package/tests/skill_ask_for_help.mjs +3 -3
  233. package/tests/skill_grade_audit.mjs +2 -2
  234. package/tests/skill_grader_health.mjs +3 -3
  235. package/tests/smoke_write_contract.mjs +1 -1
@@ -268,7 +268,7 @@ async function main() {
268
268
  console.log(`\n📜 wrote ${relDoc}`);
269
269
 
270
270
  // File the seed ideas to the planning inbox. Payload mirrors capture.js
271
- // (POST /api/gds/inbox): { title, body_md, kind, suggested_version }.
271
+ // (POST /api/bongos/inbox): { title, body_md, kind, suggested_version }.
272
272
  // Provenance (which audit produced it) is folded into body_md.
273
273
  let filed = 0;
274
274
  const api = await cliClient();
@@ -157,7 +157,7 @@ async function fetchAuditedTasks({ call = apiCall } = {}) {
157
157
  for (let page = 0; page < 100; page++) {
158
158
  const q = buildTaskPageQuery({ status, limit: TASK_LIST_MAX_LIMIT, offset });
159
159
  const qs = new URLSearchParams(q).toString();
160
- const r = await call('GET', `/api/gds/tasks?${qs}`);
160
+ const r = await call('GET', `/api/bongos/tasks?${qs}`);
161
161
  if (!r || !r.ok) throw new Error(`GET /tasks?status=${status} → ${r && r.status}`);
162
162
  const page_rows = (r.data && r.data.tasks) || [];
163
163
  rows.push(...page_rows);
@@ -208,7 +208,7 @@ function blockerBody(stranded) {
208
208
 
209
209
  async function fileBlocker(stranded, { call = apiCall } = {}) {
210
210
  if (!stranded.length) return { filed: false, reason: 'nothing to report' };
211
- const r = await call('POST', '/api/gds/blockers', {
211
+ const r = await call('POST', '/api/bongos/blockers', {
212
212
  title: `${stranded.length} shipped task(s) claim an artifact nothing on main names`,
213
213
  body_md: blockerBody(stranded),
214
214
  source: 'artifact-audit',
@@ -160,7 +160,7 @@ async function fetchShipped(days) {
160
160
  const d = b.domains || {};
161
161
  const statusBase = String(d.statusOrigin || d.publicOrigin || '').replace(/\/+$/, '');
162
162
  const r = await fetch(
163
- `${statusBase}/api/gds/public/recent-shipped?days=${days}&limit=500`
163
+ `${statusBase}/api/bongos/public/recent-shipped?days=${days}&limit=500`
164
164
  );
165
165
  const data = await r.json();
166
166
  return data.tasks || [];
@@ -174,7 +174,7 @@ async function fetchFullTask(id) {
174
174
  }
175
175
 
176
176
  async function fetchLearning(taskId) {
177
- // /api/gds/learnings?task=<id> — we just need body_md.
177
+ // /api/bongos/learnings?task=<id> — we just need body_md.
178
178
  const api = await cliClient();
179
179
  const r = await api.learnings.getLearnings({ query: { task: taskId } });
180
180
  if (!r.ok) return null;
@@ -2,7 +2,7 @@
2
2
  // Backfill cost_log from the art-pipeline cost ledger.
3
3
  //
4
4
  // Reads art/iterations/cost_ledger.jsonl (gitignored, lives in whichever
5
- // worktree ran the pipeline) and POSTs each row to /api/gds/cost.
5
+ // worktree ran the pipeline) and POSTs each row to /api/bongos/cost.
6
6
  //
7
7
  // Idempotent thanks to migration 004_pms_cost_idempotency.sql:
8
8
  // re-running this script is a no-op (skipped rows print as 'dup').
@@ -56,7 +56,7 @@ const argVal = (name) => {
56
56
  };
57
57
  const EXISTING_FILE = argVal('existing') || '/tmp/otb-existing-session-ids.txt';
58
58
  const LIMIT = argVal('limit') ? parseInt(argVal('limit'), 10) : Infinity;
59
- // The /api/gds write limiter is per-IP 30 writes / 60s (the binding constraint;
59
+ // The /api/bongos write limiter is per-IP 30 writes / 60s (the binding constraint;
60
60
  // per-session is 60/60s). 2100ms spacing keeps us safely under 30/min so the
61
61
  // limiter never trips during a long backfill. Override with --pace=<ms>.
62
62
  const PACE_MS = argVal('pace') ? parseInt(argVal('pace'), 10) : 2100;
@@ -37,7 +37,7 @@
37
37
  // SAFETY MODEL (mirrors scripts/gds/backfill-task-rewards.js, ADR 0097):
38
38
  // * DRY-RUN BY DEFAULT. With no flags it prints the full plan + grand total and
39
39
  // writes NOTHING. A live mint requires ALL of: --apply, Archon rank verified
40
- // server-side via GET /api/gds/me, and a typed y/N confirmation (--yes skips
40
+ // server-side via GET /api/bongos/me, and a typed y/N confirmation (--yes skips
41
41
  // only the typing).
42
42
  // * IDEMPOTENT BY CONSTRUCTION, not by a new bookkeeping key. Every mint goes
43
43
  // through the REAL reward writer (modules/economy/credits.js
@@ -17,7 +17,7 @@
17
17
  // * DRY-RUN BY DEFAULT. With no flags it prints the full plan + grand total
18
18
  // and writes NOTHING. A live mint requires ALL of:
19
19
  // --apply explicit opt-in to write
20
- // Archon rank verified server-side via GET /api/gds/me; the
20
+ // Archon rank verified server-side via GET /api/bongos/me; the
21
21
  // script refuses for any other rank
22
22
  // interactive y/N a typed confirmation at the terminal (skip only
23
23
  // with --yes, which an Archon must pass deliberately)
@@ -372,7 +372,7 @@ async function main() {
372
372
  const api = await cliClient();
373
373
  me = await api.me.getMe();
374
374
  } catch (err) {
375
- console.error('--apply requires a verified Archon session; could not reach /api/gds/me:', err.message);
375
+ console.error('--apply requires a verified Archon session; could not reach /api/bongos/me:', err.message);
376
376
  await pool.end().catch(() => {});
377
377
  process.exit(3);
378
378
  }
@@ -70,7 +70,7 @@ async function probeMe(tokenInfo) {
70
70
  const ctl = new AbortController();
71
71
  const timer = setTimeout(() => ctl.abort(), ME_TIMEOUT_MS);
72
72
  try {
73
- const res = await fetch(`${tokenInfo.apiBase}/api/gds/me`, {
73
+ const res = await fetch(`${tokenInfo.apiBase}/api/bongos/me`, {
74
74
  method: 'GET',
75
75
  headers: { Authorization: `Bearer ${tokenInfo.token}`, 'User-Agent': 'box-auth-check/1.0' },
76
76
  signal: ctl.signal,
@@ -89,8 +89,8 @@ async function runWiden(argv) {
89
89
  const listOnly = !add && !remove && !clear;
90
90
 
91
91
  const r = listOnly
92
- ? await apiCall('GET', '/api/gds/box/widen')
93
- : await apiCall('POST', '/api/gds/box/widen', {
92
+ ? await apiCall('GET', '/api/bongos/box/widen')
93
+ : await apiCall('POST', '/api/bongos/box/widen', {
94
94
  ...(add ? { add: [add] } : {}),
95
95
  ...(remove ? { remove: [remove] } : {}),
96
96
  ...(clear ? { clear: true } : {}),
@@ -200,7 +200,7 @@ function formatScopeReport(scope) {
200
200
  async function reportScope() {
201
201
  try {
202
202
  const { apiCall } = require('./cli-lib');
203
- const r = await apiCall('GET', '/api/gds/box/scope');
203
+ const r = await apiCall('GET', '/api/bongos/box/scope');
204
204
  if (!r || r.status !== 200) {
205
205
  console.log('scope: could not read your box scope right now (that does not affect the sync above).');
206
206
  return;
@@ -197,14 +197,14 @@ async function resolveBuilder(pool, ref) {
197
197
  // 1002466). Split out of cmdProvision so GDS_BASE — and the named-tunnel block
198
198
  // baked in beside it — can be unit-tested without DB/DO/Cloudflare.
199
199
  //
200
- // GDS_BASE is the FULL api base (origin + /api/gds), matching what
200
+ // GDS_BASE is the FULL api base (origin + /api/bongos), matching what
201
201
  // infra/box-report-*.sh already derive from the session file when the env var is
202
202
  // absent (`"$GDS_BASE/box/host-keys"` with no further path inserted) — every box
203
203
  // used to get this only as a fallback derived on-box; baking it explicitly closes
204
204
  // the one on-box script (box-source-fetch.sh, out-of-repo) that skips that
205
205
  // derivation entirely and hardcodes a different instance's origin instead.
206
206
  function buildBoxEnv({ apiOrigin, namedTunnel }) {
207
- let env = `# /etc/otb/box.env — baked by box.js provision\nGDS_BASE=${String(apiOrigin).replace(/\/+$/, '')}/api/gds\n`;
207
+ let env = `# /etc/otb/box.env — baked by box.js provision\nGDS_BASE=${String(apiOrigin).replace(/\/+$/, '')}/api/bongos\n`;
208
208
  if (namedTunnel) {
209
209
  const { token, hostname, credential, previewHostname } = namedTunnel;
210
210
  env += `# named tunnel (#771/#774, ADR 0038)\nBOX_TUNNEL_TOKEN=${token}\nBOX_TERMINAL_HOSTNAME=${hostname}\nBOX_TERMINAL_CREDENTIAL=${credential}\nBOX_PREVIEW_HOSTNAME=${previewHostname}\n`;
@@ -506,16 +506,16 @@ function printWelcomePacket(login, scope) {
506
506
  console.log('own Mac/Windows (it signs you in, makes + registers your SSH key, and');
507
507
  console.log('installs the Claude Desktop connection file):');
508
508
  console.log('');
509
- console.log(` macOS/Linux: curl -fsSL ${base}/api/gds/box/connect.sh | bash`);
510
- console.log(` Windows: irm ${base}/api/gds/box/connect.ps1 | iex`);
511
- console.log(` (guide: ${base}/api/gds/box/connect )`);
509
+ console.log(` macOS/Linux: curl -fsSL ${base}/api/bongos/box/connect.sh | bash`);
510
+ console.log(` Windows: irm ${base}/api/bongos/box/connect.ps1 | iex`);
511
+ console.log(` (guide: ${base}/api/bongos/box/connect )`);
512
512
  console.log('');
513
513
  console.log(`Then: restart Claude Desktop → Code → Environment → "${boxEnvLabel()} Dev Box".`);
514
514
  console.log('');
515
515
  console.log('On a Chromebook / browser-only device (no Claude Desktop)? Skip the above —');
516
516
  console.log('your box serves its own terminal in a browser tab (ADR 0038). Once it is');
517
517
  console.log('active, get the URL + password and open it:');
518
- console.log(` GET ${base}/api/gds/box/terminal (or run /builder-box)`);
518
+ console.log(` GET ${base}/api/bongos/box/terminal (or run /builder-box)`);
519
519
  console.log('In that terminal, type `claude` to start working.');
520
520
  console.log('');
521
521
  console.log(`Your box: ${host} (scope=${scope})`);
@@ -532,8 +532,8 @@ async function cmdOnboard(pool, boxes, boxOnboard, ref, { apply, allowNoKeys })
532
532
  console.error(`✖ @${builder.github_login} has no registered SSH key yet — the box would have no way in.`);
533
533
  console.error('');
534
534
  console.error(' Ask the builder to connect FIRST (this registers their key), then re-run onboard:');
535
- console.error(` macOS/Linux: curl -fsSL ${gdsBase()}/api/gds/box/connect.sh | bash`);
536
- console.error(` Windows: irm ${gdsBase()}/api/gds/box/connect.ps1 | iex`);
535
+ console.error(` macOS/Linux: curl -fsSL ${gdsBase()}/api/bongos/box/connect.sh | bash`);
536
+ console.error(` Windows: irm ${gdsBase()}/api/bongos/box/connect.ps1 | iex`);
537
537
  console.error('');
538
538
  console.error(' (Override with --allow-no-keys to provision a keyless box anyway — you will');
539
539
  console.error(' then have to re-provision once they register a key.)');
@@ -890,7 +890,7 @@ async function cmdSweepDormant(pool, boxes, { apply }) {
890
890
 
891
891
  const sendWarning = async (box, days) => {
892
892
  const left = Math.max(CONFIG.dormantDays - days, 0);
893
- const ping = postReclaimPing(`@${box.github_login} — your dev box has been parked ${days} days. Its saved disk image will be reclaimed in ${left} day(s) to save cost, and anything on it you haven't pushed will be gone with it. Wake it any time with POST /api/gds/box/ensure to keep it.`);
893
+ const ping = postReclaimPing(`@${box.github_login} — your dev box has been parked ${days} days. Its saved disk image will be reclaimed in ${left} day(s) to save cost, and anything on it you haven't pushed will be gone with it. Wake it any time with POST /api/bongos/box/ensure to keep it.`);
894
894
  if (!ping.ok) { pingFailed++; return false; }
895
895
  await boxes.recordEvent(pool, {
896
896
  boxId: box.id, builderId: box.builder_id, event: 'dormant_warning',
@@ -921,7 +921,7 @@ async function cmdSweepDormant(pool, boxes, { apply }) {
921
921
  try {
922
922
  await deprovisionOne(pool, boxes, needDo(), box, { actor: 'sweep:dormant' });
923
923
  reclaimed++;
924
- const ping = postReclaimPing(`@${box.github_login} — your dev box was parked for ${days} days and has now been reclaimed to save cost, as warned. Queue a fresh one anytime with POST /api/gds/box/ensure (no operator needed); your memory is server-side and unaffected.`);
924
+ const ping = postReclaimPing(`@${box.github_login} — your dev box was parked for ${days} days and has now been reclaimed to save cost, as warned. Queue a fresh one anytime with POST /api/bongos/box/ensure (no operator needed); your memory is server-side and unaffected.`);
925
925
  if (!ping.ok) pingFailed++;
926
926
  console.log(` ✓ reclaimed @${box.github_login} (parked ${days}d)${ping.ok ? '' : ' [chat ping failed]'}`);
927
927
  } catch (e) { errors++; await markErrorUnlessDestroyed(pool, boxes, box.builder_id, e.message); console.log(` ✖ @${box.github_login}: ${e.message}`); }
@@ -131,7 +131,7 @@ const VERBS = {
131
131
  login: { script: 'login.js', group: 'account', summary: 'Sign in to an instance (bongos login <url> — browser click, no paste)' },
132
132
  reauth: { script: 'reauth.js', group: 'account', summary: 'Refresh your session' },
133
133
  setup: { script: 'setup.js', group: 'account', summary: 'Finish builder setup on this instance (disciplines, consent)' },
134
- box: { script: 'api.js', prefixArgs: ['POST', '/api/gds/box/ensure'], group: 'account', summary: 'Turn on / wake your cloud dev box' },
134
+ box: { script: 'api.js', prefixArgs: ['POST', '/api/bongos/box/ensure'], group: 'account', summary: 'Turn on / wake your cloud dev box' },
135
135
  shell: { script: 'shell.js', group: 'account', summary: 'Open a terminal on your dev box' },
136
136
  code: { script: 'code.js', group: 'account', summary: 'Open VS Code on your dev box over Remote-SSH' },
137
137
 
@@ -142,7 +142,7 @@ const VERBS = {
142
142
  cost: { script: 'cost.js', group: 'work', summary: 'Log a cost entry' },
143
143
  release: { script: 'release.js', group: 'work', summary: 'Cancel a claim — task returns to ready' },
144
144
 
145
- api: { script: 'api.js', group: 'work', summary: 'Call any instance endpoint (bongos api GET /api/gds/me)' },
145
+ api: { script: 'api.js', group: 'work', summary: 'Call any instance endpoint (bongos api GET /api/bongos/me)' },
146
146
  };
147
147
 
148
148
  // Verbs that exist in the full core CLI and are deliberately absent here. The dispatcher prints
@@ -419,7 +419,7 @@ Run \`bongos help\` for the current list. In short: \`login\`, \`reauth\`, \`set
419
419
  the web hall can do is reachable from the terminal:
420
420
 
421
421
  \`\`\`sh
422
- bongos api GET /api/gds/me
422
+ bongos api GET /api/bongos/me
423
423
  \`\`\`
424
424
 
425
425
  ## Writing code
@@ -37,7 +37,7 @@
37
37
  // --kind → server auto-classifies from title+body (keyword heuristics
38
38
  // today; replaced by the real classifier when task B1 ships)
39
39
  // --version → most recent version with status='building' (queried from
40
- // /api/gds/versions); leave null if there isn't one
40
+ // /api/bongos/versions); leave null if there isn't one
41
41
  // --priority → null (set later at triage time)
42
42
  // --goal → capture-time ROUTING (task 1003070, R09 of goal 1000071,
43
43
  // interview decision 4). Naming a goal turns this filing into a
@@ -396,7 +396,7 @@ async function main() {
396
396
  await offerToDevelop(idea.id);
397
397
  }
398
398
 
399
- // Migration detection lives only on the server now (POST /api/gds/tasks sets
399
+ // Migration detection lives only on the server now (POST /api/bongos/tasks sets
400
400
  // tasks.needs_migration from the title/description on create — migration 081,
401
401
  // task 876). Ideas carry no touches[] and aren't tasks, so the old CLI-side
402
402
  // "keep 'migrations/' in touches[]" hint was removed with the sentinel it
@@ -3,7 +3,7 @@
3
3
  // gate (#855, ADR 0042). This is the security KEYSTONE for the ci deploy mode.
4
4
  //
5
5
  // WHY it must run in CI (not "read the recorded grade"):
6
- // POST /api/gds/tasks/:id/grade records the grader scores FROM THE REQUEST
6
+ // POST /api/bongos/tasks/:id/grade records the grader scores FROM THE REQUEST
7
7
  // BODY — the server does not independently recompute them. In laptop mode the
8
8
  // grader runs on the OPERATOR's trusted machine, so that's fine. In ci mode the
9
9
  // merge trigger moves to an UNTRUSTED builder machine; a tampered local ship.js
@@ -2,11 +2,11 @@
2
2
  // Claim-time recall hits (#956 / V4.R18 — criterion sessions-start-knowing).
3
3
  //
4
4
  // When a builder claims a task, surface the top project-knowledge sources for it
5
- // (POST /api/gds/search — the rank/owner-scoped lexical recall layer, ADR 0060) so
5
+ // (POST /api/bongos/search — the rank/owner-scoped lexical recall layer, ADR 0060) so
6
6
  // the work starts already pointed at the relevant ADRs / recipes / session-logs /
7
7
  // learnings instead of re-discovering them. This is the claim-time half of the
8
8
  // recall surface the V4.R04 context pack (#942) promised; #963 added the
9
- // resumed-session (SessionStart) half. The two share the same /api/gds/search call
9
+ // resumed-session (SessionStart) half. The two share the same /api/bongos/search call
10
10
  // and the same title-cleaning, so a session sees the same knowledge whether it
11
11
  // claims fresh or resumes.
12
12
  //
@@ -810,7 +810,7 @@ async function cliClient(opts = {}) {
810
810
  // ---- does this instance even HAVE dev boxes? (task 1003730) -----------------
811
811
  // The dev-box module is a CONTROL-PLANE capability: it provisions DigitalOcean droplets, so a
812
812
  // hosted co-tenant instance runs without it. The instance manifest has always said so —
813
- // GET /api/gds/instance carries modules.enabled — but no CLI script read it, so `bongos shell`
813
+ // GET /api/bongos/instance carries modules.enabled — but no CLI script read it, so `bongos shell`
814
814
  // on such an instance died with a bare `POST /box/ensure failed (HTTP 404: not_found)`.
815
815
  //
816
816
  // That mattered far more than a bad error string: the public CLI (ADR 0258) answers
@@ -956,7 +956,7 @@ function tableTask(t) {
956
956
 
957
957
  // V3.R13 (#237): one-line "next: <stage>" nudge for newcomers.
958
958
  //
959
- // Given the /api/gds/me response, print a banner pointing at the next
959
+ // Given the /api/bongos/me response, print a banner pointing at the next
960
960
  // uncleared onboarding stage. Silent when the builder has graduated or has
961
961
  // already cleared first_ship (the post-newcomer threshold) — gates lift
962
962
  // after the first ship, so the nudge is too. Also silent when the
@@ -1038,7 +1038,7 @@ function printCostWarning(meBody) {
1038
1038
  }
1039
1039
 
1040
1040
  // task 1013 / ADR 0073: the CLI half of the consistent "the system needs an input
1041
- // from you" signal. Given the /api/gds/me response, print a short line for each
1041
+ // from you" signal. Given the /api/bongos/me response, print a short line for each
1042
1042
  // `needs` item in the action_needed state — the builder's private surface is the
1043
1043
  // right place to tell them an input is missing (mirrors printCostWarning). Silent
1044
1044
  // when nothing needs action (covered / satisfied items don't nag) or when the
@@ -184,7 +184,7 @@ function osFacts({ platform, runWhich }) {
184
184
  };
185
185
  }
186
186
 
187
- // Normalize active claims (from /api/gds/me) into {id, title, current} rows.
187
+ // Normalize active claims (from /api/bongos/me) into {id, title, current} rows.
188
188
  // currentTaskId marks the one just claimed so the print can say "(this one)".
189
189
  function normalizeClaims(activeClaims, currentTaskId) {
190
190
  const rows = Array.isArray(activeClaims) ? activeClaims : [];
@@ -219,7 +219,7 @@ function refuse(result) {
219
219
  // answered from the same source of truth — the shape of bug where a rule is
220
220
  // enforced on one path and merely stated on the other (task 1003493).
221
221
  async function activeClaims() {
222
- const me = await apiCall('GET', '/api/gds/me');
222
+ const me = await apiCall('GET', '/api/bongos/me');
223
223
  if (!me.ok) return { ok: false, code: 'no_session', detail: { status: me.status, run: 'node scripts/gds/setup.js' } };
224
224
  return { ok: true, claims: me.data.active_claims || (me.data.active_claim ? [me.data.active_claim] : []) };
225
225
  }
@@ -295,7 +295,7 @@ async function loadPatch({ taskId, patchFile }) {
295
295
  ? ['```' + proposals.FENCE, raw.trim(), '```'].join('\n')
296
296
  : raw);
297
297
  }
298
- const res = await apiCall('GET', `/api/gds/tasks/${taskId}`);
298
+ const res = await apiCall('GET', `/api/bongos/tasks/${taskId}`);
299
299
  if (!res.ok) {
300
300
  return { ok: false, code: 'task_unreadable', detail: { task: taskId, status: res.status } };
301
301
  }
@@ -261,7 +261,7 @@ function stop(params, deps = {}) {
261
261
  }
262
262
 
263
263
  // Probe the running server. Returns { up, authConfigured }. `up` = the plain
264
- // /healthz (needs no DB); authConfigured comes from /api/gds/healthz.
264
+ // /healthz (needs no DB); authConfigured comes from /api/bongos/healthz.
265
265
  async function health(params, deps = {}) {
266
266
  const fetchImpl = deps.fetchImpl || fetch;
267
267
  const base = `http://${probeHost(params)}:${params.port}`;
@@ -273,7 +273,7 @@ async function health(params, deps = {}) {
273
273
  } catch { return { up: false, authConfigured: false }; }
274
274
  let authConfigured = false;
275
275
  try {
276
- const r = await fetchImpl(`${base}/api/gds/healthz`, { signal: AbortSignal.timeout(timeout) });
276
+ const r = await fetchImpl(`${base}/api/bongos/healthz`, { signal: AbortSignal.timeout(timeout) });
277
277
  const j = await r.json();
278
278
  authConfigured = j && j.auth_configured === true;
279
279
  } catch { /* leave false */ }
@@ -3,7 +3,7 @@
3
3
  // the local session file so a newcomer's art pipeline can use it (task 1281).
4
4
  //
5
5
  // The art pipeline (modules/art-pipeline/pipeline/gen_api.py) runs LOCALLY and can't call the API
6
- // per generation, so SessionStart runs this once: GET /api/gds/me/art-key and,
6
+ // per generation, so SessionStart runs this once: GET /api/bongos/me/art-key and,
7
7
  // based on the builder's live rank, write or remove the `shared_gemini_api_key`
8
8
  // field in ~/.config/otb/bongos-session.json. gen_api.py reads that field as a
9
9
  // fallback BELOW the builder's own key — so own key always wins, and a newcomer
@@ -43,7 +43,7 @@ async function main() {
43
43
  const timer = setTimeout(() => ctrl.abort(), FETCH_TIMEOUT_MS);
44
44
  let data = null;
45
45
  try {
46
- const res = await fetch(`${base}/api/gds/me/art-key`, {
46
+ const res = await fetch(`${base}/api/bongos/me/art-key`, {
47
47
  headers: {
48
48
  Authorization: `Bearer ${session.token}`,
49
49
  'User-Agent': require('../../src/branding').userAgent(),
@@ -5,7 +5,7 @@
5
5
  // The toggle lives server-side (builders.sound_prefs), but the sound plays from
6
6
  // a LOCAL Stop hook + ship.js via .claude/sounds/play.js — which can't make a
7
7
  // network call on every turn. So SessionStart runs this once: fetch
8
- // GET /api/gds/me/sound-prefs and write its effective_map to
8
+ // GET /api/bongos/me/sound-prefs and write its effective_map to
9
9
  // ~/.config/otb/sound-prefs.json. play.js reads that file and skips muted sounds.
10
10
  //
11
11
  // Best-effort by construction:
@@ -48,11 +48,11 @@ async function main() {
48
48
  // Fetch both prefs in parallel; a failure on either leaves both at their
49
49
  // existing cached state (fail-open).
50
50
  const [soundRes, eventRes] = await Promise.all([
51
- fetch(`${sess.apiBase}/api/gds/me/sound-prefs`, {
51
+ fetch(`${sess.apiBase}/api/bongos/me/sound-prefs`, {
52
52
  headers: { Authorization: `Bearer ${sess.token}`, 'User-Agent': require('../../src/branding').userAgent() },
53
53
  signal: ctrl.signal,
54
54
  }),
55
- fetch(`${sess.apiBase}/api/gds/me/event-sound-prefs`, {
55
+ fetch(`${sess.apiBase}/api/bongos/me/event-sound-prefs`, {
56
56
  headers: { Authorization: `Bearer ${sess.token}`, 'User-Agent': require('../../src/branding').userAgent() },
57
57
  signal: ctrl.signal,
58
58
  }),
@@ -78,7 +78,7 @@ const BAD_TASK = {
78
78
  Acceptance:
79
79
  - New table billing_charges captures one row per art-pipeline ship with
80
80
  stripe_charge_id, amount_cents, currency, status.
81
- - POST /api/gds/cost on art-pipeline tasks creates a Stripe charge against
81
+ - POST /api/bongos/cost on art-pipeline tasks creates a Stripe charge against
82
82
  the configured Hermeslines customer and writes the billing_charges row.
83
83
  - A failure to charge rolls the cost-log insert back so we never claim a
84
84
  charge that didn't happen.
@@ -92,7 +92,7 @@ async function liveRank() {
92
92
  try {
93
93
  const timeout = new Promise((resolve) => { timer = setTimeout(() => resolve('__timeout__'), LIVE_RANK_TIMEOUT_MS); });
94
94
  const res = await Promise.race([
95
- apiCall('GET', '/api/gds/me', null, { allowUnauthenticated: true }),
95
+ apiCall('GET', '/api/bongos/me', null, { allowUnauthenticated: true }),
96
96
  timeout,
97
97
  ]);
98
98
  // The loser of the race must be cleared. This used to leak: process.exit()
@@ -8,7 +8,7 @@
8
8
  // 1. gathers a spec (interactive interview, or --from <spec.json>),
9
9
  // 2. writes the instance config — config/branding.json + config/modules.json
10
10
  // (lean OVERRIDES; config/*.neutral.json fills the rest, src/branding.js),
11
- // 3. seeds the first version + its done-when goal via POST /api/gds/versions
11
+ // 3. seeds the first version + its done-when goal via POST /api/bongos/versions
12
12
  // (the primitive added in this same task), then files the starter task and
13
13
  // the human-only KICKOFF steps as real, tracked tasks via POST /tasks,
14
14
  // 4. points the owner at docs/branding-fill-prompt.md for the LOOK (a locked
@@ -200,7 +200,7 @@ function provisioningSlug(spec) {
200
200
  return slugify(base, 'instance').slice(0, 40).replace(/-+$/, '');
201
201
  }
202
202
 
203
- // The POST /api/gds/provisioning/instances body built from the interview's infra
203
+ // The POST /api/bongos/provisioning/instances body built from the interview's infra
204
204
  // answers — or null when the owner didn't opt into provisioning (no spec.provisioning
205
205
  // block). THE ADR 0111 §3 ARM: infra answers become a real provisioning REQUEST (a
206
206
  // provisioning_intents row the control-plane runner drains) instead of only a manual
@@ -382,7 +382,7 @@ function validateSpec(spec, { adopt = false, noSeed = false } = {}) {
382
382
  return errs;
383
383
  }
384
384
 
385
- // Build the POST /api/gds/versions body from the spec (pure). The first version's
385
+ // Build the POST /api/bongos/versions body from the spec (pure). The first version's
386
386
  // done_when goal becomes both the version blurb and one done-when criterion, so
387
387
  // /status has a finish line to roll up from day one.
388
388
  function versionPayload(spec) {
@@ -701,11 +701,11 @@ async function seedViaApi(spec, { dryRun, log = console.log, api = apiCall } = {
701
701
  const pr = provisioningRequest(spec); // ADR 0111 §3 — null unless the owner opted in
702
702
 
703
703
  if (dryRun) {
704
- log(`\n[dry-run] would POST /api/gds/versions:`);
704
+ log(`\n[dry-run] would POST /api/bongos/versions:`);
705
705
  log(JSON.stringify(vp, null, 2));
706
706
  log(`\n[dry-run] would create ${starters.length} starter + ${kickoff.length} kickoff task(s) under ${vp.id}.`);
707
707
  if (pr) {
708
- log(`\n[dry-run] would POST /api/gds/provisioning/instances:`);
708
+ log(`\n[dry-run] would POST /api/bongos/provisioning/instances:`);
709
709
  log(JSON.stringify(pr, null, 2));
710
710
  log(` (queues a 'provision' intent; the control-plane runner stands up hosting — ADR 0111 §2/§3.`);
711
711
  log(` production-topology is left OFF the kickoff list since it's now automated.)`);
@@ -714,7 +714,7 @@ async function seedViaApi(spec, { dryRun, log = console.log, api = apiCall } = {
714
714
  }
715
715
 
716
716
  // 1. version + first goal
717
- const vres = await api('POST', '/api/gds/versions', vp);
717
+ const vres = await api('POST', '/api/bongos/versions', vp);
718
718
  if (!vres.ok && vres.status !== 409) {
719
719
  throw new Error(`POST /versions failed (${vres.status}): ${JSON.stringify(vres.data)}`);
720
720
  }
@@ -726,7 +726,7 @@ async function seedViaApi(spec, { dryRun, log = console.log, api = apiCall } = {
726
726
  let goalId = vres.ok && vres.data && vres.data.goal ? vres.data.goal.id : null;
727
727
  if (vres.status === 409) {
728
728
  log(` • version ${vp.id} already exists — continuing.`);
729
- const gres = await api('GET', `/api/gds/goals?version=${encodeURIComponent(vp.id)}`);
729
+ const gres = await api('GET', `/api/bongos/goals?version=${encodeURIComponent(vp.id)}`);
730
730
  const goals = gres.ok ? (Array.isArray(gres.data) ? gres.data : (gres.data && gres.data.goals) || []) : [];
731
731
  const open = goals.find((g) => g && g.status === 'open' && !g.is_maintenance) || goals.find((g) => g && g.status === 'open');
732
732
  goalId = open ? open.id : null;
@@ -752,7 +752,7 @@ async function seedViaApi(spec, { dryRun, log = console.log, api = apiCall } = {
752
752
  const failures = [];
753
753
  const postTask = async (t, extra = {}) => {
754
754
  attempted++;
755
- const res = await api('POST', '/api/gds/tasks', {
755
+ const res = await api('POST', '/api/bongos/tasks', {
756
756
  version_id: vp.id, goal_id: goalId, title: t.title, description: t.description || '', status: 'ready',
757
757
  kind: t.kind || 'infra', discipline: t.discipline || 'engineer', source: 'bongos-init', ...extra,
758
758
  });
@@ -777,7 +777,7 @@ async function seedViaApi(spec, { dryRun, log = console.log, api = apiCall } = {
777
777
  // re-file that manual step here so the leg is never silently dropped.
778
778
  let provisioned = false;
779
779
  if (pr) {
780
- const pres = await api('POST', '/api/gds/provisioning/instances', pr);
780
+ const pres = await api('POST', '/api/bongos/provisioning/instances', pr);
781
781
  if (pres.ok) {
782
782
  provisioned = true;
783
783
  const inst = (pres.data && pres.data.instance) || {};
@@ -187,7 +187,7 @@ async function resolveWidgetsEnabled() {
187
187
  const ctrl = new AbortController();
188
188
  const timer = setTimeout(() => ctrl.abort(), 3000);
189
189
  try {
190
- const res = await fetch(`${base}/api/gds/me`, {
190
+ const res = await fetch(`${base}/api/bongos/me`, {
191
191
  headers: { Authorization: `Bearer ${session.token}`, 'User-Agent': require('../../src/branding').userAgent() },
192
192
  signal: ctrl.signal,
193
193
  });
@@ -100,7 +100,7 @@ function autoDetectFiles() {
100
100
 
101
101
  if (dryRun) {
102
102
  console.log('=== DRY RUN ===');
103
- console.log('POST /api/gds/learnings:');
103
+ console.log('POST /api/bongos/learnings:');
104
104
  console.log(JSON.stringify({
105
105
  title, body_md: body, tags, related_files: relatedFiles, source, source_ref: sourceRef, task_id: taskId,
106
106
  }, null, 2));
@@ -135,7 +135,7 @@ function autoDetectFiles() {
135
135
  if (learning.related_files?.length) {
136
136
  console.log(`Related files: ${learning.related_files.join(', ')}`);
137
137
  }
138
- console.log('Stored in GDS DB. Query with: node scripts/gds/learning-list.js (TBD) or GET /api/gds/learnings');
138
+ console.log('Stored in GDS DB. Query with: node scripts/gds/learning-list.js (TBD) or GET /api/bongos/learnings');
139
139
  // Phase 2b — the per-tag markdown append was removed. The DB is now the
140
140
  // canonical store for short-form learnings; long-form operational recipes
141
141
  // live separately under docs/recipes/.
@@ -24,7 +24,7 @@
24
24
  // recreates the complaint. So the classifier is deliberately conservative —
25
25
  // it links a "#NNN" ONLY when ALL of these hold:
26
26
  // • NNN is a real id of the classified kind (fetched live from the public
27
- // /api/gds/public/ref-ids allow-list; PR-only numbers are therefore never
27
+ // /api/bongos/public/ref-ids allow-list; PR-only numbers are therefore never
28
28
  // touched, and an idea id is never linked as a task).
29
29
  // • It is a bare reference — NOT a markdown heading anchor like
30
30
  // `](#12-session-update-protocol)` (digits followed by `-`/word chars), and
@@ -520,7 +520,7 @@ function linkifyText(text, ids, stats) {
520
520
  // Token-free: the public id allow-list, so this script (and the CI gate) work
521
521
  // with no builder session. Override the host with GDS_API_BASE for local dev.
522
522
  async function fetchRefIds() {
523
- const res = await fetch(`${API_BASE}/api/gds/public/ref-ids`);
523
+ const res = await fetch(`${API_BASE}/api/bongos/public/ref-ids`);
524
524
  if (!res.ok) throw new Error(`/public/ref-ids fetch failed (HTTP ${res.status})`);
525
525
  const data = await res.json();
526
526
  const toSet = (a) => new Set((a || []).map(Number).filter(Number.isInteger));
@@ -4,7 +4,7 @@
4
4
  // preview a dev box gets at sandbox-<login>.example.com (ADR 0044/0046/0052)
5
5
  // — but served at http://localhost:<port> on their OWN machine: no Cloudflare
6
6
  // tunnel, no public URL, $0. It runs the ADR 0052 game-only entry
7
- // (src/preview-server.js), which serves ONLY the playable game (no /api/gds, no
7
+ // (src/preview-server.js), which serves ONLY the playable game (no /api/bongos, no
8
8
  // BuildersHall), degraded-DB exactly like the box sandbox.
9
9
  //
10
10
  // The preview is a long-running DETACHED background process (the laptop analogue