@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
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// scripts/gds/session-digest.js — BFG 6D session capture on the SessionEnd seam
|
|
3
3
|
// (ADR 0027; follow-up to #608/#617, idea #178).
|
|
4
4
|
//
|
|
5
|
-
// Uploads the FULL session digest to the BFG corpus (POST /api/
|
|
5
|
+
// Uploads the FULL session digest to the BFG corpus (POST /api/bongos/sessions)
|
|
6
6
|
// when a Claude Code session ENDS. Wired as a SessionEnd hook in
|
|
7
7
|
// .claude/settings.json (sibling to session-cost.js), which pipes
|
|
8
8
|
// { session_id, transcript_path, cwd, reason } as JSON on stdin.
|
package/scripts/gds/session.js
CHANGED
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
// --all show the long-tail (everything else that's claimable)
|
|
12
12
|
// --json machine-readable output
|
|
13
13
|
//
|
|
14
|
-
// Calls POST /api/
|
|
15
|
-
// GET /api/
|
|
14
|
+
// Calls POST /api/bongos/session/optimize when available; falls back to
|
|
15
|
+
// GET /api/bongos/tasks/claimable + a deterministic local greedy when the
|
|
16
16
|
// endpoint isn't deployed yet (P1 #44 ships it in parallel; P2 #45 the
|
|
17
17
|
// batch-claim endpoint is also not in flight). The fallback uses the same
|
|
18
18
|
// scoring rules so the recommendation set is stable either way.
|
package/scripts/gds/setup.js
CHANGED
|
@@ -286,7 +286,7 @@ const { isDeviceFlowDisabled, deviceFlowFallbackLines } = require('./device-flow
|
|
|
286
286
|
async function redeemCliToken(token) {
|
|
287
287
|
let res;
|
|
288
288
|
try {
|
|
289
|
-
res = await fetch(`${API_BASE}/api/
|
|
289
|
+
res = await fetch(`${API_BASE}/api/bongos/me`, { headers: { Authorization: `Bearer ${token}` } });
|
|
290
290
|
} catch (err) {
|
|
291
291
|
console.error(`Could not reach ${API_BASE}: ${err.message}`);
|
|
292
292
|
return { ok: false, status: 0 };
|
|
@@ -392,7 +392,7 @@ async function main() {
|
|
|
392
392
|
console.log('');
|
|
393
393
|
const preExisting = await loadSession();
|
|
394
394
|
if (preExisting && preExisting.token && !forceFlag) {
|
|
395
|
-
dryRunStep(`Would verify existing session at ${SESSION_PATH} via GET /api/
|
|
395
|
+
dryRunStep(`Would verify existing session at ${SESSION_PATH} via GET /api/bongos/me.`);
|
|
396
396
|
dryRunStep('If the token is valid: on an interactive shell, would ASK whether to continue as that builder or set up as a different one ([1] continue / [2] sign in again, replacing the saved session). Non-interactive shells keep the existing session. (--force skips the question and re-auths directly.)');
|
|
397
397
|
dryRunStep('If the token is rejected (401), would fall through to the Device Flow.');
|
|
398
398
|
} else if (preExisting && forceFlag) {
|
|
@@ -400,17 +400,17 @@ async function main() {
|
|
|
400
400
|
} else {
|
|
401
401
|
dryRunStep(`No existing session at ${SESSION_PATH}; would proceed straight to Device Flow.`);
|
|
402
402
|
}
|
|
403
|
-
dryRunStep('Would POST /api/
|
|
403
|
+
dryRunStep('Would POST /api/bongos/auth/device/start to get a user_code + verification_uri from GitHub.');
|
|
404
404
|
dryRunStep('If GitHub refuses with device_flow_disabled (a one-click App whose checkbox is unticked, task 1003051): would print the web sign-in guidance (hall Settings → CLI Access) and prompt for a pasted CLI token instead of dead-ending.');
|
|
405
|
-
dryRunStep('Would print the verification_uri and user_code, then poll /api/
|
|
405
|
+
dryRunStep('Would print the verification_uri and user_code, then poll /api/bongos/auth/device/poll every few seconds until the user approves or the code expires.');
|
|
406
406
|
dryRunStep(`On approval, would write the bearer token + builder profile to ${SESSION_PATH} (chmod 600).`);
|
|
407
407
|
if (SKIP_KEYS) {
|
|
408
408
|
dryRunStep('Would skip the Gemini-key prompt (--skip-keys set).');
|
|
409
409
|
} else {
|
|
410
410
|
dryRunStep(`Would prompt for a per-builder GOOGLE_AI_STUDIO_KEY on TTY shells and store it as gemini_api_key in ${SESSION_PATH} (mode 600). Used by modules/art-pipeline/pipeline/gen_api.py for per-builder cost attribution.`);
|
|
411
411
|
}
|
|
412
|
-
dryRunStep('Would read ~/.claude.json oauthAccount and, on a TTY, prompt to confirm the Anthropic email; on a match would POST /api/
|
|
413
|
-
dryRunStep('Would prompt for preferred disciplines (creative / engineering / both / skip) and PATCH /api/
|
|
412
|
+
dryRunStep('Would read ~/.claude.json oauthAccount and, on a TTY, prompt to confirm the Anthropic email; on a match would POST /api/bongos/me/anthropic-link and store anthropic_user_id in the session (kept as cosmetic attribution; the identity pin was removed — task 1039 / idea 258). On mismatch would REFUSE to link.');
|
|
413
|
+
dryRunStep('Would prompt for preferred disciplines (creative / engineering / both / skip) and PATCH /api/bongos/me/disciplines on TTY shells.');
|
|
414
414
|
dryRunStep(`Would prompt for onboarding-friction consent (Y/n) and record the decision to ${onboardingConfig.CONSENT_PATH} on TTY shells.`);
|
|
415
415
|
dryRunStep('Would print "Authenticated as <github_login>" and exit 0.');
|
|
416
416
|
process.exit(0);
|
|
@@ -503,7 +503,7 @@ async function main() {
|
|
|
503
503
|
// GitHub device flow below (auth.idp unset) is untouched — the self-hosted default.
|
|
504
504
|
let idpCfg = null;
|
|
505
505
|
try {
|
|
506
|
-
const m = await fetch(`${API_BASE}/api/
|
|
506
|
+
const m = await fetch(`${API_BASE}/api/bongos/instance`);
|
|
507
507
|
const mj = m.ok ? await m.json() : null;
|
|
508
508
|
idpCfg = (mj && mj.auth && mj.auth.idp) || null;
|
|
509
509
|
} catch (_) { /* manifest unreachable → fall through to the direct flow */ }
|
package/scripts/gds/ship-flow.js
CHANGED
|
@@ -563,7 +563,7 @@ async function shipMain() {
|
|
|
563
563
|
console.error(' grade fails, fix its findings and re-run (unlimited, no attempt cap):');
|
|
564
564
|
console.error(` node scripts/gds/ship.js ${taskId} --regrade`);
|
|
565
565
|
console.error(` If the grade genuinely cannot pass, ask a builder whose role holds`);
|
|
566
|
-
console.error(` task.confirm.grade_bypass${floorNote} to POST /api/
|
|
566
|
+
console.error(` task.confirm.grade_bypass${floorNote} to POST /api/bongos/tasks/${taskId}/confirm.`);
|
|
567
567
|
process.exit(1);
|
|
568
568
|
}
|
|
569
569
|
console.error(`manual-confirm failed: ${apiErrorLine(confirm.data, confirm.status)}`);
|
|
@@ -601,7 +601,7 @@ async function shipMain() {
|
|
|
601
601
|
console.error('Task stays at completed. Manual options:');
|
|
602
602
|
console.error(` - Re-run /builder-ship ${taskId} to try grading again, or`);
|
|
603
603
|
console.error(` - node scripts/gds/ship.js ${taskId} --regrade after fixing findings, or`);
|
|
604
|
-
console.error(` - POST /api/
|
|
604
|
+
console.error(` - POST /api/bongos/tasks/${taskId}/confirm to manual-confirm (last resort —`);
|
|
605
605
|
console.error(' permission-gated on task.confirm.grade_bypass).');
|
|
606
606
|
process.exit(1);
|
|
607
607
|
}
|
|
@@ -896,7 +896,7 @@ async function regradeMain() {
|
|
|
896
896
|
console.error('');
|
|
897
897
|
console.error(`✖ Confirming without a passing grade is permission-gated: task.confirm.grade_bypass${floor ? ` (floor: ${floor})` : ''}.`);
|
|
898
898
|
console.error(' This is an authorization wall, not a verdict on your work.');
|
|
899
|
-
console.error(` Ask a builder whose role holds it to POST /api/
|
|
899
|
+
console.error(` Ask a builder whose role holds it to POST /api/bongos/tasks/${taskId}/confirm.`);
|
|
900
900
|
process.exit(1);
|
|
901
901
|
}
|
|
902
902
|
console.error(`manual-confirm failed: ${apiErrorLine(confirm.data, confirm.status)}`);
|
|
@@ -293,7 +293,7 @@ function formatGradeOutcome(g, taskId, cliFinding = null) {
|
|
|
293
293
|
out.push('When the grader is reachable again, re-grade:');
|
|
294
294
|
out.push(` node scripts/gds/ship.js ${taskId} --regrade`);
|
|
295
295
|
out.push('Or land it now via manual-confirm:');
|
|
296
|
-
out.push(` curl -X POST -H "Authorization: Bearer <token>" ${resolveInstanceBase() || '<instance-origin>'}/api/
|
|
296
|
+
out.push(` curl -X POST -H "Authorization: Bearer <token>" ${resolveInstanceBase() || '<instance-origin>'}/api/bongos/tasks/${taskId}/confirm`);
|
|
297
297
|
return out.join('\n');
|
|
298
298
|
}
|
|
299
299
|
|
|
@@ -350,7 +350,7 @@ function formatGradeOutcome(g, taskId, cliFinding = null) {
|
|
|
350
350
|
out.push('When the grader is healthy again, re-grade:');
|
|
351
351
|
out.push(` node scripts/gds/ship.js ${taskId} --regrade`);
|
|
352
352
|
out.push('Or land it now via manual-confirm:');
|
|
353
|
-
out.push(` curl -X POST -H "Authorization: Bearer <token>" ${resolveInstanceBase() || '<instance-origin>'}/api/
|
|
353
|
+
out.push(` curl -X POST -H "Authorization: Bearer <token>" ${resolveInstanceBase() || '<instance-origin>'}/api/bongos/tasks/${taskId}/confirm`);
|
|
354
354
|
return out.join('\n');
|
|
355
355
|
}
|
|
356
356
|
|
|
@@ -377,7 +377,7 @@ function formatGradeOutcome(g, taskId, cliFinding = null) {
|
|
|
377
377
|
out.push('Grade failed — task stays at completed. Fix the issues above, commit, then re-grade:');
|
|
378
378
|
out.push(` node scripts/gds/ship.js ${taskId} --regrade`);
|
|
379
379
|
out.push('Last resort (only if the grade was wrong):');
|
|
380
|
-
out.push(` curl -X POST -H "Authorization: Bearer <token>" ${resolveInstanceBase() || '<instance-origin>'}/api/
|
|
380
|
+
out.push(` curl -X POST -H "Authorization: Bearer <token>" ${resolveInstanceBase() || '<instance-origin>'}/api/bongos/tasks/${taskId}/confirm`);
|
|
381
381
|
}
|
|
382
382
|
return out.join('\n');
|
|
383
383
|
}
|
|
@@ -17,7 +17,7 @@ const { REPO_ROOT } = require('./ship-state.js');
|
|
|
17
17
|
// ---------- Memory sync-on-ship (Task #274 / V3.R55) ----------
|
|
18
18
|
//
|
|
19
19
|
// After a successful ship, push the builder's local Claude Code memory dir to
|
|
20
|
-
// the server (POST /api/
|
|
20
|
+
// the server (POST /api/bongos/memory/sync), so a builder's MEMORY.md +
|
|
21
21
|
// feedback_*.md follow them across machines and survive a dead laptop. This is
|
|
22
22
|
// the push half of ADR 0024's cloneable-memory chain; #275 wires the pull side.
|
|
23
23
|
//
|
|
@@ -18,7 +18,7 @@ const { REPO_ROOT } = require('./ship-state.js');
|
|
|
18
18
|
// ---------- Session upload-on-ship (6D.1 / ADR 0027) ----------
|
|
19
19
|
//
|
|
20
20
|
// After a successful ship, upload a COMPACT, secret-scrubbed digest of this
|
|
21
|
-
// Claude Code session (POST /api/
|
|
21
|
+
// Claude Code session (POST /api/bongos/sessions), so the BFG (a local Claude Code
|
|
22
22
|
// routine — 6D.3) can later search the corpus (6D.2) and deep-dive the wasteful
|
|
23
23
|
// sessions. We never upload raw transcript CONTENT — only per-turn metadata
|
|
24
24
|
// (role, tool name, error flag, token usage, length) + short scrubbed snippets
|
|
@@ -277,14 +277,14 @@ async function uploadSessionOnShip(taskId) {
|
|
|
277
277
|
recordUploadSkip(taskId, {
|
|
278
278
|
code: 'session_invalid',
|
|
279
279
|
reason:
|
|
280
|
-
'POST /api/
|
|
280
|
+
'POST /api/bongos/sessions returned 401 — the GDS session token is missing or invalid, so the ' +
|
|
281
281
|
'digest was rejected. Re-auth with /builder-reauth. This ship will NOT appear in the BFG session corpus.',
|
|
282
282
|
});
|
|
283
283
|
} else {
|
|
284
284
|
recordUploadSkip(taskId, {
|
|
285
285
|
code: `http_${r.status}`,
|
|
286
286
|
reason:
|
|
287
|
-
`POST /api/
|
|
287
|
+
`POST /api/bongos/sessions returned ${r.status}${r.data && r.data.error ? ` (${apiErrorLine(r.data)})` : ''} — ` +
|
|
288
288
|
'the API rejected or could not store the digest. This ship will NOT appear in the BFG session corpus.',
|
|
289
289
|
});
|
|
290
290
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# GDS batch-claim smoke test. Renamed from PMS in V3.R01.
|
|
3
3
|
#
|
|
4
|
-
# Exercises POST /api/
|
|
4
|
+
# Exercises POST /api/bongos/claims/batch:
|
|
5
5
|
# Case A: 2 ready tasks, disjoint touches → 201, 2 claim rows.
|
|
6
6
|
# Case B: 2 ready tasks, OVERLAPPING touches → 409, BATCH_TOUCHES_CONFLICT,
|
|
7
7
|
# no claims persisted (both tasks stay 'ready').
|
|
@@ -70,7 +70,7 @@ print(json.dumps({
|
|
|
70
70
|
'source': 'smoke',
|
|
71
71
|
'source_ref': '${ts}-${suffix}'
|
|
72
72
|
}))")
|
|
73
|
-
parse_call "$(call POST /api/
|
|
73
|
+
parse_call "$(call POST /api/bongos/tasks "${body}")"
|
|
74
74
|
python3 -c "import json,sys; print(json.loads('''${PAYLOAD}''')['task']['id'])"
|
|
75
75
|
}
|
|
76
76
|
|
|
@@ -83,7 +83,7 @@ cleanup() {
|
|
|
83
83
|
echo "--- cleanup ---"
|
|
84
84
|
for cid in "${CREATED_CLAIMS[@]:-}"; do
|
|
85
85
|
[[ -z "${cid}" ]] && continue
|
|
86
|
-
call POST "/api/
|
|
86
|
+
call POST "/api/bongos/claims/${cid}/resolve" \
|
|
87
87
|
'{"outcome":"abandoned","notes_md":"smoke cleanup"}' >/dev/null || true
|
|
88
88
|
done
|
|
89
89
|
for tid in "${CREATED_TASKS[@]:-}"; do
|
|
@@ -94,7 +94,7 @@ cleanup() {
|
|
|
94
94
|
# failure. Every run since has leaked its fixtures as status='ready'
|
|
95
95
|
# (the 2026-05-11 batch, then 1001920-1001925 from 2026-07-03). The real
|
|
96
96
|
# endpoint is POST /tasks/:id/abandon {"reason": ...}.
|
|
97
|
-
if ! call POST "/api/
|
|
97
|
+
if ! call POST "/api/bongos/tasks/${tid}/abandon" \
|
|
98
98
|
'{"reason":"smoke cleanup (scripts/gds/smoke-batch-claim.sh)"}' >/dev/null 2>&1; then
|
|
99
99
|
leaked+=("${tid}")
|
|
100
100
|
fi
|
|
@@ -127,7 +127,7 @@ CREATED_TASKS+=("${TA1}" "${TA2}")
|
|
|
127
127
|
echo " created tasks ${TA1}, ${TA2}"
|
|
128
128
|
|
|
129
129
|
BODY_A=$(python3 -c "import json; print(json.dumps({'task_ids':[${TA1},${TA2}],'worktree_name':'__smoke_batch__'}))")
|
|
130
|
-
parse_call "$(call POST /api/
|
|
130
|
+
parse_call "$(call POST /api/bongos/claims/batch "${BODY_A}")"
|
|
131
131
|
if [[ "${CODE}" == "201" ]]; then
|
|
132
132
|
N=$(python3 -c "import json,sys; print(len(json.loads('''${PAYLOAD}''')['claims']))")
|
|
133
133
|
if [[ "${N}" == "2" ]]; then
|
|
@@ -154,7 +154,7 @@ CREATED_TASKS+=("${TB1}" "${TB2}")
|
|
|
154
154
|
echo " created tasks ${TB1}, ${TB2} (both touch __smoke__/batch/${ts}/shared)"
|
|
155
155
|
|
|
156
156
|
BODY_B=$(python3 -c "import json; print(json.dumps({'task_ids':[${TB1},${TB2}]}))")
|
|
157
|
-
parse_call "$(call POST /api/
|
|
157
|
+
parse_call "$(call POST /api/bongos/claims/batch "${BODY_B}")"
|
|
158
158
|
if [[ "${CODE}" == "409" ]]; then
|
|
159
159
|
REASON=$(python3 -c "
|
|
160
160
|
import json,sys
|
|
@@ -170,7 +170,7 @@ print(','.join(reasons))
|
|
|
170
170
|
fi
|
|
171
171
|
# Confirm neither task got claimed (status still 'ready').
|
|
172
172
|
for tid in "${TB1}" "${TB2}"; do
|
|
173
|
-
parse_call "$(call GET "/api/
|
|
173
|
+
parse_call "$(call GET "/api/bongos/tasks/${tid}")"
|
|
174
174
|
S=$(python3 -c "import json,sys; print(json.loads('''${PAYLOAD}''')['task']['status'])")
|
|
175
175
|
if [[ "${S}" == "ready" ]]; then
|
|
176
176
|
ok "B: task #${tid} stayed 'ready' (rollback worked)"
|
|
@@ -191,7 +191,7 @@ CREATED_TASKS+=("${TC1}" "${TC2}")
|
|
|
191
191
|
echo " created tasks ${TC1} (will pre-claim), ${TC2} (still ready)"
|
|
192
192
|
|
|
193
193
|
# Pre-claim TC1 via the single-claim path so it's already 'active'.
|
|
194
|
-
parse_call "$(call POST /api/
|
|
194
|
+
parse_call "$(call POST /api/bongos/claims "{\"task_id\":${TC1}}")"
|
|
195
195
|
if [[ "${CODE}" == "201" ]]; then
|
|
196
196
|
PRE_CLAIM_ID=$(python3 -c "import json,sys; print(json.loads('''${PAYLOAD}''')['claim']['id'])")
|
|
197
197
|
CREATED_CLAIMS+=("${PRE_CLAIM_ID}")
|
|
@@ -201,7 +201,7 @@ else
|
|
|
201
201
|
fi
|
|
202
202
|
|
|
203
203
|
BODY_C=$(python3 -c "import json; print(json.dumps({'task_ids':[${TC1},${TC2}]}))")
|
|
204
|
-
parse_call "$(call POST /api/
|
|
204
|
+
parse_call "$(call POST /api/bongos/claims/batch "${BODY_C}")"
|
|
205
205
|
if [[ "${CODE}" == "409" ]]; then
|
|
206
206
|
ENUM=$(python3 -c "
|
|
207
207
|
import json,sys
|
|
@@ -217,7 +217,7 @@ print(','.join(str(i) for i in ids))
|
|
|
217
217
|
bad "C: 409 but failures[] missing #${TC1} (got: ${ENUM})"
|
|
218
218
|
fi
|
|
219
219
|
# Confirm TC2 stayed 'ready' (no partial commit).
|
|
220
|
-
parse_call "$(call GET "/api/
|
|
220
|
+
parse_call "$(call GET "/api/bongos/tasks/${TC2}")"
|
|
221
221
|
S=$(python3 -c "import json,sys; print(json.loads('''${PAYLOAD}''')['task']['status'])")
|
|
222
222
|
if [[ "${S}" == "ready" ]]; then
|
|
223
223
|
ok "C: task #${TC2} stayed 'ready' (no partial commit)"
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# GDS batch-release + dry-run-validate smoke test (task 1758).
|
|
3
3
|
#
|
|
4
|
-
# Exercises POST /api/
|
|
4
|
+
# Exercises POST /api/bongos/claims/batch/release:
|
|
5
5
|
# Case A: 2 own active claims → 200, both in released[], both tasks 'ready'.
|
|
6
6
|
# Case B: 1 own active claim + 1 bogus claim id → 200 (NOT all-or-nothing —
|
|
7
7
|
# the batch has no cross-claim invariant), the good one released,
|
|
8
8
|
# the bad one enumerated in failures[] with CLAIM_NOT_FOUND.
|
|
9
9
|
#
|
|
10
|
-
# Exercises POST /api/
|
|
10
|
+
# Exercises POST /api/bongos/claims/batch/validate:
|
|
11
11
|
# Case C: 2 ready tasks, disjoint touches → parallel_safe:true, both valid.
|
|
12
12
|
# Case D: 2 ready tasks, OVERLAPPING touches → parallel_safe:false, both
|
|
13
13
|
# marked invalid (BATCH_TOUCHES_CONFLICT) — and, since this is a
|
|
@@ -76,7 +76,7 @@ print(json.dumps({
|
|
|
76
76
|
'source': 'smoke',
|
|
77
77
|
'source_ref': '${ts}-${suffix}'
|
|
78
78
|
}))")
|
|
79
|
-
parse_call "$(call POST /api/
|
|
79
|
+
parse_call "$(call POST /api/bongos/tasks "${body}")"
|
|
80
80
|
python3 -c "import json,sys; print(json.loads('''${PAYLOAD}''')['task']['id'])"
|
|
81
81
|
}
|
|
82
82
|
|
|
@@ -90,7 +90,7 @@ claim_task() {
|
|
|
90
90
|
# can hold as many of these as it needs for fixture setup (NULL sessions are
|
|
91
91
|
# explicitly excluded from the uniq_active_claim_per_session index).
|
|
92
92
|
local tid="$1"
|
|
93
|
-
parse_call "$(call POST /api/
|
|
93
|
+
parse_call "$(call POST /api/bongos/claims/batch "{\"task_ids\":[${tid}],\"bind_session\":false}")"
|
|
94
94
|
python3 -c "import json,sys; print(json.loads('''${PAYLOAD}''')['claims'][0]['id'])"
|
|
95
95
|
}
|
|
96
96
|
|
|
@@ -104,7 +104,7 @@ cleanup() {
|
|
|
104
104
|
echo "--- cleanup ---"
|
|
105
105
|
for cid in "${CREATED_CLAIMS[@]:-}"; do
|
|
106
106
|
[[ -z "${cid}" ]] && continue
|
|
107
|
-
call POST "/api/
|
|
107
|
+
call POST "/api/bongos/claims/${cid}/resolve" \
|
|
108
108
|
'{"outcome":"abandoned","notes_md":"smoke cleanup"}' >/dev/null || true
|
|
109
109
|
done
|
|
110
110
|
for tid in "${CREATED_TASKS[@]:-}"; do
|
|
@@ -112,7 +112,7 @@ cleanup() {
|
|
|
112
112
|
# task 1002856: same bug as smoke-batch-claim.sh — /tasks/:id/promote is the
|
|
113
113
|
# backlog->ready transition and ignores a status field, so this never
|
|
114
114
|
# abandoned anything and the redirect swallowed the failure.
|
|
115
|
-
if ! call POST "/api/
|
|
115
|
+
if ! call POST "/api/bongos/tasks/${tid}/abandon" \
|
|
116
116
|
'{"reason":"smoke cleanup (scripts/gds/smoke-batch-release.sh)"}' >/dev/null 2>&1; then
|
|
117
117
|
leaked+=("${tid}")
|
|
118
118
|
fi
|
|
@@ -145,7 +145,7 @@ CA2=$(claim_task "${TA2}"); CREATED_CLAIMS+=("${CA2}")
|
|
|
145
145
|
echo " claimed #${TA1}→claim ${CA1}, #${TA2}→claim ${CA2}"
|
|
146
146
|
|
|
147
147
|
BODY_A=$(python3 -c "import json; print(json.dumps({'claim_ids':[${CA1},${CA2}]}))")
|
|
148
|
-
parse_call "$(call POST /api/
|
|
148
|
+
parse_call "$(call POST /api/bongos/claims/batch/release "${BODY_A}")"
|
|
149
149
|
if [[ "${CODE}" == "200" ]]; then
|
|
150
150
|
N=$(python3 -c "import json,sys; print(len(json.loads('''${PAYLOAD}''')['released']))")
|
|
151
151
|
NF=$(python3 -c "import json,sys; print(len(json.loads('''${PAYLOAD}''')['failures']))")
|
|
@@ -159,7 +159,7 @@ else
|
|
|
159
159
|
bad "A: expected 200, got ${CODE} → ${PAYLOAD}"
|
|
160
160
|
fi
|
|
161
161
|
for tid in "${TA1}" "${TA2}"; do
|
|
162
|
-
parse_call "$(call GET "/api/
|
|
162
|
+
parse_call "$(call GET "/api/bongos/tasks/${tid}")"
|
|
163
163
|
S=$(python3 -c "import json,sys; print(json.loads('''${PAYLOAD}''')['task']['status'])")
|
|
164
164
|
if [[ "${S}" == "ready" ]]; then
|
|
165
165
|
ok "A: task #${tid} back to 'ready'"
|
|
@@ -179,7 +179,7 @@ BOGUS_CLAIM_ID=999999999
|
|
|
179
179
|
echo " claimed #${TB1}→claim ${CB1}; bogus id ${BOGUS_CLAIM_ID}"
|
|
180
180
|
|
|
181
181
|
BODY_B=$(python3 -c "import json; print(json.dumps({'claim_ids':[${CB1},${BOGUS_CLAIM_ID}]}))")
|
|
182
|
-
parse_call "$(call POST /api/
|
|
182
|
+
parse_call "$(call POST /api/bongos/claims/batch/release "${BODY_B}")"
|
|
183
183
|
if [[ "${CODE}" == "200" ]]; then
|
|
184
184
|
RELEASED_IDS=$(python3 -c "
|
|
185
185
|
import json,sys
|
|
@@ -214,7 +214,7 @@ TC1=$(mk_task C1 "__smoke__/batch-release/${ts}/c1"); CREATED_TASKS+=("${TC1}")
|
|
|
214
214
|
TC2=$(mk_task C2 "__smoke__/batch-release/${ts}/c2"); CREATED_TASKS+=("${TC2}")
|
|
215
215
|
|
|
216
216
|
BODY_C=$(python3 -c "import json; print(json.dumps({'task_ids':[${TC1},${TC2}]}))")
|
|
217
|
-
parse_call "$(call POST /api/
|
|
217
|
+
parse_call "$(call POST /api/bongos/claims/batch/validate "${BODY_C}")"
|
|
218
218
|
if [[ "${CODE}" == "200" ]]; then
|
|
219
219
|
PS=$(python3 -c "import json,sys; print(json.loads('''${PAYLOAD}''')['parallel_safe'])")
|
|
220
220
|
if [[ "${PS}" == "True" ]]; then
|
|
@@ -227,7 +227,7 @@ else
|
|
|
227
227
|
fi
|
|
228
228
|
# Dry run — confirm NOTHING got claimed.
|
|
229
229
|
for tid in "${TC1}" "${TC2}"; do
|
|
230
|
-
parse_call "$(call GET "/api/
|
|
230
|
+
parse_call "$(call GET "/api/bongos/tasks/${tid}")"
|
|
231
231
|
S=$(python3 -c "import json,sys; print(json.loads('''${PAYLOAD}''')['task']['status'])")
|
|
232
232
|
if [[ "${S}" == "ready" ]]; then
|
|
233
233
|
ok "C: task #${tid} still 'ready' (validate did not claim)"
|
|
@@ -244,7 +244,7 @@ TD2=$(mk_task D2 "__smoke__/batch-release/${ts}/shared"); CREATED_TASKS+=("${TD2
|
|
|
244
244
|
echo " created tasks ${TD1}, ${TD2} (both touch __smoke__/batch-release/${ts}/shared)"
|
|
245
245
|
|
|
246
246
|
BODY_D=$(python3 -c "import json; print(json.dumps({'task_ids':[${TD1},${TD2}]}))")
|
|
247
|
-
parse_call "$(call POST /api/
|
|
247
|
+
parse_call "$(call POST /api/bongos/claims/batch/validate "${BODY_D}")"
|
|
248
248
|
if [[ "${CODE}" == "200" ]]; then
|
|
249
249
|
PS=$(python3 -c "import json,sys; print(json.loads('''${PAYLOAD}''')['parallel_safe'])")
|
|
250
250
|
REASONS=$(python3 -c "
|
|
@@ -265,7 +265,7 @@ else
|
|
|
265
265
|
bad "D: expected 200, got ${CODE} → ${PAYLOAD}"
|
|
266
266
|
fi
|
|
267
267
|
for tid in "${TD1}" "${TD2}"; do
|
|
268
|
-
parse_call "$(call GET "/api/
|
|
268
|
+
parse_call "$(call GET "/api/bongos/tasks/${tid}")"
|
|
269
269
|
S=$(python3 -c "import json,sys; print(json.loads('''${PAYLOAD}''')['task']['status'])")
|
|
270
270
|
if [[ "${S}" == "ready" ]]; then
|
|
271
271
|
ok "D: task #${tid} still 'ready' (validate did not claim)"
|
|
@@ -283,7 +283,7 @@ CE1=$(claim_task "${TE1}"); CREATED_CLAIMS+=("${CE1}")
|
|
|
283
283
|
echo " #${TE1} pre-claimed (claim ${CE1}, now 'active'); #${TE2} stays 'ready'"
|
|
284
284
|
|
|
285
285
|
BODY_E=$(python3 -c "import json; print(json.dumps({'task_ids':[${TE1},${TE2}]}))")
|
|
286
|
-
parse_call "$(call POST /api/
|
|
286
|
+
parse_call "$(call POST /api/bongos/claims/batch/validate "${BODY_E}")"
|
|
287
287
|
if [[ "${CODE}" == "200" ]]; then
|
|
288
288
|
VALID_E1=$(python3 -c "
|
|
289
289
|
import json,sys
|
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
# 1. Create 2 disjoint __smoke__ tasks
|
|
10
10
|
# 2. Claim both as the same builder
|
|
11
11
|
# 3. Hit every consumer surface that currently exists:
|
|
12
|
-
# - GET /api/
|
|
13
|
-
# - GET /api/
|
|
12
|
+
# - GET /api/bongos/me (always present)
|
|
13
|
+
# - GET /api/bongos/builders/me (PMS-V2 P6) (capability-gated)
|
|
14
14
|
# The /builder-start and /builder-session CLIs render server data;
|
|
15
15
|
# they do not constitute independent surfaces in the sense of
|
|
16
|
-
# criterion 7 (they consume /api/
|
|
16
|
+
# criterion 7 (they consume /api/bongos/* responses). We assert at the
|
|
17
17
|
# API boundary, which is where the bug class lives.
|
|
18
18
|
# 4. Extract the ordered (task_id) sequence from each surface
|
|
19
19
|
# 5. Assert all surfaces return identical sequences
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
# which surfaces were checked vs skipped.
|
|
25
25
|
#
|
|
26
26
|
# TODO: once PMS-V2 P6 (#48 — /builders web profile) ships, the
|
|
27
|
-
# /api/
|
|
27
|
+
# /api/bongos/builders/me surface will start returning 200 and this smoke
|
|
28
28
|
# will automatically include it. No edits needed here.
|
|
29
29
|
#
|
|
30
30
|
# Usage:
|
|
@@ -101,7 +101,7 @@ print(json.dumps({
|
|
|
101
101
|
}))
|
|
102
102
|
")
|
|
103
103
|
local out
|
|
104
|
-
out=$(call POST /api/
|
|
104
|
+
out=$(call POST /api/bongos/tasks "${body}")
|
|
105
105
|
echo "${out}" | python3 -c "import json,sys; print(json.load(sys.stdin)['task']['id'])"
|
|
106
106
|
}
|
|
107
107
|
|
|
@@ -110,13 +110,13 @@ claim_task() {
|
|
|
110
110
|
local body
|
|
111
111
|
body=$(python3 -c "import json; print(json.dumps({'task_id': ${task_id}, 'worktree_name': '__smoke__'}))")
|
|
112
112
|
local out
|
|
113
|
-
out=$(call POST /api/
|
|
113
|
+
out=$(call POST /api/bongos/claims "${body}")
|
|
114
114
|
echo "${out}" | python3 -c "import json,sys; print(json.load(sys.stdin)['claim']['id'])"
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
release_claim() {
|
|
118
118
|
local claim_id="$1"
|
|
119
|
-
call POST "/api/
|
|
119
|
+
call POST "/api/bongos/claims/${claim_id}/resolve" '{"outcome":"abandoned","notes_md":"smoke cleanup"}' >/dev/null || true
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
echo "=== GDS claim-consistency smoke test ==="
|
|
@@ -168,8 +168,8 @@ checked=0
|
|
|
168
168
|
skipped=0
|
|
169
169
|
fail=0
|
|
170
170
|
|
|
171
|
-
# Surface 1: /api/
|
|
172
|
-
ME_PAYLOAD=$(call GET /api/
|
|
171
|
+
# Surface 1: /api/bongos/me — always present.
|
|
172
|
+
ME_PAYLOAD=$(call GET /api/bongos/me)
|
|
173
173
|
ME_IDS=$(extract_ids "${ME_PAYLOAD}" "[c['task_id'] for c in data.get('active_claims', [])]")
|
|
174
174
|
# Filter to just our 2 smoke task_ids in case the builder has other live claims.
|
|
175
175
|
ME_FILTERED=$(python3 -c "
|
|
@@ -177,19 +177,19 @@ ids = '${ME_IDS}'.split(',') if '${ME_IDS}' else []
|
|
|
177
177
|
keep = [x for x in ids if x in ('${TASK_A}', '${TASK_B}')]
|
|
178
178
|
print(','.join(keep))
|
|
179
179
|
")
|
|
180
|
-
echo "/api/
|
|
180
|
+
echo "/api/bongos/me -> ${ME_FILTERED}"
|
|
181
181
|
if [[ "${ME_FILTERED}" == "${EXPECTED}" ]]; then
|
|
182
|
-
echo " PASS /api/
|
|
182
|
+
echo " PASS /api/bongos/me ordering matches"
|
|
183
183
|
checked=$((checked+1))
|
|
184
184
|
else
|
|
185
|
-
echo " FAIL /api/
|
|
185
|
+
echo " FAIL /api/bongos/me ordering mismatch (expected ${EXPECTED}, got ${ME_FILTERED})"
|
|
186
186
|
fail=1
|
|
187
187
|
fi
|
|
188
188
|
|
|
189
|
-
# Surface 2: /api/
|
|
190
|
-
BUILDERS_ME_CODE=$(probe_status /api/
|
|
189
|
+
# Surface 2: /api/bongos/builders/me — PMS-V2 P6, capability-gated.
|
|
190
|
+
BUILDERS_ME_CODE=$(probe_status /api/bongos/builders/me)
|
|
191
191
|
if [[ "${BUILDERS_ME_CODE}" == "200" ]]; then
|
|
192
|
-
BME_PAYLOAD=$(call GET /api/
|
|
192
|
+
BME_PAYLOAD=$(call GET /api/bongos/builders/me)
|
|
193
193
|
# Try both common shapes: top-level active_claims, or nested under builder/profile.
|
|
194
194
|
BME_IDS=$(extract_ids "${BME_PAYLOAD}" "[c['task_id'] for c in (data.get('active_claims') or data.get('builder', {}).get('active_claims') or data.get('profile', {}).get('active_claims') or [])]")
|
|
195
195
|
BME_FILTERED=$(python3 -c "
|
|
@@ -197,16 +197,16 @@ ids = '${BME_IDS}'.split(',') if '${BME_IDS}' else []
|
|
|
197
197
|
keep = [x for x in ids if x in ('${TASK_A}', '${TASK_B}')]
|
|
198
198
|
print(','.join(keep))
|
|
199
199
|
")
|
|
200
|
-
echo "/api/
|
|
200
|
+
echo "/api/bongos/builders/me -> ${BME_FILTERED}"
|
|
201
201
|
if [[ "${BME_FILTERED}" == "${EXPECTED}" ]]; then
|
|
202
|
-
echo " PASS /api/
|
|
202
|
+
echo " PASS /api/bongos/builders/me ordering matches /api/bongos/me"
|
|
203
203
|
checked=$((checked+1))
|
|
204
204
|
else
|
|
205
|
-
echo " FAIL /api/
|
|
205
|
+
echo " FAIL /api/bongos/builders/me ordering mismatch (expected ${EXPECTED}, got ${BME_FILTERED})"
|
|
206
206
|
fail=1
|
|
207
207
|
fi
|
|
208
208
|
else
|
|
209
|
-
echo "/api/
|
|
209
|
+
echo "/api/bongos/builders/me -> HTTP ${BUILDERS_ME_CODE} (SKIP — PMS-V2 P6 not live yet)"
|
|
210
210
|
skipped=$((skipped+1))
|
|
211
211
|
fi
|
|
212
212
|
|
|
@@ -31,29 +31,29 @@ BASE="${GDS_BASE:-$(gds_api_base)}"
|
|
|
31
31
|
SUFFIX="$(date +%s)"
|
|
32
32
|
|
|
33
33
|
echo "=== 1. Create task B (depends-on target, status=ready) ==="
|
|
34
|
-
B=$(curl -sS -X POST "$BASE/api/
|
|
34
|
+
B=$(curl -sS -X POST "$BASE/api/bongos/tasks" \
|
|
35
35
|
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
|
|
36
36
|
--data "{\"version_id\":\"GDS-V3\",\"title\":\"__smoke__ dep-test B $SUFFIX\",\"description\":\"smoke\",\"status\":\"ready\",\"kind\":\"feature\",\"discipline\":\"engineering\",\"priority\":5,\"touches\":[\"smoke-dep-B-$SUFFIX/\"],\"source\":\"smoke\",\"source_ref\":\"smoke-dep-B-$SUFFIX\"}")
|
|
37
37
|
B_ID=$(echo "$B" | python3 -c "import json,sys; print(json.load(sys.stdin)['task']['id'])")
|
|
38
38
|
echo " B id=$B_ID"
|
|
39
39
|
|
|
40
40
|
echo "=== 2. Create task A (dependent, status=backlog) ==="
|
|
41
|
-
A=$(curl -sS -X POST "$BASE/api/
|
|
41
|
+
A=$(curl -sS -X POST "$BASE/api/bongos/tasks" \
|
|
42
42
|
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
|
|
43
43
|
--data "{\"version_id\":\"GDS-V3\",\"title\":\"__smoke__ dep-test A $SUFFIX\",\"description\":\"smoke\",\"status\":\"backlog\",\"kind\":\"feature\",\"discipline\":\"engineering\",\"priority\":5,\"touches\":[\"smoke-dep-A-$SUFFIX/\"],\"source\":\"smoke\",\"source_ref\":\"smoke-dep-A-$SUFFIX\"}")
|
|
44
44
|
A_ID=$(echo "$A" | python3 -c "import json,sys; print(json.load(sys.stdin)['task']['id'])")
|
|
45
45
|
echo " A id=$A_ID"
|
|
46
46
|
|
|
47
47
|
echo "=== 3. Wire A → depends_on B ==="
|
|
48
|
-
curl -sS -X POST "$BASE/api/
|
|
48
|
+
curl -sS -X POST "$BASE/api/bongos/tasks/$A_ID/dependencies" \
|
|
49
49
|
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
|
|
50
50
|
--data "{\"depends_on_task_id\": $B_ID}" | python3 -m json.tool
|
|
51
51
|
|
|
52
52
|
echo "=== 4. Manually promote A (testing claim-time gate, not auto-promote) ==="
|
|
53
|
-
curl -sS -X POST "$BASE/api/
|
|
53
|
+
curl -sS -X POST "$BASE/api/bongos/tasks/$A_ID/promote" -H "Authorization: Bearer $TOKEN" | python3 -m json.tool
|
|
54
54
|
|
|
55
55
|
echo "=== 5. Attempt claim A — MUST 409 DEPS_NOT_SHIPPED ==="
|
|
56
|
-
CLAIM_RESP=$(curl -sS -X POST "$BASE/api/
|
|
56
|
+
CLAIM_RESP=$(curl -sS -X POST "$BASE/api/bongos/claims" \
|
|
57
57
|
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
|
|
58
58
|
--data "{\"task_id\": $A_ID, \"worktree_name\": \"smoke-$SUFFIX\"}")
|
|
59
59
|
echo "$CLAIM_RESP" | python3 -m json.tool
|
|
@@ -63,14 +63,14 @@ echo "=== 6. Claim + ship B (the dep) ==="
|
|
|
63
63
|
node scripts/gds/claim.js "$B_ID" --worktree "smoke-$SUFFIX-B"
|
|
64
64
|
# Move through completed → confirmed → shipped using direct API calls (skip the
|
|
65
65
|
# scanner/grader by going straight at /resolve + /confirm + /ship)
|
|
66
|
-
curl -sS -X POST "$BASE/api/
|
|
66
|
+
curl -sS -X POST "$BASE/api/bongos/claims/by-task/$B_ID/resolve" \
|
|
67
67
|
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
|
|
68
68
|
--data '{"outcome":"completed","verification":{"passed":true,"smoke_ok":true}}' >/dev/null
|
|
69
|
-
curl -sS -X POST "$BASE/api/
|
|
70
|
-
curl -sS -X POST "$BASE/api/
|
|
69
|
+
curl -sS -X POST "$BASE/api/bongos/tasks/$B_ID/confirm" -H "Authorization: Bearer $TOKEN" >/dev/null
|
|
70
|
+
curl -sS -X POST "$BASE/api/bongos/tasks/$B_ID/ship" -H "Authorization: Bearer $TOKEN" >/dev/null
|
|
71
71
|
|
|
72
72
|
echo "=== 7. Verify A auto-promoted (status should still be 'ready' from manual step 4, or auto-flipped from backlog) ==="
|
|
73
|
-
A_STATUS=$(curl -sS -H "Authorization: Bearer $TOKEN" "$BASE/api/
|
|
73
|
+
A_STATUS=$(curl -sS -H "Authorization: Bearer $TOKEN" "$BASE/api/bongos/tasks/$A_ID" | python3 -c "import json,sys; print(json.load(sys.stdin)['task']['status'])")
|
|
74
74
|
echo " A status: $A_STATUS"
|
|
75
75
|
[ "$A_STATUS" = "ready" ] && echo " PASS" || (echo " FAIL: A not ready"; exit 1)
|
|
76
76
|
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
# Exercises the full claim → ship round-trip against the live API:
|
|
5
5
|
# 1. Read session token from ~/.config/otb/bongos-session.json (or the legacy
|
|
6
6
|
# gds-session.json / pms-session.json names, all still accepted on read)
|
|
7
|
-
# 2. POST /api/
|
|
8
|
-
# 3. POST /api/
|
|
9
|
-
# 4. POST /api/
|
|
7
|
+
# 2. POST /api/bongos/tasks → create a synthetic task titled '__smoke__ <ts>'
|
|
8
|
+
# 3. POST /api/bongos/claims → claim it
|
|
9
|
+
# 4. POST /api/bongos/claims/:id/resolve outcome=shipped
|
|
10
10
|
# 5. Validate: tasks.status flipped to 'shipped'
|
|
11
11
|
# session_logs row exists for this claim
|
|
12
12
|
# public/recent-shipped does NOT contain the smoke title
|
|
@@ -53,7 +53,7 @@ call() {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
snapshot_progress() {
|
|
56
|
-
curl -sS "${API}/api/
|
|
56
|
+
curl -sS "${API}/api/bongos/public/progress" \
|
|
57
57
|
| python3 -c "import json,sys; d=json.load(sys.stdin); print(','.join(f\"{r['version_id']}:{r['shipped_weight']}/{r['total_weight']}\" for r in d['progress']))"
|
|
58
58
|
}
|
|
59
59
|
|
|
@@ -83,7 +83,7 @@ echo "Version: ${VERSION_ID}"
|
|
|
83
83
|
# version-select.js, and node is the interpreter a Windows builder box actually
|
|
84
84
|
# has — the python3 the rest of this file depends on is frequently absent there
|
|
85
85
|
# (it is the Microsoft Store stub), so a python3 step cannot be verified locally.
|
|
86
|
-
GOAL_ID=$(call GET "/api/
|
|
86
|
+
GOAL_ID=$(call GET "/api/bongos/goals?version=${VERSION_ID}" | node -e '
|
|
87
87
|
let s = "";
|
|
88
88
|
process.stdin.on("data", (d) => { s += d; });
|
|
89
89
|
process.stdin.on("end", () => {
|
|
@@ -140,21 +140,21 @@ print(json.dumps({
|
|
|
140
140
|
'source_ref': '${ts}'
|
|
141
141
|
}))
|
|
142
142
|
")
|
|
143
|
-
TASK_JSON=$(call POST /api/
|
|
143
|
+
TASK_JSON=$(call POST /api/bongos/tasks "${CREATE_BODY}")
|
|
144
144
|
TASK_ID=$(echo "${TASK_JSON}" | python3 -c "import json,sys; print(json.load(sys.stdin)['task']['id'])")
|
|
145
145
|
echo "created task #${TASK_ID}"
|
|
146
146
|
|
|
147
147
|
echo
|
|
148
148
|
echo "--- 2. claim task ---"
|
|
149
149
|
CLAIM_BODY=$(python3 -c "import json; print(json.dumps({'task_id': ${TASK_ID}, 'worktree_name': '__smoke__'}))")
|
|
150
|
-
CLAIM_JSON=$(call POST /api/
|
|
150
|
+
CLAIM_JSON=$(call POST /api/bongos/claims "${CLAIM_BODY}")
|
|
151
151
|
CLAIM_ID=$(echo "${CLAIM_JSON}" | python3 -c "import json,sys; print(json.load(sys.stdin)['claim']['id'])")
|
|
152
152
|
echo "claim #${CLAIM_ID}"
|
|
153
153
|
|
|
154
154
|
echo
|
|
155
155
|
echo "--- 3. resolve claim shipped (verification.passed=true → lands at completed; grade gates confirm) ---"
|
|
156
156
|
RESOLVE_BODY='{"outcome":"shipped","notes_md":"smoke-test","value_summary":"smoke-test","verification":{"passed":true,"scanner_clean":true,"smoke_clean":true}}'
|
|
157
|
-
RESOLVE_JSON=$(call POST "/api/
|
|
157
|
+
RESOLVE_JSON=$(call POST "/api/bongos/claims/${CLAIM_ID}/resolve" "${RESOLVE_BODY}")
|
|
158
158
|
echo "${RESOLVE_JSON}"
|
|
159
159
|
|
|
160
160
|
echo
|
|
@@ -162,7 +162,7 @@ echo "--- 4. validate ---"
|
|
|
162
162
|
fail=0
|
|
163
163
|
|
|
164
164
|
# 4a. recent-shipped does NOT contain the smoke title
|
|
165
|
-
RECENT=$(curl -sS "${API}/api/
|
|
165
|
+
RECENT=$(curl -sS "${API}/api/bongos/public/recent-shipped")
|
|
166
166
|
if echo "${RECENT}" | python3 -c "
|
|
167
167
|
import json, sys
|
|
168
168
|
data = json.load(sys.stdin)
|
|
@@ -196,7 +196,7 @@ fi
|
|
|
196
196
|
# (Pre-#209 this asserted 'confirmed', which has been failing on every run
|
|
197
197
|
# since the grader gate landed — fixed in #468.) The task should never reach
|
|
198
198
|
# 'shipped' (that needs a merge). credits_reward=0, so no credit_log row.
|
|
199
|
-
TASK_AFTER=$(call GET "/api/
|
|
199
|
+
TASK_AFTER=$(call GET "/api/bongos/tasks/${TASK_ID}")
|
|
200
200
|
STATUS_AFTER=$(echo "${TASK_AFTER}" | python3 -c "import json,sys; print(json.load(sys.stdin)['task']['status'])")
|
|
201
201
|
if [[ "${STATUS_AFTER}" == "completed" ]]; then
|
|
202
202
|
echo "PASS task.status = completed (resolve landed it at completed; grade gates confirm — V3.R18 #209)"
|
|
@@ -249,7 +249,7 @@ cleanup_throwaway_task() {
|
|
|
249
249
|
out=$(curl -sS -X POST \
|
|
250
250
|
-H "Authorization: Bearer ${TOKEN}" -H "Content-Type: application/json" \
|
|
251
251
|
-d "${reason}" -w "\n%{http_code}" \
|
|
252
|
-
"${API}/api/
|
|
252
|
+
"${API}/api/bongos/tasks/${TASK_ID}/abandon") || true
|
|
253
253
|
code="${out##*$'\n'}"
|
|
254
254
|
case "${code}" in
|
|
255
255
|
2*) echo "PASS cleaned up throwaway task #${TASK_ID} (abandoned)" ;;
|