@bongos/core 1.19.256 → 1.19.258

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.256",
6
- "core_contract": "1.19.256",
7
- "source_commit": "c59b2d80defd16a675d8cb51cd7dcaf5ff1ca234",
5
+ "core_version": "1.19.258",
6
+ "core_contract": "1.19.258",
7
+ "source_commit": "66f71503310987ea2c91b4e930f3d5c81b3fb018",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-08-19T02:25:48.410Z",
9
+ "built_at": "2026-08-19T18:01:56.705Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
- "docs_redacted": 315,
12
+ "docs_redacted": 317,
13
13
  "agent_docs_stubbed": 22,
14
- "functional_verbatim": 1348,
14
+ "functional_verbatim": 1358,
15
15
  "rules": 3,
16
16
  "gate_literals": 3,
17
17
  "gate": "passed"
18
18
  },
19
- "file_count": 1685,
20
- "tree_sha256": "442984caa92378f234d5808a753846264279dbdd313ab7ec9224a3c775f743f8",
19
+ "file_count": 1697,
20
+ "tree_sha256": "66ae54f6968edbafb532b3e566ec10fad20a45ca1c48af7951a8bc3fe1a06cd7",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/blocker-review/SKILL.md",
@@ -527,7 +527,7 @@
527
527
  {
528
528
  "path": "docs/adr/0022-secrets-policy.md",
529
529
  "mode": "0000644",
530
- "sha256": "91cd6dc20c4e605bf1a5f36a1fe374778c6f0904f910ca461f197953634a9927"
530
+ "sha256": "8ea4766c05c27517d19a9ef7343e4083e71604b22b88ed058071dc82399529bb"
531
531
  },
532
532
  {
533
533
  "path": "docs/adr/0023-kind-multipliers-and-idea-bonus.md",
@@ -1379,10 +1379,15 @@
1379
1379
  "mode": "0000644",
1380
1380
  "sha256": "782900e7a2e49c14d7796d94e2b63493659e3c6c3ad8eb8bd721fa589307612b"
1381
1381
  },
1382
+ {
1383
+ "path": "docs/adr/0180-dependency-intake-and-drift-policy.md",
1384
+ "mode": "0000644",
1385
+ "sha256": "62de8180208c3945c7a040b2b2799dceafd59b1c5a117aab7db56a57eb538e44"
1386
+ },
1382
1387
  {
1383
1388
  "path": "docs/adr/README.md",
1384
1389
  "mode": "0000644",
1385
- "sha256": "bf9dddba0e72ab43ee6124fbba2a0479f1cb7dfc35ea4005f3382aae98e0066f"
1390
+ "sha256": "798471e95b27664e775d12dbf008fc1aa12edff0b115942a3632ecb0f2da24b5"
1386
1391
  },
