@bongos/core 1.19.701 → 1.19.702

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.701",
6
- "core_contract": "1.19.701",
7
- "source_commit": "6c01baa69654043099e16c9bf0353eff61d2012d",
5
+ "core_version": "1.19.702",
6
+ "core_contract": "1.19.702",
7
+ "source_commit": "3b1a2e8029758a6ee091812baccb9e24fdc4670a",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-09-13T03:22:47.893Z",
9
+ "built_at": "2026-09-13T03:33:51.903Z",
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": 2631,
20
- "tree_sha256": "640bb539971ad78a750aa80116d26c7f1f81fc1b2afb21ef0fd33855189fe10a",
20
+ "tree_sha256": "7bf1dff3812c90015cc9d2476643856d5c6e9e950d26c6859e219c0eab9796b5",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/ask-for-help/SKILL.md",
@@ -227,7 +227,7 @@
227
227
  {
228
228
  "path": ".claude/skills/planning-session/SKILL.md",
229
229
  "mode": "0000644",
230
- "sha256": "2cb49f8643cf49664c1b9371e7ca4bce605eaa58c1806a32d3c98dcb517c3ad9"
230
+ "sha256": "701d484d1ae558257d0f319d9b684b242294f24602e98186b8c19ffa58459711"
231
231
  },
