@bongos/core 1.19.383 → 1.19.385

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,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.383",
6
- "core_contract": "1.19.383",
7
- "source_commit": "f168cbd261a7c290f0bbdb8877d111f12cfa6918",
5
+ "core_version": "1.19.385",
6
+ "core_contract": "1.19.385",
7
+ "source_commit": "3ed24b93e1f32dddb11c2a7a8bfaa9dda77a6f31",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-08-27T18:02:01.508Z",
9
+ "built_at": "2026-08-27T21:33:52.536Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
- "docs_redacted": 337,
12
+ "docs_redacted": 338,
13
13
  "agent_docs_stubbed": 22,
14
- "functional_verbatim": 1602,
14
+ "functional_verbatim": 1603,
15
15
  "rules": 3,
16
16
  "gate_literals": 3,
17
17
  "gate": "passed"
18
18
  },
19
- "file_count": 1961,
20
- "tree_sha256": "0ab207ced344bae7190af953ae3da3574356220f56737ae7bde90ca0ad27a00c",
19
+ "file_count": 1963,
20
+ "tree_sha256": "405834d1bb0740aa2af5d7666798ac5219e895d514d397afb2c9c53953a431c8",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/blocker-review/SKILL.md",
@@ -1469,10 +1469,15 @@
1469
1469
  "mode": "0000644",
1470
1470
  "sha256": "65bd3a60b8d313af7ea69acf7fe9a522a15a144c4395b3788bd3f82cc20e8351"
1471
1471
  },
1472
+ {
1473
+ "path": "docs/adr/0195-adr-numbers-are-checked-like-migration-numbers.md",
1474
+ "mode": "0000644",
1475
+ "sha256": "bef44bdf75d61a0e7f076b78d384c4523cb706e5a1023768daa232feee6898aa"
1476
+ },
1472
1477
  {
1473
1478
  "path": "docs/adr/README.md",
1474
1479
  "mode": "0000644",
1475
- "sha256": "7f7354c2597bd982d92e0008595e05642c8ccc05c1e9446388c304e80b142626"
1480
+ "sha256": "ad42cce140bb167b6702b8181d1e31ca39f537dca3f294440fcc53ece97f47d3"
1476
1481
  },
