@bongos/core 1.19.1016 → 1.19.1018
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 +98 -48
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +4 -0
- package/clients/bongos-client/index.cjs +4 -0
- package/clients/bongos-client/index.d.ts +6 -1
- package/clients/bongos-client/index.mjs +4 -0
- package/docs/adr/0208-application-lifecycle-the-handle-waits-and-the-vouch-has-no-minter.md +1 -0
- package/docs/adr/0333-the-application-vouch-is-a-third-token-spent-once-and-bound-to-its-login.md +86 -0
- package/docs/adr/0334-the-recruiting-directory-lists-a-hidden-builder-by-name.md +47 -0
- package/docs/adr/README.md +2 -0
- package/docs/api/openapi.json +56 -5
- package/docs/api-reference.md +7 -1
- package/docs/copy-inventory.md +5 -3
- package/docs/copy-registry.json +22 -4
- package/docs/file-map.md +1 -1
- package/docs/module-api-changelog.md +9 -0
- package/migrations/core_254_access_requests_applicant_handle.sql +23 -0
- package/modules/hall-ui/public/people.html +11 -0
- package/modules/hall-ui/public/people.js +77 -11
- package/modules/hall-ui/public/people.states.json +1 -1
- package/modules/onboarding/routes/access-requests.js +31 -4
- package/modules/platform-identity/account-visibility.js +33 -2
- package/modules/platform-identity/builder-search.js +153 -0
- package/modules/platform-identity/hub-keys.js +51 -32
- package/modules/platform-identity/migrations/platform_identity_023_builder_search_trgm.sql +40 -0
- package/modules/platform-identity/module.json +1 -1
- package/modules/platform-identity/routes/community-search.js +120 -0
- package/modules/platform-identity/routes/my-projects.js +33 -1
- package/modules/platform-identity/routes/scouting.js +14 -7
- package/modules/platform-identity/scouting-name-only.js +47 -0
- package/modules/public-landing/public/projects-floor.states.json +9 -2
- package/modules/public-landing/public/projects.html +69 -4
- package/modules/ui-design/styles/expedition/mock.html +16 -3
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/src/bongos/auth-idp.js +93 -48
- package/src/bongos/auth.js +2 -1
- package/src/module-api.js +7 -1
- package/tests/account_privacy_flags.mjs +4 -1
- package/tests/application_echo.mjs +100 -1
- package/tests/application_lifecycle.mjs +145 -6
- package/tests/card_apply_ui.mjs +297 -0
- package/tests/community_search_route.mjs +385 -0
- package/tests/effective_visibility_predicate.mjs +49 -1
- package/tests/idp_device_exchange.mjs +174 -0
- package/tests/module_api.mjs +1 -0
- package/tests/people_name_only.mjs +262 -0
- package/tests/profile_route.mjs +23 -5
- package/tests/recruiter_sliver_boundary.mjs +3 -0
- package/tests/scouting_owner_access_and_reach.mjs +112 -2
- package/tests/ui_design_styles.mjs +13 -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.1018",
|
|
6
|
+
"core_contract": "1.19.1018",
|
|
7
|
+
"source_commit": "49eb795ed8e84657315241e6cfa652f3491e6edc",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-09-25T01:
|
|
9
|
+
"built_at": "2026-09-25T01:46:13.363Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
|
-
"docs_redacted":
|
|
12
|
+
"docs_redacted": 527,
|
|
13
13
|
"agent_docs_stubbed": 26,
|
|
14
|
-
"functional_verbatim":
|
|
14
|
+
"functional_verbatim": 2440,
|
|
15
15
|
"rules": 3,
|
|
16
16
|
"gate_literals": 3,
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
|
-
"file_count":
|
|
20
|
-
"tree_sha256": "
|
|
19
|
+
"file_count": 2993,
|
|
20
|
+
"tree_sha256": "ed9091f7fa992b1a3cb4b1d473869986f200827a94ca69cc0a8c86770b571b71",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/ask-for-help/SKILL.md",
|
|
@@ -352,12 +352,12 @@
|
|
|
352
352
|
{
|
|
353
353
|
"path": "clients/bongos-client/README.md",
|
|
354
354
|
"mode": "0000644",
|
|
355
|
-
"sha256": "
|
|
355
|
+
"sha256": "1d0f3cc30c66a4eb757e297d95406a42c55cedc073ee29671827926f06c0d260"
|
|
356
356
|
},
|
|
357
357
|
{
|
|
358
358
|
"path": "clients/bongos-client/bongos-client.global.js",
|
|
359
359
|
"mode": "0000644",
|
|
360
|
-
"sha256": "
|
|
360
|
+
"sha256": "c913bb0302165f718776d8f5f6f5d3bdde73ee152a9eabbe3fc4f92d23e6b0e3"
|
|
361
361
|
},
|
|
362
362
|
{
|
|
363
363
|
"path": "clients/bongos-client/examples/hello-world.mjs",
|
|
@@ -367,17 +367,17 @@
|
|
|
367
367
|
{
|
|
368
368
|
"path": "clients/bongos-client/index.cjs",
|
|
369
369
|
"mode": "0000644",
|
|
370
|
-
"sha256": "
|
|
370
|
+
"sha256": "48051577351ecb7f13d874668d2ed3171b1cad370969ba5e8b4124b20584c839"
|
|
371
371
|
},
|
|
372
372
|
{
|
|
373
373
|
"path": "clients/bongos-client/index.d.ts",
|
|
374
374
|
"mode": "0000644",
|
|
375
|
-
"sha256": "
|
|
375
|
+
"sha256": "ffbc111669a6fb27297d1819c35d02f732c3d69b87411613a88b348b0fa897c6"
|
|
376
376
|
},
|
|
377
377
|
{
|
|
378
378
|
"path": "clients/bongos-client/index.mjs",
|
|
379
379
|
"mode": "0000644",
|
|
380
|
-
"sha256": "
|
|
380
|
+
"sha256": "81da43a07fc9e2c89899334f58440d07c8f36df0efc5a1f3a9512a20f2a90047"
|
|
381
381
|
},
|
|
382
382
|
{
|
|
383
383
|
"path": "clients/bongos-client/package.json",
|
|
@@ -1542,7 +1542,7 @@
|
|
|
1542
1542
|
{
|
|
1543
1543
|
"path": "docs/adr/0208-application-lifecycle-the-handle-waits-and-the-vouch-has-no-minter.md",
|
|
1544
1544
|
"mode": "0000644",
|
|
1545
|
-
"sha256": "
|
|
1545
|
+
"sha256": "84f46e47b23542bf6d4fb78c7e1914f1ebbbf9548e40159814c41bb4003f827e"
|
|
1546
1546
|
},
|
|
1547
1547
|
{
|
|
1548
1548
|
"path": "docs/adr/0209-one-budget-for-the-account-existence-oracle.md",
|
|
@@ -2154,6 +2154,16 @@
|
|
|
2154
2154
|
"mode": "0000644",
|
|
2155
2155
|
"sha256": "659b73c16da06bb150434de1eae1bcc1dfe4f6acf61ac0b2d787f3b52f617187"
|
|
2156
2156
|
},
|
|
2157
|
+
{
|
|
2158
|
+
"path": "docs/adr/0333-the-application-vouch-is-a-third-token-spent-once-and-bound-to-its-login.md",
|
|
2159
|
+
"mode": "0000644",
|
|
2160
|
+
"sha256": "b89c4d4bd55e2fe48686cdeabe5bd7eb08c41d195e4d06ea422096d1b7466e0b"
|
|
2161
|
+
},
|
|
2162
|
+
{
|
|
2163
|
+
"path": "docs/adr/0334-the-recruiting-directory-lists-a-hidden-builder-by-name.md",
|
|
2164
|
+
"mode": "0000644",
|
|
2165
|
+
"sha256": "60b5794466cfbdd544c19119d6e6e18ae264782b90b0d3a1d96d4a178619e62c"
|
|
2166
|
+
},
|
|
2157
2167
|
{
|
|
2158
2168
|
"path": "docs/adr/0335-an-invite-is-a-pre-approved-row-on-the-projects-own-instance.md",
|
|
2159
2169
|
"mode": "0000644",
|
|
@@ -2167,17 +2177,17 @@
|
|
|
2167
2177
|
{
|
|
2168
2178
|
"path": "docs/adr/README.md",
|
|
2169
2179
|
"mode": "0000644",
|
|
2170
|
-
"sha256": "
|
|
2180
|
+
"sha256": "8227e2293df9bc8364bc66ecd8890341e7a1410b9edc7906c38abae37ce7eccd"
|
|
2171
2181
|
},
|
|
2172
2182
|
{
|
|
2173
2183
|
"path": "docs/api-reference.md",
|
|
2174
2184
|
"mode": "0000644",
|
|
2175
|
-
"sha256": "
|
|
2185
|
+
"sha256": "89d96b4b83075fea2954bbbfda5d815a74f12a06f46cb11da3d83c3d7951d65b"
|
|
2176
2186
|
},
|
|
2177
2187
|
{
|
|
2178
2188
|
"path": "docs/api/openapi.json",
|
|
2179
2189
|
"mode": "0000644",
|
|
2180
|
-
"sha256": "
|
|
2190
|
+
"sha256": "0e679eec9a95a36a04a91c2d37a34dcba1dec397b0eff30eff6b0b1c5e267627"
|
|
2181
2191
|
},
|
|
2182
2192
|
{
|
|
2183
2193
|
"path": "docs/architecture.md",
|
|
@@ -2202,12 +2212,12 @@
|
|
|
2202
2212
|
{
|
|
2203
2213
|
"path": "docs/copy-inventory.md",
|
|
2204
2214
|
"mode": "0000644",
|
|
2205
|
-
"sha256": "
|
|
2215
|
+
"sha256": "7824524ca9e6c4eed55c42542e5bca4904650f4476218a22012bf8e13d1e9ac3"
|
|
2206
2216
|
},
|
|
2207
2217
|
{
|
|
2208
2218
|
"path": "docs/copy-registry.json",
|
|
2209
2219
|
"mode": "0000644",
|
|
2210
|
-
"sha256": "
|
|
2220
|
+
"sha256": "72b54a0726ff452ddc7c1e6938b6274c1251e2a471592d8083e2530aeef10778"
|
|
2211
2221
|
},
|
|
2212
2222
|
{
|
|
2213
2223
|
"path": "docs/design/apex-pass-2-direction.md",
|
|
@@ -2727,7 +2737,7 @@
|
|
|
2727
2737
|
{
|
|
2728
2738
|
"path": "docs/file-map.md",
|
|
2729
2739
|
"mode": "0000644",
|
|
2730
|
-
"sha256": "
|
|
2740
|
+
"sha256": "569c8541506b9f7669dfda06ab3768be173e7d2091d8ff591c07fa67c0fda0eb"
|
|
2731
2741
|
},
|
|
2732
2742
|
{
|
|
2733
2743
|
"path": "docs/handoff-template.md",
|
|
@@ -2737,7 +2747,7 @@
|
|
|
2737
2747
|
{
|
|
2738
2748
|
"path": "docs/module-api-changelog.md",
|
|
2739
2749
|
"mode": "0000644",
|
|
2740
|
-
"sha256": "
|
|
2750
|
+
"sha256": "a0b015494e2c8eaf772b17de3bd6c38737a4ad939921a395021172271b445e3f"
|
|
2741
2751
|
},
|
|
2742
2752
|
{
|
|
2743
2753
|
"path": "docs/modules-contract.md",
|
|
@@ -3859,6 +3869,11 @@
|
|
|
3859
3869
|
"mode": "0000644",
|
|
3860
3870
|
"sha256": "968b1f4b893c9368da682fae0845b69ec367aa465ae608f60644c266818b874e"
|
|
3861
3871
|
},
|
|
3872
|
+
{
|
|
3873
|
+
"path": "migrations/core_254_access_requests_applicant_handle.sql",
|
|
3874
|
+
"mode": "0000644",
|
|
3875
|
+
"sha256": "040de8cddf1a8740ac7e97fb35572e56494a5a3b51ce8873887f71759f6a3b9d"
|
|
3876
|
+
},
|
|
3862
3877
|
{
|
|
3863
3878
|
"path": "modules/agents/CLAUDE.md",
|
|
3864
3879
|
"mode": "0000644",
|
|
@@ -5182,17 +5197,17 @@
|
|
|
5182
5197
|
{
|
|
5183
5198
|
"path": "modules/hall-ui/public/people.html",
|
|
5184
5199
|
"mode": "0000644",
|
|
5185
|
-
"sha256": "
|
|
5200
|
+
"sha256": "4da8ca7dc9321f3d7303332e78ec9caeb6ea65a71fa670b20f593874514585ac"
|
|
5186
5201
|
},
|
|
5187
5202
|
{
|
|
5188
5203
|
"path": "modules/hall-ui/public/people.js",
|
|
5189
5204
|
"mode": "0000644",
|
|
5190
|
-
"sha256": "
|
|
5205
|
+
"sha256": "4f5ececf426b07f6df121c857f15c436e1ae4c1269c7352104f258a21589eca1"
|
|
5191
5206
|
},
|
|
5192
5207
|
{
|
|
5193
5208
|
"path": "modules/hall-ui/public/people.states.json",
|
|
5194
5209
|
"mode": "0000644",
|
|
5195
|
-
"sha256": "
|
|
5210
|
+
"sha256": "5db6df77fb3ea39e03de3489178ab2bf3e978fdd7f67b795ce0da207c71e3eb9"
|
|
5196
5211
|
},
|
|
5197
5212
|
{
|
|
5198
5213
|
"path": "modules/hall-ui/public/primer.css",
|
|
@@ -6402,7 +6417,7 @@
|
|
|
6402
6417
|
{
|
|
6403
6418
|
"path": "modules/onboarding/routes/access-requests.js",
|
|
6404
6419
|
"mode": "0000644",
|
|
6405
|
-
"sha256": "
|
|
6420
|
+
"sha256": "301c45e4f72024c7b1507245a9fccf4388224bb544ad747712c69155d41d1861"
|
|
6406
6421
|
},
|
|
6407
6422
|
{
|
|
6408
6423
|
"path": "modules/onboarding/routes/onboarding.js",
|
|
@@ -6417,7 +6432,7 @@
|
|
|
6417
6432
|
{
|
|
6418
6433
|
"path": "modules/platform-identity/account-visibility.js",
|
|
6419
6434
|
"mode": "0000644",
|
|
6420
|
-
"sha256": "
|
|
6435
|
+
"sha256": "59275121f2a8c6a044659ca94c7f7671f65be27bfc4a6759ec94afc962fc01cd"
|
|
6421
6436
|
},
|
|
6422
6437
|
{
|
|
6423
6438
|
"path": "modules/platform-identity/activity-snapshots.js",
|
|
@@ -6434,6 +6449,11 @@
|
|
|
6434
6449
|
"mode": "0000644",
|
|
6435
6450
|
"sha256": "8217660dc23b57ba0fb54d6375aca9aec190c7abb1d70f9d44d4e290da272c64"
|
|
6436
6451
|
},
|
|
6452
|
+
{
|
|
6453
|
+
"path": "modules/platform-identity/builder-search.js",
|
|
6454
|
+
"mode": "0000644",
|
|
6455
|
+
"sha256": "69e85980a3cb693fa3d39f05b6fadee34799e27c66a2e63fe86ca461f2cfa394"
|
|
6456
|
+
},
|
|
6437
6457
|
{
|
|
6438
6458
|
"path": "modules/platform-identity/canonical-profile.js",
|
|
6439
6459
|
"mode": "0000644",
|
|
@@ -6452,7 +6472,7 @@
|
|
|
6452
6472
|
{
|
|
6453
6473
|
"path": "modules/platform-identity/hub-keys.js",
|
|
6454
6474
|
"mode": "0000644",
|
|
6455
|
-
"sha256": "
|
|
6475
|
+
"sha256": "a8dcce2d4be3d041c349c59cfc0eab2171a08869225f3ccfdb525c70faffb8eb"
|
|
6456
6476
|
},
|
|
6457
6477
|
{
|
|
6458
6478
|
"path": "modules/platform-identity/invite-authz.js",
|
|
@@ -6574,10 +6594,15 @@
|
|
|
6574
6594
|
"mode": "0000644",
|
|
6575
6595
|
"sha256": "b9b4ca90e638af35682b04d311b2ed42f4630a41e003ee329648374fe74fef09"
|
|
6576
6596
|
},
|
|
6597
|
+
{
|
|
6598
|
+
"path": "modules/platform-identity/migrations/platform_identity_023_builder_search_trgm.sql",
|
|
6599
|
+
"mode": "0000644",
|
|
6600
|
+
"sha256": "f119d0d4f8775e2ec1e0e30702ba9564d7f4f712853751e2e66bb3c103cf1da4"
|
|
6601
|
+
},
|
|
6577
6602
|
{
|
|
6578
6603
|
"path": "modules/platform-identity/module.json",
|
|
6579
6604
|
"mode": "0000644",
|
|
6580
|
-
"sha256": "
|
|
6605
|
+
"sha256": "a0f4d7143929eee513926111a314c5687005c95ebff998d0d59dd498bb5c62f2"
|
|
6581
6606
|
},
|
|
6582
6607
|
{
|
|
6583
6608
|
"path": "modules/platform-identity/origin-containment.js",
|
|
@@ -6624,6 +6649,11 @@
|
|
|
6624
6649
|
"mode": "0000644",
|
|
6625
6650
|
"sha256": "4f6854050e3c7459f698c550577fa97958a573d7f1981c9de4d29417af2669c0"
|
|
6626
6651
|
},
|
|
6652
|
+
{
|
|
6653
|
+
"path": "modules/platform-identity/routes/community-search.js",
|
|
6654
|
+
"mode": "0000644",
|
|
6655
|
+
"sha256": "f2f8f4f7a94b7f3a917b583a71fcaf482d110ed06e22a1c1aaad6d9a71a34cad"
|
|
6656
|
+
},
|
|
6627
6657
|
{
|
|
6628
6658
|
"path": "modules/platform-identity/routes/connections.js",
|
|
6629
6659
|
"mode": "0000644",
|
|
@@ -6632,7 +6662,7 @@
|
|
|
6632
6662
|
{
|
|
6633
6663
|
"path": "modules/platform-identity/routes/my-projects.js",
|
|
6634
6664
|
"mode": "0000644",
|
|
6635
|
-
"sha256": "
|
|
6665
|
+
"sha256": "56700357273c03d412afce1ef9937ba811257d0c5110f08d757bbef3e517a416"
|
|
6636
6666
|
},
|
|
6637
6667
|
{
|
|
6638
6668
|
"path": "modules/platform-identity/routes/profile.js",
|
|
@@ -6652,7 +6682,7 @@
|
|
|
6652
6682
|
{
|
|
6653
6683
|
"path": "modules/platform-identity/routes/scouting.js",
|
|
6654
6684
|
"mode": "0000644",
|
|
6655
|
-
"sha256": "
|
|
6685
|
+
"sha256": "fbd1f8679be51718131d3d95d6ed7d8dcd1ebe091df6cfc190b69fd62c00013c"
|
|
6656
6686
|
},
|
|
6657
6687
|
{
|
|
6658
6688
|
"path": "modules/platform-identity/routes/sso.js",
|
|
@@ -6664,6 +6694,11 @@
|
|
|
6664
6694
|
"mode": "0000644",
|
|
6665
6695
|
"sha256": "b4da61899339ac5e9fac517efa4b3d98e39a8e7d38fd8b0cffbd8464ba85e902"
|
|
6666
6696
|
},
|
|
6697
|
+
{
|
|
6698
|
+
"path": "modules/platform-identity/scouting-name-only.js",
|
|
6699
|
+
"mode": "0000644",
|
|
6700
|
+
"sha256": "cfffe99b93ad044a115f322eec909983b0e12428975d7cf1e0f2bd9060f922ce"
|
|
6701
|
+
},
|
|
6667
6702
|
{
|
|
6668
6703
|
"path": "modules/platform-identity/terms-acceptance.js",
|
|
6669
6704
|
"mode": "0000644",
|
|
@@ -7487,12 +7522,12 @@
|
|
|
7487
7522
|
{
|
|
7488
7523
|
"path": "modules/public-landing/public/projects-floor.states.json",
|
|
7489
7524
|
"mode": "0000644",
|
|
7490
|
-
"sha256": "
|
|
7525
|
+
"sha256": "598d3d330ec8f054a8af2ca0b354e7f3a604c6335a34607dd6bcd4cd2dae4584"
|
|
7491
7526
|
},
|
|
7492
7527
|
{
|
|
7493
7528
|
"path": "modules/public-landing/public/projects.html",
|
|
7494
7529
|
"mode": "0000644",
|
|
7495
|
-
"sha256": "
|
|
7530
|
+
"sha256": "5239de18d6e58de7e8e22f4666965afe956f567b3f31304a206feb9f476258cc"
|
|
7496
7531
|
},
|
|
7497
7532
|
{
|
|
7498
7533
|
"path": "modules/public-landing/public/projects.probes.json",
|
|
@@ -8207,7 +8242,7 @@
|
|
|
8207
8242
|
{
|
|
8208
8243
|
"path": "modules/ui-design/styles/expedition/mock.html",
|
|
8209
8244
|
"mode": "0000644",
|
|
8210
|
-
"sha256": "
|
|
8245
|
+
"sha256": "3596b070d8ece6f93894257fd9d8ae5c6a4a12690302c13e6eafa971161b102d"
|
|
8211
8246
|
},
|
|
8212
8247
|
{
|
|
8213
8248
|
"path": "modules/ui-design/styles/expedition/mock.states.json",
|
|
@@ -8262,12 +8297,12 @@
|
|
|
8262
8297
|
{
|
|
8263
8298
|
"path": "package-lock.json",
|
|
8264
8299
|
"mode": "0000644",
|
|
8265
|
-
"sha256": "
|
|
8300
|
+
"sha256": "c5cc97b40c78fcf1e0eb46f141d801315cb7cdc9afb99ee7435707df4a067f04"
|
|
8266
8301
|
},
|
|
8267
8302
|
{
|
|
8268
8303
|
"path": "package.json",
|
|
8269
8304
|
"mode": "0000644",
|
|
8270
|
-
"sha256": "
|
|
8305
|
+
"sha256": "3f6fc02ebfabdea595b601e08e7bb9aa2004f576bc4497ecf1d36482889b8efb"
|
|
8271
8306
|
},
|
|
8272
8307
|
{
|
|
8273
8308
|
"path": "public-docs/index.html",
|
|
@@ -10022,12 +10057,12 @@
|
|
|
10022
10057
|
{
|
|
10023
10058
|
"path": "src/bongos/auth-idp.js",
|
|
10024
10059
|
"mode": "0000644",
|
|
10025
|
-
"sha256": "
|
|
10060
|
+
"sha256": "fb4d7e17e113cdb41e118d3ecaefc6dc81676dcb780deb3f13532bd998b1412d"
|
|
10026
10061
|
},
|
|
10027
10062
|
{
|
|
10028
10063
|
"path": "src/bongos/auth.js",
|
|
10029
10064
|
"mode": "0000644",
|
|
10030
|
-
"sha256": "
|
|
10065
|
+
"sha256": "f35226f4ab906fa8dbcd688e1c429ce9f161e616f6b5c4a96dee3cebdf33e4b1"
|
|
10031
10066
|
},
|
|
10032
10067
|
{
|
|
10033
10068
|
"path": "src/bongos/cascade-dispatch.js",
|
|
@@ -10312,7 +10347,7 @@
|
|
|
10312
10347
|
{
|
|
10313
10348
|
"path": "src/module-api.js",
|
|
10314
10349
|
"mode": "0000644",
|
|
10315
|
-
"sha256": "
|
|
10350
|
+
"sha256": "2bc85f866eb82befe5dd49e4e5b3c1ed1195f33eb2d00a8f5c8f952d82c99843"
|
|
10316
10351
|
},
|
|
10317
10352
|
{
|
|
10318
10353
|
"path": "src/module-loader/catalog.js",
|
|
@@ -10407,7 +10442,7 @@
|
|
|
10407
10442
|
{
|
|
10408
10443
|
"path": "tests/account_privacy_flags.mjs",
|
|
10409
10444
|
"mode": "0000644",
|
|
10410
|
-
"sha256": "
|
|
10445
|
+
"sha256": "1b49da051770c8bcce351c5d6dd96070962913bb63c687a7b5ae0cc0248ad1e6"
|
|
10411
10446
|
},
|
|
10412
10447
|
{
|
|
10413
10448
|
"path": "tests/achievements_reconcile.mjs",
|
|
@@ -10582,12 +10617,12 @@
|
|
|
10582
10617
|
{
|
|
10583
10618
|
"path": "tests/application_echo.mjs",
|
|
10584
10619
|
"mode": "0000644",
|
|
10585
|
-
"sha256": "
|
|
10620
|
+
"sha256": "eec3a0404674e2a02d3ba7f38ec9fee92e5f06870240161d98986d525cb03d3f"
|
|
10586
10621
|
},
|
|
10587
10622
|
{
|
|
10588
10623
|
"path": "tests/application_lifecycle.mjs",
|
|
10589
10624
|
"mode": "0000644",
|
|
10590
|
-
"sha256": "
|
|
10625
|
+
"sha256": "975389846058a123344a6cd56d2355b606c86e2ce59a48981782f61204090096"
|
|
10591
10626
|
},
|
|
10592
10627
|
{
|
|
10593
10628
|
"path": "tests/architect.mjs",
|
|
@@ -11029,6 +11064,11 @@
|
|
|
11029
11064
|
"mode": "0000644",
|
|
11030
11065
|
"sha256": "2ddceb37d46eda5c3ab2a56b54c86f3cf55596479b5fe7f30646f45b1ac11ac2"
|
|
11031
11066
|
},
|
|
11067
|
+
{
|
|
11068
|
+
"path": "tests/card_apply_ui.mjs",
|
|
11069
|
+
"mode": "0000644",
|
|
11070
|
+
"sha256": "998dcc1ca4ff0dfc2368fe4237a5b00bc98fbf7824cd1992f1f7e90bb01c1c56"
|
|
11071
|
+
},
|
|
11032
11072
|
{
|
|
11033
11073
|
"path": "tests/cascade-dispatch.mjs",
|
|
11034
11074
|
"mode": "0000644",
|
|
@@ -11169,6 +11209,11 @@
|
|
|
11169
11209
|
"mode": "0000644",
|
|
11170
11210
|
"sha256": "654e70af16092ed0dc76c058b245863c8470b8c3441c39e4c4f5bfd40f60c138"
|
|
11171
11211
|
},
|
|
11212
|
+
{
|
|
11213
|
+
"path": "tests/community_search_route.mjs",
|
|
11214
|
+
"mode": "0000644",
|
|
11215
|
+
"sha256": "4562631deca93ab222d9ead95c31cbc0964f30194dd59e025bfee35c4d18bb80"
|
|
11216
|
+
},
|
|
11172
11217
|
{
|
|
11173
11218
|
"path": "tests/compose_demo_credentials.mjs",
|
|
11174
11219
|
"mode": "0000644",
|
|
@@ -11542,7 +11587,7 @@
|
|
|
11542
11587
|
{
|
|
11543
11588
|
"path": "tests/effective_visibility_predicate.mjs",
|
|
11544
11589
|
"mode": "0000644",
|
|
11545
|
-
"sha256": "
|
|
11590
|
+
"sha256": "385ffb03ca61b6422f521dfefa4ab584af1fe87cd8bd4c6fb4cf3a5d631acc28"
|
|
11546
11591
|
},
|
|
11547
11592
|
{
|
|
11548
11593
|
"path": "tests/est_advisory.mjs",
|
|
@@ -12642,7 +12687,7 @@
|
|
|
12642
12687
|
{
|
|
12643
12688
|
"path": "tests/idp_device_exchange.mjs",
|
|
12644
12689
|
"mode": "0000644",
|
|
12645
|
-
"sha256": "
|
|
12690
|
+
"sha256": "3a57c5a71dae3b35d90fb360efc8ae39ca889f18dbc18d504a68cbc01f0c219c"
|
|
12646
12691
|
},
|
|
12647
12692
|
{
|
|
12648
12693
|
"path": "tests/idp_federation.mjs",
|
|
@@ -13012,7 +13057,7 @@
|
|
|
13012
13057
|
{
|
|
13013
13058
|
"path": "tests/module_api.mjs",
|
|
13014
13059
|
"mode": "0000644",
|
|
13015
|
-
"sha256": "
|
|
13060
|
+
"sha256": "02f08f0c3449d0d3d7e3df4f2116aba31a01732b7f083dad0d1d11358c90ff53"
|
|
13016
13061
|
},
|
|
13017
13062
|
{
|
|
13018
13063
|
"path": "tests/module_api_lazy.mjs",
|
|
@@ -13254,6 +13299,11 @@
|
|
|
13254
13299
|
"mode": "0000644",
|
|
13255
13300
|
"sha256": "e3b2f36780b35fd66690b1c426832322b2781c5386cf7fd50e995a7c2cc089bb"
|
|
13256
13301
|
},
|
|
13302
|
+
{
|
|
13303
|
+
"path": "tests/people_name_only.mjs",
|
|
13304
|
+
"mode": "0000644",
|
|
13305
|
+
"sha256": "a94562e7680e7153b065fa5b152e13d9880de477e7e9f2a4c9b8de0224266ead"
|
|
13306
|
+
},
|
|
13257
13307
|
{
|
|
13258
13308
|
"path": "tests/permission_path.mjs",
|
|
13259
13309
|
"mode": "0000644",
|
|
@@ -13357,7 +13407,7 @@
|
|
|
13357
13407
|
{
|
|
13358
13408
|
"path": "tests/profile_route.mjs",
|
|
13359
13409
|
"mode": "0000644",
|
|
13360
|
-
"sha256": "
|
|
13410
|
+
"sha256": "2e23ed585a9cc31bc3627c284ba7fd1e9234ef746d050d79fa771e8029eaf1e8"
|
|
13361
13411
|
},
|
|
13362
13412
|
{
|
|
13363
13413
|
"path": "tests/profile_ui_cross_project.mjs",
|
|
@@ -13797,7 +13847,7 @@
|
|
|
13797
13847
|
{
|
|
13798
13848
|
"path": "tests/recruiter_sliver_boundary.mjs",
|
|
13799
13849
|
"mode": "0000644",
|
|
13800
|
-
"sha256": "
|
|
13850
|
+
"sha256": "522df6e7930347ff312ef5b2cb98cfde3c53f7465a133618dd970872241bc2b3"
|
|
13801
13851
|
},
|
|
13802
13852
|
{
|
|
13803
13853
|
"path": "tests/redteam_followup_kind.mjs",
|
|
@@ -13962,7 +14012,7 @@
|
|
|
13962
14012
|
{
|
|
13963
14013
|
"path": "tests/scouting_owner_access_and_reach.mjs",
|
|
13964
14014
|
"mode": "0000644",
|
|
13965
|
-
"sha256": "
|
|
14015
|
+
"sha256": "bbaff2a089e24b294961d8be52714be3704b81b934457a0872e32bdf3b330a96"
|
|
13966
14016
|
},
|
|
13967
14017
|
{
|
|
13968
14018
|
"path": "tests/scouting_page_gate.mjs",
|
|
@@ -14732,7 +14782,7 @@
|
|
|
14732
14782
|
{
|
|
14733
14783
|
"path": "tests/ui_design_styles.mjs",
|
|
14734
14784
|
"mode": "0000644",
|
|
14735
|
-
"sha256": "
|
|
14785
|
+
"sha256": "e10c29d3cf8ad7b617276c1af424a6f7c84b6b5b2c20c0284f229a0f0077c678"
|
|
14736
14786
|
},
|
|
14737
14787
|
{
|
|
14738
14788
|
"path": "tests/unit_report_status.mjs",
|
|
@@ -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
|
+
- 417 operations across 63 resource groups
|
|
9
9
|
|
|
10
10
|
## Use it from your project
|
|
11
11
|
|
|
@@ -308,6 +308,10 @@ function createClient(opts = {}) {
|
|
|
308
308
|
// GET /closeness/with/{builderId} — rank: any-builder — GET /closeness/with/:builderId
|
|
309
309
|
getClosenessWithBuilderId: (args) => request("GET", "/closeness/with/{builderId}", { hasBody: false }, args),
|
|
310
310
|
},
|
|
311
|
+
"community": {
|
|
312
|
+
// GET /community/search — rank: public — GET /community/search
|
|
313
|
+
getCommunitySearch: (args) => request("GET", "/community/search", { hasBody: false }, args),
|
|
314
|
+
},
|
|
311
315
|
"connections": {
|
|
312
316
|
// GET /connections — rank: any-builder — GET /connections
|
|
313
317
|
getConnections: (args) => request("GET", "/connections", { hasBody: false }, args),
|
|
@@ -307,6 +307,10 @@ function createClient(opts = {}) {
|
|
|
307
307
|
// GET /closeness/with/{builderId} — rank: any-builder — GET /closeness/with/:builderId
|
|
308
308
|
getClosenessWithBuilderId: (args) => request("GET", "/closeness/with/{builderId}", { hasBody: false }, args),
|
|
309
309
|
},
|
|
310
|
+
"community": {
|
|
311
|
+
// GET /community/search — rank: public — GET /community/search
|
|
312
|
+
getCommunitySearch: (args) => request("GET", "/community/search", { hasBody: false }, args),
|
|
313
|
+
},
|
|
310
314
|
"connections": {
|
|
311
315
|
// GET /connections — rank: any-builder — GET /connections
|
|
312
316
|
getConnections: (args) => request("GET", "/connections", { hasBody: false }, args),
|
|
@@ -49,6 +49,7 @@ export interface GetBuildersRosterResponse { builders: unknown; stale_hours: unk
|
|
|
49
49
|
export interface GetClosenessForMeResponse { closeness: unknown; count: unknown; returned: unknown }
|
|
50
50
|
export interface GetClosenessWeightsResponse { weights: unknown; window_days: unknown; note: unknown }
|
|
51
51
|
export interface GetClosenessWithBuilderIdResponse { closeness: unknown; why: unknown }
|
|
52
|
+
export interface GetCommunitySearchResponse { query: unknown; discipline: unknown; count: unknown; results: unknown; page: unknown }
|
|
52
53
|
export interface GetConnectionsDegreeHandleResponse { handle: unknown; degree: unknown; mutuals: unknown; mutual_count: unknown; truncated: unknown }
|
|
53
54
|
export interface GetConnectionsRequestsResponse { incoming: unknown; outgoing: unknown; incoming_count: unknown; outgoing_count: unknown }
|
|
54
55
|
export interface GetConnectionsResponse { connections: unknown; count: unknown }
|
|
@@ -134,7 +135,7 @@ export interface GetPublicUptimeResponse { services: unknown }
|
|
|
134
135
|
export interface GetPublicVersionsResponse { versions: unknown; page: PageInfo }
|
|
135
136
|
export interface GetRemovalProposalsResponse { pending: unknown; count: unknown }
|
|
136
137
|
export interface GetScoutingHandleResponse { sliver: unknown }
|
|
137
|
-
export interface GetScoutingResponse { builders: unknown }
|
|
138
|
+
export interface GetScoutingResponse { builders: unknown; name_only: unknown }
|
|
138
139
|
export interface GetSecurityDocsResponse { docs: unknown }
|
|
139
140
|
export interface GetSecurityDocsSlugResponse { doc: unknown }
|
|
140
141
|
export interface GetSecurityReportsResponse { reports: unknown; bounty_table: unknown; statuses: unknown }
|
|
@@ -694,6 +695,10 @@ export interface BongosClient {
|
|
|
694
695
|
/** GET /closeness/with/{builderId} — rank: any-builder */
|
|
695
696
|
getClosenessWithBuilderId(args?: RequestArgs): Promise<GetClosenessWithBuilderIdResponse>;
|
|
696
697
|
};
|
|
698
|
+
"community": {
|
|
699
|
+
/** GET /community/search — rank: public */
|
|
700
|
+
getCommunitySearch(args?: RequestArgs): Promise<GetCommunitySearchResponse>;
|
|
701
|
+
};
|
|
697
702
|
"connections": {
|
|
698
703
|
/** GET /connections — rank: any-builder */
|
|
699
704
|
getConnections(args?: RequestArgs): Promise<GetConnectionsResponse>;
|
|
@@ -304,6 +304,10 @@ export function createClient(opts = {}) {
|
|
|
304
304
|
// GET /closeness/with/{builderId} — rank: any-builder — GET /closeness/with/:builderId
|
|
305
305
|
getClosenessWithBuilderId: (args) => request("GET", "/closeness/with/{builderId}", { hasBody: false }, args),
|
|
306
306
|
},
|
|
307
|
+
"community": {
|
|
308
|
+
// GET /community/search — rank: public — GET /community/search
|
|
309
|
+
getCommunitySearch: (args) => request("GET", "/community/search", { hasBody: false }, args),
|
|
310
|
+
},
|
|
307
311
|
"connections": {
|
|
308
312
|
// GET /connections — rank: any-builder — GET /connections
|
|
309
313
|
getConnections: (args) => request("GET", "/connections", { hasBody: false }, args),
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
- **Status:** accepted
|
|
4
4
|
- **Date:** 2026-08-29
|
|
5
5
|
- **Task:** [task 1002284](https://cloudbongos.com/builders#/task/1002284) (R08, goal 1000045 — criteria C3/C4)
|
|
6
|
+
- **Resolved by:** [ADR 0333](0333-the-application-vouch-is-a-third-token-spent-once-and-bound-to-its-login.md) (task 1002285) — D1's handle and D2's minter, verifier tightening and jti choice are built there.
|
|
6
7
|
- **Relates to:** [ADR 0201](0201-cross-project-application-vouched-row-live-record.md) (the design this builds — D1, D3.2, D4), [ADR 0016](0016-trust-boundary-server-enforced-permissions.md) (descriptive analytics are never authority), [ADR 0141](<redacted>.md) (identity federated, authority local), [ADR 0171](0171-profile-rollup-join-and-consent.md) D2 (the non-numeric principal guard), [ADR 0116](0116-api-error-envelope-and-code-taxonomy.md) (a refusal names the action available), [ADR 0202](0202-connections-graph-and-bounded-degree.md) D4 (the `account-visibility.js` "its own small file" precedent this reuses)
|
|
7
8
|
|
|
8
9
|
## Context
|
package/docs/adr/0333-the-application-vouch-is-a-third-token-spent-once-and-bound-to-its-login.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# ADR 0333 — The application vouch is a third token kind, spent once, bound to the login it names, and carries a handle only past the consent floor
|
|
2
|
+
|
|
3
|
+
- **Status:** accepted
|
|
4
|
+
- **Date:** 2026-09-24
|
|
5
|
+
- **Task:** [task 1002285](https://cloudbongos.com/builders#/task/1002285) (R09, goal 1000045 — criterion C4)
|
|
6
|
+
- **Relates to:** [ADR 0201](0201-cross-project-application-vouched-row-live-record.md) D2 (the vouch, the header, the handle), [ADR 0208](0208-application-lifecycle-the-handle-waits-and-the-vouch-has-no-minter.md) D1 + D2 (the handle waits; the minter that cannot express it), [ADR 0260](0260-the-application-is-the-consent-and-the-echo-is-the-gate.md) (the live consumer, built dormant), [ADR 0141](<redacted>.md) §1 (the signed assertion), [ADR 0144](0144-federated-single-logout-backchannel.md) (the logout token), [ADR 0016](0016-trust-boundary-server-enforced-permissions.md) (a vouch is never authority), [ADR 0091](0091-bounding-the-kernel-and-db-carve.md) §2 (boundary-forced duplication)
|
|
7
|
+
|
|
8
|
+
## Context
|
|
9
|
+
|
|
10
|
+
ADR 0201 D2 decided that an application relayed by the hub carries a hub-signed vouch in a header, so a project's reviewer can safely see the applicant's cross-project record beside the name. ADR 0208 D2 then found that the vouch could not be built as D2.1 wrote it: `mintHubAssertion` has no `purpose`, and — worse — `verifyHubAssertion` accepted *any* identity payload, purpose or not, so a captured vouch would have verified as a device sign-in. ADR 0260 built everything downstream of the vouch (the D7 applicant view, the echo-gated `POST /sso/applicant-profile`, the queue's live read keyed on `applicant_github_id`) and left it dormant, because nothing wrote that column.
|
|
11
|
+
|
|
12
|
+
This task writes it. Four choices in the writer are not obvious, and ADR 0208 D2 explicitly asked for one of them to be *chosen* rather than inherited.
|
|
13
|
+
|
|
14
|
+
## Decision
|
|
15
|
+
|
|
16
|
+
### D1 — A third mint/verify pair over one shared envelope, on both sides
|
|
17
|
+
|
|
18
|
+
`mintHubApplicationVouch` (hub) and `<redacted>` (instance) carry `purpose: 'application'` **and** identity (`sub`, `applicant_login`, `handle`). The three token kinds now differ only in their claims, so each side mints and verifies them through one envelope — `signHubToken` in `hub-keys.js`, `verifyHubToken` in `auth-idp.js` (signature first, Ed25519 hardcoded, issuer, audience, expiry) — rather than three copies of the same twenty lines of crypto. Each verifier then demands exactly what the other two lack:
|
|
19
|
+
|
|
20
|
+
| Kind | Identity | `purpose` |
|
|
21
|
+
|---|---|---|
|
|
22
|
+
| login assertion | required | **forbidden** |
|
|
23
|
+
| logout token | absent | `backchannel-logout` |
|
|
24
|
+
| application vouch | required, as `applicant_login` | `application` |
|
|
25
|
+
|
|
26
|
+
The existing error messages are preserved byte-for-byte (the envelope takes the kind's name as a label).
|
|
27
|
+
|
|
28
|
+
**The vouch's login rides as `applicant_login`, not `github_login`, and that is what makes it safe on cores that have not upgraded.** Every login verifier any core ever shipped demands `github_login`, so a vouch relayed to a project still on an older pin is refused there as a device sign-in too — the purpose refusal in D2 only exists on cores that run this release, and the hub cannot know which pin a project runs. Found by review before ship: with a shared `github_login` claim, an older project that ignored the header could have exchanged a captured vouch for a CLI session within its ~120s life. The two defences are independent, and `tests/idp_device_exchange.mjs` asserts each on its own.
|
|
29
|
+
|
|
30
|
+
### D2 — `verifyHubAssertion` refuses ANY `purpose`, not a list of known ones
|
|
31
|
+
|
|
32
|
+
ADR 0208 D2 named the window: the tightening is free only while no minter puts a purpose on an identity token, and this task is the one that starts doing so. The check is presence (`hasOwnProperty`), so `purpose: null`, `''` and any future marker are refused too. A list of forbidden purposes would reopen the device-login replay the day someone adds a fourth kind and forgets the list.
|
|
33
|
+
|
|
34
|
+
### D3 — The jti is CHOSEN: a separate single-use store, and a vouch must carry one
|
|
35
|
+
|
|
36
|
+
One vouch vouches one application. The store is its own register — not the CLI assertion map it could have inherited — for the reason the logout store gave: no two token kinds share dedupe state. All three registers now come from one `jtiStore()` factory, so they cannot drift apart. The vouch is spent when it is read, before the INSERT: a write that then fails answers 500, the hub reports the project unreachable, and the applicant's retry mints a fresh vouch — so a spent-but-unwritten vouch costs nothing. `<redacted>` also **requires** a `jti` (its siblings tolerate a missing one) and **requires an audience**: the shared envelope skips the audience check when no client id is given, and a vouch checked that way would accept one minted for any project on the platform.
|
|
37
|
+
|
|
38
|
+
### D4 — The vouch must name the login the request names; otherwise the row is written unvouched
|
|
39
|
+
|
|
40
|
+
The body's `github_login` is a string anyone may type. Without the match, any valid vouch could be stapled to a request naming someone else, and the reviewer would read "Identity vouched" beside a name the vouch never confirmed — the exact impersonation surface ADR 0201 exists to close. A mismatch, like every other failure (absent, forged, expired, foreign, replayed, no hub key), writes the unvouched row: **never a refusal** (ADR 0201 D2.3).
|
|
41
|
+
|
|
42
|
+
### D4b — A vouched re-application takes over an UNVOUCHED pending row for its own login
|
|
43
|
+
|
|
44
|
+
The one-open-row index means a later application for a login that already has a pending row cannot insert. Left alone, anyone who filed an unvouched request under a well-known builder's login first — off the landing page, no header needed — would pre-empt that builder's real, vouched application for as long as the row sat there: the reviewer would see "Name unvouched" beside the squatter's name and note. So when the INSERT hits the index and the request carried a verified vouch for that login, the route UPDATEs the pending row with the vouch **and replaces its display name and note** with the vouched request's own, so the words beside "Identity vouched" are the vouched applicant's. The UPDATE's own `WHERE applicant_github_id IS NULL` means a row that is already vouched is never re-stamped, and an unvouched re-application still changes nothing (D1.4). Found by review before ship; the first draft named it as a limit instead.
|
|
45
|
+
|
|
46
|
+
### D5 — The handle is identity, not record; it rides only past the consent floor, and it is stored
|
|
47
|
+
|
|
48
|
+
`applicant_handle` (`core_254`) is written in the same statement as `applicant_github_id` and `vouched_at`, so the three can never disagree. ADR 0260 D4 says nothing about the applicant is stored — that sentence is about the **record**, which is still resolved live on every render; the handle is in the class of `github_login` and `applicant_github_id`, which the row already holds.
|
|
49
|
+
|
|
50
|
+
The hub puts a handle in the vouch only when the account clears `isAccountActive` (active **and** the platform terms accepted) — the same floor the applicant view applies — so the vouch never discloses a handle the reviewer's own queue would not show. A **private** account's handle does ride: applying is the consent (ADR 0260 D2), and its D3 sliver carries the handle anyway. The identity itself comes from the hub session, not the account row, so a provisional account is still vouched — just handle-less. The instance re-checks the handle against the hub's handle charset (a boundary-forced mirror of `normalizeHandle`, driven against it in `tests/idp_device_exchange.mjs`) and stores null for anything else.
|
|
51
|
+
|
|
52
|
+
**Storing it does not outlive a withdrawal, because nothing withdraws a handle.** The floor it passed is write-once in both halves — `profile_state` never demotes from `active`, and `terms_accepted_at` is COALESCE-stamped once (ADR 0213) — and neither `hide_stats` nor going private withholds a handle on any surface (the sliver carries it; `hide_stats` suppresses numbers, never addressability). So the stored handle never shows a reviewer more than the live applicant view would, except after a rename (below).
|
|
53
|
+
|
|
54
|
+
Since ADR 0260 moved the record read server-side and keyed it on `github_id`, the handle is no longer the lookup key ADR 0201 D2.5–6 needed. It is what the reviewer's queue can call the applicant when the hub is unreachable, and it is returned only by the archon-gated `GET /access-requests`.
|
|
55
|
+
|
|
56
|
+
### D6 — On the hub the vouch is best-effort, never a gate
|
|
57
|
+
|
|
58
|
+
A hub with no signing key sends no header and reads nothing — the project writes the unvouched row it always wrote. A failed account read still vouches the identity, handle-less. A mint failure sends no vouch. None of them delays or fails the application. The echo — which is what authorizes the project's later profile read — is written by the same relay on the same `requested` outcome, so a vouch never arrives without the echo it needs, except when the echo write itself fails (below).
|
|
59
|
+
|
|
60
|
+
### D7 — The instance reaches it through a narrow doorway port
|
|
61
|
+
|
|
62
|
+
`readApplicationVouch(token, { githubLogin })` joins the doorway beside `<redacted>`. Core supplies the hub public key and this instance's client id; the onboarding module passes a token and a login and can neither substitute a key nor re-address the audience.
|
|
63
|
+
|
|
64
|
+
## Consequences
|
|
65
|
+
|
|
66
|
+
- The ADR 0260 path lights up with no UI or route change: a vouched row's `applicant_github_id` drives the live profile read, and `watch.js` already renders the pill and the profile block.
|
|
67
|
+
- It lights up only when **both** ends run this release: the hub mints, the project verifies and has `core_254`. Either alone is inert and safe — an old project ignores the header, an old hub sends none.
|
|
68
|
+
- The approve path and `hasInvitedAccessRequest` are unchanged and still name no vouch column; `tests/application_lifecycle.mjs` now asserts that for a row written by the real writer, not only a seeded one.
|
|
69
|
+
|
|
70
|
+
## Honest limits
|
|
71
|
+
|
|
72
|
+
- **The vouch travels with every relay, including to a project whose door then refuses.** The header is minted before the project answers, so an invite-only or unpublished project's server receives the account id and (past the consent floor) the handle of someone who pressed Apply there. It learns no more than the body already tells it — the login and display name — plus the handle and the numeric GitHub id, both public-shaped identity, and it was the applicant who chose to knock.
|
|
73
|
+
- **The jti store is per-process memory.** A restart inside the ~120s window forgets spent vouches; the audience binding stays the primary control, and a replay can only re-assert the identity it already carried at the project it was minted for.
|
|
74
|
+
- **The handle is a snapshot.** A rename after applying is not followed; the hub's previous-handle 301 covers one, and the live profile block shows the current handle whenever the hub answers.
|
|
75
|
+
- **A vouched row can still show no record** when the relay's best-effort echo write failed, since ADR 0260 D3 gates the profile read on the echo. That is the degrade the queue already renders.
|
|
76
|
+
- **No Postgres executes the new INSERT in CI** — the ADR 0208 limit stands. The fake pool in `tests/application_lifecycle.mjs` matches the column list and `VALUES` exactly, so dropping or reordering a vouch column reds the suite; the migration is additive and idempotent.
|
|
77
|
+
|
|
78
|
+
## Rejected
|
|
79
|
+
|
|
80
|
+
- **A `purpose` argument on `mintHubAssertion`.** ADR 0208 D2's reason: it would look like D2.1 shipped while leaving the device-login replay open.
|
|
81
|
+
- **Reusing the CLI assertion's jti map.** Shared dedupe state across token kinds is what the logout store already declined.
|
|
82
|
+
- **Refusing an invalid or mismatched vouch.** Hands an attacker a way to make applications fail and locks out older hubs (ADR 0201 D2.3).
|
|
83
|
+
- **Taking the row's login from the vouch instead of the body.** A mismatch means something is wrong; silently renaming the request to whoever the vouch names would hide it.
|
|
84
|
+
- **Upgrading a squatted row but keeping its name and note.** It would stamp "Identity vouched" beside words someone else may have typed.
|
|
85
|
+
- **Asking the project's version before minting, to skip older pins.** A second round-trip on every application to learn what a claim name (D1) already guarantees on every pin.
|
|
86
|
+
- **Sending the handle regardless of consent.** A provisional or no-terms account discloses nothing on any other surface; the vouch would have been the one exception.
|