@bongos/core 1.19.493 → 1.19.495
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 +419 -14
- package/.claude/skills/builder-redteam/SKILL.md +2 -2
- package/docs/adr/0234-idea-routing-capture-time-promotion-landing-matrix-homeless-inbox.md +183 -0
- package/docs/adr/README.md +1 -0
- package/docs/design/reviews/hall-v2/README.md +124 -0
- package/docs/design/reviews/hall-v2/atlas--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/atlas--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/atlas--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/collab--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/collab--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/collab--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/copy-desk--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/copy-desk--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/copy-desk--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/diagrams--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/diagrams--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/diagrams--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/drachmae--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/drachmae--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/drachmae--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/gate--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/gate--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/gate--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/goals--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/goals--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/goals--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/government--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/government--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/government--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/harbor--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/harbor--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/harbor--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/idea--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/idea--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/idea--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/ideas--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/ideas--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/ideas--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/index--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/index--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/index--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/modules--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/modules--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/modules--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/not-ready--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/not-ready--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/not-ready--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/pair--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/pair--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/pair--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/people--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/people--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/people--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/primer--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/primer--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/primer--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/profile--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/profile--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/profile--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/ranks--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/ranks--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/ranks--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/roadmap--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/roadmap--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/roadmap--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/roster--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/roster--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/roster--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/sessions--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/sessions--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/sessions--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/settings--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/settings--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/settings--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/task--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/task--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/task--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/watch--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/watch--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/watch--xenos.webp +0 -0
- package/docs/design/reviews/hall-v2/work--archon.webp +0 -0
- package/docs/design/reviews/hall-v2/work--metic.webp +0 -0
- package/docs/design/reviews/hall-v2/work--xenos.webp +0 -0
- package/docs/module-api-changelog.md +4 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/src/module-api.js +1 -1
- package/tests/redteam_followup_kind.mjs +44 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# 0234 — Idea routing: capture-time promotion, the landing matrix, and the homeless-only inbox
|
|
2
|
+
|
|
3
|
+
- **Status:** Accepted
|
|
4
|
+
- **Date:** 2026-09-03
|
|
5
|
+
- **Tasks:** [#1003064](https://cloudbongos.com/builders#/task/1003064) (R14 of goal 1000071, "Idea routing") — records the mechanism R01/R02/R05/R07 built and the identity R13 gave the inbox
|
|
6
|
+
- **Spec:** [`docs/specs/<redacted>.md`](../specs/<redacted>.md) — "Design decisions & assumptions" + "Interview decisions"
|
|
7
|
+
- **Related:** ADR 0084 (auto-derived per-task rank floor), ADR 0086 (goal-scoped work hierarchy), ADR 0016 (trust boundary, server-enforced), ADR 0172 (ideator credit lane, the lineage this feeds)
|
|
8
|
+
|
|
9
|
+
## Context
|
|
10
|
+
|
|
11
|
+
Idea 1000771 named the failure this goal exists to close: Discord `#bugs` created tasks **directly**
|
|
12
|
+
(`createTask`, no `idea_inbox` row) against a **hardcoded, already-shipped** version id. Every bug
|
|
13
|
+
reported through that channel landed in a version catch-all nobody would ever reopen, and — the worse
|
|
14
|
+
half — no `captured_by`, no `ideas_task_lineage` row, so the ideator-credit lane (goal 1000067) had
|
|
15
|
+
nothing to ever pay against. The reporter vanished from the record the moment their report became work.
|
|
16
|
+
|
|
17
|
+
Meanwhile the *other* 49 open `idea_inbox` rows sat waiting for a human triage pass that, on
|
|
18
|
+
promotion, dropped the resulting task into "`<version> — general`" — because nothing in the capture
|
|
19
|
+
path had ever named a goal. Work that plainly had a home (a bug in a live feature, a feature request
|
|
20
|
+
against an open goal) got no closer to that home than a homeless idea did.
|
|
21
|
+
|
|
22
|
+
This ADR records what shipped to fix both: five tasks (R01–R03, R05, R07) plus the promote-path change
|
|
23
|
+
(R13), all now `shipped`.
|
|
24
|
+
|
|
25
|
+
## Decision
|
|
26
|
+
|
|
27
|
+
### 1. Routing is capture-time promotion, inside `captureIdea` — never a second door
|
|
28
|
+
|
|
29
|
+
`inbox.captureIdea` (`modules/ideas/inbox.js:225`, task 1003065 / R01) is documented in its own header
|
|
30
|
+
as **"THE ONE CAPTURE CHOKEPOINT"** — every filing vector (hall, `capture.js`, the Discord `#ideas`
|
|
31
|
+
inbound via the `ideas.capture` port, agents, seeds) already funnels through it, so routing was added
|
|
32
|
+
as one optional argument (`goalId`) rather than a sibling `captureAndRoute` function. The module's own
|
|
33
|
+
comment names the reason explicitly: *"A `captureAndRoute` sibling would have been the same code with
|
|
34
|
+
an invitation to bypass it."* That is the direct, structural answer to the Discord `#bugs` lesson — a
|
|
35
|
+
second creation path is exactly the shape idea 1000771 was.
|
|
36
|
+
|
|
37
|
+
When the landing matrix (below) says **don't route**, `captureIdea` runs the pre-routing INSERT
|
|
38
|
+
unchanged — `idea_inbox` status `'open'`, no task. This is the default path and is what every
|
|
39
|
+
goal-unaware caller still gets (routing is strictly additive).
|
|
40
|
+
|
|
41
|
+
When the matrix says **route**, `routeIdeaToGoal` (`modules/ideas/inbox.js:303`) runs **one
|
|
42
|
+
transaction**: the idea row (`status='promoted'`, `reviewed_at` stamped — routing's whole claim is
|
|
43
|
+
that this row never needed a triage pass), the task via the `lifecycle.createTask` kernel port, and an
|
|
44
|
+
`ideas_task_lineage` row with `origin='route'`. The order is forced by foreign keys (idea → task →
|
|
45
|
+
lineage), and the module's own comment states the stakes: *"THE TRANSACTION IS THE POINT, not an
|
|
46
|
+
optimisation... A route that committed the task but lost the lineage row would manufacture exactly
|
|
47
|
+
that bug, at scale, on the path whose whole promise is that attribution survives (criterion C3)."* If
|
|
48
|
+
any step fails, the whole thing rolls back and the filer's report is never silently lost mid-flight.
|
|
49
|
+
|
|
50
|
+
`captureIdea` treats `filerRank`/`grade` as **read-only inputs to the decision** — it performs no
|
|
51
|
+
authority check itself; that is R05's job (below), a deliberately separate, load-bearing gate.
|
|
52
|
+
|
|
53
|
+
### 2. The landing matrix, as shipped (`modules/ideas/routing.js`, task 1003065 / R01 + task 1003066 / R05)
|
|
54
|
+
|
|
55
|
+
`decideLanding()` is a pure, DB-free function — no clock, no rank lookup — so every cell is pinned by
|
|
56
|
+
`tests/idea_routing.mjs` without touching Postgres. Its posture is explicitly **fail-closed**: every
|
|
57
|
+
uncertainty resolves toward "don't route" or "route to backlog", never toward `'ready'`.
|
|
58
|
+
|
|
59
|
+
| Filed thing | Filer rank | Landing (as shipped) |
|
|
60
|
+
|---|---|---|
|
|
61
|
+
| No goal named | any | `idea_inbox`, `status='open'` — the default path (reason: `no_goal`) |
|
|
62
|
+
| `grade='full'` (Full Idea) | any | Never routes — the Board Room's subject (reason: `full_idea_never_routes`) |
|
|
63
|
+
| `kind` ∈ {`criterion-proposal`, `decision`} | any | Never routes — judgment work (reason: `judgment_kind`) |
|
|
64
|
+
| `kind='bug'` with a goal | Metic or Archon | Task in the goal, `status='ready'` (reason: `bug_trusted_filer`) |
|
|
65
|
+
| `kind='bug'` with a goal | sub-Metic / unknown | Task in the goal, `status='backlog'` (reason: `bug_awaiting_nod`) |
|
|
66
|
+
| Anything else with a goal (feature, cleanup, refactor, infra, or an unrecognised kind) | any | Task in the goal, `status='backlog'` (reason: `soft_landing`) |
|
|
67
|
+
|
|
68
|
+
This matches the spec's table (`docs/specs/<redacted>.md` "Landing matrix") exactly for the
|
|
69
|
+
hard-land/soft-land split. Priority on a routed task defaults to the idea's own `suggested_priority`,
|
|
70
|
+
clamped to 1–5, else `3` (`routedPriority`) — precisely the "decided without interview" line the spec
|
|
71
|
+
records.
|
|
72
|
+
|
|
73
|
+
`decideLanding` only decides the **status**; it grants nothing. `authorizeRoutedLanding`
|
|
74
|
+
(`modules/ideas/routing.js:169`, task 1003066 / R05) is the **binding** gate `routeIdeaToGoal` calls
|
|
75
|
+
before it writes anything, and it closes a hole the matrix alone left open: a routed task declares no
|
|
76
|
+
`touches[]`, so the ordinary ADR 0084/0085 rank-floor derivation would land it at `xenos` even when the
|
|
77
|
+
goal's `scope_modules` reach protected territory (the permission/ship-grade/deploy/migration core).
|
|
78
|
+
Two rules, ordered and fail-closed (the `authorizeGoalTaskCreate` precedent):
|
|
79
|
+
|
|
80
|
+
- **Touches declared** (a programmatic filer that knows its own blast radius) → `goalScopeCheck.check`
|
|
81
|
+
runs verbatim, refusals and all — the same wall `POST /goals/:id/tasks` applies to an authored task.
|
|
82
|
+
- **Touches absent** (every human filing — demanding touches[] as the price of reporting a bug is
|
|
83
|
+
exactly the triage tax this goal removes) → protection moves to the **claim side**: a goal whose
|
|
84
|
+
scope reaches protected territory raises the task's `requires_rank` floor to `metic`
|
|
85
|
+
(`PROTECTED_SCOPE_FLOOR`), and — the part R05 tightened after its first cut — a **sub-Metic filer is
|
|
86
|
+
refused outright** (`ROUTE_NOT_AUTHORIZED` / `protected_scope`, HTTP 403) rather than merely having
|
|
87
|
+
the floor stamped on afterward. The refusal costs the filer nothing they had before: omit `goal_id`
|
|
88
|
+
and the report files to the inbox exactly as it always did.
|
|
89
|
+
|
|
90
|
+
**Membership is deliberately not required to route into a goal**, and the module's comment names this
|
|
91
|
+
as the one place the routed path diverges from the authored one on purpose: `authorizeGoalTaskCreate`
|
|
92
|
+
refuses a non-member (`not_a_member`) because *authoring* inside someone's workspace is a member's
|
|
93
|
+
privilege, but *reporting* is not — criterion C5's promise ("the filer never has to know the goal map")
|
|
94
|
+
and C1's ("a bug filed anywhere lands in its home") both require that a non-member can still route a
|
|
95
|
+
report in. The safety membership would have carried moves instead to the rank floor (claim side) and
|
|
96
|
+
the matrix (ready side), and is pinned by a test rather than left to erode quietly.
|
|
97
|
+
|
|
98
|
+
### 3. The schema: one advisory hint column, one widened CHECK (task 1003060 / R02)
|
|
99
|
+
|
|
100
|
+
`migrations/<redacted>.sql` adds `idea_inbox.suggested_goal_id` (nullable FK
|
|
101
|
+
`ON DELETE SET NULL`) — **not** where a routed idea's goal lives (that is `tasks.goal_id`, set by
|
|
102
|
+
construction), but the leftover hint for rows that did **not** convert: soft-landed/homeless ideas, a
|
|
103
|
+
Discord classifier's guess, Full Ideas and criterion-proposals. The migration's own comment is explicit
|
|
104
|
+
that the column is "load-bearing for NOTHING — no rank check, no scope wall, and no payout may read
|
|
105
|
+
it." It lives in **core** migrations, not a module migration, because `idea_inbox` is a core table and
|
|
106
|
+
`fitness.js`'s `checkModuleMigrationsAdditive` forbids a module `ALTER TABLE` against it.
|
|
107
|
+
|
|
108
|
+
`modules/ideas/migrations/<redacted>.sql` widens `ideas_task_lineage`'s CHECK to
|
|
109
|
+
admit a third `origin`: `'route'`, alongside the pre-existing `'promote'` (a human triaged it) and
|
|
110
|
+
`'develop'` (a spark became a Full Idea). The distinction is deliberate — "how much triage routing
|
|
111
|
+
actually saved" (criterion C6) is only answerable if capture-time conversions are tagged differently
|
|
112
|
+
from later human promotions in the ledger.
|
|
113
|
+
|
|
114
|
+
### 4. The suggester answers "which goal" *before* anything is created (task 1003062 / R07)
|
|
115
|
+
|
|
116
|
+
`modules/lifecycle/goal-suggest.js` lifts the candidate logic `buildGoalAdvisory` already had (goal
|
|
117
|
+
1000071's "Reuse, do not rebuild" table) into a **pure, creation-free read**: `suggestGoals(goals,
|
|
118
|
+
draft, opts)` ranks open goals against a draft title/body by weighted token overlap (title terms
|
|
119
|
+
weight 2, body terms weight 1 — the `criterion-suggest.js` precedent), returning `[]` rather than five
|
|
120
|
+
arbitrary goals when nothing scores (the `includeZero` default). `GET /goals/suggestions` exposes it to
|
|
121
|
+
a human picker (the hall filing surface, the CLI prompt); `suggestGoalForCapture({ title, body })`
|
|
122
|
+
collapses the same ranking to a **single confident answer or null**, for a vector with nobody to choose
|
|
123
|
+
— currently Discord `#bugs` (below). It ranks across **every** version still open to work
|
|
124
|
+
(`versionAcceptsNewWork`, task 1003061 / R03), not one, because an earlier "decline if more than one
|
|
125
|
+
version is open" design would have returned null on every report this instance (which runs two
|
|
126
|
+
building versions concurrently) ever files.
|
|
127
|
+
|
|
128
|
+
### 5. The inbox's new identity: homeless-only (task 1003071 / R13)
|
|
129
|
+
|
|
130
|
+
`scripts/gds/triage.js`'s `resolveGoalDefault(idea, versionId)` gives the promote path a goal by a
|
|
131
|
+
strict precedence — `idea.suggested_goal_id` (a human or filing surface already named this goal; a
|
|
132
|
+
heuristic must not overrule it) **before** the R07 suggester (only when there is no stored hint) — and
|
|
133
|
+
`createTask({ ..., goalId })` finally sends `goal_id` on `POST /tasks`, a field the route has accepted
|
|
134
|
+
since task 1763 with no client ever sending it. `.claude/skills/idea-triage/SKILL.md` states the
|
|
135
|
+
contract plainly: *"the inbox holds only HOMELESS work — bugs and goal-bound captures now route to a
|
|
136
|
+
task at filing time and never reach the inbox."* Triage shrinks to the judgment calls a routing rule
|
|
137
|
+
cannot make for itself: Full Ideas (Board Room material), `criterion-proposal`/`decision` rows, and
|
|
138
|
+
anything nobody could suggest a home for.
|
|
139
|
+
|
|
140
|
+
## Divergence from the spec, recorded rather than silently reconciled
|
|
141
|
+
|
|
142
|
+
The spec's interview decision 2 says: *"Discord-filed bugs soft-land with a suggested goal. The report
|
|
143
|
+
files as an idea with a classifier-suggested goal attached and surfaces in the pending queue for a
|
|
144
|
+
one-click route. Nothing lands unvetted."* **That is not what R11 shipped.** `modules/discord/discord-bugs.js`
|
|
145
|
+
(task 1003067 / R11, retiring the hardcoded-`GDS-V3` path idea 1000771 named) instead resolves a
|
|
146
|
+
suggested goal via `suggestGoalForCapture` and hands it straight into `captureIdea` as `goalId` — so a
|
|
147
|
+
**linked Metic+ builder's Discord bug hard-lands `'ready'` immediately**, through the *same* landing
|
|
148
|
+
matrix every other filing vector uses, rather than always parking at `'backlog'` pending a one-click
|
|
149
|
+
nod. The file's own header explains the choice: a local copy of the rank split would only ever drift
|
|
150
|
+
from the one definition in `modules/ideas/routing.js` (`tests/filing_abuse_matrix.mjs` exists precisely
|
|
151
|
+
to prevent that divergence), and "same outcomes as before" (the pre-routing #bugs behaviour already
|
|
152
|
+
hard-landed a trusted linked builder's report). An **unlinked** Discord author still gets no goal and
|
|
153
|
+
no rank, so the matrix cannot route their report into work at all — it lands as a homeless idea, same
|
|
154
|
+
as `#ideas` has always given that person, which is the actual "nothing lands unvetted" guarantee that
|
|
155
|
+
survived.
|
|
156
|
+
|
|
157
|
+
The companion interview decision — **"Discord `#ideas` files with HINTS only (`suggested_goal_id`),
|
|
158
|
+
never routes"** — is recorded here as the design intent, but **is not yet built**: R12 (task 1003068,
|
|
159
|
+
"Discord `#ideas` carries routing hints") is still `status='ready'`, not shipped. Today,
|
|
160
|
+
`modules/discord/discord-inbound.js`'s `#ideas` capture carries no goal hint at all; every `#ideas`
|
|
161
|
+
filing lands exactly as it did before this goal, an ordinary homeless `idea_inbox` row. When R12 ships,
|
|
162
|
+
its hint must land as `suggested_goal_id` only (never `goal_id`) — consistent with every other
|
|
163
|
+
"classifier guess, not a route" vector this ADR documents — or it would silently convert `#ideas` into
|
|
164
|
+
a second bypass of the kind idea 1000771 already named once.
|
|
165
|
+
|
|
166
|
+
## Consequences
|
|
167
|
+
|
|
168
|
+
- **Attribution survives routing by construction, not by discipline.** `tests/idea_routing.mjs` pins
|
|
169
|
+
the matrix; `tests/filing_abuse_matrix.mjs` (task 1003073 / R06) pins that a Xenos mass-filing bugs
|
|
170
|
+
never lands anything claimable, never lands in protected scope, and never escalates via filing;
|
|
171
|
+
task 1003072 / R04 is the proof that a routed bug's lineage + `captured_by` survive end-to-end to a
|
|
172
|
+
shipped task.
|
|
173
|
+
- **A caller lying about `filerRank` moves a bug from `'backlog'` to `'ready'` and nothing else** — the
|
|
174
|
+
matrix's own header states this as the reason R06's abuse matrix tests the *route* (server-derived
|
|
175
|
+
rank), not `captureIdea` (which trusts whatever rank it is handed, by design, because the route is
|
|
176
|
+
the only legitimate caller).
|
|
177
|
+
- **The inbox count is now a real signal.** With bugs and goal-bound features routed away at filing
|
|
178
|
+
time, `idea_inbox`'s open count should trend toward "things that genuinely have no home yet" —
|
|
179
|
+
measured by task 1003074 / R15's before/after sweep of the ~50 rows open when the spec was written
|
|
180
|
+
(not yet shipped at the time of this ADR).
|
|
181
|
+
- **R08–R10, R12, R15 remain open** (hall filing surface, CLI `--goal`, hall reassignment affordance,
|
|
182
|
+
Discord `#ideas` hints, the reclassification-sweep proof). This ADR documents the mechanism and the
|
|
183
|
+
matrix those tasks build against; it does not claim the whole spec is delivered.
|
package/docs/adr/README.md
CHANGED
|
@@ -321,5 +321,6 @@ This keeps the decision history honest and traceable.
|
|
|
321
321
|
| 0232 | [**Rot is derived, not swept; and `water` is the only new verb** ([task 1003279](https://cloudbongos.com/builders#/task/1003279) · goal 1000072, criterion `legibility-sort-and-staleness`). The inbox half [ADR 0226](<redacted>.md) split out and left open. Owner decision (2026-08-25): a goal or task past the timer raises a **needs-attention line** — not an automatic status change (it mutates real work with no human in the loop, and a wrong timer then silently freezes it) and not a nightly digest (a notification is not an action, and one you scroll past is indistinguishable from the silent decay it was meant to fix). The build note asked for an idempotent poller; the decision is that **there is no poller and no items table** — a line is a `SELECT` comparing the thing's rot clock to the timer, so "exactly one item per stale thing, not one per sweep" is true by arithmetic rather than by deduplication code that must be written correctly and then stay correct, and clearing falls out for free (an edit moves `updated_at`, a decision moves `status`, watering moves the mark). A stored item would have been a cache of a query whose inputs it could not observe. **The exclusions are the load-bearing part**: rot is work nobody picked up (`backlog`/`ready`, and `open` goals), and `active` is deliberately excluded because the claim-silence timer already reports it in hours — listing it here in days would put one rot in two inboxes under two numbers, the 6h-vs-24h split one tier up; `blocked`, `completed`/`confirmed` and the terminal states are excluded for the same reason, each naming the surface that owns it. The clock is **not a new definition of touched** — it is `task-lib.js`'s published `max(updated_at, shipped_at)` (task 1003278) plus a water mark, pinned by a test asserting the domain expression appears verbatim in migration `core_231`'s index expressions, because drift there is silent. The timer is a **second** timer and defends itself as a different question (days vs hours, DB vs env, asks a human vs releases a claim), stored in a new unseeded generic `project_settings` table — no row means "never configured", which is what lets a settings page tell that apart from "set to the default" — with ADR 0226's precedence and its reporting-degrades fail posture, and an unreachable DB explicitly not treated as a bad value. Three of the four verbs (**prioritise/prune/kill**) reuse `promote`/`demote`/`abandon`/`archive`, the task-1003066 precedent, so they add no permission; only `water` is new, gated on ownership OR `builder.roster.read` inside the handler (a creator holding no atom must still get through). Verbs are **served with each row** rather than hardcoded, since a goal legitimately gets two where a task gets four. Rejected: an items table, a sweep, a digest, auto-demotion, and a fourth verb on goals that would render a dead button.](<redacted>.md) | GDS / legibility + hall |
|
|
322
322
|
|
|
323
323
|
| 0233 | [**A copy proposal is a task carrying a patch, and the applier is the only writer** ([task 1003114](https://cloudbongos.com/builders#/task/1003114) · goal 1000074, criterion `artist-edits-land-as-tasks`). Goal 1000074 asks for two things that pull against each other in its own text: the artist must change copy WITHOUT an engineer, and there must be NO LIVE CMS because every copy change is a claimed, graded, shipped task. R02 shipped the half that needs no reconciliation (the flag) and [ADR 0178](<redacted>.md) §3 pinned the absence of any column that could hold replacement text, naming this task as the one that would have to keep it true. Decisions: (1) the shape is **borrowed from the design half, not invented** — ADR 0081 already has a tool authoring and an `adapter.export()` landing the output as a committed diff under a claim inside a path guard, so the artist is the tool, the copy desk is where they author, and the proposal is the export. (2) A proposal is a **TASK carrying a fenced `copy-proposal` patch**, never a row: the ledger is where a proposal belongs anyway, nothing renders a task description as product copy, a reviewer can read the change without running anything, and `copy-desk` gains NO migration (the obvious-but-wrong R03 is a `copy_desk_proposals` table, which is the forbidden column with extra steps). The module gains `consumes: ["lifecycle"]` and calls `createTask` through the port — it can put a request INTO the ledger and nothing can pull copy OUT of it. (3) `scripts/gds/copy-apply.js` **re-derives the position** rather than trusting the patch, which required teaching R01s extractor to record a source SPAN and deliberately dropping it from the committed registry: an offset goes stale the moment anything above it changes, while the id is designed to survive exactly that movement, so the span is recomputed at the moment of the edit by the same code that decided the string was copy. (4) The **placeholder arithmetic** is what makes a patch mechanical rather than a note for an engineer — the applier puts the sources own `${expr}` back, k-th hole to k-th expression, so an artist may MOVE a value within a sentence but never add or drop one, checked at proposal time and again against the real source. (5) Every ambiguity is a **named refusal** (`target_gone`, `ambiguous_target`, `no_exact_span`, `placeholder_mismatch`, `path_outside_surface` — the design adapters path guard, derived from R01s own SURFACES), because a wrong edit is worse than no edit; after writing, the applier regenerates the registry and checks that what it wrote is what the inventory now reads. (6) Proposing is **open to every rank** (an artist is a craft, not a rank) and lands at `backlog`, so a proposal is a request that passes ordinary triage. Rejected: a proposals table, a column beside the flag, trusting the patchs line number, an escape-aware index map to buy spans for nine strings, auto-closing the flag a proposal answers.](<redacted>.md) | copy-desk / the artist loop |
|
|
324
|
+
| 0234 | [**Idea routing: capture-time promotion, the landing matrix, and the homeless-only inbox** ([task 1003064](https://cloudbongos.com/builders#/task/1003064) · goal 1000071, "Idea routing"). Idea 1000771 named the failure: Discord `#bugs` created tasks DIRECTLY against a hardcoded, already-shipped version — no `captured_by`, no lineage, so the ideator-credit lane had nothing to pay against — while every other open idea sat waiting for a human triage pass that dropped its promotion into a version catch-all, because nothing in capture ever named a goal. Records what R01/R02/R05/R07/R13 shipped. `captureIdea` (`modules/ideas/inbox.js`) stays the ONE capture chokepoint — routing is one optional `goalId` argument, never a second creation door — and when the matrix routes, `routeIdeaToGoal` writes the idea row, the task (via the `lifecycle.createTask` port) and an `ideas_task_lineage` row (`origin='route'`) in ONE transaction, so a route can never mint attribution-free work the way `#bugs` did. `modules/ideas/routing.js`'s `decideLanding` is PURE and fail-closed: a bug from a Metic+ filer hard-lands `ready`, a sub-Metic bug or any other kind with a goal soft-lands `backlog`, a Full Idea or `criterion-proposal`/`decision` never routes, no goal named stays the pre-routing inbox path. `authorizeRoutedLanding` is the BINDING gate underneath the matrix's decision — a goal reaching protected scope raises the task's rank floor to Metic and REFUSES a sub-Metic filer outright, while membership is deliberately NOT required (reporting isn't authoring). `core_222`'s `suggested_goal_id` is an advisory hint only — the real home is `tasks.goal_id`, set by construction — and `/idea-triage` (`scripts/gds/triage.js`) now sends `goal_id` on promotion, so the inbox is homeless-only. Divergence recorded: R11 (Discord `#bugs`) hard-lands a linked Metic+ builder's bug immediately through the SAME shared matrix rather than the spec's "always soft-land, pending queue" design, because a local copy of the rank split would only drift from the one definition; and R12 (Discord `#ideas` hints) is NOT YET SHIPPED, so `#ideas` carries no goal hint today despite the interview decision that it should, hint-only, never route.](<redacted>.md) | ideas / lifecycle |
|
|
324
325
|
|
|
325
326
|
> ⚠️ **Numbering collisions are now machine-enforced, not narrated.** Twenty numbers are shared by two ADRs each — assigned in parallel sessions before anything checked. The files keep their filenames (renumbering would break every existing citation, and a number once assigned is never reused), and this table disambiguates each pair as `NNNN-a` / `NNNN-b`. The authoritative list is `LEGACY_DUPLICATE_ADRS` in [`scripts/gds/adr-namespace.js`](../../scripts/gds/adr-namespace.js), frozen by exact filename: a **new** collision — or a third file joining a legacy number, or a rename of either half — hard-fails the `unit` CI gate, as does an index row that points at no file or an ADR with no row. The list may only shrink. This paragraph used to narrate the collisions one by one and had fallen eight behind reality; see [ADR 0195](<redacted>.md) for why the check exists and why the pairs are grandfathered rather than renumbered.
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# The hall in the world — verification walk (task 1003309, goal 1000081)
|
|
2
|
+
|
|
3
|
+
Walked 2026-09-02 against origin/main `88baa433` (the tree with every goal-1000081 redesign task landed, through PR 518). This folder is the record the task asked for: every page, every rank, both modes, the gates, keyboard and focus, reduced motion, console errors, residual palette, and the unit gate — with one contact sheet per page-lane and the defect list filed as tasks.
|
|
4
|
+
|
|
5
|
+
## Verdict
|
|
6
|
+
|
|
7
|
+
**Passed with four defects filed** (tasks 1003495, 1003496, 1003497, 1003498 — all `ready`, all under goal 1000081). Nothing found blocks the hall; nothing found was left unfiled.
|
|
8
|
+
|
|
9
|
+
## What was walked
|
|
10
|
+
|
|
11
|
+
The 26 pages that carry a `*.states.json` (`modules/hall-ui/public/`), each rendered through the ui-design kit (`modules/ui-design/kit/render.js`, ADR 0197) at 1440 / 390 / 320 in dark and light plus a reduced-motion pass per mode, against three preview harnesses serving the same fixtures as **xenos**, **metic** and **archon** (`scripts/hall-preview/server.js --fixture-me --rank <r>`). The kit's own signed-out stub rendered each page's signed-out states. The archon lane rendered every width; xenos and metic skipped 320 (the floors there are rank-independent).
|
|
12
|
+
|
|
13
|
+
| | |
|
|
14
|
+
|---|---|
|
|
15
|
+
| renders | **1,232** (78 page-lanes: 26 pages × 3 ranks) + 2 reduced-motion passes per page-lane |
|
|
16
|
+
| floors measured per render | console-errors · failed-requests · horizontal-overflow · one-header-main-h1 · controls-24px · top-bar-80px · reduced-motion |
|
|
17
|
+
| page-lanes with a problem | 19, every one classified below |
|
|
18
|
+
| real defects | 4 (filed) · harness limitations: 3 kinds · correct rank refusals: 7 pages |
|
|
19
|
+
|
|
20
|
+
Sheets: `<page>--<rank>.webp`, one per page-lane — dark rows above light, 1440 → 390 → 320 left to right, one tile per state. (The atlas sheets are from the second run, with `atlas.json` generated.)
|
|
21
|
+
|
|
22
|
+
## Page × rank
|
|
23
|
+
|
|
24
|
+
| page | xenos | metic | archon |
|
|
25
|
+
|---|---|---|---|
|
|
26
|
+
| atlas | 20 renders · clean · 3 tells | 20 renders · clean · 3 tells | 30 renders · clean · 3 tells |
|
|
27
|
+
| collab | 8 · clean | 8 · clean | 12 · clean |
|
|
28
|
+
| copy-desk | 20 · clean | 20 · clean | 30 · clean |
|
|
29
|
+
| diagrams | 8 · harness (sign-in redirect) | 8 · harness | 12 · harness |
|
|
30
|
+
| drachmae | 16 · stub (signed-out feeds) | 16 · stub | 24 · stub |
|
|
31
|
+
| gate | 12 · refused (metic+) | 12 · clean | 18 · clean |
|
|
32
|
+
| goals | 20 · clean | 20 · clean | 30 · clean |
|
|
33
|
+
| government | 20 · refused (permissions view is archon) | 20 · refused (same) | 30 · clean |
|
|
34
|
+
| harbor | 12 · refused (metic+) | 12 · clean | 18 · clean |
|
|
35
|
+
| idea | 8 · clean | 8 · clean | 12 · clean |
|
|
36
|
+
| ideas | 8 · clean | 8 · clean | 12 · clean |
|
|
37
|
+
| index | 16 · clean | 16 · clean | 24 · clean |
|
|
38
|
+
| modules | 20 · clean | 20 · clean | 30 · clean |
|
|
39
|
+
| not-ready | 8 · clean | 8 · clean | 12 · clean |
|
|
40
|
+
| pair | 8 · clean | 8 · clean | 12 · clean |
|
|
41
|
+
| people | 12 · clean | 12 · clean | 18 · clean |
|
|
42
|
+
| primer | 12 · harness (sign-in redirect) | 12 · harness | 18 · harness |
|
|
43
|
+
| profile | 20 · **defect 1003497** (signed-out links) | 20 · **defect 1003497** | 30 · **defect 1003497** |
|
|
44
|
+
| ranks | 8 · clean | 8 · clean | 12 · clean |
|
|
45
|
+
| roadmap | 8 · clean | 8 · clean | 12 · clean |
|
|
46
|
+
| roster | 12 · clean | 12 · clean | 18 · clean |
|
|
47
|
+
| sessions | 8 · refused (metic+) | 8 · clean | 12 · clean |
|
|
48
|
+
| settings | 16 · clean | 16 · clean | 24 · clean |
|
|
49
|
+
| task | 12 · clean | 12 · clean | 18 · clean |
|
|
50
|
+
| watch | 16 · refused (metic+) | 16 · clean | 24 · clean |
|
|
51
|
+
| work | 24 · clean | 24 · clean | 36 · **defect 1003498** (320, filters open) |
|
|
52
|
+
|
|
53
|
+
"clean" = every floor held in every render of that lane. Tells (the kit's advisory lines, never problems) are summarised under *Tells* below.
|
|
54
|
+
|
|
55
|
+
## Every problem, classified
|
|
56
|
+
|
|
57
|
+
| kind | count | where | what it is |
|
|
58
|
+
|---|---|---|---|
|
|
59
|
+
| `failed-requests` on `/api/gds/auth/web/start?return=…` | 236 | diagrams, primer — all lanes | **harness limitation.** The sign-in redirect target has no fixture on the preview harness, so each signed-out render logs one failed request per navigation. Live answers that URL with the real sign-in door (see *Gates*). |
|
|
60
|
+
| `dispatchClick: nothing matches #svg .ab-node` / `#ab-index-rows …` | 28 | atlas — all lanes, first run | **harness limitation.** The atlas reads a generated, gitignored `atlas.json`; `atlas.states.json` says to run `scripts/gds/gen-atlas.js` first. Re-run with it generated: **all three lanes clean** (the sheets here are that run). |
|
|
61
|
+
| `failed-requests` on `drachmae-and-karma.md` + `public/repo-info` (`127.0.0.1`) | 28 | drachmae — all lanes | **stub limitation.** The kit's own signed-out stub carries no hall feeds; `drachmae.states.json` does not list these two as expected 404s the way `atlas.states.json` does. States-file hygiene, not a page defect (the page renders its honest empty). |
|
|
62
|
+
| `controls-24px: a "roster" 37x18 \| a "sign in" 40x18` | 14 | profile `out` — all lanes, both modes | **defect → task 1003497.** The signed-out empty state's two inline links are 18px tall. Never rendered before: the harness always answers `/me`, so this state only appears against the kit's stub. |
|
|
63
|
+
| `horizontal-overflow: scrollWidth 358 > 320` | 2 | work `filters-open` @320 — archon, both modes | **defect → task 1003498.** The filter drawer's goal `<select>` (332px) will not shrink; measured on the harness, it and its label are the elements past the edge. |
|
|
64
|
+
| `expected visible: #gov-rank-list` | 8 | government `permissions` — xenos, metic | **correct refusal.** `GET /government/ranks` is `government.manage` (archon); the view does not render for a metic. |
|
|
65
|
+
| `expected visible: #gate-body` / `#harbor-body` / `#sessions-scroll` / `#stats-scroll` / `#watch-*` / `#pane-*`, `page.click: Timeout` | 32 | gate, harbor, sessions, watch — xenos | **correct refusal.** These pages are `requireGovernmentPage` (metic+); the harness serves the shell, the API 403s, the page shows nothing. On live the page gate refuses the shell itself (below). |
|
|
66
|
+
|
|
67
|
+
## Gates
|
|
68
|
+
|
|
69
|
+
- `tests/hall_page_gate_map.mjs`, `government_page_gates.mjs`, `auth_page_gate.mjs`, `scouting_page_gate.mjs`: **21 / 21 pass** — every hall URL is wired to the gate the oracle names.
|
|
70
|
+
- Live, signed out (`curl`, no cookie): **every** `/builders/*` URL probed — work, pair, settings, atlas, modules, goals, roadmap, primer, diagrams, watch, harbor, gate, sessions, people, government, roster, `/builders/`, ranks, drachmae, profile, not-ready, task/1003491, idea/1000904, ideas — answers **401** with the instance's own sign-in door (`noindex`), and so does the apex `/`. That is wider than the oracle's router-level map (which leaves roster, ranks, drachmae, profile, not-ready and `/builders/` ungated) because this project runs `project.platformVisibility = gated` — the member door in `src/bongos/platform-visibility-gate.js` (task 1003043, ADR 0190) refuses strangers on every surface before any page gate runs. Both layers behave as designed.
|
|
71
|
+
- Rank refusals on the harness (the table above) match the catalog floors: gate, harbor, sessions, watch, government → metic+; government's permissions view → archon.
|
|
72
|
+
|
|
73
|
+
## Keyboard and focus
|
|
74
|
+
|
|
75
|
+
- Measured on the harness as archon, after a real `Tab` (keyboard modality): every visible focusable element (`a[href], button, input, select, textarea, summary, [tabindex]`) focused in turn and its computed outline / box-shadow read — **work board 140 / 140 ringed, profile 47 / 47, task page 46 / 46** (the new grade panel and session-log disclosure included); first Tab stop on all three is the skip link, and the kit's focus-order fact on all 1,232 renders reads `Skip to content › Builders' Hall › Home › Roadmap …`.
|
|
76
|
+
- Static: three `outline: none` sites in the hall's sheets. `diagram-viewer.css:47` is restored by `.dgv__stage:focus-visible` (inset ring); `style.css:531` `main:focus` is the skip link's programmatic target; **`style.css` `.palette__input` has no replacement → task 1003496** (the command palette input, hidden until Ctrl+K, so the measured pages could not reach it).
|
|
77
|
+
- `controls-24px` held on every render except the profile's signed-out state (task 1003497).
|
|
78
|
+
|
|
79
|
+
## Reduced motion, console, overflow, structure
|
|
80
|
+
|
|
81
|
+
- Reduced motion: **every page-lane, both modes: `dead — running 0, rAF 0`** (nothing animates and no frame loop runs under `prefers-reduced-motion`).
|
|
82
|
+
- Console errors: **none** on any of the 1,232 renders (the floors' `console-errors` never fired; the states files' `ignoreConsole` lists cover only the expected 401/403/404 noise).
|
|
83
|
+
- Horizontal overflow: none except work @320 with the filter drawer open (task 1003498).
|
|
84
|
+
- One `<header>`, one `<main>`, one `<h1>`, top bar ≤ 80px: held on every render.
|
|
85
|
+
|
|
86
|
+
## Residual palette (hex / rgb outside `style.css`)
|
|
87
|
+
|
|
88
|
+
`grep -nE "#[0-9a-fA-F]{3,8}\b|rgba?\(|hsla?\(" modules/hall-ui/public/*.{css,html,js} | grep -v ^style.css`, comments removed:
|
|
89
|
+
|
|
90
|
+
| site | verdict |
|
|
91
|
+
|---|---|
|
|
92
|
+
| `builders.js:563–568` — Standing's recent-grades column: `color:#a04040`, `var(--olive,#5b7a4d)`, `var(--ink-soft,#8a8577)` inline | **defect → task 1003495** (verification state must wear `--ok/--danger`) |
|
|
93
|
+
| `copy-desk.css:76` — `.cd-dialog::backdrop { background: rgba(0,0,0,.55) }` | **folded into 1003495** |
|
|
94
|
+
| `atlas.css:24–51`, `atlas.js:22–56` — the `--ab-*` node palette | **exempt** — the atlas's semantic node palette is fixed by ADR 0094 (its own states file says so) |
|
|
95
|
+
| `settings.css:157–158` — `#5865F2` on the Discord button | **accepted** — a third-party brand colour |
|
|
96
|
+
| `diagram-viewer.css:10`, `work.css:11,209` | comments only |
|
|
97
|
+
|
|
98
|
+
## Tells (advisory, reviewed, not filed)
|
|
99
|
+
|
|
100
|
+
- `tiny-type` on `#shell-user-rank`, `.fact-pill`, `.task__tag`, `.prow__tag`, `.sessions-row__badge`, `.badge`, `.rm-goal__ready`, `.gate-reason__floor`, `small` — all **10.5px**, the world's label tier (`--label-size`), 0.5px under the kit's 11px line. A token decision, consistent everywhere; flagged for the owner to raise the tier if wanted, not a defect.
|
|
101
|
+
- `proportional-numerals` on date and id cells (profile ledger, sessions, gate) — cosmetic; worth `tabular-nums` on ledger cells in a later polish.
|
|
102
|
+
- `prose-measure` on `li.rank-card` (~146ch) on the ranks page; `headline-lines` (an h1 at 4 lines) on the task page at 320 with a long title — inherent to the content.
|
|
103
|
+
|
|
104
|
+
## Unit gate
|
|
105
|
+
|
|
106
|
+
- CI `unit` (npm test + fitness + knip + audit) **green on this exact tree**: PR 518 (`88baa433`) and PR 516 before it.
|
|
107
|
+
- Local, this worktree: the hall's own 18 suites `tests/hall_*.mjs` — **285 / 285 pass**; the four gate suites 21 / 21; `fitness.js` all checks passed. A full local `npm test` on this Windows box reports 28 suite failures, none in hall-ui: generated-artifact freshness (`api_client`, `copy_inventory`), worktree/git path resolution (`next_number`, `box_infra_resolve`, `lib_sh_resolution`, `migrate_root_resolution`…) and Windows process aborts (`0xC0000409`) — environment, not the tree; CI is the gate of record.
|
|
108
|
+
|
|
109
|
+
## Reproduce
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# in a checkout at the verified tree
|
|
113
|
+
node scripts/gds/gen-atlas.js # the atlas's generated feed
|
|
114
|
+
node scripts/hall-preview/server.js --port 4641 --fixture-me --rank xenos # and 4642 metic, 4643 archon
|
|
115
|
+
for s in modules/hall-ui/public/*.states.json; do
|
|
116
|
+
node modules/ui-design/kit/render.js --states "$s" --base-in http://builders.localhost:4643 \
|
|
117
|
+
--sizes 1440,390,320 --out /tmp/walk/archon/$(basename "$s" .states.json) # no --base-out: the kit's stub renders signed-out
|
|
118
|
+
done
|
|
119
|
+
# sheets: normalise every <mode>-<width>-<state>.png to 480×300 (ffmpeg scale+pad), then tile=6xN → <page>--<rank>.webp
|
|
120
|
+
node --test tests/hall_page_gate_map.mjs tests/government_page_gates.mjs tests/auth_page_gate.mjs tests/scouting_page_gate.mjs
|
|
121
|
+
node --test tests/hall_*.mjs
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Lanes must be launched as async processes — a synchronous spawn serialises the three ranks.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1423,5 +1423,9 @@ is load-bearing: the script throws rather than guess if it is missing, and
|
|
|
1423
1423
|
landed since 1.19.491 with no explicit bump. run 33693742388. (task 1002620)
|
|
1424
1424
|
1.19.493 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
1425
1425
|
landed since 1.19.492 with no explicit bump. run 33694576680. (task 1002620)
|
|
1426
|
+
1.19.494 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
1427
|
+
landed since 1.19.493 with no explicit bump. run 33697218855. (task 1002620)
|
|
1428
|
+
1.19.495 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
1429
|
+
landed since 1.19.494 with no explicit bump. run 33766103175. (task 1002620)
|
|
1426
1430
|
---------------------------------------------------------------------------
|
|
1427
1431
|
```
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.495",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bongos/core",
|
|
9
|
-
"version": "1.19.
|
|
9
|
+
"version": "1.19.495",
|
|
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.
|
|
3
|
+
"version": "1.19.495",
|
|
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
|
@@ -45,7 +45,7 @@ const { validateOrRespond, LIMITS, parseId, asyncHandler, corsPublicGet, parsePa
|
|
|
45
45
|
// there. scripts/gds/bump-version.js still rewrites the literal below; it appends
|
|
46
46
|
// the entry to that file. Look for a version's history there, not here.
|
|
47
47
|
// ---------------------------------------------------------------------------
|
|
48
|
-
const CORE_VERSION = '1.19.
|
|
48
|
+
const CORE_VERSION = '1.19.495'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
|
|
49
49
|
|
|
50
50
|
// A namespaced logger so a module's log lines are attributable + consistent.
|
|
51
51
|
// Usage: const log = api.logger('dev-box'); log.info('mounted');
|