@bongos/core 1.19.804 → 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.
- package/.bongos-core.json +257 -237
- package/.claude/skills/ask-for-help/SKILL.md +6 -6
- package/.claude/skills/backlog-review/SKILL.md +1 -1
- package/.claude/skills/blocker-review/SKILL.md +7 -7
- package/.claude/skills/blocker-solve/SKILL.md +5 -5
- package/.claude/skills/bug-triage/SKILL.md +7 -7
- package/.claude/skills/builder-claim/SKILL.md +3 -3
- package/.claude/skills/builder-cost/SKILL.md +2 -2
- package/.claude/skills/builder-end/SKILL.md +2 -2
- package/.claude/skills/builder-exit/SKILL.md +7 -7
- package/.claude/skills/builder-key/SKILL.md +2 -2
- package/.claude/skills/builder-reauth/SKILL.md +2 -2
- package/.claude/skills/builder-redteam/SKILL.md +7 -7
- package/.claude/skills/builder-release/SKILL.md +2 -2
- package/.claude/skills/builder-sequence/SKILL.md +1 -1
- package/.claude/skills/builder-setup/SKILL.md +3 -3
- package/.claude/skills/builder-ship/SKILL.md +1 -1
- package/.claude/skills/builder-stage/SKILL.md +1 -1
- package/.claude/skills/builder-start/SKILL.md +1 -1
- package/.claude/skills/fix-task/SKILL.md +4 -4
- package/.claude/skills/goal-create/SKILL.md +18 -18
- package/.claude/skills/goal-review/SKILL.md +7 -7
- package/.claude/skills/grade-audit/SKILL.md +5 -5
- package/.claude/skills/grade-recover/SKILL.md +4 -4
- package/.claude/skills/grader-health/SKILL.md +6 -6
- package/.claude/skills/idea-triage/SKILL.md +14 -14
- package/.claude/skills/merge-mode/SKILL.md +3 -3
- package/.claude/skills/planning-session/SKILL.md +20 -20
- package/.claude/skills/priority-session/SKILL.md +10 -10
- package/.claude/skills/recall/SKILL.md +1 -1
- package/.claude/skills/scan-before-install/SKILL.md +3 -3
- package/.claude/skills/status/SKILL.md +2 -2
- package/.claude/skills/strand-fix/SKILL.md +2 -2
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +2 -0
- package/clients/bongos-client/index.cjs +2 -0
- package/clients/bongos-client/index.d.ts +2 -0
- package/clients/bongos-client/index.mjs +2 -0
- package/docs/api/openapi.json +45 -11
- package/docs/api-reference.md +11 -10
- package/docs/module-api-changelog.md +2 -0
- package/modules/builder-settings/profile-nudge-prefs.js +1 -1
- package/modules/builder-settings/render-prefs.js +1 -1
- package/modules/dev-box/app/README.md +1 -1
- package/modules/dev-box/app/src/gds-client.js +11 -9
- package/modules/dev-box/app/src/vendor/bongos-client.cjs +2 -0
- package/modules/dev-box/app/test/unit.mjs +13 -13
- package/modules/dev-box/box-access.js +3 -3
- package/modules/dev-box/box-onboard.js +7 -7
- package/modules/discord/bug-attachments.js +1 -1
- package/modules/economy/cost-classify.js +6 -6
- package/modules/grading/grader-rubric.json +1 -1
- package/modules/grading/grader-score.js +1 -1
- package/modules/hall-ui/module.json +1 -1
- package/modules/hall-ui/public/drachmae.js +3 -3
- package/modules/hall-ui/public/idea.js +1 -1
- package/modules/hall-ui/public/md-reader.js +1 -1
- package/modules/hall-ui/public/people.html +1 -1
- package/modules/hall-ui/public/people.js +2 -2
- package/modules/hall-ui/public/primer.js +4 -4
- package/modules/hall-ui/public/roster.js +1 -1
- package/modules/hall-ui/public/shell.js +1 -1
- package/modules/hall-ui/public/task.js +1 -1
- package/modules/ideas/inbox.js +2 -2
- package/modules/lifecycle/db-analytics.js +1 -1
- package/modules/lifecycle/done-when.js +4 -4
- package/modules/lifecycle/version-close.js +1 -1
- package/modules/memory/learnings.js +2 -2
- package/modules/memory/memory.js +1 -1
- package/modules/onboarding/onboarding.js +1 -1
- package/modules/platform-identity/routes/my-projects.js +1 -1
- package/modules/platform-identity/routes/sso.js +2 -2
- package/modules/public-landing/public/index.html +2 -2
- package/modules/public-landing/public/projects-floor.states.json +1 -1
- package/modules/public-landing/public/projects.html +1 -1
- package/modules/public-landing/public/projects.states.json +1 -1
- package/modules/sessions/db.js +120 -0
- package/modules/sessions/module.json +2 -2
- package/modules/sessions/pollers/session-upload-health.js +111 -0
- package/modules/sessions/pulse.js +2 -2
- package/modules/sessions/routes/sessions.js +46 -0
- package/modules/sessions/upload-health.js +197 -0
- package/modules/status-ui/module.json +1 -1
- package/modules/status-ui/public/explore.js +1 -1
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/scripts/gds/agent-invoke.js +3 -3
- package/scripts/gds/api.js +4 -4
- package/scripts/gds/api.sh +1 -1
- package/scripts/gds/architect-audit.js +1 -1
- package/scripts/gds/artifact-audit.js +2 -2
- package/scripts/gds/audit-ships.js +2 -2
- package/scripts/gds/backfill-cost.js +1 -1
- package/scripts/gds/backfill-sessions.js +1 -1
- package/scripts/gds/backfill-subagent-rewards.js +1 -1
- package/scripts/gds/backfill-task-rewards.js +2 -2
- package/scripts/gds/box-auth-check.js +1 -1
- package/scripts/gds/box-sync.js +3 -3
- package/scripts/gds/box.js +10 -10
- package/scripts/gds/build-cli-package.js +3 -3
- package/scripts/gds/capture.js +2 -2
- package/scripts/gds/ci-grade.js +1 -1
- package/scripts/gds/claim-recall.js +2 -2
- package/scripts/gds/cli-lib.js +3 -3
- package/scripts/gds/context-pack.js +1 -1
- package/scripts/gds/copy-apply.js +2 -2
- package/scripts/gds/dev-lib.js +2 -2
- package/scripts/gds/fetch-art-key.js +2 -2
- package/scripts/gds/fetch-sound-prefs.js +3 -3
- package/scripts/gds/grade-smoke.js +1 -1
- package/scripts/gds/hooks/pre-push.js +1 -1
- package/scripts/gds/init.js +9 -9
- package/scripts/gds/key-card.js +1 -1
- package/scripts/gds/learning-capture.js +2 -2
- package/scripts/gds/linkify-refs.js +2 -2
- package/scripts/gds/local-preview-lib.js +1 -1
- package/scripts/gds/login.js +11 -10
- package/scripts/gds/main-audit.js +1 -1
- package/scripts/gds/newcomer-floor.config.json +1 -1
- package/scripts/gds/newcomer-floor.js +2 -2
- package/scripts/gds/newcomer-floor.templates.json +2 -2
- package/scripts/gds/onboarding-ship.js +1 -1
- package/scripts/gds/paste-token.js +3 -3
- package/scripts/gds/portability-smoke-memory.sh +5 -5
- package/scripts/gds/prove-strict-versioning.js +2 -2
- package/scripts/gds/provision-net.js +2 -2
- package/scripts/gds/provision-units.js +3 -3
- package/scripts/gds/pulse.js +2 -2
- package/scripts/gds/push-path-brief.js +2 -2
- package/scripts/gds/reauth.js +1 -1
- package/scripts/gds/recall.js +1 -1
- package/scripts/gds/redteam-patrol.js +3 -3
- package/scripts/gds/render-ideas.js +5 -5
- package/scripts/gds/repo-metrics.js +1 -1
- package/scripts/gds/sandbox-stage.js +3 -3
- package/scripts/gds/seed-adopt-tasks.js +3 -3
- package/scripts/gds/seed-board-room-tasks.js +1 -1
- package/scripts/gds/seed-bongos-app-tasks.js +2 -2
- package/scripts/gds/seed-bongos-coreB-tranche1-tasks.js +3 -3
- package/scripts/gds/seed-bongos-coreB-tranche2-tasks.js +4 -4
- package/scripts/gds/seed-bongos-tasks.js +5 -5
- package/scripts/gds/seed-bongos-v1-idea-routing-tasks.js +1 -1
- package/scripts/gds/seed-bongos-v1-seo-tasks.js +1 -1
- package/scripts/gds/seed-bv1-community-tasks.js +1 -1
- package/scripts/gds/seed-bv1-privacy-invites-tasks.js +1 -1
- package/scripts/gds/seed-bv1-profile-page-tasks.js +1 -1
- package/scripts/gds/seed-bv1-profiles-tasks.js +1 -1
- package/scripts/gds/seed-bv1-r01-delta-tasks.js +1 -1
- package/scripts/gds/seed-gds-v4-tasks.js +3 -3
- package/scripts/gds/seed-medusa-tasks.js +1 -1
- package/scripts/gds/seed-productization-tasks.js +1 -1
- package/scripts/gds/seed-project-admin-console-tasks.js +1 -1
- package/scripts/gds/seed-provisioning-tasks.js +2 -2
- package/scripts/gds/seed-strict-versioning-tasks.js +3 -3
- package/scripts/gds/seed-v2-world-tasks.js +2 -2
- package/scripts/gds/seed-verify-criteria.js +1 -1
- package/scripts/gds/session-digest.js +1 -1
- package/scripts/gds/session.js +2 -2
- package/scripts/gds/setup.js +7 -7
- package/scripts/gds/ship-flow.js +3 -3
- package/scripts/gds/ship-grade-steps.js +3 -3
- package/scripts/gds/ship-memory-sync.js +1 -1
- package/scripts/gds/ship-session-upload.js +3 -3
- package/scripts/gds/smoke-batch-claim.sh +10 -10
- package/scripts/gds/smoke-batch-release.sh +14 -14
- package/scripts/gds/smoke-claim-consistency.sh +19 -19
- package/scripts/gds/smoke-dependencies.sh +9 -9
- package/scripts/gds/smoke-write.sh +11 -11
- package/scripts/gds/start.js +1 -1
- package/scripts/gds/status.js +2 -2
- package/scripts/gds/strand-watch.js +1 -1
- package/scripts/gds/triage.js +4 -4
- package/scripts/gds/version-close.js +2 -2
- package/scripts/hall-preview/README.md +1 -1
- package/scripts/hall-preview/server.js +1 -1
- package/src/bongos/auth-admission.js +3 -3
- package/src/bongos/auth-idp.js +2 -2
- package/src/bongos/auth.js +3 -3
- package/src/bongos/db.js +2 -2
- package/src/bongos/llm-cache.js +2 -2
- package/src/bongos/metrics.js +1 -1
- package/src/bongos/middleware/audit.js +3 -3
- package/src/bongos/middleware/rate-limit.js +1 -1
- package/src/bongos/platform-visibility-gate.js +2 -2
- package/src/bongos/routes/_helpers.js +1 -1
- package/src/bongos/routes/audit-log.js +1 -1
- package/src/bongos/routes/auth.js +5 -5
- package/src/bongos/routes/backup.js +1 -1
- package/src/bongos/routes/builders.js +1 -1
- package/src/bongos/routes/instance.js +1 -1
- package/src/bongos/routes/live.js +1 -1
- package/src/bongos/routes/me.js +2 -2
- package/src/bongos/routes/modules.js +2 -2
- package/src/bongos/routes/public.js +1 -1
- package/src/bongos/routes/security.js +4 -4
- package/src/bongos/routes.js +1 -1
- package/src/bongos/serve-internal.js +6 -6
- package/src/branding.js +1 -1
- package/src/module-api.js +1 -1
- package/src/module-seams.js +2 -2
- package/src/platform-server.js +2 -2
- package/tests/api_alias_exceptions.mjs +67 -0
- package/tests/application_echo.mjs +12 -12
- package/tests/artifact_audit.mjs +1 -1
- package/tests/auth_page_gate.mjs +4 -4
- package/tests/auth_web_recovery.mjs +11 -11
- package/tests/bongos_login.mjs +7 -4
- package/tests/box_env.mjs +6 -6
- package/tests/bug_attachments.mjs +1 -1
- package/tests/cli_sessions.mjs +1 -1
- package/tests/dev_lib.mjs +1 -1
- package/tests/discord_bugs.mjs +2 -2
- package/tests/discord_inbound.mjs +2 -2
- package/tests/explore_visible_states.mjs +1 -1
- package/tests/government_page_gates.mjs +1 -1
- package/tests/hall_reference_world.mjs +1 -1
- package/tests/idea_ideate_full.mjs +1 -1
- package/tests/idp_federation.mjs +2 -2
- package/tests/llm-cache.mjs +1 -1
- package/tests/manage_manifest_shared_read.mjs +3 -3
- package/tests/people_directory_clip.mjs +1 -1
- package/tests/planning_session_skill.mjs +1 -1
- package/tests/platform_visibility_gate.mjs +15 -15
- package/tests/profile_route.mjs +25 -25
- package/tests/projects_hub.mjs +2 -2
- package/tests/provision.mjs +2 -2
- package/tests/provision_settings_apply.mjs +4 -4
- package/tests/sandbox_stage.mjs +8 -8
- package/tests/scouting_owner_access_and_reach.mjs +3 -3
- package/tests/session_upload_health.mjs +329 -0
- package/tests/setup_device_flow_fallback.mjs +1 -1
- package/tests/skill_ask_for_help.mjs +3 -3
- package/tests/skill_grade_audit.mjs +2 -2
- package/tests/skill_grader_health.mjs +3 -3
- package/tests/smoke_write_contract.mjs +1 -1
package/scripts/gds/box.js
CHANGED
|
@@ -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/
|
|
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/
|
|
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/
|
|
510
|
-
console.log(` Windows: irm ${base}/api/
|
|
511
|
-
console.log(` (guide: ${base}/api/
|
|
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/
|
|
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/
|
|
536
|
-
console.error(` Windows: irm ${gdsBase()}/api/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
422
|
+
bongos api GET /api/bongos/me
|
|
423
423
|
\`\`\`
|
|
424
424
|
|
|
425
425
|
## Writing code
|
package/scripts/gds/capture.js
CHANGED
|
@@ -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/
|
|
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/
|
|
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
|
package/scripts/gds/ci-grade.js
CHANGED
|
@@ -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/
|
|
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/
|
|
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/
|
|
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
|
//
|
package/scripts/gds/cli-lib.js
CHANGED
|
@@ -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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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
|
}
|
package/scripts/gds/dev-lib.js
CHANGED
|
@@ -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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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()
|
package/scripts/gds/init.js
CHANGED
|
@@ -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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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) || {};
|
package/scripts/gds/key-card.js
CHANGED
|
@@ -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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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
|
package/scripts/gds/login.js
CHANGED
|
@@ -32,13 +32,14 @@ const { branding } = require('../../src/branding');
|
|
|
32
32
|
// --- pure helpers (unit-tested) ---------------------------------------------
|
|
33
33
|
|
|
34
34
|
// Normalize whatever the user pastes into an origin: add https:// if no scheme,
|
|
35
|
-
// drop trailing slashes, and tolerate a pasted
|
|
35
|
+
// drop trailing slashes, and tolerate a pasted API base — the canonical
|
|
36
|
+
// /api/bongos or the permanent /api/gds alias, with or without the /v1 segment.
|
|
36
37
|
function normalizeInstanceBase(raw) {
|
|
37
38
|
let s = String(raw || '').trim();
|
|
38
39
|
if (!s) throw new Error('missing instance URL');
|
|
39
40
|
if (!/^https?:\/\//i.test(s)) s = `https://${s}`;
|
|
40
41
|
s = s.replace(/\/+$/, '');
|
|
41
|
-
s = s.replace(/\/api\/gds
|
|
42
|
+
s = s.replace(/\/api\/(?:bongos|gds)(?:\/v1)?\/?$/i, '');
|
|
42
43
|
return s;
|
|
43
44
|
}
|
|
44
45
|
|
|
@@ -95,7 +96,7 @@ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
|
95
96
|
// The instance's OWN admission gate runs at poll (direct) or exchange (federated),
|
|
96
97
|
// so the stranger path is identical for both.
|
|
97
98
|
async function runDeviceFlow(base, { log, idp = null }) {
|
|
98
|
-
const startUrl = idp ? `${idp.origin}/api/
|
|
99
|
+
const startUrl = idp ? `${idp.origin}/api/bongos/sso/device/start` : `${base}/api/bongos/auth/device/start`;
|
|
99
100
|
const start = await fetchJson(startUrl, {
|
|
100
101
|
method: 'POST',
|
|
101
102
|
// Federated: the hub resolves + binds the client from the USER-TYPED origin
|
|
@@ -136,7 +137,7 @@ async function runDeviceFlow(base, { log, idp = null }) {
|
|
|
136
137
|
openBrowser(verification_uri);
|
|
137
138
|
log(' Waiting for you to approve in the browser…');
|
|
138
139
|
|
|
139
|
-
const pollUrl = idp ? `${idp.origin}/api/
|
|
140
|
+
const pollUrl = idp ? `${idp.origin}/api/bongos/sso/device/poll` : `${base}/api/bongos/auth/device/poll`;
|
|
140
141
|
const deadline = Date.now() + expires * 1000;
|
|
141
142
|
while (Date.now() < deadline) {
|
|
142
143
|
await sleep(interval * 1000);
|
|
@@ -150,7 +151,7 @@ async function runDeviceFlow(base, { log, idp = null }) {
|
|
|
150
151
|
if (st === 'ok') {
|
|
151
152
|
if (!idp) return { state: 'ok', token: poll.data.token, builder: poll.data.builder };
|
|
152
153
|
// Federated: exchange the hub assertion at the instance for a real session.
|
|
153
|
-
const ex = await fetchJson(`${base}/api/
|
|
154
|
+
const ex = await fetchJson(`${base}/api/bongos/auth/device/exchange`, {
|
|
154
155
|
method: 'POST',
|
|
155
156
|
body: JSON.stringify({ assertion: poll.data.assertion }),
|
|
156
157
|
});
|
|
@@ -200,9 +201,9 @@ async function main() {
|
|
|
200
201
|
// 1. Manifest — brand + admission posture, and a check that this really is a
|
|
201
202
|
// Cloud Bongos instance before we start a device flow.
|
|
202
203
|
log(`▸ Connecting to ${base}…`);
|
|
203
|
-
const man = await fetchJson(`${base}/api/
|
|
204
|
+
const man = await fetchJson(`${base}/api/bongos/instance`);
|
|
204
205
|
if (!man.ok || !man.data || man.data.schema !== 'instance-manifest/v1') {
|
|
205
|
-
console.error(`✖ ${base} does not look like a Cloud Bongos instance (no /api/
|
|
206
|
+
console.error(`✖ ${base} does not look like a Cloud Bongos instance (no /api/bongos/instance manifest).`);
|
|
206
207
|
process.exit(1);
|
|
207
208
|
}
|
|
208
209
|
const instanceName = man.data.name || base;
|
|
@@ -230,7 +231,7 @@ async function main() {
|
|
|
230
231
|
let stored = null;
|
|
231
232
|
try { stored = await loadStoredSession(base); } catch (_) { stored = null; }
|
|
232
233
|
if (stored && stored.token) {
|
|
233
|
-
const me = await fetchJson(`${base}/api/
|
|
234
|
+
const me = await fetchJson(`${base}/api/bongos/me`, { headers: { Authorization: `Bearer ${stored.token}` } });
|
|
234
235
|
if (me.ok && me.data && me.data.builder) {
|
|
235
236
|
await saveSession({ ...stored, builder: me.data.builder, api_base: base,
|
|
236
237
|
instance: { name: instanceName, origin: base } });
|
|
@@ -265,7 +266,7 @@ async function main() {
|
|
|
265
266
|
console.error('✖ need your GitHub username to request access.');
|
|
266
267
|
process.exit(2);
|
|
267
268
|
}
|
|
268
|
-
const reqRes = await fetchJson(`${base}/api/
|
|
269
|
+
const reqRes = await fetchJson(`${base}/api/bongos/access-requests`, {
|
|
269
270
|
method: 'POST',
|
|
270
271
|
body: JSON.stringify({ github_login: ghLogin, note: 'via bongos login' }),
|
|
271
272
|
});
|
|
@@ -287,7 +288,7 @@ async function main() {
|
|
|
287
288
|
const admitDeadline = Date.now() + 30 * 60 * 1000; // 30 min
|
|
288
289
|
for (;;) {
|
|
289
290
|
await sleep(5000);
|
|
290
|
-
const s = await fetchJson(`${base}/api/
|
|
291
|
+
const s = await fetchJson(`${base}/api/bongos/access-requests/status?github_login=${encodeURIComponent(ghLogin)}`);
|
|
291
292
|
const decision = pollDecision(s.data);
|
|
292
293
|
if (decision === 'admitted') {
|
|
293
294
|
log('\n ✓ Approved! Finishing sign-in — approve once more in your browser.');
|
|
@@ -282,7 +282,7 @@ async function fetchRankMap({ useDb = false } = {}) {
|
|
|
282
282
|
// Caveat: a zero-activity builder may be absent → resolves as UNRESOLVED
|
|
283
283
|
// ('review' finding), never as falsely-trusted.
|
|
284
284
|
try {
|
|
285
|
-
const res = await fetch(`${API_BASE}/api/
|
|
285
|
+
const res = await fetch(`${API_BASE}/api/bongos/public/leaderboard`);
|
|
286
286
|
if (res.ok) {
|
|
287
287
|
const data = await res.json();
|
|
288
288
|
return rowsToMap(data?.leaderboard || []);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_doc": "Supply knob for the deterministic newcomer-task floor replenisher (scripts/gds/newcomer-floor.js) and the on-claim restock (src/bongos/newcomer-restock.js). As of task 1488 each discipline holds a LIST of chore templates, and each chore keeps its OWN standing pool to its OWN `floor` (declared per-template in newcomer-floor.templates.json). The `floor` in this disciplines map is now the DEFAULT applied to any template that omits its own — i.e. a fallback, not the primary knob. The pool is measured in READY copies of each template (source_ref tmpl:<discipline>:<template_id>:<seq>); when a chore's ready copies drop below its floor, fresh identical copies are stamped — deterministic, no AI subagent, no 401. The CHORE definitions (and their per-template floors) live in templates.json (edit there to add/change a chore or tune its pool depth).",
|
|
3
|
-
"_review_gate": "`auto_promote` is the review toggle for the CLI seeder. true -> stamped copies land at status='ready' (claimable immediately). Safe here because output is deterministic and the templates are pre-approved (set true 2026-06-16, owner decision). false -> copies land at status='backlog' (NOT Xenos-claimable) for an Archon to promote via POST /api/
|
|
3
|
+
"_review_gate": "`auto_promote` is the review toggle for the CLI seeder. true -> stamped copies land at status='ready' (claimable immediately). Safe here because output is deterministic and the templates are pre-approved (set true 2026-06-16, owner decision). false -> copies land at status='backlog' (NOT Xenos-claimable) for an Archon to promote via POST /api/bongos/tasks/:id/promote. (The on-claim restock always stamps 'ready' — it tops a just-claimed chore's pool back up so the shelf is never empty.)",
|
|
4
4
|
"_floor_note": "Per-template `floor` lives in newcomer-floor.templates.json (next to each chore's credits_reward + est_minutes). The disciplines map below is only the per-discipline DEFAULT used when a template omits its own floor. credits_reward is never read from here.",
|
|
5
5
|
"templates_path": "newcomer-floor.templates.json",
|
|
6
6
|
"auto_promote": true,
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
// deterministic and the templates are pre-approved.
|
|
38
38
|
// false -> copies land status='backlog' for an Archon to promote.
|
|
39
39
|
//
|
|
40
|
-
// AUTH: POST /api/
|
|
40
|
+
// AUTH: POST /api/bongos/tasks is archon-gated (creating work is scope-shaping —
|
|
41
41
|
// ADR 0016). Run under an Archon session (on the droplet, the operator's).
|
|
42
42
|
//
|
|
43
43
|
// Usage:
|
|
@@ -393,7 +393,7 @@ function report(summary, FLAGS, { checkOnly }) {
|
|
|
393
393
|
}
|
|
394
394
|
if (!summary.autoPromote && !FLAGS.dryRun && summary.stamped.some((g) => g.task_id)) {
|
|
395
395
|
console.log('\nNext: a Metic+ builder promotes the new backlog copies to ready:');
|
|
396
|
-
console.log(' node scripts/gds/api.js POST /api/
|
|
396
|
+
console.log(' node scripts/gds/api.js POST /api/bongos/tasks/<id>/promote (or the builders\' hall)');
|
|
397
397
|
}
|
|
398
398
|
}
|
|
399
399
|
|
|
@@ -70,13 +70,13 @@
|
|
|
70
70
|
"est_minutes": 45,
|
|
71
71
|
"credits_reward": 12,
|
|
72
72
|
"title": "Idea-seed pass: file 5-8 fresh in-world ideas (names, lore, or builder-UX) into the idea inbox",
|
|
73
|
-
"description": "## What you'll do\n\nThe seed of almost everything built here is the **idea_inbox** — a queue anyone can drop ideas into, which trusted builders later triage into real tasks. Your first ship as an ideator is simple and concrete: **add a small batch of fresh ideas to that inbox.** You write no code, touch no game, change no system — you think, write a few short well-shaped ideas, and file them with one command each.\n\nIt is identical for every newcomer and **always valuable**: the inbox is never \"done\" — every triage pass consumes ideas (promote/discard/merge), so it is permanently hungry for fresh input, and a growing world always wants more names, more lore, more texture. Your batch is brand-new content, so it can never duplicate \"the work\" — the supply IS the work.\n\n## Pick ONE branch\n\n- **Branch A — PRODUCT flavour (default).** Ideas that grow the world players see: **names + one line of lore** for a character, structure, landmark, district, ship, or festival; or a world-background snippet (a custom, a superstition, a line a named NPC says). Tone: mythic, mysterious, a \"discovered secret\"; Mediterranean ancient-Greek coast (just south of Athens); NOT modern, NOT tongue-in-cheek-modern. Ground it in CLAUDE.md §3/§6/§7.\n- **Branch B — INTERNAL / builder-UX.** Small user-experience improvement ideas for the GDS / builders' hall (the surfaces builders use, not the game): a clearer label, a confusing onboarding message, a quality-of-life tweak to a status page or a slash-command's output. See `docs/TRACKS.md` for product vs internal.\n\n## How to find your way in\n\n1. (Branch A) Read CLAUDE.md §3/§6/§7 for tone. (Branch B) Skim `docs/TRACKS.md` and click around your instance's /builders hall for the rough edge you'll write up.\n2. See what's already filed so you don't repeat it: `node scripts/gds/api.js GET /api/
|
|
73
|
+
"description": "## What you'll do\n\nThe seed of almost everything built here is the **idea_inbox** — a queue anyone can drop ideas into, which trusted builders later triage into real tasks. Your first ship as an ideator is simple and concrete: **add a small batch of fresh ideas to that inbox.** You write no code, touch no game, change no system — you think, write a few short well-shaped ideas, and file them with one command each.\n\nIt is identical for every newcomer and **always valuable**: the inbox is never \"done\" — every triage pass consumes ideas (promote/discard/merge), so it is permanently hungry for fresh input, and a growing world always wants more names, more lore, more texture. Your batch is brand-new content, so it can never duplicate \"the work\" — the supply IS the work.\n\n## Pick ONE branch\n\n- **Branch A — PRODUCT flavour (default).** Ideas that grow the world players see: **names + one line of lore** for a character, structure, landmark, district, ship, or festival; or a world-background snippet (a custom, a superstition, a line a named NPC says). Tone: mythic, mysterious, a \"discovered secret\"; Mediterranean ancient-Greek coast (just south of Athens); NOT modern, NOT tongue-in-cheek-modern. Ground it in CLAUDE.md §3/§6/§7.\n- **Branch B — INTERNAL / builder-UX.** Small user-experience improvement ideas for the GDS / builders' hall (the surfaces builders use, not the game): a clearer label, a confusing onboarding message, a quality-of-life tweak to a status page or a slash-command's output. See `docs/TRACKS.md` for product vs internal.\n\n## How to find your way in\n\n1. (Branch A) Read CLAUDE.md §3/§6/§7 for tone. (Branch B) Skim `docs/TRACKS.md` and click around your instance's /builders hall for the rough edge you'll write up.\n2. See what's already filed so you don't repeat it: `node scripts/gds/api.js GET /api/bongos/inbox`.\n3. File each idea with `node scripts/gds/capture.js \"<title>\" --body-file <path>` (filing an idea is the open-to-all path — a Xenos/Thetes session is allowed to do it; you just can't triage them). Put one line of detail + a `track: product` or `track: internal` line in each body file.",
|
|
74
74
|
"done_when": [
|
|
75
75
|
"You filed 5–8 fresh ideas into the idea_inbox via `node scripts/gds/capture.js` (each prints a `Captured idea #N` confirmation), all in ONE branch (A product, or B internal/UX).",
|
|
76
76
|
"Each idea has a clear title and a body with at least one sentence of detail — for Branch A, one line of in-world lore (who/what it is); for Branch B, what the rough edge is and what 'better' looks like.",
|
|
77
77
|
"Branch A ideas are in the world's voice and consistent with CLAUDE.md §3/§6/§7 (ancient-Greek coast, Example, mythic 'discovered secret' tone — not modern/anachronistic).",
|
|
78
78
|
"Each idea body declares its track on a `track: product` or `track: internal` line so triage can route it.",
|
|
79
|
-
"Before filing you ran `GET /api/
|
|
79
|
+
"Before filing you ran `GET /api/bongos/inbox` and confirmed your ideas are not near-duplicates of open ones.",
|
|
80
80
|
"You touched only the idea_inbox via capture.js — no code, no migrations, no infra, no permission/pipeline files; nothing committed to the repo."
|
|
81
81
|
],
|
|
82
82
|
"touches": [],
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// realized as a privacy-preserving two-step: this script gzips completed
|
|
12
12
|
// transcripts into a local spool, and onboarding-analyze.js then ships only
|
|
13
13
|
// the *distilled friction signal* (not the raw transcript) to the shared GDS
|
|
14
|
-
// via POST /api/
|
|
14
|
+
// via POST /api/bongos/inbox. The raw transcript never leaves the machine — a
|
|
15
15
|
// deliberate privacy choice given transcripts can contain anything the builder
|
|
16
16
|
// typed. A dedicated upload endpoint would need a new route + storage table
|
|
17
17
|
// (migration), both outside this task's touches[].
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// scripts/gds/paste-token.js — V3.R91 / #401.
|
|
3
3
|
//
|
|
4
|
-
// Accept a CLI bearer minted by the builders' hall (POST /api/
|
|
4
|
+
// Accept a CLI bearer minted by the builders' hall (POST /api/bongos/auth/cli-token/issue)
|
|
5
5
|
// and write it into ~/.config/otb/bongos-session.json. Preserves any existing
|
|
6
6
|
// fields (notably gemini_api_key registered via /builder-setup) so a token
|
|
7
7
|
// paste never silently un-registers a builder's Gemini key.
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// builder can copy + paste a single line.
|
|
15
15
|
//
|
|
16
16
|
// Safety contract:
|
|
17
|
-
// 1. The token is verified against /api/
|
|
17
|
+
// 1. The token is verified against /api/bongos/me BEFORE the session file is
|
|
18
18
|
// touched. A bad paste exits non-zero with a clear message and leaves
|
|
19
19
|
// the existing session intact.
|
|
20
20
|
// 2. The file is written with mode 0600, same as setup.js.
|
|
@@ -70,7 +70,7 @@ async function main() {
|
|
|
70
70
|
// paste was meant to REPLACE, not destroy.
|
|
71
71
|
let me;
|
|
72
72
|
try {
|
|
73
|
-
const res = await fetch(`${API_BASE}/api/
|
|
73
|
+
const res = await fetch(`${API_BASE}/api/bongos/me`, {
|
|
74
74
|
headers: { Authorization: `Bearer ${token}` },
|
|
75
75
|
});
|
|
76
76
|
if (res.status === 401) {
|