@bongos/core 1.19.587 → 1.19.589
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 +22 -12
- package/docs/adr/0263-how-a-version-closes.md +275 -0
- package/docs/adr/0264-the-ten-working-areas.md +144 -0
- package/docs/adr/README.md +2 -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/.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.
|
|
6
|
-
"core_contract": "1.19.
|
|
7
|
-
"source_commit": "
|
|
5
|
+
"core_version": "1.19.589",
|
|
6
|
+
"core_contract": "1.19.589",
|
|
7
|
+
"source_commit": "29fe6277ac47bc629f56c68e20dca829ed9370f2",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-09-
|
|
9
|
+
"built_at": "2026-09-08T02:16:53.692Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
|
-
"docs_redacted":
|
|
12
|
+
"docs_redacted": 457,
|
|
13
13
|
"agent_docs_stubbed": 24,
|
|
14
14
|
"functional_verbatim": 2060,
|
|
15
15
|
"rules": 3,
|
|
16
16
|
"gate_literals": 3,
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
|
-
"file_count":
|
|
20
|
-
"tree_sha256": "
|
|
19
|
+
"file_count": 2541,
|
|
20
|
+
"tree_sha256": "d96aab84f10a639efe4d035824854aed5cb9bf2fcc7723f62a69f4b1a8074591",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/blocker-review/SKILL.md",
|
|
@@ -1829,10 +1829,20 @@
|
|
|
1829
1829
|
"mode": "0000644",
|
|
1830
1830
|
"sha256": "cc30ad9de02409b6e3db26517bef2966133b3362903a984b65d94ea289fd0d88"
|
|
1831
1831
|
},
|
|
1832
|
+
{
|
|
1833
|
+
"path": "docs/adr/0263-how-a-version-closes.md",
|
|
1834
|
+
"mode": "0000644",
|
|
1835
|
+
"sha256": "07a3561c7bc7f55bb2077925df4df6a24b68a1f0c8d4052ac50278edd9d4eba1"
|
|
1836
|
+
},
|
|
1837
|
+
{
|
|
1838
|
+
"path": "docs/adr/0264-the-ten-working-areas.md",
|
|
1839
|
+
"mode": "0000644",
|
|
1840
|
+
"sha256": "03f1cf19a181d6726066ba6fb72156add0cb8ede004ebc7ddf8ac3859a335596"
|
|
1841
|
+
},
|
|
1832
1842
|
{
|
|
1833
1843
|
"path": "docs/adr/README.md",
|
|
1834
1844
|
"mode": "0000644",
|
|
1835
|
-
"sha256": "
|
|
1845
|
+
"sha256": "b38a32c8557012f9e5e761c5e219901ad628af9b63d2cb190d32e783dbf9aaa9"
|
|
1836
1846
|
},
|
|
1837
1847
|
{
|
|
1838
1848
|
"path": "docs/api-reference.md",
|
|
@@ -2717,7 +2727,7 @@
|
|
|
2717
2727
|
{
|
|
2718
2728
|
"path": "docs/module-api-changelog.md",
|
|
2719
2729
|
"mode": "0000644",
|
|
2720
|
-
"sha256": "
|
|
2730
|
+
"sha256": "0ca6c49c46b3bc4621613099885595eb387c784e86f9fb83d5600912c1ea4c38"
|
|
2721
2731
|
},
|
|
2722
2732
|
{
|
|
2723
2733
|
"path": "docs/modules-contract.md",
|
|
@@ -7592,12 +7602,12 @@
|
|
|
7592
7602
|
{
|
|
7593
7603
|
"path": "package-lock.json",
|
|
7594
7604
|
"mode": "0000644",
|
|
7595
|
-
"sha256": "
|
|
7605
|
+
"sha256": "57bf21d2c0b7e235c4628f7f1d7e52c8b65b30375d96adcce8558a5e1cce1b5a"
|
|
7596
7606
|
},
|
|
7597
7607
|
{
|
|
7598
7608
|
"path": "package.json",
|
|
7599
7609
|
"mode": "0000644",
|
|
7600
|
-
"sha256": "
|
|
7610
|
+
"sha256": "fc682e53b7902f41fb4a455c9f61d70a5b154159df150b6e7e6c696c596df4e4"
|
|
7601
7611
|
},
|
|
7602
7612
|
{
|
|
7603
7613
|
"path": "public-docs/index.html",
|
|
@@ -9307,7 +9317,7 @@
|
|
|
9307
9317
|
{
|
|
9308
9318
|
"path": "src/module-api.js",
|
|
9309
9319
|
"mode": "0000644",
|
|
9310
|
-
"sha256": "
|
|
9320
|
+
"sha256": "9264831ff874468719e9a6f73a3dfa39507f6ce033f25cdfc9d08e840d1a58fe"
|
|
9311
9321
|
},
|
|
9312
9322
|
{
|
|
9313
9323
|
"path": "src/module-loader/catalog.js",
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
# 0263 — How a version closes: auto, early, roll-forward, and the maintenance exemption
|
|
2
|
+
|
|
3
|
+
- **Status:** Accepted
|
|
4
|
+
- **Date:** 2026-09-07
|
|
5
|
+
- **Tasks:** [#1003593](https://cloudbongos.com/builders#/task/1003593) (this design pass, BV1.R06). Implemented by BV1.R12 ([#1003599](https://cloudbongos.com/builders#/task/1003599)), R16 ([#1003603](https://cloudbongos.com/builders#/task/1003603)), R17 ([#1003604](https://cloudbongos.com/builders#/task/1003604)), R18 ([#1003605](https://cloudbongos.com/builders#/task/1003605)), R20 ([#1003607](https://cloudbongos.com/builders#/task/1003607)) and R23 ([#1003610](https://cloudbongos.com/builders#/task/1003610)).
|
|
6
|
+
- **Goal:** [#1000086](https://cloudbongos.com/builders#/goal/1000086) — Strict versioning.
|
|
7
|
+
- **Implements:** [ADR 0250](<redacted>.md) D5. That decision says a version *can* close; this one says *how*, so the five build tasks under it are mechanical.
|
|
8
|
+
|
|
9
|
+
## 1. Why a second ADR
|
|
10
|
+
|
|
11
|
+
[ADR 0250](<redacted>.md) is the
|
|
12
|
+
decision: the version boundary is the scope gate, and a version must be able to
|
|
13
|
+
reach done. It deliberately stops at the rule. Closing a version is the widest
|
|
14
|
+
write in the system — it flips a version, dispositions every goal still standing,
|
|
15
|
+
promotes the next version into `building`, and carries a bug queue across the
|
|
16
|
+
boundary — and *four* separate tasks build pieces of it. Left undesigned, each
|
|
17
|
+
would pick its own refusal codes, its own payload shape, and its own answer to
|
|
18
|
+
"what happens to the maintenance goal", and the seams would only meet in
|
|
19
|
+
production.
|
|
20
|
+
|
|
21
|
+
So this ADR pins the mechanics. It adds no rule ADR 0250 did not already decide.
|
|
22
|
+
|
|
23
|
+
## 2. The state machine
|
|
24
|
+
|
|
25
|
+
`versions.status` has four values (migration 003): `planning`, `building`,
|
|
26
|
+
`shipped`, `frozen`. Only two transitions are in scope here:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
planning ──promote──> building ──close──> shipped
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`frozen` is archival bookkeeping and no business of this design. Nothing
|
|
33
|
+
un-closes a version: reopening is not a move, and a version closed in error is
|
|
34
|
+
corrected the way any other bad row is.
|
|
35
|
+
|
|
36
|
+
**Only a `building` version may close.** Closing a `planning` version is
|
|
37
|
+
meaningless (nothing was built), and closing an already-`shipped` one is a
|
|
38
|
+
double-close. Both are `version_not_building` (409).
|
|
39
|
+
|
|
40
|
+
## 3. Two doors, and the asymmetry that makes the design simple
|
|
41
|
+
|
|
42
|
+
The single most useful thing to notice about D5 is that **auto-close, by
|
|
43
|
+
construction, has nothing to disposition.**
|
|
44
|
+
|
|
45
|
+
Auto-close fires when the last non-maintenance goal achieves. If that goal was
|
|
46
|
+
the last one, then every non-maintenance goal on the version is already
|
|
47
|
+
`achieved` or `archived` — so the set of open goals needing a decision is *empty
|
|
48
|
+
by definition*. The disposition machinery is not merely unnecessary on that path;
|
|
49
|
+
it can never have input.
|
|
50
|
+
|
|
51
|
+
That splits the feature cleanly in two:
|
|
52
|
+
|
|
53
|
+
| | **Auto-close** (R16) | **Early close** (R12) |
|
|
54
|
+
|---|---|---|
|
|
55
|
+
| Trigger | the last non-maintenance goal achieves | an Archon calls `POST /versions/:id/close` |
|
|
56
|
+
| Open goals at close | zero, by construction | any number |
|
|
57
|
+
| Disposition required | none — there is nothing to disposition | one per open non-maintenance goal |
|
|
58
|
+
| Actor | the system, on a ship or a satisfy | an Archon, deliberately |
|
|
59
|
+
| Roll-forward | the maintenance goal only | the maintenance goal, plus every goal dispositioned `roll_forward` |
|
|
60
|
+
|
|
61
|
+
Every complication in this feature — the disposition map, the refusal that
|
|
62
|
+
returns the open goals, the successor lineage — belongs to **early close only**.
|
|
63
|
+
R16 is a much smaller task than the ADR 0250 sentence makes it sound, and R12 is
|
|
64
|
+
where the weight is.
|
|
65
|
+
|
|
66
|
+
## 4. Auto-close: where it fires, and why it cannot fail a ship
|
|
67
|
+
|
|
68
|
+
Goal achievement has **two writers**, and [ADR 0250](<redacted>.md) D2 already made them a deliberate,
|
|
69
|
+
documented duplicate rather than one helper, because collapsing them creates a
|
|
70
|
+
require cycle (`db-goals` → `done-when` → `db-goals`):
|
|
71
|
+
|
|
72
|
+
- [`db-goals.js` `achieveGoalIfComplete`](../../modules/lifecycle/db-goals.js) — the manual `POST /done-when/:id/satisfy` path.
|
|
73
|
+
- [`done-when.js` `autoSatisfyShippedCriteria`](../../modules/lifecycle/done-when.js) — the cascade that fires on **every ship** and every reconciler tick, on the ship transaction's own `exec`.
|
|
74
|
+
|
|
75
|
+
**Auto-close hangs off both, on the same exec, exactly as R08/R09's closure check
|
|
76
|
+
did.** The rule is written twice on purpose, and the two copies move together or
|
|
77
|
+
a version closes correctly through one door and wrongly through the other. That
|
|
78
|
+
sentence is already load-bearing in both files; this feature adds a second clause
|
|
79
|
+
governed by it, so it is repeated here rather than left to be rediscovered.
|
|
80
|
+
|
|
81
|
+
**Auto-close must never fail a ship.** This is not a preference — it is the
|
|
82
|
+
established posture of the surrounding code:
|
|
83
|
+
[`closeCompletedWorkForShip`](../../modules/lifecycle/done-when.js) already
|
|
84
|
+
swallows its own failure and reports it in a summary line, on the argument that a
|
|
85
|
+
criterion close must never fail a ship and the reconciler's unscoped sweep
|
|
86
|
+
retries every tick. Version close is a strictly wider write than a criterion
|
|
87
|
+
close, so it inherits the posture *a fortiori*:
|
|
88
|
+
|
|
89
|
+
- it runs inside the ship transaction so it sees the uncommitted `shipped` flip (the same reason R09's clause needs `exec`);
|
|
90
|
+
- it is wrapped so a throw is caught, logged, and reported — never propagated into the ship;
|
|
91
|
+
- it is **idempotent** (`WHERE status = 'building'` guards the flip), so the reconciler sweep retrying it is a no-op once it has run.
|
|
92
|
+
|
|
93
|
+
The consequence, stated plainly: **a version can be left un-closed by a failure,
|
|
94
|
+
and never half-closed.** Un-closed self-heals on the next sweep. That is the
|
|
95
|
+
correct trade — the opposite choice makes a bug in version-close able to block
|
|
96
|
+
every builder's ship.
|
|
97
|
+
|
|
98
|
+
### The archive doc is not part of the transaction
|
|
99
|
+
|
|
100
|
+
`limitations/<version>-shipped.md` is a **repo file**, and a route cannot write
|
|
101
|
+
one. Auto-close therefore flips the database and nothing else; the scope archive
|
|
102
|
+
stays a human/agent follow-up driven by
|
|
103
|
+
[`scripts/gds/version-close.js`](../../scripts/gds/version-close.js) (R23). This is
|
|
104
|
+
worth saying because ADR 0250 §7 speaks of a version "reaching done", and a
|
|
105
|
+
reader could reasonably assume the archive rides along. It does not, and pretending
|
|
106
|
+
otherwise would put file I/O inside a ship transaction.
|
|
107
|
+
|
|
108
|
+
## 5. Early close: the two-step, mirroring the archive refusal
|
|
109
|
+
|
|
110
|
+
`POST /versions/:id/close` is Archon-only, behind the **already-defined**
|
|
111
|
+
`version.close` permission ([`government/catalog.js`](../../modules/government/catalog.js)) that nothing has referenced until now.
|
|
112
|
+
|
|
113
|
+
The shape is **the R10 archive two-step, verbatim in spirit** — that precedent is
|
|
114
|
+
shipped, agents already know it, and inventing a second idiom for the same
|
|
115
|
+
interaction is how two surfaces drift:
|
|
116
|
+
|
|
117
|
+
**Step 1 — refuse, and return the work.** Called with open non-maintenance goals
|
|
118
|
+
and no disposition, the route refuses with `version_holds_open_goals` (409) and
|
|
119
|
+
**returns the goals**, not merely a count. R10's reasoning applies unchanged: the
|
|
120
|
+
caller's next move is to decide what happens to each, and an agent that has to go
|
|
121
|
+
fetch the list first will guess instead.
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
409 { error: "version_holds_open_goals",
|
|
125
|
+
message: "Version 'BONGOS-V1' still holds 12 open goal(s). …",
|
|
126
|
+
details: { total: 12, shown: 12,
|
|
127
|
+
goals: [ { id, title, open_tasks } … ] } }
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Step 2 — proceed with a disposition map.** One entry per open non-maintenance
|
|
131
|
+
goal, keyed by goal id:
|
|
132
|
+
|
|
133
|
+
```json
|
|
134
|
+
{ "reason": "V1 is done; the rest is V2 scope.",
|
|
135
|
+
"dispositions": {
|
|
136
|
+
"1000044": { "verb": "roll_forward" },
|
|
137
|
+
"1000065": { "verb": "abandon" }
|
|
138
|
+
} }
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Two verbs, and only two:
|
|
142
|
+
|
|
143
|
+
- **`roll_forward`** — a successor goal is created in the planning version (§6).
|
|
144
|
+
- **`abandon`** — the goal is archived, and its open tasks are abandoned with the close's `reason`, through the same path R14 gives the archive flow. It is deliberately **not** possible to abandon a goal without a reason: `reason` is required on the close call, and it is what lands in each abandoned task's record.
|
|
145
|
+
|
|
146
|
+
**A version holding zero open goals stays a single call**, exactly as a goal
|
|
147
|
+
holding zero open tasks does. That is the auto-close path's shape too, so both
|
|
148
|
+
doors agree.
|
|
149
|
+
|
|
150
|
+
### Refusal codes
|
|
151
|
+
|
|
152
|
+
Every one is **named**, per ADR 0250 §7 — the callers are agents, and an unnamed
|
|
153
|
+
409 is an agent stopping to ask a human.
|
|
154
|
+
|
|
155
|
+
| Code | Status | When |
|
|
156
|
+
|---|---|---|
|
|
157
|
+
| `version_not_found` | 404 | no such version |
|
|
158
|
+
| `version_not_building` | 409 | the version is `planning`, `shipped` or `frozen` |
|
|
159
|
+
| `version_holds_open_goals` | 409 | open non-maintenance goals and no/partial disposition map; returns the goals |
|
|
160
|
+
| `bad_disposition` | 400 | a disposition names an unknown goal, a goal not on this version, or a verb outside `roll_forward`/`abandon` |
|
|
161
|
+
| `no_planning_version` | 409 | a `roll_forward` was asked for and no `planning` version exists to receive it |
|
|
162
|
+
| `close_reason_required` | 400 | `reason` missing on a close that dispositions anything |
|
|
163
|
+
|
|
164
|
+
`no_planning_version` is the one that will actually be hit in practice, and it is
|
|
165
|
+
a **refusal rather than an auto-create on purpose**: cutting the successor version
|
|
166
|
+
is a scope decision with its own criteria, and doing it implicitly inside a close
|
|
167
|
+
is precisely the "fake hotfix version" failure ADR 0250 §3 built the override
|
|
168
|
+
counter to prevent.
|
|
169
|
+
|
|
170
|
+
## 6. Roll-forward: the lineage column already exists, pointing the other way
|
|
171
|
+
|
|
172
|
+
Migration 160 gave `goals` a **`succeeded_by_goal_id`** column — on the *old*
|
|
173
|
+
goal, pointing at the *new* one. Both ADR 0250 and task 1003604's brief say
|
|
174
|
+
`succeeds_goal_id`, which does **not** exist. The column that exists wins; there
|
|
175
|
+
is no migration here, and R17 must write:
|
|
176
|
+
|
|
177
|
+
```sql
|
|
178
|
+
UPDATE goals SET succeeded_by_goal_id = <new.id> WHERE id = <old.id>
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Naming this explicitly is the whole reason this section exists — R17's brief would
|
|
182
|
+
otherwise send a builder to reserve a migration number for a column that has been
|
|
183
|
+
in the schema since the goal tier landed.
|
|
184
|
+
|
|
185
|
+
A rolled-forward goal is created on the planning version carrying the original's
|
|
186
|
+
`title`, `description`, `scope_modules`, `category_id` and **membership**; its
|
|
187
|
+
open tasks are re-pointed at it. The predecessor is then `archived` with zero
|
|
188
|
+
open tasks — so it passes R10's own check on the way out, rather than being
|
|
189
|
+
special-cased around it.
|
|
190
|
+
|
|
191
|
+
## 7. The maintenance goal: the flag R18 owes, and the exemption
|
|
192
|
+
|
|
193
|
+
The maintenance goal is currently **matched by title** —
|
|
194
|
+
`ensureMaintenanceGoal` (task 1003691) looks up `"<version> — maintenance"`, and
|
|
195
|
+
its own comment flags this as R18's debt:
|
|
196
|
+
|
|
197
|
+
> MATCHED BY TITLE, because there is no column that says "this is the maintenance goal" … task 1003605 (BV1.R18) is where a real flag belongs when the feature gets its own column.
|
|
198
|
+
|
|
199
|
+
**R18 adds the column**: `goals.is_maintenance boolean NOT NULL DEFAULT false`,
|
|
200
|
+
backfilled by title for the rows that already exist, after which the title lookup
|
|
201
|
+
becomes a flag read. This is not cosmetic. The close count asks "are there any
|
|
202
|
+
open non-maintenance goals?", and answering it with a `title NOT LIKE` would make
|
|
203
|
+
a hand-titled goal silently exempt from the gate that decides when a **version**
|
|
204
|
+
closes — a much worse blast radius than the provenance wrinkle the title match
|
|
205
|
+
carries today.
|
|
206
|
+
|
|
207
|
+
The exemption is then one predicate, used identically by auto-close and early
|
|
208
|
+
close:
|
|
209
|
+
|
|
210
|
+
```sql
|
|
211
|
+
WHERE version_id = $1 AND status = 'open' AND NOT is_maintenance
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**The maintenance goal always rolls forward, and never needs a disposition.** It
|
|
215
|
+
is exempt from the close count, so it cannot hold a version open; and its open
|
|
216
|
+
bugs move to the successor version's maintenance goal (`ensureMaintenanceGoal` on
|
|
217
|
+
the newly-promoted version — the find-or-create already exists and is
|
|
218
|
+
advisory-locked). Bugs arrive on their own schedule and must not need an override
|
|
219
|
+
to be filed; that is the pressure valve ADR 0250 §3 describes, and it only works
|
|
220
|
+
if the queue survives the boundary.
|
|
221
|
+
|
|
222
|
+
## 8. Promotion: the close's last act
|
|
223
|
+
|
|
224
|
+
On a successful close, the single `planning` version is promoted to `building`
|
|
225
|
+
(R20), so the project is never without a live train.
|
|
226
|
+
|
|
227
|
+
- It runs **in the close's transaction** — a project with zero building versions is a broken state, not an intermediate one, and `currentBuildingVersionId` returns `null` there, which fails every routing path closed over it.
|
|
228
|
+
- **Zero planning versions is not an error.** The close succeeds and the project sits with no building version until someone cuts one. Refusing the close would trap a finished version open because nobody had scoped the next one yet.
|
|
229
|
+
- Exactly one can be promoted, because R04 already refuses a second `planning` version.
|
|
230
|
+
- The promoted version gets its maintenance goal via `ensureMaintenanceGoal`, which is what receives the carried-forward bugs in §7.
|
|
231
|
+
|
|
232
|
+
**Ordering inside the transaction is load-bearing:** promote *before* roll-forward
|
|
233
|
+
and before the bug carry-over, because both need a destination version that is
|
|
234
|
+
already `building` — `ensureMaintenanceGoal` returns `null` for a version whose
|
|
235
|
+
status is not `building`, so a carry-over run before the promotion silently
|
|
236
|
+
carries nothing.
|
|
237
|
+
|
|
238
|
+
## 9. The race, and where the index belongs
|
|
239
|
+
|
|
240
|
+
[`versions.js`](../../modules/lifecycle/routes/versions.js) already documents R04's
|
|
241
|
+
unmitigated check-then-insert race and names R19 as the place to fix both halves
|
|
242
|
+
with one partial unique index. That still stands, and this design adds the close
|
|
243
|
+
side of the same exposure: two concurrent closes could both promote.
|
|
244
|
+
|
|
245
|
+
The single migration R19 reserves should therefore carry **both** guards:
|
|
246
|
+
|
|
247
|
+
```sql
|
|
248
|
+
CREATE UNIQUE INDEX ON versions ((status)) WHERE status = 'planning';
|
|
249
|
+
CREATE UNIQUE INDEX ON versions ((status)) WHERE status = 'building';
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
With those in place the promotion race resolves the way the version-id collision
|
|
253
|
+
already does — the loser gets a `23505` and the route translates it into the same
|
|
254
|
+
clean refusal, rather than the check-then-act prayer both rules rely on today.
|
|
255
|
+
|
|
256
|
+
## 10. What this design does not do
|
|
257
|
+
|
|
258
|
+
- **It does not gate shipping.** Consistent with ADR 0250 §4. Auto-close rides the ship transaction and is swallowed on failure; nothing here can refuse a ship, a claim, or a grade.
|
|
259
|
+
- **It does not write the scope archive.** §4. The route closes the version; the doc is R23's CLI work.
|
|
260
|
+
- **It does not auto-create the successor version.** §5. That is a scope decision with criteria, and doing it implicitly is the escape hatch ADR 0250 exists to close.
|
|
261
|
+
- **It does not add a reopen.** A version does not un-close.
|
|
262
|
+
|
|
263
|
+
## 11. The sub-tasks this implies
|
|
264
|
+
|
|
265
|
+
All five were already filed by the planning session; this ADR is what makes them
|
|
266
|
+
mechanical. Two briefs are **corrected** by it:
|
|
267
|
+
|
|
268
|
+
| Task | What this ADR pins |
|
|
269
|
+
|---|---|
|
|
270
|
+
| R12 [#1003599](https://cloudbongos.com/builders#/task/1003599) | the route, the six refusal codes, the two-step + disposition payload (§5) |
|
|
271
|
+
| R16 [#1003603](https://cloudbongos.com/builders#/task/1003603) | **corrected** — auto-close needs no disposition machinery (§3); it hangs off *both* achievement writers on the caller exec and may never fail a ship (§4) |
|
|
272
|
+
| R17 [#1003604](https://cloudbongos.com/builders#/task/1003604) | **corrected** — the column is `succeeded_by_goal_id` and already exists; no migration (§6) |
|
|
273
|
+
| R18 [#1003605](https://cloudbongos.com/builders#/task/1003605) | the `is_maintenance` flag, the backfill, the exemption predicate, the bug carry-over (§7) |
|
|
274
|
+
| R20 [#1003607](https://cloudbongos.com/builders#/task/1003607) | promotion runs in the close txn, before roll-forward; zero planning versions is not an error (§8) |
|
|
275
|
+
| R19 [#1003606](https://cloudbongos.com/builders#/task/1003606) | its migration carries the `building` partial index **and** R04's `planning` one (§9) |
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# 0264 — The ten working areas: one goal per area, held until 5,000 builders
|
|
2
|
+
|
|
3
|
+
- **Status:** Accepted
|
|
4
|
+
- **Date:** 2026-09-07
|
|
5
|
+
- **Tasks:** [#1003696](https://cloudbongos.com/builders#/task/1003696) (this record). Executed by BV1.R25 ([#1003612](https://cloudbongos.com/builders#/task/1003612)), R26 ([#1003613](https://cloudbongos.com/builders#/task/1003613)), R27 ([#1003614](https://cloudbongos.com/builders#/task/1003614)), R28 ([#1003615](https://cloudbongos.com/builders#/task/1003615)) and R29 ([#1003617](https://cloudbongos.com/builders#/task/1003617)).
|
|
6
|
+
- **Goal:** [#1000086](https://cloudbongos.com/builders#/goal/1000086) — Strict versioning, criterion `sv-cutover-proven-live`.
|
|
7
|
+
- **Decided by:** the owner and the full team, in a manual goal review on 2026-09-07.
|
|
8
|
+
- **Builds on:** [ADR 0250](<redacted>.md) (the version boundary is the scope gate — this is the scope that boundary will hold), [ADR 0086](<redacted>.md) (the goal tier).
|
|
9
|
+
|
|
10
|
+
## 1. The decision
|
|
11
|
+
|
|
12
|
+
**The platform runs on exactly ten goals — one per working area — until it has
|
|
13
|
+
5,000 builders.** Each area has a named owner and a description of what "done"
|
|
14
|
+
looks like at that scale. Thirty-eight goals are open today; they collapse into
|
|
15
|
+
these ten.
|
|
16
|
+
|
|
17
|
+
| # | Working area | Owner | The 5,000-builder state |
|
|
18
|
+
|---|---|---|---|
|
|
19
|
+
| 1 | **Project creation** | Rini | Any new user, developer or not, can create a project from an existing folder or code repository whatever it already contains. |
|
|
20
|
+
| 2 | **Account creation, management & community** | Rini | — |
|
|
21
|
+
| 3 | **Human project management** | Scott | A project-management system with scalable levels of hierarchy — not infinitely configurable. Users edit, scope and manage work without ever prompting Claude. |
|
|
22
|
+
| 4 | **Bongos Core distribution** (staging of updates) | Lars / Will | Core updates are offered in every project's UI, and via the update CLI or skill. Approved users decide whether to take an update. A changelog is visible inside the update. |
|
|
23
|
+
| 5 | **Module distribution & economy** | Will | Modules are bought with money or credits and update the same way. Bongos assesses and ranks module quality; willing users test before mass deployment; only the best modules are listed, on price and assessed quality. |
|
|
24
|
+
| 6 | **Governor / Builder / Artist / Ideator experience** (incl. agents) | Masterqua / Rini | Each role gets a tailored experience that cannot break into the others. Noise is limited at every human interface. Agents are designed to aid all these roles. |
|
|
25
|
+
| 7 | **Government** | Will / Masterqua | Fully customizable creation of ranks and what each entails for project access. Recommended base ranks and governments ship for different project types and sizes. |
|
|
26
|
+
| 8 | **Platform credit economy** | Scott | Real money reaches users for completed work, without fail. Users hold platform balances, fund projects and pay each other with no fees. Bongos banks project funds and delivers them on cash-out. |
|
|
27
|
+
| 9 | **Platform analytics** | Lars | Bongos gathers as much user data as it can to improve itself — session transcripts as an efficiency signal, plus every user action and work delivery across the ecosystem through the Bongos API. |
|
|
28
|
+
| 10 | **Security** | all except Nils and Scott | Ranks are enforced. The Bongos server is not hackable by Claude's latest model. Red-teaming is consistent. |
|
|
29
|
+
|
|
30
|
+
## 2. Why ten, and why now
|
|
31
|
+
|
|
32
|
+
Thirty-eight open goals is not a plan; it is a list of everything anyone has ever
|
|
33
|
+
wanted. [ADR 0250](<redacted>.md) measured what that costs — 523 open tasks, fourteen goals
|
|
34
|
+
reporting done while holding thirty-five unfinished tasks — and built the
|
|
35
|
+
machinery to stop the drift. But **enforcement alone cannot shrink a scope that
|
|
36
|
+
is already too large**: D1 closes the goal set of a *building* version, which
|
|
37
|
+
freezes thirty-eight goals in place just as effectively as it would freeze ten.
|
|
38
|
+
|
|
39
|
+
So the rules and the cut are two halves of one move. This ADR is the cut. Ten is
|
|
40
|
+
chosen to be small enough that every area has a single owner who can hold its
|
|
41
|
+
whole shape in their head, and the horizon is **5,000 builders** rather than a
|
|
42
|
+
date, because the point at which this set stops being the right set is a scale
|
|
43
|
+
question, not a calendar one.
|
|
44
|
+
|
|
45
|
+
## 3. The disposition of all 38 open goals
|
|
46
|
+
|
|
47
|
+
Nothing on this list is a guess. Every row below the horizontal rule was named in
|
|
48
|
+
the review; the three rows above it were not, and are marked as such.
|
|
49
|
+
|
|
50
|
+
### Not covered by the review — open questions
|
|
51
|
+
|
|
52
|
+
| Goal | Note |
|
|
53
|
+
|---|---|
|
|
54
|
+
| [#1000003](https://cloudbongos.com/builders#/goal/1000003) — Work with no goal yet | The per-version catch-all. Already R25's target: drained and archived there. No separate decision needed. |
|
|
55
|
+
| [#1000065](https://cloudbongos.com/builders#/goal/1000065) — Community surface | Reads as the community half of area 2 and is treated as such below, but the review did not say so. **Confirm before executing R25.** |
|
|
56
|
+
| [#1000088](https://cloudbongos.com/builders#/goal/1000088) — Repo cleanup: everything justifies itself | Genuinely unmentioned, and maps to no area. **Needs an owner decision: fold, keep as an eleventh, or close.** |
|
|
57
|
+
|
|
58
|
+
### Becomes an area, or folds into one
|
|
59
|
+
|
|
60
|
+
| Goal | Disposition | Area |
|
|
61
|
+
|---|---|---|
|
|
62
|
+
| [#1000046](https://cloudbongos.com/builders#/goal/1000046) — Project creation | **becomes the area** (active; Rini building, Lars on the npm package) | 1 |
|
|
63
|
+
| [#1000065](https://cloudbongos.com/builders#/goal/1000065) — Community surface | becomes the area *(assumed — see above)* | 2 |
|
|
64
|
+
| [#1000045](https://cloudbongos.com/builders#/goal/1000045) — Public builder profiles | fold — relevant, active | 2 |
|
|
65
|
+
| [#1000075](https://cloudbongos.com/builders#/goal/1000075) — Collaboration & the social hall | fold — Niels almost done; builder collaboration is refined under community | 2 |
|
|
66
|
+
| [#1000085](https://cloudbongos.com/builders#/goal/1000085) — The operable hall | fold | 3 |
|
|
67
|
+
| [#1000054](https://cloudbongos.com/builders#/goal/1000054) — Public distribution | fold — Rini and Lars, relevant | 4 |
|
|
68
|
+
| [#1000029](https://cloudbongos.com/builders#/goal/1000029) — Module upstreaming & catalog | fold — looped into the module goal | 5 |
|
|
69
|
+
| [#1000066](https://cloudbongos.com/builders#/goal/1000066) — Role-composed context | fold — this is the working-area goal | 6 |
|
|
70
|
+
| [#1000038](https://cloudbongos.com/builders#/goal/1000038) — Agent framework & registry | fold — stays, needs cleanup from Rini; dedicated agents for specific tasks | 6 |
|
|
71
|
+
| [#1000039](https://cloudbongos.com/builders#/goal/1000039) — Agent authoring & first roster | fold into the agents one | 6 |
|
|
72
|
+
| [#1000040](https://cloudbongos.com/builders#/goal/1000040) — Agent scheduling & spend limits | fold into the agents one | 6 |
|
|
73
|
+
| [#1000025](https://cloudbongos.com/builders#/goal/1000025) — Builder experience | review first, close out solid tasks, then fold | 6 |
|
|
74
|
+
| [#1000068](https://cloudbongos.com/builders#/goal/1000068) — Government, not governance | **becomes the area** — Lars blitzes it; bugs and a rename | 7 |
|
|
75
|
+
| [#1000057](https://cloudbongos.com/builders#/goal/1000057) — Rank blocker matrix | fold into government | 7 |
|
|
76
|
+
| [#1000078](https://cloudbongos.com/builders#/goal/1000078) — Project money out | merge into builder compensation | 8 |
|
|
77
|
+
| [#1000067](https://cloudbongos.com/builders#/goal/1000067) — Ideator compensation | merge into builder payout | 8 |
|
|
78
|
+
| [#1000084](https://cloudbongos.com/builders#/goal/1000084) — Execution integrity & tenant isolation | bring into the security goal | 10 |
|
|
79
|
+
| [#1000070](https://cloudbongos.com/builders#/goal/1000070) — Scan-before-install | fold — Rini does the bug task | 10 |
|
|
80
|
+
|
|
81
|
+
Areas **3** (human project management), **4** (core distribution), **5** (module
|
|
82
|
+
distribution & economy), **8** (credit economy), **9** (platform analytics) and
|
|
83
|
+
**10** (security) have no single existing goal to promote and are **created** by
|
|
84
|
+
R29, taking the folds listed against them.
|
|
85
|
+
|
|
86
|
+
### Finish, then close
|
|
87
|
+
|
|
88
|
+
| Goal | Disposition |
|
|
89
|
+
|---|---|
|
|
90
|
+
| [#1000086](https://cloudbongos.com/builders#/goal/1000086) — Strict versioning | *"EVERYONE DO THIS NOW."* Finish, then close — it is the enabling work for the cut itself. |
|
|
91
|
+
| [#1000073](https://cloudbongos.com/builders#/goal/1000073) — Finish the GDS→Bongos rename | Niels finishes; small. |
|
|
92
|
+
| [#1000082](https://cloudbongos.com/builders#/goal/1000082) — Status ledger in the world | Lars deletes the status page, then closes it out. |
|
|
93
|
+
| [#1000024](https://cloudbongos.com/builders#/goal/1000024) — Build-pipeline integrity | A pile of bugs — check relevance, then fold or close. |
|
|
94
|
+
| [#1000032](https://cloudbongos.com/builders#/goal/1000032) — Instance hosting + domains | Clean out, then close. |
|
|
95
|
+
| [#1000058](https://cloudbongos.com/builders#/goal/1000058) — Non-cloudbongos project lifecycle | All bugs — fold into another goal. |
|
|
96
|
+
|
|
97
|
+
### Deleted
|
|
98
|
+
|
|
99
|
+
Twelve goals are cut outright:
|
|
100
|
+
|
|
101
|
+
[#1000037](https://cloudbongos.com/builders#/goal/1000037) Pay-on-land incentive alignment ·
|
|
102
|
+
[#1000043](https://cloudbongos.com/builders#/goal/1000043) Platform security: safe multi-tenant hosting ·
|
|
103
|
+
[#1000044](https://cloudbongos.com/builders#/goal/1000044) Living project sky ·
|
|
104
|
+
[#1000047](https://cloudbongos.com/builders#/goal/1000047) Project pricing & hosting revenue ·
|
|
105
|
+
[#1000048](https://cloudbongos.com/builders#/goal/1000048) SEO & public discoverability ·
|
|
106
|
+
[#1000049](https://cloudbongos.com/builders#/goal/1000049) Orb Physics ·
|
|
107
|
+
[#1000050](https://cloudbongos.com/builders#/goal/1000050) Self-hosted project analytics ·
|
|
108
|
+
[#1000052](https://cloudbongos.com/builders#/goal/1000052) First-run onboarding ·
|
|
109
|
+
[#1000053](https://cloudbongos.com/builders#/goal/1000053) Sessions start knowing ·
|
|
110
|
+
[#1000063](https://cloudbongos.com/builders#/goal/1000063) The front door ·
|
|
111
|
+
[#1000064](https://cloudbongos.com/builders#/goal/1000064) The hall as the room ·
|
|
112
|
+
[#4](https://cloudbongos.com/builders#/goal/4) CB-V1 — general (the old general bucket).
|
|
113
|
+
|
|
114
|
+
**"Delete" means `archived`, not a row removal.** `goals.status` is
|
|
115
|
+
`open|achieved|archived` (migration 160) and nothing deletes a goal — archiving is
|
|
116
|
+
the disposition, and it is reversible via `POST /goals/:id/reopen`. Preserving the
|
|
117
|
+
rows is deliberate: shipped tasks under a cut goal keep their attribution and
|
|
118
|
+
credit history, which a delete would strand.
|
|
119
|
+
|
|
120
|
+
## 4. The consequence that reorders the goal: R14 is the keystone
|
|
121
|
+
|
|
122
|
+
**None of section 3 can be executed today, and the reason is a rule this goal
|
|
123
|
+
shipped four tasks ago.**
|
|
124
|
+
|
|
125
|
+
R10 ([task #1003597](https://cloudbongos.com/builders#/task/1003597)) made
|
|
126
|
+
`POST /goals/:id/archive` refuse a goal that still holds unfinished tasks, returning
|
|
127
|
+
the tasks and demanding a disposition. That was correct and is exactly ADR 0250 D3.
|
|
128
|
+
But **the vector that supplies a disposition is R14** ([task #1003601](https://cloudbongos.com/builders#/task/1003601)), which has not shipped. So right now the
|
|
129
|
+
archive door is closed and the key has not been cut.
|
|
130
|
+
|
|
131
|
+
Every one of the twelve deletes and every fold in section 3 goes through that
|
|
132
|
+
door. That makes R14 the **keystone of the entire cut**, not one feature among
|
|
133
|
+
thirteen, and it should be built before the rest of the version-close chain
|
|
134
|
+
rather than in rank order.
|
|
135
|
+
|
|
136
|
+
This is worth stating plainly because it looks like a bug and is not: the refusal
|
|
137
|
+
is the system working as designed, one task ahead of its own remedy.
|
|
138
|
+
|
|
139
|
+
## 5. What this does not decide
|
|
140
|
+
|
|
141
|
+
- **It does not renumber or re-rank the ten areas.** The order in §1 is the review's order, not a priority.
|
|
142
|
+
- **It does not set criteria for the six new goals.** R29 scopes them; an area without done-when criteria cannot close, and inventing criteria for someone else's area is how a goal acquires scope its owner never agreed to.
|
|
143
|
+
- **It does not move any task.** Rehoming is R25 (the catch-alls) and R26 (the closed goals holding open work).
|
|
144
|
+
- **It does not decide the three open questions in §3.** They are surfaced, not guessed.
|
package/docs/adr/README.md
CHANGED
|
@@ -354,3 +354,5 @@ This keeps the decision history honest and traceable.
|
|
|
354
354
|
| 0260 | [**An application IS the consent, and the hub’s own echo is the gate** ([task 1002972](https://cloudbongos.com/builders#/task/1002972) · goal 1000045, criterion C4). Privacy spec **D7** asks that a reviewer see what the applicant’s OWN profile rules would already show, evaluated LIVE at review time. The rule is ONE port composing the two EXISTING views — `getPublicProfileExtras` for a public account, `recruiter-sliver`’s own `sliverShapeFor` for a private one — because a third five-key lookalike **is** the new disclosure class D7 forbids. **The one deliberate difference from the D3 sliver:** `getRecruiterSliver` floors on recruiting REACH, and reusing it verbatim would be wrong in the direction that looks safe — `recruiter_discoverable` defaults to FALSE for a private account, so a private builder who deliberately applied would show their reviewer NOTHING and C4 would be satisfied by an empty box. D7 settles it: *“applying is an explicit act”*. The swap relaxes REACH only; `accountActiveSql` (active **and** terms accepted) and `hide_stats` still floor it, and the proof asserts both directions on the same account so the tempting refactor cannot pass quietly. **The federated route’s gate is the whole security story** ([ADR 0205](<redacted>.md) / security report 1000027): client credentials name a PROJECT and never a person, so `POST /sso/applicant-profile` authenticated alone is a bulk disclosure oracle over every account on the platform, private ones included. `applicationBacksProfileRead` demands a HUB-WRITTEN echo for exactly (this account, this client) inside the same 30-day window — a row only the hub’s own join relay creates — refusing **404, never 403**, and BEFORE any account is read (asserted on the statement log, because a gate that refuses after reading has already done the disclosure work). LIVE means nothing is stored at either end; the queue keys on the VOUCH and never on `github_login` (the one PUBLIC unauthenticated write makes an unvouched login an impersonation surface); and the hub client secret stays in core behind a narrow doorway port. **The path is complete but DORMANT until R09 ([task 1002285](https://cloudbongos.com/builders#/task/1002285)) ships the vouch writer** — nothing writes `applicant_github_id` today, and that dependency was missing from 1002972’s graph. Rejected: routing the port through `getRecruiterSliver`, a snapshot at apply time, resolving by `github_login`, and putting `loadIdpConfig` on the doorway.](<redacted>.md) | platform identity / privacy |
|
|
355
355
|
| 0261 | [**A preselect always carries a reason; the bundle’s summary is the floor** ([task 1003684](https://cloudbongos.com/builders#/task/1003684) · goal 1000046 — *Project creation*). Resolves a collision between two rules that were each right alone. [ADR 0243](<redacted>.md) made `adjustments` a **delta** — a team-shape rule that fires without moving anything claims nothing, because a sentence explaining a change that did not happen is a claim the owner cannot check. [ADR 0237](<redacted>.md) says a preselect the owner cannot see a reason for is one they must audit, which is worse than no preselect at all. The two collide whenever a type’s bundle **already contains** what a rule would add: `game` is `[dev-box, discord]` and the `small-team` rule adds `dev-box`, so the rule fires, moves nothing, and correctly reports `adjustments: []`. Confirmed on live core 1.19.580 — `byTeamShape[small-team]` = `{"bundle":["dev-box","discord"],"adjustments":[]}`. The owner then reached step 4 and saw **two extras switched on with no reason beside them**, `#modWhy` an empty hidden div: exactly what 0237 exists to prevent, produced by 0243 behaving correctly. Filed as a dropped adjustment; it was not — the engine is right, and the panel simply had ONE voice and fell silent when the rule had nothing to say. **Decision: the why-line has two voices and the type’s is the floor.** A real adjustment still speaks for itself and is never displaced; when none moved, the type’s own curated `summary` explains the preselect; when the owner has answered the picker themselves the panel stays silent (unchanged — a reason handed back for a toggle they just flipped reads as the panel arguing with them); a bundle with no summary still says nothing, because a floor is not an invention. **No new copy, endpoint or field** — the summary was authored for this job in `starter-bundles.js`, served on every row of `GET /provisioning/starter-bundles`, and rendered NOWHERE in the product until now. 0243 is not weakened: the delta stays a delta and no rule is credited with a change it did not make. The pin `tests/projects_hub_module_picker.mjs` carried a fixture with **no `summary` field**, which made four “no adjustment, no sentence” cases pass for the wrong reason; the fixture now carries the real summaries and those cases assert the new contract, including explicitly that no RULE sentence is invented for a change that did not happen. Rejected: making the rule claim a no-op change (re-introduces the unverifiable claim 0243 removed); widening the bundles so no rule is ever redundant (contorts curated presets for a rendering concern, and the redundancy returns on the next edit); and leaving it silent, declined by the owner once the trade-off was put to them directly.](<redacted>.md) | provisioning / starter bundles / owner-facing copy |
|
|
356
356
|
| 0262 | [**A bug never lands in the inbox: the system names the home the reporter didn't** ([task 1003691](https://cloudbongos.com/builders#/task/1003691) · goal 1000086 — *Strict versioning*). `routing.js` returned early on a goal-less filing, so its own `kind='bug'` hard-land branch was UNREACHABLE without a goal — `kind` only ever chose a routed task's STATUS, never whether it routed — and a reported defect sat in `idea_inbox` awaiting the triage pass criterion C1 exists to remove. The premise that [ADR 0250](<redacted>.md) D4 and [ADR 0235](<redacted>.md) contradict each other is FALSE: 0235's exemption is an advisory silence in `goal-advisory.adviseGoal`, and its actual decision already requires a real `goal_id`. So nothing is amended; this is the explicit decision 0235 §6 said would be needed. **D1** a homeless bug gets the version's MAINTENANCE goal (R18's design), find-or-created under an advisory lock inside the route's own transaction — not the catch-all R11 is deleting, and adding no `allowCatchAll` caller. **D2** the gate is the VECTOR (`api`, `discord-bugs`), not the kind: `#ideas` passes no kind, so the classifier guesses one from keywords, and gating on kind alone would silently overturn [ADR 0234](<redacted>.md)'s owner-interview decision. Rejected: goal-less bug tasks (breaks D4 a day after it landed); rejecting the filing (Discord cannot retry, so the report is lost); the catch-all (repopulates the bucket being drained); building R18 whole first.](<redacted>.md) | work intake / idea routing / the version-goal invariant |
|
|
357
|
+
| 0263 | [**How a version closes: auto, early, roll-forward, and the maintenance exemption** ([task 1003593](https://cloudbongos.com/builders#/task/1003593) · goal 1000086 — *Strict versioning*). [ADR 0250](<redacted>.md) D5 decided a version *can* close; this is the design pass that makes its five build tasks mechanical, so they do not each invent their own refusal codes and payload shapes and meet only in production. **The asymmetry that shrinks the feature:** auto-close fires when the last non-maintenance goal achieves — so by construction every non-maintenance goal is already closed and the set needing a disposition is EMPTY. All the machinery (the disposition map, the refusal that returns the goals, successor lineage) belongs to EARLY close alone; R16 is small and R12 carries the weight. **Auto-close hangs off BOTH achievement writers** (`db-goals.achieveGoalIfComplete` and the `done-when` cascade — the deliberate duplicate D2 already governs, a require cycle being the reason they are not one helper), on the caller `exec` so it sees the ship's uncommitted flip, and **may never fail a ship**: wrapped and swallowed like `closeCompletedWorkForShip`, idempotent under `WHERE status='building'`, so a failure leaves a version un-closed (self-healing on the next reconciler sweep) and never half-closed. **Early close** is the R10 archive two-step verbatim in spirit — refuse with `version_holds_open_goals` **returning the goals**, then proceed with a per-goal `roll_forward`/`abandon` map and a required `reason`; six named codes, because the callers are agents. **Two briefs are corrected by measurement:** the lineage column is `succeeded_by_goal_id` (migration 160, on the OLD row pointing forward) — not the `succeeds_goal_id` both 0250 and R17's brief name, so R17 needs NO migration; and R18's `is_maintenance` flag is load-bearing rather than cosmetic, because answering the close count with a `title NOT LIKE` would let a hand-titled goal silently exempt itself from the gate that decides when a VERSION closes. Promotion runs inside the close txn and BEFORE roll-forward (`ensureMaintenanceGoal` returns null for a non-`building` version, so a carry-over run first silently carries nothing); zero planning versions is not an error; R19's one migration should carry the `building` AND `planning` partial unique indexes so the promotion race resolves like a 23505 rather than a prayer. Rejected: auto-creating the successor version inside a close (the "fake hotfix version" escape hatch 0250 built the override counter to prevent), writing `limitations/<version>-shipped.md` from the route (file I/O in a ship transaction — it stays R23's CLI work), and a version reopen.](<redacted>.md) | version lifecycle / scope closure |
|
|
358
|
+
| 0264 | [**The ten working areas: one goal per area, held until 5,000 builders** ([task 1003696](https://cloudbongos.com/builders#/task/1003696) · goal 1000086 — *Strict versioning*, criterion `sv-cutover-proven-live`). The owner and the full team ran a manual goal review on 2026-09-07 and cut **38 open goals down to 10**, one per working area, each with a named owner and a described 5,000-builder end state: project creation (Rini), account/community (Rini), human project management (Scott), core distribution (Lars/Will), module distribution & economy (Will), the four-role experience incl. agents (Masterqua/Rini), government (Will/Masterqua), the credit economy (Scott), platform analytics (Lars), security (everyone bar Nils and Scott). **Why the rules were not enough on their own:** [ADR 0250](<redacted>.md) D1 closes the goal set of a BUILDING version — which freezes 38 goals exactly as effectively as it would freeze 10. Enforcement cannot shrink a scope that is already too large, so the rules and the cut are two halves of one move; the horizon is a SCALE (5,000 builders), not a date, because that is the question that decides when this set stops being the right set. **The finding that reorders the goal:** none of the cut can be executed today. R10 ([task 1003597](https://cloudbongos.com/builders#/task/1003597)) made `POST /goals/:id/archive` refuse a goal holding unfinished tasks and demand a disposition — correct, and exactly D3 — but the vector that SUPPLIES a disposition is R14 ([task 1003601](https://cloudbongos.com/builders#/task/1003601)), unshipped. Every one of the 12 deletes and every fold goes through that door, so **R14 is the keystone of the whole cut**, not one feature among thirteen, and is built before the rest of the version-close chain rather than in rank order. It looks like a bug and is not: the refusal is the design, landed one task ahead of its own remedy. "Delete" means `archived`, never a row removal (`goals.status` is open|achieved|archived, migration 160; reversible via `/reopen`) — preserving the rows keeps shipped-task attribution and credit history a delete would strand. Three open goals were NOT covered by the review and are surfaced as open questions rather than guessed: 1000003 (the catch-all — already R25's target), 1000065 (assumed to be area 2's community half), and 1000088 (repo cleanup — maps to no area, needs an owner decision). Deliberately does not decide: the areas' priority order, criteria for the six goals R29 must create (inventing criteria for someone else's area is how a goal acquires scope its owner never agreed to), or any task rehoming (R25/R26).](<redacted>.md) | scope / goal set / owner decision |
|
|
@@ -1623,5 +1623,9 @@ is load-bearing: the script throws rather than guess if it is missing, and
|
|
|
1623
1623
|
landed since 1.19.585 with no explicit bump. run 34167072966. (task 1002620)
|
|
1624
1624
|
1.19.587 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
1625
1625
|
landed since 1.19.586 with no explicit bump. run 34172785860. (task 1002620)
|
|
1626
|
+
1.19.588 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
1627
|
+
landed since 1.19.587 with no explicit bump. run 34178696372. (task 1002620)
|
|
1628
|
+
1.19.589 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
1629
|
+
landed since 1.19.588 with no explicit bump. run 34179479729. (task 1002620)
|
|
1626
1630
|
---------------------------------------------------------------------------
|
|
1627
1631
|
```
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.589",
|
|
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.589",
|
|
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.589",
|
|
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
|
@@ -55,7 +55,7 @@ const { buildInfo } = require('./build-info');
|
|
|
55
55
|
// there. scripts/gds/bump-version.js still rewrites the literal below; it appends
|
|
56
56
|
// the entry to that file. Look for a version's history there, not here.
|
|
57
57
|
// ---------------------------------------------------------------------------
|
|
58
|
-
const CORE_VERSION = '1.19.
|
|
58
|
+
const CORE_VERSION = '1.19.589'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
|
|
59
59
|
|
|
60
60
|
// A namespaced logger so a module's log lines are attributable + consistent.
|
|
61
61
|
// Usage: const log = api.logger('dev-box'); log.info('mounted');
|