@bongos/core 1.19.501 → 1.19.502

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.501",
6
- "core_contract": "1.19.501",
7
- "source_commit": "d6bac950eb66f758928e815cf88f2d6ddacaf30a",
5
+ "core_version": "1.19.502",
6
+ "core_contract": "1.19.502",
7
+ "source_commit": "0028d2b0b8159fb3da54835fd45eeb3ae98f7916",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-09-03T15:41:46.721Z",
9
+ "built_at": "2026-09-03T16:16:35.542Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
12
  "docs_redacted": 426,
@@ -17,7 +17,7 @@
17
17
  "gate": "passed"
18
18
  },
19
19
  "file_count": 2392,
20
- "tree_sha256": "d4ef43893ca56f9d2d4e0df1823f7fdb2692bb3f3a18d8bb2fece9221dc83925",
20
+ "tree_sha256": "ad1558679b2605e11cf647772ee24f67c5bd59c0e1d98bcdf81d7a795c456654",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/blocker-review/SKILL.md",
@@ -317,7 +317,7 @@
317
317
  {
318
318
  "path": ".gitattributes",
319
319
  "mode": "0000644",
320
- "sha256": "106e3a8a087cf1a9dd932513115d16c387cfeebea0e22ed269a672f95efdac1e"
320
+ "sha256": "3848ed851a03fd11f8dae94c1e94b802c4aa625efaa7f4aff27438a1fdfb67ac"
321
321
  },
