@bongos/core 1.19.393 → 1.19.395

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 (48) hide show
  1. package/.bongos-core.json +108 -58
  2. package/.claude/skills/design/SKILL.md +68 -0
  3. package/.claude/skills/design-sync/SKILL.md +2 -2
  4. package/.claude/skills/figma-design-sync/SKILL.md +3 -3
  5. package/config/design-tokens.neutral.json +1 -1
  6. package/config/design-tokens.schema.json +1 -1
  7. package/docs/adr/0197-the-ui-design-module.md +52 -0
  8. package/docs/adr/README.md +1 -0
  9. package/docs/architecture.md +1 -1
  10. package/docs/copy-inventory.md +249 -236
  11. package/docs/copy-registry.json +543 -324
  12. package/docs/file-map.md +2 -0
  13. package/docs/modules-contract.md +1 -0
  14. package/docs/onboarding/slash-commands.md +1 -1
  15. package/docs/recipes/claude-design-loop.md +3 -3
  16. package/docs/recipes/figma-design-loop.md +4 -4
  17. package/modules/ui-design/CLAUDE.md +15 -0
  18. package/{src/ui → modules/ui-design}/adapters/claude-design/index.js +1 -1
  19. package/{src/ui → modules/ui-design}/adapters/figma/index.js +3 -3
  20. package/{docs → modules/ui-design/docs}/design-contract.md +12 -12
  21. package/modules/ui-design/kit/README.md +3 -0
  22. package/modules/ui-design/module.json +11 -0
  23. package/modules/ui-design/scripts/design-sync.js +65 -0
  24. package/modules/ui-design/scripts/figma-design-sync.js +64 -0
  25. package/modules/ui-design/scripts/validate-design.js +258 -0
  26. package/modules/ui-design/skills/README.md +3 -0
  27. package/modules/ui-design/styles/README.md +3 -0
  28. package/package-lock.json +2 -2
  29. package/package.json +1 -1
  30. package/public-landing/assets/cosmos.css +235 -103
  31. package/public-landing/index.html +228 -75
  32. package/public-landing/projects.html +256 -140
  33. package/scripts/gds/copy-inventory.js +7 -5
  34. package/scripts/gds/design-sync.js +9 -59
  35. package/scripts/gds/doc-cli-guard.js +11 -5
  36. package/scripts/gds/figma-design-sync.js +9 -59
  37. package/scripts/gds/fitness-checks-identity.js +5 -3
  38. package/scripts/gds/publish-manifest.js +1 -1
  39. package/scripts/gds/validate-design.js +7 -249
  40. package/src/bongos/module-scope-map.js +18 -0
  41. package/src/module-api.js +5 -1
  42. package/tests/design_tokens_sync.mjs +1 -1
  43. package/tests/doc_cli_guard.mjs +19 -0
  44. package/tests/figma_adapter.mjs +1 -1
  45. package/tests/landing_page.mjs +72 -2
  46. package/tests/module_loader.mjs +4 -1
  47. package/tests/projects_hub.mjs +52 -73
  48. package/tests/projects_hub_pre_uat.mjs +10 -8
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.393",
6
- "core_contract": "1.19.393",
7
- "source_commit": "e4673d8af6d2b24d57be0c3a9d31c15627ef07db",
5
+ "core_version": "1.19.395",
6
+ "core_contract": "1.19.395",
7
+ "source_commit": "c6682951454183e1d8561983b2bb2295aced7775",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-08-28T13:49:26.259Z",
9
+ "built_at": "2026-08-28T16:02:31.625Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
- "docs_redacted": 340,
13
- "agent_docs_stubbed": 22,
14
- "functional_verbatim": 1630,
12
+ "docs_redacted": 345,
13
+ "agent_docs_stubbed": 23,
14
+ "functional_verbatim": 1634,
15
15
  "rules": 3,
16
16
  "gate_literals": 3,
17
17
  "gate": "passed"
18
18
  },
19
- "file_count": 1992,
20
- "tree_sha256": "f327722f7c80662fb8f132891464528b071371bd874c73487b6f3a55b6424113",
19
+ "file_count": 2002,
20
+ "tree_sha256": "354b4dc6de55dc65198160070a23c27d7aa950cd96962014f2f436a5ccfaefc8",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/blocker-review/SKILL.md",
@@ -122,7 +122,12 @@
122
122
  {
123
123
  "path": ".claude/skills/design-sync/SKILL.md",
124
124
  "mode": "0000644",
125
- "sha256": "9fe1d51e1bbf277bb197dcdc7f514971c390bbb33186454b2e2ccf318f5bd544"
125
+ "sha256": "7ef4539cc8f7a588cac1ab1c81a0bcd2403e1e3f5d67422e53a4973d057b55c7"
126
+ },
127
+ {
128
+ "path": ".claude/skills/design/SKILL.md",
129
+ "mode": "0000644",
130
+ "sha256": "83f2d423421bc08e7f460847616bc0cfba636cb24563566724776b2c7c1a1662"
126
131
  },