232
232
  {
233
233
  "path": ".claude/skills/priority-session/SKILL.md",
@@ -2802,7 +2802,7 @@
2802
2802
  {
2803
2803
  "path": "docs/module-api-changelog.md",
2804
2804
  "mode": "0000644",
2805
- "sha256": "4fc39aaaae76afb8153485474fc9f3459a2ee380b96f59d1d693a4a7680db464"
2805
+ "sha256": "7458093aecd8dd3fcc7753356a12e995b25663e9251a295c406e4ecc4cc54c27"
2806
2806
  },
2807
2807
  {
2808
2808
  "path": "docs/modules-contract.md",
@@ -7782,12 +7782,12 @@
7782
7782
  {
7783
7783
  "path": "package-lock.json",
7784
7784
  "mode": "0000644",
7785
- "sha256": "f7fb304e4955f8024186863281f2540c2e92299e49b16f7f6ea0f78c6d46d22a"
7785
+ "sha256": "1aa096840e001b544038432419a0e07577014954f7cb83d8e19c716704e3f36c"
7786
7786
  },
7787
7787
  {
7788
7788
  "path": "package.json",
7789
7789
  "mode": "0000644",
7790
- "sha256": "be0e756de883b5e3291f721efe8515540771994df5d83f0eb96bd07f87ecf1e8"
7790
+ "sha256": "cee79b868fecce6053d7d04108233e795a92c3635854bea1bf3003b909953e20"
7791
7791
  },
7792
7792
  {
7793
7793
  "path": "public-docs/index.html",
@@ -9552,7 +9552,7 @@
9552
9552
  {
9553
9553
  "path": "src/module-api.js",
9554
9554
  "mode": "0000644",
9555
- "sha256": "2fdd8c72769bba600991d5c886878c7390ef2086f67ad8c1036555e45631a971"
9555
+ "sha256": "be1bd4054da76be7eb7aa62d3e9ee2805de116d811e25043a49bbd4731ad1643"
9556
9556
  },
9557
9557
  {
9558
9558
  "path": "src/module-loader/catalog.js",
@@ -11912,7 +11912,7 @@
11912
11912
  {
11913
11913
  "path": "tests/planning_session_skill.mjs",
11914
11914
  "mode": "0000644",
11915
- "sha256": "1f2d52192e96bc1f2693a4b1a8458bc0f533e9c971c9ac42d9199e11d01eec48"
11915
+ "sha256": "bdf3a2d275c6f40fd1c3b8fbb16f39724227496ce8e38b89b408384610d3df7e"
11916
11916
  },
11917
11917
  {
11918
11918
  "path": "tests/platform_boot.mjs",
@@ -279,12 +279,35 @@ Once the spec is finalized (Phase 4), **read `docs/specs/<ver>-<goal-slug>.md` a
279
279
 
280
280
  5. **Run the seed script.** Verify exit code 0 — the seed's own final step (the Seeding contract's `verifySeedCriteriaLinks` call, above) already fails loudly if any criterion's linked task count doesn't match the plan, so a 0 exit means the links landed correctly, not just that the POSTs didn't error. Also spot-check totals via `GET /api/gds/public/progress` and `GET /api/gds/versions/<ver>/done-when`.
281
281
 
282
- 6. **Promote the zero-dep layer to `ready`.** Every newly-seeded task lands `status='backlog'`. The auto-promotion trigger only fires when a *dependency* ships — so a task with zero deps has nothing to wait for and would sit unclaimable forever. Run, in the same psql session as the migration (or via SSH to the droplet):
282
+ 6. **Promote the zero-dep layer to `ready` — scoped to the tasks you just seeded.** Every newly-seeded task lands `status='backlog'`. The auto-promotion trigger only fires when a *dependency* ships — so a task with zero deps has nothing to wait for and would sit unclaimable forever.
283
+
284
+ **Scope this to your own seed, and never to the whole version** (task 1001438). `version_id + status='backlog' + kind<>'spike' + no dep edge` also describes rows that are sitting at `backlog` **on purpose**, and promoting those is a silent, unlogged override of another subsystem's decision:
285
+ - **cascade-filed tasks** — `cascade.js` files generated work at `backlog`, **never** `ready`, as one of its four pinned properties (`modules/lifecycle/CLAUDE.md`; task 1003549). A cascade task has no dependency edge, so an unscoped promote flips exactly the rows that guarantee says it never will.
286
+ - **restored tasks** — `POST /tasks/:id/promote` → `db.restoreTask` returns an abandoned task to `backlog` so a human re-scopes the dead edge deliberately (owner ruling 2026-08-21, ADR-backed in `modules/lifecycle/CLAUDE.md`). Promoting it straight to `ready` is the "silently release work built on something that was never built" outcome that ruling forbids.
287
+
288
+ Both are ordinary carry-overs in any version that has been live for a while, so the blast radius grows the longer an instance runs.
289
+
290
+ Every seed script POSTs with `source: 'planning-session'` and a per-seed `source_ref` prefix (see `scripts/gds/<redacted>.js`), which is the handle to scope by — it needs no id transcription and cannot drift from what the seed actually created. **Dry-run the SELECT first and read the rows**, in the same psql session as the migration (or via SSH to the droplet):
291
+
292
+ ```sql
293
+ SELECT id, title, priority, kind
294
+ FROM tasks
295
+ WHERE version_id = '<ver>'
296
+ AND source = 'planning-session'
297
+ AND source_ref LIKE '<seed-ref-prefix>-%'
298
+ AND status = 'backlog'
299
+ AND kind <> 'spike'
300
+ AND id NOT IN (SELECT task_id FROM task_dependencies);
301
+ ```
302
+
303
+ The count must match the zero-dep tasks your seed script just created. If it is larger, your `source_ref` prefix is catching an earlier seed — narrow it (or fall back to the explicit list, `AND id = ANY('{<seeded ids>}')`) before writing anything. Then re-run it as the UPDATE:
283
304
 
284
305
  ```sql
285
306
  UPDATE tasks
286
307
  SET status = 'ready', promoted_at = now()
287
308
  WHERE version_id = '<ver>'
309
+ AND source = 'planning-session'
310
+ AND source_ref LIKE '<seed-ref-prefix>-%'
288
311
  AND status = 'backlog'
289
312
  AND kind <> 'spike'
290
313
  AND id NOT IN (SELECT task_id FROM task_dependencies)
@@ -1861,5 +1861,7 @@ is load-bearing: the script throws rather than guess if it is missing, and
1861
1861
  landed since 1.19.699 with no explicit bump. run 34735048203. (task 1002620)
1862
1862
  1.19.701 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1863
1863
  landed since 1.19.700 with no explicit bump. run 34735311256. (task 1002620)
1864
+ 1.19.702 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1865
+ landed since 1.19.701 with no explicit bump. run 34735775228. (task 1002620)
1864
1866
  ---------------------------------------------------------------------------
1865
1867
  ```
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.701",
3
+ "version": "1.19.702",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.19.701",
9
+ "version": "1.19.702",
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.701",
3
+ "version": "1.19.702",
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.701'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
74
+ const CORE_VERSION = '1.19.702'; // 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');
@@ -91,5 +91,48 @@ test('the step is scoped to process-change sessions, not every planning session'
91
91
  assert.ok(/skip/i.test(section), 'says explicitly when to skip it');
92
92
  });
93
93
 
94
+ // --- task 1001438: the Phase 5 promote must be scoped to the seeded set -----
95
+ // The bug was an UPDATE filtered only by version_id + backlog + non-spike +
96
+ // zero-dep. That predicate also describes rows parked at `backlog` ON PURPOSE —
97
+ // cascade.js files generated work at backlog and never ready (one of its four
98
+ // pinned properties), and db-ship.js restoreTask returns an abandoned task to
99
+ // backlog so a human re-scopes the dead edge. Neither carries a dependency edge,
100
+ // so an unscoped promote silently overrides both. These pin the scoping so the
101
+ // narrowing cannot be dropped back out during a later edit of this step.
102
+
103
+ function promoteStep() {
104
+ const start = NORM.indexOf('Promote the zero-dep layer');
105
+ assert.notEqual(start, -1, 'the Phase 5 promote step must still exist');
106
+ const end = NORM.indexOf('Surface higher-priority spikes', start);
107
+ return NORM.slice(start, end === -1 ? undefined : end);
108
+ }
109
+
110
+ test('the Phase 5 promote is scoped to the seeded set, not the whole version', () => {
111
+ const step = promoteStep();
112
+ // Either handle is acceptable — the source_ref prefix (no id transcription) or
113
+ // the explicit id list the row originally proposed.
114
+ assert.ok(
115
+ step.includes('source_ref LIKE') || step.includes("id = ANY('{"),
116
+ 'the promote must carry a seed-scoped predicate, not version_id alone',
117
+ );
118
+ assert.ok(step.includes("source = 'planning-session'"), 'names the seed source it scopes by');
119
+ });
120
+
121
+ test('the promote step says WHY scoping matters, naming both kinds of deliberate backlog row', () => {
122
+ const step = promoteStep();
123
+ assert.ok(/cascade/i.test(step), 'names cascade-filed tasks');
124
+ assert.ok(/restore/i.test(step), 'names restored (formerly abandoned) tasks');
125
+ // A reader who only sees "scope it" will widen it again the first time the
126
+ // narrow filter is inconvenient. The reason is the durable half.
127
+ assert.ok(/on purpose|deliberate/i.test(step), 'says these rows sit at backlog deliberately');
128
+ });
129
+
130
+ test('the operator is told to dry-run the SELECT before the UPDATE', () => {
131
+ const step = promoteStep();
132
+ assert.ok(/SELECT id, title, priority, kind/.test(step), 'a read-only form of the query is shown first');
133
+ assert.ok(/dry-run/i.test(step), 'labels it as a dry run');
134
+ assert.ok(step.indexOf('SELECT id, title') < step.indexOf('UPDATE tasks'), 'the SELECT comes before the UPDATE');
135
+ });
136
+
94
137
  console.log(`\nplanning_session_skill: ${passed} passed, ${failed} failed`);
95
138
  if (failed > 0) process.exit(1);