322
322
  {
323
323
  "path": "CLAUDE.md",
@@ -877,7 +877,7 @@
877
877
  {
878
878
  "path": "docs/adr/0082-server-side-merge-conflict-auto-resolution.md",
879
879
  "mode": "0000644",
880
- "sha256": "ce00626058783ba42629d88da8d03ef868d4743d4b01ed87b6348d20fcbca395"
880
+ "sha256": "7da7140202139c123e832f527167c96de18eb498ae21243cd30cea6b133c8f90"
881
881
  },
882
882
  {
883
883
  "path": "docs/adr/0083-modular-architecture-strangler-build-plan.md",
@@ -2572,7 +2572,7 @@
2572
2572
  {
2573
2573
  "path": "docs/module-api-changelog.md",
2574
2574
  "mode": "0000644",
2575
- "sha256": "49c673ec2ee31c6174bdc48d1b124905bd1f47a51db4e0a3a75e4d937a25ba0a"
2575
+ "sha256": "bccd3e96df6a344e806052af69493507b4ccab78ab3149aa10f7373d8546fb97"
2576
2576
  },
2577
2577
  {
2578
2578
  "path": "docs/modules-contract.md",
@@ -7217,12 +7217,12 @@
7217
7217
  {
7218
7218
  "path": "package-lock.json",
7219
7219
  "mode": "0000644",
7220
- "sha256": "79dfc35495b354b8e53ac84d6210c5c84e8d1bd6a97fc08c84dcbcfd7cc7379d"
7220
+ "sha256": "5911d20e472c017d950ca2154d1c0e86e7479e07c9efb4a02eecea0534aae58c"
7221
7221
  },
7222
7222
  {
7223
7223
  "path": "package.json",
7224
7224
  "mode": "0000644",
7225
- "sha256": "5c08ffd017c27b4ac3a97a55988bbd1fd9958a1ac15ab9e4a689af04531889b6"
7225
+ "sha256": "2220826fc5bb64636838a79c72229e973109a28639174748ca7e2fb505192f97"
7226
7226
  },
7227
7227
  {
7228
7228
  "path": "public-docs/index.html",
@@ -7737,7 +7737,7 @@
7737
7737
  {
7738
7738
  "path": "scripts/gds/git-merge-regen.js",
7739
7739
  "mode": "0000644",
7740
- "sha256": "75130de4a880fc7d76f5a8d79ed65750238df94847c1ccfdc974188f9300a1e6"
7740
+ "sha256": "f9a391ac6f32b2d5ca939b48186b6d9cb7aa171554652a5b5afbc4a408aae203"
7741
7741
  },
7742
7742
  {
7743
7743
  "path": "scripts/gds/go-live.js",
@@ -8892,7 +8892,7 @@
8892
8892
  {
8893
8893
  "path": "src/module-api.js",
8894
8894
  "mode": "0000644",
8895
- "sha256": "980689b2fd9c8e0db4213b6ef449b68cef246f40ff3752925562f0f7ed818a16"
8895
+ "sha256": "636b358e8be667bd38743b42009ee1101b0c330584fc647f71424c03fe166c71"
8896
8896
  },
8897
8897
  {
8898
8898
  "path": "src/module-loader/catalog.js",
@@ -9882,7 +9882,7 @@
9882
9882
  {
9883
9883
  "path": "tests/git_merge_regen.mjs",
9884
9884
  "mode": "0000644",
9885
- "sha256": "3c718cdd83f7c997a89bcf55120ad641a2c8ed4bea7cbbf5aa253792f867a467"
9885
+ "sha256": "2d3574914c1f9c843396f498a8e68c2fd8ec2a5bc574c98f64dc2505aa1ccba8"
9886
9886
  },
9887
9887
  {
9888
9888
  "path": "tests/github_push_ancestry.mjs",
package/.gitattributes CHANGED
@@ -74,6 +74,16 @@ src/bongos/CLAUDE.md merge=otb-regen
74
74
  src/bongos/routes/CLAUDE.md merge=otb-regen
75
75
  scripts/gds/CLAUDE.md merge=otb-regen
76
76
 
77
+ # docs/copy-registry.json + docs/copy-inventory.md (task 1003543): the copy
78
+ # registry's committed pair (scripts/gds/copy-inventory.js) — fully generated from
79
+ # a tree scan, nothing hand-authored in either, so two branches that each touch
80
+ # hall/status/landing copy regenerate them differently and conflict like ordinary
81
+ # files. Same otb-regen shape as docs/session-log-index.md above (whole-file
82
+ # rebuild, all three merge sides ignored); REGENERABLE in git-merge-regen.js
83
+ # carries the matching rule.
84
+ docs/copy-registry.json merge=otb-regen
85
+ docs/copy-inventory.md merge=otb-regen
86
+
77
87
  # Append-only index tables (task 1385 / ADR 0082). docs/adr/README.md is a
78
88
  # hand-maintained ADR index whose ONLY recurring conflict is two branches each
79
89
  # appending a new row — there is no generator to regen it from, so `otb-regen`
@@ -48,6 +48,10 @@ The PR's required checks (unit / trufflehog / audit / gate-review) re-run on the
48
48
  - `docs/adr/README.md` itself now carries `merge=union`, so this ADR's own index row — and every future one — stops conflicting.
49
49
  - The generated-artifact set is defined once (`REGENERABLE` in `git-merge-regen.js`, mirrored by `.gitattributes` and the `fitness.js` freshness gate); adding a future generated file means adding it in those places together.
50
50
 
51
+ ## Addendum (task 1003543, 2026-09-03) — the copy registry joined the whole-file set
52
+
53
+ Two hall PRs in one session (526 for task 1003069, 531 for task 1003157) both ran `scripts/gds/copy-inventory.js` and sat `confirmed` with GitHub `mergeable=CONFLICTING` for 20+ minutes: `docs/copy-inventory.md` + `docs/copy-registry.json` carried no `.gitattributes` entry and no `REGENERABLE` rule, so they conflicted as ordinary text/JSON and the server resolver could not heal them (`resolveBranchConflicts` *did* run — its log line fired for both PRs — but the `otb-regen` driver refused the unregistered paths and the merge came back non-zero, which the resolver correctly reported as `unresolvable_conflict`; the reconciler dispatch was never the gap). Both files are, like `docs/repo-map.md` and `docs/session-log-index.md`, 100% generated from a tree scan with nothing hand-authored in either — `copy-inventory.js`'s own header says so ("Deterministic on a given tree — regenerate and commit rather than hand-editing"), so they needed the whole-file `otb-regen` shape, not `union`. The fix: `docs/copy-registry.json merge=otb-regen` + `docs/copy-inventory.md merge=otb-regen` in `.gitattributes`, both added to `REGENERABLE` in `git-merge-regen.js` with a regeneration rule that calls `copy-inventory.js`'s `buildRegistry()`/`renderReport()` directly (ignoring all three merge sides, same as the repo-map heal). No change was needed to `conflict-resolve.js`, `publish-reconciler.js`, or `ship-preflight-steps.js` — none of the three keeps its own copy of the generated-file list; all three read `REGENERABLE` (or, for the resolver, register the driver that reads it), so the new pair is covered everywhere the existing four already were.
54
+
51
55
  ## Alternatives considered
52
56
 
53
57
  - **Lower deploy/merge access to `thetes`** (the owner's first instinct) — rejected: reopens the Builder 25 hole for zero benefit here (the stranded session was already Archon; rank was never the blocker).
@@ -1439,5 +1439,7 @@ is load-bearing: the script throws rather than guess if it is missing, and
1439
1439
  landed since 1.19.499 with no explicit bump. run 33772499045. (task 1002620)
1440
1440
  1.19.501 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1441
1441
  landed since 1.19.500 with no explicit bump. run 33774087943. (task 1002620)
1442
+ 1.19.502 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1443
+ landed since 1.19.501 with no explicit bump. run 33777587058. (task 1002620)
1442
1444
  ---------------------------------------------------------------------------
1443
1445
  ```
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.501",
3
+ "version": "1.19.502",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.19.501",
9
+ "version": "1.19.502",
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.501",
3
+ "version": "1.19.502",
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",
@@ -28,6 +28,7 @@ const { spawnSync } = require('node:child_process');
28
28
  const G = require('./gen-repo-map');
29
29
  const FM = require('./gen-file-map');
30
30
  const SI = require('./gen-session-index');
31
+ const CI = require('./copy-inventory');
31
32
 
32
33
  const REPO_ROOT = path.resolve(__dirname, '..', '..');
33
34
 
@@ -36,10 +37,18 @@ const REPO_ROOT = path.resolve(__dirname, '..', '..');
36
37
  // hand-written prose with one generated block; docs/file-map.md is hand-written
37
38
  // prose with TWO generated section blocks (ADR 0066). (task 1385: session-log-index
38
39
  // joined so a confirmed PR that only conflicts on it self-heals like the rest.)
40
+ // docs/copy-inventory.md + docs/copy-registry.json (task 1003543) are the copy
41
+ // registry's own pair — like repo-map.md, `copy-inventory.js` writes them
42
+ // wholesale from a tree scan with nothing hand-authored in either, so any two
43
+ // branches that both touch hall/status/landing copy regenerate them differently
44
+ // and conflict on ordinary text; they join the whole-file group for the same
45
+ // reason session-log-index.md did.
39
46
  const REGENERABLE = new Set([
40
47
  'docs/repo-map.md',
41
48
  'docs/file-map.md',
42
49
  'docs/session-log-index.md',
50
+ 'docs/copy-inventory.md',
51
+ 'docs/copy-registry.json',
43
52
  ...G.NESTED_DIRS.map((d) => `${d}/CLAUDE.md`),
44
53
  ]);
45
54
 
@@ -86,6 +95,17 @@ function regenerateResolved(relpath, { base = '', ours = '', theirs = '' } = {})
86
95
  return { content: SI.renderIndex(SI.collectEntries()), ok: true };
87
96
  }
88
97
 
98
+ // docs/copy-registry.json / docs/copy-inventory.md: both artifacts of one scan
99
+ // (copy-inventory.js), fully generated — ignore all three sides, rebuild from
100
+ // the merged tree. Reuse buildRegistry() rather than shelling out to write() so
101
+ // this stays in-process like the repo-map/session-index heals above.
102
+ if (relpath === 'docs/copy-registry.json') {
103
+ return { content: `${JSON.stringify(CI.buildRegistry(), null, 2)}\n`, ok: true };
104
+ }
105
+ if (relpath === 'docs/copy-inventory.md') {
106
+ return { content: CI.renderReport(CI.buildRegistry()), ok: true };
107
+ }
108
+
89
109
  const model = G.buildModel();
90
110
 
91
111
  // docs/repo-map.md is fully generated — ignore all three sides, rebuild it.
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.501'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
48
+ const CORE_VERSION = '1.19.502'; // 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');
@@ -14,6 +14,14 @@
14
14
  // markers remain) so a human resolves it — the heal never clobbers real edits.
15
15
  // 4. The merge-driver entrypoint writes %A + exits 0 (heal) / 1 (real conflict).
16
16
  // 5. A non-generated path is never touched (not in REGENERABLE).
17
+ // 6. END-TO-END: a real `git merge` invokes the driver via .gitattributes.
18
+ // 7. .gitattributes' merge=otb-regen lines and REGENERABLE agree (task 1003543).
19
+ // 8. docs/copy-registry.json + docs/copy-inventory.md (task 1003543) — the copy
20
+ // registry's own pair — regenerate clean from the merged tree, same as
21
+ // repo-map.md, ignoring the conflicted sides.
22
+ // 9. END-TO-END for docs/copy-registry.json: two branches that each regenerate
23
+ // it differently merge without conflict markers via the real .gitattributes +
24
+ // git-config wiring, and the result equals a fresh regeneration.
17
25
  //
18
26
  // Run: node tests/git_merge_regen.mjs
19
27
 
@@ -30,6 +38,7 @@ const here = path.dirname(fileURLToPath(import.meta.url));
30
38
  const repo = path.resolve(here, '..');
31
39
  const regen = require('../scripts/gds/git-merge-regen.js');
32
40
  const G = require('../scripts/gds/gen-repo-map.js');
41
+ const CI = require('../scripts/gds/copy-inventory.js');
33
42
 
34
43
  const MARKERS = /^(<{7}|={7}|>{7})/m;
35
44
 
@@ -148,4 +157,82 @@ function withBlockBody(src, body) {
148
157
  }
149
158
  }
150
159
 
160
+ // ── 7) .gitattributes' merge=otb-regen lines and REGENERABLE agree (task 1003543) ─
161
+ // The whole scheme is two hand-maintained lists naming the same files (one in
162
+ // .gitattributes, one in REGENERABLE) — nothing checked that they still matched, so
163
+ // docs/copy-inventory.md + docs/copy-registry.json could be (and were) added to
164
+ // neither and merge like ordinary text. This pins the two lists as one set.
165
+ {
166
+ const attrsText = fs.readFileSync(path.join(repo, '.gitattributes'), 'utf8');
167
+ const otbRegenPaths = [...attrsText.matchAll(/^(\S+)\s+merge=otb-regen\s*$/gm)].map((m) => m[1]);
168
+ assert.ok(otbRegenPaths.length > 0, 'expected at least one merge=otb-regen line in .gitattributes');
169
+ for (const p of otbRegenPaths) {
170
+ assert.ok(regen.REGENERABLE.has(p), `.gitattributes declares merge=otb-regen for ${p} but REGENERABLE (git-merge-regen.js) does not know it`);
171
+ }
172
+ for (const p of regen.REGENERABLE) {
173
+ assert.ok(otbRegenPaths.includes(p), `REGENERABLE (git-merge-regen.js) knows ${p} but .gitattributes has no merge=otb-regen line for it`);
174
+ }
175
+ }
176
+
177
+ // ── 8) docs/copy-registry.json + docs/copy-inventory.md regenerate clean ────────
178
+ // (task 1003543 — the copy registry's own pair, from copy-inventory.js. Both
179
+ // artifacts of one scan, fully generated — like docs/repo-map.md, all three
180
+ // conflicted sides are ignored and the merged tree is rebuilt from scratch.)
181
+ {
182
+ const freshReg = CI.buildRegistry();
183
+ const freshJson = `${JSON.stringify(freshReg, null, 2)}\n`;
184
+ const freshMd = CI.renderReport(freshReg);
185
+
186
+ const rJson = regen.regenerateResolved('docs/copy-registry.json', {
187
+ base: '{}\n', ours: '<<<<<<< ours\n{"a":1}\n=======\n{"b":2}\n>>>>>>> theirs\n', theirs: 'nonsense\n',
188
+ });
189
+ assert.equal(rJson.ok, true, 'copy-registry.json heal must succeed');
190
+ assert.ok(!MARKERS.test(rJson.content), 'copy-registry.json heal must leave no conflict markers');
191
+ assert.equal(rJson.content, freshJson, 'copy-registry.json heal must equal a fresh regeneration');
192
+
193
+ const rMd = regen.regenerateResolved('docs/copy-inventory.md', {
194
+ base: '# base\n', ours: '<<<<<<< ours\n# a\n=======\n# b\n>>>>>>> theirs\n', theirs: 'nonsense\n',
195
+ });
196
+ assert.equal(rMd.ok, true, 'copy-inventory.md heal must succeed');
197
+ assert.ok(!MARKERS.test(rMd.content), 'copy-inventory.md heal must leave no conflict markers');
198
+ assert.equal(rMd.content, freshMd, 'copy-inventory.md heal must equal a fresh regeneration');
199
+ }
200
+
201
+ // ── 9) END-TO-END: two branches that both regenerate docs/copy-registry.json ────
202
+ // differently merge clean via the real .gitattributes + git-config wiring — the
203
+ // exact PR 526/531 shape from task 1003543 (two hall PRs both ran copy-inventory.js
204
+ // concurrently and conflicted as ordinary JSON/markdown). Mirrors test 6 above.
205
+ {
206
+ const driver = path.join(repo, 'scripts/gds/git-merge-regen.js');
207
+ const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'otb-gitmerge-copyreg-'));
208
+ const g = (...a) => {
209
+ const r = spawnSync('git', a, { cwd: tmp, encoding: 'utf8' });
210
+ return { status: r.status, out: `${r.stdout || ''}${r.stderr || ''}` };
211
+ };
212
+ const writeReg = (s) => fs.writeFileSync(path.join(tmp, 'docs', 'copy-registry.json'), s);
213
+ try {
214
+ g('init', '-q');
215
+ g('config', 'user.email', 't@t'); g('config', 'user.name', 't');
216
+ g('config', 'merge.otb-regen.driver', `node ${driver} %O %A %B %P`);
217
+ fs.writeFileSync(path.join(tmp, '.gitattributes'), 'docs/copy-registry.json merge=otb-regen\n');
218
+ fs.mkdirSync(path.join(tmp, 'docs'));
219
+ writeReg('{"schema":0}\n'); g('add', '-A'); g('commit', '-qm', 'base');
220
+ g('checkout', '-qb', 'feature');
221
+ writeReg('{"schema":0,"feature":true}\n'); g('add', '-A'); g('commit', '-qm', 'feat');
222
+ g('checkout', '-q', 'master');
223
+ if (g('rev-parse', '--verify', 'master').status !== 0) g('checkout', '-q', 'main');
224
+ writeReg('{"schema":0,"master":true}\n'); g('add', '-A'); g('commit', '-qm', 'mast');
225
+ const merge = g('merge', '--no-edit', 'feature');
226
+ assert.equal(merge.status, 0, `real git merge must auto-resolve via the driver; got ${merge.status} :: ${merge.out}`);
227
+ const unmerged = g('diff', '--name-only', '--diff-filter=U').out.trim();
228
+ assert.equal(unmerged, '', `no file may be left unmerged; got: ${unmerged}`);
229
+ const healed = fs.readFileSync(path.join(tmp, 'docs', 'copy-registry.json'), 'utf8');
230
+ assert.ok(!MARKERS.test(healed), 'merged copy-registry.json must have no conflict markers');
231
+ assert.equal(healed, `${JSON.stringify(CI.buildRegistry(), null, 2)}\n`,
232
+ 'merged copy-registry.json must equal a fresh regeneration from the (real) merged tree');
233
+ } finally {
234
+ fs.rmSync(tmp, { recursive: true, force: true });
235
+ }
236
+ }
237
+
151
238
  console.log('git_merge_regen: all assertions passed');