127
132
  {
128
133
  "path": ".claude/skills/dev/SKILL.md",
@@ -137,7 +142,7 @@
137
142
  {
138
143
  "path": ".claude/skills/figma-design-sync/SKILL.md",
139
144
  "mode": "0000644",
140
- "sha256": "2f9d2b9c2d0377a582c71262462c08237f30b31d91ef748f40a188e4e7aadbf2"
145
+ "sha256": "f3abceebc2b098b61e9f0765bf0a515beaf340aa5138b23db1c59ba761a195cd"
141
146
  },
142
147
  {
143
148
  "path": ".claude/skills/fix-task/SKILL.md",
@@ -387,12 +392,12 @@
387
392
  {
388
393
  "path": "config/design-tokens.neutral.json",
389
394
  "mode": "0000644",
390
- "sha256": "386558d2c902f81b4b9a9cb74aa41b89e7195e5cba5ec043f96fc7beab899630"
395
+ "sha256": "50d0705a8e37af0bda238327ba0a09f96bcec3d8d1eb0e090ea5a2fb22d9f928"
391
396
  },
392
397
  {
393
398
  "path": "config/design-tokens.schema.json",
394
399
  "mode": "0000644",
395
- "sha256": "f7030358eb36b01ebe252fd52dbd6bc5763e28aa169a6f84a373ce949182511b"
400
+ "sha256": "0e1d5d75d0c990b4092876650875330adaaf4b1086d2731c14374a1f5659a31c"
396
401
  },
397
402
  {
398
403
  "path": "config/government.neutral.json",
@@ -1479,10 +1484,15 @@
1479
1484
  "mode": "0000644",
1480
1485
  "sha256": "838197eef10523949529e6ca906a8b489e5a512df8915a48dc0edb15414a390e"
1481
1486
  },
1487
+ {
1488
+ "path": "docs/adr/0197-the-ui-design-module.md",
1489
+ "mode": "0000644",
1490
+ "sha256": "901dcd1ca9748e999ea0db27e213f76c7e38caf620fb6b17fc8d1cf9dbee5e9d"
1491
+ },
1482
1492
  {
1483
1493
  "path": "docs/adr/README.md",
1484
1494
  "mode": "0000644",
1485
- "sha256": "f8fb053b786e60f3213e0038c994f10492c87fa24ec89deeb8bea66182356285"
1495
+ "sha256": "34f327bac4b238f5af2c47e2eb5298f20c9aac35c336dcab29c11396be992e48"
1486
1496
  },
1487
1497
  {
1488
1498
  "path": "docs/api-reference.md",
@@ -1497,7 +1507,7 @@
1497
1507
  {
1498
1508
  "path": "docs/architecture.md",
1499
1509
  "mode": "0000644",
1500
- "sha256": "92cbe2a55fff82a842e7ac3668c99d4eef05e922079d036a5984f607a64496ae"
1510
+ "sha256": "68d30a764a36e963d40e4271010c56b61a824b9e2fad61599fdc62ee1bc2fddf"
1501
1511
  },
1502
1512
  {
1503
1513
  "path": "docs/branding-contract.md",
@@ -1517,17 +1527,12 @@
1517
1527
  {
1518
1528
  "path": "docs/copy-inventory.md",
1519
1529
  "mode": "0000644",
1520
- "sha256": "6b2b21a3b5812c9d344165441ffd7397f39cabe4a72f652bb977ad31edb9a65a"
1530
+ "sha256": "fabaf96fa63e3bf2e690619ef11038b3503154368aeaa9c10d8eb2641e306dee"
1521
1531
  },
1522
1532
  {
1523
1533
  "path": "docs/copy-registry.json",
1524
1534
  "mode": "0000644",
1525
- "sha256": "460230106e7c700485a3e9f797eb96e78dca54365e9dcaf56d60b111a08c1008"
1526
- },
1527
- {
1528
- "path": "docs/design-contract.md",
1529
- "mode": "0000644",
1530
- "sha256": "9623542a240479c3ecec12dd0c9050d4b79b2791a414bc2cd6b05d99530a9c44"
1535
+ "sha256": "cfdea83dda157439808ea4d0ef9ba7af11e77ad4693b6dd135cdddc529754583"
1531
1536
  },
1532
1537
  {
1533
1538
  "path": "docs/design/apex-pass-2-direction.md",
@@ -1817,7 +1822,7 @@
1817
1822
  {
1818
1823
  "path": "docs/file-map.md",
1819
1824
  "mode": "0000644",
1820
- "sha256": "4da98da4c1d5bc5e2a1c1949775f362d8867faa5a2a0321ccd954dc0a5b71202"
1825
+ "sha256": "3789594e075f2501de76ac637a3adcb383e3bc611f84f985ed9e385e5d5c8169"
1821
1826
  },
1822
1827
  {
1823
1828
  "path": "docs/handoff-template.md",
@@ -1827,7 +1832,7 @@
1827
1832
  {
1828
1833
  "path": "docs/modules-contract.md",
1829
1834
  "mode": "0000644",
1830
- "sha256": "60701a916fa001bfb160a46ef2f5d565384df2515f1cce097c5af39313d5d370"
1835
+ "sha256": "1dddea16f7716cf500e329a73159d5f3a0548e4eed380148668b085712e985a7"
1831
1836
  },
1832
1837
  {
1833
1838
  "path": "docs/onboarding/browser-terminal-guide.md",
@@ -1892,7 +1897,7 @@
1892
1897
  {
1893
1898
  "path": "docs/onboarding/slash-commands.md",
1894
1899
  "mode": "0000644",
1895
- "sha256": "c9e898609ff1287f63dc1bb2edb6653711d396dcbd77c0e25a6a984425ff9476"
1900
+ "sha256": "8e8d5c7d0843faa2dc550a640676a824c9be319c751cf1a1cb19eaebeb86b153"
1896
1901
  },
1897
1902
  {
1898
1903
  "path": "docs/project-context.template.md",
@@ -1922,7 +1927,7 @@
1922
1927
  {
1923
1928
  "path": "docs/recipes/claude-design-loop.md",
1924
1929
  "mode": "0000644",
1925
- "sha256": "389dbbbfb7c941315731d533e300b5d43f40a8aac866c5a1c74c32d5be212a22"
1930
+ "sha256": "96e8774c29aa5444dd0035af55a24ded99894caff5f901a7dc1eac35e75f605d"
1926
1931
  },
1927
1932
  {
1928
1933
  "path": "docs/recipes/core-release-pipeline.md",
@@ -1947,7 +1952,7 @@
1947
1952
  {
1948
1953
  "path": "docs/recipes/figma-design-loop.md",
1949
1954
  "mode": "0000644",
1950
- "sha256": "6bfee82bddc07a5743316e310dda1e6cb7266fa7805fc1eed67bc8cc17980b46"
1955
+ "sha256": "80fcc5cb6e10e6f55bf518604c64072e8a0848cf157dbc1f761519f14eab8399"
1951
1956
  },
1952
1957
  {
1953
1958
  "path": "docs/recipes/gds-db-backup.md",
@@ -5149,15 +5154,70 @@
5149
5154
  "mode": "0000644",
5150
5155
  "sha256": "75a40d70207669ab57b0be05e4b6be70a2936cb9febf333b0a34224a80047e7e"
5151
5156
  },
5157
+ {
5158
+ "path": "modules/ui-design/CLAUDE.md",
5159
+ "mode": "0000644",
5160
+ "sha256": "7cb9dac9cb87b679e1ae50e4112b3a7928a38ebb9902c8947a74d17bec4d9009"
5161
+ },
5162
+ {
5163
+ "path": "modules/ui-design/adapters/claude-design/index.js",
5164
+ "mode": "0000644",
5165
+ "sha256": "3794d5b8736824033a916c77661caf995385334047f3167d29aa3e0aa32b5bed"
5166
+ },
5167
+ {
5168
+ "path": "modules/ui-design/adapters/figma/index.js",
5169
+ "mode": "0000644",
5170
+ "sha256": "859a23a1a10fe74717b37a4c86962750b7fd6d13b56ed801f6e217a245fea956"
5171
+ },
5172
+ {
5173
+ "path": "modules/ui-design/docs/design-contract.md",
5174
+ "mode": "0000644",
5175
+ "sha256": "2095ddb991fa02e6800b4f92e5536e82512af6abb9e791596365a87c541a0530"
5176
+ },
5177
+ {
5178
+ "path": "modules/ui-design/kit/README.md",
5179
+ "mode": "0000644",
5180
+ "sha256": "70f65052951335b63def03590ee971e2f482d6db08365484b532e4bc3c676495"
5181
+ },
5182
+ {
5183
+ "path": "modules/ui-design/module.json",
5184
+ "mode": "0000644",
5185
+ "sha256": "1dedeb68927743a51b048b7d3f70ea939958fcfe3831b22c4120d53d78beb2f8"
5186
+ },
5187
+ {
5188
+ "path": "modules/ui-design/scripts/design-sync.js",
5189
+ "mode": "0000644",
5190
+ "sha256": "c9376b96f9f963425f2cb2552b5b7b2e4d8264e3f4dac27c7e0410f95dfc3e7a"
5191
+ },
5192
+ {
5193
+ "path": "modules/ui-design/scripts/figma-design-sync.js",
5194
+ "mode": "0000644",
5195
+ "sha256": "ce7c64e5068be597e9676e184fc1f411b4a4661a00b4f1df11ea8bb511fb8347"
5196
+ },
5197
+ {
5198
+ "path": "modules/ui-design/scripts/validate-design.js",
5199
+ "mode": "0000644",
5200
+ "sha256": "c9d90b5ffb6e3895c8e98cefbdc89ff4fdd52a22a1073d8fe956a487c4b7816d"
5201
+ },
5202
+ {
5203
+ "path": "modules/ui-design/skills/README.md",
5204
+ "mode": "0000644",
5205
+ "sha256": "709a99b3879eec15552c7ce18291fad5a4922d477955982eb51b718577ee7948"
5206
+ },
5207
+ {
5208
+ "path": "modules/ui-design/styles/README.md",
5209
+ "mode": "0000644",
5210
+ "sha256": "5f98022a5edc4c1b405823cbf8ba8da745f60c3d47a7cb59eba537edf9bf29be"
5211
+ },
5152
5212
  {
5153
5213
  "path": "package-lock.json",
5154
5214
  "mode": "0000644",
5155
- "sha256": "e07dabb4292a7652cbd2f4bf6092eb6e4037693fcd55ee4964cb6b091749228d"
5215
+ "sha256": "58c9432c30c1c3c319aa7c526368a890cc9722773a0fb4f31bed0e59e1d5ebe9"
5156
5216
  },
5157
5217
  {
5158
5218
  "path": "package.json",
5159
5219
  "mode": "0000644",
5160
- "sha256": "f8304e8d1f9338bccfae2cac3ea289dd58262eeccf5820857145a5490660a2e8"
5220
+ "sha256": "8a4b801babd875eed0c1ca44c26640f0745a8e7a1fc82c51fea271333e68e62c"
5161
5221
  },
5162
5222
  {
5163
5223
  "path": "public-docs/index.html",
@@ -5397,7 +5457,7 @@
5397
5457
  {
5398
5458
  "path": "public-landing/assets/cosmos.css",
5399
5459
  "mode": "0000644",
5400
- "sha256": "53cf1fba6106728c120f6dfc8cc3e3bb7495319a5886462950c39588f0f3293c"
5460
+ "sha256": "e854e608853de74e99a35f9d8f21d16576e598022026630cb6e5ac1b676ff702"
5401
5461
  },
5402
5462
  {
5403
5463
  "path": "public-landing/assets/verro-medallion.png",
@@ -5487,7 +5547,7 @@
5487
5547
  {
5488
5548
  "path": "public-landing/index.html",
5489
5549
  "mode": "0000644",
5490
- "sha256": "05079e16fc7cfa02d9b31416a25960eefe969b7522a75ae9c7a228c76ee3ca22"
5550
+ "sha256": "1e7ceb571c899be95c7a945a8bd4337bb000af2b90d6f8de5b4dfcef3a5e8891"
5491
5551
  },
5492
5552
  {
5493
5553
  "path": "public-landing/privacy.html",
@@ -5497,7 +5557,7 @@
5497
5557
  {
5498
5558
  "path": "public-landing/projects.html",
5499
5559
  "mode": "0000644",
5500
- "sha256": "da2b7c197dda6f975eb660fb51c88e037a4ea94e7e4164e7282f33602e6c438e"
5560
+ "sha256": "1e1867918ec2a8fe489d9d21aa2e50fada9950b220c865c57f23c703a6c29f24"
5501
5561
  },
5502
5562
  {
5503
5563
  "path": "public-landing/terms.html",
@@ -5797,7 +5857,7 @@
5797
5857
  {
5798
5858
  "path": "scripts/gds/copy-inventory.js",
5799
5859
  "mode": "0000644",
5800
- "sha256": "24e875eaace524598d18b5bf4a931700296f580404b79166da1e7c1d2d906de3"
5860
+ "sha256": "40d3f8bb29ccc13e12fd79de5f79b25eb9d7df5d0500b887c965199187f4ab8b"
5801
5861
  },
5802
5862
  {
5803
5863
  "path": "scripts/gds/coreB-carve-proof.sh",
@@ -5837,7 +5897,7 @@
5837
5897
  {
5838
5898
  "path": "scripts/gds/design-sync.js",
5839
5899
  "mode": "0000644",
5840
- "sha256": "a10293363019251a22051af207aa9ece83f9384942f7ae09065072aa77e57570"
5900
+ "sha256": "06901aa9fa0fcf89e0710f8f35274bc589f4711024e88350a981a453d5937f96"
5841
5901
  },
5842
5902
  {
5843
5903
  "path": "scripts/gds/dev-lib.js",
@@ -5877,7 +5937,7 @@
5877
5937
  {
5878
5938
  "path": "scripts/gds/doc-cli-guard.js",
5879
5939
  "mode": "0000644",
5880
- "sha256": "9cf6c8ead8129799d17a18eadedf0423828cb457fa07fd317dcf2853254861e9"
5940
+ "sha256": "de19e1ffe48ffb9ad942828dafe858a7d88a9269fa812474be5018b263772a3e"
5881
5941
  },
5882
5942
  {
5883
5943
  "path": "scripts/gds/doc-comment-coverage.js",
@@ -5912,12 +5972,12 @@
5912
5972
  {
5913
5973
  "path": "scripts/gds/figma-design-sync.js",
5914
5974
  "mode": "0000644",
5915
- "sha256": "7a7721155c8c7cb169a48e6f279e5d7c0ba0dc4462678a4a2ec41a2686501962"
5975
+ "sha256": "b8b1a7ed1d8dd217b24757a3ec9f4b3aa58b26a3e2a7b2cef9de217792e5ea43"
5916
5976
  },
5917
5977
  {
5918
5978
  "path": "scripts/gds/fitness-checks-identity.js",
5919
5979
  "mode": "0000644",
5920
- "sha256": "f87265779d60ae2d642e370f7af2d1d70fa6a1354a7389835d887b0dfe3c5dfc"
5980
+ "sha256": "142b37957cd6205da618001d8a14d45979a8d81107ce60791302b008df276555"
5921
5981
  },
5922
5982
  {
5923
5983
  "path": "scripts/gds/fitness-checks-vocabulary.js",
@@ -6287,7 +6347,7 @@
6287
6347
  {
6288
6348
  "path": "scripts/gds/publish-manifest.js",
6289
6349
  "mode": "0000644",
6290
- "sha256": "12b3b200c1f60cc8a287d9a3ca2dd28201fda3cc219e83dffb60913c084e0413"
6350
+ "sha256": "6d97163d0d8019642105d0eef8b8e017ec6763679255053969a8f8db020773a8"
6291
6351
  },
6292
6352
  {
6293
6353
  "path": "scripts/gds/pulse.js",
@@ -6742,7 +6802,7 @@
6742
6802
  {
6743
6803
  "path": "scripts/gds/validate-design.js",
6744
6804
  "mode": "0000644",
6745
- "sha256": "3d417b8510d58afec754d2a4dd62d5029dbc41140868ff74f633e56ef06f90d6"
6805
+ "sha256": "49e169d297e73fd32f27bc2af746a47c04a107abc39ae720122aa80f1ab1dff1"
6746
6806
  },
6747
6807
  {
6748
6808
  "path": "scripts/gds/version-close.js",
@@ -6972,7 +7032,7 @@
6972
7032
  {
6973
7033
  "path": "src/bongos/module-scope-map.js",
6974
7034
  "mode": "0000644",
6975
- "sha256": "c3b5499005ae5150d1e3288437dbfd422e28068a28e3c5783a8c4b3fa2edd09c"
7035
+ "sha256": "77dd62d640862624066bfcd2845c6ed2801091ce49ed676a809da3cce5077761"
6976
7036
  },
6977
7037
  {
6978
7038
  "path": "src/bongos/module-submissions.js",
@@ -7147,7 +7207,7 @@
7147
7207
  {
7148
7208
  "path": "src/module-api.js",
7149
7209
  "mode": "0000644",
7150
- "sha256": "14825991cbc68b5a14edfedbcb6ed78739254bc02ea966ce02516f65c9d5abc0"
7210
+ "sha256": "5ead37acb3188ec29cea517b3b256b2882ca304152e30ecfea7d2ef82716bce2"
7151
7211
  },
7152
7212
  {
7153
7213
  "path": "src/module-loader/catalog.js",
@@ -7189,16 +7249,6 @@
7189
7249
  "mode": "0000644",
7190
7250
  "sha256": "a012619e42522c8b38ffdaf00cfe8d89a9438fc0cea00752474ab22f13d3f722"
7191
7251
  },
7192
- {
7193
- "path": "src/ui/adapters/claude-design/index.js",
7194
- "mode": "0000644",
7195
- "sha256": "69ec9f8c405987a67570aca7375e8b29951898775cdb56fa7bc68a74dfcfd10b"
7196
- },
7197
- {
7198
- "path": "src/ui/adapters/figma/index.js",
7199
- "mode": "0000644",
7200
- "sha256": "4331ee8d20ad98faac520cd42bcee2614820e15d1b1691ad3cee4584bbab9fb7"
7201
- },
7202
7252
  {
7203
7253
  "path": "tests/abandon_task.mjs",
7204
7254
  "mode": "0000644",
@@ -7837,7 +7887,7 @@
7837
7887
  {
7838
7888
  "path": "tests/design_tokens_sync.mjs",
7839
7889
  "mode": "0000644",
7840
- "sha256": "9dcbd0bc8f34f98ec0b0ff63a629780928c9d60199f3d961733e03ab6a7bb4fa"
7890
+ "sha256": "0454ee692bbbf19d02c7f19c029f4da5a4dd939b84c4d67ebb713d12de179c2a"
7841
7891
  },
7842
7892
  {
7843
7893
  "path": "tests/dev_lib.mjs",
@@ -7967,7 +8017,7 @@
7967
8017
  {
7968
8018
  "path": "tests/doc_cli_guard.mjs",
7969
8019
  "mode": "0000644",
7970
- "sha256": "4e68c67489daa51167b8d738a36f7c0187016b342e8a57731d14241563262878"
8020
+ "sha256": "3c7567070ad3ce59fdfef9d57da39d62cf1e7c745bfeefd432c1b96c247b42ec"
7971
8021
  },
7972
8022
  {
7973
8023
  "path": "tests/doc_comment_coverage.mjs",
@@ -8012,7 +8062,7 @@
8012
8062
  {
8013
8063
  "path": "tests/figma_adapter.mjs",
8014
8064
  "mode": "0000644",
8015
- "sha256": "73a9099549d21f33f1bc88a30991aacef129e2c9a567aaaaf5bd51117a19541c"
8065
+ "sha256": "73bb1d6cbbf6301a8aa92e9cb4fd4b7fe222cf3bb77d01778cbc5438fa549512"
8016
8066
  },
8017
8067
  {
8018
8068
  "path": "tests/file_map.mjs",
@@ -8752,7 +8802,7 @@
8752
8802
  {
8753
8803
  "path": "tests/landing_page.mjs",
8754
8804
  "mode": "0000644",
8755
- "sha256": "7b5f7ad4fb9863ec7b49adcff1745cca99024018e56b509e8f777f9ad7be05e9"
8805
+ "sha256": "51ed4d09e7c7ebb8b444c626dbfaaf3e22c970028873d538b6d84fde4b861eb6"
8756
8806
  },
8757
8807
  {
8758
8808
  "path": "tests/lib_sh_resolution.mjs",
@@ -8927,7 +8977,7 @@
8927
8977
  {
8928
8978
  "path": "tests/module_loader.mjs",
8929
8979
  "mode": "0000644",
8930
- "sha256": "c768beda710cc8446023d95cf5736cb70364403ed6412c41eef7c3c5039c1604"
8980
+ "sha256": "157fbb9db4830c87654edf6c6548fba2e535830c0c832bbdf0fd199019d6219f"
8931
8981
  },
8932
8982
  {
8933
8983
  "path": "tests/module_manifest.mjs",
@@ -9162,12 +9212,12 @@
9162
9212
  {
9163
9213
  "path": "tests/projects_hub.mjs",
9164
9214
  "mode": "0000644",
9165
- "sha256": "6d2d4c0debb5fe6cc1ed5670e5f556f217b590290fbf0b95e6b4010b17aa4517"
9215
+ "sha256": "8ea87c88469101212ac3554d8153664ebb297bdec0734b4f2fb73af2282398d2"
9166
9216
  },
9167
9217
  {
9168
9218
  "path": "tests/projects_hub_pre_uat.mjs",
9169
9219
  "mode": "0000644",
9170
- "sha256": "6a454949fbe19cc62adcba125f5e193f4ee253a8fd92ff310bd65c4d8841c19f"
9220
+ "sha256": "3104082c86aabc56824a026eccf028c9971bfbffc5a2c7801accbe1c899cba0c"
9171
9221
  },
9172
9222
  {
9173
9223
  "path": "tests/promote_goal_id.mjs",
@@ -0,0 +1,68 @@
1
+ ---
2
+ name: design
3
+ description: The UI design session — the operating playbook for ui-discipline work (layouts, pages, components, design systems, the hall / status / landing surfaces) on ANY Cloud Bongos instance. Triggers when the user says "/design", "design this page", "let's work on the UI", "make this look right", "start a design session", or when a claimed task's discipline routes here (claim.js prints a directive to invoke /design for ui tasks). Show-first like /paint — the interface is judged by looking at it — and world-first: the instance's branding pack + DESIGN.md are read before any taste rule applies. Shipped by the ui-design module (ADR 0197).
4
+ ---
5
+
6
+ You are running a **UI design session**. Two things make it different from `/dev`: the work is judged **by looking at it** (so every step ends in a rendered screen, not a paragraph), and it is done **inside a world that is not yours** — the instance's, which you read first and never override. The `ui-design` module's [CLAUDE.md](../../../modules/ui-design/CLAUDE.md) is the reference; this file is the loop.
7
+
8
+ ## Step 0 — detect the mode
9
+
10
+ - **Interactive** (someone is here to look and react): show, let them steer, iterate. One or two lines per step, then a screen.
11
+ - **Autonomous** (no one will look): build inside the contract, prove it in both modes, stage or park the screens for review, and **never ship an interface change blind** — a task that cannot be verified visually gets a release with a reason, not a guess.
12
+
13
+ ## Step 1 — load the world before you draw anything
14
+
15
+ Read, in this order, and quote nothing from memory:
16
+
17
+ 1. `config/branding.json` over `config/branding.neutral.json` — `theme.ui` is **the fifteen tokens** (thirteen colours + two font stacks): the only palette a platform surface may rely on.
18
+ 2. `config/design-tokens.json` over `config/design-tokens.neutral.json` — the `--dt-*` tokens an adapter emits; `config/design-sources.json` — which tool authors each surface.
19
+ 3. **`DESIGN.md` at the repo root** — the instance's world: palette + derived tiers, faces, materials, motion grammar, components, do's and don'ts, accessibility floors. If it names a rule, it wins over your taste.
20
+ 4. The surface's own sheet and the nested `CLAUDE.md` of the directory you're in; `/recall <surface>` for what was already decided.
21
+
22
+ **No `DESIGN.md`?** Then the neutral pack *is* the world and the platform floors below are the whole rulebook. Say so in your notes and build to them. Do not invent a palette.
23
+
24
+ ## Step 2 — look before you ship
25
+
26
+ Render the real surface before and after — never reason about layout from source alone:
27
+
28
+ - Stage it (`/builder-stage` on a box; a local stub + Playwright on a laptop — the kit under `modules/ui-design/kit/` ports the apex probes once [task 1003320](https://cloudbongos.com/builders#/task/1003320) lands) and screenshot **three widths (≥1280 / ~900 / ≤480) × two modes (light / dark)** at minimum.
29
+ - Show the screens, then caption them in one line. The person you're working with judges the picture.
30
+ - Grep the receiving page for class collisions before porting a component across pages (the landing's content sections are `.band`; the menu is `.menuBand`).
31
+
32
+ ## Step 3 — build inside the contract (the platform floors)
33
+
34
+ These hold on every instance; a `DESIGN.md` may tighten them, never loosen them:
35
+
36
+ - **The Fifteen Rule** — every colour is a `var()` or a `color-mix()` of the fifteen; the only legal literal is pure black or white with alpha as a scrim, mask or halo.
37
+ - **The dark twins** — every dark rule written twice, byte-identical: `:root[data-mode="dark"]` and `@media (prefers-color-scheme: dark) { :root:not([data-mode="light"]) }`.
38
+ - **No page `:root`** — the pack's `:root` is spliced at the end of `<head>`; page tokens live on `body`.
39
+ - **The 24px floor** — every control clears 24px on both sides; primary pills 46–48px.
40
+ - **AA in both modes** — 4.5:1 body text, 3:1 large text and non-text, light *and* dark, measured from the real stylesheet.
41
+ - **The Kill Switch** — `prefers-reduced-motion: reduce` at the foot of the token layer kills every animation and transition; no motion in JavaScript; the rest frame is a complete composition.
42
+
43
+ Generated code uses the `--dt-*` variables; adapters write only `src/ui/<surface>/`, `assets/ui/<surface>/` and `config/design-sources.json`.
44
+
45
+ ## Step 4 — prove it, then ship the tests with the UI
46
+
47
+ - `node scripts/gds/validate-design.js --strict` after touching adapters, tokens or `design-sources.json` (fitness runs it on every PR).
48
+ - **New interactive code gets a pin in the page's own test file in the same diff** — the grader's Quality worker fails a chrome change that arrives with no test. Contrast pairs are measured in CI, not eyeballed.
49
+ - The task's DONE WHEN is read literally — "both pages" means both pages. Deliberate deviations from a mock stay minor if the ship notes say why.
50
+ - `/builder-ship` with real `--notes` (what changed, which screens you looked at, in which modes) and a plain-language `--summary`.
51
+
52
+ ## Round-tripping with a design tool
53
+
54
+ - **Claude Design** (`/design-sync`): export the tokens + surfaces in, land the generated code back under the claimed task. Design is code; it merges like code.
55
+ - **Figma** (`/figma-design-sync`): push the current state so a designer never opens a stale file; land their edit back as committed code. Canvas art that won't translate becomes an asset, never forced into code.
56
+ - Both are adapters against `modules/ui-design/docs/design-contract.md`; a third tool is a third adapter, not a new integration.
57
+
58
+ ## Stay clear of
59
+
60
+ - The pack's neutral values and `DESIGN.md`'s named rules — changing the world is the owner's decision and an ADR, not a session's taste.
61
+ - A page-private palette, a hex that isn't one of the fifteen, a `:root` in a page, motion in JavaScript.
62
+ - Text: the copy half belongs to `copy-desk` — flag a string, don't rewrite the product's voice in passing.
63
+ - Image generation for anything but text-free hero plates (the owner's rule); UI is rebuilt from templates and the instance's world, not painted.
64
+
65
+ ## How sessions reach this skill
66
+
67
+ - **Standalone:** invoke `/design` to have the loop in front of you.
68
+ - **From a claim:** a `ui`-discipline task makes `claim.js` print the `/design` directive from `scripts/gds/discipline-modes.json` — one carrier, one lookup, the same map `/dev`, `/paint` and `/ideate` ride.
@@ -7,7 +7,7 @@ You are helping the builder run the Claude Design sync loop: export the repo's d
7
7
 
8
8
  ## What this skill does
9
9
 
10
- 1. **Import** — `node scripts/gds/design-sync.js` builds a token-preview bundle (HTML color/typography/spacing/radii cards, `tokens.css`, `tokens.json`, `surfaces.json`) in a temp directory and prints a JSON manifest.
10
+ 1. **Import** — `node scripts/gds/design-sync.js` (a thin shim over `modules/ui-design/scripts/design-sync.js`, the module home — ADR 0197) builds a token-preview bundle (HTML color/typography/spacing/radii cards, `tokens.css`, `tokens.json`, `surfaces.json`) in a temp directory and prints a JSON manifest.
11
11
  2. **Push** — the DesignSync MCP tool (`list_projects` → `finalize_plan` → `write_files`) uploads the bundle to a Claude Design project.
12
12
  3. **Export (handoff)** — when Claude Design generates UI code, the handoff lands it under a claimed Bongos task via `adapter.export()`.
13
13
 
@@ -41,7 +41,7 @@ HTML files with `<!-- @dsCard group="Tokens" -->` appear as Design System cards
41
41
  When Claude Design finishes and hands off to Claude Code, call the adapter directly in Node:
42
42
 
43
43
  ```js
44
- const adapter = require('./src/ui/adapters/claude-design/index.js');
44
+ const adapter = require('./modules/ui-design/adapters/claude-design/index.js');
45
45
  await adapter.export({
46
46
  repoRoot: process.cwd(),
47
47
  surfaceId: '<surface-id>', // e.g. "hall-ui"
@@ -7,7 +7,7 @@ You are helping the builder run the Figma round-trip loop for the `ui` disciplin
7
7
 
8
8
  ## What this skill does
9
9
 
10
- 1. **Import (push)** — `node scripts/gds/figma-design-sync.js` builds a push plan (`figma-plan.json`: color-swatch frame, typography-specimen frame, one reference frame per surface) in a temp directory and prints a JSON manifest.
10
+ 1. **Import (push)** — `node scripts/gds/figma-design-sync.js` (a thin shim over `modules/ui-design/scripts/figma-design-sync.js`, the module home — ADR 0197) builds a push plan (`figma-plan.json`: color-swatch frame, typography-specimen frame, one reference frame per surface) in a temp directory and prints a JSON manifest.
11
11
  2. **Push** — the live Figma MCP tool (`mcp__figma__*` write capability, or `use_figma`) creates/updates the frames described in the plan inside the target Figma file. If write capability isn't available in this session, stop and surface the gap — do not fake the push.
12
12
  3. **Export (handoff)** — when a designer finishes a Figma edit, hand its output to `adapter.export()`.
13
13
 
@@ -34,7 +34,7 @@ Figma hands back one of two shapes, depending on whether Code Connect is wired f
34
34
 
35
35
  **Code Connect output (ready code — the common case):**
36
36
  ```js
37
- const adapter = require('./src/ui/adapters/figma/index.js');
37
+ const adapter = require('./modules/ui-design/adapters/figma/index.js');
38
38
  await adapter.export({
39
39
  repoRoot: process.cwd(),
40
40
  surfaceId: '<surface-id>',
@@ -61,7 +61,7 @@ Round-trip fidelity is limited to what Code Connect or the Figma MCP can extract
61
61
 
62
62
  ## Code-canonical vs. Figma-canonical
63
63
 
64
- Code-canonical is the default: the repo is authoritative, Figma is a synced view. A surface may be flagged `"figmaCanonical": true` in `config/design-sources.json` as an explicit exception (docs/design-contract.md §3.4) — only do this when the builder explicitly asks for a surface a designer actively iterates on in Figma.
64
+ Code-canonical is the default: the repo is authoritative, Figma is a synced view. A surface may be flagged `"figmaCanonical": true` in `config/design-sources.json` as an explicit exception (modules/ui-design/docs/design-contract.md §3.4) — only do this when the builder explicitly asks for a surface a designer actively iterates on in Figma.
65
65
 
66
66
  ## Path safety
67
67
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "_note": "Cloud Bongos neutral design tokens — the baseline every instance resolves over. To override, copy values into config/design-tokens.json (the instance pack). These match config/branding.neutral.json theme.ui (the chrome world, task 1003298; tests/design_tokens_sync.mjs fails on drift) so a vanilla instance with no instance pack still renders correctly. The world's derived tokens, materials and motion grammar are recorded in DESIGN.md. See docs/design-contract.md.",
2
+ "_note": "Cloud Bongos neutral design tokens — the baseline every instance resolves over. To override, copy values into config/design-tokens.json (the instance pack). These match config/branding.neutral.json theme.ui (the chrome world, task 1003298; tests/design_tokens_sync.mjs fails on drift) so a vanilla instance with no instance pack still renders correctly. The world's derived tokens, materials and motion grammar are recorded in DESIGN.md. See modules/ui-design/docs/design-contract.md.",
3
3
  "colors": {
4
4
  "bg": "#edecee",
5
5
  "bgCard": "#fbfafc",
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "cloud-bongos/design-tokens",
4
4
  "title": "Cloud Bongos design tokens",
5
- "description": "Canonical design-token schema for a Cloud Bongos instance. Extends config/branding.json theme.ui. Validated by scripts/gds/validate-design.js. See docs/design-contract.md.",
5
+ "description": "Canonical design-token schema for a Cloud Bongos instance. Extends config/branding.json theme.ui. Validated by modules/ui-design/scripts/validate-design.js (node scripts/gds/validate-design.js is its shim). See modules/ui-design/docs/design-contract.md.",
6
6
  "type": "object",
7
7
  "required": ["colors", "fonts"],
8
8
  "additionalProperties": false,
@@ -0,0 +1,52 @@
1
+ # ADR 0197 — The ui-design module: design is a platform capability; the instance owns its world
2
+
3
+ - **Status:** accepted
4
+ - **Date:** 2026-08-28
5
+ - **Task:** [task 1003324](https://cloudbongos.com/builders#/task/1003324) (goal 1000080 — Apex UI pass 2; the first of five tasks scoped with the owner on 2026-08-28: 1003320 the kit, 1003321 the skills, 1003322 the apex carve, 1003323 the style library)
6
+ - **Relates to:** [ADR 0081](<redacted>.md) (the tool-agnostic design layer this module absorbs), [ADR 0083](<redacted>.md) (the module system + the one-way rule), [ADR 0062 §7](<redacted>.md) (the core ↔ host split), [ADR 0108 §1](<redacted>.md) (host content vs the core package), [ADR 0196](<redacted>.md) (the chrome world as the token contract), ADR 0178 (the copy half), `modules/ui-design/CLAUDE.md`
7
+
8
+ ## Context
9
+
10
+ ADR 0081 made the repo the source of truth for design and put its layer in core: two adapters under `src/ui/adapters/`, three CLIs under `scripts/gds/`, the contract at `docs/design-contract.md`, the tokens under `config/`. It shipped as *Cloud Bongos's* design machinery — and the whole-frontend pass under goal 1000080 (tasks 1003296–1003300) then built Cloud Bongos's own world on top of it: the chrome world, the fifteen-token contract, `DESIGN.md`, the probes and renderers that made "look before you ship" real, the vetted taste skills the sessions leaned on.
11
+
12
+ On 2026-08-28 the owner reframed what that work is. It is **not Cloud Bongos's front door**. It is a **platform capability**: every builder on every instance should be able to create and design good-looking, functional UIs *in line with that instance's world* — its palette, its faces, its materials — and build on them. Cloud Bongos's front door is the first customer of that capability, not its owner. The three things a builder needs (the contract and its tooling; a way to look before shipping; the taste and the looks) were scattered across core, session scratchpads and personal skill installs, with no home, no manifest and no line between "this is the platform's rule" and "this is Cloud Bongos's taste".
13
+
14
+ Two facts shaped the shape of the module:
15
+
16
+ 1. **The core ↔ host split already had a name for this** (ADR 0062 §7): the core ships method, the instance ships identity. `config/design-tokens.*`, `config/design-sources.json` and `DESIGN.md` are identity; the adapters, the validator, the playbook and the floors are method.
17
+ 2. **The module contract is the platform's unit of capability** (ADR 0083): a self-contained directory the loader discovers, that contributes what it ships and reaches core only through the doorway. grading, economy, memory are default-on because every instance grades, pays and remembers. Every instance has a face.
18
+
19
+ ## Decision
20
+
21
+ 1. **`modules/ui-design/` is a default-on core-domain module** that ships METHOD and never a world. It joins the default-on roster beside grading / economy / memory (`default: true`, `maintenance: core-maintained`) and is allowlisted in `publish-manifest.js`, so a released core carries it.
22
+
23
+ 2. **ADR 0081's layer moves in; the host boundary stays out.** `src/ui/adapters/{claude-design,figma}` → `modules/ui-design/adapters/`; `scripts/gds/{design-sync,figma-design-sync,validate-design}.js` → `modules/ui-design/scripts/`; `docs/design-contract.md` → `modules/ui-design/docs/`. `config/design-tokens.neutral.json`, `config/design-tokens.schema.json` and `config/design-sources.json` **stay in `config/`**: they are the branding contract the module reads and never owns. `DESIGN.md` stays at the repo root: it is the instance's world. `src/ui/` is gone from the core tree — the contract's `src/ui/<surface>/` layout is what an adapter *targets* on an instance, not core code.
24
+
25
+ 3. **Declaration-only.** The manifest contributes three skills (`design`, `design-sync`, `figma-design-sync`) and nothing else — no routes, pollers, web surfaces, migrations or ports (the `character-anim` shape). Consequences that matter: `GET /modules` lists it; `claude-materialize` skips its skills on an instance that disables it; disabling it withdraws the skills and touches no served surface, which is the DONE WHEN's "can be disabled without breaking anything" in structural form. It contributes **no `ui` discipline yet**: `enabledDisciplines()` feeds the hall settings page and newcomer-restock, neither of which knows `ui`; `discipline-modes.json` already routes a `ui` task to `/design`, so the playbook works today and offering the discipline on sign-up is a follow-up.
26
+
27
+ 4. **The `/design` playbook exists.** `discipline-modes.json` has pointed `ui` tasks at a `/design` skill since task 1267; the skill was never written, so a claimed `ui` task told the builder to open a door that wasn't there. It is written now, in the `/paint` shape (show-first) with a world-first Step 1: read the instance's pack + `DESIGN.md`, and where an instance has none, the neutral pack + the floors are the whole rulebook — no page invents a palette.
28
+
29
+ 5. **The module's `CLAUDE.md` draws the line between the platform's floors and the instance's world.** Floors — held on every instance, tightenable by a `DESIGN.md`, never loosenable — are the Fifteen Rule (thirteen colours + two font stacks are the only host-overridable surface), the dark twins (every dark rule written twice at (0,2,0)), no page `:root`, the 24px control floor, AA in both modes measured from the real stylesheet, and the Kill Switch (`prefers-reduced-motion` kills everything; no motion in JavaScript). The instance's world is everything those floors leave open: the palette, the faces, the materials, the motion grammar, the taste bans. This is the same split as ADR 0062 §7, written for design.
30
+
31
+ 6. **The CLIs keep thin `scripts/gds/` shims** rather than every caller re-pointing at the module. Three reasons, all mechanical: `node scripts/gds/<x>.js` is the invocation form `claude-materialize` rewrites to `bongos exec scripts/gds/<x>.js` for a packaged core (a module path would not be rewritten and would not resolve at an instance root); `doc-cli-guard` (Check 22) resolves documented flags against `scripts/gds/` sources, so the shims carry the usage lines; and every carved domain before this one kept its commands under `scripts/gds/` (memory, ideas, sessions — "a command travels with its domain but stays under scripts/"). The module file is the implementation and the DONE WHEN's `node modules/ui-design/scripts/validate-design.js` runs it directly; the shim is a `require()` and nothing else. Inside the module the CLIs resolve the repo root by walking up from `__dirname` instead of the computed `require(path.resolve(…, 'src', 'instance-config'))` they carried before — a reach into core that the static boundary scanner could not see and that a module may not make (ADR 0083); the instance root *is* the repo root today (ADR 0108 §1), and when the core installs as a package the root arrives through the doorway.
32
+
33
+ 7. **Three reserved homes, each named for the task that fills it:** `kit/` (task 1003320 — the stub, the renderer/auditor, the probes, the mock checker), `skills/` (task 1003321 — the vendored UI skills with provenance sidecars, a licence allowlist and the PLATFORM PREAMBLE; **the vendoring policy is that task's ADR**, this one only points at it), `styles/` (task 1003323 — looks as branding packs). A README in each so the home is visible in git and a builder landing there knows what belongs.
34
+
35
+ 8. **The front door keeps its own key.** `public-landing` stays a separate module key (and carves to `modules/public-landing/` in task 1003322), because a customer of a capability is not part of it: a second instance's landing must be able to use `ui-design` without inheriting Cloud Bongos's page. The module's scope-map key covers its own dir, the three shims, its contributed skill dirs and the two recipes; none of those paths is protected, so a goal scoped to `ui-design` needs Metic, not Archon.
36
+
37
+ ## Consequences
38
+
39
+ - **A builder on any instance gets the same entry.** `modules/ui-design/CLAUDE.md` is the door: what the module gives, how the world is resolved, which rules are the platform's and which are the instance's. The next three tasks fill the kit, the skills and the styles into homes that already exist and already have a manifest.
40
+ - **The one-way rule holds for the design layer for the first time.** The adapters and CLIs reach nothing in core; `<redacted>` guards them from now on. The core-side callers (the shims, `checkDesignContract`) live under `scripts/`, outside the kernel boundary.
41
+ - **knip loses sight of the moved files** — its `project` set covers `src/**` and `scripts/**`, not `modules/ui-design/**`. Accepted: the `knip_issue_count` ratchet is shrink-only and a module's files are exercised by its tests and by fitness, not by knip's reachability graph. Extending knip to module trees is a devsecops decision, not this carve's.
42
+ - **`copy-inventory.js`'s recorded mismatch changes wording, not meaning:** `src/ui/` no longer holds "only `adapters/`" — it no longer exists in the core tree. The registry note says so, and regenerates.
43
+ - **Nothing an instance serves changed.** The move is byte-identical in behaviour: same adapters, same CLIs, same validator, same contract text with its paths updated. `validate-design` runs green from the new home on a fresh clone.
44
+
45
+ ## Rejected alternatives
46
+
47
+ - **Leave the layer in core and put only the kit/skills/styles in a module.** Splits one capability across two homes with two rulebooks — the exact scatter the owner asked to end. The contract and its adapters are the method; they go where the method lives.
48
+ - **Move `config/design-tokens.*` and `design-sources.json` into the module.** Makes the instance's world module-owned and module-versioned: re-theming an instance would mean editing the core package. The host boundary is the point of ADR 0062 §7; the tokens stay in `config/`.
49
+ - **Put the front door in the module (`ui-design` owns `public-landing/`).** A capability that ships its first customer's page cannot be reused by a second customer without inheriting the first's world. First customer, not owner.
50
+ - **Module-hosted CLIs with no shims.** Breaks `claude-materialize`'s rewrite on a packaged core and every documented invocation at once, for no boundary benefit — a shim is a `require()`.
51
+ - **Contribute the `ui` discipline now.** Surfaces it on sign-up before the hall settings page and newcomer-restock know it; a discipline that the restock cannot stock is a newcomer with no chore. Follow-up, once those readers are taught.
52
+ - **A `--dt-*`-only contract with no `DESIGN.md` resolution.** Tokens say *what the colours are*; they cannot say *what the world is* (materials, motion, taste bans). The floors/world split needs the prose file as much as the pack.
@@ -284,5 +284,6 @@ This keeps the decision history honest and traceable.
284
284
  | 0194 | [**A project's membership door is one decision, answered the same way everywhere a stranger meets it** ([task 1003044](https://cloudbongos.com/builders#/task/1003044), goal 1000058). The owner's 2026-08-16 joinability setting — open / apply / invite_only — was stored (1003040), pushed (1003139/1003140) and resolved into `branding().project.joinability`, enforced by nothing. Decision: ONE reader, `joinabilityMode()` in `auth-admission.js`, and `openEnrollmentEnabled()` becomes `mode === 'open'`, so the four sign-in call sites, `webAdmissionStatus` and the manifest's `admission.policy` follow untouched (SR-19: one gate, no drift). The legacy `OPEN_XENOS_ENROLLMENT` flag still opens an APPLY project — a self-hosted instance that set it keeps its door across the upgrade — but never reopens an explicit invite_only; an unreadable pack or a value this core cannot read fails CLOSED (invite_only), the ADR 0192 rule. The public `POST /access-requests` answers the door FIRST — before validation, before any lookup — `403 invite_only` / `409 open_enrollment` with plain sentences: no query, nothing revealed about who exists, and DB-free enough for the real booted app to prove. An Archon's invite is the row the gate already reads: `POST /access-requests/invite` writes `access_requests` at 'invited' (resolving a pending one in place), so sign-in consults nothing new — surfaced as "Invite by GitHub username" on the Watch page. The door is SAID wherever a stranger meets it, in the project's words: the hall landing renders one door per mode from the injected pack, the web 403 names the invite-only door and the way in, the CLI stops instead of filing, the hub's join relay names the door in the hub's own words (a project is trusted to build, not to write prose into the platform's UI) instead of painting a refusal as "requested" or "unreachable". `admission.policy` stays binary (pinned; agrees for free); `joinabilityMode` joins the doorway — a human MINOR by ADR 0161 §2, which the publish lane's LIVE test refused (HEAD's version must be a CI carrier's), so it rides the next CI patch and the contradiction is filed as an idea. The hub's `#mJoinability` clones `#mVisibility` rather than a factory — a third setting is where a factory pays. Rejected: folding the flag into `branding()` (memoized vs per-call; the manifest must stay the pushed value); a 200 for the open door (an older CLI would wait thirty minutes for an approval); re-deriving the mode inside the module; a second invite table.](<redacted>.md) | instance / project joinability |
285
285
  | 0195 | [**ADR numbers are checked like migration numbers, and the twenty existing collisions are grandfathered by name** ([task 1003164](https://cloudbongos.com/builders#/task/1003164)). Two ADRs could share a number and nothing flagged it — git sees no path collision, the index auto-merges into two rows, and every gate passes; it was found by a human reading `ls docs/adr/`, after a task note had already cited a number the collision made point at an unrelated document. Migrations had this guard already (`stemCollisions()` hard-fails CI, because a re-used migration number silently skips a migration); ADRs had only a best-effort allocator at claim time and nothing afterwards. `scripts/gds/adr-namespace.js` is the sibling module, wired into fitness as Check 31 and so into the required `unit` gate. Building it found twenty live collisions, not one, plus fourteen index defects of the same merge class — two ADRs listed twice and twelve with no row at all, ten of them the second file of a colliding pair, which is how a collision hides. The twenty pairs are grandfathered by EXACT FILENAME rather than renumbered: renumbering breaks every citation to them, which is the harm the check exists to prevent, and set-equality keeps the exemption as narrow as the history that earned it — a third file on a legacy number, or a rename of either half, still fails, and the list may only shrink. The index half is keyed on LINK TARGET, not number (a number rule cannot express a grandfathered pair): every file has exactly one row, every row points at a file that exists. Row ordering warns and never blocks — ten legacy rows are out of order and no PR author caused that (the ADR 0189 split). Rejected: renumbering; grandfathering by number; a numeric cutoff like LEGACY_BARE_CORE_MAX (a new ADR takes a number above the max, so it would catch nothing); fixing it in the claim-time allocator (which already tries, against a stale tree — that is how the collision happened).](<redacted>.md) | docs / numbering discipline |
286
286
  | 0196 | [**The chrome world becomes the token contract; the landing gets its own world sheet beside the hub's** ([task 1003298](https://cloudbongos.com/builders#/task/1003298), goal 1000080). The owner picked the chrome-blobs world (1003296) and the v3 composition with light rebuilt to the dark standard (1003297); this build makes it the platform's token contract. Decisions: (1) the neutral pack moves to the world's LIGHT values (pale grey paper, black ink, salmon accent, Manrope + JetBrains Mono) and design-tokens mirrors it; --accent-deep is #a3481a rather than the mock's #d96a35 because the hub and the gate pages paint TEXT with it and #a3481a is the lightest burnt orange clearing 4.5:1 on all three light grounds; the rgba hairlines are flattened to hex so hex-maths consumers survive. (2) theme.ui.backdrop becomes var(--bg): a literal there paints the light ground under the dark page in both modes, since the body rule outranks every sheet. (3) The landing gets its own world sheet public-landing/assets/world.css (contract tier = pack, derived tier both modes, root-absolute plate token PAIRS, the kill switch; NO composition switches) and cosmos.css stays the hub's component sheet until A4 — folding the two tiers would have collided (--line is a width in the world and a colour in the hub; the world's warm --ok/--warn/--err would repaint the hub's fixed green/amber/red chips). cosmos.css's dark tier moves to the world's black and its derived tier is retuned for the salmon accent (dark ink on the fill, never white). (4) Plates ship under public-landing/assets/world/ with provenance embedded: black plates verbatim JPEG, cutouts as WebP with alpha at 1600px (85–170 KB vs 1.1–2.4 MB PNG), sidecars; plate URLs in custom properties escape the ?v= stamp (edge cache 4h), accepted. (5) Live figures are BAKED inside apex-only sentinels (real, dated; a child renders empty until its own feed answers) and refreshed at render time from the five public feeds with fixed definitions: tasks shipped = the sum over every version row, builders = leaderboard entries holding credits, the ledger line = the first building version; live titles have em dashes normalised to a comma and a trailing parenthetical dropped. Every pack-reading fallback site (the claude-design adapter, the status explore page, provisioning onboarding, dev-box brand artifacts + tray icons, the two gate pages) is moved in the same task so no page keeps a private palette. Rejected: one merged token tier; a landing-private palette; PNG cutouts; a script-only ledger; #d96a35 as accent-deep.](<redacted>.md) | apex / design system |
287
+ | 0197 | [**The ui-design module: design is a platform capability; the instance owns its world** ([task 1003324](https://cloudbongos.com/builders#/task/1003324), goal 1000080 — the first of the five ui-design tasks scoped with the owner 2026-08-28). ADR 0081 put the tool-agnostic design layer in core as Cloud Bongos's machinery; the whole-frontend pass then built the chrome world on it and left the three things a builder needs — the contract and its tooling, a way to look before shipping, the taste and the looks — scattered across core, scratchpads and personal skill installs. The owner's reframing: this is NOT the front door, it is a PLATFORM capability every builder on every instance gets, and Cloud Bongos's front door is its first customer, not its owner. Decisions: (1) `modules/ui-design/` is a default-on core-domain module beside grading/economy/memory — it ships METHOD, never a world; (2) ADR 0081's layer moves in (`src/ui/adapters/` → `adapters/`, the three `scripts/gds/` CLIs → `scripts/`, `docs/design-contract.md` → `docs/`) while `config/design-tokens.*`, `design-sources.json` and `DESIGN.md` STAY out as the host boundary — the ADR 0062 §7 split written for design; (3) declaration-only: three contributed skills, no routes/port/migrations, so `GET /modules` lists it and disabling it withdraws the skills and touches no served surface — and NO `ui` discipline yet, because the hall settings page and newcomer-restock don't know it; (4) the `/design` playbook is finally written — `discipline-modes.json` had routed `ui` tasks to a skill that did not exist since task 1267; (5) the module CLAUDE.md draws the platform FLOORS (the Fifteen Rule, the dark twins, no page `:root`, the 24px floor, AA in both modes, the Kill Switch) against the instance's WORLD (its packs + DESIGN.md), tightenable and never loosenable; (6) the CLIs keep thin `scripts/gds/` shims — the form `claude-materialize` rewrites to `bongos exec` on a packaged core, the form `doc-cli-guard` resolves, and the carve precedent — while inside the module they walk up from `__dirname` instead of the computed `require()` into `src/instance-config.js` the static boundary scanner could not see; (7) three reserved homes, each README'd for the task that fills it, the vendoring policy pointed at the skills task's ADR; (8) `public-landing` keeps its own key. Rejected: leaving the layer in core; moving the token files in; the module owning the front door; module-hosted CLIs with no shims; contributing the `ui` discipline now.](<redacted>.md) | modules / design system |
287
288
 
288
289
  > ⚠️ **Numbering collisions are now machine-enforced, not narrated.** Twenty numbers are shared by two ADRs each — assigned in parallel sessions before anything checked. The files keep their filenames (renumbering would break every existing citation, and a number once assigned is never reused), and this table disambiguates each pair as `NNNN-a` / `NNNN-b`. The authoritative list is `LEGACY_DUPLICATE_ADRS` in [`scripts/gds/adr-namespace.js`](../../scripts/gds/adr-namespace.js), frozen by exact filename: a **new** collision — or a third file joining a legacy number, or a rename of either half — hard-fails the `unit` CI gate, as does an index row that points at no file or an ADR with no row. The list may only shrink. This paragraph used to narrate the collisions one by one and had fallen eight behind reality; see [ADR 0195](<redacted>.md) for why the check exists and why the pairs are grandfathered rather than renumbered.