@bongos/core 1.19.824 → 1.19.825

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,22 +2,22 @@
2
2
  "artifact": "bongos-core",
3
3
  "manifest_schema": 1,
4
4
  "generator": "scripts/gds/package-core.js",
5
- "core_version": "1.19.824",
6
- "core_contract": "1.19.824",
7
- "source_commit": "95554434b3e9a6349986ebd50fb547858e7c0fbd",
5
+ "core_version": "1.19.825",
6
+ "core_contract": "1.19.825",
7
+ "source_commit": "cb729764661db914505acde16e83bf6db16e47fb",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-09-17T12:15:41.626Z",
9
+ "built_at": "2026-09-17T13:27:19.562Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
- "docs_redacted": 490,
12
+ "docs_redacted": 491,
13
13
  "agent_docs_stubbed": 26,
14
14
  "functional_verbatim": 2234,
15
15
  "rules": 3,
16
16
  "gate_literals": 3,
17
17
  "gate": "passed"
18
18
  },
19
- "file_count": 2750,
20
- "tree_sha256": "5eaa31427b8c53ddb2d3aa0a10a2e851968649d578993ab3c4412fc279e1014a",
19
+ "file_count": 2751,
20
+ "tree_sha256": "d080ea1d5501cd02f6af8cde89d25b58442a1abf7d282379bbf683df5b00ee33",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/ask-for-help/SKILL.md",
@@ -1979,10 +1979,15 @@
1979
1979
  "mode": "0000644",
1980
1980
  "sha256": "8fcac086f276e57b59ba635cdf34600bf78bfb69d80177d43065dfc6776b0611"
1981
1981
  },
1982
+ {
1983
+ "path": "docs/adr/0299-the-nod-queue-stays-scoped-to-routed-filings.md",
1984
+ "mode": "0000644",
1985
+ "sha256": "f52bf2568d02d5cf8589dc394dc76cbf0ea3a7ba193275f300e320c2ab64a51c"
1986
+ },
1982
1987
  {
1983
1988
  "path": "docs/adr/README.md",
1984
1989
  "mode": "0000644",
1985
- "sha256": "14c4e2e04bba4a0438375364a88e41eca44983ab0fb2c3ecd13bf0190f0ad151"
1990
+ "sha256": "0b4e0cd78a8bd6ae3d41c0d010634dfdc29ecd4dca1f8b49127791d1b4cd7450"
1986
1991
  },
