@bongos/core 1.19.819 → 1.19.821

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 (43) hide show
  1. package/.bongos-core.json +77 -42
  2. package/.claude/skills/builder-end/SKILL.md +1 -1
  3. package/clients/bongos-client/index.d.ts +1 -1
  4. package/docs/adr/0021-per-builder-skill-model-preferences.md +1 -1
  5. package/docs/adr/0024-multi-agent-system-architecture.md +1 -1
  6. package/docs/adr/0026-bfg-memory-hygiene-and-cross-builder-learning.md +1 -1
  7. package/docs/adr/0028-honest-llm-spend-accounting.md +1 -1
  8. package/docs/adr/0035-builder-onboarding-three-paths.md +1 -1
  9. package/docs/adr/0055-server-mediated-branch-publish.md +1 -1
  10. package/docs/adr/0058-automatic-gate-surface-gatekeeper.md +1 -1
  11. package/docs/adr/0059-single-approval-remove-devbox-approval-gate.md +1 -1
  12. package/docs/adr/0060-gds-retrieval-layer.md +1 -1
  13. package/docs/adr/0070-deterministic-session-card-delivery.md +1 -1
  14. package/docs/adr/0073-builder-needs-signal-and-byok-gemini-key.md +1 -1
  15. package/docs/adr/0081-tool-agnostic-design-layer.md +2 -2
  16. package/docs/adr/0086-goal-scoped-work-hierarchy.md +4 -4
  17. package/docs/adr/0117-api-versioning-and-deprecation-policy.md +1 -1
  18. package/docs/api/openapi.json +4 -2
  19. package/docs/copy-inventory.md +23 -18
  20. package/docs/copy-registry.json +76 -31
  21. package/docs/module-api-changelog.md +5 -1
  22. package/docs/recipes/multi-builder-merge.md +2 -2
  23. package/docs/recipes/search-index-ingestion.md +2 -2
  24. package/migrations/core_246_session_type.sql +49 -0
  25. package/modules/hall-ui/public/sessions.css +19 -0
  26. package/modules/hall-ui/public/sessions.html +16 -1
  27. package/modules/hall-ui/public/sessions.js +135 -6
  28. package/modules/sessions/db.js +92 -6
  29. package/modules/sessions/routes/sessions.js +18 -1
  30. package/modules/sessions/session-type.js +132 -0
  31. package/package-lock.json +2 -2
  32. package/package.json +1 -1
  33. package/scripts/gds/backfill-session-types.js +87 -0
  34. package/scripts/gds/fitness.js +12 -1
  35. package/scripts/gds/home-isolation-guard.js +126 -0
  36. package/scripts/gds/ship-merge.js +5 -1
  37. package/scripts/gds/ship-regen.js +29 -0
  38. package/src/module-api.js +1 -1
  39. package/tests/cli_package.mjs +18 -2
  40. package/tests/hall_roster_world.mjs +10 -5
  41. package/tests/home_isolation_guard.mjs +95 -0
  42. package/tests/session_type.mjs +215 -0
  43. package/tests/ship_regen_copy_inventory.mjs +69 -0
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.819",
6
- "core_contract": "1.19.819",
7
- "source_commit": "b56f301dfa5e889c7f8e46624eb564de4bed3510",
5
+ "core_version": "1.19.821",
6
+ "core_contract": "1.19.821",
7
+ "source_commit": "8010be7b18c8402b4992ca02d3ea6486e3864b8d",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-09-17T09:33:00.702Z",
9
+ "built_at": "2026-09-17T10:54:28.375Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
12
  "docs_redacted": 490,
13
13
  "agent_docs_stubbed": 26,
14
- "functional_verbatim": 2220,
14
+ "functional_verbatim": 2227,
15
15
  "rules": 3,
16
16
  "gate_literals": 3,
17
17
  "gate": "passed"
18
18
  },
19
- "file_count": 2736,
20
- "tree_sha256": "235bf7bed8d6ad67aa73deddbbb1dc9a87fa6a697935f24b52bf2cdf5c299139",
19
+ "file_count": 2743,
20
+ "tree_sha256": "b45cfd41d39a01485663e30b259328725d4eb07530cb520214df9811d2842e0b",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/ask-for-help/SKILL.md",
@@ -62,7 +62,7 @@
62
62
  {
63
63
  "path": ".claude/skills/builder-end/SKILL.md",
64
64
  "mode": "0000644",
65
- "sha256": "60573c4e129df5bb386e7588989fbb407dfd1b88b4b9d567b2415d3e597f54da"
65
+ "sha256": "6f410236fa6fed591838b52a1d962210ed3c376e1feb439755c39930edd96ede"
66
66
  },