1477
1482
  {
1478
1483
  "path": "docs/api-reference.md",
@@ -3532,7 +3537,7 @@
3532
3537
  {
3533
3538
  "path": "modules/grading/grader-workers/index.js",
3534
3539
  "mode": "0000644",
3535
- "sha256": "8ec5e91341ec5247ee643c6ce75fb5ec21a62b3bba176fdde060cdb352edb808"
3540
+ "sha256": "186ebc1d6456f3d9d0435766744fd767005b667fc4f6020bb9041f6b66388c4b"
3536
3541
  },
3537
3542
  {
3538
3543
  "path": "modules/grading/grader-workers/narc.js",
@@ -3562,7 +3567,7 @@
3562
3567
  {
3563
3568
  "path": "modules/grading/grader.js",
3564
3569
  "mode": "0000644",
3565
- "sha256": "bb66bece4bf5d1364be931b39d7b1e179615b59613d74e491ff48b399291ff24"
3570
+ "sha256": "53001adcb058742f39bdb475fca023809c239f50bf9dddc61ccef966d5d01d6a"
3566
3571
  },
3567
3572
  {
3568
3573
  "path": "modules/grading/module.json",
@@ -5112,12 +5117,12 @@
5112
5117
  {
5113
5118
  "path": "package-lock.json",
5114
5119
  "mode": "0000644",
5115
- "sha256": "5ec288b35333dfb113e92535712c2d9ba8a10c6a50ca18f967ab66d2c00c0e9c"
5120
+ "sha256": "44a05f902a0d9063f2642c03a377c0c850dc4871e65c8b680c1190ca905bb3ec"
5116
5121
  },
5117
5122
  {
5118
5123
  "path": "package.json",
5119
5124
  "mode": "0000644",
5120
- "sha256": "196e6dcab90b3a4761fba39ebaa94c05bdba3cb3c963dd684d9fada3730ffff1"
5125
+ "sha256": "da469f97be509ad2739415aa339e06765bb4b3ea0c828620fb72391e76bb8862"
5121
5126
  },
5122
5127
  {
5123
5128
  "path": "public-docs/index.html",
@@ -5474,6 +5479,11 @@
5474
5479
  "mode": "0000644",
5475
5480
  "sha256": "07ff338beac12979eba50e4a6fe9c2f6dbfd842fa01abe1c412b19888d10c4a0"
5476
5481
  },
5482
+ {
5483
+ "path": "scripts/gds/adr-namespace.js",
5484
+ "mode": "0000644",
5485
+ "sha256": "9c7ef61b64e41ee5dd6d913883e16dfed6d44bd6eefa4960b8dde566a63b5621"
5486
+ },
5477
5487
  {
5478
5488
  "path": "scripts/gds/api.js",
5479
5489
  "mode": "0000644",
@@ -5827,7 +5837,7 @@
5827
5837
  {
5828
5838
  "path": "scripts/gds/fitness.js",
5829
5839
  "mode": "0000644",
5830
- "sha256": "4dec7f6bee219ca3c11dbf5b9c3380de286264a66830fd8e2d37018a989eb83e"
5840
+ "sha256": "2fcc7dfa75a6fcf1ebc0fb75d0e4343dc54b9d75b88fb798f8b16674b919c1b8"
5831
5841
  },
5832
5842
  {
5833
5843
  "path": "scripts/gds/gate-review.js",
@@ -6462,7 +6472,7 @@
6462
6472
  {
6463
6473
  "path": "scripts/gds/ship-grade-steps.js",
6464
6474
  "mode": "0000644",
6465
- "sha256": "52dc5ae1aca08033d2d217694273d8fed1597c0329491118ffa48ccdadc0a3ca"
6475
+ "sha256": "e68f4c2848cb59878cd0b96b48fdd075db4a035354d51afef52aa6225f7895e5"
6466
6476
  },
6467
6477
  {
6468
6478
  "path": "scripts/gds/ship-grade.js",
@@ -7022,7 +7032,7 @@
7022
7032
  {
7023
7033
  "path": "src/module-api.js",
7024
7034
  "mode": "0000644",
7025
- "sha256": "b388ffe0abec635f957a2d9eb05863590873e963bc445879a27fbd723ca417db"
7035
+ "sha256": "63478a33b8d134113541ea814481eedb00ad89ac0b6777e87a1a6053b5718d72"
7026
7036
  },
7027
7037
  {
7028
7038
  "path": "src/module-loader/catalog.js",
@@ -7912,7 +7922,7 @@
7912
7922
  {
7913
7923
  "path": "tests/fitness.mjs",
7914
7924
  "mode": "0000644",
7915
- "sha256": "465c7ef58342b6e03947858fe34649f5a13a5bcf3658478601baed1e8b2420ef"
7925
+ "sha256": "e247bd7ab5ea26493186d9c308a7774bd6ef65fe057613da887ec94fe8b2b5b5"
7916
7926
  },
7917
7927
  {
7918
7928
  "path": "tests/fitness_ratchets.mjs",
@@ -8292,7 +8302,7 @@
8292
8302
  {
8293
8303
  "path": "tests/grade_unavailable_display.mjs",
8294
8304
  "mode": "0000644",
8295
- "sha256": "82746689da273a8bd9d53d80204b15147d87574d2331c3a70d736d95a6126a09"
8305
+ "sha256": "08e08714d025fe7c0f1177fbfa6724241ff519cd34848f953d5bc7cce6c142fa"
8296
8306
  },
8297
8307
  {
8298
8308
  "path": "tests/grader.mjs",
@@ -8312,7 +8322,7 @@
8312
8322
  {
8313
8323
  "path": "tests/grader_panel.mjs",
8314
8324
  "mode": "0000644",
8315
- "sha256": "2e62f5eb5896691df78e1c63f495d1cf7bea23dd1dfb8f2bd764e23e87982616"
8325
+ "sha256": "32dc0e219ed6aa7430c9ba9523faddb2ddc9602d939731788c660d9d79751d22"
8316
8326
  },
8317
8327
  {
8318
8328
  "path": "tests/grader_prompt_fencing.mjs",
@@ -0,0 +1,46 @@
1
+ # 0195 — ADR numbers are checked like migration numbers, and the twenty existing collisions are grandfathered by name
2
+
3
+ - **Status:** Accepted
4
+ - **Date:** 2026-08-27
5
+ - **Deciders:** the builder on [task 1003164](https://cloudbongos.com/builders#/task/1003164)
6
+
7
+ ## Context
8
+
9
+ Two ADRs could carry the same number and nothing flagged it. It happened for real on 2026-08-22: [task 1002483](https://cloudbongos.com/builders#/task/1002483)'s branch authored `<redacted>.md` while, three days into that branch sitting stranded at `completed`, [task 1003042](https://cloudbongos.com/builders#/task/1003042) landed `0181-teardown-state-gate-and-address-retention.md` on `main`. Merging `main` into the branch produced both files side by side.
10
+
11
+ **Git cannot see this.** The filenames differ, so there is no path collision and no merge conflict — git adds both cleanly. `docs/adr/README.md` auto-merges too, ending up with two `| 0181 |` rows, the incoming one placed out of the ascending order the index reads in. The `unit` gate, fitness, docs-entropy and the grader all passed. A human reading `ls docs/adr/` found it.
12
+
13
+ **The asymmetry that made this a bug rather than a gap.** Migrations already have exactly this protection. `migration-namespace.js` exports `stemCollisions()`, and `fitness.js` runs `checkMigrationNamespacing` as a hard failure — because a re-used migration number silently *skips* a migration, which the team correctly treated as unacceptable. ADRs got `next-number.js`, which computes the next free number for a claim card from a possibly-stale tree, best-effort, at claim time — and then nothing enforced it afterwards. Same shared, monotonic, human-allocated number line; one guarded, one not.
14
+
15
+ **Why it matters past tidiness.** An ADR number is a *citation target*. [Task 1000900](https://cloudbongos.com/builders#/task/1000900)'s close-rationale cited "ADR 0180" and, because of this collision, `0180` on `main` is *Dependency intake & drift policy* — an unrelated document. A reader following that citation lands nowhere near the ship gate it meant. ADRs cite each other by number throughout, and `docs/adr/README.md` is the index every agent is told to consult, so a duplicated number makes a citation ambiguous **forever**.
16
+
17
+ **What building the check revealed.** The bug report described one collision. The live tree held **twenty**, plus fourteen index defects the same merge class had produced: two ADRs listed twice (`0116`, `0117` — a merge duplicated the rows verbatim) and twelve ADRs with no index row at all. Ten of those twelve were the *second file of a colliding pair* — which is the mechanism by which a collision hides, since the file that never gets indexed is the one nobody sees. The hand-written "known collision" paragraph under the index narrated eight collisions and had fallen twelve behind reality: a record nobody checked, the shape [ADR 0184](<redacted>.md) was written about.
18
+
19
+ ## Decision
20
+
21
+ **We will check ADR numbers the way we check migration numbers — a hard CI failure — and grandfather the twenty existing collisions by exact filename rather than renumbering them.**
22
+
23
+ 1. **`scripts/gds/adr-namespace.js`** is the ADR sibling of `migration-namespace.js`: pure functions over a file list and the index text, no disk, unit-testable. It exports `checkAdrNumbering()`, registered in `fitness.js` (Check 31) and therefore inside the required `unit` CI check — no new workflow.
24
+
25
+ 2. **A number claimed by two files is a hard failure naming both paths**, unless that number's file set is *exactly* the frozen pair in `LEGACY_DUPLICATE_ADRS`.
26
+
27
+ 3. **The index is checked by link target, not by number**: every ADR file has exactly one row, and every row points at a file that exists. This is one invariant covering all three real defects — the dangling row, the duplicated row, and the unindexed file.
28
+
29
+ 4. **Row ordering warns, never blocks.** Ten legacy rows sit out of ascending order. Blocking would fail every PR for a mess nobody's diff created — the split [ADR 0189](<redacted>.md) draws between declaration rot (hard) and inherited drift (warn).
30
+
31
+ ## Alternatives considered
32
+
33
+ - **Renumber the nineteen newer halves so the tree is genuinely unique.** Rejected: renumbering breaks every existing citation to those numbers, which is precisely the harm this check exists to prevent, and `README.md` states the rule outright — a number, once assigned, is never reused. It would also rewrite nineteen files' git history for a cosmetic property no reader depends on, since each pair's two files are unambiguous by *name*.
34
+ - **Grandfather by number instead of by exact filename** (`0181` is simply exempt). Rejected: that permanently un-guards twenty numbers. A third ADR joining `0181`, or a rename of either half, would pass silently. Set-equality on filenames keeps the exemption exactly as wide as the history that earned it, and the list can only shrink.
35
+ - **A numeric cutoff, mirroring `LEGACY_BARE_CORE_MAX`.** Rejected: migrations could use a cutoff because the new namespace makes collision *structurally* impossible above it. Here a new ADR takes a number above the current max, so a cutoff would exempt every historical number while catching nothing that hasn't already happened — and a new file deliberately numbered `0050` would sail through.
36
+ - **Enforce "exactly one index row per ADR *number*"**, as the bug report proposed. Rejected: it cannot express a grandfathered pair, which legitimately has two rows. Keying on the link target says what we actually mean and catches strictly more.
37
+ - **Fix it in `next-number.js` instead** — make the allocator authoritative. Rejected: the allocator already exists and already tries. It runs at *claim* time against a tree that may be days stale, which is exactly how the `0181` pair happened; only a check at merge time sees both files.
38
+ - **Leave the check advisory** (warn, like the doc-comment gate). Rejected: this is the failure the migration check treats as unacceptable, one layer up, and a warning is what the situation already effectively had.
39
+
40
+ ## Consequences
41
+
42
+ - A new ADR number collision now fails the `unit` gate, naming both paths and the remedy. The failure arrives on the PR that creates it rather than months later via a wrong citation.
43
+ - The index and the tree can no longer drift apart unnoticed: 214 files, 214 rows, checked on every PR. Adding an ADR without indexing it is now a build failure — a small new obligation on every ADR author, and the point.
44
+ - The twenty legacy pairs keep their filenames and their citations. They are listed once, in code, in a list that may only shrink; the prose paragraph that used to narrate them (and lagged twelve behind) now points at that list instead of restating it.
45
+ - Ten index rows sit out of order and stay that way, as warnings. Anyone reordering them is welcome to; nothing forces it.
46
+ - `docs/adr/README.md`'s `#` column now uses `NNNN-a` / `NNNN-b` for all twenty pairs, extending a convention that previously covered five of them.