@bongos/core 1.19.628 → 1.19.629

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.628",
6
- "core_contract": "1.19.628",
7
- "source_commit": "4f99983713ad375f7f42c932c781c3c77a47bc66",
5
+ "core_version": "1.19.629",
6
+ "core_contract": "1.19.629",
7
+ "source_commit": "80bf853bd558fa5134bd5bddcb0e4804579fc27e",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-09-09T19:56:16.788Z",
9
+ "built_at": "2026-09-09T22:26:18.376Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
12
  "docs_redacted": 466,
@@ -17,7 +17,7 @@
17
17
  "gate": "passed"
18
18
  },
19
19
  "file_count": 2588,
20
- "tree_sha256": "ab072d3e169daecbd6fbfc4d2e18d2786ea247cb5b84a4d4d5dc06cf17b0c210",
20
+ "tree_sha256": "c5bd187e5ed644428b20c65f6fee6c2b6b122ae4952a3e36e19b84cfa2e4d722",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/backlog-review/SKILL.md",
@@ -332,7 +332,7 @@
332
332
  {
333
333
  "path": ".gitattributes",
334
334
  "mode": "0000644",
335
- "sha256": "7f5faf22678ad182025b2f3f9107c209f92e461200e15665fa2feb4a3cd86858"
335
+ "sha256": "83c94b055dc619fdbf3bc1142fc5357810d901e4200644f1fb399e6939571c5f"
336
336
  },
