@bongos/core 1.21.111 → 1.21.112

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.21.111",
6
- "core_contract": "1.21.111",
7
- "source_commit": "a3e0196872aa25b75c2e6477c588bf9a3cc19b06",
5
+ "core_version": "1.21.112",
6
+ "core_contract": "1.21.112",
7
+ "source_commit": "20d2e0bfe68101dc84b13e8322b6c1dd35abcfe3",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-10-09T17:16:36.431Z",
9
+ "built_at": "2026-10-09T17:32:18.946Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
12
  "docs_redacted": 592,
@@ -17,7 +17,7 @@
17
17
  "gate": "passed"
18
18
  },
19
19
  "file_count": 3657,
20
- "tree_sha256": "c31261294242b2cd66c134daea2ffb60526f5cfa809bbed76fee9c229436b1a9",
20
+ "tree_sha256": "8fb96168c1321372e872219e26f508d99b040b9ebce4ce6ca17e482c0216c0a0",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/ask-for-help/SKILL.md",
@@ -612,7 +612,7 @@
612
612
  {
613
613
  "path": "docs/adr/0043-git-ssh-trust-boundary-and-rank-floor-on-permission-paths.md",
614
614
  "mode": "0000644",
615
- "sha256": "250ee61fac1aff3aa602a769a0b6fb2dcdac9f9abe9c61381d755a1b53a0eea2"
615
+ "sha256": "9127ee3f769616ad16e7151cb7f5f5a461690303804ce0ee7ddf6410f101dbd0"
616
616
  },
