@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
|
@@ -109,11 +109,11 @@ if [ -z "$REMOTE" ]; then bad "could not resolve origin remote for fresh-clone t
|
|
|
109
109
|
fi
|
|
110
110
|
|
|
111
111
|
# --- 3. unauthenticated memory read is rejected (guard) ----------------------
|
|
112
|
-
code=$(curl -sS -o /dev/null -w '%{http_code}' "$BASE/api/
|
|
112
|
+
code=$(curl -sS -o /dev/null -w '%{http_code}' "$BASE/api/bongos/memory/files" || echo 000)
|
|
113
113
|
[ "$code" = "401" ] && ok "unauth GET /memory/files → 401" || bad "unauth GET /memory/files → $code (expected 401)"
|
|
114
114
|
|
|
115
115
|
# --- 4. authenticated builder can pull their server-canonical memory ---------
|
|
116
|
-
FILES_JSON=$(curl -sS -H "Authorization: Bearer $TOKEN" "$BASE/api/
|
|
116
|
+
FILES_JSON=$(curl -sS -H "Authorization: Bearer $TOKEN" "$BASE/api/bongos/memory/files" || echo '{}')
|
|
117
117
|
COUNT=$(echo "$FILES_JSON" | python3 -c "import json,sys;print(json.load(sys.stdin).get('count',-1))" 2>/dev/null || echo -1)
|
|
118
118
|
if [ "$COUNT" -ge 1 ] 2>/dev/null; then
|
|
119
119
|
ok "authenticated pull lists $COUNT server-canonical memory file(s)"
|
|
@@ -125,7 +125,7 @@ fi
|
|
|
125
125
|
# Take the first listed file, fetch it, recompute sha256, compare to server's.
|
|
126
126
|
FIRST_PATH=$(echo "$FILES_JSON" | python3 -c "import json,sys;f=json.load(sys.stdin).get('files',[]);print(f[0]['path'] if f else '')" 2>/dev/null || echo "")
|
|
127
127
|
if [ -n "$FIRST_PATH" ]; then
|
|
128
|
-
VERDICT=$(curl -sS -H "Authorization: Bearer $TOKEN" --get "$BASE/api/
|
|
128
|
+
VERDICT=$(curl -sS -H "Authorization: Bearer $TOKEN" --get "$BASE/api/bongos/memory/file" --data-urlencode "path=$FIRST_PATH" \
|
|
129
129
|
| python3 -c "
|
|
130
130
|
import json,sys,hashlib
|
|
131
131
|
d=json.load(sys.stdin)
|
|
@@ -158,9 +158,9 @@ if [ "${GDS_SMOKE_ALLOW_WRITE:-0}" = "1" ] && [ "$TOKEN_SRC" = "env" ]; then
|
|
|
158
158
|
PUSH_BODY=$(python3 -c "import json,sys;print(json.dumps({'files':[{'path':'$SPATH','content':sys.argv[1]}]}))" "$STAMP")
|
|
159
159
|
PUSH_CODE=$(curl -sS -o /dev/null -w '%{http_code}' -X POST \
|
|
160
160
|
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
|
|
161
|
-
"$BASE/api/
|
|
161
|
+
"$BASE/api/bongos/memory/sync" -d "$PUSH_BODY" || echo 000)
|
|
162
162
|
if [ "$PUSH_CODE" = "200" ]; then
|
|
163
|
-
RT=$(curl -sS -H "Authorization: Bearer $TOKEN" --get "$BASE/api/
|
|
163
|
+
RT=$(curl -sS -H "Authorization: Bearer $TOKEN" --get "$BASE/api/bongos/memory/file" --data-urlencode "path=$SPATH" \
|
|
164
164
|
| python3 -c "import json,sys;d=json.load(sys.stdin);print('OK' if d.get('content')==sys.argv[1] else 'MISMATCH')" "$STAMP" 2>/dev/null || echo ERR)
|
|
165
165
|
[ "$RT" = "OK" ] && ok "push→pull sync round-trip (content persisted + retrieved intact)" \
|
|
166
166
|
|| bad "push→pull round-trip content mismatch ($RT)"
|
|
@@ -71,14 +71,14 @@ function errorCode(body) {
|
|
|
71
71
|
|
|
72
72
|
/** GET a Bongos API path, returning the parsed body. Throws on a non-2xx. */
|
|
73
73
|
async function get(path) {
|
|
74
|
-
const r = await apiCall('GET', `/api/
|
|
74
|
+
const r = await apiCall('GET', `/api/bongos${path}`);
|
|
75
75
|
if (!r.ok) throw new Error(`GET ${path} → ${r.status}`);
|
|
76
76
|
return r.data;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
/** POST a probe. Returns the status WITHOUT throwing — the status IS the proof. */
|
|
80
80
|
async function probePost(path, body) {
|
|
81
|
-
const r = await apiCall('POST', `/api/
|
|
81
|
+
const r = await apiCall('POST', `/api/bongos${path}`, body || {});
|
|
82
82
|
return { status: r.status, body: r.data, why: errorCode(r.data) };
|
|
83
83
|
}
|
|
84
84
|
|
|
@@ -55,7 +55,7 @@ function shouldFederate(inst, deps) {
|
|
|
55
55
|
// device sign-in (and a wrong origin would be a takeover vector). client_id is the
|
|
56
56
|
// (unique, DNS-safe) slug, so a re-provision rotates the SAME row's secret via
|
|
57
57
|
// registerClient's ON CONFLICT rather than orphaning a client. redirect_uri lists both
|
|
58
|
-
// callback prefixes the core may emit (/api/
|
|
58
|
+
// callback prefixes the core may emit (/api/bongos is what auth.js builds today) so the
|
|
59
59
|
// hub's exact-match allow-list accepts the browser leg. --apply gates the real hub
|
|
60
60
|
// write; dry-run returns a placeholder block (so webEnvBody can still be composed) + logs.
|
|
61
61
|
async function federateInstance(inst, deps) {
|
|
@@ -246,7 +246,7 @@ function healthzCmd(inst) {
|
|
|
246
246
|
|
|
247
247
|
// The instance manifest, read over loopback — the identity companion to healthzCmd (task 1003740).
|
|
248
248
|
function identityCmd(inst) {
|
|
249
|
-
return `curl -sS --max-time 5 http://127.0.0.1:${inst.port}/api/
|
|
249
|
+
return `curl -sS --max-time 5 http://127.0.0.1:${inst.port}/api/bongos/instance`;
|
|
250
250
|
}
|
|
251
251
|
|
|
252
252
|
// Does a freshly provisioned instance report ITSELF, or the platform it is hosted on?
|
|
@@ -153,7 +153,7 @@ WantedBy=timers.target
|
|
|
153
153
|
//
|
|
154
154
|
// The pin outlived it, and src/branding.js's ENV_OVERRIDES cover domains, auth.idp and landing —
|
|
155
155
|
// never `identity.productName`. So every hosted instance kept serving the NEUTRAL pack's name:
|
|
156
|
-
// GET /api/
|
|
156
|
+
// GET /api/bongos/instance on hermeslines-marketing, mercury and demo all answered "Cloud Bongos"
|
|
157
157
|
// while each instance's own pack on disk said otherwise, and `bongos login <instance>` greeted a
|
|
158
158
|
// newcomer with the platform's name at the moment they were deciding whether to trust it.
|
|
159
159
|
//
|
|
@@ -310,10 +310,10 @@ function settingsEnvVarsFor(inst) {
|
|
|
310
310
|
}
|
|
311
311
|
|
|
312
312
|
// The instance's own public manifest — the settings read-back ADR 0190 names
|
|
313
|
-
// (GET /api/
|
|
313
|
+
// (GET /api/bongos/instance → brand.project). Sibling of provision-net's healthzCmd:
|
|
314
314
|
// same loopback + timeout, a different question ("did you READ it?").
|
|
315
315
|
function instanceManifestCmd(inst) {
|
|
316
|
-
return `curl -sS --max-time 5 http://127.0.0.1:${inst.port}/api/
|
|
316
|
+
return `curl -sS --max-time 5 http://127.0.0.1:${inst.port}/api/bongos/instance`;
|
|
317
317
|
}
|
|
318
318
|
|
|
319
319
|
// Did the restarted instance CONSUME the pushed settings? Compares each key of
|
package/scripts/gds/pulse.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
//
|
|
16
16
|
// -------------------------------------------------------------------------
|
|
17
17
|
// Pulse-mode follow-up note (unchanged from original):
|
|
18
|
-
// POST /api/
|
|
18
|
+
// POST /api/bongos/pulse is NOT yet wired (route lives in src/bongos/routes.js,
|
|
19
19
|
// which is OUT of THAT task's touches[]). Once a follow-up task adds
|
|
20
20
|
// the route, the pulse path starts working with no changes. Until then,
|
|
21
21
|
// running it will print a 404 from the server — that is expected.
|
|
@@ -314,7 +314,7 @@ async function releaseStale({ timer, dryRun }) {
|
|
|
314
314
|
const r = await api.request('POST', '/pulse', { body: { claim_id: claimId } });
|
|
315
315
|
if (!r.ok) {
|
|
316
316
|
// Fire-and-forget: log the diagnostic but do not fail.
|
|
317
|
-
// Until the /api/
|
|
317
|
+
// Until the /api/bongos/pulse route is mounted, this routinely returns 404.
|
|
318
318
|
console.error(`pulse non-ok (status ${r.status}):`, r.data);
|
|
319
319
|
process.exit(0);
|
|
320
320
|
}
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
// strand-watch.js. On the server-publish path (pushVia() 'server' — no authenticated
|
|
19
19
|
// gh, i.e. a dev box or any credential-less checkout) it prints ONE line stating the
|
|
20
20
|
// credential model and where the truth about published work lives
|
|
21
|
-
// (GET /api/
|
|
21
|
+
// (GET /api/bongos/tasks/:id/publish-status). On a laptop that pushes locally
|
|
22
22
|
// (pushVia() 'local') it prints NOTHING — a line that fires on every healthy laptop
|
|
23
23
|
// becomes wallpaper and the real one gets scrolled past (the strand-watch lesson).
|
|
24
24
|
//
|
|
@@ -40,7 +40,7 @@ const BRIEF = 'This machine holds NO GitHub push credential — BY DESIGN (ADR 0
|
|
|
40
40
|
+ 'git push / ls-remote / fetch against origin fail with auth errors here, and that is not a fault to fix. '
|
|
41
41
|
+ 'Landing is server-mediated — /builder-ship uploads a git bundle and the SERVER pushes, opens the PR, and lands it. '
|
|
42
42
|
+ 'NEVER ask the owner for a PAT or credential; that request is always wrong on this machine. '
|
|
43
|
-
+ 'To see whether work reached GitHub, use GET /api/
|
|
43
|
+
+ 'To see whether work reached GitHub, use GET /api/bongos/tasks/:id/publish-status — never raw git probes.';
|
|
44
44
|
|
|
45
45
|
// briefLine(via) — the unit-testable core: the SessionStart line for this publish
|
|
46
46
|
// path, or null. Null IS the silence (the laptop case, and the undetermined case —
|
package/scripts/gds/reauth.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// getting back in — the slow Device Flow, terminal codes, Gemini-key prompts — is
|
|
12
12
|
// not something to keep. This script is the fix:
|
|
13
13
|
//
|
|
14
|
-
// 1. Detect — is the current session still valid? (GET /api/
|
|
14
|
+
// 1. Detect — is the current session still valid? (GET /api/bongos/me)
|
|
15
15
|
// valid → print who you are + exit 0. Nothing to do.
|
|
16
16
|
// invalid → exit 10 ("re-auth needed") after opening the browser.
|
|
17
17
|
// 2. Guide — open the builder's Settings page in the default browser (where
|
package/scripts/gds/recall.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// scripts/gds/recall.js — one-call project-knowledge search (task 955, V4.R17 /
|
|
3
|
-
// ADR 0060). Wraps POST /api/
|
|
3
|
+
// ADR 0060). Wraps POST /api/bongos/search: lexical (FTS + pg_trgm) fused with RRF,
|
|
4
4
|
// rank/owner-scoped server-side (a sub-Metic caller never sees protected docs;
|
|
5
5
|
// you only ever see your own private chunks). Authenticated — reads the builder
|
|
6
6
|
// session like every other /builder-* CLI.
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
//
|
|
29
29
|
// Filing: DRY-RUN by default (prints what it would file). --file POSTs one
|
|
30
30
|
// report PER CLASS (max severity within the class, details in repro_steps_md)
|
|
31
|
-
// to /api/
|
|
31
|
+
// to /api/bongos/security/reports. --canary proves the end-to-end pipe: plants a
|
|
32
32
|
// constructed token, asserts the scanner catches it, files a low "[canary]"
|
|
33
33
|
// report, and dispute-closes it so the queue stays clean.
|
|
34
34
|
//
|
|
@@ -317,14 +317,14 @@ function filingBlocker() {
|
|
|
317
317
|
|
|
318
318
|
async function fileReport(report) {
|
|
319
319
|
const { apiCall } = require('./cli-lib.js');
|
|
320
|
-
const r = await apiCall('POST', '/api/
|
|
320
|
+
const r = await apiCall('POST', '/api/bongos/security/reports', report);
|
|
321
321
|
const row = (r.data && r.data.report) || {};
|
|
322
322
|
return row.id || null;
|
|
323
323
|
}
|
|
324
324
|
|
|
325
325
|
async function disputeReport(id, note) {
|
|
326
326
|
const { apiCall } = require('./cli-lib.js');
|
|
327
|
-
return apiCall('POST', `/api/
|
|
327
|
+
return apiCall('POST', `/api/bongos/security/reports/${id}/dispute`, { note });
|
|
328
328
|
}
|
|
329
329
|
|
|
330
330
|
// ---------- canary ----------
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// Renders generative-ideas.md from the GDS idea_inbox table.
|
|
3
3
|
//
|
|
4
|
-
// Reads via GET /api/
|
|
4
|
+
// Reads via GET /api/bongos/inbox (authenticated). Writes a generated markdown
|
|
5
5
|
// view to the repo's top-level generative-ideas.md. The file is overwritten
|
|
6
6
|
// on every run — manual edits will not survive. Capture via /builder-capture
|
|
7
7
|
// or `node scripts/gds/capture.js`; triage via /builder-triage or the API.
|
|
8
8
|
//
|
|
9
|
-
// Note (2026-05-10): the current GET /api/
|
|
9
|
+
// Note (2026-05-10): the current GET /api/bongos/inbox endpoint returns open
|
|
10
10
|
// ideas only (see src/bongos/inbox.js listOpenIdeas). The "Recently Promoted",
|
|
11
11
|
// "Recently Discarded", and "Merged" sections will be empty until the API
|
|
12
12
|
// is extended to expose those statuses. The script is forward-compatible:
|
|
@@ -33,7 +33,7 @@ const HEADER = `<!-- GENERATED FILE — Edit via /builder-capture or /builder-tr
|
|
|
33
33
|
>
|
|
34
34
|
> **Capture an idea:** \`node scripts/gds/capture.js "short title"\` (or the \`/builder-capture\` slash command).
|
|
35
35
|
>
|
|
36
|
-
> **Triage open ideas:** \`/idea-triage\` (or \`PATCH /api/
|
|
36
|
+
> **Triage open ideas:** \`/idea-triage\` (or \`PATCH /api/bongos/inbox/<id>\` with \`{ status: 'promoted' | 'discarded' | 'merged', promoted_to_task_id: N }\`).
|
|
37
37
|
`;
|
|
38
38
|
|
|
39
39
|
function fmtTimestamp(iso) {
|
|
@@ -102,13 +102,13 @@ function renderSection(heading, ideas, emptyMsg) {
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
async function fetchAllIdeas() {
|
|
105
|
-
// GET /api/
|
|
105
|
+
// GET /api/bongos/inbox currently returns open ideas only. We request the max
|
|
106
106
|
// limit so this works as the inbox grows. When the API is extended to
|
|
107
107
|
// return other statuses, this script will pick them up automatically.
|
|
108
108
|
const api = await cliClient();
|
|
109
109
|
const { ok, status, data } = await api.inbox.getInbox({ query: { limit: 500 } });
|
|
110
110
|
if (!ok) {
|
|
111
|
-
throw new Error(`GET /api/
|
|
111
|
+
throw new Error(`GET /api/bongos/inbox failed: HTTP ${status} ${JSON.stringify(data)}`);
|
|
112
112
|
}
|
|
113
113
|
return data.ideas || [];
|
|
114
114
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// "You can't manage what you don't measure." This dependency-free CLI shells
|
|
6
6
|
// out to git / wc / knip and emits a JSON snapshot of repo health, then upserts
|
|
7
7
|
// it into repo_health_snapshots (idempotent on calendar date — rerun same day
|
|
8
|
-
// = upsert, not a new row). The latest row feeds /api/
|
|
8
|
+
// = upsert, not a new row). The latest row feeds /api/bongos/public/repo-health,
|
|
9
9
|
// which renders a trend tile on status.example.com.
|
|
10
10
|
//
|
|
11
11
|
// What the snapshot contains:
|
|
@@ -219,11 +219,11 @@ function restartPreview(deps = {}) {
|
|
|
219
219
|
// task 1002607: the discriminator probe URL — same origin as the health URL, at
|
|
220
220
|
// the API healthz path only the FULL server mounts. Pure + exported for tests.
|
|
221
221
|
function apiHealthzProbeUrl(healthUrl) {
|
|
222
|
-
try { return new URL('/api/
|
|
222
|
+
try { return new URL('/api/bongos/healthz', healthUrl).toString(); } catch { return null; }
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
// task 1002607: is the thing answering the health URL actually the MAIN server?
|
|
226
|
-
// The game-only preview entry (ADR 0052) mounts no /api/
|
|
226
|
+
// The game-only preview entry (ADR 0052) mounts no /api/bongos, so a 200 from the
|
|
227
227
|
// API healthz proves the answerer is the full server — whose default bind is the
|
|
228
228
|
// SAME 127.0.0.1:3000 the box health check probes — not the preview. A probe
|
|
229
229
|
// error/404 means "not the main server", which is the expected preview answer.
|
|
@@ -254,7 +254,7 @@ async function waitHealthy(deps = {}) {
|
|
|
254
254
|
if (await answeredByMainServer(healthUrl, fetchImpl)) {
|
|
255
255
|
return {
|
|
256
256
|
ok: false,
|
|
257
|
-
reason: `${healthUrl} is answered by the MAIN server (/api/
|
|
257
|
+
reason: `${healthUrl} is answered by the MAIN server (/api/bongos/healthz responded 200), not the game preview — the preview did not start (its port is taken by the full server)`,
|
|
258
258
|
};
|
|
259
259
|
}
|
|
260
260
|
return { ok: true };
|
|
@@ -38,7 +38,7 @@ const TASKS = [
|
|
|
38
38
|
const idByRef = {};
|
|
39
39
|
// Phase 1: create tasks (idempotent on source_ref) + link the criterion.
|
|
40
40
|
for (const t of TASKS) {
|
|
41
|
-
const create = await apiCall('POST', '/api/
|
|
41
|
+
const create = await apiCall('POST', '/api/bongos/tasks', {
|
|
42
42
|
version_id: 'BONGOS-V1',
|
|
43
43
|
goal_id: GOAL_ID,
|
|
44
44
|
title: t.title,
|
|
@@ -54,7 +54,7 @@ const TASKS = [
|
|
|
54
54
|
const id = task && task.id;
|
|
55
55
|
if (!id) { console.log(` ${t.ref}: CREATE FAILED — ${create.status} ${JSON.stringify(create.data).slice(0, 160)}`); continue; }
|
|
56
56
|
idByRef[t.ref] = id;
|
|
57
|
-
const link = await apiCall('POST', `/api/
|
|
57
|
+
const link = await apiCall('POST', `/api/bongos/tasks/${id}/criteria`, { criterion_ids: t.crit });
|
|
58
58
|
console.log(` ${t.ref} -> task ${id} (${t.kind}, P${t.priority}, goal ${task.goal_id}) · criterion ${link.status === 200 ? 'ok' : (JSON.stringify(link.data).slice(0, 120))}`);
|
|
59
59
|
}
|
|
60
60
|
// Phase 2: dependency edges (idempotent on (task_id, depends_on_task_id)).
|
|
@@ -65,7 +65,7 @@ const TASKS = [
|
|
|
65
65
|
const localDepIds = t.deps.map((d) => idByRef[d]).filter(Boolean);
|
|
66
66
|
const allDeps = [...localDepIds, ...t.extDeps];
|
|
67
67
|
for (const depId of allDeps) {
|
|
68
|
-
const r = await apiCall('POST', `/api/
|
|
68
|
+
const r = await apiCall('POST', `/api/bongos/tasks/${id}/dependencies`, { depends_on_task_id: depId });
|
|
69
69
|
console.log(` ${t.ref}(${id}) -> ${depId} ${r.status === 200 || r.status === 201 ? 'ok' : (JSON.stringify(r.data).slice(0, 120))}`);
|
|
70
70
|
}
|
|
71
71
|
}
|
|
@@ -15,7 +15,7 @@ const H = { Authorization: `Bearer ${TOKEN}`, 'Content-Type': 'application/json'
|
|
|
15
15
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
16
16
|
async function api(method, path, body, _tries = 0) {
|
|
17
17
|
await sleep(500); // base throttle to stay under the per-IP rate limit
|
|
18
|
-
const res = await fetch(`${BASE}/api/
|
|
18
|
+
const res = await fetch(`${BASE}/api/bongos${path}`, {
|
|
19
19
|
method, headers: H, body: body ? JSON.stringify(body) : undefined,
|
|
20
20
|
});
|
|
21
21
|
const text = await res.text();
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
// Design home: the "Bongos App — V1" plan artifact (favicon 🥁).
|
|
7
7
|
//
|
|
8
8
|
// Shape mirrors seed-bongos-tasks.js exactly:
|
|
9
|
-
// - POST /api/
|
|
10
|
-
// - POST /api/
|
|
9
|
+
// - POST /api/bongos/tasks { version_id:'BONGOS-V1', criterion_ids:['C1'], ... }
|
|
10
|
+
// - POST /api/bongos/tasks/:id/dependencies { depends_on_task_ids:[...] }
|
|
11
11
|
// - idempotent on source_ref (skips already-created); deps idempotent server-side.
|
|
12
12
|
// Run migration 120_bongos_v1_planning_seed.sql FIRST so the version + C1..C4 exist.
|
|
13
13
|
// After this runs, promote the zero-dependency tasks (R01/R02/R03) to 'ready'
|
|
@@ -53,12 +53,12 @@ async function post(path, body) {
|
|
|
53
53
|
criterion_ids: ['C7'],
|
|
54
54
|
source: 'planning', source_ref: `BONGOS-V1-coreB-${t.ref}`,
|
|
55
55
|
};
|
|
56
|
-
let { status, json } = await post('/api/
|
|
56
|
+
let { status, json } = await post('/api/bongos/tasks', body);
|
|
57
57
|
let id = json.id || (json.task && json.task.id);
|
|
58
58
|
if (!id && t.kind === 'verify') {
|
|
59
59
|
// memory: kind=verify has 500'd before (idea #357). Fall back, keep going.
|
|
60
60
|
console.log(` ${t.ref}: kind=verify failed (${json.error || status}); retrying as kind=feature`);
|
|
61
|
-
({ status, json } = await post('/api/
|
|
61
|
+
({ status, json } = await post('/api/bongos/tasks', { ...body, kind: 'feature' }));
|
|
62
62
|
id = json.id || (json.task && json.task.id);
|
|
63
63
|
}
|
|
64
64
|
if (!id) { console.log(` ${t.ref}: CREATE FAILED — ${status} ${JSON.stringify(json).slice(0, 160)}`); continue; }
|
|
@@ -73,7 +73,7 @@ async function post(path, body) {
|
|
|
73
73
|
for (const dep of t.deps) {
|
|
74
74
|
const depId = idByRef[dep];
|
|
75
75
|
if (!depId) { console.log(` ${t.ref}: dep ${dep} not created — skip`); continue; }
|
|
76
|
-
const { status, json } = await post(`/api/
|
|
76
|
+
const { status, json } = await post(`/api/bongos/tasks/${id}/dependencies`, { depends_on_task_id: depId });
|
|
77
77
|
console.log(` ${t.ref}(${id}) depends on ${dep}(${depId}) -> ${status === 200 || status === 201 ? 'ok' : (json.error || status)}`);
|
|
78
78
|
}
|
|
79
79
|
}
|
|
@@ -69,19 +69,19 @@ async function post(path, body) {
|
|
|
69
69
|
criterion_ids: ['C7'],
|
|
70
70
|
source: 'planning', source_ref: `BONGOS-V1-coreB-${t.ref}`,
|
|
71
71
|
};
|
|
72
|
-
let { status, json } = await post('/api/
|
|
72
|
+
let { status, json } = await post('/api/bongos/tasks', body);
|
|
73
73
|
let id = json.id || (json.task && json.task.id);
|
|
74
74
|
if (!id && t.kind === 'verify') {
|
|
75
75
|
// memory: kind=verify has 500'd before (idea #357). Fall back, keep going.
|
|
76
76
|
console.log(` ${t.ref}: kind=verify failed (${json.error || status}); retrying as kind=feature`);
|
|
77
|
-
({ status, json } = await post('/api/
|
|
77
|
+
({ status, json } = await post('/api/bongos/tasks', { ...body, kind: 'feature' }));
|
|
78
78
|
id = json.id || (json.task && json.task.id);
|
|
79
79
|
}
|
|
80
80
|
if (!id) { console.log(` ${t.ref}: CREATE FAILED — ${status} ${JSON.stringify(json).slice(0, 160)}`); continue; }
|
|
81
81
|
idByRef[t.ref] = id;
|
|
82
82
|
// Link C7 explicitly (criterion_ids at create is not honored on this build;
|
|
83
83
|
// the /criteria endpoint is idempotent — re-adding an existing link is a no-op).
|
|
84
|
-
const link = await post(`/api/
|
|
84
|
+
const link = await post(`/api/bongos/tasks/${id}/criteria`, { criterion_ids: ['C7'] });
|
|
85
85
|
console.log(` ${t.ref} -> task ${id} (${t.kind}, P${t.priority}) · C7 link ${link.status === 200 ? 'ok' : (link.json.error || link.status)}`);
|
|
86
86
|
}
|
|
87
87
|
// Phase 2: wire dependencies (idempotent on (task_id, depends_on_task_id)).
|
|
@@ -92,7 +92,7 @@ async function post(path, body) {
|
|
|
92
92
|
for (const dep of t.deps) {
|
|
93
93
|
const depId = idByRef[dep];
|
|
94
94
|
if (!depId) { console.log(` ${t.ref}: dep ${dep} not created — skip`); continue; }
|
|
95
|
-
const { status, json } = await post(`/api/
|
|
95
|
+
const { status, json } = await post(`/api/bongos/tasks/${id}/dependencies`, { depends_on_task_id: depId });
|
|
96
96
|
console.log(` ${t.ref}(${id}) depends on ${dep}(${depId}) -> ${status === 200 || status === 201 ? 'ok' : (json.error || status)}`);
|
|
97
97
|
}
|
|
98
98
|
}
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
// instance 1). Design doc: artifact 02bcca71 (the bongos toolkit).
|
|
6
6
|
//
|
|
7
7
|
// Shape mirrors seed-medusa-tasks.js exactly:
|
|
8
|
-
// - POST /api/
|
|
9
|
-
// - POST /api/
|
|
8
|
+
// - POST /api/bongos/tasks { version_id:'GDS-V4', criterion_ids:['C8'], ... }
|
|
9
|
+
// - POST /api/bongos/tasks/:id/dependencies { depends_on_task_ids:[...] }
|
|
10
10
|
// - idempotent on source_ref (skips already-created); deps idempotent server-side.
|
|
11
11
|
//
|
|
12
12
|
// Display R## numbers are assigned dynamically from the current max V4.R## in
|
|
@@ -81,12 +81,12 @@ A \`curl -fsSL https://get.bongos.dev | sh\` bootstrap (detects OS/arch, downloa
|
|
|
81
81
|
},
|
|
82
82
|
{
|
|
83
83
|
key: 'P4A',
|
|
84
|
-
title: 'Instance manifest endpoint — GET /api/
|
|
84
|
+
title: 'Instance manifest endpoint — GET /api/bongos/instance (brand + modules + repo)',
|
|
85
85
|
description: `Part of Cloud Bongos / C8. Cross-ref: R53 (branding-contract layer), R54 (feature-module selection). This is the read-API over those two configs — the conda "environment.yml" a CLI fetches to configure itself.
|
|
86
86
|
|
|
87
87
|
A small public, read-only endpoint returning the instance descriptor assembled from the R53 branding contract + the R54 module flags: product/instance name + brand (identity, copy, theme — NO secrets), enabled feature-modules, the GitHub repo binding, the rank ladder, supported auth methods (device-flow / app-pair), admission policy (invite-only vs open), and whether a managed dev-box backend is available. So \`bongos login <url>\` brands itself, knows the repo for \`--local\`, and hides verbs an instance doesn't run (e.g. no \`box\` if dev-box is off). Today GET /healthz returns only { ok, auth_configured } — this is a genuine gap.
|
|
88
88
|
|
|
89
|
-
**Done when:** GET /api/
|
|
89
|
+
**Done when:** GET /api/bongos/instance returns a documented manifest assembled from the branding contract + module flags, contains no secrets/topology, is fetchable pre-auth (CORS read), and the CLI can brand + feature-gate itself from it. Depends on R53/R54 so the brand + module sources exist.`,
|
|
90
90
|
kind: 'feature', discipline: 'engineer', priority: 3,
|
|
91
91
|
est_minutes: 240, manual_degree: 2, credits_reward: 50,
|
|
92
92
|
touches: ['src/bongos/routes/', 'src/bongos/'], criteria: ['C8'], deps: ['R53', 'R54'],
|
|
@@ -96,7 +96,7 @@ A small public, read-only endpoint returning the instance descriptor assembled f
|
|
|
96
96
|
title: 'bongos login <instance> (instance-agnostic) + stranger access-request flow; folds in init/upgrade',
|
|
97
97
|
description: `Part of Cloud Bongos / C8. Cross-ref: P1, P4A (manifest), R64 (\`medusa/bongos upgrade\`), R65 (\`init\`), ADR 0050/0057/0059 (admission).
|
|
98
98
|
|
|
99
|
-
\`bongos login <instance-url>\` fetches the P4A manifest, runs the GitHub device-flow (browser-click, no token paste — the UI-first rule), stores a per-instance scoped session, and brands the CLI for that instance. For someone NOT yet admitted, it files the public POST /api/
|
|
99
|
+
\`bongos login <instance-url>\` fetches the P4A manifest, runs the GitHub device-flow (browser-click, no token paste — the UI-first rule), stores a per-instance scoped session, and brands the CLI for that instance. For someone NOT yet admitted, it files the public POST /api/bongos/access-requests (their GitHub username) and polls — telling them "an Archon will approve you with a 👍 in Discord" — until admission flips, then completes sign-in. No GitHub collaborator invite is involved. Default admission is invite-only. Also folds the already-planned \`bongos init\` (scaffold a brand-new instance, R65) and \`bongos upgrade\` (R64) in as subcommands of the same CLI.
|
|
100
100
|
|
|
101
101
|
**Done when:** \`bongos login <any-instance-url>\` works end-to-end including the not-yet-admitted path (files the request, polls, completes once approved); the CLI is instance-agnostic (no hard-coded example); \`init\`/\`upgrade\` are reachable subcommands.`,
|
|
102
102
|
kind: 'feature', discipline: 'engineer', priority: 3,
|
|
@@ -28,7 +28,7 @@ const H = { Authorization: `Bearer ${TOKEN}`, 'Content-Type': 'application/json'
|
|
|
28
28
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
29
29
|
async function api(method, path, body, _tries = 0) {
|
|
30
30
|
await sleep(400); // base throttle to stay under the per-IP rate limit
|
|
31
|
-
const res = await fetch(`${BASE}/api/
|
|
31
|
+
const res = await fetch(`${BASE}/api/bongos${path}`, {
|
|
32
32
|
method, headers: H, body: body ? JSON.stringify(body) : undefined,
|
|
33
33
|
});
|
|
34
34
|
const text = await res.text();
|
|
@@ -16,7 +16,7 @@ const H = { Authorization: `Bearer ${TOKEN}`, 'Content-Type': 'application/json'
|
|
|
16
16
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
17
17
|
async function api(method, path, body, _tries = 0) {
|
|
18
18
|
await sleep(400); // base throttle to stay under the per-IP rate limit
|
|
19
|
-
const res = await fetch(`${BASE}/api/
|
|
19
|
+
const res = await fetch(`${BASE}/api/bongos${path}`, {
|
|
20
20
|
method, headers: H, body: body ? JSON.stringify(body) : undefined,
|
|
21
21
|
});
|
|
22
22
|
const text = await res.text();
|
|
@@ -20,7 +20,7 @@ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
|
20
20
|
|
|
21
21
|
async function api(method, path, body, _tries = 0) {
|
|
22
22
|
await sleep(1500);
|
|
23
|
-
const r = await apiCall(method, `/api/
|
|
23
|
+
const r = await apiCall(method, `/api/bongos${path}`, body);
|
|
24
24
|
if (r.status === 429 && _tries < 8) {
|
|
25
25
|
const wait = (r.data?.error?.details?.retry_after_seconds || 30) + 1;
|
|
26
26
|
console.log(` …rate-limited, waiting ${wait}s`);
|
|
@@ -24,7 +24,7 @@ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
|
24
24
|
// Throttled + 429-aware wrapper (same shape as the sibling seeders).
|
|
25
25
|
async function api(method, path, body, _tries = 0) {
|
|
26
26
|
await sleep(1500);
|
|
27
|
-
const r = await apiCall(method, `/api/
|
|
27
|
+
const r = await apiCall(method, `/api/bongos${path}`, body);
|
|
28
28
|
if (r.status === 429 && _tries < 8) {
|
|
29
29
|
const wait = (r.data?.error?.details?.retry_after_seconds || 30) + 1;
|
|
30
30
|
console.log(` …rate-limited, waiting ${wait}s`);
|
|
@@ -33,7 +33,7 @@ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
|
33
33
|
// is exactly the shape the per-IP limiter is there to catch.
|
|
34
34
|
async function api(method, path, body, _tries = 0) {
|
|
35
35
|
await sleep(400);
|
|
36
|
-
const r = await apiCall(method, `/api/
|
|
36
|
+
const r = await apiCall(method, `/api/bongos${path}`, body);
|
|
37
37
|
if (r.status === 429 && _tries < 8) {
|
|
38
38
|
const wait = (r.data?.error?.details?.retry_after_seconds || 30) + 1;
|
|
39
39
|
console.log(` …rate-limited, waiting ${wait}s`);
|
|
@@ -24,7 +24,7 @@ const H = { Authorization: `Bearer ${TOKEN}`, 'Content-Type': 'application/json'
|
|
|
24
24
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
25
25
|
async function api(method, path, body, _tries = 0) {
|
|
26
26
|
await sleep(400); // base throttle to stay under the per-IP rate limit
|
|
27
|
-
const res = await fetch(`${BASE}/api/
|
|
27
|
+
const res = await fetch(`${BASE}/api/bongos${path}`, {
|
|
28
28
|
method, headers: H, body: body ? JSON.stringify(body) : undefined,
|
|
29
29
|
});
|
|
30
30
|
const text = await res.text();
|
|
@@ -29,7 +29,7 @@ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
|
29
29
|
// Throttled + 429-aware wrapper (same shape as the sibling seeders).
|
|
30
30
|
async function api(method, path, body, _tries = 0) {
|
|
31
31
|
await sleep(1500);
|
|
32
|
-
const r = await apiCall(method, `/api/
|
|
32
|
+
const r = await apiCall(method, `/api/bongos${path}`, body);
|
|
33
33
|
if (r.status === 429 && _tries < 8) {
|
|
34
34
|
const wait = (r.data?.error?.details?.retry_after_seconds || 30) + 1;
|
|
35
35
|
console.log(` …rate-limited, waiting ${wait}s`);
|
|
@@ -162,7 +162,7 @@ Nightly sweep (systemd timer modeled on gds-db-backup) indexing: tasks.descripti
|
|
|
162
162
|
},
|
|
163
163
|
{
|
|
164
164
|
ref: 'R11',
|
|
165
|
-
title: 'POST /api/
|
|
165
|
+
title: 'POST /api/bongos/search — lexical hybrid (FTS + trgm) fused with RRF',
|
|
166
166
|
description: `**Criterion:** one-call-recall. Cross-ref: V4.R06.
|
|
167
167
|
|
|
168
168
|
requireBuilder-gated search endpoint: websearch_to_tsquery leg + pg_trgm leg fused with Reciprocal Rank Fusion in one SQL CTE; k, filters (source_type, track), source citations in results. Per-builder read limiter (memory.js pattern — the global limiter doesn't cap GETs). Add to smoke-gds.js CHECKS (401 unauth).
|
|
@@ -202,7 +202,7 @@ The #1 tool-error class (84 hits): edits/git ops landing in the wrong tree. Add
|
|
|
202
202
|
title: 'JSON 404 + hint on API-shaped paths; promote-hint on TASK_NOT_READY 409',
|
|
203
203
|
description: `**Criterion:** machine-room-ergonomics.
|
|
204
204
|
|
|
205
|
-
Two self-describing-error fixes: (1) requests to API-shaped paths (/tasks, /gds/*, /api/*) that miss the /api/
|
|
205
|
+
Two self-describing-error fixes: (1) requests to API-shaped paths (/tasks, /gds/*, /api/*) that miss the /api/bongos mount get a JSON 404 with a hint instead of the HTML island page (which today causes a secondary JSON.parse fault); (2) the TASK_NOT_READY 409 names the promote endpoint.
|
|
206
206
|
|
|
207
207
|
**Done when:** both error shapes verified by tests; smoke unaffected.`,
|
|
208
208
|
kind: 'feature', discipline: 'engineering', priority: 4,
|
|
@@ -238,7 +238,7 @@ tests/grader_panel.mjs fails 2/7 on a clean baseline (noted in the 2026-06-08 se
|
|
|
238
238
|
title: '/recall skill — one-call project-knowledge search from any session',
|
|
239
239
|
description: `**Criterion:** one-call-recall. Cross-refs: V4.R11, V4.R12.
|
|
240
240
|
|
|
241
|
-
New slash skill wrapping POST /api/
|
|
241
|
+
New slash skill wrapping POST /api/bongos/search via the cross-platform scripts/gds/api.js: query in, cited sources out, with guidance to follow up by reading the real source. Works identically on laptop, dev box, and browser-only sessions.
|
|
242
242
|
|
|
243
243
|
**Done when:** skill shipped + documented in CLAUDE.md quick-nav; round-trip verified against prod.`,
|
|
244
244
|
kind: 'feature', discipline: 'engineering', priority: 4,
|
|
@@ -56,7 +56,7 @@ Locks: the exact GDS/game boundary; the per-instance branding-contract schema (c
|
|
|
56
56
|
|
|
57
57
|
A Medusa-only boot (sibling to src/preview-server.js) that builds the Express app, mounts buildGdsRouter() + public-builders/ + public-status/, and constructs NO Colyseus game server and NO Phaser/tile static mounts. The existing game boot (server.js) stays untouched.
|
|
58
58
|
|
|
59
|
-
**Done when:** a smoke test boots Medusa, reaches /api/
|
|
59
|
+
**Done when:** a smoke test boots Medusa, reaches /api/bongos/health + the hall, and asserts no game route/asset is reachable in the process.`,
|
|
60
60
|
kind: 'infra', discipline: 'engineer', priority: 5,
|
|
61
61
|
est_minutes: 240, manual_degree: 2, credits_reward: 40,
|
|
62
62
|
touches: ['server.js', 'src/'], criteria: ['C8'], deps: ['R50'],
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// clean" -> C32.
|
|
12
12
|
//
|
|
13
13
|
// Shape mirrors seed-bongos-tasks.js exactly:
|
|
14
|
-
// - POST /api/
|
|
14
|
+
// - POST /api/bongos/tasks { version_id:'BONGOS-V1', criterion_ids:['C32'], ... }
|
|
15
15
|
// - idempotent on source_ref (skips already-created)
|
|
16
16
|
// - display BV1.R## assigned dynamically after the current max (decorative)
|
|
17
17
|
//
|
|
@@ -15,7 +15,7 @@ const SRC = 'planning-session';
|
|
|
15
15
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
16
16
|
async function api(method, path, body, _tries = 0) {
|
|
17
17
|
await sleep(400); // base throttle to stay under the per-IP rate limit
|
|
18
|
-
const r = await apiCall(method, `/api/
|
|
18
|
+
const r = await apiCall(method, `/api/bongos${path}`, body);
|
|
19
19
|
const json = r.data || {};
|
|
20
20
|
if (r.status === 429 && _tries < 8) {
|
|
21
21
|
const wait = ((json.error && json.error.details && json.error.details.retry_after_seconds) || 30) + 1;
|
|
@@ -62,7 +62,7 @@ async function post(path, body) {
|
|
|
62
62
|
est_minutes: t.est, goal_id: GOAL,
|
|
63
63
|
source: 'planning', source_ref: `BONGOS-V1-prov-${t.ref}`,
|
|
64
64
|
};
|
|
65
|
-
const { status, json } = await post('/api/
|
|
65
|
+
const { status, json } = await post('/api/bongos/tasks', body);
|
|
66
66
|
const id = json.id || (json.task && json.task.id);
|
|
67
67
|
if (!id) { console.log(` ${t.ref}: CREATE FAILED — ${status} ${JSON.stringify(json).slice(0, 160)}`); continue; }
|
|
68
68
|
idByRef[t.ref] = id;
|
|
@@ -75,7 +75,7 @@ async function post(path, body) {
|
|
|
75
75
|
if (!id) continue;
|
|
76
76
|
const allDeps = [...t.deps.map((d) => idByRef[d]).filter(Boolean), ...t.extDeps];
|
|
77
77
|
for (const depId of allDeps) {
|
|
78
|
-
const { status, json } = await post(`/api/
|
|
78
|
+
const { status, json } = await post(`/api/bongos/tasks/${id}/dependencies`, { depends_on_task_id: depId });
|
|
79
79
|
console.log(` ${t.ref}(${id}) depends on ${depId} -> ${status === 200 || status === 201 ? 'ok' : (json.error || status)}`);
|
|
80
80
|
}
|
|
81
81
|
}
|
|
@@ -244,7 +244,7 @@ async function main() {
|
|
|
244
244
|
source_ref: `${PREFIX}-${t.ref}`,
|
|
245
245
|
criterion_ids: t.criteria,
|
|
246
246
|
};
|
|
247
|
-
const r = await throttledWrite('POST', '/api/
|
|
247
|
+
const r = await throttledWrite('POST', '/api/bongos/tasks', body);
|
|
248
248
|
const id = r.json?.task?.id;
|
|
249
249
|
if (!id) throw new Error(`No task id back for ${t.ref} (status ${r.status}): ${JSON.stringify(r.json)}`);
|
|
250
250
|
ids[t.ref] = id;
|
|
@@ -256,7 +256,7 @@ async function main() {
|
|
|
256
256
|
for (const t of TASKS) {
|
|
257
257
|
for (const dep of t.deps) {
|
|
258
258
|
if (!ids[dep]) throw new Error(`${t.ref} depends on unknown ref ${dep}`);
|
|
259
|
-
const r = await throttledWrite('POST', `/api/
|
|
259
|
+
const r = await throttledWrite('POST', `/api/bongos/tasks/${ids[t.ref]}/dependencies`, { depends_on_task_id: ids[dep] });
|
|
260
260
|
console.log(` ${t.ref} depends on ${dep} (${ids[dep]}) ${r.status}`);
|
|
261
261
|
}
|
|
262
262
|
}
|
|
@@ -265,7 +265,7 @@ async function main() {
|
|
|
265
265
|
await verifySeedCriteriaLinks({
|
|
266
266
|
goalId: GOAL,
|
|
267
267
|
expectedCounts: expectedCriterionCounts(planned),
|
|
268
|
-
fetchGoal: (goalId) => api('GET', `/api/
|
|
268
|
+
fetchGoal: (goalId) => api('GET', `/api/bongos/goals/${goalId}`),
|
|
269
269
|
});
|
|
270
270
|
|
|
271
271
|
console.log('\nSeed complete. Task ids:');
|
|
@@ -187,8 +187,8 @@ const TASKS = [
|
|
|
187
187
|
credits_reward: 40, module_key: 'game', requires_rank: 'metic',
|
|
188
188
|
criterion_ids: ['map-editor'], depends_on_refs: ['ED2', 'E4'] },
|
|
189
189
|
|
|
190
|
-
{ ref: 'ED4', version: 'V3', title: 'V3.W06 — save: rank-gated POST /api/
|
|
191
|
-
description: 'Save maps back to the game: rank-gated `POST /api/
|
|
190
|
+
{ ref: 'ED4', version: 'V3', title: 'V3.W06 — save: rank-gated POST /api/bongos/maps/:id validated by mapFormat',
|
|
191
|
+
description: 'Save maps back to the game: rank-gated `POST /api/bongos/maps/:id`, validated by `mapFormat`, persisted per the S3 (V3.W02) save-model spike. Depends on ED3 (V3.W05) + S3 (V3.W02). Criterion map-editor.',
|
|
192
192
|
kind: 'feature', discipline: 'engineer', priority: 2, est_minutes: 180, manual_degree: 3,
|
|
193
193
|
credits_reward: 30, module_key: 'game', requires_rank: 'metic',
|
|
194
194
|
criterion_ids: ['map-editor'], depends_on_refs: ['ED3', 'S3'] },
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// success; only a manual GET /goals rollup caught it, after the fact). A seed
|
|
6
6
|
// script tallies the criterion_ids it actually POSTed per task into its own
|
|
7
7
|
// plan, then calls verifySeedCriteriaLinks() as its LAST step to fetch
|
|
8
|
-
// GET /api/
|
|
8
|
+
// GET /api/bongos/goals/<id> and diff `criteria[].linked_tasks` against that
|
|
9
9
|
// plan — loud and non-zero-exit on any mismatch, zero included.
|
|
10
10
|
//
|
|
11
11
|
// Transport-agnostic on purpose: seed scripts don't share one HTTP client
|