@bongos/core 1.19.686 → 1.19.687

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 CHANGED
@@ -2,11 +2,11 @@
2
2
  "artifact": "bongos-core",
3
3
  "manifest_schema": 1,
4
4
  "generator": "scripts/gds/package-core.js",
5
- "core_version": "1.19.686",
6
- "core_contract": "1.19.686",
7
- "source_commit": "8f52ba91e493a99b11854b478933ac337d300c17",
5
+ "core_version": "1.19.687",
6
+ "core_contract": "1.19.687",
7
+ "source_commit": "80529e693e8b33d02d80143fce82b5300e5f0c01",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-09-12T21:51:30.504Z",
9
+ "built_at": "2026-09-12T23:13:15.800Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
12
  "docs_redacted": 477,
@@ -17,7 +17,7 @@
17
17
  "gate": "passed"
18
18
  },
19
19
  "file_count": 2626,
20
- "tree_sha256": "fe7db21bbf1cad87c2f341633ce01284a5dec1940e45febe42bb66534e623865",
20
+ "tree_sha256": "c85f4828bf21b1e106dfef13e6d603ea2774214cacdaf87ddbdb7f4242506e5c",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/ask-for-help/SKILL.md",
@@ -2802,7 +2802,7 @@
2802
2802
  {
2803
2803
  "path": "docs/module-api-changelog.md",
2804
2804
  "mode": "0000644",
2805
- "sha256": "048ac25e9d49525c5bbf927234ff4b2386134bc83978ac2c6ba1fcd86764d3a3"
2805
+ "sha256": "f596cd52ec02d7e08108da8ce76a21a085aa1455989496d6a8501d1d7955ec5a"
2806
2806
  },