337
337
  {
338
338
  "path": "CLAUDE.md",
@@ -2767,7 +2767,7 @@
2767
2767
  {
2768
2768
  "path": "docs/module-api-changelog.md",
2769
2769
  "mode": "0000644",
2770
- "sha256": "f0bda08beedf16b6f2eed29c598f4a7602c35e84f084ca744861c6242656fe01"
2770
+ "sha256": "aba3d7e763196a3052a53ee81f5327e0caad5274bd4de41b09b031b2277c82d2"
2771
2771
  },
2772
2772
  {
2773
2773
  "path": "docs/modules-contract.md",
@@ -3012,7 +3012,7 @@
3012
3012
  {
3013
3013
  "path": "docs/recipes/windows-builders.md",
3014
3014
  "mode": "0000644",
3015
- "sha256": "229da205775c6b84534633bc15be7355337d0d8cfacd81ff03860bc24bfc783f"
3015
+ "sha256": "b7d849d1786c7eca4156969d38343425839bef3bae19a10a94b5e54916e3ea09"
3016
3016
  },
3017
3017
  {
3018
3018
  "path": "docs/recipes/work-on-a-task-from-your-dev-box.md",
@@ -7697,12 +7697,12 @@
7697
7697
  {
7698
7698
  "path": "package-lock.json",
7699
7699
  "mode": "0000644",
7700
- "sha256": "aba13c3ae1fa839b97bc3f11aff342251f550f7cbcc8531a9ae3c6856f326d6e"
7700
+ "sha256": "41fdf5ef9ec5b4cb8a9f7a85f0efeba2595895fc5688c3c78702652fe4002d67"
7701
7701
  },
7702
7702
  {
7703
7703
  "path": "package.json",
7704
7704
  "mode": "0000644",
7705
- "sha256": "bdea58839926be753b49b016fc961cff55481f292f911d9fa044e77db022db21"
7705
+ "sha256": "c8bb2a1526d2abc3ba1bcb859d83ca86a081fd7c89a178f45f5b39a481ecaebe"
7706
7706
  },
7707
7707
  {
7708
7708
  "path": "public-docs/index.html",
@@ -8012,7 +8012,7 @@
8012
8012
  {
8013
8013
  "path": "scripts/gds/copy-inventory.js",
8014
8014
  "mode": "0000644",
8015
- "sha256": "8c798359b51abdd749233e65aa5906732bccc5b9088dae32513cde7949404b6c"
8015
+ "sha256": "7269164648fc1d00e1bf3272a82f933a5f8da228e562e00848dbc29c671d3e94"
8016
8016
  },
8017
8017
  {
8018
8018
  "path": "scripts/gds/coreB-carve-proof.sh",
@@ -9442,7 +9442,7 @@
9442
9442
  {
9443
9443
  "path": "src/module-api.js",
9444
9444
  "mode": "0000644",
9445
- "sha256": "f14dc0f62bb0abba340f775a22b7810b56eacc91c29015a9712f7d9afd57f0ac"
9445
+ "sha256": "46df738e31dab69636774474ec6714365bf625a395df0a0e5ab4ecbacf178b16"
9446
9446
  },
9447
9447
  {
9448
9448
  "path": "src/module-loader/catalog.js",
@@ -10137,7 +10137,7 @@
10137
10137
  {
10138
10138
  "path": "tests/copy_inventory.mjs",
10139
10139
  "mode": "0000644",
10140
- "sha256": "97ff5dac1f7bef96cf0f80082e8f6ebb2cea30f3c371c3ab080e9189818fb5fd"
10140
+ "sha256": "716aa03c5e93b71aec0c7e6fe646e5abd702b8b6ffda0ef6235a804d2c17a0ca"
10141
10141
  },
10142
10142
  {
10143
10143
  "path": "tests/cosmos_token_contrast.mjs",
@@ -10517,7 +10517,7 @@
10517
10517
  {
10518
10518
  "path": "tests/git_merge_regen.mjs",
10519
10519
  "mode": "0000644",
10520
- "sha256": "1d5f97589b84b493f7406fba3b162443a70fbf0ad24190049d054dbd2fe17273"
10520
+ "sha256": "c6cb1bda6809d8d384a9c35b376995af038d18c26b1b935cb5c0faebb163b72e"
10521
10521
  },
10522
10522
  {
10523
10523
  "path": "tests/github_push_ancestry.mjs",
package/.gitattributes CHANGED
@@ -85,8 +85,18 @@ src/bongos/routes/CLAUDE.md merge=otb-regen
85
85
  # files. Same otb-regen shape as docs/session-log-index.md above (whole-file
86
86
  # rebuild, all three merge sides ignored); REGENERABLE in git-merge-regen.js
87
87
  # carries the matching rule.
88
+ #
89
+ # The `text eol=lf` on the .md (task 1003619) is NOT cosmetic — it is what keeps
90
+ # `copy-inventory.js --check` honest on Windows. The generator writes LF and the
91
+ # check string-compares its output against the worktree file, so under the default
92
+ # `* text=auto` above (index LF, worktree CRLF) the check reported STALE forever on
93
+ # every Windows checkout while the committed content was already correct. The .json
94
+ # never had the bug because `*.json text eol=lf` above already pins it; the .md fell
95
+ # through to text=auto because no `*.md` rule exists (and none should — pinning all
96
+ # 685 tracked .md files would renormalize the whole docs tree for one generated file).
97
+ # `*.md` deliberately stays unpinned; only the GENERATED artifact is pinned here.
88
98
  docs/copy-registry.json merge=otb-regen
89
- docs/copy-inventory.md merge=otb-regen
99
+ docs/copy-inventory.md merge=otb-regen text eol=lf
90
100
 
91
101
  # Append-only index tables (task 1385 / ADR 0082). docs/adr/README.md is a
92
102
  # hand-maintained ADR index whose ONLY recurring conflict is two branches each
@@ -1705,5 +1705,7 @@ is load-bearing: the script throws rather than guess if it is missing, and
1705
1705
  landed since 1.19.626 with no explicit bump. run 34390069410. (task 1002620)
1706
1706
  1.19.628 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1707
1707
  landed since 1.19.627 with no explicit bump. run 34397967061. (task 1002620)
1708
+ 1.19.629 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1709
+ landed since 1.19.628 with no explicit bump. run 34412159317. (task 1002620)
1708
1710
  ---------------------------------------------------------------------------
1709
1711
  ```
@@ -147,3 +147,4 @@ caught a real bug during task 1003548, so read its assertion before blaming the
147
147
 
148
148
  - Several hall files (`people.css`, `people.html`, `style.css`, the privacy spec) and every `.claude/skills/*/SKILL.md` are CRLF; `scripts/gds/*.js` and the tests are LF. An exact-string patch must detect the file's EOL before joining lines (`text.includes('\r\n') ? '\r\n' : '\n'`), or the find matches nothing and the edit is a silent no-op (session log 2026-08-24).
149
149
  - A `git diff --stat` that touches every line of a file you barely edited is an EOL flip — check with `git diff --stat --ignore-cr-at-eol`, and restore the original EOL before committing.
150
+ - **`copy-inventory.js --check` no longer reds on line endings alone** (task 1003619). It used to: the generator emits LF and the check byte-compared that against a CRLF worktree file, so `/ship-check` showed one permanent red line on every Windows checkout while the committed content was already correct — and a builder who "fixed" it committed a whole-file CRLF diff. `docs/copy-inventory.md` is now pinned `text eol=lf` in `.gitattributes` (its `.json` sibling always was, via `*.json`), and the check compares EOL-blind so an already-CRLF worktree passes without a re-clone. If it reports STALE now, the content really is stale — regenerate, don't reach for `--ignore-cr-at-eol`. Note `*.md` is deliberately NOT pinned repo-wide; only that one generated artifact is.
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.628",
3
+ "version": "1.19.629",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.19.628",
9
+ "version": "1.19.629",
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.628",
3
+ "version": "1.19.629",
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",
@@ -485,6 +485,32 @@ function renderReport(reg) {
485
485
  return L.join('\n');
486
486
  }
487
487
 
488
+ // Line-ending-blind view of a file's text, for the --check compare ONLY (task 1003619).
489
+ // Why: the generator emits LF, and --check string-compares that against the file on
490
+ // disk. A Windows checkout hands back CRLF, so the compare reported STALE forever on
491
+ // content that was byte-identical in the index — a permanently red /ship-check gate,
492
+ // which teaches builders to wave past the one check that catches a REAL stale artifact.
493
+ // .gitattributes now pins this pair to eol=lf, but that only governs FUTURE checkouts:
494
+ // a file already sitting CRLF in an existing worktree stays CRLF until renormalized,
495
+ // so the checker must not care either way. Freshness is a question about CONTENT.
496
+ // Not used on the write path — generated files are still written with LF endings.
497
+ function lf(s) {
498
+ return s.replace(/\r\n/g, '\n');
499
+ }
500
+
501
+ // Is the artifact on disk still what the generator would write? Freshness is a
502
+ // question about CONTENT, so CRLF-vs-LF is not a difference — see lf() above for
503
+ // why that mattered. A missing file (`have === null`) is stale by definition.
504
+ // Only \r\n is folded, NOT a lone \r: no tool in this repo emits classic-Mac
505
+ // endings, and treating a bare \r as a newline would let a genuinely corrupt file
506
+ // read as fresh. Pure + exported so the decision is unit-testable without writing
507
+ // to the committed artifacts (same shape as shouldRefuseSessionClaim in
508
+ // modules/lifecycle/routes/claims.js).
509
+ function matchesGenerated(have, want) {
510
+ if (have === null || have === undefined) return false;
511
+ return lf(have) === lf(want);
512
+ }
513
+
488
514
  function write({ check = false } = {}) {
489
515
  const reg = buildRegistry();
490
516
  const json = `${JSON.stringify(reg, null, 2)}\n`;
@@ -495,7 +521,7 @@ function write({ check = false } = {}) {
495
521
  const stale = [];
496
522
  for (const [p, want] of [[jsonPath, json], [mdPath, md]]) {
497
523
  const have = fs.existsSync(p) ? fs.readFileSync(p, 'utf8') : null;
498
- if (have !== want) stale.push(path.relative(REPO_ROOT, p));
524
+ if (!matchesGenerated(have, want)) stale.push(path.relative(REPO_ROOT, p));
499
525
  }
500
526
  return { reg, stale };
501
527
  }
@@ -525,5 +551,5 @@ if (require.main === module) {
525
551
  module.exports = {
526
552
  SURFACES, COPY_ATTRS, BLIND_SPOTS, REGISTRY_REL, REPORT_REL,
527
553
  cmp, stableId, looksLikeCopy, lineIndex, lineAt, stripEmbedded, fromHtml, fromJs, filesFor,
528
- buildRegistry, renderReport, write,
554
+ buildRegistry, renderReport, write, lf, matchesGenerated,
529
555
  };
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.628'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
58
+ const CORE_VERSION = '1.19.629'; // 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');
Binary file
@@ -176,9 +176,24 @@ function withBlockBody(src, body) {
176
176
  // .gitattributes, one in REGENERABLE) — nothing checked that they still matched, so
177
177
  // docs/copy-inventory.md + docs/copy-registry.json could be (and were) added to
178
178
  // neither and merge like ordinary text. This pins the two lists as one set.
179
+ // A .gitattributes line may carry SEVERAL attributes for one path — git reads
180
+ // `docs/copy-inventory.md merge=otb-regen text eol=lf` exactly as it reads the
181
+ // bare `merge=otb-regen` form. The original matcher here was end-anchored
182
+ // (/^(\S+)\s+merge=otb-regen\s*$/), so adding any second attribute made this
183
+ // check stop SEEING the entry and report it as missing (task 1003619, where the
184
+ // .md gained an eol pin). Under-inclusive in the dangerous direction too: a
185
+ // regenerable path declared with extra attributes would slip the REGENERABLE
186
+ // cross-check entirely. Tokenize the attribute list instead of pattern-matching
187
+ // the whole line, so the set equality below is about PATHS, not line formatting.
179
188
  {
180
189
  const attrsText = fs.readFileSync(path.join(repo, '.gitattributes'), 'utf8');
181
- const otbRegenPaths = [...attrsText.matchAll(/^(\S+)\s+merge=otb-regen\s*$/gm)].map((m) => m[1]);
190
+ const otbRegenPaths = attrsText
191
+ .split(/\r?\n/)
192
+ .map((line) => line.trim())
193
+ .filter((line) => line && !line.startsWith('#'))
194
+ .map((line) => line.split(/\s+/))
195
+ .filter((tokens) => tokens.slice(1).includes('merge=otb-regen'))
196
+ .map((tokens) => tokens[0]);
182
197
  assert.ok(otbRegenPaths.length > 0, 'expected at least one merge=otb-regen line in .gitattributes');
183
198
  for (const p of otbRegenPaths) {
184
199
  assert.ok(regen.REGENERABLE.has(p), `.gitattributes declares merge=otb-regen for ${p} but REGENERABLE (git-merge-regen.js) does not know it`);