@bongos/core 1.19.186 → 1.19.188

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.
Files changed (54) hide show
  1. package/.bongos-core.json +83 -78
  2. package/config/government.neutral.json +6 -6
  3. package/docs/adr/0151-governance-permissions-as-atom-ranks-as-roles.md +7 -0
  4. package/docs/adr/0172-editable-rank-roles-substrate-axis.md +8 -1
  5. package/docs/adr/README.md +2 -2
  6. package/docs/api/openapi.json +8 -8
  7. package/docs/api-reference.md +7 -7
  8. package/docs/architecture.md +1 -1
  9. package/docs/canonical-permissions.md +9 -9
  10. package/docs/file-map.md +1 -1
  11. package/modules/builder-settings/wandering-prefs.js +13 -13
  12. package/modules/government/catalog.js +75 -75
  13. package/modules/government/config.js +43 -33
  14. package/modules/government/db.js +57 -57
  15. package/modules/government/protected-surfaces.js +7 -7
  16. package/modules/government/protected-surfaces.json +4 -4
  17. package/modules/government/ranks.js +17 -17
  18. package/modules/government/resolver.js +24 -24
  19. package/modules/government/routes/government.js +86 -86
  20. package/modules/government/routes/rank-sync.js +6 -6
  21. package/modules/government/session-scopes.js +7 -7
  22. package/modules/government/session-scopes.json +5 -5
  23. package/modules/hall-ui/public/government.css +1 -1
  24. package/modules/hall-ui/public/government.html +1 -1
  25. package/modules/hall-ui/public/government.js +3 -3
  26. package/modules/lifecycle/claim-eligibility.js +1 -1
  27. package/modules/lifecycle/db.js +1 -1
  28. package/package-lock.json +2 -2
  29. package/package.json +1 -1
  30. package/scripts/gds/fitness.js +138 -0
  31. package/src/bongos/auth.js +2 -2
  32. package/src/module-api.js +5 -1
  33. package/tests/auth_page_gate.mjs +2 -2
  34. package/tests/{governance_abuse_matrix.mjs → government_abuse_matrix.mjs} +36 -36
  35. package/tests/{governance_catalog.mjs → government_catalog.mjs} +11 -11
  36. package/tests/{governance_claim_eligibility.mjs → government_claim_eligibility.mjs} +2 -2
  37. package/tests/{governance_config.mjs → government_config.mjs} +54 -54
  38. package/tests/{governance_fold.mjs → government_fold.mjs} +6 -6
  39. package/tests/{governance_fold_bench.mjs → government_fold_bench.mjs} +3 -3
  40. package/tests/{governance_live_proof.mjs → government_live_proof.mjs} +5 -5
  41. package/tests/{governance_ownership_scope.mjs → government_ownership_scope.mjs} +16 -16
  42. package/tests/{governance_page_gates.mjs → government_page_gates.mjs} +5 -5
  43. package/tests/{governance_parity.mjs → government_parity.mjs} +3 -3
  44. package/tests/{governance_principals.mjs → government_principals.mjs} +14 -14
  45. package/tests/{governance_protected_surfaces.mjs → government_protected_surfaces.mjs} +1 -1
  46. package/tests/{governance_role_sync.mjs → government_rank_sync.mjs} +2 -2
  47. package/tests/{governance_require_permission.mjs → government_require_permission.mjs} +1 -1
  48. package/tests/{governance_resolver.mjs → government_resolver.mjs} +6 -6
  49. package/tests/{governance_routes.mjs → government_routes.mjs} +32 -32
  50. package/tests/{governance_seed.mjs → government_seed.mjs} +8 -8
  51. package/tests/{governance_session_scope.mjs → government_session_scope.mjs} +10 -10
  52. package/tests/{governance_vanilla_boot.mjs → government_vanilla_boot.mjs} +26 -26
  53. package/tests/government_vocabulary.mjs +94 -0
  54. package/tests/hall_page_gate_map.mjs +1 -1
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.186",
6
- "core_contract": "1.19.186",
7
- "source_commit": "6cbbcc0e845fce8a100732deadbed810ed8b7a0c",
5
+ "core_version": "1.19.188",
6
+ "core_contract": "1.19.188",
7
+ "source_commit": "d007613318330a2803d0a0fc1d6111d6e68edd49",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-08-16T22:45:57.773Z",
9
+ "built_at": "2026-08-16T23:22:52.135Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
12
  "docs_redacted": 308,
13
13
  "agent_docs_stubbed": 21,
14
- "functional_verbatim": 1281,
14
+ "functional_verbatim": 1282,
15
15
  "rules": 3,
16
16
  "gate_literals": 3,
17
17
  "gate": "passed"
18
18
  },
19
- "file_count": 1610,
20
- "tree_sha256": "18131419ad0fd9f0d498fad1bd304caefa22719a484a3e7c92d50ad798a5dfb4",
19
+ "file_count": 1611,
20
+ "tree_sha256": "67d041849002f213d0fe7900fc4ffd31daa363a1ebb8e4c79c8dc18a1e8f1c50",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/blocker-review/SKILL.md",
@@ -397,7 +397,7 @@
397
397
  {
398
398
  "path": "config/government.neutral.json",
399
399
  "mode": "0000644",
400
- "sha256": "1d285d78452558c995d2c0568190f4377ac4ecfddea642f5a94949298a1e48b1"
400
+ "sha256": "70fe731d06dd9744178a27ec4379ee8c769f9a45d9a585f095b1765433767afc"
401
401
  },