2807
2807
  {
2808
2808
  "path": "docs/modules-contract.md",
@@ -5872,7 +5872,7 @@
5872
5872
  {
5873
5873
  "path": "modules/lifecycle/routes/claims.js",
5874
5874
  "mode": "0000644",
5875
- "sha256": "8a4f6d5513b97e84c44695b88e42c6e5bdc1875e97202be41caf6c739b2fa42e"
5875
+ "sha256": "9d4625ddaaa79e8496e05980153aca1a171d79aad3a32f1711be60be3be05955"
5876
5876
  },
5877
5877
  {
5878
5878
  "path": "modules/lifecycle/routes/closeness.js",
@@ -7782,12 +7782,12 @@
7782
7782
  {
7783
7783
  "path": "package-lock.json",
7784
7784
  "mode": "0000644",
7785
- "sha256": "8280f5610873fad997cfc9c6508c7bcdb9b3fe38ea34ac55b31b6a8a46931ab7"
7785
+ "sha256": "ad18930429a58c935061b8269dfea3c2fcbb1095eeff26859158679b9faf37d3"
7786
7786
  },
7787
7787
  {
7788
7788
  "path": "package.json",
7789
7789
  "mode": "0000644",
7790
- "sha256": "47a7ca80b0914f25810d596d5bce2393d5e3ee93bb302a82a34047c76799720d"
7790
+ "sha256": "f4d3a3c0536c755502e2f9bafaf07a54fda378a3394b22e0a3a3368992300073"
7791
7791
  },
7792
7792
  {
7793
7793
  "path": "public-docs/index.html",
@@ -9547,7 +9547,7 @@
9547
9547
  {
9548
9548
  "path": "src/module-api.js",
9549
9549
  "mode": "0000644",
9550
- "sha256": "1da978ad0d4fe540320d997da64154fb2780d80c346d1888cf6789e85f1c455d"
9550
+ "sha256": "c323740fa5182f9e2c200cdbd349d19753cf7d6f2faee9cf98ff44ba13249d2f"
9551
9551
  },
9552
9552
  {
9553
9553
  "path": "src/module-loader/catalog.js",
@@ -9702,7 +9702,7 @@
9702
9702
  {
9703
9703
  "path": "tests/api_path_404.mjs",
9704
9704
  "mode": "0000644",
9705
- "sha256": "427f5750b4115fc0ddd30f6f7f8202521d5b31300b191093bc98f8416bb4a228"
9705
+ "sha256": "82ca3700f6dd9d0aa88b39a0d6c45a03c20628201508b619e36a6d77ce0215ce"
9706
9706
  },
9707
9707
  {
9708
9708
  "path": "tests/app_pair.mjs",
@@ -1831,5 +1831,7 @@ is load-bearing: the script throws rather than guess if it is missing, and
1831
1831
  landed since 1.19.684 with no explicit bump. run 34719298791. (task 1002620)
1832
1832
  1.19.686 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1833
1833
  landed since 1.19.685 with no explicit bump. run 34721104118. (task 1002620)
1834
+ 1.19.687 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1835
+ landed since 1.19.686 with no explicit bump. run 34724811506. (task 1002620)
1834
1836
  ---------------------------------------------------------------------------
1835
1837
  ```
@@ -68,6 +68,28 @@ function taskNotReadyHint(taskId, currentStatus) {
68
68
  : `Task #${idNum} is '${currentStatus}', not 'ready' — only 'ready' tasks are claimable (promote applies to 'backlog': POST /api/bongos/tasks/${idNum}/promote).`;
69
69
  }
70
70
 
71
+ // task 1003768: the way-forward hint on a REBASE_REQUIRED 409 (ADR 0120 part 3's
72
+ // owed-rebase claim gate). Pure + exported so the wording is pinned by a test,
73
+ // the same contract taskNotReadyHint above carries.
74
+ //
75
+ // WHY THE MENU CHANGED. The old wording offered "(rebase its branch + re-ship, or
76
+ // /merge-mode)". /merge-mode cannot run on a builder machine with no GitHub push
77
+ // credential — and that is the DOCUMENTED DEFAULT posture, not a misconfiguration
78
+ // (ADR 0031 §6 / ADR 0055: landing is server-mediated, /builder-ship uploads a
79
+ // bundle and the SERVER pushes). Meanwhile /strand-fix — whose own frontmatter
80
+ // says it is "the fix for a claim refused 409 REBASE_REQUIRED" — went unmentioned.
81
+ // So the one exit that works everywhere was missing and the first one offered
82
+ // fails on auth for most readers. The gate was always clearable; the MENU was
83
+ // wrong, and this hint is the menu.
84
+ //
85
+ // Ordering is the fix: the universally-available command leads, /merge-mode is
86
+ // marked as needing a push credential rather than dropped (it is still the right
87
+ // tool on a credentialed machine), and /builder-release stays as the give-up exit.
88
+ function rebaseRequiredHint(rebaseTasks) {
89
+ const ids = (rebaseTasks || []).map((t) => `task ${t.id}`);
90
+ return `Your queue is gated: ${ids.length} confirmed task(s) await your rebase (${ids.join(', ') || 'unknown'}). Clear it with /strand-fix N (works on any machine), or rebase the branch and re-ship — /merge-mode only if this machine has a GitHub push credential. To give up on one instead, /builder-release it. If CI is simply backed up, waiting is correct: a task already landed clears the gate on its own.`;
91
+ }
92
+
71
93
  // task 1642 (+ the worktree-keying fix) — the pure one-active-claim decision.
72
94
  // Working two tasks from one WORKING TREE means every commit lands on the single
73
95
  // branch that tree owns; /builder-ship publishes the whole branch, so shipping one
@@ -343,8 +365,7 @@ module.exports = function buildClaimsRouter() {
343
365
  // ADR 0120 part 3: name the offending task(s) + the two ways to clear the
344
366
  // gate, so the builder isn't left guessing why their claim was refused.
345
367
  if (err.code === 'REBASE_REQUIRED') {
346
- const ids = (err.rebaseTasks || []).map((t) => `task ${t.id}`);
347
- err.hint = `Your queue is gated: ${ids.length} confirmed task(s) await your rebase (${ids.join(', ') || 'unknown'}). Land each (rebase its branch + re-ship, or /merge-mode) — or /builder-release it — then claim new work.`;
368
+ err.hint = rebaseRequiredHint(err.rebaseTasks);
348
369
  }
349
370
  // task 1002650: name the blocker(s) and the way forward — the same rule
350
371
  // the claimable feed enforces, spoken at the gate instead of a bare 409.
@@ -645,6 +666,10 @@ module.exports = function buildClaimsRouter() {
645
666
  module.exports.resolveCreatorSessionId = resolveCreatorSessionId;
646
667
  // V4.R14 (#952): the TASK_NOT_READY 409 hint — exported so its wording is pinned.
647
668
  module.exports.taskNotReadyHint = taskNotReadyHint;
669
+ // task 1003768: the REBASE_REQUIRED 409 hint — exported so its wording is pinned
670
+ // (tests/claim_gate_rebase.mjs). A remediation menu that names an impossible
671
+ // command is how a builder loses twenty minutes at a gate they met with no context.
672
+ module.exports.rebaseRequiredHint = rebaseRequiredHint;
648
673
  // task 1642: the pure session-scoped one-active-claim decision — exported for
649
674
  // tests/one_active_claim_per_session.mjs (DB-free) and reuse.
650
675
  module.exports.shouldRefuseSessionClaim = shouldRefuseSessionClaim;
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.686",
3
+ "version": "1.19.687",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.19.686",
9
+ "version": "1.19.687",
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.19.686",
3
+ "version": "1.19.687",
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/src/module-api.js CHANGED
@@ -71,7 +71,7 @@ const { responsibilityFor, ROLE_RESPONSIBILITIES } = require('./role-responsibil
71
71
  // there. scripts/gds/bump-version.js still rewrites the literal below; it appends
72
72
  // the entry to that file. Look for a version's history there, not here.
73
73
  // ---------------------------------------------------------------------------
74
- const CORE_VERSION = '1.19.686'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
74
+ const CORE_VERSION = '1.19.687'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
75
75
 
76
76
  // A namespaced logger so a module's log lines are attributable + consistent.
77
77
  // Usage: const log = api.logger('dev-box'); log.info('mounted');
@@ -6,8 +6,11 @@
6
6
  // hint, never the HTML island page (which JSON.parse-faulted on the client).
7
7
  // 2. A TASK_NOT_READY 409 names the promote route instead of leaving the caller
8
8
  // to spelunk for it (#506).
9
+ // 3. A REBASE_REQUIRED 409 offers exits the reader's machine can actually take
10
+ // (task 1003768) — it used to lead with /merge-mode, which needs a GitHub push
11
+ // credential most builder machines deliberately lack.
9
12
  //
10
- // Both are pinned via the pure exported helpers (no server, no DB).
13
+ // All three are pinned via the pure exported helpers (no server, no DB).
11
14
  //
12
15
  // Run: node tests/api_path_404.mjs
13
16
 
@@ -16,7 +19,7 @@ import { createRequire } from 'node:module';
16
19
 
17
20
  const require = createRequire(import.meta.url);
18
21
  const { isApiShapedPath, apiPathHint, apiNotFoundBody } = require('../src/bongos/api-path-404.js');
19
- const { taskNotReadyHint } = require('../modules/lifecycle/routes/claims.js');
22
+ const { taskNotReadyHint, rebaseRequiredHint } = require('../modules/lifecycle/routes/claims.js');
20
23
 
21
24
  let passed = 0;
22
25
  let failed = 0;
@@ -95,5 +98,51 @@ t('taskNotReadyHint: a non-backlog status is explained + still names promote', (
95
98
  assert.match(h, /POST \/api\/bongos\/tasks\/953\/promote/);
96
99
  });
97
100
 
101
+ // ---- rebaseRequiredHint (the 409) ------------------------------------------
102
+ // task 1003768. This gate fires at SESSION START and blocks every new claim, so a
103
+ // builder meets it before they have any context — which makes each command it names
104
+ // load-bearing. Pinned here rather than in tests/claim_gate_rebase.mjs because that
105
+ // suite needs Postgres and sits in the INTEGRATION set, so a pin there would never
106
+ // run in the gate that guards main.
107
+ t('rebaseRequiredHint: leads with /strand-fix, the exit that works on any machine', () => {
108
+ const h = rebaseRequiredHint([{ id: 1003529 }]);
109
+ const strand = h.indexOf('/strand-fix');
110
+ const mergeMode = h.indexOf('/merge-mode');
111
+ // Both indices are asserted present before they are compared: indexOf returns -1
112
+ // for a missing needle, and -1 < anything, so a bare `strand < mergeMode` would
113
+ // report PASS on a hint that had dropped /strand-fix entirely.
114
+ assert.ok(strand >= 0, 'the hint must name /strand-fix');
115
+ assert.ok(mergeMode >= 0, 'this pin assumes /merge-mode is still mentioned; update it if that changes');
116
+ assert.ok(strand < mergeMode, 'the universally-available command must come before the credentialed-machine one');
117
+ });
118
+
119
+ t('rebaseRequiredHint: never offers /merge-mode unconditionally', () => {
120
+ const h = rebaseRequiredHint([{ id: 1003529 }]);
121
+ // Landing is server-mediated and most builder machines hold no push credential
122
+ // BY DESIGN (ADR 0031 §6 / ADR 0055) — naming /merge-mode without that condition
123
+ // sends the reader to a command that fails on auth.
124
+ assert.match(h, /push credential/);
125
+ });
126
+
127
+ t('rebaseRequiredHint: keeps /builder-release as the give-up exit', () => {
128
+ assert.match(rebaseRequiredHint([{ id: 7 }]), /\/builder-release/);
129
+ });
130
+
131
+ t('rebaseRequiredHint: names every gating task, and degrades to "unknown" on none', () => {
132
+ const h = rebaseRequiredHint([{ id: 11 }, { id: 22 }]);
133
+ assert.match(h, /task 11, task 22/);
134
+ assert.match(h, /2 confirmed task\(s\)/);
135
+ // A gate that cannot name its cause is the failure mode this hint exists to avoid.
136
+ assert.match(rebaseRequiredHint([]), /unknown/);
137
+ assert.match(rebaseRequiredHint(undefined), /unknown/, 'a missing list must not throw');
138
+ });
139
+
140
+ t('rebaseRequiredHint: says waiting is correct when CI is merely backed up', () => {
141
+ // learning 1000209: an exhausted Actions budget flags every confirmed task
142
+ // REBASE_REQUIRED, and there the right move is to WAIT — re-shipping or releasing
143
+ // makes it worse. Cheap to say in the menu; not cheaply detectable server-side.
144
+ assert.match(rebaseRequiredHint([{ id: 7 }]), /waiting is correct/);
145
+ });
146
+
98
147
  console.log(`\napi_path_404: ${passed} passed, ${failed} failed`);
99
148
  process.exit(failed ? 1 : 0);