@bongos/core 1.19.241 → 1.19.242
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.bongos-core.json
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
"artifact": "bongos-core",
|
|
3
3
|
"manifest_schema": 1,
|
|
4
4
|
"generator": "scripts/gds/package-core.js",
|
|
5
|
-
"core_version": "1.19.
|
|
6
|
-
"core_contract": "1.19.
|
|
7
|
-
"source_commit": "
|
|
5
|
+
"core_version": "1.19.242",
|
|
6
|
+
"core_contract": "1.19.242",
|
|
7
|
+
"source_commit": "900c5fe4161d60490d52cd4dfa2e0857a2748042",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-08-18T20:51
|
|
9
|
+
"built_at": "2026-08-18T20:58:51.212Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
12
|
"docs_redacted": 312,
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
19
|
"file_count": 1660,
|
|
20
|
-
"tree_sha256": "
|
|
20
|
+
"tree_sha256": "367c3937d0fd713cbda6b0e1ea8a32ea5f0be72b756ba5440760d6ff8a07b5d4",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/blocker-review/SKILL.md",
|
|
@@ -1367,7 +1367,7 @@
|
|
|
1367
1367
|
{
|
|
1368
1368
|
"path": "docs/adr/0177-goal-membership-kind.md",
|
|
1369
1369
|
"mode": "0000644",
|
|
1370
|
-
"sha256": "
|
|
1370
|
+
"sha256": "922dc12e699d3631907292e0a5550806ac88a160394c65c8223f65e58a46bc6f"
|
|
1371
1371
|
},
|
|
1372
1372
|
{
|
|
1373
1373
|
"path": "docs/adr/README.md",
|
|
@@ -2377,7 +2377,7 @@
|
|
|
2377
2377
|
{
|
|
2378
2378
|
"path": "migrations/core_220_goal_members_membership_kind.sql",
|
|
2379
2379
|
"mode": "0000644",
|
|
2380
|
-
"sha256": "
|
|
2380
|
+
"sha256": "e0503f677b4b30eca07badd76ba9b177f603f3740da366c1be40cb67a5537690"
|
|
2381
2381
|
},
|
|
2382
2382
|
{
|
|
2383
2383
|
"path": "modules/autonomy/CLAUDE.md",
|
|
@@ -4347,12 +4347,12 @@
|
|
|
4347
4347
|
{
|
|
4348
4348
|
"path": "package-lock.json",
|
|
4349
4349
|
"mode": "0000644",
|
|
4350
|
-
"sha256": "
|
|
4350
|
+
"sha256": "026bf4799e0c4eab9e946c1f9d1668f5ee3f47ad487ef5abbfe9de063867cc0f"
|
|
4351
4351
|
},
|
|
4352
4352
|
{
|
|
4353
4353
|
"path": "package.json",
|
|
4354
4354
|
"mode": "0000644",
|
|
4355
|
-
"sha256": "
|
|
4355
|
+
"sha256": "343d7a6a0e9c8123a4f5cf336dfb8bdaf59c735227371c8fe8b632b6a17706a5"
|
|
4356
4356
|
},
|
|
4357
4357
|
{
|
|
4358
4358
|
"path": "public-docs/index.html",
|
|
@@ -5967,7 +5967,7 @@
|
|
|
5967
5967
|
{
|
|
5968
5968
|
"path": "src/module-api.js",
|
|
5969
5969
|
"mode": "0000644",
|
|
5970
|
-
"sha256": "
|
|
5970
|
+
"sha256": "c78192a54a2578a22420c02ac2da5397bccc6fa582540d8184d792dac9b13df3"
|
|
5971
5971
|
},
|
|
5972
5972
|
{
|
|
5973
5973
|
"path": "src/module-loader/catalog.js",
|
|
@@ -7347,7 +7347,7 @@
|
|
|
7347
7347
|
{
|
|
7348
7348
|
"path": "tests/membership_kind_lockstep.mjs",
|
|
7349
7349
|
"mode": "0000644",
|
|
7350
|
-
"sha256": "
|
|
7350
|
+
"sha256": "e40df74d518a508417dbea2d8f39952bd8f666e866aff985a8ab72758ead873a"
|
|
7351
7351
|
},
|
|
7352
7352
|
{
|
|
7353
7353
|
"path": "tests/memory_isolation.mjs",
|
|
@@ -128,9 +128,11 @@ cannot, if the new column has a DEFAULT: **Postgres materializes a column defaul
|
|
|
128
128
|
statement — took the "new code wrote it" branch and overwrote `role`, turning a pending
|
|
129
129
|
INVITE into an active membership. So the new column stays **DEFAULT-less** while the legacy
|
|
130
130
|
one is still written (NULL then means exactly "not written"), and `DEFAULT` + `NOT NULL`
|
|
131
|
-
arrive together in step 2. `core_220` shipped with the defective form and
|
|
132
|
-
under task [#1003093](https://cloudbongos.com/builders#/task/1003093) —
|
|
133
|
-
statement
|
|
131
|
+
arrive together in step 2. `core_220` shipped with the defective form and was corrected
|
|
132
|
+
the same day under task [#1003093](https://cloudbongos.com/builders#/task/1003093) — there
|
|
133
|
+
the same statement demoted a goal's first lead to `member` on a fresh install
|
|
134
|
+
(`<redacted>.sql` runs after the core migrations), and no production
|
|
135
|
+
row was ever affected because the pin still served 1.19.218; the invariant is
|
|
134
136
|
pinned statically by `tests/membership_kind_lockstep.mjs`, since the trigger only
|
|
135
137
|
misbehaves against a live Postgres and CI has none.
|
|
136
138
|
|
|
@@ -43,8 +43,15 @@ ALTER TABLE goal_members
|
|
|
43
43
|
|
|
44
44
|
UPDATE goal_members SET membership_kind = role WHERE membership_kind IS NULL;
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
-- NO DEFAULT WHILE `role` IS STILL WRITTEN — and this is load-bearing, not tidiness
|
|
47
|
+
-- (task 1003093, found by the grader on the sibling migration). Postgres materializes
|
|
48
|
+
-- a column DEFAULT into NEW *before* any BEFORE ROW trigger fires, so a default here
|
|
49
|
+
-- would make `NEW.membership_kind IS NULL` never true and the trigger could no longer
|
|
50
|
+
-- tell "the caller wrote the new column" from "the default filled it". An old-release
|
|
51
|
+
-- INSERT naming only `role` — lifecycle_001_goal_first_leads.sql's `'lead'`, or
|
|
52
|
+
-- createGoal / transferGoalOwnership on a pre-1003013 pin — would then be silently
|
|
53
|
+
-- rewritten to the default, DEMOTING the goal's own lead to a plain member. The
|
|
54
|
+
-- DEFAULT (and NOT NULL) arrive in step 2, when `role` is dropped.
|
|
48
55
|
|
|
49
56
|
DO $$
|
|
50
57
|
BEGIN
|
|
@@ -63,20 +70,24 @@ END $$;
|
|
|
63
70
|
-- statement that wrote either one — no second UPDATE, no window where the two
|
|
64
71
|
-- disagree, and nothing for application code to remember.
|
|
65
72
|
--
|
|
66
|
-
-- Direction is decided by WHICH SIDE
|
|
67
|
-
--
|
|
73
|
+
-- Direction is decided by WHICH SIDE THE CALLER WROTE: new code sets
|
|
74
|
+
-- membership_kind and `role` follows; the historical
|
|
68
75
|
-- lifecycle_001_goal_first_leads.sql seed (and any pre-upgrade code, including
|
|
69
|
-
-- the release a rollback would restore) sets `role` and membership_kind
|
|
70
|
-
--
|
|
71
|
-
--
|
|
72
|
-
--
|
|
76
|
+
-- the release a rollback would restore) sets `role` and membership_kind follows.
|
|
77
|
+
-- On INSERT that question is answered by `NEW.membership_kind IS NULL`, which is
|
|
78
|
+
-- only trustworthy because the new column has NO DEFAULT — see the note above it.
|
|
79
|
+
-- On UPDATE, OLD is available and the comparison is direct.
|
|
73
80
|
CREATE OR REPLACE FUNCTION goal_members_membership_kind_lockstep() RETURNS trigger AS $$
|
|
74
81
|
BEGIN
|
|
75
82
|
IF TG_OP = 'INSERT' THEN
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
83
|
+
-- NULL means the caller did not write the new column (see the no-DEFAULT note
|
|
84
|
+
-- above): an old-release INSERT, so `role` is the source of truth. Otherwise the
|
|
85
|
+
-- caller is new code and `role` follows, so an older release can still read it.
|
|
86
|
+
IF NEW.membership_kind IS NULL THEN
|
|
79
87
|
NEW.membership_kind := COALESCE(NEW.role, 'member');
|
|
88
|
+
NEW.role := COALESCE(NEW.role, 'member');
|
|
89
|
+
ELSE
|
|
90
|
+
NEW.role := NEW.membership_kind;
|
|
80
91
|
END IF;
|
|
81
92
|
ELSE
|
|
82
93
|
IF NEW.membership_kind IS DISTINCT FROM OLD.membership_kind THEN
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.242",
|
|
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.242",
|
|
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.242",
|
|
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
|
@@ -909,8 +909,10 @@ const { validateOrRespond, LIMITS, parseId, asyncHandler, corsPublicGet, parsePa
|
|
|
909
909
|
// landed since 1.19.239 with no explicit bump. run 32182178305. (task 1002620)
|
|
910
910
|
// 1.19.241 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
911
911
|
// landed since 1.19.240 with no explicit bump. run 32184475745. (task 1002620)
|
|
912
|
+
// 1.19.242 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
913
|
+
// landed since 1.19.241 with no explicit bump. run 32185198139. (task 1002620)
|
|
912
914
|
// ---------------------------------------------------------------------------
|
|
913
|
-
const CORE_VERSION = '1.19.
|
|
915
|
+
const CORE_VERSION = '1.19.242'; // CI auto-patch carrier (ADR 0161); see changelog above
|
|
914
916
|
|
|
915
917
|
// A namespaced logger so a module's log lines are attributable + consistent.
|
|
916
918
|
// Usage: const log = api.logger('dev-box'); log.info('mounted');
|
|
@@ -19,6 +19,12 @@
|
|
|
19
19
|
// A old-invite-pending | role=builder | membership_kind=member ← WRONG (before)
|
|
20
20
|
// A old-invite-pending | role=pending | membership_kind=pending ← after the fix
|
|
21
21
|
//
|
|
22
|
+
// core_220 carried the same defect (task 1003093): an old-release
|
|
23
|
+
// `INSERT … (goal_id, builder_id, role) VALUES (…, 'lead')` — which is exactly what
|
|
24
|
+
// lifecycle_001_goal_first_leads.sql issues on a FRESH install, after the core
|
|
25
|
+
// migrations — landed `role=member, membership_kind=member`, silently demoting every
|
|
26
|
+
// new goal's creator out of manager standing.
|
|
27
|
+
//
|
|
22
28
|
// The fix is the absence of a DEFAULT while the legacy column is still written, so
|
|
23
29
|
// NULL means exactly "not written". The DEFAULT (and NOT NULL) belong to step 2,
|
|
24
30
|
// when the legacy column is dropped. This file pins that invariant statically,
|
|
@@ -34,11 +40,17 @@ import { fileURLToPath } from 'node:url';
|
|
|
34
40
|
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
35
41
|
const read = (rel) => fs.readFileSync(path.join(ROOT, rel), 'utf8');
|
|
36
42
|
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
//
|
|
43
|
+
// BOTH expand-phase migrations, since task 1003093 fixed core_220's identical
|
|
44
|
+
// INSERT branch. core_220's version of the bug demoted a goal's own LEAD: on a fresh
|
|
45
|
+
// install, lifecycle_001_goal_first_leads.sql inserts the creator with `role='lead'`
|
|
46
|
+
// AFTER core migrations run, so every new goal's creator landed as a plain member and
|
|
47
|
+
// lost manager standing. Verified against a real Postgres both ways round.
|
|
41
48
|
const EXPAND_MIGRATIONS = [
|
|
49
|
+
{
|
|
50
|
+
rel: 'migrations/core_220_goal_members_membership_kind.sql',
|
|
51
|
+
table: 'goal_members',
|
|
52
|
+
legacy: 'role',
|
|
53
|
+
},
|
|
42
54
|
{
|
|
43
55
|
rel: 'modules/platform-identity/migrations/platform_identity_010_membership_kind.sql',
|
|
44
56
|
table: 'platform_identity_project_memberships',
|