402
402
  {
403
403
  "path": "config/modules.neutral.json",
@@ -1222,7 +1222,7 @@
1222
1222
  {
1223
1223
  "path": "docs/adr/0151-governance-permissions-as-atom-ranks-as-roles.md",
1224
1224
  "mode": "0000644",
1225
- "sha256": "20fcf384ddef52e0ac09e52372cbd532ea3a4c40705dba7a84e48891a5c14256"
1225
+ "sha256": "dc8615b7e8b807ef69852ee4cdfcad7db0ab737a1ed733fc96ca712a4ad18ec2"
1226
1226
  },
1227
1227
  {
1228
1228
  "path": "docs/adr/0152-landing-gate-served-by-the-core-app.md",
@@ -1337,7 +1337,7 @@
1337
1337
  {
1338
1338
  "path": "docs/adr/0172-editable-rank-roles-substrate-axis.md",
1339
1339
  "mode": "0000644",
1340
- "sha256": "0bfe5ce46139bf9ee236868317cc80ee10eb8747d5606d0dd0fe9f2580ea5177"
1340
+ "sha256": "390339e26a5e05fd65c8bd4f9303434a8d799e4747b6c1921c2abcc859a331ae"
1341
1341
  },
1342
1342
  {
1343
1343
  "path": "docs/adr/0172-per-craft-compensation-ideator-credit-lane.md",
@@ -1357,22 +1357,22 @@
1357
1357
  {
1358
1358
  "path": "docs/adr/README.md",
1359
1359
  "mode": "0000644",
1360
- "sha256": "79b6d2e5dee626f509ace71bcd133e707ae26b7cbe96a64eb93ebf868c3aabf3"
1360
+ "sha256": "68c676272ad284adc2dd0c9c05b0c6eb0198577a27dd5f2468257eec9d87faf7"
1361
1361
  },
1362
1362
  {
1363
1363
  "path": "docs/api-reference.md",
1364
1364
  "mode": "0000644",
1365
- "sha256": "683e1e4a67d553e5ac75a4593c936ba8e273e07eace3ae623cb5a08b4d73c81c"
1365
+ "sha256": "32c6c5fe14cf8684d353f0c73cde4b09d84ba61eabcb13e75c11bd5b7f9be2b7"
1366
1366
  },
1367
1367
  {
1368
1368
  "path": "docs/api/openapi.json",
1369
1369
  "mode": "0000644",
1370
- "sha256": "051c79468a982cd07b8a398b81346aed6c366b3d35347243891a2cebe79805fb"
1370
+ "sha256": "7892d449572d19f058c6ac364d5b697e28d76bcd922d25d33b5203f5e1b5b7aa"
1371
1371
  },
1372
1372
  {
1373
1373
  "path": "docs/architecture.md",
1374
1374
  "mode": "0000644",
1375
- "sha256": "f6fc3ee98615f246b4a79b89f17641bf96a8da3c07fa30ddb0fcc0112118897e"
1375
+ "sha256": "497b1fbf18ec1cf6d7e0f3620669cfba9008bc6a40e1f70e4b5f53d3406bc12e"
1376
1376
  },
1377
1377
  {
1378
1378
  "path": "docs/branding-contract.md",
@@ -1387,7 +1387,7 @@
1387
1387
  {
1388
1388
  "path": "docs/canonical-permissions.md",
1389
1389
  "mode": "0000644",
1390
- "sha256": "7f32dfe18655bec5890fbaf00491c8ff7fd1f960f0de3caf1cf56ab34562e4fa"
1390
+ "sha256": "9cd97486edfff51a2175c2e758ce99cd217658caec857fddaca366db338822ad"
1391
1391
  },
1392
1392
  {
1393
1393
  "path": "docs/design-contract.md",
@@ -1492,7 +1492,7 @@
1492
1492
  {
1493
1493
  "path": "docs/file-map.md",
1494
1494
  "mode": "0000644",
1495
- "sha256": "e174499ab9f798b88f5747ea143400ddfa3fa6602858dc7518de769c839831f5"
1495
+ "sha256": "a045f8b58bb2e52d770a24fe44524c27afaa4a24acd3e886e1a9a55cff24d3ed"
1496
1496
  },
1497
1497
  {
1498
1498
  "path": "docs/handoff-template.md",
@@ -2452,7 +2452,7 @@
2452
2452
  {
2453
2453
  "path": "modules/builder-settings/wandering-prefs.js",
2454
2454
  "mode": "0000644",
2455
- "sha256": "1e47da4c8a0db204baf3cbfaae516e254a3a273e37a0e1d68e4c0108b3fa7450"
2455
+ "sha256": "e84c11a506bcd47b1f9b6be16bcd262d69aa7162f283c41da63687c5dd611845"
2456
2456
  },
2457
2457
  {
2458
2458
  "path": "modules/dev-box/CLAUDE.md",
@@ -2887,17 +2887,17 @@
2887
2887
  {
2888
2888
  "path": "modules/government/catalog.js",
2889
2889
  "mode": "0000644",
2890
- "sha256": "461a836f14eef90c2e1fcb2f6a3641e952a5904ef95fd0adc64bbf24d2bdc908"
2890
+ "sha256": "b7073912e1aea3da33f876999a6beaae028142f0bf7bf66c1f95efc261b41272"
2891
2891
  },
2892
2892
  {
2893
2893
  "path": "modules/government/config.js",
2894
2894
  "mode": "0000644",
2895
- "sha256": "57086a188ac6557b2f7c2c52e4a75f3960dfd1b7a54ce6fa3c0ce3a216411703"
2895
+ "sha256": "183bca92e8ba897871287aeb58e6f9cfebcf9510b15d6cd9701066ce7c108edd"
2896
2896
  },
2897
2897
  {
2898
2898
  "path": "modules/government/db.js",
2899
2899
  "mode": "0000644",
2900
- "sha256": "250edf5a95aadb06b6b4229bb202ae138c13585caa09f5d8cfeff4c1a982bcc9"
2900
+ "sha256": "0e84802af9d1dd4c139548d4e621fc11896513415abf4e9eadfacbae33c40952"
2901
2901
  },
2902
2902
  {
2903
2903
  "path": "modules/government/migrations/governance_001_tables.sql",
@@ -2952,42 +2952,42 @@
2952
2952
  {
2953
2953
  "path": "modules/government/protected-surfaces.js",
2954
2954
  "mode": "0000644",
2955
- "sha256": "1855c8cd74b7aa00e6f87fb9d402a4be440ecbb26691a84418b6725b83dd2cf9"
2955
+ "sha256": "f2acc38f5d9a361522944334f6db046a96b1d49aa2030f91391ab80752f42274"
2956
2956
  },
2957
2957
  {
2958
2958
  "path": "modules/government/protected-surfaces.json",
2959
2959
  "mode": "0000644",
2960
- "sha256": "d7423da998a11b30cf8015dd5fd537c262f3e3d739ed02a1473debbc5eeb4e6c"
2960
+ "sha256": "6d9a7520b2565b34bf002df016598543101639ccc384d81a622d313ed688acbc"
2961
2961
  },
2962
2962
  {
2963
2963
  "path": "modules/government/ranks.js",
2964
2964
  "mode": "0000644",
2965
- "sha256": "3b217eea2db398db99d580a3d3b2cef8574e3f14b2737e5764fe32d93a1ffc3d"
2965
+ "sha256": "fb0903c3b885a81c99136cc6f080aaf7fc00f86bd1c45c235e37c7c45a462ffc"
2966
2966
  },
2967
2967
  {
2968
2968
  "path": "modules/government/resolver.js",
2969
2969
  "mode": "0000644",
2970
- "sha256": "7c86e964b457bb21192aaacd9f014ec1afabea1779c751fc1682f30fb9a8ac81"
2970
+ "sha256": "bc30290bd0726f643f37984e4e537f503b89a3013bc8319d39d3af116dd08d94"
2971
2971
  },
2972
2972
  {
2973
2973
  "path": "modules/government/routes/government.js",
2974
2974
  "mode": "0000644",
2975
- "sha256": "8fd54465c050cd1e648e419df89ed4c39a853068fd792c5321e10f2ae691bf1d"
2975
+ "sha256": "63e80d002e09d05a93238e15491a82dd733baea219814e8f7e2961ecb5373e1f"
2976
2976
  },
2977
2977
  {
2978
2978
  "path": "modules/government/routes/rank-sync.js",
2979
2979
  "mode": "0000644",
2980
- "sha256": "55b6e1c2c5d02c71b319b40f19676f2e780c58fba5e4767a9b335919bfa13ff0"
2980
+ "sha256": "e7fd1b378d48e93b946237261713a5791f7506dfdd7fcef2d843fe0e2ae8b370"
2981
2981
  },
2982
2982
  {
2983
2983
  "path": "modules/government/session-scopes.js",
2984
2984
  "mode": "0000644",
2985
- "sha256": "d27dc4b14eeaa2e06f7a8ea175b7928d972f424a1165f9ec3e6577ccdd2faf35"
2985
+ "sha256": "1452e5a0480e7c3e1692ec210cb4d85f724d7ebb8dcf38048fb3369c483be46b"
2986
2986
  },
2987
2987
  {
2988
2988
  "path": "modules/government/session-scopes.json",
2989
2989
  "mode": "0000644",
2990
- "sha256": "813e4ddb324363278bfbd6b65260a54697673ac20f0df8e8992dd4ece57efea8"
2990
+ "sha256": "acf5d2391c2228d09c33e6c9a5cfe850dcf8986abb80b30b0c7ff778795938b2"
2991
2991
  },
2992
2992
  {
2993
2993
  "path": "modules/grading/CLAUDE.md",
@@ -3212,17 +3212,17 @@
3212
3212
  {
3213
3213
  "path": "modules/hall-ui/public/government.css",
3214
3214
  "mode": "0000644",
3215
- "sha256": "0b59d6379cb7c61f270676db628c738aadfb24141ee7fdc29d194fae4e63637e"
3215
+ "sha256": "5d58516ae9a07e045de49c7d2bad2b024dbea5207f9cf84cb2928ebd995cbd4e"
3216
3216
  },
3217
3217
  {
3218
3218
  "path": "modules/hall-ui/public/government.html",
3219
3219
  "mode": "0000644",
3220
- "sha256": "7c923d794a0c69e5e4ed48eeae326ce9ae070c896a693264de2882a99583ca52"
3220
+ "sha256": "91c14637adc59dde39f47e51cfd243ddc1796b0a4108491f46aa64e68eea4a0d"
3221
3221
  },
3222
3222
  {
3223
3223
  "path": "modules/hall-ui/public/government.js",
3224
3224
  "mode": "0000644",
3225
- "sha256": "98e28a3a54fddc29481645223e5f15bd295899cdbdc557c20a3b37f56335f978"
3225
+ "sha256": "b7504f63fc1086c4367dbd76da7ac96ac4297a23f74456f90c5aebe5e974e034"
3226
3226
  },
3227
3227
  {
3228
3228
  "path": "modules/hall-ui/public/hall-kit.js",
@@ -3527,7 +3527,7 @@
3527
3527
  {
3528
3528
  "path": "modules/lifecycle/claim-eligibility.js",
3529
3529
  "mode": "0000644",
3530
- "sha256": "14fcf797d47f5a194fd316efc6f670c7beabed0d9102741a324850cdad59a596"
3530
+ "sha256": "0c52ae165d304f0f08ca04c9a288ef7d8ffb07288282dcd7b2d503fced7cd744"
3531
3531
  },
3532
3532
  {
3533
3533
  "path": "modules/lifecycle/conflict-resolve.js",
@@ -3542,7 +3542,7 @@
3542
3542
  {
3543
3543
  "path": "modules/lifecycle/db.js",
3544
3544
  "mode": "0000644",
3545
- "sha256": "4408fc7ed6a7f82e7a55c96b260497e4c36eeaf703d1646cecb28514f1150643"
3545
+ "sha256": "7fa58e9a9c09ba4857d57fe7cc1ed36d827d34f8cc1119ae42dc9dffdd4653b5"
3546
3546
  },
3547
3547
  {
3548
3548
  "path": "modules/lifecycle/done-when.js",
@@ -4257,12 +4257,12 @@
4257
4257
  {
4258
4258
  "path": "package-lock.json",
4259
4259
  "mode": "0000644",
4260
- "sha256": "169da149860df789f1900e847fa5f87394e13bddd9399eddd6e015d8b0290a26"
4260
+ "sha256": "c9866e8f3a03bb27a37058828216a3417a9801d563f2ba225f0789e4c744faf3"
4261
4261
  },
4262
4262
  {
4263
4263
  "path": "package.json",
4264
4264
  "mode": "0000644",
4265
- "sha256": "f42ff0f356c3390d07015cc5c3fdebc8352e62f329f891ea25027739f0178bb2"
4265
+ "sha256": "c320b8445c25728e9a37ef01af92966969f35efdd5758782245b108fc2badef7"
4266
4266
  },
4267
4267
  {
4268
4268
  "path": "public-docs/index.html",
@@ -4887,7 +4887,7 @@
4887
4887
  {
4888
4888
  "path": "scripts/gds/fitness.js",
4889
4889
  "mode": "0000644",
4890
- "sha256": "887cf9daf51448f1ca031b4cc26d0695dd6e7577bb62bba6b619c91ea8e3024b"
4890
+ "sha256": "65648d6d05b73dafc08194e843850b460b738a17b565a69a5234dd817386eea8"
4891
4891
  },
4892
4892
  {
4893
4893
  "path": "scripts/gds/gate-review.js",
@@ -5627,7 +5627,7 @@
5627
5627
  {
5628
5628
  "path": "src/bongos/auth.js",
5629
5629
  "mode": "0000644",
5630
- "sha256": "0d173ce76410884480e5545aad4201da26ff661516e6096de7a2ff2bd2a4015c"
5630
+ "sha256": "8fd6f6ce798ebcde76cd2ac0ccf7129a60555506ce3d2fed818deb1eb331d42b"
5631
5631
  },
5632
5632
  {
5633
5633
  "path": "src/bongos/cascade-dispatch.js",
@@ -5867,7 +5867,7 @@
5867
5867
  {
5868
5868
  "path": "src/module-api.js",
5869
5869
  "mode": "0000644",
5870
- "sha256": "8381e5e0b51bce1387c53e9518d693e74ac93f640d29dee0daa35931cdf2d4f5"
5870
+ "sha256": "ba52655bc052427326c93c2501bf8916161d7b81617132f76c973c82b67ff1e0"
5871
5871
  },
5872
5872
  {
5873
5873
  "path": "src/module-loader/catalog.js",
@@ -6062,7 +6062,7 @@
6062
6062
  {
6063
6063
  "path": "tests/auth_page_gate.mjs",
6064
6064
  "mode": "0000644",
6065
- "sha256": "3d4fd12068c6256ed2b74930fce0fd43ba1ed28f323cd80d4c24a984ca0eeba4"
6065
+ "sha256": "3ed218eada5e36170217ded839fdc80d1cbad4ec71086d9707f00115d6c622d2"
6066
6066
  },
6067
6067
  {
6068
6068
  "path": "tests/auth_resolve_failure.mjs",
@@ -6770,99 +6770,104 @@
6770
6770
  "sha256": "412ca7c0bdc10abc90146b777571bcc7a180e19f0e3d058c6998ac2d33941940"
6771
6771
  },
6772
6772
  {
6773
- "path": "tests/governance_abuse_matrix.mjs",
6773
+ "path": "tests/government_abuse_matrix.mjs",
6774
6774
  "mode": "0000644",
6775
- "sha256": "ddec9f958d49c45e140006d97f91ff9ffdcd0cf49b6041cc5098f6f46ee27597"
6775
+ "sha256": "8f5354cbacf15c9b49500f96b265fe52f5c0d4500a4ec7b41b4819a149782893"
6776
6776
  },
6777
6777
  {
6778
- "path": "tests/governance_catalog.mjs",
6778
+ "path": "tests/government_catalog.mjs",
6779
6779
  "mode": "0000644",
6780
- "sha256": "5611b3eeabcf98b37a6e36f131af2a8d1086b672017df12bb520d2471761bbee"
6780
+ "sha256": "74cfbd482b689df40348af3bdaf050f056e216ff18fdd6add4136d4589b7cd92"
6781
6781
  },
6782
6782
  {
6783
- "path": "tests/governance_claim_eligibility.mjs",
6783
+ "path": "tests/government_claim_eligibility.mjs",
6784
6784
  "mode": "0000644",
6785
- "sha256": "33cb7e88aaf45dac176216c29eb41d2ba5152779e53cb91779d81006f2e6c043"
6785
+ "sha256": "2750f75bc0ef7f5286a2abe1d59e49ff2ea6ea300d3c1760dda31ae8ad74dc61"
6786
6786
  },
6787
6787
  {
6788
- "path": "tests/governance_config.mjs",
6788
+ "path": "tests/government_config.mjs",
6789
6789
  "mode": "0000644",
6790
- "sha256": "c71ac0c7a7b519dac0fed1557f6ce5de52bf29bb830ee940e7cfcb29ce483205"
6790
+ "sha256": "979deef4473243dc86ab13b9284104bce71f6a1ee839acc6c5a6db04770cd62c"
6791
6791
  },
6792
6792
  {
6793
- "path": "tests/governance_fold.mjs",
6793
+ "path": "tests/government_fold.mjs",
6794
6794
  "mode": "0000644",
6795
- "sha256": "9a4feed7e93183e1558ef4c2012c94f1d93786abc2fcca429534d5248b00bebd"
6795
+ "sha256": "5ea27c3008f17597984c72cf504e8e934a76a3ff76323c94b7ccb65e01c84ead"
6796
6796
  },
6797
6797
  {
6798
- "path": "tests/governance_fold_bench.mjs",
6798
+ "path": "tests/government_fold_bench.mjs",
6799
6799
  "mode": "0000644",
6800
- "sha256": "ee9dd3cd6a9965272305cf3ddffab45a860efbe6cf6f0f4209fd458cd1dd5c16"
6800
+ "sha256": "52f32270eff1105ca1164398c4a1ef279657573d9bb50c7588bd03981f2354a9"
6801
6801
  },
6802
6802
  {
6803
- "path": "tests/governance_live_proof.mjs",
6803
+ "path": "tests/government_live_proof.mjs",
6804
6804
  "mode": "0000644",
6805
- "sha256": "29196719cfa414945a2eeec5b4f8fab30bcdc5bc24a7c184e0c5223d108ec67e"
6805
+ "sha256": "af6423ac87819ff344c8a7804c0eda903a3e8c7633d1e4182e7d4f446d30cec0"
6806
6806
  },
6807
6807
  {
6808
- "path": "tests/governance_ownership_scope.mjs",
6808
+ "path": "tests/government_ownership_scope.mjs",
6809
6809
  "mode": "0000644",
6810
- "sha256": "737343cc8955211c15215a155ed67e20047b5082283f33941f1a027dd435d602"
6810
+ "sha256": "ad627c69ede0d79a2f38030d762cbd5bcf630cd6b067441f5763f261b829d1ba"
6811
6811
  },
6812
6812
  {
6813
- "path": "tests/governance_page_gates.mjs",
6813
+ "path": "tests/government_page_gates.mjs",
6814
6814
  "mode": "0000644",
6815
- "sha256": "a1ef5da5f04e3bd82584e618b5be830c470d3c7f319de81d6ed41bddd954c8c0"
6815
+ "sha256": "a0e02201ecc2ab17fc05dd8e20ce106c90dcffd936aa057f4a44cebe01109e4a"
6816
6816
  },
6817
6817
  {
6818
- "path": "tests/governance_parity.mjs",
6818
+ "path": "tests/government_parity.mjs",
6819
6819
  "mode": "0000644",
6820
- "sha256": "12c821eb8c1e051b9de43a9759ea0c5954433b89a88ed4f83699e8cf726979dc"
6820
+ "sha256": "7e1cc047dc75b9574bd64329974f8d1ae59b474d8719fbaae00314c7b2cc88e5"
6821
6821
  },
6822
6822
  {
6823
- "path": "tests/governance_principals.mjs",
6823
+ "path": "tests/government_principals.mjs",
6824
6824
  "mode": "0000644",
6825
- "sha256": "d41e822485d4830e9c5e2154527ca5ebf63bda6281eace6ed7d77f380b74c28b"
6825
+ "sha256": "c2a7d6b6d644b44ca2248fa0247261a4a548e25bd744fa7e029db550231d9da7"
6826
6826
  },
6827
6827
  {
6828
- "path": "tests/governance_protected_surfaces.mjs",
6828
+ "path": "tests/government_protected_surfaces.mjs",
6829
6829
  "mode": "0000644",
6830
- "sha256": "875978b1f2b9a25b9345a6652ff6b7eb48325ec94e11408c45b15e2c0b21fa9a"
6830
+ "sha256": "fd05f72404be0d007222793a6ed3a49904239f8bb354cddab6b052d74288b3b1"
6831
6831
  },
6832
6832
  {
6833
- "path": "tests/governance_require_permission.mjs",
6833
+ "path": "tests/government_rank_sync.mjs",
6834
6834
  "mode": "0000644",
6835
- "sha256": "c546c5d7924031867fa90ebfed8cb9ee5f6906ab199ebb5e837c3ec25920e15c"
6835
+ "sha256": "83462482dff692a3587edecd0e57e0d7638fa08076329a7591c0cb2222d50e47"
6836
6836
  },
6837
6837
  {
6838
- "path": "tests/governance_resolver.mjs",
6838
+ "path": "tests/government_require_permission.mjs",
6839
6839
  "mode": "0000644",
6840
- "sha256": "9153ae65a4f9f4a92fe7ccea791149137c7ec62bed7220bb61421b5c75af8de8"
6840
+ "sha256": "36596b8870d2edc60bd810af5e10fa864d7f35e62e358d2dff58ed85b69922c0"
6841
6841
  },
6842
6842
  {
6843
- "path": "tests/governance_role_sync.mjs",
6843
+ "path": "tests/government_resolver.mjs",
6844
6844
  "mode": "0000644",
6845
- "sha256": "79f837585e89c5f55ad523b4ab2e6e02507c40c1020d387df9fae72557425f29"
6845
+ "sha256": "1e37f1902b59676c1004d4790078ddb39ad6dacd74a5e9ac861982fc33fe2b6d"
6846
6846
  },
6847
6847
  {
6848
- "path": "tests/governance_routes.mjs",
6848
+ "path": "tests/government_routes.mjs",
6849
6849
  "mode": "0000644",
6850
- "sha256": "efc7bfe423db45280ae2ccdfccec2ab1e15e29b604052f1a36b732ac8edf9a73"
6850
+ "sha256": "099954d8dbfa1fd3d503ee1b4825f9a3f10d5ae1e3694c600dd3f06e6a21a127"
6851
6851
  },
6852
6852
  {
6853
- "path": "tests/governance_seed.mjs",
6853
+ "path": "tests/government_seed.mjs",
6854
6854
  "mode": "0000644",
6855
- "sha256": "2543dcac04230360ce311fc13da51134ef1f4e879cb24046457337d2160e50bb"
6855
+ "sha256": "97c9728181f98dcf2daed14a4f87b8acb0fa9fa1d6d55e628eaa06c60c539094"
6856
6856
  },
6857
6857
  {
6858
- "path": "tests/governance_session_scope.mjs",
6858
+ "path": "tests/government_session_scope.mjs",
6859
6859
  "mode": "0000644",
6860
- "sha256": "084d6c0c1af8434a225a0ad9d770a36709debb04938ae70cc7a02e13187da5a4"
6860
+ "sha256": "7aea1db75ada98b9e3756695c743516a3aac5f12a71d654adc383ae886c2568c"
6861
6861
  },
6862
6862
  {
6863
- "path": "tests/governance_vanilla_boot.mjs",
6863
+ "path": "tests/government_vanilla_boot.mjs",
6864
6864
  "mode": "0000644",
6865
- "sha256": "ee9c6fe61ef2b747a7aebd2cc1a000282def4e9c8bd40c181f726c3494c8660c"
6865
+ "sha256": "da3ebb855209f5de20b7d9ec45a9b09a068e251bc644e3090818e5a3f063b356"
6866
+ },
6867
+ {
6868
+ "path": "tests/government_vocabulary.mjs",
6869
+ "mode": "0000644",
6870
+ "sha256": "71bd23242e53b1acd15fddedcb093790a847471c8c55485614d379d29e3065f3"
6866
6871
  },
6867
6872
  {
6868
6873
  "path": "tests/grade_aggregates_unavailable.mjs",
@@ -6937,7 +6942,7 @@
6937
6942
  {
6938
6943
  "path": "tests/hall_page_gate_map.mjs",
6939
6944
  "mode": "0000644",
6940
- "sha256": "9488c26f674a3e76ea3e7d4319f9c20ad392d1b7376dfb60dba18183c2d04e3e"
6945
+ "sha256": "cb23b7a54220c3c53906fed559fb0c8a8e97375aa48dfc3cf64a1af88339e110"
6941
6946
  },
6942
6947
  {
6943
6948
  "path": "tests/hall_palette.mjs",
@@ -1,21 +1,21 @@
1
1
  {
2
- "_note": "Neutral governance starter — the role TEMPLATES a fresh instance inherits (BV1.R96, ADR 0151). Resolved by modules/governance/config.js with the branding precedence: env override -> config/governance.json (instance) -> this file. TEMPLATES AND DEFAULTS ONLY. Live roles, grants, and per-builder assignments are DB rows (governance_roles / governance_role_permissions / governance_builder_roles), resolved server-side per request by resolver.js — putting a live grant here would make config a second source of authority truth and break ADR 0016. The four seeded rank-roles carry label + description only: their grants derive from catalog.js floors and are materialised by governance_002, so config may relabel a seeded role, never re-grant it. A CUSTOM role template may propose a `permissions` array, but a `system: true` key or a key the catalog does not define is stripped fail-closed — a config file is editable by anyone who can write the checkout, so it is not a trust boundary. Carries NO host identity: a vanilla instance boots sane from this file alone (proved by R102). To customise, copy to config/governance.json and edit there.",
3
- "roles": {
2
+ "_note": "Neutral governance starter \u2014 the rank TEMPLATES a fresh instance inherits (BV1.R96, ADR 0151). Resolved by modules/government/config.js with the branding precedence: env override -> config/government.json (instance) -> this file. TEMPLATES AND DEFAULTS ONLY. Live ranks, grants, and per-builder assignments are DB rows (government_ranks / government_rank_permissions / government_builder_ranks), resolved server-side per request by resolver.js \u2014 putting a live grant here would make config a second source of authority truth and break ADR 0016. The four seeded ranks carry label + description only: their grants derive from catalog.js floors and are materialised by governance_002, so config may relabel a seeded rank, never re-grant it. A CUSTOM rank template may propose a `permissions` array, but a `system: true` key or a key the catalog does not define is stripped fail-closed \u2014 a config file is editable by anyone who can write the checkout, so it is not a trust boundary. Carries NO host identity: a vanilla instance boots sane from this file alone (proved by R102). To customise, copy to config/government.json and edit there.",
3
+ "ranks": {
4
4
  "xenos": {
5
5
  "label": "Xenos",
6
- "description": "Seeded rank-role — the sandboxed entry rank. Own-work + public read."
6
+ "description": "Seeded rank \u2014 the sandboxed entry rank. Own-work + public read."
7
7
  },
8
8
  "thetes": {
9
9
  "label": "Thetes",
10
- "description": "Seeded rank-role — graduated newcomer. Adds the general claim queue."
10
+ "description": "Seeded rank \u2014 graduated newcomer. Adds the general claim queue."
11
11
  },
12
12
  "metic": {
13
13
  "label": "Metic",
14
- "description": "Seeded rank-role — the trusted working rank. Adds review/triage/authoring."
14
+ "description": "Seeded rank \u2014 the trusted working rank. Adds review/triage/authoring."
15
15
  },
16
16
  "archon": {
17
17
  "label": "Archon",
18
- "description": "Seeded rank-role — top authority. Adds the admin + system (non-grantable) powers."
18
+ "description": "Seeded rank \u2014 top authority. Adds the admin + system (non-grantable) powers."
19
19
  }
20
20
  }
21
21
  }
@@ -10,6 +10,13 @@
10
10
 
11
11
  ---
12
12
 
13
+
14
+ > **⚠ VOCABULARY AMENDED by [ADR 0174](<redacted>.md) (owner directive, 2026-08-16) — the DECISION below is unchanged.**
15
+ > What this ADR calls *governance* is now the **government**; what it calls *seeded roles* / *rank-roles* are now simply **ranks**. The word *role* is reserved for the three Cloud Bongos crafts — Artist, Ideator, Builder — and appears nowhere on the government side.
16
+ > Concretely: `governance_roles` → `government_ranks`, `governance_builder_roles` → `government_builder_ranks`, `governance_role_permissions` → `government_rank_permissions`, `role_key` → `rank_key`, `governance.manage` → `government.manage`, `page.view.governance` → `page.view.government`, `/governance/roles/*` → `/government/ranks/*`, and `modules/governance/` → `modules/government/`.
17
+ > **The body below is deliberately left in the old vocabulary.** An ADR records what was decided and why at a point in time; rewriting it to match today's words would erase the evidence that the words changed — which is the one thing a reader who hits "rank-role" in an old session log actually needs. Every decision it makes still holds; only the nouns moved. A `fitness.js` check now enforces the new vocabulary, and excludes this file by construction.
18
+
19
+
13
20
  ## Context
14
21
 
15
22
  Authority in Cloud Bongos is a **single rank threshold** today. [ADR 0016](<redacted>.md) put authority in one DB column (`builders.rank`), checked server-side per request with no caching; [ADR 0018](<redacted>.md) / [ADR 0034](<redacted>.md) wired the four live ranks into the ordered tier `xenos (1) < thetes (2) < metic (3) < archon (4)`. Every privileged route calls `requireRank(...allowed)`, which admits a builder whose rank sits **at or above** the lowest-authority rank named (a threshold, [#591](https://cloudbongos.com/builders#/task/591)). That design is sound and is **not** being replaced — it is the substrate this ADR builds *on top of*.
@@ -6,6 +6,13 @@
6
6
  - **Amends:** ADR 0151 §2 (the "four seeded rank-roles are immutable through this API" wall — the GRANT half only)
7
7
  - **Related:** ADR 0016 (trust boundary — server-enforced, uncached, per request), 0043 (git/ssh trust boundary + the rank floor on protected paths), 0157 (the archon→metic delegation of nineteen operational keys)
8
8
 
9
+
10
+ > **⚠ VOCABULARY AMENDED by [ADR 0174](<redacted>.md) (owner directive, 2026-08-16) — the DECISIONS below are unchanged.**
11
+ > What this ADR calls *governance* is now the **government**; what it calls *seeded roles* / *rank-roles* are now simply **ranks**. The word *role* is reserved for the three Cloud Bongos crafts — Artist, Ideator, Builder — and appears nowhere on the government side.
12
+ > Concretely: `governance_roles` → `government_ranks`, `governance_builder_roles` → `government_builder_ranks`, `governance_role_permissions` → `government_rank_permissions`, `role_key` → `rank_key`, `governance.manage` → `government.manage`, `page.view.governance` → `page.view.government`, `/governance/roles/*` → `/government/ranks/*`, and `modules/governance/` → `modules/government/`.
13
+ > **The body below is deliberately left in the old vocabulary.** An ADR records what was decided and why at a point in time; rewriting it to match today's words would erase the evidence that the words changed — which is the one thing a reader who hits "rank-role" in an old session log actually needs. Every decision it makes still holds; only the nouns moved. A `fitness.js` check now enforces the new vocabulary, and excludes this file by construction.
14
+
15
+
9
16
  ## Context
10
17
 
11
18
  The governance tab (BV1.R110/R111) let an Archon build custom roles and toggle their operational permissions, but rendered all four **rank roles** — Newcomer/`xenos`, Contributor/`thetes`, Trusted/`metic`, Owner/`archon` — read-only. The owner asked why, and then asked for them to be editable.
@@ -13,7 +20,7 @@ The governance tab (BV1.R110/R111) let an Archon build custom roles and toggle t
13
20
  Three facts made this cheaper and narrower than the read-only rendering suggested:
14
21
 
15
22
  1. **The rank roles' grants were already ordinary rows.** `<redacted>.sql` writes them into `governance_role_permissions` exactly like a custom role's. The immutability was a route-level refusal (`loadMutableRole` → `seeded_role_immutable`) plus a disabled toggle — policy, not structure. Nothing had to be remodelled to make them editable.
16
- 2. **The `system` flag was carrying two different meanings.** ADR 0151 used one boolean for "trust-boundary power," but the twelve `system:true` keys split cleanly in two. Seven are **in-app**: a real route reads them through `requirePermission`, so a grant row genuinely confers them (`builder.rank.set`, `version.close`, `task.confirm.grade_bypass`, `dependency.cross_tier.manage`, `goal.scope.manage`, `governance.manage`, `gate_approval.decide`). Three are **substrate**: `deploy.push_main`, `path.protected.modify`, `infra.ssh` are enforced entirely outside the app by the pre-push hook, `main-audit.js`, the grader pre-pass and credential placement (ADR 0043) — `tests/governance_abuse_matrix.mjs` V10 asserts *no route consumes them* at all. Two are **principal** keys, held by an exact `builders.system_role` identity and by no role ever.
23
+ 2. **The `system` flag was carrying two different meanings.** ADR 0151 used one boolean for "trust-boundary power," but the twelve `system:true` keys split cleanly in two. Seven are **in-app**: a real route reads them through `requirePermission`, so a grant row genuinely confers them (`builder.rank.set`, `version.close`, `task.confirm.grade_bypass`, `dependency.cross_tier.manage`, `goal.scope.manage`, `governance.manage`, `gate_approval.decide`). Three are **substrate**: `deploy.push_main`, `path.protected.modify`, `infra.ssh` are enforced entirely outside the app by the pre-push hook, `main-audit.js`, the grader pre-pass and credential placement (ADR 0043) — `tests/government_abuse_matrix.mjs` V10 asserts *no route consumes them* at all. Two are **principal** keys, held by an exact `builders.system_role` identity and by no role ever.
17
24
  3. **A grant row for a substrate key is inert.** It resolves honestly and admits nothing (abuse matrix V8/V10/V11). So the interesting question was never "is it dangerous to allow" but "would allowing it be *true*" — and it would not be.
18
25
 
19
26
  The owner was presented with the choice and chose to delegate the in-app Archon powers as well as the operational ones, having been told the escalation consequence explicitly.
@@ -220,7 +220,7 @@ This keeps the decision history honest and traceable.
220
220
  | 0146 | [Configurable reward mode — an instance chooses whether a shipped task pays BOTH reward streams or ONLY the cost-plus one ([task 1002270](https://cloudbongos.com/builders#/task/1002270), goal 1000037; follow-up to [ADR 0120](<redacted>.md)). A shipped task pays two streams onto one balance (the [ADR 0054](<redacted>.md) "two conventions, one ledger" tension): the per-task author ESTIMATE (`credits_reward` × kind multiplier — unitless, [ADR 0023](<redacted>.md)) AND the cost-plus SESSION reward (`round(true_cost_usd × 1.20)`, 1 credit = $1 — ADR 0054). New `branding.reward.mode`: `"cost-plus-and-estimate"` (DEFAULT — pay both, exactly today's behavior; every existing instance unchanged on upgrade) or `"cost-plus-only"` (the cost-plus reward is the SOLE equity reward; the per-task estimate PAYOUT is withheld and its idea-promotion slice cascades to 0). Resolved by a pure `rewardPolicy()`; gated in the single per-task credit writer (`insertMultipliedConfirmCredit`) — entirely inside the economy module, ZERO lifecycle changes. `credits_reward` still rides the task row for display + the no-zero-reward claim gate; only the payout is suppressed. Unknown mode → default (a typo can't silently zero rewards). Cloud Bongos selects `cost-plus-only`; achievements + the net-negative +1 bonus are out of scope. Backward-compatible + reversible — no clawback, no migration.](<redacted><redacted>.md) | GDS / economy |
221
221
  | 0149 | [`bongos dev` — a one-command LOCAL launcher for a standalone instance repo (owner ask, 2026-07-19: "we need a better option to stand up the local host"). A freshly-created project's `config/branding.json` points at `http://localhost:<port>` — configured to run on the owner's machine — but the platform shipped no command to START it there; `bongos onboard` provisions a CLOUD server and Docker serves a vanilla brand on `:3000`. Standing it up by hand was a six-part assembly (Postgres → createdb → migrate → PORT/PGDATABASE/PGHOST/OAuth env → server → login) with three silent mismatches: the server reads PORT from env not branding (platform-server.js:44); the pool DB name collapses to the OS user while migrate.sh defaults to `example` (pool.js:47 vs migrate.sh:52) unless PGDATABASE is set for BOTH; and node-pg defaults to the Linux peer socket `/var/run/postgresql` (pool.js:46), absent under Homebrew on a Mac. `bongos dev` does the whole thing idempotently from one source of truth (branding): ensures Postgres, createdb, migrate (`MEDUSA_GDS_ONLY=1`), starts the server on the branding port, and signs in. The background server is MANAGED (pid/log per instance) with `bongos dev stop`/`status` — the fix for the orphaned-server accident (a stale `:3005` answering a new project's login). Pure resolution + process mgmt in `scripts/gds/dev-lib.js` (unit-tested `tests/dev_lib.mjs`); orchestration in `scripts/gds/dev.js`. Alternatives rejected: cloud dev box (needs hosting + cost — kept for remote work), Docker (vanilla brand/wrong port — kept for Windows), recipe-only (leaves the six steps). Not bundled into the standalone on-ramp binary (needs a real checkout).](<redacted>.md) | Cloud Bongos / dev experience |
222
222
  | 0150 | [Box first-boot bring-up on vendored instances — resolve `infra/` from the instance root + fail loud on empty user-data (spike BV1.R97, [task 1002385](https://cloudbongos.com/builders#/task/1002385); C2 of goals 1000051/1000052, "make cloudbongos boxes stop coming up bare"). Root cause: `box.js` sets `REPO_ROOT` two dirs up from itself, which on a VENDORED instance is the `@bongos/core` package — but the R89 packaging split kept `infra/` (the DO cloud-init template + inlined `box-source-fetch.sh`/cloudflared/ttyd/heartbeat scripts) as INSTANCE content, not in the core publish-manifest. So `readCloudInit` reads a missing template, its `try/catch` returns `null`, and the caller's only guard (`0 > 64KiB`) passes → the box is created with EMPTY user-data and boots bare Ubuntu (no clone, no toolchain, no terminal); `fileGzB64` is likewise fail-soft (warns, returns `''`) so a partial `infra/` half-wires. Live re-confirmed 2026-07-19: instance-root `infra/` present, vendored-core `infra/` gone (the [ADR 0144](<redacted>.md) node_modules workaround wiped by a reinstall), fleet idle so the bug is latent-but-live (next provision boots bare). Fix (R98, [task 1002386](https://cloudbongos.com/builders#/task/1002386)): a `resolveBoxInfraDir()` locating `infra/` via [ADR 0108](<redacted>.md)'s `resolveInstanceRootExplicit()` (cloudbongos `bongos.config.json` = `{"instanceRoot":"."}`) + an env override + a walk-up-out-of-`node_modules` fallback, AND fail-loud backstops (throw on missing template; abort provision on empty user-data). R99 ([task 1002387](https://cloudbongos.com/builders#/task/1002387)) then ensures the toolchain builds on the box. Reinstall-proof + portable; core-only, no migration/doorway change.](<redacted>.md) | GDS / dev boxes |
223
- | 0151 | [Governance: **permissions are the atom, ranks become seeded roles** — the foundation of the BONGOS-V1 Governance goal (1000030), spike BV1.R90 ([task 1001838](https://cloudbongos.com/builders#/task/1001838)); settles the model in an ADR before R93–R114 build. Authority stops being an all-or-nothing rank threshold ([ADR 0016](<redacted>.md)/0018/0034) and becomes granular **permissions** (code constants that map 1:1 to real routes/surfaces — a permission no route consumes doesn't exist), bundled into assignable **roles**; the four live ranks become four seeded roles whose grants reproduce today's thresholds EXACTLY (the compat seed — cumulative nested supersets, so the resolver's UNION preserves the at-or-above threshold), and `builders.rank` stays as the identity/graduation column. A per-request **uncached** `resolveBuilderPermissions()` (kernel port, preserving ADR 0016's instant-demotion) + a `requirePermission()` gate that coexists with `requireRank` via the seed → gates migrate route-by-route, no flag day. The **complete authority model** (C3) represents four axes as first-class types, not rank special-cases: rank-seeded roles, machine **principals** (`system_role`=bfg/discord_bot, exact-identity gate, never UI-grantable), **session-scopes** (box tokens, deny-by-default allow-list intersected with the builder's roles), and **ownership-scoped** perms (`X.manage.own` ≠ `.any`; goal owner/manager per [ADR 0106](<redacted>.md)). The safety keystone (C6): every permission carries a **`system` flag** — `system:true` (deploy, protected-path, rank-set, version-close, grade-bypass, cross-tier edges) is **non-grantable** and LOCKED in the tab, so no configurable role can hand out the crown jewels; and the today-hardcoded `PROTECTED_GLOBS`/`EXPECTED_RANKS` map becomes a **governance-owned protected-surface registry** that the OUT-OF-BAND substrate (pre-push hook, grader pre-pass, `main-audit.js`, gate-review — [ADR 0043](<redacted>.md)) READS but never moves in-process: **policy owns / substrate enforces** — the tab can re-map the floor but a forced `system` grant still can't deploy (abuse-matrix + live-demo proofs, R112/R114). Capability in **core** (`modules/governance/`, default:true); role templates are per-instance **config** (`config/governance.json` over `config/governance.neutral.json` over env, mirroring `src/branding.js`), live assignments in the DB. Collapses the ~6 duplicated numeric rank-tier maps (the Builder-25-incident drift class) behind the resolver. Zero day-one behavior change (parity test R103); one deliberate fail-closed divergence (unwired divine ranks map to no role instead of latently inheriting Archon). Includes the full enumerated permission catalog (every key + `system` flag) grounded in the 2026-07-24 authority sweep. No new recurring cost.](<redacted>.md) | governance / permissions / Cloud Bongos |
223
+ | 0151 | [Governance: **permissions are the atom, ranks become seeded roles** — the foundation of the BONGOS-V1 Governance goal (1000030), spike BV1.R90 ([task 1001838](https://cloudbongos.com/builders#/task/1001838)); settles the model in an ADR before R93–R114 build. Authority stops being an all-or-nothing rank threshold ([ADR 0016](<redacted>.md)/0018/0034) and becomes granular **permissions** (code constants that map 1:1 to real routes/surfaces — a permission no route consumes doesn't exist), bundled into assignable **roles**; the four live ranks become four seeded roles whose grants reproduce today's thresholds EXACTLY (the compat seed — cumulative nested supersets, so the resolver's UNION preserves the at-or-above threshold), and `builders.rank` stays as the identity/graduation column. A per-request **uncached** `resolveBuilderPermissions()` (kernel port, preserving ADR 0016's instant-demotion) + a `requirePermission()` gate that coexists with `requireRank` via the seed → gates migrate route-by-route, no flag day. The **complete authority model** (C3) represents four axes as first-class types, not rank special-cases: rank-seeded roles, machine **principals** (`system_role`=bfg/discord_bot, exact-identity gate, never UI-grantable), **session-scopes** (box tokens, deny-by-default allow-list intersected with the builder's roles), and **ownership-scoped** perms (`X.manage.own` ≠ `.any`; goal owner/manager per [ADR 0106](<redacted>.md)). The safety keystone (C6): every permission carries a **`system` flag** — `system:true` (deploy, protected-path, rank-set, version-close, grade-bypass, cross-tier edges) is **non-grantable** and LOCKED in the tab, so no configurable role can hand out the crown jewels; and the today-hardcoded `PROTECTED_GLOBS`/`EXPECTED_RANKS` map becomes a **governance-owned protected-surface registry** that the OUT-OF-BAND substrate (pre-push hook, grader pre-pass, `main-audit.js`, gate-review — [ADR 0043](<redacted>.md)) READS but never moves in-process: **policy owns / substrate enforces** — the tab can re-map the floor but a forced `system` grant still can't deploy (abuse-matrix + live-demo proofs, R112/R114). Capability in **core** (`modules/governance/`, default:true); role templates are per-instance **config** (`config/governance.json` over `config/governance.neutral.json` over env, mirroring `src/branding.js`), live assignments in the DB. Collapses the ~6 duplicated numeric rank-tier maps (the Builder-25-incident drift class) behind the resolver. Zero day-one behavior change (parity test R103); one deliberate fail-closed divergence (unwired divine ranks map to no role instead of latently inheriting Archon). Includes the full enumerated permission catalog (every key + `system` flag) grounded in the 2026-07-24 authority sweep. No new recurring cost. **Vocabulary amended by ADR 0174 (2026-08-16): governance→government, seeded roles→ranks; the decisions are unchanged.**](<redacted>.md) | governance / permissions / Cloud Bongos |
224
224
  | 0152 | [The landing gate is served by the **core app**, not by the front proxy — the cutover step of the landing migration ([task 1002411](https://example.com/builders#/task/1002411), L05 of goal 1000035). The reference instance's orb-gate front page was `file_server`'d by Caddy straight out of a checkout of an UNRELATED product repo (`root * <checkout>/brand/cloud-bongos`), so the landing had two sources of truth, no deploy path of its own, and a cross-product coupling the core could not express. [L01](https://example.com/builders#/task/1002407) had already ported the bundle into the core as `public-landing/` and [L02](https://example.com/builders#/task/1002408) had already taught `platform-server.js` to serve it (`/` -> 302 `/gate/`, `/gate/` serves the index raw, `express.static` covers the assets) — so by the time L05 came up, BOTH halves of its original plan ("give the landing (a) its own Caddy config and (b) its own deploy script") had dissolved. **Decision:** the app owns the landing end to end; the proxy drops `root` + `file_server` and keeps exactly three jobs on that surface — TLS, an optional pre-launch `basic_auth` lock, and the `@hidden` guard that keeps `gate/README.md` unreachable. No separate Caddy config to write (the resulting block IS the generic pure-proxy shape `provision.js`'s `caddyBlock()` already emits per instance, [ADR 0111](<redacted>.md) §4; host-specific hostnames/certs stay on the host per [ADR 0062](<redacted>.md) §7) and no separate deploy script to write (the landing ships INSIDE the pinned core package, so it rides the instance's existing pull-deploy — one artifact, one version, one path). Keeps `redir / /gate/ 302` because Caddy orders `redir` before `basic_auth`, so "/" behaves identically before and after, and the app issues the same 302 once the lock is lifted. Cost accepted: the landing now sits in the app's request path (a dead app = a dead front page — but the gate's whole purpose is to reach the app), and a landing tweak now needs a core release. Verified on the live instance: identical status codes across the apex and both vanity doors before/after, relative redirects (no origin leak), and a **severance test** — with the foreign repo's landing folder moved aside entirely the site still served the byte-identical gate, proving the dependency is cut rather than merely unused. Retiring the foreign copy is L06 ([task 1002412](https://example.com/builders#/task/1002412)).](<redacted>.md) | platform serving / instance infra |
225
225
  | 0152 | [**Metic gains task abandonment, paired with an un-abandon at the same rank** (owner directive 2026-07-27: "Metics should also be able to abandon tasks"; [task 1002476](https://cloudbongos.com/builders#/task/1002476)). [ADR 0090](<redacted>.md) moved task authoring (create/edit/promote/deps/criteria) down to the trusted working rank but kept `POST /tasks/:id/abandon` Archon-only as "terminal scope removal" — so the rank that runs idea-triage, seeds the tasks, and shapes them still had to hand every duplicate/moot/superseded chore back to the owner to retire. That hand-back is janitorial, not adjudication. The real hazard was never the grant: abandon was **one-way through the API** (`/promote` took only backlog/blocked, `PATCH` refuses `status`), so a mis-retire needed hand-SQL on prod, and an abandoned task is invisible in every claimable list and every version rollup (migration 017 excludes it from `version_progress`) — nobody notices until the work silently doesn't happen. So the gate moves to `requireRank('metic','archon')` **and** `/promote` gains a third source state, `abandoned → backlog` (never straight to ready — a retired task re-enters un-workable and takes a second deliberate promote), backed by `db.restoreTask`, the mirror of `abandonTask`, which clears the `'Abandoned: <reason>'` stamp and only that. Unchanged: the shipped-task and active-claim refusals, idempotency, and the `audit_log` record of who retired what and who brought it back. The `EXPECTED_RANKS` lifecycle pin moves in lockstep (a *further* downgrade stays a hard CI fail); under [ADR 0151](<redacted>.md) the `task.abandon` floor moves archon→metic, landing as `governance_003` because the compat seed is run-once — purely additive, and the drift guard now compares the **union** of grant migrations to the catalog and fails loudly on a future revocation.](<redacted>.md) | GDS / permissions |
226
226
  | 0153 | [**Sequential chain execution — one kickoff walks a dependency chain** ([task 1002484](https://cloudbongos.com/builders#/task/1002484)). [ADR 0015](<redacted>.md) made `dependencies[]` load-bearing and auto-promotes a task's dependents `backlog`→`ready` on ship — but nothing *picks the unblocked task up*, so on the live instance **146 of 303 open tasks sit behind a predecessor** and a 24-task planning seed needed 24 separate human kickoffs. The only "sequential" affordance was a clipboard prompt on the Tasks board (`<redacted>`), which is text rather than execution and cannot even select the gated successors, because they are still `backlog`. Requested independently by two builders (ideas 1000461, 1000398). **Decision:** a chain runner with **no schema change** (the polymorphic `dependencies` table + `task_is_fully_unblocked` + the promote-on-ship trigger already encode the order; a `chain_id`/queue column would be a second, drift-prone source of truth) and **no new claim guard** (one-active-claim-per-session is keyed on the *working tree*, so ship-before-next-claim is already the enforced shape — and batch-claiming a chain is impossible anyway, since successors fail `DEPS_NOT_SHIPPED` until their predecessor ships; the ship IS what unblocks the next step). Deterministic plumbing (`scripts/gds/sequence.js` — scope, topological order, halt matrix, all read off the task row) is split from judgement (`.claude/skills/builder-sequence/`, which defers to `/builder-claim` + `/dev` + `/builder-ship`). **Halt, do not skip** (owner decision): on `needs_migration`, `security_sensitive`, `protected_path`, `rank_floor`, `thin_spec`, `judgement_kind`, `not_claimable`, `deps_unmet`, `in_flight`, or `cycle`, the runner stops and reports with the task still claimed — because in a dependency graph a skipped task is a *predecessor*, so skipping strands everything behind it while the run keeps posting apparent progress. Not built: chains as a priced claimable unit on the board (idea 1000398), which is additive.](<redacted>.md) | GDS / methodology |
@@ -244,7 +244,7 @@ This keeps the decision history honest and traceable.
244
244
  | 0167 | [**The /create gate trust link defaults to the AGPL-3.0 license text, not the npm package page** ([task 1002705](https://cloudbongos.com/builders#/task/1002705); gap 1 of the project-creation audit). The gate's "open source" link pointed at a nonexistent repo (404); the task brief's suggested default — the npm package page — is ALSO dead for the gate's actual audience (signed-out visitors): `@cloudbongos/core` and `@bongos/core` both 404 anonymously (private scopes, ADR 0134), and the ADR 0099 public mirror stays dormant until ~2026-11. The license text is the one live, instance-neutral artifact behind the claim today. The browsable-code upgrade is the owner's filed choice (idea 1000700): public repo now (forfeits the ADR 0065 §4 redaction window) / public npm package / wait for the mirror. Rejected: the npm link (verified dead), flipping the repo public (not a builder's call), plain unlinked text (less information, same cost).](<redacted>.md) | public landing / governance |
245
245
  | 0169 | [**`bongos serve`: the `bongos dev` boot path, on a real host** ([task 1002398](https://cloudbongos.com/builders#/task/1002398), goal 1000052). [ADR 0149](<redacted>.md) gave an owner one command to stand an instance up on their laptop; "now put it on a server" had no equally good answer — Docker serves the *vanilla* brand on `:3000`, `bongos onboard` provisions a whole droplet through the control plane, and [`instance-deploy.md`](../recipes/instance-deploy.md) left the systemd unit as a hand-written prose step. The six steps (deps → Postgres → createdb → migrate → env → server → health) were already right for a host; only four *decisions inside them* were laptop-shaped. So: a `--server` **mode** on the same script (`bongos serve`), never a second boot path, so the two can't drift. (1) **Supervision** — a systemd unit (`Restart=always`, `WantedBy=multi-user.target`) instead of a pid file that dies on reboot, falling back to the pid-managed process where systemd is absent rather than refusing. (2) **Bind address, derived from the origin** — `https://…` means a proxy terminates TLS, so bind `127.0.0.1`; plain `http://` on a public host means nothing is in front, so bind `0.0.0.0`. The common misconfiguration (app publicly reachable on its raw port behind a proxy) becomes impossible by default. (3) **Peer-auth bootstrap** — a fresh `apt-get install postgresql` cluster has only the `postgres` role, so a deploy user's `createdb` fails with `role "deploy" does not exist`; that reads like a broken install and is really an unbootstrapped cluster, so we create the login role as the superuser. (4) **Health means the PUBLIC origin** — the loopback probe proves the app; DNS/proxy/TLS are where a host actually fails, so it probes the advertised origin too and names the missing layer (advisory — DNS may legitimately not be wired). Secrets go to a root-owned `0600` `EnvironmentFile`, never `Environment=` (`systemctl show` leaks those, and the laptop path's `buildEnv()` spreads the caller's whole shell). Every decision is a pure injectable in `dev-lib.js`, proved in `tests/dev_lib.mjs` with no host. Rejected: a separate `deploy.sh` (drift — the point is the *same* six steps), Docker-on-the-host (makes brand+port a compose override), always binding `0.0.0.0` (exposes the raw port), refusing without systemd (breaks containers/BSD).](<redacted>.md) | onboarding / deploy |
246
246
  | 0173 | [**The legacy multi-ship reward shortfall is NOT backfilled — it closes as a one-time transition cost** ([task 1002520](https://cloudbongos.com/builders#/task/1002520), goal 1000037). Before `core_196` the cost-plus reward booked ONE row per session, so a multi-ship session (the normal shape — ship, new worktree, claim again) was paid at its first ship's level and never topped up; `core_196`'s watermark accounting `(session_id, reward_basis)` fixed that forward and deferred the retroactive half to an "owner-signed-off backfill, tracked separately". This is that decision, and it is **decline**. Measured live 2026-08-16, both of the task's open questions answered: (1) the task's own premise is wrong — `reward_basis = 0` is the column's DEFAULT, so it means "booked before top-ups existed", not "underpaid", and **over-selects by ~60%** (478 legacy sessions, but 287 are single-ship and were paid in full; only 191 are candidates); (2) re-pricing each candidate's stored `session_records.model_usage` at `round(true_cost_usd × 1.20)` gives **7,697 credits owed** across 119 sessions — example-owner 5,296 (69%), jaxri 2,319, scootermack 82 — with **72 candidates unreconstructable** (empty `model_usage`) and 16 already OVER-paid by 1,131 that nobody proposed clawing back. Declined because it mirrors the ADR 0146 clawback's own logic (the accounting changed; neither side of the boundary reopens), because paying only the 119 that happened to leave a server-side trace is arbitrary against the 38% that did not, and because correcting shortfalls while ignoring overpayment is a policy choice the owner declined to adopt. Consequence recorded plainly: three builders stay permanently short. **Does NOT close task 1002448** — that is the Windows `encodeProjectPath` population, never *recorded* rather than paid at a stale watermark, still recoverable and still owed.](<redacted>.md) | economy / rewards |
247
- | 0172 | [**The sub-Archon rank roles are owner-editable; the Archon role is not; the substrate keys are non-grantable to everything** ([task 1002961](https://cloudbongos.com/builders#/task/1002961), goal 1000030). Amends ADR 0151 §2's "the four seeded rank-roles are immutable through this API" wall — the GRANT half only. Their grants were always ordinary `governance_role_permissions` rows (the `governance_002` seed writes them); the read-only rendering was route policy, not structure. Three walls now, where there was one: the **Archon** rank-role stays frozen as the LOCKOUT GUARD (it is the only role holding `governance.manage` by seed, so freezing it means no click sequence can revoke the permission needed to reach this tab); the three **sub-Archon** rank-roles become grant-editable, the seven **in-app** Archon powers included (owner's explicit choice, escalation consequence stated); and `substrate` becomes a declared catalog axis — `deploy.push_main`/`path.protected.modify`/`infra.ssh` are non-grantable to EVERY role forever, because ADR 0043 enforces them out of band, so a grant row confers nothing and the toggle would be the UI lying. Grantability goes per-role (`isGrantableTo(key, role)`); `isGrantable(key)` survives as the narrow custom-role question config.js strips against. **Custom roles are deliberately NOT widened** — a rank-role moves only by a rank write, a custom role is assignable by anyone holding `governance.manage`. Assignment stays rank-derived (R95b) untouched. Adds `POST /governance/roles/:roleKey/reset` (one transaction, filtered through `isGrantableTo`, refused on a custom role) because a drifted ~60-row rank has no way back by clicking. Rejected: substrate keys behind a warning (a toggle that succeeds and delegates nothing), an editable Archon role behind a confirm (a confirm is not a guard; real recovery is hand-written SQL on the droplet).](<redacted>.md) | governance / permissions |
247
+ | 0172 | [**The sub-Archon rank roles are owner-editable; the Archon role is not; the substrate keys are non-grantable to everything** ([task 1002961](https://cloudbongos.com/builders#/task/1002961), goal 1000030). Amends ADR 0151 §2's "the four seeded rank-roles are immutable through this API" wall — the GRANT half only. Their grants were always ordinary `governance_role_permissions` rows (the `governance_002` seed writes them); the read-only rendering was route policy, not structure. Three walls now, where there was one: the **Archon** rank-role stays frozen as the LOCKOUT GUARD (it is the only role holding `governance.manage` by seed, so freezing it means no click sequence can revoke the permission needed to reach this tab); the three **sub-Archon** rank-roles become grant-editable, the seven **in-app** Archon powers included (owner's explicit choice, escalation consequence stated); and `substrate` becomes a declared catalog axis — `deploy.push_main`/`path.protected.modify`/`infra.ssh` are non-grantable to EVERY role forever, because ADR 0043 enforces them out of band, so a grant row confers nothing and the toggle would be the UI lying. Grantability goes per-role (`isGrantableTo(key, role)`); `isGrantable(key)` survives as the narrow custom-role question config.js strips against. **Custom roles are deliberately NOT widened** — a rank-role moves only by a rank write, a custom role is assignable by anyone holding `governance.manage`. Assignment stays rank-derived (R95b) untouched. Adds `POST /governance/roles/:roleKey/reset` (one transaction, filtered through `isGrantableTo`, refused on a custom role) because a drifted ~60-row rank has no way back by clicking. Rejected: substrate keys behind a warning (a toggle that succeeds and delegates nothing), an editable Archon role behind a confirm (a confirm is not a guard; real recovery is hand-written SQL on the droplet). **Vocabulary amended by ADR 0174 (2026-08-16): governance→government, seeded roles→ranks; the decisions are unchanged.**](<redacted>.md) | governance / permissions |
248
248
  | 0171 | [**Profile ↔ cross-project rollup: the join runs in-process on the hub; consent is fail-closed account state; the hide flag lives on the account, enforced in the read path** ([task 1002277](https://cloudbongos.com/builders#/task/1002277), R01 of goal 1000045). The C1 cross-project profile reads the platform-identity rollup through the module's **declared-but-never-registered `platform-identity.hub` port**: the module registers a real provider and core `GET /builders/:id/profile` `resolveOptional`s it beside `reward` — zero network, `null` (clean degrade) on every non-hub instance. Federated instances **link out** instead of inlining (amends profile-page spec Decision 1: an instance-side copy is either stale-on-hide or a per-view hub call). Consent: `profile_state` on `platform_identity_accounts`, **fail-closed** — `active` iff touched by a hub-session `/sso/authorize` (device-poll/check-in create `provisional`; backfill = all provisional, lazy upgrade; no core-`builders` join — type-unsafe vs `system:*` ids and a module-migration boundary breach), so the P03 owner decision can only ever widen, never claw back. The C2 hide flag is `hide_stats` on the account (NOT per-instance `behavior_prefs`), enforced **inside** the module's read functions — `listScoutingRollup` itself gains the `active AND NOT hide_stats` predicate so the live Metic-floor `/people`+`/scouting` surfaces honor it by construction. Hub profile responses go `no-store` (hide must beat the 60s cache). Publishing is gated on hardening the self-reported rollup (membership-row requirement, rank-vocab validation, disciplines caps, check-in→rollup sequencing). Found + filed: the `LATERAL unnest` fan-out inflating rollup sums (task 1002911), the unreserved `u` slug (task 1002912), the missing platform T&C artifact (task 1002913), criterion amendments (task 1002914). Rejected: instance→hub per-view pull (always-on dependency), hub→instance mirroring (stale-on-hide), storing the flag in builder-settings, backfilling `active` from hub `builders` rows.](<redacted>.md) | platform identity / profiles / privacy |
249
249
  | 0170 | [**The featured projection tells time honestly: `created_at` in, `updated_at` out, owner from the project's own archon** ([task 1002778](https://cloudbongos.com/builders#/task/1002778), goal 1000061). The hub card's metadata pass added `created_at` to the public `/projects/featured` projection, labelled **Listed** — it is the moment the hub catalogued the row, never when the project began, and the C6 card test bans the word "Created". Two recorded deviations: (1) the task brief said `updated_at` was ready to add, but the column is bumped by every client re-registration AND the Archon's feature toggle, so as a public "last updated" it would report curation noise as project activity — it may sort, never project, and the test pins the SELECT list itself (`SELECT *` banned: the route is CORS-open rank:public and a star would leak `owner_github_id`/`status`). (2) The owner fact reads the project's OWN leaderboard archon row (login + avatar, type-checked and capped) from the payload project-stats already fetches — zero extra requests, the 2-fetch pin intact, the advisory `owner_github_id` column still unread per the design contract. Multi-archon: top-credits archon is named; a fallen-off-the-page archon renders as no owner shown, never a wrong one. Rejected: projecting `updated_at` as asked (it lies), reading `owner_github_id` (advisory, contract-banned), a third per-origin fetch for activity recency (moves the test pin for a fact nobody asked for yet).](<redacted>.md) | platform identity / public surface |
250
250
  | 0174 | [**Governance is renamed government, its positions are ranks, and "role" is reserved for the three crafts** ([task 1003002](https://cloudbongos.com/builders#/task/1003002), R01 of goal 1000068). Owner directive, 2026-08-16. The word **role** named two unrelated things: the permission system's ladder tiers (`governance_roles`, the "rank-roles") and the three crafts (`tasks.discipline` = engineer/artist/ideator) — and goal 1000066 was actively claiming it for the crafts (`three-roles-only`, `users-hold-roles`), putting the two on a collision course. Resolved at full depth rather than as a label pass, because a labels-only fix leaves the UI and the code disagreeing, which is the condition that produced the collision. `modules/governance/` → `modules/government/`; the kernel module key, the config files, `/api/bongos/governance/*` → `/government/*`, and the permission keys `governance.manage` → `government.manage` (~50 sites) + `page.view.governance` → `page.view.government`. **The entity IS the rank — no second noun**: `governance_roles` → `government_ranks`, `role_key` → `rank_key`, `rank-roles.js` → `ranks.js`; "position" stays prose-only, since introducing it as a code term would recreate the qualifier problem "rank-role" already demonstrates. The cross-module kernel port `governance.roleSync` → `government.rankSync` must land atomically across its provider and both consumers (`modules/lifecycle/db.js`, `src/bongos/db.js`) because it is a transaction participant on the rank-write path. Hand-composed bundles stay in the one table as **custom ranks** — the owner's call over splitting them into a separate "appointments" concept, with the objection recorded (a custom bundle is not a ladder position, and ADR 0172 §4 already treats the two kinds as different). Enforced by a `fitness.js` rule, allowlist shipped with reasons. **Discord's server roles keep the word** — that noun belongs to Discord's API. Amends ADR 0151 + ADR 0172 (the editable-rank-roles one) in **vocabulary only**; ladder slugs, `builders.rank`, `requireRank`, and every floor/grant/assignment semantic are untouched. Rejected: renaming the ladder slugs (turns a bounded rename into a trust-boundary migration), a permanent compat shim (both vocabularies stay correct forever).](<redacted>.md) | government / permissions |