67
67
  {
68
68
  "path": ".claude/skills/builder-exit/SKILL.md",
@@ -367,7 +367,7 @@
367
367
  {
368
368
  "path": "clients/bongos-client/index.d.ts",
369
369
  "mode": "0000644",
370
- "sha256": "d2b1b59658899d95484cea739fad158009c1d5365881854b117e8350e09521d3"
370
+ "sha256": "7f48743a6878f01e484b8f2884b4b12588b956db307fd6bc83a67a19df61a52b"
371
371
  },
372
372
  {
373
373
  "path": "clients/bongos-client/index.mjs",
@@ -517,7 +517,7 @@
517
517
  {
518
518
  "path": "docs/adr/0021-per-builder-skill-model-preferences.md",
519
519
  "mode": "0000644",
520
- "sha256": "bcd0b55d7fd83e3e8877c55dbddbc9c101a2627f1a7be29207ab3e3bf8732e71"
520
+ "sha256": "12ee736d317c0076261f469c7fa010f71625329d81ee15bf2f069af80850826a"
521
521
  },
522
522
  {
523
523
  "path": "docs/adr/0022-secrets-policy.md",
@@ -537,7 +537,7 @@
537
537
  {
538
538
  "path": "docs/adr/0024-multi-agent-system-architecture.md",
539
539
  "mode": "0000644",
540
- "sha256": "0aa00a713d3c15f456d535c15968547141df4f76f6b351a86c4c50132bad937c"
540
+ "sha256": "f446e8a7b535cd9b35a7255c2e78179ca287c16985f4b3e294c4282c5b1cfab4"
541
541
  },
542
542
  {
543
543
  "path": "docs/adr/0025-offsite-backup-vendor-digitalocean-spaces.md",
@@ -552,7 +552,7 @@
552
552
  {
553
553
  "path": "docs/adr/0026-bfg-memory-hygiene-and-cross-builder-learning.md",
554
554
  "mode": "0000644",
555
- "sha256": "4e337e424c15df34f411877ecc371ad2e8f111c9922f9898eedc648d5d9bb1fe"
555
+ "sha256": "50d275eeea0cac619c5806583db070a3b95ab4e350a89e2b99e9d6fd4022332d"
556
556
  },
557
557
  {
558
558
  "path": "docs/adr/0027-bfg-session-inefficiency-evaluator.md",
@@ -562,7 +562,7 @@
562
562
  {
563
563
  "path": "docs/adr/0028-honest-llm-spend-accounting.md",
564
564
  "mode": "0000644",
565
- "sha256": "31a0378984e53c9cb08370f70f3dca296cf532c1bf7e55a39c898683b1cb0c22"
565
+ "sha256": "7d8e8a3de946d3ddd2b9ee2d717b067fdcf7ecaa66bad814fd4567846b4c749e"
566
566
  },
567
567
  {
568
568
  "path": "docs/adr/0029-status-page-outage-resilience.md",
@@ -597,7 +597,7 @@
597
597
  {
598
598
  "path": "docs/adr/0035-builder-onboarding-three-paths.md",
599
599
  "mode": "0000644",
600
- "sha256": "e411de75d8fa21b6870d5ca85052e3608b7fc59505990fd19bd23ac4c474b0e9"
600
+ "sha256": "eefc4f6a5d9090c853bcb45d03e1b5fb410910a003b08331dbf16a3d50836e80"
601
601
  },
602
602
  {
603
603
  "path": "docs/adr/0036-builders-subdomain-and-ui-reorg.md",
@@ -702,7 +702,7 @@
702
702
  {
703
703
  "path": "docs/adr/0055-server-mediated-branch-publish.md",
704
704
  "mode": "0000644",
705
- "sha256": "4b2b10b4ae53c2b5c33d1220563b3021822c3ddc5e1a5034afc04a0d286f7bec"
705
+ "sha256": "09b32b0cf2f01db37797c6f99262b37dd5be51a47a57cb5005c49e9058c06c81"
706
706
  },
707
707
  {
708
708
  "path": "docs/adr/0056-prod-deploy-script-mirror-and-healthcheck-retry.md",
@@ -722,17 +722,17 @@
722
722
  {
723
723
  "path": "docs/adr/0058-automatic-gate-surface-gatekeeper.md",
724
724
  "mode": "0000644",
725
- "sha256": "308a1342c514ef4028da846a8b3963df4a3908e72e1ed3a688fe1c1e51c67ec9"
725
+ "sha256": "35b2bfccd503b150c3e6587564c1e1779400bdbf1899ee2346c31eb19d8b2681"
726
726
  },
727
727
  {
728
728
  "path": "docs/adr/0059-single-approval-remove-devbox-approval-gate.md",
729
729
  "mode": "0000644",
730
- "sha256": "adb7a32e2afc71212a680fd59443e4435a884758053f78509ec6bc7b8f738e23"
730
+ "sha256": "6b425c8416bf8695c5a85b93d0f24e3db9d1a43ee9fa3032aa38a9178fbb740a"
731
731
  },
732
732
  {
733
733
  "path": "docs/adr/0060-gds-retrieval-layer.md",
734
734
  "mode": "0000644",
735
- "sha256": "9d0546a4d24f38f1632aa94789c3d599777ff9dbf9664929993934f6b2ffcd1f"
735
+ "sha256": "9f965ad0eb78ea5e5dd83f46426129a593335bb35e312209d1cfe3a240d53be3"
736
736
  },
737
737
  {
738
738
  "path": "docs/adr/0061-context-layer-decomposition.md",
@@ -782,7 +782,7 @@
782
782
  {
783
783
  "path": "docs/adr/0070-deterministic-session-card-delivery.md",
784
784
  "mode": "0000644",
785
- "sha256": "b8ecbe554ac874f415bca4e31198e77f574fdba7fc0d2a6f9491701094203062"
785
+ "sha256": "f215a47f3432a8efce4b9fd7a9eb90dd3221ca314b8fa8ca35486464f3027769"
786
786
  },
787
787
  {
788
788
  "path": "docs/adr/0071-box-confirm-before-destroyed-and-drift-reconcile.md",
@@ -802,7 +802,7 @@
802
802
  {
803
803
  "path": "docs/adr/0073-builder-needs-signal-and-byok-gemini-key.md",
804
804
  "mode": "0000644",
805
- "sha256": "b7e794e23d06b44d7e4cbdc4985275aa4c26b5b88aa5a5c019881ac0b88bfaa7"
805
+ "sha256": "cf5981d3c27dfed8e2f02b07a77c9de08a8df6bda0a746ecd3bc0943d30d64da"
806
806
  },
807
807
  {
808
808
  "path": "docs/adr/0073-secrets-scan-exclude-uri-detector.md",
@@ -847,7 +847,7 @@
847
847
  {
848
848
  "path": "docs/adr/0081-tool-agnostic-design-layer.md",
849
849
  "mode": "0000644",
850
- "sha256": "6fbbd598f08196d32253f15a797dd20bdc28cb7c38930e10f9dcf5467e6dbf97"
850
+ "sha256": "d2f5de4793bf1e9cd184a4bfc2cddb9dd44c560e42e3ef8d0f0e6668fd84d69a"
851
851
  },
852
852
  {
853
853
  "path": "docs/adr/0082-productized-key-storage-provisioning.md",
@@ -877,7 +877,7 @@
877
877
  {
878
878
  "path": "docs/adr/0086-goal-scoped-work-hierarchy.md",
879
879
  "mode": "0000644",
880
- "sha256": "db082db26afc1fefd429c826ba934e99ff1e127cd0b099810de1b9e83ef8514f"
880
+ "sha256": "15c590ed8bb381435564f4ba797f8933b2332620da6178e2f2b47c22feedc15b"
881
881
  },
882
882
  {
883
883
  "path": "docs/adr/0087-bongos-app-architecture-and-handoff-contract.md",
@@ -1052,7 +1052,7 @@
1052
1052
  {
1053
1053
  "path": "docs/adr/0117-api-versioning-and-deprecation-policy.md",
1054
1054
  "mode": "0000644",
1055
- "sha256": "738b956bbf896aabdfd28b7f885b47e4b44cce6406d9ac9a5b67a23f3b0cac5d"
1055
+ "sha256": "6a9f4f42867cfd07f7ad85b2d7fc8dab58f6e6ce0c7e0145cb7d58aa16955619"
1056
1056
  },
1057
1057
  {
1058
1058
  "path": "docs/adr/0118-api-contract-source-of-truth-code-first.md",
@@ -1992,7 +1992,7 @@
1992
1992
  {
1993
1993
  "path": "docs/api/openapi.json",
1994
1994
  "mode": "0000644",
1995
- "sha256": "28a4aec3929aefa72cfdffc1bcad6eba5ce1d3bb00518e28eddee631f219dfe5"
1995
+ "sha256": "11ffe0dfc04855064064f335396b1b57887a1d4e61b21559c376d279ea7513fd"
1996
1996
  },
1997
1997
  {
1998
1998
  "path": "docs/architecture.md",
@@ -2017,12 +2017,12 @@
2017
2017
  {
2018
2018
  "path": "docs/copy-inventory.md",
2019
2019
  "mode": "0000644",
2020
- "sha256": "4e21dfe9140f8da88b5ba49d7d2c380196408073253e915198ab5f9cdbeab933"
2020
+ "sha256": "1e6864ea2bb93e1fb03ec61bb9f462937ff8d3a73645fcda5a3902b88a4093ae"
2021
2021
  },
2022
2022
  {
2023
2023
  "path": "docs/copy-registry.json",
2024
2024
  "mode": "0000644",
2025
- "sha256": "cb8da77e04f8fa238c513bf2fc04f4f00a13527022e2fbb34dd607ddced16bdd"
2025
+ "sha256": "153a5874fbcc691ce74495bea2ea5cdc321c4e5d61054788abe531f5eab537d5"
2026
2026
  },
2027
2027
  {
2028
2028
  "path": "docs/design/apex-pass-2-direction.md",
@@ -2547,7 +2547,7 @@
2547
2547
  {
2548
2548
  "path": "docs/module-api-changelog.md",
2549
2549
  "mode": "0000644",
2550
- "sha256": "671ac9949acbb7120d9a6b3acf43082dba90d2c5119afb61b7cd215fbbec2fdc"
2550
+ "sha256": "9d562958c91d14116733518e2934b1a78b980adc6a19c652cfe47eb85c3693bf"
2551
2551
  },
2552
2552
  {
2553
2553
  "path": "docs/modules-contract.md",
@@ -2732,7 +2732,7 @@
2732
2732
  {
2733
2733
  "path": "docs/recipes/multi-builder-merge.md",
2734
2734
  "mode": "0000644",
2735
- "sha256": "048875fdcbd2e6637f19b96e3b6660434e4ceb68b5ee171580a6d6a13b39242b"
2735
+ "sha256": "368b0acc045087c8aff34b3a551ced958e6e87987afcf6c3210eff093c8a9eea"
2736
2736
  },
2737
2737
  {
2738
2738
  "path": "docs/recipes/ops-gotchas.md",
@@ -2772,7 +2772,7 @@
2772
2772
  {
2773
2773
  "path": "docs/recipes/search-index-ingestion.md",
2774
2774
  "mode": "0000644",
2775
- "sha256": "70989ad134f5aaffc08007a180bfa5f9cccceef780346a965fcade293490dc71"
2775
+ "sha256": "dd333b764d0ed25162b6bee7f02cb5231d7384918abb30a05ad3a18aa099f4dd"
2776
2776
  },
2777
2777
  {
2778
2778
  "path": "docs/recipes/self-host.md",
@@ -3644,6 +3644,11 @@
3644
3644
  "mode": "0000644",
3645
3645
  "sha256": "b51a03436ede7269f32f6b1e9400070dcbe3895ab64088ca27da5406cbcf5eea"
3646
3646
  },
3647
+ {
3648
+ "path": "migrations/core_246_session_type.sql",
3649
+ "mode": "0000644",
3650
+ "sha256": "0481e0b8205c707ed002f404c801d3f2059b2b0e0fcfa9bc436968f6665a296f"
3651
+ },
3647
3652
  {
3648
3653
  "path": "modules/agents/CLAUDE.md",
3649
3654
  "mode": "0000644",
@@ -5227,17 +5232,17 @@
5227
5232
  {
5228
5233
  "path": "modules/hall-ui/public/sessions.css",
5229
5234
  "mode": "0000644",
5230
- "sha256": "a76ccf7d6dabbc0a13135247d2169b59ff5b67c98148626988ee8a9e214a9d8f"
5235
+ "sha256": "33d03e1b23898e5bdefdee514ab09fa4ab92c236bce82250b4402b1a6e463a5e"
5231
5236
  },
5232
5237
  {
5233
5238
  "path": "modules/hall-ui/public/sessions.html",
5234
5239
  "mode": "0000644",
5235
- "sha256": "4e11a2472cc56043fa6ff7d95d1ded217ae89a87b377bcb9eb941adc107ef565"
5240
+ "sha256": "3a3a17d9623e601c2c45d9c87f34ad3b29c7ba495658dda9900086ecd47a64de"
5236
5241
  },
5237
5242
  {
5238
5243
  "path": "modules/hall-ui/public/sessions.js",
5239
5244
  "mode": "0000644",
5240
- "sha256": "c9a5f1c7e558dc7edebf5047a1e10f002247d3a0e248bc7ab78cade0f94229f7"
5245
+ "sha256": "c5069163675001d8249948769ddcf42f125eb18fd62891a8a8052b26bb83013e"
5241
5246
  },
5242
5247
  {
5243
5248
  "path": "modules/hall-ui/public/sessions.states.json",
@@ -7262,7 +7267,7 @@
7262
7267
  {
7263
7268
  "path": "modules/sessions/db.js",
7264
7269
  "mode": "0000644",
7265
- "sha256": "b8d46d5bea53a3b4c903d25863cbdc3ab0045b8a6a60e300ac2040050f1ce119"
7270
+ "sha256": "cc57b04cea74b500af2980fa5517900606d49547432dcb6c9286a38c6b855bde"
7266
7271
  },
7267
7272
  {
7268
7273
  "path": "modules/sessions/module.json",
@@ -7287,7 +7292,12 @@
7287
7292
  {
7288
7293
  "path": "modules/sessions/routes/sessions.js",
7289
7294
  "mode": "0000644",
7290
- "sha256": "0770b21c54d78a7e6277d3aa4bff3f2be9b6469f0add2d5468283030840a906b"
7295
+ "sha256": "501a9a4ae7ec695c40ea98d40661ea3b8d8428ea308c2bc2549c3adaf8ee092c"
7296
+ },
7297
+ {
7298
+ "path": "modules/sessions/session-type.js",
7299
+ "mode": "0000644",
7300
+ "sha256": "75f0e8a5627aa4763fd18fd4aea945056130861c1ee93e1405ec0da8f5edb051"
7291
7301
  },
7292
7302
  {
7293
7303
  "path": "modules/sessions/upload-health.js",
@@ -7802,12 +7812,12 @@
7802
7812
  {
7803
7813
  "path": "package-lock.json",
7804
7814
  "mode": "0000644",
7805
- "sha256": "80eb7e1ecf3c324277a00d732da45ff1e094ac64e4ba176777395fc5c4cb33e4"
7815
+ "sha256": "bd6442d6f7a4122841efdb7ed6d796e43f9df2bb4a65677d19d586af19cb0650"
7806
7816
  },
7807
7817
  {
7808
7818
  "path": "package.json",
7809
7819
  "mode": "0000644",
7810
- "sha256": "30a0133ce3cc21770d6915e5d7bd65d7c8a3a8e0494d0eb0e3230586f66f0876"
7820
+ "sha256": "8185455c292222a25c1928dc9ef4959bc09783fb71fc231e89dca09793239e44"
7811
7821
  },
7812
7822
  {
7813
7823
  "path": "public-docs/index.html",
@@ -7979,6 +7989,11 @@
7979
7989
  "mode": "0000644",
7980
7990
  "sha256": "c25865910384689095e0e62e0ea1df888933e8c3da9653ba1e9f2291ef64c3e1"
7981
7991
  },
7992
+ {
7993
+ "path": "scripts/gds/backfill-session-types.js",
7994
+ "mode": "0000644",
7995
+ "sha256": "551dc5a07fe069c23ac3b444d306709192b36f544bd3156653a2d26746dea397"
7996
+ },
7982
7997
  {
7983
7998
  "path": "scripts/gds/backfill-sessions.js",
7984
7999
  "mode": "0000644",
@@ -8342,7 +8357,7 @@
8342
8357
  {
8343
8358
  "path": "scripts/gds/fitness.js",
8344
8359
  "mode": "0000644",
8345
- "sha256": "ae592ffeaff620254f0c08774579ab6bee3d3440801067937e280d5f8cd50768"
8360
+ "sha256": "8725f7a8dcdd6445e8d2379e24c3985624b1889cc67be055cce8365b312457d2"
8346
8361
  },
8347
8362
  {
8348
8363
  "path": "scripts/gds/gate-review.js",
@@ -8459,6 +8474,11 @@
8459
8474
  "mode": "0000644",
8460
8475
  "sha256": "14bc150d985492f180c5a22cadfffcfa355be2543ba54d7f20876dd6a4d364ee"
8461
8476
  },
8477
+ {
8478
+ "path": "scripts/gds/home-isolation-guard.js",
8479
+ "mode": "0000644",
8480
+ "sha256": "736c66bdb189f7c15a122bf9744a7211719434263fcdd0b26f5455e093d86530"
8481
+ },
8462
8482
  {
8463
8483
  "path": "scripts/gds/hooks/pre-push.js",
8464
8484
  "mode": "0000644",
@@ -9097,7 +9117,7 @@
9097
9117
  {
9098
9118
  "path": "scripts/gds/ship-merge.js",
9099
9119
  "mode": "0000644",
9100
- "sha256": "99401464922cc545681786e59ebdc5ad35ec5578f7562c7986e458af797e85ab"
9120
+ "sha256": "0a1a9be854950574c554ab4a38d92123eeb6b283f2e17a4a9c1ce07aa80beaee"
9101
9121
  },
9102
9122
  {
9103
9123
  "path": "scripts/gds/ship-preflight-steps.js",
@@ -9107,7 +9127,7 @@
9107
9127
  {
9108
9128
  "path": "scripts/gds/ship-regen.js",
9109
9129
  "mode": "0000644",
9110
- "sha256": "778615b383916f692188657896bfde82cc091897c99e03afb429ffec58eef692"
9130
+ "sha256": "71b4cbb7ba05408737cd845e0bded390e25dcb80b6b5d3a873afea498055fc74"
9111
9131
  },
9112
9132
  {
9113
9133
  "path": "scripts/gds/ship-resume.js",
@@ -9702,7 +9722,7 @@
9702
9722
  {
9703
9723
  "path": "src/module-api.js",
9704
9724
  "mode": "0000644",
9705
- "sha256": "37b1b65e9b2e4136ec74c3d22f13da1a58740de5f1a6e4ddd29dd46cc544eb1f"
9725
+ "sha256": "363876fc33b090bf88ca7b767b82778feb63ee9bb607c00e4a37a2aae0b5416f"
9706
9726
  },
9707
9727
  {
9708
9728
  "path": "src/module-loader/catalog.js",
@@ -10432,7 +10452,7 @@
10432
10452
  {
10433
10453
  "path": "tests/cli_package.mjs",
10434
10454
  "mode": "0000644",
10435
- "sha256": "334c952eadfdd7d5ee467cfd50a9f178a23389e94288cdb6a431c69c6e8e327c"
10455
+ "sha256": "9c40324ec0faf739c6b78e428b43cd0c3f01a3f70bb9ded78b3cf33657098163"
10436
10456
  },
10437
10457
  {
10438
10458
  "path": "tests/cli_sessions.mjs",
@@ -11507,7 +11527,7 @@
11507
11527
  {
11508
11528
  "path": "tests/hall_roster_world.mjs",
11509
11529
  "mode": "0000644",
11510
- "sha256": "4e66d23ab4f61eb0d170b8fb66154b444cd22e52c4c5696b60002bfdfe682acb"
11530
+ "sha256": "fa735cfdf918e70b76be99c21d53cca971ceed78d379512b5ba9c36183d7cb72"
11511
11531
  },
11512
11532
  {
11513
11533
  "path": "tests/hall_sessions_ledger.mjs",
@@ -11559,6 +11579,11 @@
11559
11579
  "mode": "0000644",
11560
11580
  "sha256": "6853241b64b5f71dfb782956a4fab468a05aa2a9ee41d5159a4cbea5f0424f38"
11561
11581
  },
11582
+ {
11583
+ "path": "tests/home_isolation_guard.mjs",
11584
+ "mode": "0000644",
11585
+ "sha256": "b42c0338476c2fc7be72888b2eec1a79fcfb3ff1c27e85eff605d3248b2780e4"
11586
+ },
11562
11587
  {
11563
11588
  "path": "tests/hook_core_resolve.mjs",
11564
11589
  "mode": "0000644",
@@ -13024,6 +13049,11 @@
13024
13049
  "mode": "0000644",
13025
13050
  "sha256": "a630ac72981f230e8aa6609152765c13e8928ac329cb0ff3fe615371f31208d2"
13026
13051
  },
13052
+ {
13053
+ "path": "tests/session_type.mjs",
13054
+ "mode": "0000644",
13055
+ "sha256": "a04221d0f039e1fce28c4cd45f3fc6c5b2d0c43052482d6908981f83affd3585"
13056
+ },
13027
13057
  {
13028
13058
  "path": "tests/session_upload_health.mjs",
13029
13059
  "mode": "0000644",
@@ -13134,6 +13164,11 @@
13134
13164
  "mode": "0000644",
13135
13165
  "sha256": "d69bad6c8b3a01434b4fd5230f2b781bbe7fd9938df3d96b2a4ef34906287e54"
13136
13166
  },
13167
+ {
13168
+ "path": "tests/ship_regen_copy_inventory.mjs",
13169
+ "mode": "0000644",
13170
+ "sha256": "6cd0aa6964a55b0f57921b96de1cbcd405ca7eb6226191620a757e8e869d4792"
13171
+ },
13137
13172
  {
13138
13173
  "path": "tests/ship_resume.mjs",
13139
13174
  "mode": "0000644",
@@ -13,7 +13,7 @@ This is **not** `/builder-exit` — that deactivates an entire builder (releases
13
13
  Composes operations that already exist, in a safe order, with the destructive ones gated last:
14
14
 
15
15
  1. **Resolve the claim** — `/builder-ship` when there's committed, shippable work; `/builder-release` when there isn't. (It calls the sibling skills; it does not re-implement shipping.)
16
- 2. **Clean-git verify** — refuse to go further if any *tracked* file is uncommitted. This is the same guard `scripts/gds/ship.js` enforces (`trackedDirty` in [`src/bongos/ship-preflight.js`](../../../src/bongos/ship-preflight.js)): untracked scratch is ignored, but a modified/staged/deleted tracked file means real work isn't committed — stop before anything is lost.
16
+ 2. **Clean-git verify** — refuse to go further if any *tracked* file is uncommitted. This is the same guard `scripts/gds/ship.js` enforces (`trackedDirty` in [`modules/lifecycle/ship-preflight.js`](../../../modules/lifecycle/ship-preflight.js)): untracked scratch is ignored, but a modified/staged/deleted tracked file means real work isn't committed — stop before anything is lost.
17
17
  3. **Worktree teardown** — from the main checkout, remove this session's linked worktree via `node scripts/gds/worktree.js remove` (junction-aware), `prune`, and delete the now-merged `claude/<name>` branch.
18
18
 
19
19
  It never pushes to `main`, never `ssh`-es, never runs a deploy — landing is `/builder-ship`'s job (server-mediated). It only ever touches the caller's **own** claim and **own** worktree.
@@ -134,7 +134,7 @@ export interface GetSecurityReportsResponse { reports: unknown; bounty_table: un
134
134
  export interface GetSecurityScansResponse { scans: unknown }
135
135
  export interface GetSessionsIdResponse { session: unknown }
136
136
  export interface GetSessionsMineResponse { sessions: unknown; count: unknown }
137
- export interface GetSessionsSearchResponse { sessions: unknown; count: unknown; total: unknown; totals: unknown; limit: unknown; offset: unknown }
137
+ export interface GetSessionsSearchResponse { sessions: unknown; count: unknown; total: unknown; totals: unknown; limit: unknown; offset: unknown; session_types: unknown }
138
138
  export interface GetSpecialitiesIdDocumentsResponse { documents: unknown }
139
139
  export interface GetSpecialitiesIdResponse { speciality: unknown }
140
140
  export interface GetSpecialitiesOfferedResponse { suggestions: unknown }
@@ -93,7 +93,7 @@ If V4 retires per-skill defaults in favor of per-skill-*kind* defaults (the broa
93
93
  ## Cross-references
94
94
 
95
95
  - [Migration 037](../../migrations/037_builder_skill_model_prefs.sql) — the schema change.
96
- - [`src/bongos/skill-prefs.js`](../../src/bongos/skill-prefs.js) — the helper module and source of truth for defaults.
96
+ - [`modules/builder-settings/skill-prefs.js`](../../modules/builder-settings/skill-prefs.js) — the helper module and source of truth for defaults.
97
97
  - [`tests/skill_prefs.mjs`](../../tests/skill_prefs.mjs) — unit coverage for the pure helpers.
98
98
  - [ADR 0017](0017-code-simplification-and-repo-cleanliness.md) — same spirit: keep judgment work intentional, mechanism work cheap.
99
99
  - CLAUDE.md §2 — the project-wide subagent routing policy this ADR sits beside (not replaces — the policy is the default the matrix opens with).
@@ -10,7 +10,7 @@
10
10
 
11
11
  As the GDS opens to multiple builders, three structural risks scale faster than headcount:
12
12
 
13
- 1. **The ship-time grader is lenient by construction.** [`src/bongos/grader.js`](../../src/bongos/grader.js) v2 (V3.R18 / [#209](https://example.com/builders#/task/209)) runs a *single* Opus subagent against the diff. Opus wrote the code; Opus grades it. Academic LLM-as-judge work (Zheng et al. 2023, Chiang & Lee 2023) consistently documents ~10–15% same-family inflation. The prompt asks "what score?" rather than "find what's wrong, then decide if it passes" — the default-to-pass framing is the bias. The recorded 14-day passing rate (65/75 = 87%) is suspiciously high for un-calibrated work.
13
+ 1. **The ship-time grader is lenient by construction.** [`modules/grading/grader.js`](../../modules/grading/grader.js) v2 (V3.R18 / [#209](https://example.com/builders#/task/209)) runs a *single* Opus subagent against the diff. Opus wrote the code; Opus grades it. Academic LLM-as-judge work (Zheng et al. 2023, Chiang & Lee 2023) consistently documents ~10–15% same-family inflation. The prompt asks "what score?" rather than "find what's wrong, then decide if it passes" — the default-to-pass framing is the bias. The recorded 14-day passing rate (65/75 = 87%) is suspiciously high for un-calibrated work.
14
14
 
15
15
  2. **Methodology hygiene is reactive.** Documentation drift, dead code, and architectural sprawl are caught (if at all) by `overnight-code-review` and `repo-simplify-sweep` — both downstream of merge, both advisory, both already overfilling. No upstream gate looks at the *system* the way the grader looks at the diff.
16
16
 
@@ -22,7 +22,7 @@ This ADR records the architecture and, critically, the **boundaries** that turn
22
22
 
23
23
  ### What the substrate already gives us
24
24
 
25
- - **Builder memory is server-canonical and per-builder isolated** — [`builder_memory`](../../src/bongos/routes/memory.js), `PRIMARY KEY (builder_id, path)`. The *only* cross-builder access that exists today is an **Archon-only, audit-logged, read-only** forensic path. **There is no cross-builder *write* path at all** — that was a conscious decision ([ADR 0016](0016-trust-boundary-server-enforced-permissions.md), [ADR 0024-memory](0024-cloneable-repo-local-first-memory.md) §4).
25
+ - **Builder memory is server-canonical and per-builder isolated** — [`builder_memory`](../../modules/memory/routes/memory.js), `PRIMARY KEY (builder_id, path)`. The *only* cross-builder access that exists today is an **Archon-only, audit-logged, read-only** forensic path. **There is no cross-builder *write* path at all** — that was a conscious decision ([ADR 0016](0016-trust-boundary-server-enforced-permissions.md), [ADR 0024-memory](0024-cloneable-repo-local-first-memory.md) §4).
26
26
  - **Karma** ([`karma_log`](../../migrations/040_builder_karma.sql)) is the existing good-citizenship reputation ledger (append-only, `granted_by` records who drove a delta, `NULL` = system).
27
27
  - **Cron roles** live as `SKILL.md` files under [`.claude/scheduled-tasks/`](../../.claude/scheduled-tasks/); the read-only `overnight-code-review` routine is the closest existing pattern.
28
28
 
@@ -22,7 +22,7 @@ Capture the two sources at **two different seams**, because their cost data live
22
22
 
23
23
  ### 1. Grader cost — read it from the subprocess envelope (client-side, exact)
24
24
 
25
- `grader.runSubagent` spawns each worker as `claude -p --print --output-format json` ([src/bongos/grader.js](../../src/bongos/grader.js)). With `--output-format json`, the CLI returns a result envelope that includes **`total_cost_usd`** (and a `usage` block) — *verified* on a real call: `{type, …, total_cost_usd: 0.198, usage, modelUsage}`. The old `extractAssistantResult` parsed only `env.result` and **discarded the cost**.
25
+ `grader.runSubagent` spawns each worker as `claude -p --print --output-format json` ([modules/grading/grader.js](../../modules/grading/grader.js)). With `--output-format json`, the CLI returns a result envelope that includes **`total_cost_usd`** (and a `usage` block) — *verified* on a real call: `{type, …, total_cost_usd: 0.198, usage, modelUsage}`. The old `extractAssistantResult` parsed only `env.result` and **discarded the cost**.
26
26
 
27
27
  > **Correction (made during [#486](https://example.com/builders#/task/486) implementation):** the panel does **not** run server-side. `gradeSubagent` is invoked **client-side in `scripts/gds/ship.js`** (and `conductor-dispatch.js`); the server's `/tasks/:id/grade` route only *validates/scores* the result ship.js POSTs. So there is no in-process DB handle at grade time — the cost is logged over HTTP, exactly like the session path. The substance below (exact envelope cost, no pricing table) is unchanged; only the seam moved from `db.logCost` to `POST /api/gds/cost`.
28
28
 
@@ -13,7 +13,7 @@ A new builder can reach Example three different ways, but the project has never
13
13
 
14
14
  1. **The live onboarding contradicts the intended model.** Today the *only* fully-working setup path is the one documented in [`docs/onboarding/primer.md`](../onboarding/primer.md) "Get set up": **accept a GitHub collaborator invite and clone the private repo onto your own disk** — open to *every* rank, including a brand-new Xenos. ADR 0031 §6 says source access should be a *rank-gated, revocable, box-held* boundary. So the live behavior is the exact opposite of the locked design: an unproven newcomer currently gets a permanent local copy of the whole repo. This must be reconciled.
15
15
  2. **The box lane is built but has no front door.** ADR 0031 + [#701](https://example.com/builders#/task/701) shipped the whole provisioning spine — `POST /box/ensure`, the intent queue, the control-plane runner, the pairing-link path. But there is no *guided arrival*: nothing tells a non-technical or Chromebook builder, in plain language, "here is your first session, here is what to type, here is how you wait for your box." The capability exists; the on-ramp doesn't.
16
- 3. **Cost exposure is unbounded at the front door.** Anyone with a GitHub account can complete Device-Flow auth and become a Xenos, and a Xenos is above the box provisioning floor (`DEFAULT_PROVISION_FLOOR = 'xenos'`, [`src/bongos/boxes.js`](../../src/bongos/boxes.js)). With [#701](https://example.com/builders#/task/701)'s auto-draining intent queue, a signup could cause a paid droplet (~$24/mo, ~$5/active after auto-park) to be created with **zero human in the loop**. On a $5,000/yr budget that's a real hole.
16
+ 3. **Cost exposure is unbounded at the front door.** Anyone with a GitHub account can complete Device-Flow auth and become a Xenos, and a Xenos is above the box provisioning floor (`DEFAULT_PROVISION_FLOOR = 'xenos'`, [`modules/dev-box/boxes.js`](../../modules/dev-box/boxes.js)). With [#701](https://example.com/builders#/task/701)'s auto-draining intent queue, a signup could cause a paid droplet (~$24/mo, ~$5/active after auto-park) to be created with **zero human in the loop**. On a $5,000/yr budget that's a real hole.
17
17
 
18
18
  ## The three paths (what each *is*, who it's for, how it's gated)
19
19
 
@@ -26,7 +26,7 @@ A box-scoped token still cannot ship. The builder runs **`/builder-reauth`** (th
26
26
 
27
27
  - `POST /api/gds/tasks/:id/publish-branch` — `auth.requireBuilder` + `gateTaskOwnership` (the same [#871](https://example.com/builders#/task/871) gate as `/grade`/`/confirm`/`/ship`), **deliberately without `auth.allowBoxScope`**, so a box-scoped session is `403 box_scope`. Accepts the branch as a **thin git bundle** (base64, `origin/main..HEAD`), `head_sha`, and `value_summary`. The server: writes the bundle to a per-request temp dir, fast `git clone --bare --local` of its own checkout for `main`'s objects (no network, no worktree touch → never races the `deploy-prod.yml` reset), unbundles, **verifies the bundle tip == the claimed `head_sha`** (binds the pushed code to the already-graded sha), then `git push` to GitHub via a **one-shot `x-access-token:<redacted> URL** (never persisted, never logged — the `box-source-fetch.sh` pattern), opens the PR, and enables auto-merge.
28
28
  - `GET /api/gds/tasks/:id/publish-status?branch=…` — ownership-gated; the server derives PR + deploy state live from GitHub so `ship.js` confirms the land WITHOUT `gh` on the box. No DB column added.
29
- - Implementation: [`src/bongos/github-push.js`](../../src/bongos/github-push.js) (push/PR/status via `execFile` arg-arrays + raw `fetch`, all behind test seams), routes in [`src/bongos/routes/tasks.js`](../../src/bongos/routes/tasks.js), the bundle body bypasses the global 64 KB JSON cap via the skip-list in [`src/bongos/routes.js`](../../src/bongos/routes.js) (route-scoped 32 MB parser + a 20 MB decoded-byte cap).
29
+ - Implementation: [`modules/lifecycle/github-push.js`](../../modules/lifecycle/github-push.js) (push/PR/status via `execFile` arg-arrays + raw `fetch`, all behind test seams), routes in [`modules/lifecycle/routes/tasks.js`](../../modules/lifecycle/routes/tasks.js), the bundle body bypasses the global 64 KB JSON cap via the skip-list in [`src/bongos/routes.js`](../../src/bongos/routes.js) (route-scoped 32 MB parser + a 20 MB decoded-byte cap).
30
30
 
31
31
  ### 3. `ship.js` chooses the path automatically
32
32
 
@@ -46,7 +46,7 @@ The hard floor is the irreducible root of trust: a compromised or prompt-injecte
46
46
 
47
47
  ## Update — enforcing, and the two server-attestation vectors (task 1142, task 1169)
48
48
 
49
- The gatekeeper went **ENFORCING** (task 1142): `gate-review.yml` no longer sets `GATE_REPORT_ONLY`, and `gate-review` is a required check. The `GATE_AUTHOR_TRUSTED` signal is the `gate-author-trust` **commit status** — set only by the server (which alone holds the authenticated builder's server-resolved rank + the App/PAT credential), so CI reads it but cannot forge it. The server posts it via `githubPush.setCommitStatus` from **two** ship paths, sharing one helper (`postGateAuthorTrust` in [`src/bongos/routes/tasks.js`](../../src/bongos/routes/tasks.js)):
49
+ The gatekeeper went **ENFORCING** (task 1142): `gate-review.yml` no longer sets `GATE_REPORT_ONLY`, and `gate-review` is a required check. The `GATE_AUTHOR_TRUSTED` signal is the `gate-author-trust` **commit status** — set only by the server (which alone holds the authenticated builder's server-resolved rank + the App/PAT credential), so CI reads it but cannot forge it. The server posts it via `githubPush.setCommitStatus` from **two** ship paths, sharing one helper (`postGateAuthorTrust` in [`modules/lifecycle/routes/tasks.js`](../../modules/lifecycle/routes/tasks.js)):
50
50
 
51
51
  1. **Server-mediated publish** ([ADR 0055](0055-server-mediated-branch-publish.md), dev box / `pushVia 'server'`): `POST /tasks/:id/publish-branch` attests the pushed tip after opening the PR.
52
52
  2. **Laptop `ci`-land** (`pushVia 'local'` — task 1169): `ship.js` pushes the branch + opens the PR with the laptop's own `gh` credential, which **cannot** forge the attestation. So `ciLandLocal` calls `POST /tasks/:id/attest-gate` (`requireBuilder` + ownership, deliberately **no** `allowBoxScope`) right **after the push and before opening the PR** — race-free for a fresh PR, since the PR-open is what fires `gate-review` and it runs only after the status is already present. Before task 1169 the laptop path posted *nothing*, so a Metic+ author's gate-surface PR from a laptop was BLOCKED and they could not self-approve their own PR (hit live on task 1162 / PR #131).
@@ -25,7 +25,7 @@ This **supersedes** [ADR 0035](0035-builder-onboarding-three-paths.md) §2 (Deci
25
25
  ## Consequences
26
26
 
27
27
  - **The member invite becomes the SOLE human gate before a paid (~$24/mo) box is created.** An admitted Xenos can provision their first box hands-off — the spend is bounded by the fact that a human already chose to admit them, not by a second per-box click.
28
- - **The box provisioning RANK FLOOR still bounds eligibility.** `BOX_PROVISION_MIN_RANK` ([`src/bongos/boxes.js`](../../src/bongos/boxes.js)) is unchanged: the floor is still the rank-side control on who may have a box at all, and the per-builder "one box at a time" invariant (`box_intents` partial unique index, one `builder_boxes` row) is untouched. Removing the *first-box* gate does not widen *who* qualifies; it only removes the second human click for someone already admitted and already above the floor.
28
+ - **The box provisioning RANK FLOOR still bounds eligibility.** `BOX_PROVISION_MIN_RANK` ([`modules/dev-box/boxes.js`](../../modules/dev-box/boxes.js)) is unchanged: the floor is still the rank-side control on who may have a box at all, and the per-builder "one box at a time" invariant (`box_intents` partial unique index, one `builder_boxes` row) is untouched. Removing the *first-box* gate does not widen *who* qualifies; it only removes the second human click for someone already admitted and already above the floor.
29
29
  - **Migration 102 reverts the schema** introduced by migration 071 — the `pending_approval` box-intent state (and any approval-tracking column) is removed; in-flight first-box intents are migrated to `pending` so the runner drains them.
30
30
  - **The box-panel "awaiting approval" UI state is removed** — `/builder-box` and the hall box panel no longer surface "your box is awaiting approval," because no box waits.
31
31
  - **The `#box-approvals` Discord channel + its box-intent approve/deny wiring are removed** (the box half of [ADR 0057](0057-discord-archon-approval-channels.md)). `#member-approvals` and the admission approve/dismiss wiring stay — admission is still the gate.
@@ -67,7 +67,7 @@ Results are fused with **Reciprocal Rank Fusion** (RRF: `score = Σ 1/(k + rank_
67
67
 
68
68
  ### 6. Scoping — per-chunk `min_rank` + owner, server-enforced (V4.R12 / [#950](https://example.com/builders#/task/950))
69
69
 
70
- This is the load-bearing security property, mirroring [`src/bongos/routes/memory.js`](../../src/bongos/routes/memory.js)'s posture:
70
+ This is the load-bearing security property, mirroring [`modules/memory/routes/memory.js`](../../modules/memory/routes/memory.js)'s posture:
71
71
 
72
72
  - Every query is filtered **in the SQL WHERE clause** (not post-hoc in JS) by the caller's **live, server-resolved rank** (`req.builder.rank`, read fresh per request — never from input): `min_rank` must be ≤ the caller's rank in the ladder.
73
73
  - A chunk with a non-null `owner_builder_id` (a per-builder private chunk, e.g. memory) is returned **only** to that owner — `owner_builder_id IS NULL OR owner_builder_id = req.builder.id`. There is no parameter to name another builder; the owner is always the authenticated session.
@@ -25,7 +25,7 @@ Make card **delivery** deterministic via hooks, and split the vehicle by whether
25
25
 
26
26
  1. **Read-only cards** (`/builder-start`, `/status`; future: `/recall`) → **[`session-cards.js`](../../.claude/hooks/session-cards.js)**, a `UserPromptSubmit` hook. On a matching intent it runs the script's `--hook` mode, which emits a one-fetch JSON envelope `{widgets_enabled, html, markdown, warnings}`, and injects the finished card + a one-step "render this once" directive. Registry-driven: adding a read-only card is one `CARDS` entry (a matcher, a script, an arg-extractor). Safe to pre-run because these scripts only fetch + render.
27
27
 
28
- 2. **Mutating / lifecycle cards** (`/builder-claim`, `/builder-ship`; `release` matched, emits none today) → **[`lifecycle-card.js`](../../.claude/hooks/lifecycle-card.js)**, a `PostToolUse`/Bash hook. These **must never be pre-run** — claiming or shipping as a side effect of merely typing would be catastrophic. Instead the model runs the script itself; the hook fires immediately after, reads the `[otb-card-html] <path>` marker the shared emitter ([`src/bongos/ship-card.js`](../../src/bongos/ship-card.js)) wrote, reads that file, and injects the card + directive next to the tool result.
28
+ 2. **Mutating / lifecycle cards** (`/builder-claim`, `/builder-ship`; `release` matched, emits none today) → **[`lifecycle-card.js`](../../.claude/hooks/lifecycle-card.js)**, a `PostToolUse`/Bash hook. These **must never be pre-run** — claiming or shipping as a side effect of merely typing would be catastrophic. Instead the model runs the script itself; the hook fires immediately after, reads the `[otb-card-html] <path>` marker the shared emitter ([`modules/lifecycle/ship-card.js`](../../modules/lifecycle/ship-card.js)) wrote, reads that file, and injects the card + directive next to the tool result.
29
29
 
30
30
  Both hooks honor the task-1279 widgets knob (OFF ⇒ no HTML injected, the plain-text card stands), carry **exactly two** fence markers around each payload (no extraction ambiguity), and follow the standard hook discipline: silent-fail (any miss/parse/IO error → exit 0, no output), zero model calls, a kill-switch (`OTB_SESSION_CARDS_OFF`) and the `OTB_SUBAGENT` guard. The skills (`builder-start`, `status`, `builder-claim`, `builder-ship`) are slimmed to **defer to the injected directive**, keeping their old run-the-script logic as the fallback when no directive appears (hook disabled, an older checkout, or a silent failure).
31
31
 
@@ -23,7 +23,7 @@ Two coupled pieces: a **reusable signal** (the general mechanism the owner asked
23
23
 
24
24
  ### 1. The `needs` signal — one consistent way to flag a required input
25
25
 
26
- A new pure module, [`src/bongos/builder-needs.js`](../../src/bongos/builder-needs.js), is a small **registry**. Each thing the system needs from a builder to run a capability — today the Gemini image key; tomorrow a Stripe key, a first-party Anthropic link, … — is one `(ctx) => need|null` entry. The server computes the live list on `GET /api/gds/me` (`needs: { items, action_needed_count, has_action_needed }`); every surface renders the **same** shape. Adding a future input is one registry entry — the renderers don't change.
26
+ A new pure module, [`modules/builder-settings/builder-needs.js`](../../modules/builder-settings/builder-needs.js), is a small **registry**. Each thing the system needs from a builder to run a capability — today the Gemini image key; tomorrow a Stripe key, a first-party Anthropic link, … — is one `(ctx) => need|null` entry. The server computes the live list on `GET /api/gds/me` (`needs: { items, action_needed_count, has_action_needed }`); every surface renders the **same** shape. Adding a future input is one registry entry — the renderers don't change.
27
27
 
28
28
  A need is always in exactly one of three states:
29
29
 
@@ -9,7 +9,7 @@ Developers collaborate through Git because code is text: it diffs line-by-line a
9
9
  Three forces made this worth deciding now:
10
10
 
11
11
  1. **UI is becoming real work.** Today the GDS has three disciplines — `engineer | artist | ideator` — and "design/figma/UI" tasks fall into `artist`, the pixel-art lane. UI (HUD, menus, the builders' hall, status dashboard, landing pages) is a different problem from world tiles and deserves its own lane.
12
- 2. **The grader is secretly two systems.** The GDS ship pipeline (`confirm → grade → merge → deploy → credits`) does **not** branch by discipline — every task rides the same rails. But the *grade* step is the code panel [`grader.js`](../../src/bongos/grader.js) (reads a git diff; scores code quality), while pixel art is really gated by a *separate* Gemini vision pipeline ([`art/pipeline/review.py`](../../art/pipeline/review.py)) that runs **upstream** in `/paint`, not at ship. Art passes the ship-time grader as a near-rubber-stamp because a text-only panel can't see pixels. Two grader codebases is a maintenance trap.
12
+ 2. **The grader is secretly two systems.** The GDS ship pipeline (`confirm → grade → merge → deploy → credits`) does **not** branch by discipline — every task rides the same rails. But the *grade* step is the code panel [`grader.js`](../../modules/grading/grader.js) (reads a git diff; scores code quality), while pixel art is really gated by a *separate* Gemini vision pipeline ([`art/pipeline/review.py`](../../art/pipeline/review.py)) that runs **upstream** in `/paint`, not at ship. Art passes the ship-time grader as a near-rubber-stamp because a text-only panel can't see pixels. Two grader codebases is a maintenance trap.
13
13
  3. **Claude Design changed the calculus.** [Claude Design](https://www.anthropic.com/news/claude-design-anthropic-labs) (Anthropic Labs, beta, 2026) **writes code and renders it** — it has no vector canvas. Its output is HTML/CSS/JS, and its June 2026 update added tight Claude Code sync (`/design-sync` imports a repo's design system in; a finished design hands off to Claude Code "where the designer left off"). So for Claude Design, *design is code* — it merges like any other code.
14
14
 
15
15
  Owner (Lars) requirements, reached in the 2026-06-21 design conversation:
@@ -40,7 +40,7 @@ Owner (Lars) requirements, reached in the 2026-06-21 design conversation:
40
40
  - **Designers keep Figma.** Manual Figma edits are first-class for structured/design-system changes and round-trip into the repo via a normal GDS task + the same grader. The honest limit: the Figma→code round-trip is lossy for arbitrary canvas art — that work becomes a committed asset, not round-tripped code.
41
41
  - **One grader to maintain, not two.** The standalone Gemini review path is retired into the unified engine. Code doesn't auto-regen today (a failed grade = human fixes + re-ships); unifying gives every type the same generate→grade→regenerate loop.
42
42
  - **Graphics is unchanged.** World pixel art stays on the Claude Code + Gemini pipeline; Figma stays its viewer ([`otb-figma-sync`](../../.claude/skills/otb-figma-sync/SKILL.md)). This ADR adds the `ui` lane beside it, it does not disturb the art pipeline.
43
- - **Gate-review floor applies.** [#1380](https://example.com/builders#/task/1380) touches [`grader.js`](../../src/bongos/grader.js) + [`ship.js`](../../scripts/gds/ship.js) — the gate-review **hard floor** ([ADR 0043](0043-git-ssh-trust-boundary-and-rank-floor-on-permission-paths.md)). It needs owner Gate approval even for Archon, and the multimodal call path wants a security review.
43
+ - **Gate-review floor applies.** [#1380](https://example.com/builders#/task/1380) touches [`grader.js`](../../modules/grading/grader.js) + [`ship.js`](../../scripts/gds/ship.js) — the gate-review **hard floor** ([ADR 0043](0043-git-ssh-trust-boundary-and-rank-floor-on-permission-paths.md)). It needs owner Gate approval even for Archon, and the multimodal call path wants a security review.
44
44
 
45
45
  ## Rejected alternatives
46
46
 
@@ -12,7 +12,7 @@
12
12
 
13
13
  ## Context
14
14
 
15
- Today only the Archon can create or edit tasks — `POST /tasks` and `PATCH /tasks/:id` are both `requireRank('archon')` ([`src/bongos/routes/tasks.js`](../../src/bongos/routes/tasks.js)). Lower-ranking builders (`xenos`, `thetes`) can only **file ideas** into `idea_inbox`; they have no ability to shape their own work toward an objective.
15
+ Today only the Archon can create or edit tasks — `POST /tasks` and `PATCH /tasks/:id` are both `requireRank('archon')` ([`modules/lifecycle/routes/tasks.js`](../../modules/lifecycle/routes/tasks.js)). Lower-ranking builders (`xenos`, `thetes`) can only **file ideas** into `idea_inbox`; they have no ability to shape their own work toward an objective.
16
16
 
17
17
  > **Update (2026-06-26, [ADR 0090](0090-metic-task-authoring.md)):** `POST /tasks` / `PATCH /tasks/:id` are now `requireRank('metic','archon')` — a *Metic* may author tasks directly. This ADR's goal-scoped, module-fenced authoring path (`POST /goals/:id/tasks`) is now the mechanism for **sub-Metic** ranks (`xenos`/`thetes`) specifically; everything below about the scope-subset wall and protected-path block is unchanged and still governs that path. Every task must be hand-authored by the owner first — a delegation bottleneck that wastes capable builders' judgment, and the opposite of the AI-first norm where agents do the building.
18
18
 
@@ -54,7 +54,7 @@ The tier set is host-configured, not hardcoded — the [ADR 0062](0062-medusa-in
54
54
  ### 3. Bounded task authoring (membership grants it; the create-time gate)
55
55
 
56
56
  - **`POST /goals`** — `requireRank('metic','archon')`; **Archon-only when `scope_modules` includes a `protected` module.**
57
- - **`POST /goals/:id/join` / `leave`** — open join for normal goals; **joining a sensitive-scope goal needs Archon approval** (reuse the access-request pattern, [`access-requests.js`](../../src/bongos/routes/access-requests.js)).
57
+ - **`POST /goals/:id/join` / `leave`** — open join for normal goals; **joining a sensitive-scope goal needs Archon approval** (reuse the access-request pattern, [`access-requests.js`](../../modules/onboarding/routes/access-requests.js)).
58
58
  - **`POST /goals/:id/tasks`** — `requireBuilder` + an in-handler gate (the maneuverability grant), ordered + fail-closed: goal `open` and **caller is a member** (or Archon); version guards reused from `POST /tasks`; **scope subset** — every `touches[]` element covered by the goal's `scope_modules` globs (`touchesOverlap`, [`path-match.js`](../../src/bongos/path-match.js)); **protected-path block** — `checkPermissionPaths` ([`permission-path-check.js`](../../src/bongos/permission-path-check.js)) so a sub-Metic member cannot author a task touching the protected core; then `db.createTask` stamping `goal_id`. `POST /tasks` / `PATCH /tasks/:id` stay byte-identical (Archon-only) for ungoverned creation.
59
59
  - **Rank floor is auto-derived, not a bespoke cap.** Per [ADR 0084](0084-auto-derived-per-task-rank-floor.md), a created task's `requires_rank` is auto-derived from its touches + sensitivity (`deriveRequiredRank` → `metic` for protected/sensitive, else `xenos`) and can only be raised. So a goal member need not (and cannot) self-set a rank that escapes their own gate — and a sensitive task auto-floors to `metic`, which a sub-Metic author could not claim. No new cap mechanism; this composes with the one that already exists.
60
60
 
@@ -78,7 +78,7 @@ The tier set is host-configured, not hardcoded — the [ADR 0062](0062-medusa-in
78
78
 
79
79
  ### 7. How the boundary holds (reuse + defense-in-depth)
80
80
 
81
- The create-time gate sees only *declared* touches (advisory — git merge is the real collision detector, [ADR 0049](0049-split-parallel-safety-contract.md)), so it is the first filter, **not** the enforcement boundary. The existing **ship-time gates remain authoritative on the real diff**: the grader's `permissionPathPrePass`/`routeRankPrePass` + `serverSideGuards` ([`grader.js`](../../src/bongos/grader.js)), the `gate-review` ESCALATE floor, and the post-push `main-audit`. A mis-declared task still cannot *merge* if its real diff hits protected paths. Two CI fitness checks ([`fitness.js`](../../scripts/gds/fitness.js)) guard drift: goal routes are pinned in `route-rank-check.EXPECTED_RANKS`, and the scope code must *import* `PROTECTED_GLOBS`, never re-declare it.
81
+ The create-time gate sees only *declared* touches (advisory — git merge is the real collision detector, [ADR 0049](0049-split-parallel-safety-contract.md)), so it is the first filter, **not** the enforcement boundary. The existing **ship-time gates remain authoritative on the real diff**: the grader's `permissionPathPrePass`/`routeRankPrePass` + `serverSideGuards` ([`grader.js`](../../modules/grading/grader.js)), the `gate-review` ESCALATE floor, and the post-push `main-audit`. A mis-declared task still cannot *merge* if its real diff hits protected paths. Two CI fitness checks ([`fitness.js`](../../scripts/gds/fitness.js)) guard drift: goal routes are pinned in `route-rank-check.EXPECTED_RANKS`, and the scope code must *import* `PROTECTED_GLOBS`, never re-declare it.
82
82
 
83
83
  ### Deferred (explicit non-decisions)
84
84
 
@@ -104,7 +104,7 @@ Each phase ships independently; implementing tasks are created via `/planning-se
104
104
 
105
105
  ## Alternatives considered
106
106
 
107
- - **Reuse `parent_task_id` for goals (a goal = a parent task) — rejected.** One-level cap ([`hierarchy.js`](../../src/bongos/hierarchy.js)), wrong lifecycle (a goal is a standing grant, not shippable work that earns credit on ship), and a task has no place for scope or membership.
107
+ - **Reuse `parent_task_id` for goals (a goal = a parent task) — rejected.** One-level cap ([`hierarchy.js`](../../modules/lifecycle/hierarchy.js)), wrong lifecycle (a goal is a standing grant, not shippable work that earns credit on ship), and a task has no place for scope or membership.
108
108
  - **Reuse `done_when_criteria` as goals — rejected.** That table *is* the criteria tier; overloading it with membership + a creation grant conflates "definition of done" with "who may do work." A goal *links to* criteria; it is not one.
109
109
  - **Single-owner goals — rejected** (Lars). Goals are shared workspaces; a single assignee would force mega-claims and block collaboration. Membership grants the authority; contribution (not membership alone) is what any future reward weights on.
110
110
  - **A bespoke per-task rank cap at goal-create — rejected in favour of [ADR 0084](0084-auto-derived-per-task-rank-floor.md).** The auto-derived floor already prevents a member minting a task that escapes their gate; a second mechanism would be a second list that drifts (the SEC [#863](https://example.com/builders#/task/863) failure mode).