1987
1992
  {
1988
1993
  "path": "docs/api-reference.md",
@@ -2547,7 +2552,7 @@
2547
2552
  {
2548
2553
  "path": "docs/module-api-changelog.md",
2549
2554
  "mode": "0000644",
2550
- "sha256": "a921ec8fff3a0bb3664431ff5f567e3660cb26dbc55a24012edcc7a1c52de4bd"
2555
+ "sha256": "bc4fb1f646f00a5ac5870be4468a5bcb94c1bc19d6c69eea48c54d63f5d0eb70"
2551
2556
  },
2552
2557
  {
2553
2558
  "path": "docs/modules-contract.md",
@@ -5422,7 +5427,7 @@
5422
5427
  {
5423
5428
  "path": "modules/ideas/inbox.js",
5424
5429
  "mode": "0000644",
5425
- "sha256": "36481a27a5921e3eb930268bf96bccd178259d3f7cce67b19b0dc4246f7d9bf1"
5430
+ "sha256": "683e2234893c9814c2ecec490099c140e273e764e993707bb1cc4c5c9d1baed3"
5426
5431
  },
5427
5432
  {
5428
5433
  "path": "modules/ideas/migrations/ideas_001_grades.sql",
@@ -7812,12 +7817,12 @@
7812
7817
  {
7813
7818
  "path": "package-lock.json",
7814
7819
  "mode": "0000644",
7815
- "sha256": "aa5cbab9d550e88355a4d19269ef77f0b414394f53d0a745dba09417158d42ae"
7820
+ "sha256": "2a7a81e9c97e32cc83b22d74eef060a6829d4e6847dfabaa9a851ebff576b151"
7816
7821
  },
7817
7822
  {
7818
7823
  "path": "package.json",
7819
7824
  "mode": "0000644",
7820
- "sha256": "50285f0725d1e9c6da37f0b47e3a64ad5f2084a81539eb2902ff9f75b7635ce0"
7825
+ "sha256": "67e42f1c6c167a0857846b43f877395adc67ce48ae72c31cc4709240906e6432"
7821
7826
  },
7822
7827
  {
7823
7828
  "path": "public-docs/index.html",
@@ -9737,7 +9742,7 @@
9737
9742
  {
9738
9743
  "path": "src/module-api.js",
9739
9744
  "mode": "0000644",
9740
- "sha256": "7bd07a13ff08f341820d14bfa056a4fff9715b0a63fbfb7f392e4d04b5336a15"
9745
+ "sha256": "8f04e8b51652109c0e95424fbc9801ed170b2bc899f91793ac827152e653c07a"
9741
9746
  },
9742
9747
  {
9743
9748
  "path": "src/module-loader/catalog.js",
@@ -0,0 +1,65 @@
1
+ # ADR 0299 — The nod queue stays scoped to routed filings; the backlog walk is the widening
2
+
3
+ **Status:** accepted · **Date:** 2026-09-17 · **Task:** [task 1003748](https://cloudbongos.com/builders#/task/1003748) (goal 1000089)
4
+
5
+ ## Context
6
+
7
+ `listRoutedAwaitingNod` (`modules/ideas/inbox.js`) feeds the "Reported work awaiting a
8
+ nod" slice of the Home attention card, and it filters `WHERE l.origin = 'route'`. On
9
+ 2026-09-08 that read returned 11 rows while 232 tasks sat at `backlog`. The task asked
10
+ whether a queue that omits ~95% of the un-nodded backlog is honestly named, or should
11
+ grow a second slice for un-routed rows. It noted two things that bound any widening:
12
+ dep-gated rows wait on a trigger (migration 163), not a person, so they must not be
13
+ shown as needing a nod; and [task 1003746](https://cloudbongos.com/builders#/task/1003746)
14
+ (`/backlog-review`) might make the question moot, so decide after that exists.
15
+
16
+ It exists now. Live numbers on 2026-09-17, from `node scripts/gds/backlog-review.js`:
17
+
18
+ | Bucket | Rows |
19
+ |---|---|
20
+ | waiting on a dependency (auto-promotes on ship) | 109 |
21
+ | spikes (backlog by convention, migration 020) | 2 |
22
+ | stranded (dep abandoned — trigger can never fire) | 1 |
23
+ | awaiting a nod (only a human gates it) | 3 |
24
+ | **total backlog** | **115** |
25
+
26
+ `GET /inbox/awaiting-nod` returned `count: 0`. `GET /inbox/rotting` returns 200 (the
27
+ route-shadowing bug the task mentioned no longer reproduces), with no rows past the
28
+ 30-day timer.
29
+
30
+ ## Decision
31
+
32
+ **Do not widen the nod queue or the card.** `origin='route'` stays the predicate.
33
+
34
+ 1. **The premise that ~220 rows had no path to a human is gone.** Of the rows the card
35
+ omits, 111 are correctly *not* a person's decision (109 dep-gated, 2 spikes). The
36
+ remaining 4 (3 nod + 1 stranded) are exactly what `/backlog-review` walks, goal by
37
+ goal, with the dependency predicate the task said any widening would need
38
+ (`include=deps` → per-edge `satisfied`). The widening the task asked for already
39
+ shipped — as a cadence skill, not a card slice.
40
+ 2. **The name is honest.** The card says *"Reported work awaiting a nod"* — reported
41
+ is the routed population. It never claimed to be the whole backlog.
42
+ 3. **A second slice would duplicate a partition.** The four-bucket split lives in
43
+ `backlog-review.js`; a card slice would need a second copy of the
44
+ stranded/dep-gated/spike rules in SQL, free to disagree with the walk. The rot
45
+ card already carries the same kind of warning about its verb list duplicated there.
46
+ 4. **The card is a push surface for filers.** A routed filing is someone waiting on an
47
+ answer; a planning-seeded backlog row is not. Mixing them dilutes the one signal
48
+ the card exists to carry (task 1003066, owner interview Q3).
49
+
50
+ ## Revisit when
51
+
52
+ - The *awaiting a nod* bucket of `/backlog-review` (not dep-gated, not spike, not routed)
53
+ grows past what one daily walk clears — then a Home count linking to the walk earns
54
+ its place. Show a **count and link**, not rows, and derive it from the same partition
55
+ the walk uses.
56
+ - `/backlog-review` stops being run — then the rot timer is again the only pull, and
57
+ this decision's first reason no longer holds.
58
+
59
+ ## Rejected
60
+
61
+ - A second "un-routed backlog" slice on the card (duplicates the partition; dilutes the
62
+ filer signal).
63
+ - Renaming the queue (the current copy already says *reported*).
64
+ - Dropping the origin filter and relying on `has_unshipped_dep` (would pull planning rows
65
+ and spikes into a surface built for filers).
@@ -390,3 +390,4 @@ This keeps the decision history honest and traceable.
390
390
  | 0296 | [**A role speciality is data over three existing surfaces, not a fourth mechanism** ([task 1003855](https://cloudbongos.com/builders#/task/1003855), goal 1000095). A craft says HOW you work; nothing said what you work ON. A speciality is a named bundle of knowledge, skills and an interaction contract sitting under a craft — an ideator with an Economics speciality. **Decision: it is DATA, not an ADR 0083 code module** — a subject-matter expert authors one, and requiring them to ship a package puts the mechanism out of reach of exactly the person it exists for. It layers over three surfaces that already exist (discipline-modes.json, the `behavior_prefs.interaction` contract path, the manifest contribution seam); only the knowledge bundle is new. The contract **rides the existing GET /me -> Conductor injection path rather than adding a second one**, and is CRAFT-SCOPED: the hook injects only the contract matching the claim in hand (which needed `t.discipline` on the active-claims read), and with no claim there is no craft and **nothing is injected** — silence beats guessing which expertise applies. Training is two-fold per the owner's 2026-09-17 ruling: documents they supplied, plus learnings captured from sessions worked in it (pointing at existing `learnings` rows, never a second corpus). The corpus is **inventoried, never inlined** — a document may run to 100k chars — so `speciality_documents` joins the recall ingester, because otherwise the contract's "search it with /recall" is a lie whose failure is silent. **`sellable` is recorded with no storefront behind it**: ADR 0107 defers the marketplace and explicitly rejected building one, so the flag captures the owner's decision when they make it and grants nothing — a deliberate partial implementation, recorded rather than silently made. Index scoping errs toward UNDER-sharing: only a public speciality's documents are corpus-wide, because `project` names a set the index cannot express.](0296-a-role-speciality-is-data-over-three-existing-surfaces.md) | roles / modules |
391
391
  | 0297 | [**A task’s creator may retire it, and that is the ownership axis’s first route** ([task 1002443](https://cloudbongos.com/builders#/task/1002443), goal 1000095 — owner request 2026-07-25: *"the creator of that task should be able to abandon that task directly inside of the UI"*). Attribution itself shipped earlier and elsewhere (`core_227`, [task 1003278](https://cloudbongos.com/builders#/task/1003278)); what had not moved is that **retiring a task was a rank power and nothing else** — `task.abandon` floors at `metic` (ADR 0152), so a sub-Metic builder could file a task and then could not withdraw their own proposal. The model already had the vocabulary and had never used it: ADR 0151 §3 defines an **ownership axis** where a `scope:'own'` key authorizes nothing until a handler supplies the row's owner, R100 made `requirePermission` refuse such a key outright so `.own` can never degrade into `.any`, and it recorded that **zero call sites passed one**. This is that axis’s first real consumer. **Decision: two authorities, only one rank-shaped** — `task.abandon` (metic, any task) OR new `task.abandon.own` (xenos, a task you created, while it is still backlog/ready/blocked). Route becomes `requireBuilder` + an in-handler decision (the `POST /goals/:id/members` shape), pin `metic+archon`→`any-builder` so it now catches an accidental **tightening** as loudly as a gate removal. **The two facts resolve in two places on purpose:** the RANK fact is request-scoped and resolves before the transaction (uncached, ADR 0016); the OWNER fact is a column that can change under us, so `created_by` joins `abandonTask`’s existing `FOR UPDATE` SELECT and a new optional `authorize` callback decides under that lock. Reading `created_by` in the route would be a TOCTOU window; resolving permissions inside the transaction would hold a row lock across a second pool acquire. The decision is a PURE module (`abandon-authz.js`, the `goal-route-authz.js` precedent) so every branch is pinned DB-free and the hall hint and server verdict provably read one rule. **A creator’s window stops at the grader** — completed/confirmed stay cross-owner, because past the grader a retire is a ledger correction, not an author changing their mind; nothing is subtracted from `task.abandon`, pinned by a test. `counterpart: ['task.abandon']` is declared not derived, verb `act` not `manage` — `manage` would silently dominate every future narrower `task.*.own` key (the verb-blind escalation task 1003195 closed). **A null creator belongs to nobody and that is load-bearing:** ~1,357 pre-`core_227` tasks plus seed/restock/discord vectors are unattributed, so the owner comparison is the government resolver’s own — injected, never re-implemented, since a duplicated ownership comparison is how one quietly widens — and one slip would open every historical task to a xenos grant at once. Fail-closed throughout: a missing `government` port, a throwing resolver, and anything but an explicit `{ok:true}` all deny, and `authorize` runs BEFORE the idempotent already-abandoned return and the shipped/active-claim guards so an unauthorized caller cannot probe a row through a 200. No guard removed. Does NOT widen edit/promote/dependency (still Metic), does not touch `task.merge`, and does not backfill attribution — the control simply does not appear on tasks predating `core_227`.](0297-a-tasks-creator-may-retire-it.md) | authority / lifecycle / ownership |
392
392
  | 0298 | [**The grader gets a reader lens: advisory, scoped to copy-bearing diffs, and it waits on a written voice** ([task 1003937](https://cloudbongos.com/builders#/task/1003937), goal 1000095 — Working area 6; owner decision 2026-09-17). Every artist review the cascade files opened with *“REVIEW THE GRADER … coach it”*, and it could not be followed: the v4 panel runs narc, quality, hacker and efficiency — completion, code quality, security, runtime cost — and not one of them reads a sentence for whether it is true, clear, in the project’s voice or worth a person’s attention. Four consecutive reviews hit the same wall and all four graded ships deservedly PASSED on the axes that were measured; the gate is not lenient, it is not pointed at this. `grader-prompt.js` already injects the craft’s written responsibility, but only when `discipline === ‘artist’`, so the unjudged case is copy shipped by someone whose craft is not the copy. **Decision: a fifth ADVISORY `reader` worker, on three settled terms.** It runs only where `modules/lifecycle/cascade.js`’s existing `hasCopyOrVisualWork` says the ship is copy-bearing — the same predicate the after-the-fact review uses, so the two can never disagree about coverage, and every other ship costs exactly what it costs today. It records `issues[]` and a `copy_score` and can never verdict `fail` or drag the panel to `concerns`, because [ADR 0241](0241-the-artist-gate-is-a-per-project-deploy-gate-that-reads-a-state.md) put the artist’s judgement on the DEPLOY and off the ship path; gating would need that ADR amended first. And it is NOT BUILT until the instance writes a voice guide — today the whole written standard is one dash rule in `DESIGN.md`, a tagline, a registry of which 1,860 strings exist, and one responsibility sentence, so a lens built now would record taste and call it a finding. Until the reader exists, STEP 1 asks the artist to WRITE DOWN what the grade could not see rather than to coach a lens that is not listening — followable today, and the corpus both the guide and the lens get written from. Nothing in the rubric, the active panel or any existing worker changes.](0298-the-reader-lens-is-advisory-and-waits-on-a-voice-guide.md) | grading / the artist’s loop / voice |
393
+ | 0299 | [**The nod queue stays scoped to routed filings; the backlog walk is the widening** ([task 1003748](https://cloudbongos.com/builders#/task/1003748), goal 1000089). `listRoutedAwaitingNod` filters `origin='route'`, and on 2026-09-08 showed 11 of 232 backlog rows. Re-measured after `/backlog-review` (task 1003746) shipped: 115 backlog rows = 109 dep-gated + 2 spikes (not a person's decision) + 1 stranded + 3 awaiting a nod, all four walked by `/backlog-review`. **Decision: do not widen the card.** The omitted population already has a walkable review with the dependency predicate any widening needed; the copy says *reported* work, so the name is honest; a card slice would be a second copy of the walk's four-bucket partition. Revisit if the un-routed nod bucket outgrows a daily walk (then a count + link, derived from the same partition) or if the walk stops being run.](0299-the-nod-queue-stays-scoped-to-routed-filings.md) | ideas / backlog / attention |
@@ -2122,5 +2122,7 @@ is load-bearing: the script throws rather than guess if it is missing, and
2122
2122
  landed since 1.19.822 with no explicit bump. run 35218585239. (task 1002620)
2123
2123
  1.19.824 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
2124
2124
  landed since 1.19.823 with no explicit bump. run 35220051893. (task 1002620)
2125
+ 1.19.825 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
2126
+ landed since 1.19.824 with no explicit bump. run 35227106979. (task 1002620)
2125
2127
  ---------------------------------------------------------------------------
2126
2128
  ```
@@ -891,7 +891,9 @@ async function sourceIdeaForTask(taskId) {
891
891
  //
892
892
  // Scoped by the lineage row (origin='route'), not by status alone — a task can be
893
893
  // at backlog for a dozen unrelated reasons, and this queue is specifically "a
894
- // person reported this and the system is waiting on a human". It reads the FILER
894
+ // person reported this and the system is waiting on a human". Widening it to the
895
+ // rest of the backlog was weighed and declined (ADR 0299): /backlog-review walks
896
+ // that population with the dependency split this read lacks. It reads the FILER
895
897
  // too (captured_by), because Q3's copy calls the pending state "awaiting a nod"
896
898
  // and shows kind + who filed it.
897
899
  //
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.824",
3
+ "version": "1.19.825",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.19.824",
9
+ "version": "1.19.825",
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.824",
3
+ "version": "1.19.825",
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.824'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
74
+ const CORE_VERSION = '1.19.825'; // 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');