@bongos/core 1.19.512 → 1.19.514
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.bongos-core.json +77 -42
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +2 -0
- package/clients/bongos-client/index.cjs +2 -0
- package/clients/bongos-client/index.d.ts +3 -0
- package/clients/bongos-client/index.mjs +2 -0
- package/docs/adr/0182-project-visibility-two-axes.md +2 -0
- package/docs/adr/0239-a-recommendation-is-a-table-that-carries-its-own-reason.md +177 -0
- package/docs/adr/README.md +1 -0
- package/docs/api/openapi.json +41 -4
- package/docs/api-reference.md +4 -3
- package/docs/copy-inventory.md +36 -35
- package/docs/copy-registry.json +93 -74
- package/docs/module-api-changelog.md +4 -0
- package/modules/dev-box/app/src/vendor/bongos-client.cjs +2 -0
- package/modules/hall-ui/public/hall-kit.js +309 -0
- package/modules/hall-ui/public/hall-render.js +10 -38
- package/modules/hall-ui/public/profile-charts.js +58 -65
- package/modules/hall-ui/public/profile.css +9 -18
- package/modules/hall-ui/public/style.css +101 -15
- package/modules/hall-ui/public/watch.css +6 -14
- package/modules/hall-ui/public/watch.html +1 -1
- package/modules/hall-ui/public/watch.js +139 -54
- package/modules/platform-identity/platform-identity.js +24 -20
- package/modules/platform-identity/projects-feed.js +142 -0
- package/modules/platform-identity/routes/projects.js +27 -8
- package/modules/platform-identity/tests/platform-identity.mjs +9 -5
- package/modules/provisioning/recommendations.js +260 -0
- package/modules/provisioning/routes/provisioning.js +29 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/src/module-api.js +1 -1
- package/tests/hall_audit.mjs +84 -0
- package/tests/hall_kit_charts.mjs +328 -0
- package/tests/hall_profile_world.mjs +27 -6
- package/tests/helpers.mjs +161 -0
- package/tests/joinability_invite_only.mjs +10 -2
- package/tests/projects_hub.mjs +5 -1
- package/tests/provisioning_recommendations.mjs +448 -0
- package/tests/task_detail_ui.mjs +1 -153
- package/tests/visible_projects_feed.mjs +320 -0
- package/tests/watch_applications_queue.mjs +381 -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.
|
|
6
|
-
"core_contract": "1.19.
|
|
7
|
-
"source_commit": "
|
|
5
|
+
"core_version": "1.19.514",
|
|
6
|
+
"core_contract": "1.19.514",
|
|
7
|
+
"source_commit": "b092f2a3e4ee99d6f856ae4d1440ed723f1dcba8",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-09-
|
|
9
|
+
"built_at": "2026-09-03T19:32:24.004Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
|
-
"docs_redacted":
|
|
12
|
+
"docs_redacted": 430,
|
|
13
13
|
"agent_docs_stubbed": 24,
|
|
14
|
-
"functional_verbatim":
|
|
14
|
+
"functional_verbatim": 1958,
|
|
15
15
|
"rules": 3,
|
|
16
16
|
"gate_literals": 3,
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
|
-
"file_count":
|
|
20
|
-
"tree_sha256": "
|
|
19
|
+
"file_count": 2412,
|
|
20
|
+
"tree_sha256": "4ea8c8583161c137a8be9e3d96b1db2589a64bd504a47f7e75ebeb15232753d2",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/blocker-review/SKILL.md",
|
|
@@ -362,12 +362,12 @@
|
|
|
362
362
|
{
|
|
363
363
|
"path": "clients/bongos-client/README.md",
|
|
364
364
|
"mode": "0000644",
|
|
365
|
-
"sha256": "
|
|
365
|
+
"sha256": "546f5670b4637aa1d4c492a8616d5189a971c79e8e2e163d12fe11276292faa6"
|
|
366
366
|
},
|
|
367
367
|
{
|
|
368
368
|
"path": "clients/bongos-client/bongos-client.global.js",
|
|
369
369
|
"mode": "0000644",
|
|
370
|
-
"sha256": "
|
|
370
|
+
"sha256": "ae151ff268d04dced73fae1136c682215a02e59bae5edb68a3d6001c0143dd57"
|
|
371
371
|
},
|
|
372
372
|
{
|
|
373
373
|
"path": "clients/bongos-client/examples/hello-world.mjs",
|
|
@@ -377,17 +377,17 @@
|
|
|
377
377
|
{
|
|
378
378
|
"path": "clients/bongos-client/index.cjs",
|
|
379
379
|
"mode": "0000644",
|
|
380
|
-
"sha256": "
|
|
380
|
+
"sha256": "72d841c53787c5ad83b214c2ac816fd4cb9c97b47329eb0417b80e660a9f6b02"
|
|
381
381
|
},
|
|
382
382
|
{
|
|
383
383
|
"path": "clients/bongos-client/index.d.ts",
|
|
384
384
|
"mode": "0000644",
|
|
385
|
-
"sha256": "
|
|
385
|
+
"sha256": "07554254c8559f81ec5cf45807ddccd8488732b228a618167455c932e7f05750"
|
|
386
386
|
},
|
|
387
387
|
{
|
|
388
388
|
"path": "clients/bongos-client/index.mjs",
|
|
389
389
|
"mode": "0000644",
|
|
390
|
-
"sha256": "
|
|
390
|
+
"sha256": "c4b04368e61803e2fe36f26ba3757aa75ada7e465384baf3e53cd012c9ce8423"
|
|
391
391
|
},
|
|
392
392
|
{
|
|
393
393
|
"path": "clients/bongos-client/package.json",
|
|
@@ -1407,7 +1407,7 @@
|
|
|
1407
1407
|
{
|
|
1408
1408
|
"path": "docs/adr/0182-project-visibility-two-axes.md",
|
|
1409
1409
|
"mode": "0000644",
|
|
1410
|
-
"sha256": "
|
|
1410
|
+
"sha256": "273133f1ce79a6e67b3beaa6d993c7aa3dda23daba0beeb2e9aedf9250152e6f"
|
|
1411
1411
|
},
|
|
1412
1412
|
{
|
|
1413
1413
|
"path": "docs/adr/0183-criteria-close-themselves.md",
|
|
@@ -1699,20 +1699,25 @@
|
|
|
1699
1699
|
"mode": "0000644",
|
|
1700
1700
|
"sha256": "fb05e36eb48861f2b32a38da04eba839f8141bd52ff9d913070bc589c115f9d5"
|
|
1701
1701
|
},
|
|
1702
|
+
{
|
|
1703
|
+
"path": "docs/adr/0239-a-recommendation-is-a-table-that-carries-its-own-reason.md",
|
|
1704
|
+
"mode": "0000644",
|
|
1705
|
+
"sha256": "42b20cd6d2e8a8d76c980df73087fd404487e4c479034dbe34d8297677bd9387"
|
|
1706
|
+
},
|
|
1702
1707
|
{
|
|
1703
1708
|
"path": "docs/adr/README.md",
|
|
1704
1709
|
"mode": "0000644",
|
|
1705
|
-
"sha256": "
|
|
1710
|
+
"sha256": "cef542ef427dd81632465f17c6343c6b27f3ab69436eba2130c4fa4b5c9bc4ae"
|
|
1706
1711
|
},
|
|
1707
1712
|
{
|
|
1708
1713
|
"path": "docs/api-reference.md",
|
|
1709
1714
|
"mode": "0000644",
|
|
1710
|
-
"sha256": "
|
|
1715
|
+
"sha256": "36baedec0a98a17dd013bf264cdb5502624de9529ed62e69aa88590574b1b236"
|
|
1711
1716
|
},
|
|
1712
1717
|
{
|
|
1713
1718
|
"path": "docs/api/openapi.json",
|
|
1714
1719
|
"mode": "0000644",
|
|
1715
|
-
"sha256": "
|
|
1720
|
+
"sha256": "718e7ab37e024cce51fb82da0b3a535aff961d04fb0dc5e25b8ec31a61e64851"
|
|
1716
1721
|
},
|
|
1717
1722
|
{
|
|
1718
1723
|
"path": "docs/architecture.md",
|
|
@@ -1737,12 +1742,12 @@
|
|
|
1737
1742
|
{
|
|
1738
1743
|
"path": "docs/copy-inventory.md",
|
|
1739
1744
|
"mode": "0000644",
|
|
1740
|
-
"sha256": "
|
|
1745
|
+
"sha256": "0cc8ccfda8d8e3e7b518fae7a7584bb368d7d2eac6703518404d30f0b6ead30d"
|
|
1741
1746
|
},
|
|
1742
1747
|
{
|
|
1743
1748
|
"path": "docs/copy-registry.json",
|
|
1744
1749
|
"mode": "0000644",
|
|
1745
|
-
"sha256": "
|
|
1750
|
+
"sha256": "1003ea51740a5f71af49e05c66ba088c337185680dd92a391c959e8ea76a3f40"
|
|
1746
1751
|
},
|
|
1747
1752
|
{
|
|
1748
1753
|
"path": "docs/design/apex-pass-2-direction.md",
|
|
@@ -2587,7 +2592,7 @@
|
|
|
2587
2592
|
{
|
|
2588
2593
|
"path": "docs/module-api-changelog.md",
|
|
2589
2594
|
"mode": "0000644",
|
|
2590
|
-
"sha256": "
|
|
2595
|
+
"sha256": "decebcba9ee02ff15412e119309d9a37203ee82159922157b37c7cd7ddc21926"
|
|
2591
2596
|
},
|
|
2592
2597
|
{
|
|
2593
2598
|
"path": "docs/modules-contract.md",
|
|
@@ -3957,7 +3962,7 @@
|
|
|
3957
3962
|
{
|
|
3958
3963
|
"path": "modules/dev-box/app/src/vendor/bongos-client.cjs",
|
|
3959
3964
|
"mode": "0000644",
|
|
3960
|
-
"sha256": "
|
|
3965
|
+
"sha256": "72d841c53787c5ad83b214c2ac816fd4cb9c97b47329eb0417b80e660a9f6b02"
|
|
3961
3966
|
},
|
|
3962
3967
|
{
|
|
3963
3968
|
"path": "modules/dev-box/app/test/unit.mjs",
|
|
@@ -4707,12 +4712,12 @@
|
|
|
4707
4712
|
{
|
|
4708
4713
|
"path": "modules/hall-ui/public/hall-kit.js",
|
|
4709
4714
|
"mode": "0000644",
|
|
4710
|
-
"sha256": "
|
|
4715
|
+
"sha256": "9fdd4fa659a6ff1f36159a89a5bab9d12009b1624f7d72f8d1296d1dffff0d3f"
|
|
4711
4716
|
},
|
|
4712
4717
|
{
|
|
4713
4718
|
"path": "modules/hall-ui/public/hall-render.js",
|
|
4714
4719
|
"mode": "0000644",
|
|
4715
|
-
"sha256": "
|
|
4720
|
+
"sha256": "e06761bf930a2b7bf8b0c4a3eba0532edb1a6f0d49d366b6889ebba9101e5d4f"
|
|
4716
4721
|
},
|
|
4717
4722
|
{
|
|
4718
4723
|
"path": "modules/hall-ui/public/hall-widgets.js",
|
|
@@ -4907,7 +4912,7 @@
|
|
|
4907
4912
|
{
|
|
4908
4913
|
"path": "modules/hall-ui/public/profile-charts.js",
|
|
4909
4914
|
"mode": "0000644",
|
|
4910
|
-
"sha256": "
|
|
4915
|
+
"sha256": "6eb791bb5d73e869f1af1dbabe6fbd04eccf970b54696a89a4cd1d28e6e705df"
|
|
4911
4916
|
},
|
|
4912
4917
|
{
|
|
4913
4918
|
"path": "modules/hall-ui/public/profile-connections.js",
|
|
@@ -4922,7 +4927,7 @@
|
|
|
4922
4927
|
{
|
|
4923
4928
|
"path": "modules/hall-ui/public/profile.css",
|
|
4924
4929
|
"mode": "0000644",
|
|
4925
|
-
"sha256": "
|
|
4930
|
+
"sha256": "18d65cb2bab78487a4cbf2447154a69674291972d15256d338123c2a437abc87"
|
|
4926
4931
|
},
|
|
4927
4932
|
{
|
|
4928
4933
|
"path": "modules/hall-ui/public/profile.html",
|
|
@@ -5057,7 +5062,7 @@
|
|
|
5057
5062
|
{
|
|
5058
5063
|
"path": "modules/hall-ui/public/style.css",
|
|
5059
5064
|
"mode": "0000644",
|
|
5060
|
-
"sha256": "
|
|
5065
|
+
"sha256": "801d467a63d65c24877cac2741308590b9cd66530231f77bdf7230d1c4ebe513"
|
|
5061
5066
|
},
|
|
5062
5067
|
{
|
|
5063
5068
|
"path": "modules/hall-ui/public/task-detail.js",
|
|
@@ -5097,17 +5102,17 @@
|
|
|
5097
5102
|
{
|
|
5098
5103
|
"path": "modules/hall-ui/public/watch.css",
|
|
5099
5104
|
"mode": "0000644",
|
|
5100
|
-
"sha256": "
|
|
5105
|
+
"sha256": "ea2f7870bdd9383cfded8b2b09724486faa0793438dfa17bc52af189c8a81c6f"
|
|
5101
5106
|
},
|
|
5102
5107
|
{
|
|
5103
5108
|
"path": "modules/hall-ui/public/watch.html",
|
|
5104
5109
|
"mode": "0000644",
|
|
5105
|
-
"sha256": "
|
|
5110
|
+
"sha256": "60ffce27ce4250223dc6bbaa22e1b7b9dfb4f689bd78b6ca1c75445088c5ddb9"
|
|
5106
5111
|
},
|
|
5107
5112
|
{
|
|
5108
5113
|
"path": "modules/hall-ui/public/watch.js",
|
|
5109
5114
|
"mode": "0000644",
|
|
5110
|
-
"sha256": "
|
|
5115
|
+
"sha256": "f5d264fde6898c3cf82387d042d26fb434bbd8e60657c376b452f89b0a85435c"
|
|
5111
5116
|
},
|
|
5112
5117
|
{
|
|
5113
5118
|
"path": "modules/hall-ui/public/watch.states.json",
|
|
@@ -5812,7 +5817,7 @@
|
|
|
5812
5817
|
{
|
|
5813
5818
|
"path": "modules/platform-identity/platform-identity.js",
|
|
5814
5819
|
"mode": "0000644",
|
|
5815
|
-
"sha256": "
|
|
5820
|
+
"sha256": "c58dad2f4aee4030bfc2e93904760f70185c799b388a20d715ebe70812b942ed"
|
|
5816
5821
|
},
|
|
5817
5822
|
{
|
|
5818
5823
|
"path": "modules/platform-identity/pollers/code-sweep.js",
|
|
@@ -5824,6 +5829,11 @@
|
|
|
5824
5829
|
"mode": "0000644",
|
|
5825
5830
|
"sha256": "2e898799632a2b5c2ead9cb44fa0b8029fcb6d217f7d5f26c8a39b34c75bbea7"
|
|
5826
5831
|
},
|
|
5832
|
+
{
|
|
5833
|
+
"path": "modules/platform-identity/projects-feed.js",
|
|
5834
|
+
"mode": "0000644",
|
|
5835
|
+
"sha256": "7ba4e7f2a375a1197524106605ff5dd6e4e597b2926bf6498f784ede5099a447"
|
|
5836
|
+
},
|
|
5827
5837
|
{
|
|
5828
5838
|
"path": "modules/platform-identity/publish-gate.js",
|
|
5829
5839
|
"mode": "0000644",
|
|
@@ -5852,7 +5862,7 @@
|
|
|
5852
5862
|
{
|
|
5853
5863
|
"path": "modules/platform-identity/routes/projects.js",
|
|
5854
5864
|
"mode": "0000644",
|
|
5855
|
-
"sha256": "
|
|
5865
|
+
"sha256": "ec297f39a3d7f23b05b24ea6837bb9bfd07a12f99734788e9332769c59acc7b7"
|
|
5856
5866
|
},
|
|
5857
5867
|
{
|
|
5858
5868
|
"path": "modules/platform-identity/routes/public-profile.js",
|
|
@@ -5882,7 +5892,7 @@
|
|
|
5882
5892
|
{
|
|
5883
5893
|
"path": "modules/platform-identity/tests/platform-identity.mjs",
|
|
5884
5894
|
"mode": "0000644",
|
|
5885
|
-
"sha256": "
|
|
5895
|
+
"sha256": "a0ed65254f629cc29f4f1093c54d5e78a148d5bc7f072fb98819562a96f7dd37"
|
|
5886
5896
|
},
|
|
5887
5897
|
{
|
|
5888
5898
|
"path": "modules/platform-identity/ui/.gitkeep",
|
|
@@ -5984,10 +5994,15 @@
|
|
|
5984
5994
|
"mode": "0000644",
|
|
5985
5995
|
"sha256": "27046325beffad5d1edfcc91c331048038900ef7d32f1d38796755c7990ba202"
|
|
5986
5996
|
},
|
|
5997
|
+
{
|
|
5998
|
+
"path": "modules/provisioning/recommendations.js",
|
|
5999
|
+
"mode": "0000644",
|
|
6000
|
+
"sha256": "8c4b2d8d17b80229c371b82ac9a5a2cf2fa979683ac586e8b833ca0a309a92fc"
|
|
6001
|
+
},
|
|
5987
6002
|
{
|
|
5988
6003
|
"path": "modules/provisioning/routes/provisioning.js",
|
|
5989
6004
|
"mode": "0000644",
|
|
5990
|
-
"sha256": "
|
|
6005
|
+
"sha256": "9285f3f2d426305c060eef4b3b98ae64fc386e4ce487f99d9ad59d9921dc493e"
|
|
5991
6006
|
},
|
|
5992
6007
|
{
|
|
5993
6008
|
"path": "modules/provisioning/starter-bundles.js",
|
|
@@ -7247,12 +7262,12 @@
|
|
|
7247
7262
|
{
|
|
7248
7263
|
"path": "package-lock.json",
|
|
7249
7264
|
"mode": "0000644",
|
|
7250
|
-
"sha256": "
|
|
7265
|
+
"sha256": "9c126ed4b632afd9452b01fa9e08eb97295699e99efc9c7d4040a761cac7f58d"
|
|
7251
7266
|
},
|
|
7252
7267
|
{
|
|
7253
7268
|
"path": "package.json",
|
|
7254
7269
|
"mode": "0000644",
|
|
7255
|
-
"sha256": "
|
|
7270
|
+
"sha256": "7cc213de070341042dae24c32b6fc458ae6912399a715d50b18dd92c52548fd8"
|
|
7256
7271
|
},
|
|
7257
7272
|
{
|
|
7258
7273
|
"path": "public-docs/index.html",
|
|
@@ -8922,7 +8937,7 @@
|
|
|
8922
8937
|
{
|
|
8923
8938
|
"path": "src/module-api.js",
|
|
8924
8939
|
"mode": "0000644",
|
|
8925
|
-
"sha256": "
|
|
8940
|
+
"sha256": "ace7f9365df0b8019d1fbc1758832db878c9b00ff59583a5ddcd839bbb69b1eb"
|
|
8926
8941
|
},
|
|
8927
8942
|
{
|
|
8928
8943
|
"path": "src/module-loader/catalog.js",
|
|
@@ -10302,7 +10317,7 @@
|
|
|
10302
10317
|
{
|
|
10303
10318
|
"path": "tests/hall_audit.mjs",
|
|
10304
10319
|
"mode": "0000644",
|
|
10305
|
-
"sha256": "
|
|
10320
|
+
"sha256": "0b30e949b0479adb4b436aa32e741c9f2ab3925a1ac4327daf6e8a95700a8c14"
|
|
10306
10321
|
},
|
|
10307
10322
|
{
|
|
10308
10323
|
"path": "tests/hall_board_world.mjs",
|
|
@@ -10324,6 +10339,11 @@
|
|
|
10324
10339
|
"mode": "0000644",
|
|
10325
10340
|
"sha256": "1d9c1d345a6fe25eacf810703a3e7f9f3b33f8e982aef49364e19eb4469de668"
|
|
10326
10341
|
},
|
|
10342
|
+
{
|
|
10343
|
+
"path": "tests/hall_kit_charts.mjs",
|
|
10344
|
+
"mode": "0000644",
|
|
10345
|
+
"sha256": "475c712af2b45fed7863b486c3d2ed3b96e955dccb9acc5909999db3990843d5"
|
|
10346
|
+
},
|
|
10327
10347
|
{
|
|
10328
10348
|
"path": "tests/hall_nav.mjs",
|
|
10329
10349
|
"mode": "0000644",
|
|
@@ -10352,7 +10372,7 @@
|
|
|
10352
10372
|
{
|
|
10353
10373
|
"path": "tests/hall_profile_world.mjs",
|
|
10354
10374
|
"mode": "0000644",
|
|
10355
|
-
"sha256": "
|
|
10375
|
+
"sha256": "b35d647c4cb7b90be70dee8e7245396cc901479992fafbf19ceef734d8195399"
|
|
10356
10376
|
},
|
|
10357
10377
|
{
|
|
10358
10378
|
"path": "tests/hall_reading_world.mjs",
|
|
@@ -10402,7 +10422,7 @@
|
|
|
10402
10422
|
{
|
|
10403
10423
|
"path": "tests/helpers.mjs",
|
|
10404
10424
|
"mode": "0000644",
|
|
10405
|
-
"sha256": "
|
|
10425
|
+
"sha256": "b3f0a87c51c9e655c712db00a0a8763e2fc08e4de3c6904c6080385e7c7dad14"
|
|
10406
10426
|
},
|
|
10407
10427
|
{
|
|
10408
10428
|
"path": "tests/hierarchy-config.mjs",
|
|
@@ -10632,7 +10652,7 @@
|
|
|
10632
10652
|
{
|
|
10633
10653
|
"path": "tests/joinability_invite_only.mjs",
|
|
10634
10654
|
"mode": "0000644",
|
|
10635
|
-
"sha256": "
|
|
10655
|
+
"sha256": "5311e076e8a72b993a235e57ebc54c9ecd529ccd31b65609432677a12e15e85d"
|
|
10636
10656
|
},
|
|
10637
10657
|
{
|
|
10638
10658
|
"path": "tests/joinability_open.mjs",
|
|
@@ -11122,7 +11142,7 @@
|
|
|
11122
11142
|
{
|
|
11123
11143
|
"path": "tests/projects_hub.mjs",
|
|
11124
11144
|
"mode": "0000644",
|
|
11125
|
-
"sha256": "
|
|
11145
|
+
"sha256": "22461d4febf616202af96aa37fc940a686841bbf68155094526455ae85ab9886"
|
|
11126
11146
|
},
|
|
11127
11147
|
{
|
|
11128
11148
|
"path": "tests/projects_hub_pre_uat.mjs",
|
|
@@ -11174,6 +11194,11 @@
|
|
|
11174
11194
|
"mode": "0000644",
|
|
11175
11195
|
"sha256": "97d04ee39cc06b720d4a5b42f3e3cc614f64d9462b27471a1af7598b5e2929be"
|
|
11176
11196
|
},
|
|
11197
|
+
{
|
|
11198
|
+
"path": "tests/provisioning_recommendations.mjs",
|
|
11199
|
+
"mode": "0000644",
|
|
11200
|
+
"sha256": "0557876002c1f0efde5a8e7c87702fa57df3a9efb26ea93b077969bcc10e3637"
|
|
11201
|
+
},
|
|
11177
11202
|
{
|
|
11178
11203
|
"path": "tests/provisioning_restart.mjs",
|
|
11179
11204
|
"mode": "0000644",
|
|
@@ -11847,7 +11872,7 @@
|
|
|
11847
11872
|
{
|
|
11848
11873
|
"path": "tests/task_detail_ui.mjs",
|
|
11849
11874
|
"mode": "0000644",
|
|
11850
|
-
"sha256": "
|
|
11875
|
+
"sha256": "d7b12d56b50a0412d50f3558065c681d92c0c631edfef5553164e646979e6fa5"
|
|
11851
11876
|
},
|
|
11852
11877
|
{
|
|
11853
11878
|
"path": "tests/task_goal_link.mjs",
|
|
@@ -11999,11 +12024,21 @@
|
|
|
11999
12024
|
"mode": "0000644",
|
|
12000
12025
|
"sha256": "2a381bab380342e4fc556211d4821c85fdde1f676a6c5c6aa2421a89a573cd27"
|
|
12001
12026
|
},
|
|
12027
|
+
{
|
|
12028
|
+
"path": "tests/visible_projects_feed.mjs",
|
|
12029
|
+
"mode": "0000644",
|
|
12030
|
+
"sha256": "4bf47b6aee92c54099c583726d05421a433ac5b5e82792a848d11c80d7ee7bd1"
|
|
12031
|
+
},
|
|
12002
12032
|
{
|
|
12003
12033
|
"path": "tests/wandering_prefs.mjs",
|
|
12004
12034
|
"mode": "0000644",
|
|
12005
12035
|
"sha256": "745a868a2e13f34afd29f96840102205792bac810f2fd911c7da00f6a5695242"
|
|
12006
12036
|
},
|
|
12037
|
+
{
|
|
12038
|
+
"path": "tests/watch_applications_queue.mjs",
|
|
12039
|
+
"mode": "0000644",
|
|
12040
|
+
"sha256": "b1f7df5aa40b89f8737c76d94def15c539514f7f439cca79a034bf37b922158d"
|
|
12041
|
+
},
|
|
12007
12042
|
{
|
|
12008
12043
|
"path": "tests/web_admission_status.mjs",
|
|
12009
12044
|
"mode": "0000644",
|
|
@@ -5,7 +5,7 @@ A **generated**, zero-dependency typed client for the Bongos API — produced fr
|
|
|
5
5
|
by hand; it regenerates when the spec changes, so it can never drift from the routes.
|
|
6
6
|
|
|
7
7
|
- API version: **v1** (served at `/api/bongos/v1`)
|
|
8
|
-
-
|
|
8
|
+
- 347 operations across 53 resource groups
|
|
9
9
|
|
|
10
10
|
## Install
|
|
11
11
|
|
|
@@ -669,6 +669,8 @@ function createClient(opts = {}) {
|
|
|
669
669
|
postProvisioningInstancesIdTeardown: (args) => request("POST", "/provisioning/instances/{id}/teardown", { hasBody: true }, args),
|
|
670
670
|
// GET /provisioning/onboard-plan — rank: public — GET /provisioning/onboard-plan
|
|
671
671
|
getProvisioningOnboardPlan: (args) => request("GET", "/provisioning/onboard-plan", { hasBody: false }, args),
|
|
672
|
+
// GET /provisioning/recommendations — rank: public — GET /provisioning/recommendations
|
|
673
|
+
getProvisioningRecommendations: (args) => request("GET", "/provisioning/recommendations", { hasBody: false }, args),
|
|
672
674
|
// GET /provisioning/slug-available — rank: any-builder — GET /provisioning/slug-available
|
|
673
675
|
getProvisioningSlugAvailable: (args) => request("GET", "/provisioning/slug-available", { hasBody: false }, args),
|
|
674
676
|
// GET /provisioning/starter-bundles — rank: public — GET /provisioning/starter-bundles
|
|
@@ -668,6 +668,8 @@ function createClient(opts = {}) {
|
|
|
668
668
|
postProvisioningInstancesIdTeardown: (args) => request("POST", "/provisioning/instances/{id}/teardown", { hasBody: true }, args),
|
|
669
669
|
// GET /provisioning/onboard-plan — rank: public — GET /provisioning/onboard-plan
|
|
670
670
|
getProvisioningOnboardPlan: (args) => request("GET", "/provisioning/onboard-plan", { hasBody: false }, args),
|
|
671
|
+
// GET /provisioning/recommendations — rank: public — GET /provisioning/recommendations
|
|
672
|
+
getProvisioningRecommendations: (args) => request("GET", "/provisioning/recommendations", { hasBody: false }, args),
|
|
671
673
|
// GET /provisioning/slug-available — rank: any-builder — GET /provisioning/slug-available
|
|
672
674
|
getProvisioningSlugAvailable: (args) => request("GET", "/provisioning/slug-available", { hasBody: false }, args),
|
|
673
675
|
// GET /provisioning/starter-bundles — rank: public — GET /provisioning/starter-bundles
|
|
@@ -97,6 +97,7 @@ export interface GetProvisioningInstancesIdResponse { instance: unknown; open_in
|
|
|
97
97
|
export interface GetProvisioningInstancesIdSettingsResponse { ok: boolean; settings: unknown; planet: unknown; options: unknown }
|
|
98
98
|
export interface GetProvisioningInstancesResponse { instances: unknown }
|
|
99
99
|
export interface GetProvisioningOnboardPlanResponse { mode: unknown; steps: unknown }
|
|
100
|
+
export interface GetProvisioningRecommendationsResponse { recommendations: unknown }
|
|
100
101
|
export interface GetProvisioningSlugAvailableResponse { slug: unknown; available: unknown; reason: unknown; address: unknown }
|
|
101
102
|
export interface GetProvisioningStarterBundlesResponse { core: unknown; bundles: unknown }
|
|
102
103
|
export interface GetPublicBlockersIdResponse { blocker: unknown }
|
|
@@ -980,6 +981,8 @@ export interface BongosClient {
|
|
|
980
981
|
postProvisioningInstancesIdTeardown(args?: RequestArgs): Promise<PostProvisioningInstancesIdTeardownResponse>;
|
|
981
982
|
/** GET /provisioning/onboard-plan — rank: public */
|
|
982
983
|
getProvisioningOnboardPlan(args?: RequestArgs): Promise<GetProvisioningOnboardPlanResponse>;
|
|
984
|
+
/** GET /provisioning/recommendations — rank: public */
|
|
985
|
+
getProvisioningRecommendations(args?: RequestArgs): Promise<GetProvisioningRecommendationsResponse>;
|
|
983
986
|
/** GET /provisioning/slug-available — rank: any-builder */
|
|
984
987
|
getProvisioningSlugAvailable(args?: RequestArgs): Promise<GetProvisioningSlugAvailableResponse>;
|
|
985
988
|
/** GET /provisioning/starter-bundles — rank: public */
|
|
@@ -665,6 +665,8 @@ export function createClient(opts = {}) {
|
|
|
665
665
|
postProvisioningInstancesIdTeardown: (args) => request("POST", "/provisioning/instances/{id}/teardown", { hasBody: true }, args),
|
|
666
666
|
// GET /provisioning/onboard-plan — rank: public — GET /provisioning/onboard-plan
|
|
667
667
|
getProvisioningOnboardPlan: (args) => request("GET", "/provisioning/onboard-plan", { hasBody: false }, args),
|
|
668
|
+
// GET /provisioning/recommendations — rank: public — GET /provisioning/recommendations
|
|
669
|
+
getProvisioningRecommendations: (args) => request("GET", "/provisioning/recommendations", { hasBody: false }, args),
|
|
668
670
|
// GET /provisioning/slug-available — rank: any-builder — GET /provisioning/slug-available
|
|
669
671
|
getProvisioningSlugAvailable: (args) => request("GET", "/provisioning/slug-available", { hasBody: false }, args),
|
|
670
672
|
// GET /provisioning/starter-bundles — rank: public — GET /provisioning/starter-bundles
|
|
@@ -161,6 +161,8 @@ Until then: `stealth` unqualified in product code and copy means the project sta
|
|
|
161
161
|
- Anything reading `featured = true AND status = 'active'` as "is this public" is now wrong and must be found. `modules/platform-identity/routes/projects.js` is the known site.
|
|
162
162
|
- **R16 makes D3's bound real, and D4's gate reach a second module.** Shipping R16 (task 1002335) surfaced one thing this ADR left implicit. D3 says `featured` may never put an unpublishable project on the map, so `PATCH /projects/:id/featured` now refuses a dark-matter row (409 `not_publishable`, `missing` in the details); un-featuring stays unconditional, since an already-featured husk must remain removable. And D4's "name what is missing" is owed to the owner *before* their project is ever catalogued on the hub — which is the `provisioning` plane, a different module that ADR 0083 forbids from importing `platform-identity`. Rather than let a two-field rule exist twice, the gate is published as a kernel seam port, `project.publishGate` (`modules/platform-identity/publish-gate.js`). `provisioning` resolves it **optionally** and declares no `consumes`: `platform-identity` is hub-only, the public map is a hub concept, and a platform without one must answer "no verdict" rather than invent a local rule — which is the same drift-avoidance argument that produced `publishableSql` in the first place.
|
|
163
163
|
|
|
164
|
+
- **R06 landed the predicate swap and the redaction, and settled three things this ADR left to the implementer** (task 1002325, `modules/platform-identity/projects-feed.js`). (a) **A black hole carries no stable per-project key.** D2a lists `name`/`tagline`/`art_url`/`origin`, and an id looks harmless beside them — but any identifier that survives a state change lets an observer who kept yesterday's public feed diff it against today's and *name* the project that went stealth. So stealth rows are byte-identical to one another and the feed grew no public id at all; the orbs page keys by position. (b) **The redaction is an ALLOW-list, not a deny-list** — every key nulled except `state` and `orb` — so a column added to the feed later is anonymous without anyone remembering to come back to it, and it NULLS rather than deletes, keeping the feed's "never drop a key" contract. (c) **An unrecognised `visibility` draws as a black hole, not a planet**: this mapping is a privacy boundary, so a fourth enum value added without mapping it must fail closed. Two smaller notes: the route PATH keeps the word `featured` (it is rank:public and CORS-open, already fetched by a static site and other origins — renaming it would break them for nothing, and `ORDER BY featured DESC` is where the flag's D3 ranking job now lives); and `getRollupForBuilder`'s `is_public` was deliberately left on the OLD `featured AND active` predicate rather than widened with the feed, because a stealth project is on the map *anonymously* and naming it in a builder's profile would be the exact leak D2a forbids — how much of a cross-project record may be NAMED is ADR 0171 D2's question, and under-naming is the safe direction meanwhile.
|
|
165
|
+
|
|
164
166
|
## Alternatives rejected
|
|
165
167
|
|
|
166
168
|
- **A stored four-valued enum including `unlisted`.** Rejected: it makes "unlisted" a choice competing with `private`, and it lets a project be simultaneously "publishable" and "unlisted" — two sources of truth for one question, which is the bug the derived gate prevents by construction.
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# 0239 — A recommendation is a table that carries its own reason; governance is a preview and invites are a seam
|
|
2
|
+
|
|
3
|
+
- **Status:** Accepted
|
|
4
|
+
- **Date:** 2026-09-03
|
|
5
|
+
- **Tasks:** [#1002336](https://cloudbongos.com/builders#/task/1002336) (this decision — BV1.R17)
|
|
6
|
+
- **Goal:** [#1000046](https://cloudbongos.com/builders#/goal/1000046) — Project creation: visibility and
|
|
7
|
+
customization; criteria `proj-module-select` ("additional modules are recommended (rule-based) from the
|
|
8
|
+
project's details"), `proj-governance-reco` ("a recommended governance setup … derived from its details"),
|
|
9
|
+
`proj-invite-builders` ("the owner can optionally invite guilds or top builders")
|
|
10
|
+
- **Related:** [ADR 0237](<redacted>.md)
|
|
11
|
+
(R19, the per-type preset this adjusts), [ADR 0182](<redacted>.md) D4 (skipping the
|
|
12
|
+
interview is a supported answer), [ADR 0083](<redacted>.md) (the
|
|
13
|
+
one-way import rule that makes the invite lookup a seam),
|
|
14
|
+
task [#1002334](https://cloudbongos.com/builders#/task/1002334) (R15, the interview whose answer this reads),
|
|
15
|
+
task [#1002772](https://cloudbongos.com/builders#/task/1002772) (the declared project type),
|
|
16
|
+
task [#1003500](https://cloudbongos.com/builders#/task/1003500) / idea 1000552 (the deferred AI layer)
|
|
17
|
+
|
|
18
|
+
## 1. The problem
|
|
19
|
+
|
|
20
|
+
Three of goal 1000046's criteria ask the same question in three places: after an
|
|
21
|
+
owner answers the optional project-detail interview, what do we *recommend* — which
|
|
22
|
+
modules, which governance setup, which builders to invite. The goal's own text pins
|
|
23
|
+
the near term: "near-term recommendations are rule-based and module search is
|
|
24
|
+
lexical; the AI/embeddings layer … is a deferred follow-up captured in the idea
|
|
25
|
+
inbox."
|
|
26
|
+
|
|
27
|
+
R19 ([ADR 0237](<redacted>.md))
|
|
28
|
+
already answered the type half — a starter bundle per declared project type — and
|
|
29
|
+
said explicitly that it is "a declaration and not a rule engine … R17/R22 own the
|
|
30
|
+
layer that reasons." This is that layer.
|
|
31
|
+
|
|
32
|
+
## 2. Two inputs, and the description is not one of them
|
|
33
|
+
|
|
34
|
+
The engine reads exactly two things, and they arrive separately because they are
|
|
35
|
+
stored separately: `type` is a column (the closed set task 1002772 fixed —
|
|
36
|
+
`game · research · business · non-profit · not-sure`) and `team_shape` is the one
|
|
37
|
+
closed-answer key the R15 interview collects (`PROJECT_DETAIL_VOCAB.team_shape ∈
|
|
38
|
+
solo | small-team | community`). The interview deliberately does not re-ask the type
|
|
39
|
+
(ADR 0237 §2), so `recommendationsForDetails({ type, team_shape })` is the file that
|
|
40
|
+
puts the two back together, and a caller holding a row passes
|
|
41
|
+
`{ type: row.type, ...projectDetail(row) }`.
|
|
42
|
+
|
|
43
|
+
The interview's *third* answer — the free-text `description` — is deliberately
|
|
44
|
+
**not** read. Inferring a bundle from prose is the deferred semantic layer
|
|
45
|
+
([#1003500](https://cloudbongos.com/builders#/task/1003500), idea 1000552), and ADR
|
|
46
|
+
0237 §7 already rejected it once for the same reason.
|
|
47
|
+
|
|
48
|
+
## 3. A table, and every row carries the sentence that explains it
|
|
49
|
+
|
|
50
|
+
The engine is three frozen tables and a resolver over them — not a scorer, not a
|
|
51
|
+
weighting, not a model:
|
|
52
|
+
|
|
53
|
+
| table | keyed on | effect |
|
|
54
|
+
|---|---|---|
|
|
55
|
+
| `TEAM_SHAPE_RULES` | `team_shape` | add/remove ONE opt-in module from the type's bundle |
|
|
56
|
+
| `GOVERNANCE_RULES` | `team_shape` | a named preset out of `GOVERNANCE_PRESETS` |
|
|
57
|
+
| `INVITE_RULES` | `team_shape` | a `seeking` descriptor, or `null` for "suggest nobody" |
|
|
58
|
+
|
|
59
|
+
Every row carries a `reason` — one sentence in the owner's own words, shipped
|
|
60
|
+
alongside the effect rather than reconstructed by whichever surface renders it. That
|
|
61
|
+
is the constraint that makes the whole thing auditable: a recommendation an owner
|
|
62
|
+
cannot be told the reason for is one they cannot disagree with, and a reason written
|
|
63
|
+
separately from the rule drifts from it the first time either changes.
|
|
64
|
+
|
|
65
|
+
The three bundle rules today: `community` **adds** `discord` (somewhere for it to
|
|
66
|
+
gather); `small-team` **adds** `dev-box` (one shared environment); `solo` **removes**
|
|
67
|
+
`dev-box` (your own machine is the setup). They are few for the reason ADR 0237 §4
|
|
68
|
+
gave — today's opt-in catalog is three modules wide, and a preselect an owner must
|
|
69
|
+
audit is worse than none. The rules' job is to correct a preset the owner's answer
|
|
70
|
+
contradicts, not to re-derive it.
|
|
71
|
+
|
|
72
|
+
## 4. `adjustments` is a delta — a rule that changes nothing claims nothing
|
|
73
|
+
|
|
74
|
+
`bundle.adjustments` lists only the rules that ACTUALLY moved the module list. The
|
|
75
|
+
game bundle already carries `discord`, so a `community` answer records no adjustment
|
|
76
|
+
even though its condition matched; the non-profit bundle has no `dev-box`, so a
|
|
77
|
+
`solo` answer removes nothing and says nothing.
|
|
78
|
+
|
|
79
|
+
The alternative — record the reason whenever the condition matches — was rejected
|
|
80
|
+
because it conflates two different sentences: "discord is on because your project is
|
|
81
|
+
a game" (the bundle, R19's opinion) and "we switched discord on because you said
|
|
82
|
+
community" (the rule). A picker rendering the second over a module the owner would
|
|
83
|
+
have had anyway is telling them something they can check and find false.
|
|
84
|
+
|
|
85
|
+
## 5. Governance is a named preview, never an applied setting
|
|
86
|
+
|
|
87
|
+
Criterion `proj-governance-reco` says it out loud: the recommendation "depends on the
|
|
88
|
+
governance module (goal 1000030), which is planned but not yet built." So a preset
|
|
89
|
+
here is a **name plus one sentence of what living under it feels like** — `owner-only`
|
|
90
|
+
/ `trusted-team` / `open-contribution` — and never a set of roles or permissions,
|
|
91
|
+
because there is nowhere to put them.
|
|
92
|
+
|
|
93
|
+
Every recommendation carries `governance.applied: false`. A constant field looks
|
|
94
|
+
redundant until you count the surfaces that otherwise hardcode the same fact: R25's
|
|
95
|
+
preview step ([#1002344](https://cloudbongos.com/builders#/task/1002344)), R18's proof
|
|
96
|
+
([#1002337](https://cloudbongos.com/builders#/task/1002337)), the wizard and the
|
|
97
|
+
project page. One flag flips when goal 1000030 lands; a test pins it false until then.
|
|
98
|
+
|
|
99
|
+
## 6. Invites are a seam, because the leaderboard is a sibling module
|
|
100
|
+
|
|
101
|
+
`invites.suggested` is **always empty**, and that is a decision rather than an
|
|
102
|
+
unfinished edge. Ranking builders means querying the leaderboard, which lives in
|
|
103
|
+
`economy` — a sibling module `provisioning` may not import (the one-way rule, ADR
|
|
104
|
+
0083). Making the route do it instead would cost the engine's purity, put a database
|
|
105
|
+
read behind a public endpoint, and duplicate work
|
|
106
|
+
[#1002347](https://cloudbongos.com/builders#/task/1002347) (R28) already owns and
|
|
107
|
+
whose dependency is R27, not R17.
|
|
108
|
+
|
|
109
|
+
So the engine emits what to look for — `invites.seeking = { kind: 'top-builders',
|
|
110
|
+
limit }`, or `null` for "suggest nobody" — and R28 turns it into names. `null` is a
|
|
111
|
+
real answer here: a solo builder is suggested nobody on purpose, which is a different
|
|
112
|
+
statement from an empty list nobody has filled yet.
|
|
113
|
+
|
|
114
|
+
## 7. Skipping is an answer, and every default is the narrowest one
|
|
115
|
+
|
|
116
|
+
The interview is optional (ADR 0182 D4), so every table has a stated default for
|
|
117
|
+
"nobody said" and each is deliberately the narrowest option: the type's own bundle
|
|
118
|
+
unadjusted, `owner-only` governance, and no invites. Widening later costs one
|
|
119
|
+
setting; a project that quietly granted strangers a role it was never asked to grant
|
|
120
|
+
is not recovered by setting it back.
|
|
121
|
+
|
|
122
|
+
An **off-vocabulary** `team_shape` — absent, misspelled, or a value that has since
|
|
123
|
+
left the vocabulary — reads as *no answer*, exactly as `normalizeProjectDetail` drops
|
|
124
|
+
it on the way in. The route follows the same rule: a missing or unusable query value
|
|
125
|
+
returns 200 with the defaults, never a 400, because refusing the request would make
|
|
126
|
+
the supported path an error.
|
|
127
|
+
|
|
128
|
+
`tailored: boolean` is the machine-readable half of criterion
|
|
129
|
+
`proj-detail-interview`'s split ("completing it produces tailored recommendations;
|
|
130
|
+
skipping produces sensible defaults") — false exactly when no detail answer shaped
|
|
131
|
+
anything. R18 is the live proof of that line.
|
|
132
|
+
|
|
133
|
+
## 8. The read surface
|
|
134
|
+
|
|
135
|
+
`GET /provisioning/recommendations?type=&team_shape=` returns
|
|
136
|
+
`{ recommendations: { type, teamShape, tailored, bundle, governance, invites } }`.
|
|
137
|
+
`bundle` is ADR 0237 §5's shape with `adjustments` added, so R20's picker
|
|
138
|
+
([#1002339](https://cloudbongos.com/builders#/task/1002339)) and this engine resolve
|
|
139
|
+
through the same `bundleForProjectType` and can never name different modules — a test
|
|
140
|
+
asserts that against the live `starter-bundles` route.
|
|
141
|
+
|
|
142
|
+
`rank: public`, the same absent gate as `starter-bundles` and `onboard-plan`: the
|
|
143
|
+
signed-out wizard asks while the owner is still answering, *before* any row exists to
|
|
144
|
+
be own-scoped against, and the answer is a declaration that names nothing private.
|
|
145
|
+
The route touches no database, and the test proves it by stubbing `pool` to throw.
|
|
146
|
+
|
|
147
|
+
## 9. Consequences
|
|
148
|
+
|
|
149
|
+
- **The UI is not wired here.** R20 renders the picker, R22
|
|
150
|
+
([#1002341](https://cloudbongos.com/builders#/task/1002341)) surfaces these
|
|
151
|
+
recommendations inside it, and R18 proves the details→recs / skip→defaults split.
|
|
152
|
+
The creation wizard currently hardcodes a `TEAM_META` copy table in
|
|
153
|
+
`modules/public-landing/public/projects.html` that says roughly what
|
|
154
|
+
`governance.preview` now says — R22 should collapse that duplicate into this route
|
|
155
|
+
rather than leave one sentence written twice.
|
|
156
|
+
- **Adding a fourth team-shape answer is a two-file change.** The interview vocabulary
|
|
157
|
+
and this file, and `tests/provisioning_recommendations.mjs` fails the build if a
|
|
158
|
+
vocabulary value has no governance rule and no invite rule.
|
|
159
|
+
- **A recommendation is still never a publish precondition** (ADR 0182 D4 — the bar is
|
|
160
|
+
name + description alone), and taking or declining one cannot move a project's
|
|
161
|
+
dark-matter state.
|
|
162
|
+
|
|
163
|
+
## 10. Rejected
|
|
164
|
+
|
|
165
|
+
- **Reading the free-text description** — that is the deferred AI/semantic layer
|
|
166
|
+
([#1003500](https://cloudbongos.com/builders#/task/1003500)), and the goal pins the
|
|
167
|
+
near term as rule-based.
|
|
168
|
+
- **Filling `invites.suggested` from `GET /public/leaderboard`** — the route exists and
|
|
169
|
+
is public, but reaching it means importing a sibling module, and R28 owns that work
|
|
170
|
+
behind a different dependency.
|
|
171
|
+
- **A scoring function over weighted signals** — with two inputs and three opt-in
|
|
172
|
+
modules there is nothing to weigh, and a score cannot be shown to an owner as a
|
|
173
|
+
sentence they can disagree with.
|
|
174
|
+
- **Recording a reason for every matched condition** — see §4; it makes a claim the
|
|
175
|
+
owner can check and find false.
|
|
176
|
+
- **Refusing an unknown `team_shape` with a 400** — skipping is the supported path, so
|
|
177
|
+
the shape of a skipped answer must not be an error.
|