1387
1392
  {
1388
1393
  "path": "docs/api-reference.md",
@@ -1527,12 +1532,12 @@
1527
1532
  {
1528
1533
  "path": "docs/file-map.md",
1529
1534
  "mode": "0000644",
1530
- "sha256": "fcba56f057bbfa22c5586075fab70ae5559137880ab6886e5f9c990f4801edd7"
1535
+ "sha256": "9762b7f69397c28e103cdb39a9987483e23bd800a827f0d83983b62ef962616b"
1531
1536
  },
1532
1537
  {
1533
1538
  "path": "docs/handoff-template.md",
1534
1539
  "mode": "0000644",
1535
- "sha256": "79186414c46089e83d18f5c6a17bc569f42e8ceff8321154ae55da5237f25768"
1540
+ "sha256": "a60d85b8523b5944d4db8105b60166395ab9c1f931fb92f0f95a825b657fe277"
1536
1541
  },
1537
1542
  {
1538
1543
  "path": "docs/modules-contract.md",
@@ -1612,7 +1617,7 @@
1612
1617
  {
1613
1618
  "path": "docs/recipes/README.md",
1614
1619
  "mode": "0000644",
1615
- "sha256": "1abab5aabf19301f3a436082aaeb15b957dee72e662de41ea2624d29dfe6cf9a"
1620
+ "sha256": "bf3caea65a8b8a117d40544fdf352c235bb120a69444645d62b91f999a9b7731"
1616
1621
  },
1617
1622
  {
1618
1623
  "path": "docs/recipes/audit-replay.md",
@@ -1724,6 +1729,11 @@
1724
1729
  "mode": "0000644",
1725
1730
  "sha256": "5bfca9628859f1cdd79d741bdd50f3fe415430ee3380a2ac7f46b97ebe082d0e"
1726
1731
  },
1732
+ {
1733
+ "path": "docs/recipes/redteam-patrol.md",
1734
+ "mode": "0000644",
1735
+ "sha256": "3dbdc33eb1aa68da5e6569e836845f09fd14953d94794e005af67ce517fb6dad"
1736
+ },
1727
1737
  {
1728
1738
  "path": "docs/recipes/search-index-ingestion.md",
1729
1739
  "mode": "0000644",
@@ -4437,12 +4447,12 @@
4437
4447
  {
4438
4448
  "path": "package-lock.json",
4439
4449
  "mode": "0000644",
4440
- "sha256": "a8f006af597e3ee7dd622b463716fa7132ae871d1955443c61f2f2afb40af36f"
4450
+ "sha256": "815b7d1a58cdf1a0d9c7e30a97f70faa146ee6f826501f0c42f1b38529851575"
4441
4451
  },
4442
4452
  {
4443
4453
  "path": "package.json",
4444
4454
  "mode": "0000644",
4445
- "sha256": "244edf862f99c7c918722240e97193b52773200fd9bb1cc81a0b879e978a7ccc"
4455
+ "sha256": "dcc8774d55d45595b6e3f3229a278b4bf5e263438bb730a8bdd620edf9c47bbd"
4446
4456
  },
4447
4457
  {
4448
4458
  "path": "public-docs/index.html",
@@ -4819,6 +4829,11 @@
4819
4829
  "mode": "0000644",
4820
4830
  "sha256": "7085afc3cc1f636027e1d1c7413cf6a346090de4717fd0fc2ae51d27ee766fd8"
4821
4831
  },
4832
+ {
4833
+ "path": "scripts/gds/audit-gate.js",
4834
+ "mode": "0000644",
4835
+ "sha256": "df91d5e2514ea8c2e79d00a2386e878404ac572f111b2fb5c80ae6f2e53bd85a"
4836
+ },
4822
4837
  {
4823
4838
  "path": "scripts/gds/audit-replay.sh",
4824
4839
  "mode": "0000644",
@@ -4959,6 +4974,11 @@
4959
4974
  "mode": "0000644",
4960
4975
  "sha256": "8ca6ee391837d7e1a45e69fc62c4a051f5e3d6060db507cdcbc7a343e2b03bd3"
4961
4976
  },
4977
+ {
4978
+ "path": "scripts/gds/control-manifest.js",
4979
+ "mode": "0000644",
4980
+ "sha256": "0d5b0c5e4bc15ff914d34849607ad2f01d1843d4dafeafdaf4191c2f365300bb"
4981
+ },
4962
4982
  {
4963
4983
  "path": "scripts/gds/copy-inventory.js",
4964
4984
  "mode": "0000644",
@@ -5069,10 +5089,15 @@
5069
5089
  "mode": "0000644",
5070
5090
  "sha256": "7a7721155c8c7cb169a48e6f279e5d7c0ba0dc4462678a4a2ec41a2686501962"
5071
5091
  },
5092
+ {
5093
+ "path": "scripts/gds/fitness-ratchets.js",
5094
+ "mode": "0000644",
5095
+ "sha256": "a27a3873f516abdc52f7f482603779010bbc1af4d6e73c0b86dd34292017bc9a"
5096
+ },
5072
5097
  {
5073
5098
  "path": "scripts/gds/fitness.js",
5074
5099
  "mode": "0000644",
5075
- "sha256": "add1ee5439ef3ddff171e7eb9a695c63a41b8323c5e8cc6c415b620b812bdfa8"
5100
+ "sha256": "81b35af96345cfdca3f30a9d4f333715c4dd431657a9aa73b5794c02ef75686f"
5076
5101
  },
5077
5102
  {
5078
5103
  "path": "scripts/gds/gate-review.js",
@@ -5142,7 +5167,7 @@
5142
5167
  {
5143
5168
  "path": "scripts/gds/gen-session-index.js",
5144
5169
  "mode": "0000644",
5145
- "sha256": "c7bdbd7f7a4d2647be17ad37b540afc35913db80d121000346256d57c065f9fa"
5170
+ "sha256": "9b936143ae25442fefb52b98949bc33d245d4b3894d778c51926e9da75c92357"
5146
5171
  },
5147
5172
  {
5148
5173
  "path": "scripts/gds/git-merge-regen.js",
@@ -5399,6 +5424,11 @@
5399
5424
  "mode": "0000644",
5400
5425
  "sha256": "564996b820fa09ccb95bcef2e5a1b57f22e5b16c4e54b67dfe1a2cd37ff716a4"
5401
5426
  },
5427
+ {
5428
+ "path": "scripts/gds/redteam-patrol.js",
5429
+ "mode": "0000644",
5430
+ "sha256": "4e4ce11a67de653550851d9e0b9931253c8b100dd4285f2a39c74ba2f932b23c"
5431
+ },
5402
5432
  {
5403
5433
  "path": "scripts/gds/regen-instance-docs.js",
5404
5434
  "mode": "0000644",
@@ -5869,6 +5899,11 @@
5869
5899
  "mode": "0000644",
5870
5900
  "sha256": "a932e617ee66dabc49b4087baf6606eeb2074f70ebb3efa0723b1d9c92add290"
5871
5901
  },
5902
+ {
5903
+ "path": "src/bongos/logger.js",
5904
+ "mode": "0000644",
5905
+ "sha256": "08a48a47445606c22c1fb5f1e709de5106693eb8b774466186fb5e30352841e8"
5906
+ },
5872
5907
  {
5873
5908
  "path": "src/bongos/metrics.js",
5874
5909
  "mode": "0000644",
@@ -5877,12 +5912,12 @@
5877
5912
  {
5878
5913
  "path": "src/bongos/middleware/audit.js",
5879
5914
  "mode": "0000644",
5880
- "sha256": "1b260403bdf9f660027a30f316be3246cd833439938216c189033c8e9b3573fa"
5915
+ "sha256": "ad2d224b01bba5ce747f8e3ab8704cbbbd67b1bfb6f4d1237bc910e91f7e4287"
5881
5916
  },
5882
5917
  {
5883
5918
  "path": "src/bongos/middleware/error-envelope.js",
5884
5919
  "mode": "0000644",
5885
- "sha256": "9a0b9c5212607285b09b5139baa665dcac534e915e9e51aa5644f42efbc8ef9b"
5920
+ "sha256": "920897ba69d929ab5b77bac1605c67d78805ebbbf962d59fec5bdc8b293bd67a"
5886
5921
  },
5887
5922
  {
5888
5923
  "path": "src/bongos/middleware/rate-limit.js",
@@ -5892,7 +5927,7 @@
5892
5927
  {
5893
5928
  "path": "src/bongos/module-scope-map.js",
5894
5929
  "mode": "0000644",
5895
- "sha256": "39fe7b2e08a64d038a2f4b5b0807a6803bf19196fe8b43d0c3ec4989fe9cbb6b"
5930
+ "sha256": "c3b5499005ae5150d1e3288437dbfd422e28068a28e3c5783a8c4b3fa2edd09c"
5896
5931
  },
5897
5932
  {
5898
5933
  "path": "src/bongos/module-submissions.js",
@@ -6027,7 +6062,7 @@
6027
6062
  {
6028
6063
  "path": "src/bongos/serve-internal.js",
6029
6064
  "mode": "0000644",
6030
- "sha256": "785c83fa3bb4a12ea33b528d70e030cffd44fb3ffaecbdb90f7c558621118f3e"
6065
+ "sha256": "2ce782b00c80482ef9b9d3e4a54a634e73c6d956e13e32cc7e3d2ff63e8282cd"
6031
6066
  },
6032
6067
  {
6033
6068
  "path": "src/bongos/stealth-gate.js",
@@ -6062,7 +6097,7 @@
6062
6097
  {
6063
6098
  "path": "src/module-api.js",
6064
6099
  "mode": "0000644",
6065
- "sha256": "187e079a50ea8d3f643cf2f33560880b86708a600109b386698425a92a55099e"
6100
+ "sha256": "a34bf521314a258ef3c444962bac548fa9aa2e0853dc45531f79586ef52bdeec"
6066
6101
  },
6067
6102
  {
6068
6103
  "path": "src/module-loader/catalog.js",
@@ -6102,7 +6137,7 @@
6102
6137
  {
6103
6138
  "path": "src/platform-server.js",
6104
6139
  "mode": "0000644",
6105
- "sha256": "9567d70acc5150dbdd0f6ea1df996977f2566c8c577bd6c9d0ca05516163dc1b"
6140
+ "sha256": "704f68cdafb697138b9e012defedeb827dee3ff97191c78bf0e86be0ae5d61cf"
6106
6141
  },
6107
6142
  {
6108
6143
  "path": "src/ui/adapters/claude-design/index.js",
@@ -6219,6 +6254,11 @@
6219
6254
  "mode": "0000644",
6220
6255
  "sha256": "917a10994a3c6b1f849953bf66fdbabf298a0fb4f07438dd51f513cff806a981"
6221
6256
  },
6257
+ {
6258
+ "path": "tests/audit_gate.mjs",
6259
+ "mode": "0000644",
6260
+ "sha256": "af91c6018f572d9cb0a213b40ec7953f9f81cc20a33634fb5a66615a1649fee8"
6261
+ },
6222
6262
  {
6223
6263
  "path": "tests/audit_middleware.mjs",
6224
6264
  "mode": "0000644",
@@ -6267,7 +6307,7 @@
6267
6307
  {
6268
6308
  "path": "tests/auth_resolve_failure.mjs",
6269
6309
  "mode": "0000644",
6270
- "sha256": "25271ff1abef5600fab6b9d768c0f94965ffdea4d926b6a60344676f5392f9f1"
6310
+ "sha256": "d14529c53ddf42f69c40fd49dc6eb230df4a519e9bc2bfdfab04df277e3dbb9c"
6271
6311
  },
6272
6312
  {
6273
6313
  "path": "tests/auth_session_ttl.mjs",
@@ -6522,7 +6562,7 @@
6522
6562
  {
6523
6563
  "path": "tests/claude_materialize.mjs",
6524
6564
  "mode": "0000644",
6525
- "sha256": "6d31d8597e3b1e9e7efde56f9a3839715cfa87378e7555f0fa3b26b09346a569"
6565
+ "sha256": "ad3daf4c6cc3a0f56d8d205077c835397b1d112a0219dabb05a7e8b3a8da9492"
6526
6566
  },
6527
6567
  {
6528
6568
  "path": "tests/clawback_confirmed_backlog.mjs",
@@ -6589,6 +6629,11 @@
6589
6629
  "mode": "0000644",
6590
6630
  "sha256": "55bd70efd8067e39d6220d14f78c743ce80d8a8ff37988acf00136b5108dc004"
6591
6631
  },
6632
+ {
6633
+ "path": "tests/control_manifest.mjs",
6634
+ "mode": "0000644",
6635
+ "sha256": "2465159282594723a49d03ed2ca9dbb10e95ddb7af96d145c45f7d7c2a8b8cee"
6636
+ },
6592
6637
  {
6593
6638
  "path": "tests/copy_desk_flags_db.mjs",
6594
6639
  "mode": "0000644",
@@ -6874,6 +6919,11 @@
6874
6919
  "mode": "0000644",
6875
6920
  "sha256": "ebb93b7bdd90c0775f71eb949a6e47022570bdb35c901bd4522413fefa750e14"
6876
6921
  },
6922
+ {
6923
+ "path": "tests/fitness_ratchets.mjs",
6924
+ "mode": "0000644",
6925
+ "sha256": "781bdee0778645704b5179bf99507e839743158714f799e45d6cc64f8fc30477"
6926
+ },
6877
6927
  {
6878
6928
  "path": "tests/fitness_two_root.mjs",
6879
6929
  "mode": "0000644",
@@ -7459,6 +7509,11 @@
7459
7509
  "mode": "0000644",
7460
7510
  "sha256": "a01036699653e810c8eb2e4f8bdabe081095e5634ef6ea4f1e4f85b2b5f56523"
7461
7511
  },
7512
+ {
7513
+ "path": "tests/logger.mjs",
7514
+ "mode": "0000644",
7515
+ "sha256": "88508517d49ad11a01d2dbc97767c4baa6789753ea42afe76699bc2bab5017d4"
7516
+ },
7462
7517
  {
7463
7518
  "path": "tests/main_audit.mjs",
7464
7519
  "mode": "0000644",
@@ -7862,7 +7917,7 @@
7862
7917
  {
7863
7918
  "path": "tests/publish_reconciler.mjs",
7864
7919
  "mode": "0000644",
7865
- "sha256": "1dfca44ba378b69041894371c1a3765eba40edbdec18570d7b67cc849bcb9e8a"
7920
+ "sha256": "c61741aebfad2e85e55f0e734b3195d9474f8dd0c7812c3ee1434b05d088c1de"
7866
7921
  },
7867
7922
  {
7868
7923
  "path": "tests/rank_gate.mjs",
@@ -7899,6 +7954,11 @@
7899
7954
  "mode": "0000644",
7900
7955
  "sha256": "6d82e99c69d23a4dd7a844ffdd7f239ea70c94d9c509e2fc8e1a672cd9f05a28"
7901
7956
  },
7957
+ {
7958
+ "path": "tests/redteam_patrol.mjs",
7959
+ "mode": "0000644",
7960
+ "sha256": "bf32ae5c734fc95873433b7c4e251a6b166c167ccc91c4684d061b97681c3357"
7961
+ },
7902
7962
  {
7903
7963
  "path": "tests/regrade_eligibility.mjs",
7904
7964
  "mode": "0000644",
@@ -1,20 +1,24 @@
1
1
  # ADR 0022 — Secrets policy
2
2
 
3
3
  **Date:** 2026-05-28
4
- **Context:** Task [#279](https://example.com/builders#/task/279) (V3.R60), GDS-V3 criterion C8. Builds on the pre-commit hook + CI scan shipped by [#257](https://example.com/builders#/task/257) (V3.R36) and pairs with [ADR 0020](<redacted>.md) (security model — public stub) and [ADR 0016](<redacted>.md) (trust boundary). Companion to [`docs/security-baseline.md`](../security-baseline.md) item 6.
4
+ **Context:** Task [#279](https://example.com/builders#/task/279) (V3.R60), GDS-V3 criterion C8. Originally built on a pre-commit hook + CI scan (task [#257](https://example.com/builders#/task/257), V3.R36); those surfaces were lost in the core extraction and rebuilt as the prevent/gate/patrol layers under goal 1000076 (task 1003131). Pairs with [ADR 0020](<redacted>.md) (security model — public stub) and [ADR 0016](<redacted>.md) (trust boundary).
5
+ **Enforcement rebuilt:** 2026-08-19 (task 1003131, goal 1000076) — see the Problem section's box.
5
6
  **Status:** Accepted.
6
7
 
7
8
  ## Problem
8
9
 
9
10
  A secret committed to a public repo is a credential someone else can use within minutes — even after a force-push to remove it, the value survives in forks, GitHub's commit cache, and any clone made between the commit and the removal. The right model is **defense in depth**: each layer assumes the next one will fail.
10
11
 
11
- We already have parts of this:
12
+ We have defense in depth (rebuilt under goal 1000076 — see the box below):
12
13
 
13
- - Pre-commit hook in `.husky/pre-commit` blocks the obvious shapes locally.
14
- - `.github/workflows/secrets-scan.yml` re-scans full history in CI on every PR.
15
- - `.gitignore` lists `.env.local`.
14
+ - **Prevent (agent-side):** `.claude/hooks/secret-gate.js`, a PreToolUse hook, blocks a secret-shaped Write/Edit/Bash payload before it reaches the tree; `.claude/settings.json` denies reading the env/key/session lanes.
15
+ - **Gate (CI):** `.gitleaks.toml` drives a gitleaks scan of the working tree in the required `unit` workflow on every PR.
16
+ - **Patrol (weekly):** `.claude/scheduled-tasks/redteam-weekly` runs a full-git-**history** gitleaks scan and files any hit as a security report.
17
+ - `.gitignore` lists `.env.local` and the key/PEM shapes.
16
18
  - Live credentials resolve from `/etc/example/` on the droplet or `~/.config/otb/env` on builder laptops — neither path is tracked.
17
19
 
20
+ > **Why this list is now trustworthy — the assurance-of-assurance.** The controls above are not just described here; each has a row in `scripts/gds/control-manifest.js`, a fitness check that reds the merge gate if any control file is deleted or comes unwired (task 1003131). This ADR **used to** name a `.husky/pre-commit` hook, a `.github/workflows/secrets-scan.yml`, and a `docs/security-baseline.md` — **none of which existed in this repo**; they were lost in the core extraction and nothing noticed for releases (the red-team baseline audit's headline finding, [`docs/audits/ai-dev-redteam-baseline.md`](../audits/ai-dev-redteam-baseline.md) §0). A doc describing a control cannot be the assurance; the manifest is.
21
+
18
22
  What's missing — and what this ADR adds — is a written **policy** that defines:
19
23
 
20
24
  1. What counts as a secret (so the scan can be tuned).
@@ -26,7 +30,7 @@ Without this document, every new builder reinvents the answers. Some answers wil
26
30
 
27
31
  ## Decision
28
32
 
29
- This ADR is **the policy**. The pre-commit hook + the CI workflow are the **enforcement**. The `docs/security-baseline.md` check is the **assertion that both still exist**. Each layer is independently maintained but consistent with this document.
33
+ This ADR is **the policy**. The prevent hook + the CI gitleaks gate + the weekly patrol are the **enforcement** (goal 1000076). `scripts/gds/control-manifest.js` — a fitness check in the `unit` gate — is the **assertion that they still exist and stay wired**. Each layer is independently maintained but consistent with this document; a change that removes an enforcement surface must update the manifest in the same commit, or CI goes red.
30
34
 
31
35
  ## What counts as a secret
32
36
 
@@ -86,11 +90,11 @@ GDS session tokens rotate automatically — they're 30-day-TTL, refresh-on-use,
86
90
 
87
91
  ## What to do when the scan finds a hit
88
92
 
89
- If `.husky/pre-commit` blocks a commit, OR `.github/workflows/secrets-scan.yml` fails on a PR, OR a one-off TruffleHog run finds a hit in history, OR `scripts/gds/security-baseline-check.sh` item 6 flips to FAIL:
93
+ If `.claude/hooks/secret-gate.js` blocks a write, OR the gitleaks step in the `unit` workflow fails on a PR, OR the weekly `redteam-weekly` patrol files a history-secrets report, OR `scripts/gds/control-manifest.js` flags a missing control:
90
94
 
91
95
  1. **Stop**. Do not push, do not merge, do not delete the offending file from the working tree (yet).
92
96
  2. **Identify the credential** — what service, what scope, was it ever active in production.
93
- 3. **Rotate the credential first** (steps 1-4 above). Treat the leaked value as compromised even if the scan was a pre-commit catch — the same value may have been pasted into a chat or a sibling file.
97
+ 3. **Rotate the credential first** (steps 1-4 above). Treat the leaked value as compromised even if the scan was a prevent-hook catch — the same value may have been pasted into a chat or a sibling file.
94
98
  4. **Then** rewrite the offending file (remove the credential) and commit. If the credential was already in pushed history, run `git filter-repo --replace-text <pattern>` to scrub it from every commit. This rewrites SHAs; force-push is required; CI scan re-validates afterward.
95
99
  5. **Document** — add an entry to [`docs/recipes/ops-gotchas.md`](../recipes/ops-gotchas.md) with the date, what happened, and what changed in the response so the next time it goes faster.
96
100
  6. **Forks + clones** — the rewrite doesn't reach existing clones. Anyone with an outdated clone gets a `git fetch` warning about non-fast-forward; they re-clone. Forks that mirror via GitHub's mirror feature need a manual `git push --force` from the upstream-aware operator.
@@ -109,16 +113,16 @@ The enforcement above keeps secrets out of the **repo**. A second egress exists:
109
113
 
110
114
  This scrubber is **transcript-grade** and **recall-first** (task 1003, which also completed the open token-redaction of task 723): a missed secret is a credential compromise, while over-redacting a non-secret in a BFG digest is merely cosmetic, so when in doubt it redacts. Five layers: (1) literal dynamic values — this run's GDS session token + every secret-shaped **env value** (`collectEnvSecrets()`, e.g. the `MAC_*`/`APPLE_*` signing creds, a baked GDS/DO token); (2) multi-line PEM private-key blocks; (3) the in-scope known shapes from this ADR (provider key prefixes, Stripe `sk_`/`rk_`/`whsec_`, our `gds_`/`pms_` tokens, `Authorization`/`Bearer` headers, JWTs, credentialed DSNs, Apple app-specific passwords); (4) recognised-key `key=value` / JSON-field assignments; (5) a **high-entropy catch-all** (`looksHighEntropySecret()`) over base64url/hex runs ≥20 chars — the net for an *unknown* secret shape. The accepted cost of layer 5 is that high-entropy non-secrets (git SHAs, UUIDs, a 40-hex value shape-identical to a GitHub OAuth client secret) are redacted too; the structured BFG metrics that matter (token/turn counts, tool names, error flags) are separate fields and untouched. The planted-secret corpus in `tests/scrubber_corpus.mjs` is the regression gate — every planted secret must be fully redacted, every benign line must survive — and **gates the full-transcript capture task**: capture must not ship until this passes.
111
115
 
112
- This scrubber is now a load-bearing enforcement surface alongside the pre-commit hook + CI scan; a change to the in-scope secret shapes above should update it (and its corpus) too, or the policy and the enforcement will drift.
116
+ This scrubber is now a load-bearing enforcement surface alongside the prevent hook + CI gitleaks gate; a change to the in-scope secret shapes above should update it (and its corpus) too, or the policy and the enforcement will drift.
113
117
 
114
118
  ## Alternatives considered
115
119
 
116
120
  - **Use a cloud secrets manager.** Rejected: cost (~$0.40/secret-month at AWS), latency (an extra network hop on cold start), single point of failure (the manager being down blocks deploys). At ~10 secrets and one operator, the filesystem-permissions model is cheaper and not meaningfully less secure.
117
121
  - **Encrypt secrets in the repo (SOPS, git-crypt).** Rejected: shifts the problem from "don't commit the secret" to "don't lose the decryption key." The decryption key has to live somewhere; if it lives in the same repo, we've solved nothing; if it lives outside, we've reinvented the current `/etc/example/` model with extra steps.
118
- - **Skip the pre-commit hook; rely on CI alone.** Rejected: CI catches the leak after the secret has already been pushed to GitHub (where it's now in their cache, even if the PR closes). The pre-commit hook is the fast feedback that prevents the leak from leaving the laptop.
122
+ - **Skip the agent-side prevent hook; rely on CI alone.** Rejected: CI catches the leak after the secret has already been pushed to GitHub (where it's now in their cache, even if the PR closes). The PreToolUse prevent hook is the fast feedback that stops the leak before it ever reaches a commit.
119
123
 
120
124
  ## Consequences
121
125
 
122
- - New builders go through a one-line orientation: "creds live in /etc/example on the droplet, in ~/.config/otb/env or .env.local on your laptop, nowhere else." If they ask "but what if I want to commit one?" — the hook blocks them; if they push past the hook, CI blocks the merge.
123
- - The pre-commit hook + CI workflow + security-baseline-check item 6 are now load-bearing. A change to any of them needs to update this ADR too, or the policy and the enforcement will drift.
126
+ - New builders go through a one-line orientation: "creds live in /etc/example on the droplet, in ~/.config/otb/env or .env.local on your laptop, nowhere else." If they ask "but what if I want to commit one?" — the prevent hook blocks the write; if they push past it, the CI gitleaks gate blocks the merge; and anything already in history is caught by the weekly patrol.
127
+ - The prevent hook + CI gitleaks gate + weekly patrol are now load-bearing, and `scripts/gds/control-manifest.js` fails CI if any of them is removed or unwired. A change to any of them needs to update this ADR (and the manifest row) too, or the policy and the enforcement will drift — the exact drift this ADR's own rewrite corrected.
124
128
  - Rotation is the operator's responsibility (Lars). The team is informed via the chat broadcast; there is no automatic distribution of new secrets to builder laptops. This is a deliberate accept-the-friction choice — automatic distribution requires a secrets manager.
@@ -0,0 +1,36 @@
1
+ # ADR 0180 — Dependency intake & drift policy
2
+
3
+ **Date:** 2026-08-19
4
+ **Context:** Task 1003127 (goal 1000076, criterion `dependency-watch`). Grounded in the red-team baseline audit ([`docs/audits/ai-dev-redteam-baseline.md`](../audits/ai-dev-redteam-baseline.md) §3): 18 known advisories (2 high) sat unwatched in the 9 production dependencies, the `undici` override pinned a vulnerable range while also breaking Node 26 CLIs, and nothing gated what an agent may `npm install`. Threat backdrop: the 2025 npm wave (chalk/debug takeover, the Shai-Hulud self-replicating worm, the Nx postinstall stealer) ran on **install-lifecycle scripts** and **stale long-lived publish tokens**.
5
+ **Status:** Accepted.
6
+
7
+ ## Decisions
8
+
9
+ ### 1. CI audit gate with a shrink-only baseline
10
+
11
+ `scripts/gds/audit-gate.js` runs in the required `unit` workflow: `npm audit --omit=dev --json`, deduped to advisory×package findings, compared against the committed [`config/audit-baseline.json`](../../config/audit-baseline.json).
12
+
13
+ - A **new high/critical** advisory (not in the baseline) **fails the merge gate**.
14
+ - New low/moderate advisories warn; a baseline entry that stops reproducing prints a ratchet-down nudge.
15
+ - The baseline records **pre-gate debt only** (10 findings, 3 high+ at adoption). It shrinks via fix tasks; adding an entry to silence a *new* advisory defeats the gate and is out of policy.
16
+ - **Fail-open on infrastructure, fail-closed on findings:** a registry outage or unparseable audit output warns and exits 0 — the gate catches new advisories, it does not prove registry uptime.
17
+ - Blanket `npm audit fix` does not run against this tree (`workspace:` protocol in the dependency graph, `EUNSUPPORTEDPROTOCOL`) — one more reason fixes are explicit tasks, not autofix side effects.
18
+
19
+ ### 2. Install-lifecycle scripts are off (`.npmrc ignore-scripts=true`)
20
+
21
+ The dominant live npm attack vector is the postinstall script. This tree needs none: **sharp** (the only native dep) installs prebuilt binaries via `optionalDependencies`, verified by a script-less `npm ci` followed by a sharp load (`vips 8.17.3`) and the full 430-test suite. `npm test`/`npm run` are unaffected (npm only suppresses install-time lifecycle hooks). A future dependency that genuinely needs an install script is an ADR-level exception with justification, not a reason to flip the flag.
22
+
23
+ ### 3. Update cooldown: patrol-enforced now, npm-native later
24
+
25
+ The consensus post-Shai-Hulud control is a **release-age cooldown** (don't install versions younger than a few days; let the ecosystem catch registry malware first). npm supports this natively from 11.10 (`minimum-release-age`), but the CI toolchain (Node 22 → npm 10) would warn on the unknown key for every builder. So:
26
+
27
+ - **Now:** the weekly red-team patrol (task 1003128) flags any dependency bumped to a version **younger than 7 days** at install time, plus stale overrides (the `undici ^6.27.0` case — pinned inside a vulnerable range) and unpinned workflow actions.
28
+ - **Later:** when the toolchain floor reaches npm ≥ 11.10, move the cooldown into `.npmrc` and drop the patrol's version-age check.
29
+
30
+ ### 4. Publish auth: OIDC trusted publishing, token as documented exception
31
+
32
+ The publish-on-merge lane (ADR 0161) authenticates with a long-lived `NPM_TOKEN` repository secret — exactly the credential class the Sept-2025 attacks monetized, and why GitHub revoked classic tokens and capped granular ones at 90 days. Decision: **adopt npm trusted publishing (OIDC)** — no long-lived secret, provenance for free. It needs a one-time owner action on npmjs.com (register the repo+workflow as a trusted publisher for `@bongos/core`), filed as a blocker. **Until then** the granular `NPM_TOKEN` remains a *documented exception*: 90-day expiry, publish-only scope, rotated on expiry.
33
+
34
+ ## What this deliberately does not cover
35
+
36
+ New-dependency *intake vetting* (registry existence/age/download checks — the slopsquatting defense) lives in the weekly patrol (task 1003128), and one-off vulnerability *fixes* (sharp ≥ 0.35 for the libvips CVEs, the colyseus chain for nanoid) are ordinary tasks that shrink the baseline — filed in the idea inbox at adoption time.
@@ -253,5 +253,6 @@ This keeps the decision history honest and traceable.
253
253
  | 0177 | [**A goal membership is a `membership_kind`, and the rename ships expand-then-contract** ([task 1003013](https://cloudbongos.com/builders#/task/1003013), goal 1000068). ADR 0174 reserved `role` for the three crafts and enforced it on the GOVERNMENT surface only — by design, since `builders.system_role` and Discord's own noun are legitimate. That left a **fourth** use uncatalogued: `goal_members.role` (`'lead' | 'member'`), the MANAGER predicate behind goal authorization. Renamed to **`membership_kind`** — values unchanged, because the noun was the problem; `rank` is wrong (not a ladder position) and `position` is worse (ADR 0174 uses it as the prose word for a rank, recreating the "rank-role" qualifier collision). A boolean `is_lead` was seriously considered and rejected: the text rename keeps the copied CHECK and stays a reversible change on a live authz column, where `ADD boolean; UPDATE; DROP text` is data-destructive. The migration is **expand-then-contract, never `RENAME COLUMN`** — auto-rollback reverts the code pin and NOT the DB, so `core_220` ADDs the column and keeps the pair in lockstep with a BEFORE trigger (direction decided by which side changed), and a later task DROPs the old column with the `-- forward-unsafe` pragma, a backup, and its own window; no `SET NOT NULL` in step 1, because a static NOT NULL on a column the previous release never heard of is what the forward-safety gate rightly flags. The API field renames with it and carries **no `role` alias** (ADR 0174's Lineage lesson: a time-boxed shim outlives its release), pinned by the test of its absence. The reservation gains a **second narrow wall** rather than a widened first one — line-scoped inside the 5k-line `db.js` to the lines that name `goal_members`, so no allowlist is needed. A **fifth** use (`project_memberships.role`) is catalogued and filed, with this as its pattern.](<redacted>.md) | naming / lifecycle |
254
254
  | 0178 | [**The copy desk: a flag carries a judgement, and no column here could ever hold copy** ([task 1003113](https://cloudbongos.com/builders#/task/1003113), R02 of goal 1000074). [ADR 0081](<redacted>.md) made the repo the source of truth for design TOKENS; user-facing TEXT had no equivalent. R01 built the inventory (`copy-inventory.js` → `docs/copy-registry.json`), which answers *what does the product say* but cannot answer *what is wrong with it* — a judgement a person must record. This is that record plus the artist's queue. A new default-on module keyed **`copy-desk`, not `copy`**, for a concrete reason: the branding contract already owns a `copy` block, so the bare word reds the `core carries no module code` fitness check on the English word in `src/branding.js` — and the editorial "copy desk" is the more accurate name anyway. **The reason is required in the route AND in a CHECK constraint**: the route gives a person a usable error, the constraint means no future write path can create the reasonless flag the queue exists to not contain (a pointer with no judgement is *worse* than no flag — it still costs the artist a look). Closing requires a note by the same symmetry, since an unexplained close is indistinguishable from clearing a queue to move a number. The load-bearing decision is **NO LIVE CMS enforced by the schema's SHAPE**: `copy_desk_flags` has no column that could hold replacement text and must never gain one, because that non-goal does not erode via an "add a CMS" commit but via one plausible column, then one plausible read of it — `copy_no_cms.mjs` pins the write surface at exactly two verbs so R03's proposal path changes it in a reviewable diff. Rank is asymmetric: **filing is open to every rank** (the engineer who wrote the toast and the newcomer who could not read the button are the likeliest noticers, and neither is the artist — the reason floor is the quality gate, rank is not), closing is Metic+ **or the author** (withdrawing your own flag is a correction, not triage); nothing gates on craft, since an artist is a craft and not a rank. Duplicates are the only automatic signal (the one of stale/duplicated/off-voice needing no judgement layer) and the count **subtracts settled work**, or it never moves and teaches that the queue is decorative. A vanished target is **reported, never auto-closed** — the id is a hash over the text, so an edit routinely orphans a flag, and closing a human judgement because a hash moved is the family of error ADR 0162 rules out. Deliberately reports **no `generated_at`**: R01's contract is determinism, so a clock is the one field it cannot carry.](<redacted>.md) | design / artist loop |
255
255
  | 0179 | [**`rank:metic+` means metic and above; a bare `rank:metic` still means exactly metic** ([task 1003094](https://cloudbongos.com/builders#/task/1003094), goal 1000069). [ADR 0175](<redacted>.md) gave the constitution ONE membership form, `rank:<key>`, resolved by an EXACT SQL match — so `rank:metic` seated metics ONLY (excluding Archons), `rank:xenos` seated NEWCOMERS ONLY rather than "everyone", and "Metic and above" was inexpressible. Everywhere else a rank is a LADDER and authority is cumulative (ADR 0034 inheritance, requireRank('metic','archon'), the floor-derived seed); board membership was the one place it meant "exactly", and nothing said so. Rehearsing R25 on a real Postgres, an Archon ratified `rank:metic` under monarchy — the apply worked perfectly — and the next vote came back 403 not_board_member: **the owner flipped the switch and fell off their own board**, with the board deadlocked at one member because an Archon can still PROPOSE but no longer VOTE. Owner decision: EXPLICIT GRAMMAR. `rank:metic+` (that rank and above), `rank:metic,archon` (union), and **a bare key still means EXACTLY that key** — rejecting the smaller diff (silently redefining the bare form) precisely because it would have changed the meaning of every already-ratified constitution, the monarchy default included, on upgrade: nothing in a government should change meaning without a vote. `+` is defined only on the STANDARD ladder — "and above" about a custom rank with no ladder position is a parse REFUSAL, not a guess, and a refusal seats nobody. The grammar had been written TWICE (a shape regex in the config sanitizer, a parse regex in the resolver, pinned by a property test) — sound for one literal form, unsound the moment a rule needs a LOOKUP, which is the same class of drift that produced the bug; both now call one pure `membership-predicate.js`. Adds the DISENFRANCHISEMENT GUARD: a proposal that would unseat its own proposer is refused before any write, naming the one-character fix, overridable with an explicit `acknowledge_self_removal` (a separate parameter, never a proposal field) because stepping back is a legitimate act. The two DB reads take a set via `= ANY($1)` + DISTINCT (a double-counted member silently raises the consent bar), the structural filters are re-proven against real Postgres (a deactivated builder and a machine principal still never govern), and the hall panel now describes every form in plain language — rendering `rank:metic+` as "the metic+ rank" would be the same bug one layer up. Unblocks task 1003095, which can now write each charter's TRUE predicate rather than wording around a limitation.](<redacted>.md) | government / the board |
256
+ | 0180 | [**Dependency intake & drift policy: baseline-ratchet audit gate, install scripts off, cooldown via patrol, OIDC publish** ([task 1003127](https://cloudbongos.com/builders#/task/1003127), goal 1000076). The red-team baseline audit found 18 advisories (2 high) sitting unwatched in 9 production deps, the `undici ^6.27.0` override pinned INSIDE a vulnerable range while also breaking Node 26 CLIs, and nothing gated what an agent may install — against a 2025 npm threat wave (chalk/debug, Shai-Hulud, Nx) that ran on postinstall scripts and long-lived publish tokens. Four decisions. (1) `scripts/gds/audit-gate.js` runs in the required `unit` check: a high/critical advisory NOT in the committed `config/audit-baseline.json` fails the merge gate; the baseline is **shrink-only pre-gate debt** (10 findings at adoption) — adding an entry to silence a NEW advisory is out of policy. Fail-OPEN on registry/infra errors, fail-CLOSED on findings: the gate catches new advisories, it does not prove registry uptime. Notably a blanket `npm audit fix` cannot even run here (`workspace:` protocol, EUNSUPPORTEDPROTOCOL) — fixes are explicit tasks. (2) `.npmrc ignore-scripts=true`: the tree needs no install-lifecycle scripts — sharp installs prebuilds via optionalDependencies, proven by a script-less `npm ci` + full 430-test suite; a future dep needing one is an ADR-level exception. (3) Update cooldown is PATROL-enforced (task 1003128 flags versions younger than 7 days + stale overrides + action-pin drift) rather than `.npmrc`-enforced, because CI's npm 10 warns on the npm-11 `minimum-release-age` key for every builder; move it into `.npmrc` when the toolchain floor reaches npm ≥ 11.10. (4) Publish auth moves to npm **trusted publishing (OIDC)** — needs a one-time owner registration on npmjs.com (blocker filed); until then the granular 90-day `NPM_TOKEN` is a documented exception.](<redacted>.md) | devsecops / supply chain |
256
257
 
257
258
  > ⚠️ **Numbering collision (known):** two ADRs share `0008`. The numbers were assigned in parallel sessions before the lock could be enforced. The files are kept under their existing filenames to preserve git history, but the table disambiguates them as `0008-a` / `0008-b`. New ADRs should resume at `0040` to avoid further collisions. (`0024` is also a real on-disk duplicate: the cloneable-repo/local-first-memory ADR and the multi-agent-system-architecture ADR were both numbered `0024` in parallel; both keep their filenames, disambiguated as `0024-a` / `0024-b` like `0008`. Likewise `0025` ended up with two on-disk files — the offsite-backup ADR and the structured-criterion↔task-link ADR — both kept under their existing filenames and disambiguated as `0025-a` / `0025-b`; separately, the BFG ADR had also claimed `0025` on 2026-05-30 and yielded to `0026`. A third happened 2026-06-06: `0036` was claimed in parallel by the builders-subdomain ADR ([#726](https://example.com/builders#/task/726)) and this Discord-channels ADR ([#727](https://example.com/builders#/task/727)); the Discord-channels ADR yielded to `0037`. A fourth landed 2026-06-10: `0044` was claimed in parallel by the palette-replacement ADR and the per-box game-preview ADR ([#897](https://example.com/builders#/task/897)); both keep their filenames, disambiguated as `0044-a` / `0044-b` like `0008`. A fifth was caught pre-land 2026-06-13: `0050` was claimed in parallel by the device-flow-admission ADR ([#1000](https://example.com/builders#/task/1000)) and the sandbox-for-everyone ADR ([#1001](https://example.com/builders#/task/1001)); the latter yielded to `0052` before merging, so there is no `0050` duplicate. A sixth was caught pre-land 2026-06-21: the tool-agnostic-design-layer ADR ([#1375](https://example.com/builders#/task/1375)) first collided at `0079` with the value-gated-autonomous-engagement ADR, then at `0080` with the llm-cache-api-transport ADR (both part of the 0075–0080 LLM-cost-reduction series, landed on `main` in parallel); it yielded to `0081` before merging, so there is no `0079`/`0080` design-layer duplicate. A seventh landed 2026-06-23: `0084` was claimed in parallel by the auto-derived-per-task-rank-floor ADR and the remove-default-spend-cap ADR (task 1499); the rank-floor ADR landed on `main` first, so the spend-cap ADR yielded to `0085`, leaving no `0084` duplicate. An eighth landed 2026-06-27: `0095` was claimed in parallel by the borrowed-memory-and-retrieval-concepts ADR (PR #459, landed first) and the cross-agent-context-management ADR ([#1651](https://example.com/builders#/task/1651), PR #460); both keep their filenames, disambiguated as `0095-a` / `0095-b` like `0008`. These two are companions — `0095-a` adopts the memory/retrieval concepts and explicitly defers the grep-vs-semantic question to `0095-b`.)
package/docs/file-map.md CHANGED
@@ -388,6 +388,7 @@ tests/
388
388
  <!-- BEGIN GENERATED FILE-MAP .claude/scheduled-tasks/ (scripts/gds/gen-file-map.js — do not hand-edit; notes live in docs/file-map.notes.json) -->
389
389
  ```
390
390
  .claude/scheduled-tasks/
391
+ └── redteam-weekly/SKILL.md ← weekly deterministic red-team patrol (task 1003128): full-history gitleaks scan + dependency drift review (audit delta, cooldown, young pkgs, stale overrides) + action-pin check → files security reports (advisory, ADR 0162)
391
392
  ```
392
393
  <!-- END GENERATED FILE-MAP .claude/scheduled-tasks/ -->
393
394
 
@@ -89,4 +89,4 @@ This template forces:
89
89
 
90
90
  ## Old entries
91
91
 
92
- There is **no per-session compaction chore** anymore. CLAUDE.md §13 shows only a generated, bounded recent-sessions snippet (older entries roll off it automatically) and the full history is the generated [`docs/session-log-index.md`](session-log-index.md) — neither is hand-maintained. Trimming very old prose from `docs/session-logs/` into `docs/session-log-archive.md` is optional on-disk housekeeping; it no longer affects the loaded-every-session context cost.
92
+ There is **no per-session compaction chore** anymore. CLAUDE.md §13 shows only a generated, bounded recent-sessions snippet (older entries roll off it automatically) and the full history is the generated `docs/session-log-index.md` — neither is hand-maintained. Trimming very old prose from `docs/session-logs/` into `docs/session-log-archive.md` is optional on-disk housekeeping; it no longer affects the loaded-every-session context cost.
@@ -17,7 +17,7 @@ A "recipe" is not a limitation (something the project cannot do). It is a multi-
17
17
 
18
18
  - Architectural decisions → [`docs/adr/`](../../docs/adr/)
19
19
  - Things the project cannot do → [`limitations/`](../../limitations/)
20
- - Things stuck on the prompter's input → [`blockers/`](../../blockers/)
20
+ - Things stuck on the prompter's input → the blockers queue (`POST /api/gds/blockers`, reviewed via `/blocker-review`)
21
21
 
22
22
  ## Read order while working
23
23
 
@@ -0,0 +1,48 @@
1
+ # The weekly red-team patrol
2
+
3
+ **What it is.** The patrol layer of goal 1000076 (task 1003128): deterministic
4
+ scanners that run weekly and file findings into the security-reports
5
+ adjudication queue. It complements the two always-on layers — the agent-side
6
+ prevent hooks (task 1003125) and the CI merge gates (tasks 1003126/1003127/1003129)
7
+ — by covering what those can't: **git history**, **the network** (registry
8
+ metadata), and **slow sweeps**.
9
+
10
+ ## Running it
11
+
12
+ ```bash
13
+ node scripts/gds/redteam-patrol.js # dry run — print, file nothing
14
+ node scripts/gds/redteam-patrol.js --file # the weekly cron form — files reports
15
+ node scripts/gds/redteam-patrol.js --canary # self-test detection only
16
+ node scripts/gds/redteam-patrol.js --canary --file # prove the full pipe (files + dispute-closes)
17
+ ```
18
+
19
+ The scheduled form lives at [`.claude/scheduled-tasks/redteam-weekly/`](../../.claude/scheduled-tasks/redteam-weekly/SKILL.md)
20
+ (`mode: deterministic`, one step, sink `gds`). Install on a machine per the
21
+ file-map convention: symlink the routine dir under `~/.claude/scheduled-tasks/`.
22
+ Weekly is the cadence — the checks watch drift measured in days (release-age,
23
+ new advisories), not minutes.
24
+
25
+ ## Prerequisites
26
+
27
+ - **gitleaks** on PATH (`brew install gitleaks`) or `GITLEAKS_BIN=<path>`. The
28
+ history scan degrades LOUDLY (a printed warning, no silent skip) when absent;
29
+ the dependency + pin checks still run.
30
+ - A GDS session (the normal builder token) for `--file`; dry runs need nothing.
31
+ - Network access to the npm registry for the dependency checks — registry
32
+ failures print notes and skip that item (advisory layer: fail-open, loud).
33
+
34
+ ## What a finding means
35
+
36
+ Reports land at `target: redteam-patrol/<class>` for Archon adjudication in the
37
+ red-team dashboard — confirm / dispute / link-fix, exactly like a
38
+ `/builder-redteam` filing (they share the pipeline and the bounty table; patrol
39
+ reports are machine-filed, so confirming one pays nobody). The fix is always an
40
+ ordinary task; the patrol never gates and never self-executes (ADR 0162).
41
+
42
+ ## Design boundaries
43
+
44
+ Deterministic only — AI review was deliberately deferred (owner decision
45
+ 2026-08-18, recorded on the goal). One report per finding class per run keeps
46
+ the queue at 0–3 rows weekly. Severity mapping: npm's `moderate` files as
47
+ `medium` (the bounty table's vocabulary). Caps: 10 itemized findings per report
48
+ body, the rest counted.
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.256",
3
+ "version": "1.19.258",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.19.256",
9
+ "version": "1.19.258",
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.256",
3
+ "version": "1.19.258",
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",