@bongos/core 1.19.882 → 1.19.883
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 +52 -52
- package/clients/bongos-client/index.d.ts +2 -2
- package/docs/adr/0309-durable-module-enablement-db-override.md +116 -0
- package/docs/adr/README.md +1 -0
- package/docs/api/openapi.json +6 -0
- package/docs/copy-inventory.md +24 -23
- package/docs/copy-registry.json +34 -25
- package/docs/file-map.md +1 -2
- package/docs/module-api-changelog.md +3 -1
- package/docs/recipes/bongos-cli-release.md +1 -1
- package/docs/recipes/managed-settings-remote-control.md +1 -1
- package/migrations/core_248_module_enablement_overrides.sql +50 -0
- package/modules/dev-box/app/README.md +4 -3
- package/modules/hall-ui/public/collab-lib.js +33 -1
- package/modules/hall-ui/public/collab.css +33 -4
- package/modules/hall-ui/public/collab.html +9 -2
- package/modules/hall-ui/public/collab.js +68 -15
- package/modules/hall-ui/public/dom-utils.js +23 -1
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/scripts/hall-preview/server.js +38 -1
- package/src/bongos/module-overrides.js +117 -0
- package/src/bongos/routes/modules.js +56 -23
- package/src/module-api.js +1 -1
- package/src/modules.js +120 -14
- package/src/platform-server.js +47 -5
- package/tests/box_sweep_docs.mjs +7 -3
- package/tests/collab_page.mjs +136 -1
- package/tests/modules.mjs +110 -0
- package/tests/modules_route_wiring.mjs +103 -0
- package/docs/recipes/builder-box-lifecycle.md +0 -181
- package/docs/recipes/devbox-app-release.md +0 -103
- package/docs/recipes/devbox-app-windows-test.md +0 -128
- package/docs/recipes/work-on-a-task-from-your-dev-box.md +0 -122
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.
|
|
6
|
-
"core_contract": "1.19.
|
|
7
|
-
"source_commit": "
|
|
5
|
+
"core_version": "1.19.883",
|
|
6
|
+
"core_contract": "1.19.883",
|
|
7
|
+
"source_commit": "38ac16c0f1716d2a3d3b040a38b4d61bcafb4598",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-09-
|
|
9
|
+
"built_at": "2026-09-19T19:12:16.216Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
|
-
"docs_redacted":
|
|
12
|
+
"docs_redacted": 498,
|
|
13
13
|
"agent_docs_stubbed": 26,
|
|
14
|
-
"functional_verbatim":
|
|
14
|
+
"functional_verbatim": 2315,
|
|
15
15
|
"rules": 3,
|
|
16
16
|
"gate_literals": 3,
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
19
|
"file_count": 2839,
|
|
20
|
-
"tree_sha256": "
|
|
20
|
+
"tree_sha256": "d96e15159f4ccd498d4c218b70f298a70541b1d97dae0f21124c8fde891881f0",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/ask-for-help/SKILL.md",
|
|
@@ -367,7 +367,7 @@
|
|
|
367
367
|
{
|
|
368
368
|
"path": "clients/bongos-client/index.d.ts",
|
|
369
369
|
"mode": "0000644",
|
|
370
|
-
"sha256": "
|
|
370
|
+
"sha256": "a433058b1d11a710689cb4eebe94d4182f5d644bc2df341359ee4ec6348718b4"
|
|
371
371
|
},
|
|
372
372
|
{
|
|
373
373
|
"path": "clients/bongos-client/index.mjs",
|
|
@@ -2034,10 +2034,15 @@
|
|
|
2034
2034
|
"mode": "0000644",
|
|
2035
2035
|
"sha256": "feab2773d4b8954874ed42bf922bc74d1b9c37e7d5ffef13c5c3cf58fd36507a"
|
|
2036
2036
|
},
|
|
2037
|
+
{
|
|
2038
|
+
"path": "docs/adr/0309-durable-module-enablement-db-override.md",
|
|
2039
|
+
"mode": "0000644",
|
|
2040
|
+
"sha256": "2aabad9f28113f3e6087b4e850d46a232aaa03c68ce9e793d04b2263e06998f5"
|
|
2041
|
+
},
|
|
2037
2042
|
{
|
|
2038
2043
|
"path": "docs/adr/README.md",
|
|
2039
2044
|
"mode": "0000644",
|
|
2040
|
-
"sha256": "
|
|
2045
|
+
"sha256": "22f4f461a476d43d15a9f77626bdce552736d1a5d96210b5dbd638eb758fbec5"
|
|
2041
2046
|
},
|
|
2042
2047
|
{
|
|
2043
2048
|
"path": "docs/api-reference.md",
|
|
@@ -2047,7 +2052,7 @@
|
|
|
2047
2052
|
{
|
|
2048
2053
|
"path": "docs/api/openapi.json",
|
|
2049
2054
|
"mode": "0000644",
|
|
2050
|
-
"sha256": "
|
|
2055
|
+
"sha256": "4a74552e803444eb13792a0c61fc41da324bda5c35c50b070d8980025d4d4935"
|
|
2051
2056
|
},
|
|
2052
2057
|
{
|
|
2053
2058
|
"path": "docs/architecture.md",
|
|
@@ -2072,12 +2077,12 @@
|
|
|
2072
2077
|
{
|
|
2073
2078
|
"path": "docs/copy-inventory.md",
|
|
2074
2079
|
"mode": "0000644",
|
|
2075
|
-
"sha256": "
|
|
2080
|
+
"sha256": "f1b9049057c56a02af6031f472a2634050753ca1539aa79549f663851db22e54"
|
|
2076
2081
|
},
|
|
2077
2082
|
{
|
|
2078
2083
|
"path": "docs/copy-registry.json",
|
|
2079
2084
|
"mode": "0000644",
|
|
2080
|
-
"sha256": "
|
|
2085
|
+
"sha256": "969894adbb9bc33d4e6f1656aaaa3ba863aba18a5fa7cdce15922916e4d43a6d"
|
|
2081
2086
|
},
|
|
2082
2087
|
{
|
|
2083
2088
|
"path": "docs/design/apex-pass-2-direction.md",
|
|
@@ -2592,7 +2597,7 @@
|
|
|
2592
2597
|
{
|
|
2593
2598
|
"path": "docs/file-map.md",
|
|
2594
2599
|
"mode": "0000644",
|
|
2595
|
-
"sha256": "
|
|
2600
|
+
"sha256": "0b1b89161e2c4731dd634a0efd074dd78e85301b1e161366a94b19dd69019905"
|
|
2596
2601
|
},
|
|
2597
2602
|
{
|
|
2598
2603
|
"path": "docs/handoff-template.md",
|
|
@@ -2602,7 +2607,7 @@
|
|
|
2602
2607
|
{
|
|
2603
2608
|
"path": "docs/module-api-changelog.md",
|
|
2604
2609
|
"mode": "0000644",
|
|
2605
|
-
"sha256": "
|
|
2610
|
+
"sha256": "a8791c0dfacd9fb522681fa5af7ddfcc63937dd597f0c30a2fa1b42498f4ee01"
|
|
2606
2611
|
},
|
|
2607
2612
|
{
|
|
2608
2613
|
"path": "docs/modules-contract.md",
|
|
@@ -2712,12 +2717,7 @@
|
|
|
2712
2717
|
{
|
|
2713
2718
|
"path": "docs/recipes/bongos-cli-release.md",
|
|
2714
2719
|
"mode": "0000644",
|
|
2715
|
-
"sha256": "
|
|
2716
|
-
},
|
|
2717
|
-
{
|
|
2718
|
-
"path": "docs/recipes/builder-box-lifecycle.md",
|
|
2719
|
-
"mode": "0000644",
|
|
2720
|
-
"sha256": "dfffcee084534239d8a748b7468409644d9375e952143b0bd09b9c2c7341e844"
|
|
2720
|
+
"sha256": "de596822f2f5925fd9e4008cc0214c025a73f5ec3a0275aa6f9a117368ed2a76"
|
|
2721
2721
|
},
|
|
2722
2722
|
{
|
|
2723
2723
|
"path": "docs/recipes/claude-design-loop.md",
|
|
@@ -2729,16 +2729,6 @@
|
|
|
2729
2729
|
"mode": "0000644",
|
|
2730
2730
|
"sha256": "53721b3314eab8f538aa7027862253abdbdd41be59f9dce75431c1b40ef80e63"
|
|
2731
2731
|
},
|
|
2732
|
-
{
|
|
2733
|
-
"path": "docs/recipes/devbox-app-release.md",
|
|
2734
|
-
"mode": "0000644",
|
|
2735
|
-
"sha256": "9334dacaa4e7c601e90c9670f101b8320d3664bc54a2cba221e93967c5f6082e"
|
|
2736
|
-
},
|
|
2737
|
-
{
|
|
2738
|
-
"path": "docs/recipes/devbox-app-windows-test.md",
|
|
2739
|
-
"mode": "0000644",
|
|
2740
|
-
"sha256": "0fe7e43b52eeb6633cdd47589bf7bace159bda115efb125ab6e3daefd231ea3f"
|
|
2741
|
-
},
|
|
2742
2732
|
{
|
|
2743
2733
|
"path": "docs/recipes/failed-ship-recovery-proof.md",
|
|
2744
2734
|
"mode": "0000644",
|
|
@@ -2777,7 +2767,7 @@
|
|
|
2777
2767
|
{
|
|
2778
2768
|
"path": "docs/recipes/managed-settings-remote-control.md",
|
|
2779
2769
|
"mode": "0000644",
|
|
2780
|
-
"sha256": "
|
|
2770
|
+
"sha256": "d1bc074f2a8de8d6d32f32d832e425637dc1dc6a03ae57ec417cd5a003264237"
|
|
2781
2771
|
},
|
|
2782
2772
|
{
|
|
2783
2773
|
"path": "docs/recipes/memory-backup.md",
|
|
@@ -2874,11 +2864,6 @@
|
|
|
2874
2864
|
"mode": "0000644",
|
|
2875
2865
|
"sha256": "dba962c19bf22e5773fd05eb6667581d15f62ecda7292a37f83b12227ad14049"
|
|
2876
2866
|
},
|
|
2877
|
-
{
|
|
2878
|
-
"path": "docs/recipes/work-on-a-task-from-your-dev-box.md",
|
|
2879
|
-
"mode": "0000644",
|
|
2880
|
-
"sha256": "cd676096bd45af0d8c95c280f9cfc7f0cc2ef410b830498a20007bca792bbbdb"
|
|
2881
|
-
},
|
|
2882
2867
|
{
|
|
2883
2868
|
"path": "docs/research/cursor-competitive-analysis.md",
|
|
2884
2869
|
"mode": "0000644",
|
|
@@ -3709,6 +3694,11 @@
|
|
|
3709
3694
|
"mode": "0000644",
|
|
3710
3695
|
"sha256": "e8d3e3f764b61ea559df7f997758e639f8778ee24da4293908e9d45ca30a425b"
|
|
3711
3696
|
},
|
|
3697
|
+
{
|
|
3698
|
+
"path": "migrations/core_248_module_enablement_overrides.sql",
|
|
3699
|
+
"mode": "0000644",
|
|
3700
|
+
"sha256": "4f35f87050a532f26b7c9cd0a9bc6f298ab5c0e15eb1c36ddcdd4d261201291d"
|
|
3701
|
+
},
|
|
3712
3702
|
{
|
|
3713
3703
|
"path": "modules/agents/CLAUDE.md",
|
|
3714
3704
|
"mode": "0000644",
|
|
@@ -3982,7 +3972,7 @@
|
|
|
3982
3972
|
{
|
|
3983
3973
|
"path": "modules/dev-box/app/README.md",
|
|
3984
3974
|
"mode": "0000644",
|
|
3985
|
-
"sha256": "
|
|
3975
|
+
"sha256": "2c82fe59e0f32aa5eaee94aac7ca896fbf822a85c7cd280748caa44eacdf8bd5"
|
|
3986
3976
|
},
|
|
3987
3977
|
{
|
|
3988
3978
|
"path": "modules/dev-box/app/assets/tray/mac-alertTemplate.png",
|
|
@@ -4837,22 +4827,22 @@
|
|
|
4837
4827
|
{
|
|
4838
4828
|
"path": "modules/hall-ui/public/collab-lib.js",
|
|
4839
4829
|
"mode": "0000644",
|
|
4840
|
-
"sha256": "
|
|
4830
|
+
"sha256": "c8c30e5f3cb5982a8218b6e8b135923c76b75604be553dcf3ed46fca0466e67f"
|
|
4841
4831
|
},
|
|
4842
4832
|
{
|
|
4843
4833
|
"path": "modules/hall-ui/public/collab.css",
|
|
4844
4834
|
"mode": "0000644",
|
|
4845
|
-
"sha256": "
|
|
4835
|
+
"sha256": "884118a3b38b0c1ed5e1ac9c90c0b5994714bbabde67959f67c49e7f49536983"
|
|
4846
4836
|
},
|
|
4847
4837
|
{
|
|
4848
4838
|
"path": "modules/hall-ui/public/collab.html",
|
|
4849
4839
|
"mode": "0000644",
|
|
4850
|
-
"sha256": "
|
|
4840
|
+
"sha256": "186a0828e1c3e44388146b94c56f239ea6b2392bd599f143c7c73029da35da32"
|
|
4851
4841
|
},
|
|
4852
4842
|
{
|
|
4853
4843
|
"path": "modules/hall-ui/public/collab.js",
|
|
4854
4844
|
"mode": "0000644",
|
|
4855
|
-
"sha256": "
|
|
4845
|
+
"sha256": "7d589e6c98f9f52831a9be9429493b49e68c3aa62f98f19cbcb77adbac70c0ca"
|
|
4856
4846
|
},
|
|
4857
4847
|
{
|
|
4858
4848
|
"path": "modules/hall-ui/public/collab.states.json",
|
|
@@ -4942,7 +4932,7 @@
|
|
|
4942
4932
|
{
|
|
4943
4933
|
"path": "modules/hall-ui/public/dom-utils.js",
|
|
4944
4934
|
"mode": "0000644",
|
|
4945
|
-
"sha256": "
|
|
4935
|
+
"sha256": "d32e03626886c73bdd36b3897588d0d17af6beee2c4477b5e06e2e4ecc0e22cd"
|
|
4946
4936
|
},
|
|
4947
4937
|
{
|
|
4948
4938
|
"path": "modules/hall-ui/public/drachmae.html",
|
|
@@ -7927,12 +7917,12 @@
|
|
|
7927
7917
|
{
|
|
7928
7918
|
"path": "package-lock.json",
|
|
7929
7919
|
"mode": "0000644",
|
|
7930
|
-
"sha256": "
|
|
7920
|
+
"sha256": "469884a3047b45a3ef2d4913c2316c2a8e2c7232bba7ff0c3d7ee3002b964be0"
|
|
7931
7921
|
},
|
|
7932
7922
|
{
|
|
7933
7923
|
"path": "package.json",
|
|
7934
7924
|
"mode": "0000644",
|
|
7935
|
-
"sha256": "
|
|
7925
|
+
"sha256": "1651df890fb2d85a35efe8281ba5c81a0c683b16db37158b2ed985d11544c683"
|
|
7936
7926
|
},
|
|
7937
7927
|
{
|
|
7938
7928
|
"path": "public-docs/index.html",
|
|
@@ -9537,7 +9527,7 @@
|
|
|
9537
9527
|
{
|
|
9538
9528
|
"path": "scripts/hall-preview/server.js",
|
|
9539
9529
|
"mode": "0000644",
|
|
9540
|
-
"sha256": "
|
|
9530
|
+
"sha256": "0052e9ed7ea2f5779c5bda8d54b1dabd731c0c11de87b4f8e06b00d051ed7a25"
|
|
9541
9531
|
},
|
|
9542
9532
|
{
|
|
9543
9533
|
"path": "scripts/hall-preview/task-visual.js",
|
|
@@ -9739,6 +9729,11 @@
|
|
|
9739
9729
|
"mode": "0000644",
|
|
9740
9730
|
"sha256": "d19b83f04b32d5ca942fb2ed3a210af6ef8607e3e9c949338f816337a3b6cf8c"
|
|
9741
9731
|
},
|
|
9732
|
+
{
|
|
9733
|
+
"path": "src/bongos/module-overrides.js",
|
|
9734
|
+
"mode": "0000644",
|
|
9735
|
+
"sha256": "91e1df91a44f1fd7eaeefcff7bf8ab1211d5f1559a50a7b3355184914bf970af"
|
|
9736
|
+
},
|
|
9742
9737
|
{
|
|
9743
9738
|
"path": "src/bongos/module-scope-map.js",
|
|
9744
9739
|
"mode": "0000644",
|
|
@@ -9872,7 +9867,7 @@
|
|
|
9872
9867
|
{
|
|
9873
9868
|
"path": "src/bongos/routes/modules.js",
|
|
9874
9869
|
"mode": "0000644",
|
|
9875
|
-
"sha256": "
|
|
9870
|
+
"sha256": "c12483b8b788420f88e7690311e0c1e079e90eaa6912df92706f7d0d584cb9d1"
|
|
9876
9871
|
},
|
|
9877
9872
|
{
|
|
9878
9873
|
"path": "src/bongos/routes/my-sessions.js",
|
|
@@ -9937,7 +9932,7 @@
|
|
|
9937
9932
|
{
|
|
9938
9933
|
"path": "src/module-api.js",
|
|
9939
9934
|
"mode": "0000644",
|
|
9940
|
-
"sha256": "
|
|
9935
|
+
"sha256": "b64003ea52fe47207f7723521aba5b1bec5b7286f3e545a4b323d379259b99ab"
|
|
9941
9936
|
},
|
|
9942
9937
|
{
|
|
9943
9938
|
"path": "src/module-loader/catalog.js",
|
|
@@ -9972,12 +9967,12 @@
|
|
|
9972
9967
|
{
|
|
9973
9968
|
"path": "src/modules.js",
|
|
9974
9969
|
"mode": "0000644",
|
|
9975
|
-
"sha256": "
|
|
9970
|
+
"sha256": "f0a19c4cda35c81c81ad62cbe2eb01dc8c7393d6129c27813d1f08b62bc356d1"
|
|
9976
9971
|
},
|
|
9977
9972
|
{
|
|
9978
9973
|
"path": "src/platform-server.js",
|
|
9979
9974
|
"mode": "0000644",
|
|
9980
|
-
"sha256": "
|
|
9975
|
+
"sha256": "ed0f3284b85d0f2b6b909832597f627b068684960ea2441f807a463946be9fd3"
|
|
9981
9976
|
},
|
|
9982
9977
|
{
|
|
9983
9978
|
"path": "src/role-responsibilities.js",
|
|
@@ -10562,7 +10557,7 @@
|
|
|
10562
10557
|
{
|
|
10563
10558
|
"path": "tests/box_sweep_docs.mjs",
|
|
10564
10559
|
"mode": "0000644",
|
|
10565
|
-
"sha256": "
|
|
10560
|
+
"sha256": "de2b626477f61e275bc0acc992d6e3b8aad20c93baa14ff3c9e888dffc2e7475"
|
|
10566
10561
|
},
|
|
10567
10562
|
{
|
|
10568
10563
|
"path": "tests/box_sync.mjs",
|
|
@@ -10787,7 +10782,7 @@
|
|
|
10787
10782
|
{
|
|
10788
10783
|
"path": "tests/collab_page.mjs",
|
|
10789
10784
|
"mode": "0000644",
|
|
10790
|
-
"sha256": "
|
|
10785
|
+
"sha256": "d7bbf03d41d8808f5f86f333a9e925291a628b5e5b4cac483be34880a6d42d04"
|
|
10791
10786
|
},
|
|
10792
10787
|
{
|
|
10793
10788
|
"path": "tests/compose_demo_credentials.mjs",
|
|
@@ -12522,13 +12517,18 @@
|
|
|
12522
12517
|
{
|
|
12523
12518
|
"path": "tests/modules.mjs",
|
|
12524
12519
|
"mode": "0000644",
|
|
12525
|
-
"sha256": "
|
|
12520
|
+
"sha256": "cffb354efd9aaedd462dfc36a1e8b741635e8434a30edb962273b189bedf0bde"
|
|
12526
12521
|
},
|
|
12527
12522
|
{
|
|
12528
12523
|
"path": "tests/modules_route.mjs",
|
|
12529
12524
|
"mode": "0000644",
|
|
12530
12525
|
"sha256": "079d7eef5828912e306e9dbbe081fef6004526067bd15aa6433dc2ff1873a4be"
|
|
12531
12526
|
},
|
|
12527
|
+
{
|
|
12528
|
+
"path": "tests/modules_route_wiring.mjs",
|
|
12529
|
+
"mode": "0000644",
|
|
12530
|
+
"sha256": "d58c353c7e32002d97da550fc493ed40b66dc624b2ed11be9d2e111a164d8aea"
|
|
12531
|
+
},
|
|
12532
12532
|
{
|
|
12533
12533
|
"path": "tests/my_projects_surface.mjs",
|
|
12534
12534
|
"mode": "0000644",
|
|
@@ -95,7 +95,7 @@ export interface GetMemoryBuildersBuilderIdFilesResponse { builder_id: unknown;
|
|
|
95
95
|
export interface GetMemoryFileResponse { builder_id: unknown; path: unknown; content: unknown; sha256: unknown; byte_len: unknown; mtime: unknown; updated_at: unknown; created_at: unknown }
|
|
96
96
|
export interface GetMemoryFilesResponse { builder_id: unknown; count: unknown; files: unknown }
|
|
97
97
|
export interface GetMingleResponse { mingle: unknown; open_pairs: unknown; you: unknown; matching: unknown }
|
|
98
|
-
export interface GetModulesResponse { modules: unknown; own_built: unknown; core_loaded: unknown; catalog: unknown; submit_pipeline_live: boolean }
|
|
98
|
+
export interface GetModulesResponse { modules: unknown; scope: unknown; own_built: unknown; core_loaded: unknown; catalog: unknown; submit_pipeline_live: boolean }
|
|
99
99
|
export interface GetModulesSubmissionsResponse { submissions: unknown }
|
|
100
100
|
export interface GetMyProjectsInvitesResponse { invites: unknown }
|
|
101
101
|
export interface GetMyProjectsResponse { owned: unknown; building: unknown; applied: unknown }
|
|
@@ -347,7 +347,7 @@ export interface PostMinglePairsIdDecideResponse { pair: unknown }
|
|
|
347
347
|
export interface PostMingleRoundRequest { limit?: number }
|
|
348
348
|
export interface PostMingleRoundResponse { paired: unknown; count: unknown; skipped: unknown }
|
|
349
349
|
export interface PostModulesKeyEnableRequest { enabled?: unknown }
|
|
350
|
-
export interface PostModulesKeyEnableResponse { ok: boolean; key: unknown; enabled: unknown; note: unknown }
|
|
350
|
+
export interface PostModulesKeyEnableResponse { ok: boolean; key: unknown; enabled: unknown; effective: unknown; source: unknown; note: unknown }
|
|
351
351
|
export interface PostModulesKeySubmitRequest { signed_by?: string }
|
|
352
352
|
export interface PostModulesKeySubmitResponse { ok: boolean; submission: unknown }
|
|
353
353
|
export interface PostMyProjectsClientIdLeaveResponse { ok: boolean; left: unknown }
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# ADR 0309 — Module enablement is a database row, above the committed pack and below env
|
|
2
|
+
|
|
3
|
+
**Status:** accepted · **Date:** 2026-09-18 · **Task:** [task 1002857](https://cloudbongos.com/builders#/task/1002857) (goal 1000091 — BONGOS-V2)
|
|
4
|
+
|
|
5
|
+
**Related:** [ADR 0107](0107-module-upstreaming-contribution-to-core-catalog.md) §9 (the Modules tab that ships the toggle) · [ADR 0016](<redacted>.md) (why an HTTP handler may not write to `main`) · [ADR 0083](<redacted>.md) (the module contract this resolves)
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
The hall's Modules-tab toggle wrote `config/modules.json` and reloaded the
|
|
10
|
+
in-process cache. The effect was immediate, so the toggle looked like it worked.
|
|
11
|
+
|
|
12
|
+
`config/modules.json` is the **committed instance pack**, and the pull-deploy runs
|
|
13
|
+
`git reset --hard origin/main`. An operator's toggle therefore reverted on the
|
|
14
|
+
next deploy unless somebody remembered to commit it — and reverted *silently*, so
|
|
15
|
+
a module an operator had deliberately turned off could come back on hours later
|
|
16
|
+
with nothing to connect the two events. That is worse than a toggle that refuses:
|
|
17
|
+
a control that reports success and then quietly undoes itself teaches people not
|
|
18
|
+
to trust the panel.
|
|
19
|
+
|
|
20
|
+
The route's own header recorded the trade-off and named the follow-up; this is it.
|
|
21
|
+
|
|
22
|
+
## The decision
|
|
23
|
+
|
|
24
|
+
**Enablement lives in `module_enablement_overrides` (migration `core_248`), read
|
|
25
|
+
as one precedence layer inside `resolveModules`.** The resolution order becomes:
|
|
26
|
+
|
|
27
|
+
neutral pack → instance pack → DB override → env → registry default
|
|
28
|
+
|
|
29
|
+
Three things in that line are the actual decision.
|
|
30
|
+
|
|
31
|
+
### 1. Above the committed pack
|
|
32
|
+
|
|
33
|
+
Outranking the file *is* the point. The pack is what `git reset --hard` restores
|
|
34
|
+
on every deploy, so an override that sat below it would be erased by the very
|
|
35
|
+
event it exists to survive.
|
|
36
|
+
|
|
37
|
+
### 2. Below env
|
|
38
|
+
|
|
39
|
+
`<PREFIX>_MODULE_<KEY>` stays the highest layer, because it is the **incident
|
|
40
|
+
knob**. An operator must be able to force a module off on one box without a
|
|
41
|
+
working database. If the database outranked env, the failure mode would be "the
|
|
42
|
+
module I am trying to kill is being switched back on by a row I cannot reach to
|
|
43
|
+
delete" — which is the kind of thing that turns an incident into an outage.
|
|
44
|
+
|
|
45
|
+
### 3. Not an auto-commit
|
|
46
|
+
|
|
47
|
+
The other way to make the toggle durable is for the handler to commit and push
|
|
48
|
+
`config/modules.json` to `main`. That was rejected, and remains rejected: it would
|
|
49
|
+
make an HTTP request a writer on `main`, bypassing the ship/grade/deploy pipeline
|
|
50
|
+
and the [ADR 0016](<redacted>.md) trust boundary. Durability
|
|
51
|
+
belongs in the database, where this instance's live state already lives.
|
|
52
|
+
|
|
53
|
+
## The two design points the task left open
|
|
54
|
+
|
|
55
|
+
### The scope key is the instance pack path
|
|
56
|
+
|
|
57
|
+
One deployed checkout can run **two instances against one database**,
|
|
58
|
+
differentiated only by `BONGOS_MODULES_FILE` / `BONGOS_BRANDING_FILE`: the default
|
|
59
|
+
instance on `config/modules.json`, and a vanilla sibling on
|
|
60
|
+
`config/modules.neutral.json`. A single global row per module would let one
|
|
61
|
+
sibling's toggle flip the other's module.
|
|
62
|
+
|
|
63
|
+
The scope key is therefore the **resolved instance pack path, relative to the
|
|
64
|
+
instance root, posix-separated** — chosen because it is not an invented
|
|
65
|
+
identifier: it is precisely the axis those two processes already differ on, so it
|
|
66
|
+
cannot say "same instance" where `loadModules` says "different pack". Normalising
|
|
67
|
+
it keeps the key stable across a moved checkout, an absolute-vs-relative env
|
|
68
|
+
value, and Windows vs Linux. `resolveInstancePackPath()` was extracted so the key
|
|
69
|
+
and the read share one ladder rather than two copies that drift.
|
|
70
|
+
|
|
71
|
+
### The DB is read into a snapshot, never inline
|
|
72
|
+
|
|
73
|
+
`loadModules()` is synchronous, behind a lazy cached singleton every caller
|
|
74
|
+
reaches through `modules()`. Making it async would ripple into effectively every
|
|
75
|
+
consumer of a module flag.
|
|
76
|
+
|
|
77
|
+
So the database is never read on the resolution path. `src/bongos/module-overrides.js`
|
|
78
|
+
reads the overrides **once per refresh** and hands `src/modules.js` a plain
|
|
79
|
+
snapshot, which the pure resolver treats as one more injected layer. There are
|
|
80
|
+
exactly two refresh points, because there are exactly two moments the answer can
|
|
81
|
+
change: **server boot**, and **a write through the route**.
|
|
82
|
+
|
|
83
|
+
The boot read is awaited *before* `buildPlatformApp()`, because routes mount from
|
|
84
|
+
the resolved module set — an override that landed after construction would not
|
|
85
|
+
change what is mounted until the next restart, which is the same complaint in a
|
|
86
|
+
new costume.
|
|
87
|
+
|
|
88
|
+
## Consequences
|
|
89
|
+
|
|
90
|
+
**An unreachable database changes nothing.** Every read here swallows its error
|
|
91
|
+
and leaves the snapshot alone, and an empty snapshot means *no opinion*, not
|
|
92
|
+
*everything off*. An instance that cannot reach its database resolves modules
|
|
93
|
+
exactly as it did before the table existed — on the packs and env alone. This is
|
|
94
|
+
what keeps the awaited boot read a best-effort improvement rather than a boot-time
|
|
95
|
+
dependency: it buys a better answer when the database is there, and never
|
|
96
|
+
withholds the server when it is not.
|
|
97
|
+
|
|
98
|
+
**Writes are not forgiving, deliberately.** `setOverride` throws. A toggle that
|
|
99
|
+
reported success while persisting nothing would be the original bug with better
|
|
100
|
+
manners.
|
|
101
|
+
|
|
102
|
+
**The winning layer is now visible.** `GET /modules` reports `enabled_source` per
|
|
103
|
+
module (`neutral` / `instance` / `override` / `env` / `spend-refusal` / `default`),
|
|
104
|
+
the override's author and timestamp, and the process's scope key. Without it,
|
|
105
|
+
"why is this module on?" costs a shell and a grep — and with two precedence layers
|
|
106
|
+
added since the tab was built, the question got harder, not easier. `sources` is
|
|
107
|
+
attached non-enumerably so no existing consumer of the boolean map sees a new key.
|
|
108
|
+
|
|
109
|
+
**One regression, caught in review and worth recording.** Wrapping the boot in an
|
|
110
|
+
`async` IIFE turned `buildPlatformApp()`'s fatal throw — an enabled module
|
|
111
|
+
consuming a port nothing provides — into a promise rejection, which the
|
|
112
|
+
unhandled-rejection backstop deliberately *survives*. The server came up
|
|
113
|
+
half-wired and said nothing, which is exactly what that throw exists to prevent.
|
|
114
|
+
The boot now rethrows from `process.nextTick`, restoring the uncaught exception
|
|
115
|
+
Node already prints raw and exits non-zero on. Pinned by
|
|
116
|
+
`tests/platform_boot.mjs`'s task 1003820 case.
|
package/docs/adr/README.md
CHANGED
|
@@ -400,3 +400,4 @@ This keeps the decision history honest and traceable.
|
|
|
400
400
|
| 0306 | [**Instance supervision is a seam, with systemd as the default** ([task 1003997](https://cloudbongos.com/builders#/task/1003997), goal 1000106, F13 from the task-1002718 QA walk). `provision-units.js` hardcoded `/etc/systemd/system` in three path functions and the runner reached for `systemctl` inline at fifteen call sites, so a standup was impossible on any plane without systemd — the self-host image runs `USER node`, installs no `sudo` and boots no systemd. **A directory knob does not fix this**: pointing the unit path somewhere writable still emits `daemon-reload` into a namespace where systemd is not PID 1. What varies is not where the unit file goes, it is what supervises the process. Chosen: four operations (install+enable, install backup schedule, restart, remove) move behind `scripts/gds/provision-process.js`, taking the `{ exec, writeFile, sudoP, log }` io the runbook already threads, so dry-run, remote-ssh and logging behaviour carry over untouched (ADR 0130). Selection is explicit (`PROVISION_PROCESS_MANAGER`, an unknown value throws) → probed (`/run/systemd/system`, the `sd_booted(3)` check) → supervisord. **The live box is unchanged by construction** — it boots systemd, and the systemd implementation emits byte-identical commands; the untouched composition assertions in `tests/provision.mjs` are the proof. Rejected: systemd `--user` units (fix an unprivileged VM we do not have, while a plain container has no user bus either). Consequences: isolation is restated per manager (systemd `User=` → supervisord `user=`, ADR 0281) or it silently drops; supervisord has no timers, so it installs no backup schedule and prints the `crontab` line instead of re-implementing cron; the seam is two implementations wide, not speculatively N. **This removes one of four container blockers** — ingress ([task 1004017](https://cloudbongos.com/builders#/task/1004017)), per-instance identity ([task 1004018](https://cloudbongos.com/builders#/task/1004018)) and the hardcoded backup-dir owner ([task 1002719](https://cloudbongos.com/builders#/task/1002719)) remain, so task 1003997's done-when was narrowed to the seam rather than claiming a self-host story that is not there.](0306-instance-supervision-is-a-seam-with-systemd-as-the-default.md) | infra / provisioning |
|
|
401
401
|
| 0307 | [**Autobongos: a deterministic supervisor, agentic workers** ([task 1003900](https://cloudbongos.com/builders#/task/1003900), goal 1000119). An always-on machine works the queue unattended inside owner-allowlisted goals. Most of the loop already existed wired to the wrong trigger — `sequence.js`'s ten-reason halt matrix (ADR 0153), an open blocker as the hold state, the Windows-aware headless spawn seam, `overnight-builder` — but the trigger was cron rather than capacity, and the **supervisor was itself a Claude session**. Decided: the supervisor is a **program**, only the worker is a session; the gauge is the statusLine's `rate_limits.five_hour`/`seven_day`, which per Anthropic's own note is absent until a session's first API response and so **cannot be read cold** (a statusline script persists it, a stale file is *unknown*, never *headroom*); **one session per task, metering not estimating** (a successor cannot be claimed until its predecessor ships, so a batch produces the same order while risking a half-done window, and a fresh session avoids a checkout going stale behind main); **completion is read from the ledger, never the session** (a worker that stopped needing a decision returns `subtype: success`, identical to one that finished); **no terminal stop, only speeds** (three failures → a probing state that self-heals; the only true stop is the server-side kill switch); the machine holds **no push credential**, so a grader outage stops the run rather than shipping unreviewed. The load-bearing finding was **tested before it was decided**: a worker told plainly to stop and ask instead settled four judgement calls and wrote them to disk — competent, and fatal to any design that waits for raised hands. Hence **gate before, record after, nothing in between**: the halt matrix refuses ambiguous work at pick time, and the worker's verdict must declare what the spec did not determine. Rejected: per-call `--permission-prompt-tool` (a thousand weak gates, and one slow supervisor stalls every worker), `--max-budget-usd` (caps dollars; on a subscription the constraint is capacity, so the bound is wall-clock), extending `overnight-builder`, and a terminal stop. Deliberately not built: mid-flight question answering, portability, per-task estimation.](0307-autobongos-a-deterministic-supervisor-and-agentic-workers.md) | autonomy / sessions |
|
|
402
402
|
| 0308 | [**An eleventh working area: Autobongos** ([task 1003900](https://cloudbongos.com/builders#/task/1003900), goal 1000119). Amends [ADR 0264](0264-the-ten-working-areas.md), which nine days earlier collapsed 38 goals into **ten** areas held until 5,000 builders. Area 11 is Autobongos ([goal 1000119](https://cloudbongos.com/builders#/goal/1000119), owner Lars). **Area 6 was the obvious home and was rejected**: area 6 is about a human's experience of the platform, and this area has no human in it — which limits to spend, which fences hold unsupervised, how it recovers with nobody at the keyboard. Those get less attention next to work with a user in front of it, not better answers. It **reopens** goal 1000028 (*Autonomy groundwork*), archived in the 38→10 cut with no successor and carried as `succeeds_goal_id`, so the lineage is in the ledger rather than the prose — and ADR 0264 §3 had already left "fold, keep as an eleventh, or close" as a live owner question. Admitting it cost something recorded: BONGOS-V2 is `building`, so its goal set is closed (ADR 0250) and `POST /goals` refuses `version_not_planning` — an Archon reopened it with a stored `admit_reason`, which is the cut holding well enough that adding to it left evidence. Does not decide: the ten-area discipline stands (one exception, written reason, 5,000-builder horizon unchanged), 0264 §3's other two open rows, or a second goal for the area.](0308-an-eleventh-working-area.md) | methodology / goals |
|
|
403
|
+
| 0309 | [**Module enablement is a database row, above the committed pack and below env** ([task 1002857](https://cloudbongos.com/builders#/task/1002857), goal 1000091). The hall Modules-tab toggle ([ADR 0107](0107-module-upstreaming-contribution-to-core-catalog.md) §9) wrote `config/modules.json` and reloaded the cache, so it looked like it worked — but that file is the committed instance pack and the pull-deploy runs `git reset --hard origin/main`, so the toggle reverted on the next deploy, **silently**. Enablement moves to `module_enablement_overrides` (migration `core_248`), read as one precedence layer: neutral pack → instance pack → **DB override** → env → default. **Above the pack** because the pack is what a deploy restores, so an override below it would be erased by the event it exists to survive; **below env** because `<PREFIX>_MODULE_<KEY>` is the incident knob and must not need a reachable database. **Auto-committing to `main` stays rejected** ([ADR 0016](<redacted>.md)): durability belongs in the DB, not in an HTTP handler that writes to the default branch. Two open design points settled: the **scope key** is the resolved instance pack path (the only axis two instances sharing one database differ on, so one sibling's toggle cannot flip the other's module), and the DB is read into a **snapshot** refreshed at boot and on write rather than inline, because `loadModules()` is synchronous and making it async would ripple into every consumer of a module flag. An unreachable database is a **no-op** — no row means "no opinion", not "off". Does not decide: whether a toggle should also restart the process so remounting is immediate.](0309-durable-module-enablement-db-override.md) | modules / ops |
|
package/docs/api/openapi.json
CHANGED
|
@@ -19648,6 +19648,7 @@
|
|
|
19648
19648
|
"type": "object",
|
|
19649
19649
|
"properties": {
|
|
19650
19650
|
"modules": {},
|
|
19651
|
+
"scope": {},
|
|
19651
19652
|
"own_built": {},
|
|
19652
19653
|
"core_loaded": {},
|
|
19653
19654
|
"catalog": {},
|
|
@@ -19657,6 +19658,7 @@
|
|
|
19657
19658
|
},
|
|
19658
19659
|
"required": [
|
|
19659
19660
|
"modules",
|
|
19661
|
+
"scope",
|
|
19660
19662
|
"own_built",
|
|
19661
19663
|
"core_loaded",
|
|
19662
19664
|
"catalog",
|
|
@@ -23479,12 +23481,16 @@
|
|
|
23479
23481
|
},
|
|
23480
23482
|
"key": {},
|
|
23481
23483
|
"enabled": {},
|
|
23484
|
+
"effective": {},
|
|
23485
|
+
"source": {},
|
|
23482
23486
|
"note": {}
|
|
23483
23487
|
},
|
|
23484
23488
|
"required": [
|
|
23485
23489
|
"ok",
|
|
23486
23490
|
"key",
|
|
23487
23491
|
"enabled",
|
|
23492
|
+
"effective",
|
|
23493
|
+
"source",
|
|
23488
23494
|
"note"
|
|
23489
23495
|
]
|
|
23490
23496
|
},
|