617
617
  {
618
618
  "path": "docs/adr/0044-mediterranean-palette-replacement.md",
@@ -2352,7 +2352,7 @@
2352
2352
  {
2353
2353
  "path": "docs/canonical-permissions.md",
2354
2354
  "mode": "0000644",
2355
- "sha256": "58b05e37108c25afa2d1d61a22c6fa0419ec2e242dacc3c1f8b7f7c70bd46ae2"
2355
+ "sha256": "453a9449ea0dc1a5f50b1d786a4d5b14086423bfd02904c9a0df5c541347d144"
2356
2356
  },
2357
2357
  {
2358
2358
  "path": "docs/copy-inventory.md",
@@ -2872,7 +2872,7 @@
2872
2872
  {
2873
2873
  "path": "docs/module-api-changelog.md",
2874
2874
  "mode": "0000644",
2875
- "sha256": "1665ae4a1fae5235c36e3a4d4d588de6d93817774de58ce40cd62e623e115a53"
2875
+ "sha256": "c7506ded99bfae21631034eaeda8c97b705dc16fe06bbf4e2419a257f578f755"
2876
2876
  },
2877
2877
  {
2878
2878
  "path": "docs/modules-contract.md",
@@ -10172,12 +10172,12 @@
10172
10172
  {
10173
10173
  "path": "package-lock.json",
10174
10174
  "mode": "0000644",
10175
- "sha256": "4ba883875bbc96c1d74b3e0ad996ea707dea726f16d20989a885b07bde0a8a5b"
10175
+ "sha256": "c0b56b64fd6deff145189d27a3aec0713132b1112d2545617719ee5d29f5e714"
10176
10176
  },
10177
10177
  {
10178
10178
  "path": "package.json",
10179
10179
  "mode": "0000644",
10180
- "sha256": "69b4ae038049ccf22290a8ab298d08d04d4e8800619f11c24a9aea97614ad535"
10180
+ "sha256": "3093047c8006d903bd5348bba1b43d9cd99f8dfd9ed19bb1575c8c92035a16b0"
10181
10181
  },
10182
10182
  {
10183
10183
  "path": "public-docs/index.html",
@@ -10197,7 +10197,7 @@
10197
10197
  {
10198
10198
  "path": "release-notes.json",
10199
10199
  "mode": "0000644",
10200
- "sha256": "aaa8e0550bc3b6b84184791498534dfe89d5accebc4c5e51220a95689c6a053e"
10200
+ "sha256": "15e75913ea8e573944116d52fe5e44135ca7be4bc7a338cb6ee7d36f4b2a44d3"
10201
10201
  },
10202
10202
  {
10203
10203
  "path": "scripts/cron/style_guide_audit.sh",
@@ -12482,7 +12482,7 @@
12482
12482
  {
12483
12483
  "path": "src/module-api.js",
12484
12484
  "mode": "0000644",
12485
- "sha256": "f10cbc790057ddb654dea27953fb735caba80cbc333d28a5b9253b44a852fd6b"
12485
+ "sha256": "a59fd4faf5376d371522507f8d01e336f655e2871ca2b4409f59606cccdfa28f"
12486
12486
  },
12487
12487
  {
12488
12488
  "path": "src/module-loader/catalog.js",
@@ -19,7 +19,7 @@ The SSH deploy failed (their box had no droplet key), but it didn't matter: the
19
19
 
20
20
  [ADR 0016](0016-trust-boundary-server-enforced-permissions.md) put authority in `builders.rank` and enforced it **server-side per request** — but **only for `/api/gds/*` HTTP routes**. It explicitly does not cover two surfaces:
21
21
 
22
- 1. **GitHub `main` is writable by every collaborator.** The repo is a **free-plan private repo**, so GitHub branch protection is *not available* ("Upgrade to GitHub Pro…"). All collaborators (`example-owner`, `LarsCode`, `willExample`, `IAMMASTERQUA`) have full push to `main`. The grader / confirm / rank gates live inside `ship.js` and the server — a raw `git push origin main` touches neither.
22
+ 1. **GitHub `main` is writable by every collaborator.** The repo is a **free-plan private repo**, so GitHub branch protection is *not available* ("Upgrade to GitHub Pro…"). All collaborators (`example-owner`, `LarsCode`, `willExample`, `IAMMASTERQUA`) have full push to `main`. The grader / confirm / rank gates live inside `ship.js` and the server — a raw `git push origin main` touches neither. *(As written at the time. Since 2026-08-08 `main` is protected — a pull request plus the `unit` check for every non-admin; see §"Branch-protection status" for the current probes.)*
23
23
  2. **The legit pipeline itself distributes the dangerous credentials.** `ship.js` does the merge-to-`main` and `ssh …deploy.sh` **client-side, from the builder's machine** — so the design hands every shipping builder the exact credentials needed to bypass it.
24
24
 
25
25
  A second, softer problem Lars raised: a sub-Metic builder had free rein to **read into and reason about the tiering/permission code** in the first place. Newcomers (`xenos`/`thetes`) should stay in their lane.
@@ -30,13 +30,13 @@ Two threads.
30
30
 
31
31
  ### A. Close the code-landing path (chosen: Option A now, Option B later)
32
32
 
33
- The protection goal is "un-graded code cannot reach prod, and a raw push to `main` is caught." Three layers, defense-in-depth, where **layer 3 is the authoritative enforcement** (the only one that survives a raw push / `--no-verify`, given GitHub can't block the push on the free plan):
33
+ The protection goal is "un-graded code cannot reach prod, and a raw push to `main` is caught." Three layers, defense-in-depth, where **layer 3 is the authoritative enforcement** (the only one that survives a raw push / `--no-verify`, given GitHub couldn't block the push on the free plan when this was written). **Since 2026-08-08 GitHub does block a non-admin's direct push** — see §"Branch-protection status"; layer 3 stays authoritative for what branch protection does not cover (the admin's direct push, a self-merged PR with zero reviews, and *who* authored a protected path — the `unit` check passes a sub-Metic author as readily as anyone):
34
34
 
35
35
  | Layer | Mechanism | Catches | Authoritative? |
36
36
  |---|---|---|---|
37
37
  | 1 — pre-push hook | `.husky/pre-push` → `scripts/gds/hooks/pre-push.js`. Blocks a direct push to `main` (override `OTB_ALLOW_MAIN_PUSH=1`, used only by the gated `scripts/gds/push-main.js`), and blocks a sub-Metic push that touches a permission-sensitive path. | the cooperative / careless case before the push leaves the box | no — bypassable with `--no-verify` |
38
38
  | 2 — grader pre-pass | `grader.permissionPathPrePass(changedFiles, builderRank)` hard-fails the grade if a sub-Metic diff touches a protected path (mirrors the route-rank pre-pass). | the honest GDS ship flow | no — skippable with `--skip-grade` / raw push |
39
- | 3 — post-push main audit | `scripts/gds/main-audit.js`: reads the **real** git history + **real** builder ranks (roster API, or Postgres via `--db` on the droplet). A resolved sub-Metic author on a protected path is a hard `[BLOCKER]`. Runs nightly (`.claude/scheduled-tasks/main-audit/`) **and** as the deploy gate (`--verify-head --db` from `~/deploy.sh`, `infra/deploy-main-audit-gate.sh`). | a raw `git push origin main`, a `--no-verify`, a `--skip-grade` — anything | **yes** — independent of the builder's cooperation |
39
+ | 3 — post-push main audit | `scripts/gds/main-audit.js`: reads the **real** git history + **real** builder ranks (roster API, or Postgres via `--db` on the droplet). A resolved sub-Metic author on a protected path is a hard `[BLOCKER]`. Runs nightly (`.claude/scheduled-tasks/main-audit/`) **and** as the deploy gate (`--verify-head --db` from `~/deploy.sh`, `infra/deploy-main-audit-gate.sh`). | a raw `git push origin main` (since 2026-08-08 only the admin's; a non-admin's is refused by GitHub), a self-merged PR, a `--no-verify`, a `--skip-grade` — anything | **yes** — independent of the builder's cooperation, and the only layer that judges the author's RANK; branch protection proves a PR + green `unit`, not who may touch a protected path |
40
40
 
41
41
  "Option A" = the merge-to-`main` + deploy move **server-side** so builders never hold main-push/droplet-SSH at all. The protections above ship now; the *full* server-side move and the credential rotation are operator steps (blockers [#15](https://example.com/builders#/blocker/15), [#16](https://example.com/builders#/blocker/16)). Until then, the legit client-side push is allowed only through `scripts/gds/push-main.js`, and the deploy gate (layer 3) is what guarantees poison never reaches prod.
42
42
 
@@ -69,7 +69,40 @@ After shipping, the fix was adversarially red-teamed (a 4-dimension panel + per-
69
69
 
70
70
  **Not yet done (finding `#7`, follow-up):** the permission-path pre-pass (layer 2) runs only client-side in `ship.js`; the server `/grade` and `/confirm` routes don't re-run it. Layer 3 is the server-side backstop today; re-running the pre-pass server-side (the server holds the live rank in `req.builder.rank`) would harden the cooperative path.
71
71
 
72
- ## Branch-protection status: re-verified 2026-07-24 (task [#1001840](https://cloudbongos.com/builders#/task/1001840))
72
+ ## Branch-protection status: re-verified 2026-09-25 (task [1004669](https://cloudbongos.com/builders#/task/1004669))
73
+
74
+ **Current. `main` IS protected — a pull request plus the `unit` check, for everyone but the admin.**
75
+ Probed 2026-09-25 with the owner's (admin) GitHub account while checking task
76
+ [1001433](https://cloudbongos.com/builders#/task/1001433); the protection itself landed 2026-08-08
77
+ (task [1002619](https://cloudbongos.com/builders#/task/1002619)):
78
+
79
+ | Probe | Result |
80
+ |---|---|
81
+ | `GET /repos/:o/:r/branches/main` | `protected: true` |
82
+ | `GET /repos/:o/:r/branches/main/protection` | `required_status_checks.contexts: ["unit"]` (`strict: false`) · `required_pull_request_reviews` present, `required_approving_review_count: 0` · `enforce_admins: false` · `allow_force_pushes: false` · `allow_deletions: false` |
83
+ | `GET /repos/:o/:r/rulesets` | `[]` — classic branch protection, not a ruleset |
84
+ | Collaborators with write | four, plus the admin owner; all four are Metic or Archon on the public leaderboard |
85
+
86
+ What this means for the claims above:
87
+
88
+ - **No longer true:** "a raw `git push origin main` by any collaborator is accepted". A non-admin's
89
+ direct push is refused; their work reaches `main` only through a PR whose `unit` check is green.
90
+ Force-pushing and deleting `main` are refused for everyone.
91
+ - **Still true:** the **admin** can push directly (`enforce_admins: false`); a write collaborator can
92
+ merge **their own** PR with zero reviews (the review count is 0 — the deliberate checks-only posture
93
+ of ADR 0162); and a builder **below Metic** reaches `main` only through the server's own publish
94
+ path (ADR 0055), never with a credential of their own.
95
+ - **So layer 3 (`main-audit.js`) stays the authoritative rank check.** Branch protection proves a
96
+ change came through a PR with a green `unit` run; it says nothing about whether its author may touch
97
+ a protected path. Option B (blocker [17](https://cloudbongos.com/builders#/blocker/17)) is half-delivered:
98
+ direct push is closed for non-admins, but nothing restricts `main` to the owner plus a deploy bot.
99
+
100
+ Treat this as the freshness stamp: re-run the probes above before asserting the claim has changed,
101
+ and update this section — not the history below — when it does.
102
+
103
+ ## Branch-protection status: 2026-07-24 (history — superseded by the section above)
104
+
105
+ _Originally headed "re-verified 2026-07-24 (task [1001840](https://cloudbongos.com/builders#/task/1001840))"; kept as written._
73
106
 
74
107
  The 2026-07-03 authority sweep reported that `main` had since gained live branch protection (required
75
108
  checks + code-owner review, direct push blocked), which would have demoted `main-audit.js` from
@@ -90,8 +123,8 @@ private repo with no protection available, and **layer 3 (`main-audit.js`) remai
90
123
  enforcement**, not a redundant second net. Option B (blocker
91
124
  [#17](https://cloudbongos.com/builders#/blocker/17)) is still open and still the durable closure.
92
125
 
93
- Treat this as the freshness stamp: re-run the probes above before asserting the claim has changed —
94
- a plan upgrade or a new ruleset would flip it, and this section is what a future sweep should update.
126
+ This was the freshness stamp until the 2026-08-08 protection flipped it; the current stamp is the
127
+ 2026-09-25 section above.
95
128
 
96
129
  ## G-2/G-17 resolution: Layer 1 delivered; the "path bug" refuted (2026-08-08, task 1002608)
97
130
 
@@ -290,12 +290,15 @@ Reading the code is not rank-gated today; what a builder can LAND is (next secti
290
290
  ADR 0016's per-request rank check covers `/api/bongos/*` only. Two surfaces it does **not** cover —
291
291
  `git push` to `main` and `ssh` to the droplet — were used in the Builder 25 incident to land an
292
292
  un-graded tiering change straight on prod `main`. **Since 2026-08-08 (task 1002619), `main` HAS
293
- live branch protection: the required `unit` status check blocks every direct push, so all work
294
- lands via PR.** The protection is *checks-only* — a code-owner review requirement was briefly
293
+ live branch protection: a pull request plus the required `unit` status check, so a non-admin's
294
+ direct push is refused and their work lands via PR.** Re-probed 2026-09-25 (task
295
+ [1004669](https://cloudbongos.com/builders#/task/1004669)): `enforce_admins` is off, so the **admin**
296
+ can still push directly; the PR needs **zero** approvals, so a write collaborator can merge their own;
297
+ force-push and deletion of `main` are refused for everyone. The protection is *checks-only* — a code-owner review requirement was briefly
295
298
  enforced and then deliberately retired by the owner (ADR 0162, task 1002635): gates are
296
299
  rank-consistent CI checks, never a named human's approval. (The 2026-07-24 state — no protection
297
300
  at all, PR #19 merged with zero checks — is preserved in ADR 0043 §"Branch-protection status" as
298
- history.) `main-audit.js` remains the authoritative *post-merge* layer — it catches what any
301
+ history, below the current 2026-09-25 probes.) `main-audit.js` remains the authoritative *post-merge* layer — it catches what any
299
302
  pre-merge gate misses, independent of the builder's cooperation:
300
303
 
301
304
  - A builder **below Metic** (`xenos`, `thetes`) may **not modify permission-sensitive paths** — the
@@ -3059,5 +3059,7 @@ is load-bearing: the script throws rather than guess if it is missing, and
3059
3059
  landed since 1.21.109 with no explicit bump. run 37963285770. (task 1002620)
3060
3060
  1.21.111 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
3061
3061
  landed since 1.21.110 with no explicit bump. run 37965024171. (task 1002620)
3062
+ 1.21.112 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
3063
+ landed since 1.21.111 with no explicit bump. run 37966893511. (task 1002620)
3062
3064
  ---------------------------------------------------------------------------
3063
3065
  ```
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.21.111",
3
+ "version": "1.21.112",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.21.111",
9
+ "version": "1.21.112",
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.21.111",
3
+ "version": "1.21.112",
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",
@@ -9524,5 +9524,11 @@
9524
9524
  "id": "1004667",
9525
9525
  "text": "Lost bug screenshots can now be brought back. We used to tell people a missing screenshot from the Discord bugs channel was gone for good. That was wrong: only the link expires, and the picture stays in Discord as long as the"
9526
9526
  }
9527
+ ],
9528
+ "1.21.112": [
9529
+ {
9530
+ "id": "1004669",
9531
+ "text": "The security record for the main branch now says what is actually true. It used to say anyone with access could push straight to the main code line. That stopped being true in August: now every change from a regular collaborat"
9532
+ }
9527
9533
  ]
9528
9534
  }
package/src/module-api.js CHANGED
@@ -75,7 +75,7 @@ const { responsibilityFor, ROLE_RESPONSIBILITIES } = require('./role-responsibil
75
75
  // MAJOR (see allowBoxScope below): passes the request through untouched.
76
76
  function deprecatedNoopMiddleware(_req, _res, next) { next(); }
77
77
 
78
- const CORE_VERSION = '1.21.111'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
78
+ const CORE_VERSION = '1.21.112'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
79
79
 
80
80
  // A namespaced logger so a module's log lines are attributable + consistent.
81
81
  // Usage: const log = api.logger('discord'); log.info('mounted');