@bongos/core 1.21.176 → 1.21.178
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 +186 -496
- package/.claude/skills/planning-session/SKILL.md +2 -2
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +0 -6
- package/clients/bongos-client/index.cjs +0 -6
- package/clients/bongos-client/index.d.ts +0 -6
- package/clients/bongos-client/index.mjs +0 -6
- package/config/scheduled-routines.json +3 -8
- package/docs/adr/0042-builder-self-deploy-ci-auto-merge.md +3 -2
- package/docs/adr/0091-bounding-the-kernel-and-db-carve.md +1 -1
- package/docs/adr/0093-tranche-2-core-carve-sequence.md +1 -1
- package/docs/api/openapi.json +1 -87
- package/docs/api-reference.md +1 -8
- package/docs/canonical-permissions.md +4 -4
- package/docs/copy-inventory.md +25 -39
- package/docs/copy-registry.json +73 -200
- package/docs/file-map.md +6 -11
- package/docs/handoff-template.md +1 -1
- package/docs/module-api-changelog.md +4 -0
- package/docs/modules-contract.md +2 -2
- package/docs/onboarding/diagrams/README.md +3 -7
- package/docs/onboarding/diagrams/assertions.json +3 -3
- package/docs/page-inventory.json +4 -7
- package/docs/page-readings.json +1520 -1569
- package/docs/recipes/ops-gotchas.md +3 -1
- package/modules/autonomy/db.js +9 -0
- package/modules/autonomy/module.json +2 -2
- package/modules/autonomy/pollers/daily-checks.js +262 -0
- package/modules/autonomy/pollers/routine-timers.js +7 -5
- package/modules/autonomy/rank-roles.js +64 -0
- package/modules/autonomy/server-schedule.js +37 -0
- package/modules/government/catalog.js +10 -7
- package/modules/government/decision-board.js +0 -1
- package/modules/government/decision-rules.js +0 -1
- package/modules/government/docket.js +0 -1
- package/modules/government/protected-surfaces.js +1 -1
- package/modules/government/protected-surfaces.json +2 -3
- package/modules/hall-ui/public/atlas.html +1 -1
- package/modules/hall-ui/public/blockers.html +1 -1
- package/modules/hall-ui/public/board-room.html +1 -1
- package/modules/hall-ui/public/city.html +1 -1
- package/modules/hall-ui/public/collab.html +1 -1
- package/modules/hall-ui/public/commands.html +1 -1
- package/modules/hall-ui/public/copy-desk.html +1 -1
- package/modules/hall-ui/public/deploy.html +1 -1
- package/modules/hall-ui/public/diagrams.html +1 -1
- package/modules/hall-ui/public/drachmae.html +1 -1
- package/modules/hall-ui/public/fleet.html +1 -1
- package/modules/hall-ui/public/gate.css +4 -26
- package/modules/hall-ui/public/gate.html +12 -27
- package/modules/hall-ui/public/gate.js +26 -176
- package/modules/hall-ui/public/gate.states.json +4 -22
- package/modules/hall-ui/public/goal-map.html +1 -1
- package/modules/hall-ui/public/goals.html +1 -1
- package/modules/hall-ui/public/government.html +1 -1
- package/modules/hall-ui/public/idea.html +1 -1
- package/modules/hall-ui/public/ideas.html +1 -1
- package/modules/hall-ui/public/index.html +1 -1
- package/modules/hall-ui/public/modules.html +1 -1
- package/modules/hall-ui/public/my-agents.html +1 -1
- package/modules/hall-ui/public/primer.html +1 -1
- package/modules/hall-ui/public/profile.html +1 -1
- package/modules/hall-ui/public/project-settings.html +1 -1
- package/modules/hall-ui/public/ranks.html +1 -1
- package/modules/hall-ui/public/roadmap.html +1 -1
- package/modules/hall-ui/public/roster.html +1 -1
- package/modules/hall-ui/public/sessions.html +1 -1
- package/modules/hall-ui/public/settings.html +1 -1
- package/modules/hall-ui/public/shell.js +1 -1
- package/modules/hall-ui/public/street-card.js +5 -9
- package/modules/hall-ui/public/street-desk.js +2 -2
- package/modules/hall-ui/public/street-inside.js +1 -1
- package/modules/hall-ui/public/street.html +1 -1
- package/modules/hall-ui/public/studio.html +1 -1
- package/modules/hall-ui/public/task.html +1 -1
- package/modules/hall-ui/public/thinking.html +1 -1
- package/modules/hall-ui/public/tweak-editor.html +1 -1
- package/modules/hall-ui/public/watch.html +1 -1
- package/modules/hall-ui/public/work.html +1 -1
- package/modules/lifecycle/matter-acts.js +0 -6
- package/modules/lifecycle/module.json +0 -1
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +36 -0
- package/scripts/bongos/adopt-preflight.js +3 -3
- package/scripts/bongos/api-alias-caller-scan.js +2 -2
- package/scripts/bongos/audit-authorship.sh +1 -8
- package/scripts/bongos/audit-rank-roles.js +15 -56
- package/scripts/bongos/bump-version.js +46 -9
- package/scripts/bongos/codemod-rename-scripts-gds.js +0 -1
- package/scripts/bongos/diagram-facts.js +1 -1
- package/scripts/bongos/do-api.js +1 -1
- package/scripts/bongos/doc-cli-guard.js +2 -0
- package/scripts/bongos/doc-control-claims.js +2 -2
- package/scripts/bongos/fitness-checks-identity.js +4 -15
- package/scripts/bongos/gen-diagrams.js +3 -3
- package/scripts/bongos/government-walk.js +3 -9
- package/scripts/bongos/hard-floor.js +52 -0
- package/scripts/bongos/publish-manifest.js +3 -3
- package/scripts/bongos/pulse.js +5 -3
- package/scripts/bongos/routine-schedule.js +38 -3
- package/scripts/bongos/run-unit-tests.js +17 -5
- package/scripts/bongos/ship-regen.js +2 -3
- package/scripts/gds/{goal-names.js → hard-floor.js} +3 -4
- package/scripts/security/dep-audit.js +50 -124
- package/src/bongos/module-scope-map.js +2 -2
- package/src/bongos/permission-path-check.js +1 -1
- package/src/bongos/route-rank-check.js +1 -8
- package/src/bongos/routes.js +1 -2
- package/src/module-api.js +1 -1
- package/src/modules.js +1 -1
- package/tests/acclaim_feed_evidence_db.mjs +42 -23
- package/tests/adr_0089_scope.mjs +7 -5
- package/tests/autonomy_daily_checks.mjs +201 -0
- package/tests/bump_version.mjs +52 -18
- package/tests/claude_materialize.mjs +12 -12
- package/tests/copy_desk_flags_db.mjs +22 -14
- package/tests/effective_visibility_predicate.mjs +0 -18
- package/tests/gating_review_retired.mjs +1 -1
- package/tests/government_act_alone_buildings.mjs +1 -3
- package/tests/government_board_membership_db.mjs +35 -22
- package/tests/government_protected_surfaces.mjs +29 -13
- package/tests/governor_docket.mjs +0 -2
- package/tests/governor_matter_acts.mjs +6 -8
- package/tests/hall_city.mjs +1 -1
- package/tests/hall_matter_card.mjs +2 -2
- package/tests/hall_oversight_world.mjs +16 -12
- package/tests/hall_street_desk.mjs +4 -3
- package/tests/hall_street_inside.mjs +1 -1
- package/tests/helpers.mjs +34 -0
- package/tests/howto_state.mjs +33 -56
- package/tests/howto_state_db.mjs +68 -0
- package/tests/idea_credit_streams_db.mjs +11 -3
- package/tests/integration_parked_ratchet.mjs +7 -1
- package/tests/nav_permission_atoms.mjs +1 -1
- package/tests/page_notes_db.mjs +12 -8
- package/tests/page_tweak_no_rearm.mjs +50 -0
- package/tests/publish_manifest.mjs +64 -0
- package/tests/routine_capture_kind.mjs +18 -7
- package/tests/routine_schedule.mjs +42 -0
- package/tests/search_isolation.mjs +5 -103
- package/tests/search_isolation_db.mjs +140 -0
- package/tests/session_earnings_mirror_db.mjs +2 -0
- package/tests/workflow_exec_paths.mjs +9 -11
- package/modules/lifecycle/routes/gate-approvals.js +0 -299
- package/scripts/bongos/artifact-staleness.js +0 -267
- package/scripts/bongos/ci-grade.js +0 -82
- package/scripts/bongos/classify-discipline.js +0 -153
- package/scripts/bongos/codemod-rename-src-gds.js +0 -145
- package/scripts/bongos/coreB-carve-proof.sh +0 -725
- package/scripts/bongos/gate-review.js +0 -330
- package/scripts/bongos/goal-names.js +0 -102
- package/scripts/bongos/rename-goals.js +0 -109
- package/scripts/bongos/seed-adopt-tasks.js +0 -75
- package/scripts/bongos/seed-api-contract-goal-tasks.js +0 -141
- package/scripts/bongos/seed-board-room-tasks.js +0 -196
- package/scripts/bongos/seed-bongos-app-tasks.js +0 -294
- package/scripts/bongos/seed-bongos-coreB-tranche1-tasks.js +0 -81
- package/scripts/bongos/seed-bongos-coreB-tranche2-tasks.js +0 -100
- package/scripts/bongos/seed-bongos-goal-hierarchy-tasks.js +0 -307
- package/scripts/bongos/seed-bongos-module-system-tasks.js +0 -346
- package/scripts/bongos/seed-bongos-tasks.js +0 -214
- package/scripts/bongos/seed-bongos-v1-seo-tasks.js +0 -104
- package/scripts/bongos/seed-bv1-community-tasks.js +0 -131
- package/scripts/bongos/seed-bv1-privacy-invites-tasks.js +0 -133
- package/scripts/bongos/seed-bv1-profile-page-tasks.js +0 -161
- package/scripts/bongos/seed-bv1-r01-delta-tasks.js +0 -154
- package/scripts/bongos/seed-bv2-tweak-mode-tasks.js +0 -277
- package/scripts/bongos/seed-gds-v4-tasks.js +0 -624
- package/scripts/bongos/seed-governance-tasks.js +0 -340
- package/scripts/bongos/seed-medusa-tasks.js +0 -440
- package/scripts/bongos/seed-module-upstreaming.js +0 -219
- package/scripts/bongos/seed-productization-tasks.js +0 -235
- package/scripts/bongos/seed-project-admin-console-tasks.js +0 -88
- package/scripts/bongos/seed-provisioning-tasks.js +0 -83
- package/scripts/bongos/seed-strict-versioning-tasks.js +0 -275
- package/scripts/bongos/seed-v2-world-tasks.js +0 -283
- package/scripts/gds/artifact-staleness.js +0 -7
- package/scripts/gds/ci-grade.js +0 -7
- package/scripts/gds/classify-discipline.js +0 -7
- package/scripts/gds/codemod-rename-src-gds.js +0 -7
- package/scripts/gds/coreB-carve-proof.sh +0 -8
- package/scripts/gds/gate-review.js +0 -7
- package/scripts/gds/rename-goals.js +0 -7
- package/scripts/gds/seed-adopt-tasks.js +0 -7
- package/scripts/gds/seed-api-contract-goal-tasks.js +0 -7
- package/scripts/gds/seed-board-room-tasks.js +0 -6
- package/scripts/gds/seed-bongos-app-tasks.js +0 -7
- package/scripts/gds/seed-bongos-coreB-tranche1-tasks.js +0 -7
- package/scripts/gds/seed-bongos-coreB-tranche2-tasks.js +0 -7
- package/scripts/gds/seed-bongos-goal-hierarchy-tasks.js +0 -7
- package/scripts/gds/seed-bongos-module-system-tasks.js +0 -7
- package/scripts/gds/seed-bongos-tasks.js +0 -7
- package/scripts/gds/seed-bongos-v1-seo-tasks.js +0 -6
- package/scripts/gds/seed-bv1-community-tasks.js +0 -6
- package/scripts/gds/seed-bv1-privacy-invites-tasks.js +0 -6
- package/scripts/gds/seed-bv1-profile-page-tasks.js +0 -6
- package/scripts/gds/seed-bv1-r01-delta-tasks.js +0 -6
- package/scripts/gds/seed-bv2-tweak-mode-tasks.js +0 -6
- package/scripts/gds/seed-gds-v4-tasks.js +0 -7
- package/scripts/gds/seed-governance-tasks.js +0 -7
- package/scripts/gds/seed-medusa-tasks.js +0 -7
- package/scripts/gds/seed-module-upstreaming.js +0 -7
- package/scripts/gds/seed-productization-tasks.js +0 -7
- package/scripts/gds/seed-project-admin-console-tasks.js +0 -6
- package/scripts/gds/seed-provisioning-tasks.js +0 -7
- package/scripts/gds/seed-strict-versioning-tasks.js +0 -7
- package/scripts/gds/seed-v2-world-tasks.js +0 -7
- package/scripts/migrate_cost_ledger.sh +0 -178
- package/tests/artifact_staleness.mjs +0 -207
- package/tests/gate_approvals.mjs +0 -611
- package/tests/gate_review.mjs +0 -152
- package/tests/goal_names.mjs +0 -120
- package/tests/newcomer_generator.mjs +0 -48
|
@@ -472,7 +472,7 @@
|
|
|
472
472
|
chrome exists before the page scripts run. -->
|
|
473
473
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
474
474
|
<script src="/builders/craft-mode.js?v=2026-10-09-living3"></script>
|
|
475
|
-
<script src="/builders/shell.js?v=2026-10-25-
|
|
475
|
+
<script src="/builders/shell.js?v=2026-10-25-autobongos"></script>
|
|
476
476
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
477
477
|
<script src="/builders/palette.js" defer></script>
|
|
478
478
|
<!-- shared frontend toolkit (window.OTB) — loaded before consuming IIFEs. -->
|
|
@@ -371,7 +371,7 @@
|
|
|
371
371
|
// Metic+ oversight could not honestly hold it. Everything below IS a rank
|
|
372
372
|
// surface, so this group's gate and audience are unchanged.
|
|
373
373
|
{ id: 'watch', label: 'Watch', icon: 'watch', href: '/watch', gate: 'government', position: true },
|
|
374
|
-
{ id: 'gate', label: '
|
|
374
|
+
{ id: 'gate', label: 'Autobongos', icon: 'gate', href: '/gate', gate: 'government', position: true }, // task 1004859: the runner panel; URL kept for bookmarks
|
|
375
375
|
{ id: 'sessions', label: 'Sessions', icon: 'sessions', href: '/sessions', gate: 'government', position: true },
|
|
376
376
|
// The project's own fundamentals (task 1003280, goal 1000072). Mirrors the
|
|
377
377
|
// server's requireGovernmentPage floor; cosmetic only, as every item here is.
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
// filed it — an amendment with its revised words, a who-decides change with
|
|
40
40
|
// its rows, a building's matter with its revised detail. The constitution's own
|
|
41
41
|
// fields are changed in the Board Room's amendment form, not here.
|
|
42
|
-
// * Release. An override
|
|
43
|
-
//
|
|
42
|
+
// * Release. An override is released from the card through its own decide
|
|
43
|
+
// route (the PR-at-the-gate release went with its route, task 1004859). A newer CORE keeps its check-then-take:
|
|
44
44
|
// the card draws the Release desk's core row (check, then take it), the same
|
|
45
45
|
// as the floor desk; only a hall without that row links to the pin's page.
|
|
46
46
|
//
|
|
@@ -447,11 +447,9 @@
|
|
|
447
447
|
cv.actions = [act('fine', 'fine by me', 'primary'), act('refuse', 'object', 'quiet')];
|
|
448
448
|
return cv;
|
|
449
449
|
}
|
|
450
|
-
if (m.source === 'override_requests'
|
|
450
|
+
if (m.source === 'override_requests') {
|
|
451
451
|
if (!mine) { cv.readOnly = true; cv.result = 'Someone who may decide it will.'; return cv; }
|
|
452
|
-
cv.result =
|
|
453
|
-
? 'It is held at the gate. Releasing it lets it merge and go live. The call is yours.'
|
|
454
|
-
: 'It failed a check or a grade. Releasing it lets it go live anyway. The call is yours.';
|
|
452
|
+
cv.result = 'It failed a check or a grade. Releasing it lets it go live anyway. The call is yours.';
|
|
455
453
|
cv.actions = [act('release', 'release', 'primary'), act('hold', 'hold', 'quiet')];
|
|
456
454
|
return cv;
|
|
457
455
|
}
|
|
@@ -712,7 +710,6 @@
|
|
|
712
710
|
},
|
|
713
711
|
criteria_uat: { force: function (id, inp, who) { return { title: 'Sign off: ' + who, action: { type: 'satisfy_criterion', criterion_id: Number(id) } }; } },
|
|
714
712
|
override_requests: { release: function (id, inp, who) { return { title: 'Release past its check: ' + who, action: { type: 'approve_override', request_id: Number(id) } }; } },
|
|
715
|
-
gate_approvals: { release: function (id, inp, who) { return { title: 'Release from the gate: ' + who, action: { type: 'approve_gate', pr: Number(id) } }; } },
|
|
716
713
|
builder_budget: {
|
|
717
714
|
budget: function (id, inp, who) { return inp.option ? { title: who + ': ' + str(inp.label || inp.option), action: { type: 'set_budget', builder_id: Number(id), monthly_usd: inp.option === 'none' ? null : Number(inp.option) } } : null; },
|
|
718
715
|
},
|
|
@@ -779,7 +776,6 @@
|
|
|
779
776
|
if (s.council && COUNCIL_ACTS[s.kind] && COUNCIL_ACTS[s.kind][key]) return councilRequest(s, key, inp);
|
|
780
777
|
if (ACT_ROUTES[s.kind] && ACT_ROUTES[s.kind][key]) return ACT_ROUTES[s.kind][key](enc(s.id), inp);
|
|
781
778
|
if (s.kind === 'override_requests' && key === 'release') return post('/override-requests/' + enc(s.id) + '/decide', { decision: 'approve' });
|
|
782
|
-
if (s.kind === 'gate_approvals' && key === 'release') return post('/gate-approvals/' + enc(s.id) + '/approve', {});
|
|
783
779
|
return null; // hold, abstain and the core's release (a link) record nothing here
|
|
784
780
|
}
|
|
785
781
|
|
|
@@ -814,7 +810,7 @@
|
|
|
814
810
|
if (key === 'abstain') return { toast: 'Noted. Nothing goes on the record, and it still waits for your vote until it closes.', building: null, kind: null, close: true };
|
|
815
811
|
if (key === 'revise') return { toast: 'Revised. It sits again on the new wording.', building: b, kind: 'light', close: true };
|
|
816
812
|
if (key === 'hold') return { toast: 'Held. It waits for you.', building: null, kind: null, close: true };
|
|
817
|
-
if (key === 'release') return { toast:
|
|
813
|
+
if (key === 'release') return { toast: 'Released. It goes live.', building: b, kind: 'rise', close: true };
|
|
818
814
|
if (key === 'fine') return { toast: cv && cv.source === 'goal_join_requests' ? 'Noted. ' + who + ' joins the team.' : 'Noted. ' + who + ' is invited in.', building: b, kind: 'rise', close: false };
|
|
819
815
|
if (key === 'refuse') return { toast: 'Noted. ' + who + ' is not let in.', building: b, kind: 'settle', close: false };
|
|
820
816
|
if (key === 'record') {
|
|
@@ -154,12 +154,12 @@
|
|
|
154
154
|
|
|
155
155
|
// The words a floor counts its rows in, and says when it is cleared.
|
|
156
156
|
const NOUNS = Object.freeze({
|
|
157
|
-
access_requests: 'waiting', goal_join_requests: 'asking', override_requests: 'asked',
|
|
157
|
+
access_requests: 'waiting', goal_join_requests: 'asking', override_requests: 'asked',
|
|
158
158
|
core_update: 'update', blockers: 'waiting', board: 'open vote', idea: 'open vote',
|
|
159
159
|
});
|
|
160
160
|
const CLEAR = Object.freeze({
|
|
161
161
|
access_requests: 'Everyone is in', goal_join_requests: 'No one is asking', override_requests: 'No overrides asked',
|
|
162
|
-
|
|
162
|
+
blockers: 'Nothing blocked on you', board: 'Every vote is in', idea: 'No ideas waiting',
|
|
163
163
|
// every other floor that holds matters says its own line too (task 1004562)
|
|
164
164
|
redteam_reports: 'No reports open', removal_proposals: 'No removals asked', grade_appeals: 'No appeals open',
|
|
165
165
|
module_rechecks: 'Every module checked', criteria_uat: 'Nothing waits for a tester', core_update: 'Core is up to date',
|
|
@@ -466,7 +466,7 @@
|
|
|
466
466
|
release: {
|
|
467
467
|
holds: 'Putting finished work live, and taking updates to Bongos itself.', rule: 'decide', cap: 7,
|
|
468
468
|
growth: 'Room for a second gate if releases are ever split by area.', annex: 'room for a second gate',
|
|
469
|
-
floors: [['Overrides', 'past a failed check or grade', { source: 'override_requests' }], ['Modules', 'listed modules, and their re-checks', { source: 'module_rechecks' }], ['Held back', 'work held from going live', { floor: 'release.held_back' }], ['Core update', 'a new version of Bongos', { source: 'core_update', desk: 'release.core' }], ['Live this month', 'what went live', { floor: 'release.live_month' }]
|
|
469
|
+
floors: [['Overrides', 'past a failed check or grade', { source: 'override_requests' }], ['Modules', 'listed modules, and their re-checks', { source: 'module_rechecks' }], ['Held back', 'work held from going live', { floor: 'release.held_back' }], ['Core update', 'a new version of Bongos', { source: 'core_update', desk: 'release.core' }], ['Live this month', 'what went live', { floor: 'release.live_month' }]],
|
|
470
470
|
},
|
|
471
471
|
treasury: {
|
|
472
472
|
holds: 'The budget, and who gets paid for what.', rule: 'majority', cap: 7,
|
|
@@ -230,7 +230,7 @@
|
|
|
230
230
|
|
|
231
231
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
232
232
|
<script src="/builders/craft-mode.js?v=2026-10-09-living3"></script>
|
|
233
|
-
<script src="/builders/shell.js?v=2026-10-25-
|
|
233
|
+
<script src="/builders/shell.js?v=2026-10-25-autobongos"></script>
|
|
234
234
|
<script src="/builders/palette.js" defer></script>
|
|
235
235
|
<script src="/builders/gov-living.js?v=2026-10-09-positions1"></script>
|
|
236
236
|
<script src="/builders/gov-feeds.js?v=2026-10-09-living3"></script>
|
|
@@ -190,7 +190,7 @@
|
|
|
190
190
|
|
|
191
191
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
192
192
|
<script src="/builders/craft-mode.js?v=2026-10-09-living3"></script>
|
|
193
|
-
<script src="/builders/shell.js?v=2026-10-25-
|
|
193
|
+
<script src="/builders/shell.js?v=2026-10-25-autobongos"></script>
|
|
194
194
|
<script src="/builders/palette.js" defer></script>
|
|
195
195
|
<script src="/builders/dom-utils.js?v=2026-06-23-contrib"></script>
|
|
196
196
|
<!-- The kit, for its ONE renderer: the full-size ship-time visual figure
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
time so the chrome exists before the deferred page scripts execute. -->
|
|
58
58
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
59
59
|
<script src="/builders/craft-mode.js?v=2026-10-09-living3"></script>
|
|
60
|
-
<script src="/builders/shell.js?v=2026-10-25-
|
|
60
|
+
<script src="/builders/shell.js?v=2026-10-25-autobongos"></script>
|
|
61
61
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
62
62
|
<script src="/builders/palette.js" defer></script>
|
|
63
63
|
<!-- shared frontend toolkit (window.OTB) — loaded FIRST so task.js can pull from it. -->
|
|
@@ -140,7 +140,7 @@
|
|
|
140
140
|
|
|
141
141
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
142
142
|
<script src="/builders/craft-mode.js?v=2026-10-09-living3"></script>
|
|
143
|
-
<script src="/builders/shell.js?v=2026-10-25-
|
|
143
|
+
<script src="/builders/shell.js?v=2026-10-25-autobongos"></script>
|
|
144
144
|
<script src="/builders/palette.js" defer></script>
|
|
145
145
|
|
|
146
146
|
<script src="/builders/idea-objects.js?v=2026-09-27-split"></script>
|
|
@@ -144,7 +144,7 @@
|
|
|
144
144
|
|
|
145
145
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
146
146
|
<script src="/builders/craft-mode.js?v=2026-10-09-living3"></script>
|
|
147
|
-
<script src="/builders/shell.js?v=2026-10-25-
|
|
147
|
+
<script src="/builders/shell.js?v=2026-10-25-autobongos"></script>
|
|
148
148
|
<script src="/builders/palette.js" defer></script>
|
|
149
149
|
<script src="/builders/dom-utils.js?v=2026-06-23-contrib"></script>
|
|
150
150
|
<script src="/builders/brand-holes.js?v=2026-09-29-aqfix"></script>
|
|
@@ -165,7 +165,7 @@
|
|
|
165
165
|
chrome exists before the page script runs. -->
|
|
166
166
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
167
167
|
<script src="/builders/craft-mode.js?v=2026-10-09-living3"></script>
|
|
168
|
-
<script src="/builders/shell.js?v=2026-10-25-
|
|
168
|
+
<script src="/builders/shell.js?v=2026-10-25-autobongos"></script>
|
|
169
169
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
170
170
|
<script src="/builders/palette.js" defer></script>
|
|
171
171
|
<!-- shared frontend toolkit (window.OTB) — loaded before watch.js, which pulls from it. -->
|
|
@@ -173,7 +173,7 @@
|
|
|
173
173
|
time so the chrome exists before the deferred page scripts execute. -->
|
|
174
174
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
175
175
|
<script src="/builders/craft-mode.js?v=2026-10-09-living3"></script>
|
|
176
|
-
<script src="/builders/shell.js?v=2026-10-25-
|
|
176
|
+
<script src="/builders/shell.js?v=2026-10-25-autobongos"></script>
|
|
177
177
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
178
178
|
<script src="/builders/palette.js" defer></script>
|
|
179
179
|
<!-- shared frontend toolkit (window.OTB) — loaded FIRST so work.js can pull from it. -->
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
// commits, through the SAME function the direct route calls:
|
|
7
7
|
// review satisfy_criterion → satisfyByOverride (POST /done-when/:id/satisfy)
|
|
8
8
|
// release approve_override → db.decideOverrideRequest (POST /override-requests/:id/decide)
|
|
9
|
-
// release approve_gate → approveGatePr (POST /gate-approvals/:pr/approve)
|
|
10
9
|
// The government module only checks the act's shape and calls in through the
|
|
11
10
|
// 'governor.matterAct' contribution point (a module never requires a sibling).
|
|
12
11
|
// Each act returns { done, reason? }: a refusal the route would give (already
|
|
@@ -23,7 +22,6 @@ const why = (area, ctx) => `A passed ${area} matter (matter ${ctx && ctx.matterI
|
|
|
23
22
|
// functions are needed here.
|
|
24
23
|
const routes = {
|
|
25
24
|
doneWhen: () => require('./routes/done-when'),
|
|
26
|
-
gate: () => require('./routes/gate-approvals'),
|
|
27
25
|
};
|
|
28
26
|
|
|
29
27
|
const ACTS = Object.freeze({
|
|
@@ -47,10 +45,6 @@ const ACTS = Object.freeze({
|
|
|
47
45
|
throw err;
|
|
48
46
|
}
|
|
49
47
|
},
|
|
50
|
-
approve_gate: async (action, ctx) => {
|
|
51
|
-
const out = await routes.gate().approveGatePr({ number: action.pr, login: `council, matter ${ctx && ctx.matterId}` });
|
|
52
|
-
return out.ok ? { done: true } : { done: false, reason: out.code };
|
|
53
|
-
},
|
|
54
48
|
}),
|
|
55
49
|
});
|
|
56
50
|
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.21.
|
|
3
|
+
"version": "1.21.178",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bongos/core",
|
|
9
|
-
"version": "1.21.
|
|
9
|
+
"version": "1.21.178",
|
|
10
10
|
"license": "AGPL-3.0-or-later",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"express": "^4.21.2",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.21.
|
|
3
|
+
"version": "1.21.178",
|
|
4
4
|
"description": "Cloud Bongos — the AI-first build platform core (GDS + platform surfaces + module system), installed as a versioned dependency (ADR 0108).",
|
|
5
5
|
"license": "AGPL-3.0-or-later",
|
|
6
6
|
"main": "src/platform-server.js",
|
package/release-notes.json
CHANGED
|
@@ -10308,5 +10308,41 @@
|
|
|
10308
10308
|
"id": "1004858",
|
|
10309
10309
|
"text": "The status page no longer shows an uptime panel and a \"standing\" card that only ever said \"unknown\" — the checker behind them was never switched on. The dead checker and its data feed are gone too."
|
|
10310
10310
|
}
|
|
10311
|
+
],
|
|
10312
|
+
"1.21.177": [
|
|
10313
|
+
{
|
|
10314
|
+
"id": "1004887",
|
|
10315
|
+
"text": "Main was failing one safety check after two cleanup changes landed together. The check's expected count now matches the files we deliberately removed, so main is green again."
|
|
10316
|
+
},
|
|
10317
|
+
{
|
|
10318
|
+
"id": "1004878",
|
|
10319
|
+
"text": "Two daily safety checks — builders on a broken rank and known-vulnerable dependencies — now run on the server by themselves and land in the ideas inbox; five dead routines were retired."
|
|
10320
|
+
},
|
|
10321
|
+
{
|
|
10322
|
+
"id": "1004856",
|
|
10323
|
+
"text": "Removed 30 old scripts that each did one job once (mostly creating batches of tasks) and were never used again — about 6,500 lines less to read and maintain. Nothing that runs today used them."
|
|
10324
|
+
}
|
|
10325
|
+
],
|
|
10326
|
+
"1.21.178": [
|
|
10327
|
+
{
|
|
10328
|
+
"id": "1004888",
|
|
10329
|
+
"text": "A test now guarantees the 2.4 MB of hall sample data from this instance can never sneak back into the core every hosted project installs, while the hall preview tool itself keeps shipping."
|
|
10330
|
+
},
|
|
10331
|
+
{
|
|
10332
|
+
"id": "1004889",
|
|
10333
|
+
"text": "An automatic security check on search results works again, and it now really catches a private note leaking to the wrong person instead of passing by luck."
|
|
10334
|
+
},
|
|
10335
|
+
{
|
|
10336
|
+
"id": "1004886",
|
|
10337
|
+
"text": "Core releases can no longer be labelled as containing code that never actually went out."
|
|
10338
|
+
},
|
|
10339
|
+
{
|
|
10340
|
+
"id": "1004859",
|
|
10341
|
+
"text": "The Gate page is now called Autobongos. It keeps the runner controls and drops the list of held pull requests, which was always empty because the check it waited on never ran. Old links to /gate still work. The two permissions"
|
|
10342
|
+
},
|
|
10343
|
+
{
|
|
10344
|
+
"id": "1004863",
|
|
10345
|
+
"text": "Eight database tests that had quietly stopped working are repaired and now run on every change, including the one that proves an idea's author is never paid twice and the one that proves search never shows someone a page above"
|
|
10346
|
+
}
|
|
10311
10347
|
]
|
|
10312
10348
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// • core<->host fitness-boundary overlaps — repo dirs that shadow core's reserved
|
|
9
9
|
// src/bongos or modules/ namespaces the fitness gate scans (ADR 0062 §1).
|
|
10
10
|
// • protected-path landings — incoming files that fall on the trust-boundary hard
|
|
11
|
-
// floor (ADR 0043, via
|
|
11
|
+
// floor (ADR 0043, via hard-floor.js's canonical matchesHardFloor).
|
|
12
12
|
// • CI collisions — the repo's workflows vs core's expected unit/secret-scan/
|
|
13
13
|
// gate-review checks.
|
|
14
14
|
// • IGNORED incoming files — a pre-existing .gitignore rule that would swallow what
|
|
@@ -26,7 +26,7 @@ const nodeFs = require('node:fs');
|
|
|
26
26
|
const nodePath = require('node:path');
|
|
27
27
|
const { execFileSync: nodeExecFileSync } = require('node:child_process');
|
|
28
28
|
const { filenameViolation, INSTANCE_NS } = require('./migration-namespace');
|
|
29
|
-
const { matchesHardFloor } = require('./
|
|
29
|
+
const { matchesHardFloor } = require('./hard-floor');
|
|
30
30
|
|
|
31
31
|
const SEV = { BLOCK: 'blocking', WARN: 'warning', INFO: 'info' };
|
|
32
32
|
const CORE_EXPECTED_CHECKS = ['unit', 'secret-scan', 'gate-review']; // the merge-gate checks core adds
|
|
@@ -66,7 +66,7 @@ function checkFitnessBoundary({ topLevelDirs = [], hasSrcBongos = false } = {})
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
// PURE — incoming paths → protected-path findings (ADR 0043). Which files adopt writes
|
|
69
|
-
// land on the trust-boundary hard floor (via
|
|
69
|
+
// land on the trust-boundary hard floor (via hard-floor.js's canonical matcher)?
|
|
70
70
|
function checkProtectedPaths(incoming = INCOMING_PATHS) {
|
|
71
71
|
const hits = incoming.filter((p) => matchesHardFloor(p));
|
|
72
72
|
if (!hits.length) return [{ category: 'protected-paths', severity: SEV.INFO, message: 'no incoming files land on protected paths.' }];
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
// Note fitness-ratchets.js belongs here too: it is the GATE, and its builder-facing hint has
|
|
37
37
|
// to spell the alias out to tell anyone what they tripped over.
|
|
38
38
|
// 4. THE RENAME GUARDRAILS (path-excluded). rename-history-check.js, rename-ledger-prose.js,
|
|
39
|
-
// gds-literal-scan.js,
|
|
39
|
+
// gds-literal-scan.js, fitness-ratchets.js and THIS FILE name the
|
|
40
40
|
// old path because that is what they are for. Same principle as GDS_RULE_FILES next door: a
|
|
41
41
|
// gate that cannot state its own rule cannot explain itself.
|
|
42
42
|
// 5. tests/ (path-excluded). Tests are what keeps the alias exercised in CI. Moving them off it
|
|
@@ -110,7 +110,7 @@ const ALIAS_EXCLUDED_PATHS = [
|
|
|
110
110
|
// 3. the live proof that the alias still answers
|
|
111
111
|
/^scripts\/(?:gds|bongos)\/smoke-gds\.js$/,
|
|
112
112
|
// 4. the rename guardrails — they name the old path on purpose
|
|
113
|
-
/^scripts\/(?:gds|bongos)\/(rename-history-check|rename-ledger-prose|gds-literal-scan|
|
|
113
|
+
/^scripts\/(?:gds|bongos)\/(rename-history-check|rename-ledger-prose|gds-literal-scan|api-alias-caller-scan|fitness-ratchets)\.js$/,
|
|
114
114
|
/^config\/(fitness-baselines|rename-history-baseline)\.json$/,
|
|
115
115
|
// 5. tests keep the alias exercised in CI — the repo's own two spellings, `tests/` at the root
|
|
116
116
|
// and a module's `tests/` or `test/` dir. Deliberately NOT a blanket `\.mjs$`: three .mjs
|
|
@@ -165,14 +165,12 @@ ALLOWLIST=(
|
|
|
165
165
|
'tests/setup_smoke.mjs'
|
|
166
166
|
|
|
167
167
|
# Test DATA that pins a real contract (task 1002640) — identity in an
|
|
168
|
-
# assertion IS the contract, not a mis-attribution:
|
|
169
|
-
# the Archon's login (gate_approvals), packaging/provisioning tests
|
|
168
|
+
# assertion IS the contract, not a mis-attribution: packaging/provisioning tests
|
|
170
169
|
# exercise the real repo owner + the mirror-redaction floor. Listed per file
|
|
171
170
|
# (never a blanket tests/ exclusion) so a NEW test file is still scanned.
|
|
172
171
|
'tests/provision.mjs'
|
|
173
172
|
'tests/package_core.mjs'
|
|
174
173
|
'tests/init.mjs'
|
|
175
|
-
'tests/gate_approvals.mjs'
|
|
176
174
|
'tests/publish_reconciler.mjs'
|
|
177
175
|
'tests/dev_lib.mjs'
|
|
178
176
|
'tests/ship_card.mjs'
|
|
@@ -196,11 +194,6 @@ ALLOWLIST=(
|
|
|
196
194
|
# instance's owner literal precisely so packaging can SCRUB it from every
|
|
197
195
|
# published core — the anti-leak spec, not a runtime hardcode (task 1002640).
|
|
198
196
|
'scripts/bongos/package-core.js'
|
|
199
|
-
|
|
200
|
-
# Frozen seed script — a task DESCRIPTION quotes migration 023's founding-
|
|
201
|
-
# Archon literal as the thing that task exists to remove (the
|
|
202
|
-
# seed-v3-tasks.js class: stripping it would lose the task history).
|
|
203
|
-
'scripts/bongos/seed-medusa-tasks.js'
|
|
204
197
|
)
|
|
205
198
|
|
|
206
199
|
# ----------------------------------------------------------------------------
|
|
@@ -21,8 +21,10 @@
|
|
|
21
21
|
// THIS IS THE RE-RUNNABLE HALF, and it is deliberately NOT fatal at boot. Idea
|
|
22
22
|
// 1000622 records that trap: an assertion that throws on startup turns a data
|
|
23
23
|
// problem on one instance into an outage. This is a standalone read-only script
|
|
24
|
-
// for a
|
|
25
|
-
// in the server's boot path requires it.
|
|
24
|
+
// for a by-hand or deploy-time caller — it exits 1 so a caller can act, and nothing
|
|
25
|
+
// in the server's boot path requires it. The SCHEDULED run is in-process: the
|
|
26
|
+
// server's daily-checks poller (task 1004878) reads the roster straight from its
|
|
27
|
+
// database and files the same idea, so it needs no CLI session.
|
|
26
28
|
//
|
|
27
29
|
// It reports rather than repairs, and that is a decision, not an omission:
|
|
28
30
|
// rewriting somebody's rank is an authority change, and it belongs to an operator
|
|
@@ -36,7 +38,7 @@
|
|
|
36
38
|
// 2 could not read the roster (no session / network / route absent)
|
|
37
39
|
//
|
|
38
40
|
// `--file-idea` is what makes this a SURFACE rather than another thing nobody
|
|
39
|
-
// runs —
|
|
41
|
+
// runs — spawning capture.js so idea
|
|
40
42
|
// filing has one implementation. Without it a nightly deterministic run that exits
|
|
41
43
|
// 1 reports into a log nobody reads, which is the exact criticism this task makes
|
|
42
44
|
// of the status quo.
|
|
@@ -48,69 +50,26 @@ const os = require('node:os');
|
|
|
48
50
|
const { cliClient, requireSession, cliExit } = require('./cli-lib');
|
|
49
51
|
const { LIVE_RANK_LADDER } = require('../../src/bongos/db-kernel.js');
|
|
50
52
|
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
//
|
|
54
|
-
|
|
55
|
-
// gate has no Postgres, which is exactly why the gap this script closes went
|
|
56
|
-
// unverified for so long. A DB-free test of the decision is not a consolation
|
|
57
|
-
// prize here — it is the thing that can actually run in CI.
|
|
58
|
-
//
|
|
59
|
-
// A row with NO rank at all counts: NULL fails the INNER JOIN the same way a
|
|
60
|
-
// legacy value does, and reads as "fine" in every UI that renders a blank.
|
|
61
|
-
function findRanksWithoutRoles(rows, liveRanks = LIVE_RANK_LADDER) {
|
|
62
|
-
const live = new Set(liveRanks);
|
|
63
|
-
return (Array.isArray(rows) ? rows : [])
|
|
64
|
-
.filter((b) => b && !live.has(b.rank))
|
|
65
|
-
.map((b) => ({
|
|
66
|
-
id: b.id != null ? String(b.id) : null,
|
|
67
|
-
// The login is what an operator needs to act; it is already visible to any
|
|
68
|
-
// caller authorised to read the roster, so this adds no exposure.
|
|
69
|
-
github_login: b.github_login || null,
|
|
70
|
-
rank: b.rank === undefined ? null : b.rank,
|
|
71
|
-
status: b.status || null,
|
|
72
|
-
}));
|
|
73
|
-
}
|
|
53
|
+
// The pure half lives in modules/autonomy/rank-roles.js (task 1004878), shared with
|
|
54
|
+
// the server's daily check (modules/autonomy/pollers/daily-checks.js) so the two
|
|
55
|
+
// cannot disagree about what an offender is. This wrapper defaults the ladder.
|
|
56
|
+
const rankRoles = require('../../modules/autonomy/rank-roles.js');
|
|
74
57
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
// nothing, which is the failure mode this whole task is about.
|
|
78
|
-
function summarize(rows) {
|
|
79
|
-
const counts = new Map();
|
|
80
|
-
for (const b of Array.isArray(rows) ? rows : []) {
|
|
81
|
-
const key = b && b.rank ? b.rank : '(none)';
|
|
82
|
-
counts.set(key, (counts.get(key) || 0) + 1);
|
|
83
|
-
}
|
|
84
|
-
return [...counts.entries()].sort((a, b) => b[1] - a[1]);
|
|
85
|
-
}
|
|
58
|
+
const findRanksWithoutRoles = (rows, liveRanks = LIVE_RANK_LADDER) => rankRoles.findRanksWithoutRoles(rows, liveRanks);
|
|
59
|
+
const { summarize } = rankRoles;
|
|
86
60
|
|
|
87
61
|
// Spawn capture.js rather than POSTing here, so idea filing keeps one
|
|
88
|
-
// implementation
|
|
62
|
+
// implementation. Best-effort: a failure to
|
|
89
63
|
// file must not turn a successful audit into a crash — the exit code and stdout
|
|
90
64
|
// still carry the finding.
|
|
91
65
|
function fileIdea(offenders) {
|
|
92
|
-
const
|
|
93
|
-
`${offenders.length} builder(s) hold a rank with no matching governance_roles row.`,
|
|
94
|
-
'',
|
|
95
|
-
'They resolve to ZERO permissions — admitted by rank threshold under requireRank,',
|
|
96
|
-
'refused by the permission resolver, and given no reason (ADR 0151 fail-closed).',
|
|
97
|
-
'',
|
|
98
|
-
...offenders.map((o) => `- builder ${o.id}${o.github_login ? ` (${o.github_login})` : ''} rank=${o.rank === null ? '(none)' : o.rank} status=${o.status || '?'}`),
|
|
99
|
-
'',
|
|
100
|
-
'Fix: move each to a live rank through the normal rank-change path, which rotates',
|
|
101
|
-
'the governance role in the same transaction. Not auto-repaired: changing a rank is',
|
|
102
|
-
'an authority decision, and a sweep is the wrong actor for it.',
|
|
103
|
-
'',
|
|
104
|
-
'Filed by scripts/bongos/audit-rank-roles.js (task 1002873).',
|
|
105
|
-
].join('\n');
|
|
66
|
+
const { title, bodyMd } = rankRoles.ideaFor(offenders);
|
|
106
67
|
const tmp = path.join(os.tmpdir(), `rank-roles-audit-${process.pid}.md`);
|
|
107
68
|
try {
|
|
108
|
-
fs.writeFileSync(tmp,
|
|
69
|
+
fs.writeFileSync(tmp, bodyMd, 'utf8');
|
|
109
70
|
const r = spawnSync(
|
|
110
71
|
process.execPath,
|
|
111
|
-
[path.join(__dirname, 'capture.js'),
|
|
112
|
-
`[rank-roles] ${offenders.length} builder(s) on a rank with no governance role`,
|
|
113
|
-
'--kind', 'bug', '--body-file', tmp],
|
|
72
|
+
[path.join(__dirname, 'capture.js'), title, '--kind', 'bug', '--body-file', tmp],
|
|
114
73
|
{ encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 60_000 }
|
|
115
74
|
);
|
|
116
75
|
if (r.status !== 0) console.error('audit-rank-roles: capture.js failed to file the idea — the exit code above still carries the finding.');
|
|
@@ -30,6 +30,8 @@
|
|
|
30
30
|
// node scripts/bongos/bump-version.js # dry-run: print the plan
|
|
31
31
|
// node scripts/bongos/bump-version.js --apply # rewrite both files
|
|
32
32
|
// node scripts/bongos/bump-version.js --apply --note "run 123456" # extra provenance
|
|
33
|
+
// node scripts/bongos/bump-version.js --apply --taken-file versions.json
|
|
34
|
+
// # skip every version in that JSON array (`npm view @bongos/core versions --json`)
|
|
33
35
|
// stdout (both modes): one JSON line { from, to, applied } for CI to capture.
|
|
34
36
|
|
|
35
37
|
'use strict';
|
|
@@ -51,12 +53,18 @@ const DIVIDER = '---------------------------------------------------------------
|
|
|
51
53
|
// entry appended too; omit it to bump the literal alone (the unit tests do).
|
|
52
54
|
// Throws with a precise message on any shape it does not recognize — a silent
|
|
53
55
|
// mis-edit of the version literal is the worst possible failure mode here.
|
|
54
|
-
|
|
56
|
+
//
|
|
57
|
+
// `taken` (task 1004886): versions that already exist on the registry. The bump
|
|
58
|
+
// lands on the first patch past `from` that is NOT taken, because npm never lets a
|
|
59
|
+
// version be published twice — and a run that "re-publishes" a taken number ships
|
|
60
|
+
// nothing new while main is told it did. That is how 1.21.175 got recorded on main
|
|
61
|
+
// on 2026-10-25 for a tree the registry's 1.21.175 (built 2026-10-23) never held.
|
|
62
|
+
function bumpPatch(src, { note = '', changelog = null, taken = new Set() } = {}) {
|
|
55
63
|
const m = src.match(CONST_RE);
|
|
56
64
|
if (!m) throw new Error(`bump-version: could not find the CORE_VERSION literal in ${TARGET} (expected: const CORE_VERSION = 'x.y.z';)`);
|
|
57
65
|
const [major, minor, patch] = [Number(m[1]), Number(m[2]), Number(m[3])];
|
|
58
66
|
const from = `${major}.${minor}.${patch}`;
|
|
59
|
-
const to =
|
|
67
|
+
const to = nextFreePatch(major, minor, patch, taken);
|
|
60
68
|
|
|
61
69
|
// 1. The literal — same line shape deploy-divergence greps for.
|
|
62
70
|
const newConstLine = `const CORE_VERSION = '${to}'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md`;
|
|
@@ -79,17 +87,40 @@ function bumpPatch(src, { note = '', changelog = null } = {}) {
|
|
|
79
87
|
return { from, to, text, changelogText };
|
|
80
88
|
}
|
|
81
89
|
|
|
90
|
+
// The first patch after `patch` whose version is not in `taken`. Bounded, so a
|
|
91
|
+
// corrupt taken-list can never spin: 10,000 consecutive taken patches is not a
|
|
92
|
+
// registry, it is a bug, and it throws.
|
|
93
|
+
function nextFreePatch(major, minor, patch, taken = new Set()) {
|
|
94
|
+
for (let p = patch + 1; p <= patch + 10000; p += 1) {
|
|
95
|
+
const v = `${major}.${minor}.${p}`;
|
|
96
|
+
if (!taken.has(v)) return v;
|
|
97
|
+
}
|
|
98
|
+
throw new Error(`bump-version: no free patch within 10000 of ${major}.${minor}.${patch} — the taken-list is not a registry listing`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Parse `npm view <pkg> versions --json` output into a Set of x.y.z strings. npm
|
|
102
|
+
// prints a bare string (not an array) when exactly one version exists. Anything
|
|
103
|
+
// that is not a strict x.y.z is dropped, so a stray line cannot become a version.
|
|
104
|
+
function registryVersions(jsonText) {
|
|
105
|
+
let v;
|
|
106
|
+
try { v = JSON.parse(String(jsonText)); } catch { return new Set(); }
|
|
107
|
+
const list = Array.isArray(v) ? v : (typeof v === 'string' ? [v] : []);
|
|
108
|
+
return new Set(list.filter((x) => typeof x === 'string' && /^\d+\.\d+\.\d+$/.test(x)));
|
|
109
|
+
}
|
|
110
|
+
|
|
82
111
|
function main() {
|
|
83
112
|
const apply = process.argv.includes('--apply');
|
|
84
113
|
const noteIdx = process.argv.indexOf('--note');
|
|
85
114
|
const note = noteIdx !== -1 ? (process.argv[noteIdx + 1] || '') : '';
|
|
115
|
+
const takenIdx = process.argv.indexOf('--taken-file');
|
|
116
|
+
const taken = takenIdx !== -1 ? registryVersions(fs.readFileSync(process.argv[takenIdx + 1], 'utf8')) : new Set();
|
|
86
117
|
|
|
87
118
|
// Read and transform BOTH files before writing EITHER: a half-applied bump
|
|
88
119
|
// (literal moved, ledger silent) is precisely the drift this script exists
|
|
89
120
|
// to prevent, and it would be committed and pushed to main before anyone saw it.
|
|
90
121
|
const src = fs.readFileSync(TARGET, 'utf8');
|
|
91
122
|
const changelog = fs.readFileSync(CHANGELOG, 'utf8');
|
|
92
|
-
const { from, to, text, changelogText } = bumpPatch(src, { note, changelog });
|
|
123
|
+
const { from, to, text, changelogText } = bumpPatch(src, { note, changelog, taken });
|
|
93
124
|
if (changelogText === null) throw new Error('bump-version: the ledger was not rewritten — refusing to write a versionless release');
|
|
94
125
|
if (apply) {
|
|
95
126
|
fs.writeFileSync(TARGET, text);
|
|
@@ -143,10 +174,13 @@ function isReleaseCommit(subject) {
|
|
|
143
174
|
// • pack or publish failed → the bump commit was never pushed (it only ever
|
|
144
175
|
// existed on the discarded runner), so no version looks taken and the next
|
|
145
176
|
// run recomputes and retries the SAME version. No gap, nothing burned.
|
|
146
|
-
// • published, push then failed → version looks free,
|
|
147
|
-
//
|
|
148
|
-
//
|
|
149
|
-
//
|
|
177
|
+
// • published, push then failed → version looks free to git, but the registry
|
|
178
|
+
// listing publish.yml passes as --taken-file has it, so the next run bumps PAST
|
|
179
|
+
// it (a gap in main's ledger, harmless). Task 1003914 used to treat npm's
|
|
180
|
+
// duplicate refusal as success and record the version instead — but the push
|
|
181
|
+
// fails precisely because main MOVED, so the recorded tree was never the one on
|
|
182
|
+
// the registry. That recorded 1.21.175 for 200+ commits npm never had (task
|
|
183
|
+
// 1004886). A duplicate refusal now fails the run and records nothing.
|
|
150
184
|
//
|
|
151
185
|
// Before that reorder the first case was the lossy one: the push landed first,
|
|
152
186
|
// so a failed publish left main declaring a version the registry never had, the
|
|
@@ -196,8 +230,9 @@ function isHumanReleaseCommit(subject) {
|
|
|
196
230
|
//
|
|
197
231
|
// BOTH failure directions stay safe, which is what makes this acceptable here. A
|
|
198
232
|
// subject wrongly counted → the lane bumps PAST a free version (a gap, harmless). A
|
|
199
|
-
// real release missed →
|
|
200
|
-
//
|
|
233
|
+
// real release missed → the registry listing marks it taken and the lane bumps past
|
|
234
|
+
// it; if even that read failed, npm refuses the duplicate and the run fails without
|
|
235
|
+
// recording anything (task 1004886). Neither direction can double-publish or mislabel.
|
|
201
236
|
function laneReleasedVersions(subjects = []) {
|
|
202
237
|
const out = new Set();
|
|
203
238
|
for (const subject of subjects) {
|
|
@@ -211,6 +246,8 @@ function laneReleasedVersions(subjects = []) {
|
|
|
211
246
|
|
|
212
247
|
module.exports = {
|
|
213
248
|
bumpPatch,
|
|
249
|
+
nextFreePatch,
|
|
250
|
+
registryVersions,
|
|
214
251
|
CONST_RE,
|
|
215
252
|
RELEASE_COMMIT_RE,
|
|
216
253
|
HUMAN_RELEASE_COMMIT_RE,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Shared fact-extractor for the onboarding diagrams (task #357).
|
|
2
2
|
//
|
|
3
3
|
// Single source of truth for "what the live system actually is", used by BOTH:
|
|
4
|
-
// - the drift checker
|
|
4
|
+
// - (formerly) the drift checker .claude/scheduled-tasks/diagram-drift/check.js, retired in task 1004878, which
|
|
5
5
|
// compares these facts against assertions.json and nudges on divergence; and
|
|
6
6
|
// - the generator (scripts/bongos/gen-diagrams.js), which regenerates the
|
|
7
7
|
// mechanical diagrams (.mmd) FROM these facts on every deploy.
|
package/scripts/bongos/do-api.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
// logs the call it WOULD make and returns a synthetic, clearly-marked
|
|
16
16
|
// result (`{ dryRun: true, ... }`) so the orchestrator's control flow runs
|
|
17
17
|
// end-to-end against a throwaway plan. This mirrors how provision-staging.sh
|
|
18
|
-
//
|
|
18
|
+
// ships runnable logic whose LIVE leg is a separate,
|
|
19
19
|
// explicit operator action.
|
|
20
20
|
// - Live mode requires a token (DO_API_TOKEN); the constructor throws clearly
|
|
21
21
|
// if asked to run live without one — it never silently no-ops a real call.
|
|
@@ -48,6 +48,8 @@ const DOC_CLI_ALLOW = new Map([
|
|
|
48
48
|
'an accepted ADR recording how its evidence was measured; the spike harness was deleted once the verdict stood (task 1004857) and the ADR names the commit to recover it from.'],
|
|
49
49
|
['docs/session-logs/2026-08-28-goal-1000072-stale-timer-and-network-map-spike.md::scripts/bongos/spike-task-map.js',
|
|
50
50
|
'a dated session log — the historical record, never rewritten — of the spike whose harness task 1004857 deleted; it describes what was run then, not what to run now.'],
|
|
51
|
+
['docs/session-logs/2026-09-16-task-1003752-stranded-detector-never-ran.md::scripts/bongos/gate-review.js',
|
|
52
|
+
'a dated session log — the historical record, never rewritten — naming the gate-review classifier task 1004859 deleted (its CI check never ran); it describes what was run then, not what to run now.'],
|
|
51
53
|
]);
|
|
52
54
|
|
|
53
55
|
// `node scripts/bongos/foo.js` … up to the end of the line/segment, so the flags that
|