@bongos/core 1.21.14 → 1.21.16
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 +51 -41
- package/docs/adr/0281-an-instance-identity-is-its-own-unix-account-and-pg-role.md +3 -0
- package/docs/adr/0364-repo-access-is-asked-at-sign-in-and-held-for-the-session.md +30 -0
- package/docs/adr/README.md +1 -0
- package/docs/copy-inventory.md +255 -255
- package/docs/copy-registry.json +288 -288
- package/docs/module-api-changelog.md +4 -0
- package/docs/page-readings.json +363 -362
- package/docs/recipes/upgrading-the-core.md +1 -0
- package/modules/hall-ui/public/deploy.js +3 -0
- package/modules/public-landing/public/account.html +2 -2
- package/modules/public-landing/public/account.probes.json +2 -2
- package/modules/public-landing/public/index.html +1 -1
- package/modules/public-landing/public/projects.html +22 -13
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +12 -0
- package/scripts/gds/provision-core-upgrade.js +52 -20
- package/scripts/gds/upgrade-migrate.js +101 -4
- package/scripts/gds/upgrade-outcome.js +6 -0
- package/scripts/gds/upgrade.js +39 -44
- package/scripts/gds/wedge-remedy.js +10 -4
- package/src/bongos/db.js +7 -6
- package/src/bongos/routes/auth.js +17 -4
- package/src/module-api.js +1 -1
- package/tests/core_upgrade_runner.mjs +34 -10
- package/tests/github_token_session_life.mjs +110 -0
- package/tests/hub_account_page.mjs +2 -2
- package/tests/instance_db_migrated_on_code_move.mjs +20 -2
- package/tests/landing_page.mjs +2 -2
- package/tests/projects_hub_pre_uat.mjs +2 -1
- package/tests/upgrade.mjs +147 -0
- package/tests/upgrade_outcome.mjs +3 -0
- package/tests/wedge_remedy.mjs +36 -2
- package/tests/wizard_draft_resume.mjs +49 -0
- package/tests/wizard_intent_resume.mjs +4 -2
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.21.
|
|
6
|
-
"core_contract": "1.21.
|
|
7
|
-
"source_commit": "
|
|
5
|
+
"core_version": "1.21.16",
|
|
6
|
+
"core_contract": "1.21.16",
|
|
7
|
+
"source_commit": "abd20c4cc71e944d231ab474f59cd6aa2c66ccc8",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-10-
|
|
9
|
+
"built_at": "2026-10-02T20:09:34.296Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
|
-
"docs_redacted":
|
|
12
|
+
"docs_redacted": 580,
|
|
13
13
|
"agent_docs_stubbed": 27,
|
|
14
|
-
"functional_verbatim":
|
|
14
|
+
"functional_verbatim": 2893,
|
|
15
15
|
"rules": 3,
|
|
16
16
|
"gate_literals": 3,
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
|
-
"file_count":
|
|
20
|
-
"tree_sha256": "
|
|
19
|
+
"file_count": 3501,
|
|
20
|
+
"tree_sha256": "59790b289cc2c7e077c0537945281043f1dbdabad4c82124fe1f4f807edf26db",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/ask-for-help/SKILL.md",
|
|
@@ -1867,7 +1867,7 @@
|
|
|
1867
1867
|
{
|
|
1868
1868
|
"path": "docs/adr/0281-an-instance-identity-is-its-own-unix-account-and-pg-role.md",
|
|
1869
1869
|
"mode": "0000644",
|
|
1870
|
-
"sha256": "
|
|
1870
|
+
"sha256": "fb3ec0877c3b32437d93f59ca5ff92c5f970820f73ff6384a522f22aaf62e609"
|
|
1871
1871
|
},
|
|
1872
1872
|
{
|
|
1873
1873
|
"path": "docs/adr/0282-a-module-that-spends-for-its-callers-declares-a-payer-and-the-core-refuses-it-without-one.md",
|
|
@@ -2279,10 +2279,15 @@
|
|
|
2279
2279
|
"mode": "0000644",
|
|
2280
2280
|
"sha256": "4feed5892da4fe2fbe148cdf56edeacd2bf7e6c3886a880a4246811e500e6973"
|
|
2281
2281
|
},
|
|
2282
|
+
{
|
|
2283
|
+
"path": "docs/adr/0364-repo-access-is-asked-at-sign-in-and-held-for-the-session.md",
|
|
2284
|
+
"mode": "0000644",
|
|
2285
|
+
"sha256": "ed10b87275d0c3fbaa665467dfd0305274adbbc85556a5162346b3a2537a78ee"
|
|
2286
|
+
},
|
|
2282
2287
|
{
|
|
2283
2288
|
"path": "docs/adr/README.md",
|
|
2284
2289
|
"mode": "0000644",
|
|
2285
|
-
"sha256": "
|
|
2290
|
+
"sha256": "037b81d2507eba161cd12c7daafb32071e6c65bc3383d0174e4ac96aa6ab6dc4"
|
|
2286
2291
|
},
|
|
2287
2292
|
{
|
|
2288
2293
|
"path": "docs/api-reference.md",
|
|
@@ -2317,12 +2322,12 @@
|
|
|
2317
2322
|
{
|
|
2318
2323
|
"path": "docs/copy-inventory.md",
|
|
2319
2324
|
"mode": "0000644",
|
|
2320
|
-
"sha256": "
|
|
2325
|
+
"sha256": "12ef21f6a7c67a603fe0fe2f7a67b461aa6823b930b2119aedd0330412a4245e"
|
|
2321
2326
|
},
|
|
2322
2327
|
{
|
|
2323
2328
|
"path": "docs/copy-registry.json",
|
|
2324
2329
|
"mode": "0000644",
|
|
2325
|
-
"sha256": "
|
|
2330
|
+
"sha256": "a0000bd2fe2852e37582c2ff0232364b77d84a5056d80deaa713799b080ce49d"
|
|
2326
2331
|
},
|
|
2327
2332
|
{
|
|
2328
2333
|
"path": "docs/design/apex-pass-2-direction.md",
|
|
@@ -2827,7 +2832,7 @@
|
|
|
2827
2832
|
{
|
|
2828
2833
|
"path": "docs/module-api-changelog.md",
|
|
2829
2834
|
"mode": "0000644",
|
|
2830
|
-
"sha256": "
|
|
2835
|
+
"sha256": "f833fe8a3166735f427b7b8b6d22ed6ce751bc815262edf04b11572b25c680ba"
|
|
2831
2836
|
},
|
|
2832
2837
|
{
|
|
2833
2838
|
"path": "docs/modules-contract.md",
|
|
@@ -2917,7 +2922,7 @@
|
|
|
2917
2922
|
{
|
|
2918
2923
|
"path": "docs/page-readings.json",
|
|
2919
2924
|
"mode": "0000644",
|
|
2920
|
-
"sha256": "
|
|
2925
|
+
"sha256": "536c5bbddab40e047204586e55f23057e9a8b4ae7a3c8cb9f96926df543ad423"
|
|
2921
2926
|
},
|
|
2922
2927
|
{
|
|
2923
2928
|
"path": "docs/project-context.template.md",
|
|
@@ -3082,7 +3087,7 @@
|
|
|
3082
3087
|
{
|
|
3083
3088
|
"path": "docs/recipes/upgrading-the-core.md",
|
|
3084
3089
|
"mode": "0000644",
|
|
3085
|
-
"sha256": "
|
|
3090
|
+
"sha256": "cc1253d5b13243b04d343db140c557b9c78c9345b001be71f3c7b782e9982860"
|
|
3086
3091
|
},
|
|
3087
3092
|
{
|
|
3088
3093
|
"path": "docs/recipes/windows-builders.md",
|
|
@@ -5482,7 +5487,7 @@
|
|
|
5482
5487
|
{
|
|
5483
5488
|
"path": "modules/hall-ui/public/deploy.js",
|
|
5484
5489
|
"mode": "0000644",
|
|
5485
|
-
"sha256": "
|
|
5490
|
+
"sha256": "5066ca5197fb8f01f41703911f9771c41f2dc21cdec20103614b8bc1df748ab6"
|
|
5486
5491
|
},
|
|
5487
5492
|
{
|
|
5488
5493
|
"path": "modules/hall-ui/public/deploy.states.json",
|
|
@@ -8427,12 +8432,12 @@
|
|
|
8427
8432
|
{
|
|
8428
8433
|
"path": "modules/public-landing/public/account.html",
|
|
8429
8434
|
"mode": "0000644",
|
|
8430
|
-
"sha256": "
|
|
8435
|
+
"sha256": "c86bf7e9ca40631cc1b011a915c834a6ce1399d23c4cb7873d9276138c8e5b56"
|
|
8431
8436
|
},
|
|
8432
8437
|
{
|
|
8433
8438
|
"path": "modules/public-landing/public/account.probes.json",
|
|
8434
8439
|
"mode": "0000644",
|
|
8435
|
-
"sha256": "
|
|
8440
|
+
"sha256": "d592e0f97f5415c1b42d8cb508b3bca327a2484640a7ee2aa9bef606d400bfa9"
|
|
8436
8441
|
},
|
|
8437
8442
|
{
|
|
8438
8443
|
"path": "modules/public-landing/public/account.states.json",
|
|
@@ -8992,7 +8997,7 @@
|
|
|
8992
8997
|
{
|
|
8993
8998
|
"path": "modules/public-landing/public/index.html",
|
|
8994
8999
|
"mode": "0000644",
|
|
8995
|
-
"sha256": "
|
|
9000
|
+
"sha256": "4a0f39a8b4ca35d64ee0a66d38c1d56ae90605678483b0e74b3618dcc1722288"
|
|
8996
9001
|
},
|
|
8997
9002
|
{
|
|
8998
9003
|
"path": "modules/public-landing/public/index.probes.json",
|
|
@@ -9037,7 +9042,7 @@
|
|
|
9037
9042
|
{
|
|
9038
9043
|
"path": "modules/public-landing/public/projects.html",
|
|
9039
9044
|
"mode": "0000644",
|
|
9040
|
-
"sha256": "
|
|
9045
|
+
"sha256": "0e6ba49becc74c5a73f3e0b1babec2521d6a84a3b8c48e116c675c05005c2d1e"
|
|
9041
9046
|
},
|
|
9042
9047
|
{
|
|
9043
9048
|
"path": "modules/public-landing/public/projects.probes.json",
|
|
@@ -9762,12 +9767,12 @@
|
|
|
9762
9767
|
{
|
|
9763
9768
|
"path": "package-lock.json",
|
|
9764
9769
|
"mode": "0000644",
|
|
9765
|
-
"sha256": "
|
|
9770
|
+
"sha256": "84060eaa86f290bb1362b6223dbab18a5427344ae4fd40069ec8d9322d20062c"
|
|
9766
9771
|
},
|
|
9767
9772
|
{
|
|
9768
9773
|
"path": "package.json",
|
|
9769
9774
|
"mode": "0000644",
|
|
9770
|
-
"sha256": "
|
|
9775
|
+
"sha256": "d0ffbee20f0738db3b4dc2d0b3a898e33b934081b9d6dff66020589764b7f432"
|
|
9771
9776
|
},
|
|
9772
9777
|
{
|
|
9773
9778
|
"path": "public-docs/index.html",
|
|
@@ -9787,7 +9792,7 @@
|
|
|
9787
9792
|
{
|
|
9788
9793
|
"path": "release-notes.json",
|
|
9789
9794
|
"mode": "0000644",
|
|
9790
|
-
"sha256": "
|
|
9795
|
+
"sha256": "e8042901e3e7969c68c77ba31cced93dce76e589df6fa7ca44816e8de56c4d0b"
|
|
9791
9796
|
},
|
|
9792
9797
|
{
|
|
9793
9798
|
"path": "scripts/bongos-mcp.js",
|
|
@@ -10792,7 +10797,7 @@
|
|
|
10792
10797
|
{
|
|
10793
10798
|
"path": "scripts/gds/provision-core-upgrade.js",
|
|
10794
10799
|
"mode": "0000644",
|
|
10795
|
-
"sha256": "
|
|
10800
|
+
"sha256": "f872595e7333304012840de5f94a631a6c4105d2753104bfa02d5e68aae7fedc"
|
|
10796
10801
|
},
|
|
10797
10802
|
{
|
|
10798
10803
|
"path": "scripts/gds/provision-disconnect.js",
|
|
@@ -11482,17 +11487,17 @@
|
|
|
11482
11487
|
{
|
|
11483
11488
|
"path": "scripts/gds/upgrade-migrate.js",
|
|
11484
11489
|
"mode": "0000644",
|
|
11485
|
-
"sha256": "
|
|
11490
|
+
"sha256": "f13cdc8f5f55b76a28230b1d20ed5116159106ea66dcce8db1dcb37302a41fa7"
|
|
11486
11491
|
},
|
|
11487
11492
|
{
|
|
11488
11493
|
"path": "scripts/gds/upgrade-outcome.js",
|
|
11489
11494
|
"mode": "0000644",
|
|
11490
|
-
"sha256": "
|
|
11495
|
+
"sha256": "c05a13867f1792cb6befee3bc3e8f6343c67372a32e14d769d49c8088d7035fa"
|
|
11491
11496
|
},
|
|
11492
11497
|
{
|
|
11493
11498
|
"path": "scripts/gds/upgrade.js",
|
|
11494
11499
|
"mode": "0000644",
|
|
11495
|
-
"sha256": "
|
|
11500
|
+
"sha256": "5197985fef3098ca0f5ba49e84a3585815bfd24e33c889cc4708c76ef1bc1a64"
|
|
11496
11501
|
},
|
|
11497
11502
|
{
|
|
11498
11503
|
"path": "scripts/gds/validate-design.js",
|
|
@@ -11522,7 +11527,7 @@
|
|
|
11522
11527
|
{
|
|
11523
11528
|
"path": "scripts/gds/wedge-remedy.js",
|
|
11524
11529
|
"mode": "0000644",
|
|
11525
|
-
"sha256": "
|
|
11530
|
+
"sha256": "611a04666351d8efc7ac5f32a5fef3e846bb087c3397ffd6e3c15a9d9a8dbacb"
|
|
11526
11531
|
},
|
|
11527
11532
|
{
|
|
11528
11533
|
"path": "scripts/gds/worktree-claim-guard.js",
|
|
@@ -11702,7 +11707,7 @@
|
|
|
11702
11707
|
{
|
|
11703
11708
|
"path": "src/bongos/db.js",
|
|
11704
11709
|
"mode": "0000644",
|
|
11705
|
-
"sha256": "
|
|
11710
|
+
"sha256": "29801ce9f6f28fef024f9424ffb1903856e6c1c3a847d16f243634ae6fbb91b0"
|
|
11706
11711
|
},
|
|
11707
11712
|
{
|
|
11708
11713
|
"path": "src/bongos/github-repos.js",
|
|
@@ -11877,7 +11882,7 @@
|
|
|
11877
11882
|
{
|
|
11878
11883
|
"path": "src/bongos/routes/auth.js",
|
|
11879
11884
|
"mode": "0000644",
|
|
11880
|
-
"sha256": "
|
|
11885
|
+
"sha256": "3ba37d575862699c9f300b67761cc88594d4a5bce256e127fa7dedd5709e5917"
|
|
11881
11886
|
},
|
|
11882
11887
|
{
|
|
11883
11888
|
"path": "src/bongos/routes/backup.js",
|
|
@@ -12012,7 +12017,7 @@
|
|
|
12012
12017
|
{
|
|
12013
12018
|
"path": "src/module-api.js",
|
|
12014
12019
|
"mode": "0000644",
|
|
12015
|
-
"sha256": "
|
|
12020
|
+
"sha256": "c818a54f4b5f23114851245f6f5882fbd37a09a2692ec5cc96e252df65241911"
|
|
12016
12021
|
},
|
|
12017
12022
|
{
|
|
12018
12023
|
"path": "src/module-loader/catalog.js",
|
|
@@ -13007,7 +13012,7 @@
|
|
|
13007
13012
|
{
|
|
13008
13013
|
"path": "tests/core_upgrade_runner.mjs",
|
|
13009
13014
|
"mode": "0000644",
|
|
13010
|
-
"sha256": "
|
|
13015
|
+
"sha256": "1c6e820ed45b489749f68f0cc00615fe2c4d6a4b08312316897cd1777c82b4dc"
|
|
13011
13016
|
},
|
|
13012
13017
|
{
|
|
13013
13018
|
"path": "tests/cosmos_token_contrast.mjs",
|
|
@@ -13619,6 +13624,11 @@
|
|
|
13619
13624
|
"mode": "0000644",
|
|
13620
13625
|
"sha256": "66fd3d349445aa00e55fa77589958d6c98980e99f3cdaf4746ff55494202333a"
|
|
13621
13626
|
},
|
|
13627
|
+
{
|
|
13628
|
+
"path": "tests/github_token_session_life.mjs",
|
|
13629
|
+
"mode": "0000644",
|
|
13630
|
+
"sha256": "40975159ab53479398036f9253f01a37e80d41d101195962d3a9b255818b2a0f"
|
|
13631
|
+
},
|
|
13622
13632
|
{
|
|
13623
13633
|
"path": "tests/github_token_store.mjs",
|
|
13624
13634
|
"mode": "0000644",
|
|
@@ -14472,7 +14482,7 @@
|
|
|
14472
14482
|
{
|
|
14473
14483
|
"path": "tests/hub_account_page.mjs",
|
|
14474
14484
|
"mode": "0000644",
|
|
14475
|
-
"sha256": "
|
|
14485
|
+
"sha256": "bf44295f77e302358bd11cc0565bc98bc5d7f35a7fbb7d53405df469caee8c09"
|
|
14476
14486
|
},
|
|
14477
14487
|
{
|
|
14478
14488
|
"path": "tests/hub_cookie_host_only.mjs",
|
|
@@ -14752,7 +14762,7 @@
|
|
|
14752
14762
|
{
|
|
14753
14763
|
"path": "tests/instance_db_migrated_on_code_move.mjs",
|
|
14754
14764
|
"mode": "0000644",
|
|
14755
|
-
"sha256": "
|
|
14765
|
+
"sha256": "cf92e51be46c5b0e2edab94cd1e269f69c324bacb4f512adf5c23881ca810704"
|
|
14756
14766
|
},
|
|
14757
14767
|
{
|
|
14758
14768
|
"path": "tests/instance_feedback.mjs",
|
|
@@ -14882,7 +14892,7 @@
|
|
|
14882
14892
|
{
|
|
14883
14893
|
"path": "tests/landing_page.mjs",
|
|
14884
14894
|
"mode": "0000644",
|
|
14885
|
-
"sha256": "
|
|
14895
|
+
"sha256": "cfc8139b18524e5b5a10b69aa7eeef13427cc60bd2c0df3d19ce080ccc913fe4"
|
|
14886
14896
|
},
|
|
14887
14897
|
{
|
|
14888
14898
|
"path": "tests/leaderboard_roles.mjs",
|
|
@@ -15812,7 +15822,7 @@
|
|
|
15812
15822
|
{
|
|
15813
15823
|
"path": "tests/projects_hub_pre_uat.mjs",
|
|
15814
15824
|
"mode": "0000644",
|
|
15815
|
-
"sha256": "
|
|
15825
|
+
"sha256": "0344be486a7d4157818929c8adcdf8406f1370ca2e35722ddc2e84a1a9ba7cce"
|
|
15816
15826
|
},
|
|
15817
15827
|
{
|
|
15818
15828
|
"path": "tests/projects_hub_render_connect.mjs",
|
|
@@ -17297,7 +17307,7 @@
|
|
|
17297
17307
|
{
|
|
17298
17308
|
"path": "tests/upgrade.mjs",
|
|
17299
17309
|
"mode": "0000644",
|
|
17300
|
-
"sha256": "
|
|
17310
|
+
"sha256": "18174c07c227e872d210cf65e0ebd52a39eb1987d05e7e0eacdb077179380712"
|
|
17301
17311
|
},
|
|
17302
17312
|
{
|
|
17303
17313
|
"path": "tests/upgrade_artist_gate.mjs",
|
|
@@ -17317,7 +17327,7 @@
|
|
|
17317
17327
|
{
|
|
17318
17328
|
"path": "tests/upgrade_outcome.mjs",
|
|
17319
17329
|
"mode": "0000644",
|
|
17320
|
-
"sha256": "
|
|
17330
|
+
"sha256": "b09c536651f8f2305451b96c2a182bbe1dd0cc8950d13ba2570cec03be4e4ff2"
|
|
17321
17331
|
},
|
|
17322
17332
|
{
|
|
17323
17333
|
"path": "tests/upgrade_persist_pin.mjs",
|
|
@@ -17427,7 +17437,7 @@
|
|
|
17427
17437
|
{
|
|
17428
17438
|
"path": "tests/wedge_remedy.mjs",
|
|
17429
17439
|
"mode": "0000644",
|
|
17430
|
-
"sha256": "
|
|
17440
|
+
"sha256": "dfb1683e7654269be0c92fce88954aa25146027373581d3b8bfcc6fbdf11f2b0"
|
|
17431
17441
|
},
|
|
17432
17442
|
{
|
|
17433
17443
|
"path": "tests/wizard_born_first_board.mjs",
|
|
@@ -17442,7 +17452,7 @@
|
|
|
17442
17452
|
{
|
|
17443
17453
|
"path": "tests/wizard_draft_resume.mjs",
|
|
17444
17454
|
"mode": "0000644",
|
|
17445
|
-
"sha256": "
|
|
17455
|
+
"sha256": "2a5891107a8ad920ec3badff34ddd1ab96a7685a11884c2709747f944b0d5916"
|
|
17446
17456
|
},
|
|
17447
17457
|
{
|
|
17448
17458
|
"path": "tests/wizard_front_door.mjs",
|
|
@@ -17452,7 +17462,7 @@
|
|
|
17452
17462
|
{
|
|
17453
17463
|
"path": "tests/wizard_intent_resume.mjs",
|
|
17454
17464
|
"mode": "0000644",
|
|
17455
|
-
"sha256": "
|
|
17465
|
+
"sha256": "683dbd4b608b65977e1ebbd1fed4916ff0ed74eead0f379d2309e940779c4b1f"
|
|
17456
17466
|
},
|
|
17457
17467
|
{
|
|
17458
17468
|
"path": "tests/wizard_physics.mjs",
|
|
@@ -48,6 +48,9 @@ ADR 0128 anticipated the DB half in its own alternatives: *"Do createdb/migrate
|
|
|
48
48
|
|
|
49
49
|
> **Amended by task 1002719 — the app user is resolved, not named.** The account whose group every instance joins (and which owns the backup dir and runs the backup timers) was the founder's own account as a literal, so a standup on any other host died `invalid user` at the backup step. `appUser()` in `provision-repo.js` now answers it: `PROVISION_APP_USER`, else the account the runner runs as — which on a plane *is* the app user, so the founder box resolves exactly what the literal said. **root is refused, not resolved**: instance accounts join this account's group, and group root is not a read grant to hand a tenant. The name is validated before it reaches a shell command or a unit file, and the refusal is a preflight: it fires before the status flip, never midway through a standup. Its **group** is the account's primary group looked up on the box (`$(id -gn …)`; the backup unit carries no `Group=`), never the account name spelled twice — an admin-made service account need not have a group of its own name. `audit-authorship.sh` now flags the founder's unix account in account position (`-o`/`-u`, `User=`, `*user = '…'`) in runtime code, because the GitHub-login grep never could.
|
|
50
50
|
|
|
51
|
+
> **Amended by task 1004512 — the read-only grant is a ceiling, so an operation that WRITES the checkout cannot run as the instance account.** The partial stated above ("file-level co-tenant separation is not what this change delivers") has a sharp edge the design did not name: the instance account has *read* on the checkout and nothing more, so any operation given to it that writes there fails. `bongos upgrade` was given to it whole (task 1004128) and died at its first step — `git status` refused with `fatal: detected dubious ownership in repository`, because the repository is owned by the app user and the asking euid is not. The clean-tree pre-flight read that as a dirty tree, the self-heal chain committed a tree nobody had touched, and every core move on a project provisioned under this ADR ended in a blocker reporting dirt that did not exist. Had git been appeased with a `safe.directory` entry, `npm install`, the pin commit and the `.claude/` materialization would each have failed next, for the same reason and with less legible errors.
|
|
52
|
+
>
|
|
53
|
+
> **So a core move now runs as two accounts, split along what each one owns.** Everything touching the CHECKOUT (the clean-tree pre-flight, the pin, `npm install`, materialize, the pin commit) runs as the app user, which owns it — the same account `pushUpgradePin` and the wedge remedy already used for their own `git` calls. Everything touching the DATABASE (the identity pre-check, migrate, the ledger insert) runs as the instance account through `sudo -n -u`, because that is where this ADR's isolation actually lives: the role owns the database and `PUBLIC` holds no `CONNECT`, so no other account can reach it. `resolveRunAs` answers both (`runAs`, `migrateAs`) and the runner passes `--migrate-as` only when they differ, so a control plane and a project predating this ADR emit the command they always did. **Nothing in this decision is relaxed** — the `/proc` and database boundaries are untouched; what changed is that work needing write access stopped being handed to an account deliberately denied it.
|
|
51
54
|
## Alternatives considered
|
|
52
55
|
|
|
53
56
|
- **A `DATABASE_URL` in `web.env` instead of discrete `PG*` vars.** `pool.js` already prefers it, so it would have needed no pool change at all. Rejected: the socket path has to ride as `?host=…` or a percent-encoded authority, and the exact parse is `pg-connection-string`'s business rather than something the test could pin — trading a stated, assertable identity for a URL whose behavior we would be trusting.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# ADR 0364 — Repo access is asked at sign-in on the hub, and held for as long as the builder stays signed in
|
|
2
|
+
|
|
3
|
+
- **Status:** Accepted.
|
|
4
|
+
- **Date:** 2026-10-02
|
|
5
|
+
- **Task:** [task 1004549](https://cloudbongos.com/builders#/task/1004549).
|
|
6
|
+
- **Amends:** [ADR 0143](0143-onboarding-repo-picker-oauth-scope.md) (the repo token's short hold) and [ADR 0155](0155-adopt-private-repo-widen-oauth-scope.md) (where the `repo` scope is asked).
|
|
7
|
+
|
|
8
|
+
## Context
|
|
9
|
+
|
|
10
|
+
The owner reported that "Allow repo access" in the create wizard's review step threw them out of the flow, and never seemed to reach GitHub. Both parts were true:
|
|
11
|
+
|
|
12
|
+
- GitHub already held the owner's approval of the `repo` scope, so its authorize step answered at once and bounced straight back. The round-trip looked like a reload.
|
|
13
|
+
- The platform asked again because it kept its copy of the token for one hour only (`GITHUB_TOKEN_TTL_MS`). An owner who signed in from the front page, or more than an hour earlier, was sent away from the middle of the wizard to fetch a grant GitHub already held.
|
|
14
|
+
- The bounce then landed on the wrong screen. With a project created earlier in the same tab, `enter()` passed every arrival to `enterCreated()`, which treats a non-deliberate arrival as "the same visit, show the watched project". So the founder landed on the earlier project's done panel instead of their draft.
|
|
15
|
+
|
|
16
|
+
## Decision
|
|
17
|
+
|
|
18
|
+
**D1 — Every sign-in door on the hub's own pages asks for repo access.** These are the front page, the projects hub (bar, Your-projects gate, manage gate, the wizard's own door and its 401 recoveries) and the account page. All of them carry `repos=1`. It is asked once, when the person signs in, because anyone signing in on the hub is there to create or run a project, which needs it. The builders' hall and the CLI sign-ins stay identity-only. That is ADR 0143's least-privilege default, and it is unchanged where the person may only be joining someone else's project.
|
|
19
|
+
|
|
20
|
+
**D2 — The token lives as long as the session it arrived with.** The callback passes the web session's remaining life (30 days today) to `upsertGithubToken` as its TTL. The one-hour constant remains only as the fallback for when no session expiry is known. A **web** sign-out deletes the token. A CLI logout (bearer header) leaves it alone, because the browser session that granted it is still live. Offboarding and a GitHub-side revocation (401) still delete it, as before.
|
|
21
|
+
|
|
22
|
+
**D3 — A GitHub round-trip never loses the founder's place.** If a draft sits at a wizard step (1–5) beside a stored create, the draft wins on any non-deliberate arrival: a reload, or a return from GitHub. The earlier project stays one click away on the resume line. A deliberate nav and the resume link still go through `enterCreated()` exactly as task 1003503 built it. The review step's "Allow repo access" offer remains as the backup for a session that predates this change.
|
|
23
|
+
|
|
24
|
+
## Consequences
|
|
25
|
+
|
|
26
|
+
- A first-time visitor signing in on the hub now sees GitHub's repository-access wording at sign-in, rather than at the review step. GitHub words it as full control of all their repositories. The wizard's own explanation still sits beside the review step's backup offer. The front page's sign-in pill carries none, which is the cost of asking at the door.
|
|
27
|
+
- The platform holds a powerful credential for up to 30 days instead of one hour. It is still encrypted at rest with secret-box, keyed to one builder and never returned to a client, and it is never stored at all when secret-box is unconfigured. A server compromise during that window exposes more than it did. The owner accepted this explicitly (2026-10-02).
|
|
28
|
+
- Tests: `tests/github_token_session_life.mjs` (D2, over the real auth router), `tests/wizard_draft_resume.mjs` slice 4 (D3), and the updated sign-in href pins in `landing_page`, `hub_account_page` and `projects_hub_pre_uat`.
|
|
29
|
+
|
|
30
|
+
Rejected: keeping the ask inside the wizard and moving it to the first screen. That is still a stop in the middle of a flow, and the owner preferred sign-in. Silently refreshing the token in the background: it needs a GitHub round-trip, which is a navigation, not a background call.
|
package/docs/adr/README.md
CHANGED
|
@@ -482,3 +482,4 @@ These 20 numbers are each shared by exactly two files. They are **accepted histo
|
|
|
482
482
|
| 0361 | [**Merges publish as candidates; Release on /deploy decides what other projects are offered** ([task 1004298](https://cloudbongos.com/builders#/task/1004298), goal 1000090). Amends ADR 0161. **D1:** merges publish under `next` when `PUBLISH_AS_CANDIDATE=1` (ships inert). **D2:** a `release` job in publish.yml moves `latest` (release-core.js: published, stable, newer than the release) over the same OIDC trusted publisher — no npm token. **D3:** /deploy's Release button (`core.pin.move`) dispatches it through the one-function `lifecycle.workflowDispatch` port. **D4:** evidence beside each button — hours on this hall, ever rolled back. **D5:** the banner and the hosted-project runner offer only released versions; the control-plane row follows candidates. Arming: roster follow → npm dist-tag permission → GitHub credential Actions: write → the variable.](0361-merges-publish-as-candidates-release-decides-what-others-are-offered.md) | publish / release / update channel |
|
|
483
483
|
| 0362 | [**The governor's docket is collected from sources each module contributes, scoped by each source's own atom** ([task 1004523](https://cloudbongos.com/builders#/task/1004523), goal 1000125). **D1:** one contribution point, `governor.docket`; each owner contributes its source on the read its own list route serves. **D2:** a source declares its list route's atom and the collector enforces it (gated out = `not_yours`, no rows; no gate = dropped). **D3:** nothing invented: `coming` / `off` / `unavailable`. **D4:** the board's needs-you is the /me summons rule. **D5:** `GET /government/docket` gates on `board.vote.cast`.](0362-the-governor-docket-is-collected-from-contributed-sources.md) | government / Governor City |
|
|
484
484
|
| 0363 | [**Who decides what is a per-project table, changed only by a passed amendment** ([task 1004529](https://cloudbongos.com/builders#/task/1004529), goal 1000125). **D1:** `government_decision_rules`, one row per building: `gate` (as today), `board` (the charter only), `nobody` (vacant) or a membership predicate with decide / first / consent / majority / unanimous / sign-off. **D2:** the seeded defaults are today, and a malformed row reads as its default. **D3:** written only inside the transaction that closes a `decision_rules` amendment as passed; JS guard + SQL condition + trigger; no settings route. **D4:** eight building matters join the board's three subjects, openable only where a row names a sitting; sign-off is the author rule. **D5:** People's rank assignments defer to People's row (`checkActAlone`); a passed People matter acts. **D6:** the docket's buildings carry who decides.](0363-who-decides-what-is-a-table-changed-only-by-amendment.md) | government / Governor City |
|
|
485
|
+
| 0364 | [**Repo access is asked at sign-in on the hub, and held for as long as the builder stays signed in** ([task 1004549](https://cloudbongos.com/builders#/task/1004549)). Amends ADR 0143 and 0155. **D1:** every sign-in door on the hub's own pages carries `repos=1`; the hall and CLI stay identity-only. **D2:** the repo token's TTL is the web session's remaining life; a web sign-out deletes it, a CLI logout does not. **D3:** a draft at a wizard step beside a stored create keeps its place on a reload or a GitHub round-trip.](0364-repo-access-is-asked-at-sign-in-and-held-for-the-session.md) | auth / GitHub / create wizard |
|