@bongos/core 1.19.429 → 1.19.431
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 +71 -51
- 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 +6 -3
- package/clients/bongos-client/index.mjs +2 -0
- package/docs/adr/0215-the-recruiter-sliver-is-a-ceiling-not-a-step.md +116 -0
- package/docs/adr/README.md +1 -0
- package/docs/api/openapi.json +74 -3
- package/docs/api-reference.md +4 -3
- package/docs/copy-inventory.md +162 -154
- package/docs/copy-registry.json +271 -198
- package/docs/design/mocks/hub/picker.html +421 -0
- package/docs/design/projects-hub-direction-v2.md +22 -0
- package/docs/file-map.md +1 -0
- 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/settings.html +1 -1
- package/modules/hall-ui/public/settings.js +17 -8
- package/modules/platform-identity/account-visibility.js +47 -0
- package/modules/platform-identity/platform-identity.js +4 -4
- package/modules/platform-identity/recruiter-sliver.js +197 -0
- package/modules/platform-identity/routes/projects.js +24 -0
- package/modules/platform-identity/routes/scouting.js +58 -0
- package/modules/provisioning/module.json +1 -1
- package/modules/provisioning/provisioning.js +63 -2
- package/modules/provisioning/routes/provisioning.js +28 -6
- package/modules/provisioning/tests/provisioning.mjs +34 -0
- package/modules/ui-design/kit/fixtures/featured-hub.json +1 -1
- package/modules/ui-design/kit/fixtures/featured.json +1 -1
- package/modules/ui-design/kit/fixtures/provisioning-instances.json +1 -1
- package/modules/ui-design/kit/serve.js +28 -4
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/public-landing/assets/cosmos.css +37 -0
- package/public-landing/projects.html +164 -5
- package/public-landing/projects.probes.json +12 -0
- package/public-landing/projects.states.json +3 -2
- package/src/module-api.js +1 -1
- package/tests/account_privacy_flags.mjs +115 -9
- package/tests/effective_visibility_predicate.mjs +58 -1
- package/tests/government_require_permission.mjs +22 -0
- package/tests/profile_route.mjs +6 -0
- package/tests/projects_hub.mjs +122 -7
- package/tests/provisioning_settings.mjs +81 -2
- package/tests/provisioning_settings_env.mjs +6 -0
- package/tests/recruiter_sliver_boundary.mjs +841 -0
- package/tests/scouting_owner_access_and_reach.mjs +4 -0
package/docs/adr/README.md
CHANGED
|
@@ -300,6 +300,7 @@ This keeps the decision history honest and traceable.
|
|
|
300
300
|
| 0212 | [**The connections section is built on the profile page that exists, and it addresses a builder by asking the API to name them** ([task 1002296](https://cloudbongos.com/builders#/task/1002296), R20 · goal 1000045 criterion C6 — the UI half of the connections wave). The profile-page spec puts section 6 on the canonical `cloudbongos.com/u/<handle>`, which [task 1002806](https://cloudbongos.com/builders#/task/1002806) proved does not exist (no route, no page, no search entry, no sitemap row) and which belongs to goal 1000048 R14. Decisions: (1) **section 6 lands in the reserved slot R04 left on the hall profile page** (`modules/hall-ui/public/profile.{html,js}`), as a separate `profile-connections.js` so neither the page script nor `platform-identity.js` grows against its line ratchet, and it follows the CROSS-PROJECT section’s contract exactly — the markup ships `hidden` and reveals only where the hub answered, so an instance without `platform-identity` never renders it. It does not pre-empt the canonical page, which inherits the same three own-scope calls. (2) **Addressing: the page hands the API the `github_login` it holds and uses the `handle` the response echoes back for every write** — core `GET /builders/:id/profile` whitelists nine columns and `handle` is not one of them, and widening that whitelist is task 1002804’s canonical-URL work. `findAccountByHandle` already resolves current-or-previous handle and the route answers with the canonical one, which is the same move the API built for a stale Connect link. It fails closed into the deliberately indistinguishable 404 (unknown / provisional / private stranger), so the ONE honest gap is stated rather than discovered: **a twice-renamed handle has no connect button on this surface**, and it disappears when `/u/<handle>` lands. (3) Three rendering rules, enforced by `tests/profile_connections_ui.mjs` (real router over a WHERE-derived fake pool on a real socket, real client above it): `degree: null` renders "Out of network" and never "not connected", with copy that is BYTE-IDENTICAL whether `truncated` was set — varying it would rebuild the ADR 0207 L2 side channel in words; a sent request claims exactly `201 { status: 'pending' }`, so a re-ask swallowed by the 90-day cooldown simply shows "Connect" again next load with no explanation anywhere; and every count is the length of the list beside it, with `seen_at` and `truncated` never reaching the screen. Rejected: waiting for the hub page (it would block C6’s proof on another goal); building `/u/<handle>` here (the spec says only one such page gets built); adding `handle` to the core profile whitelist or to `cross_project` (the latter is `null` under `hide_stats`, which is exactly where the edge must still show — ADR 0202 D4 §3); resolving through public `GET /profiles/:handle` (it 404s for a private account the viewer IS connected to). Deferred and named: a public per-builder connections list (there is deliberately no such route), removal from the other person’s profile, and sections 7–8.](<redacted>.md) | platform identity / social graph / hall UI |
|
|
301
301
|
| 0214 | [**The canonical profile URL gets one resolver, and it stays dark until the page it names actually resolves** ([task 1002804](https://cloudbongos.com/builders#/task/1002804), P08 · goal 1000045 criterion C1 — the canonical/redirect wiring). Profile-page spec Decision 1 wants `rel=canonical` on the instance, a link-out to the hub, and a numeric-id redirect; `/u/<handle>` does not exist (goal 1000048 R14 is `backlog`, and R01 — the ADR that fixes its PATH — is unwritten, while R03 proposes moving platform pages under `/bongos/…`). Decisions: (1) **one resolver** (`modules/platform-identity/canonical-profile.js`) answers where a profile lives, and it answers `null` while the page 404s — a canonical naming a non-indexable URL consolidates nothing and risks the one page that works, and the address is not even settled yet; one boolean flips all three surfaces together, and a test reds if a `/u/` route lands while it is still false. (2) **`{{hubOrigin}}`** joins `applyBrandTokens` (own `publicOrigin` on the hub, `loadIdpConfig().origin` when federated, `''` otherwise) — the server-side stamp ADR 0171 D1 asked for — delivered as a `<meta>`, never inside an `href`, because an empty value in an href degrades to a same-host URL claiming to be the hub. (3) **`handle` joins `GET /builders/:id/profile`** under the EXISTENCE predicate (`isAccountVisible`), not the rollup one: `hide_stats` suppresses numbers and never addressability, and the `handle`+`cross_project: null` pair is already published unauthenticated by `GET /profiles/:handle`. This closes ADR 0212’s stated gap — a twice-renamed builder now has a connect button. (4) **The hub redirects and a federated instance canonicalizes**, which is how Decision 1’s two apparently contradictory clauses reconcile: the hub serves the same person at both URLs, a federated instance serves genuinely different content. (5) **The redirect is not an existence oracle** — its non-redirect branch is the ordinary working page, absent/provisional/private are byte-identical, and the one bit it exposes is what `/profiles/:handle` already answers with 200-vs-404.](<redacted>.md) | platform identity / SEO / hall UI |
|
|
302
302
|
| 0210 | [**The recruiting directory graduates on an instance-asserted ownership claim, and the recruiting opt-out gates the directory and nothing else** ([task 1002290](https://cloudbongos.com/builders#/task/1002290), R14, goal 1000045 criterion C5 — "project owners, not only Archons, browse builder profiles to recruit"). Two independent problems wore one task id. The reach flag `recruiter_discoverable` protected nobody — task 1002967 said so, and the Settings row stayed in the future tense because of it. And "widen the Archon-only /scouting" was already stale (ADR 0157 lowered `project.curate` to metic) while hiding the real question: **a project owner is not a rank**, and someone who registers a project is an Archon on their OWN instance and usually a bare `xenos` on the hub where the directory lives, so no floor reaches them without reaching every stranger. **D1** "project owner" on the hub is `<redacted>.membership_kind = 'owner'` — written by the PROJECT itself at `POST /sso/membership/check-in` from its own first-admin config, and refused unless the hub's own `signin_verified_at` witness stands (ADR 0205) — and never `platform_identity_projects.owner_github_id`, the hub-curated column ADR 0201 D3 names and forbids; the prohibition is about a hub-held list consulted before an ADMISSION on someone else's box, and this is the hub reading the instance's own mirrored claim before a read of the hub's OWN directory. **D2** the two doors are an OR in `modules/platform-identity/scouting-authz.js` (the `goal-authz.js` owner-or-rank shape, kept out of `platform-identity.js` at its size ratchet): ownership is asked first and a "no" falls through to the UNMODIFIED `requirePermission`, so a refusal keeps its exact code, `required`/`held` and floors map — the widening can only admit; the atom is spelled in the ROUTE's middleware list, because a gate hidden in the helper would make `route-rank-check.js` and `gen-api-docs.js` record this privileged route as `any-builder`; and a broken ownership read falls closed onto the rank door rather than admitting or 500ing. No atom is minted — `project.recruit` belongs to the console wave (spike 1002786 R3). **D3** `PAGE_GATES` gains an optional `alsoAdmits` naming a function on the `platform-identity.hub` port, declared on `requireProjectCuratePage` alone and consulted only after the permission check refused, so the `/people` shell admits exactly the two audiences its data route does; absent port, absent function or a throw all deny. **D4** the reach COALESCE gets its SQL twin in `account-visibility.js` (its sole owner) and composes into `scoutingListableSql` = rollup AND reach, which `listScoutingRollup` joins — but reach is deliberately NOT folded into `rollupVisibleSql`, because the community spec D3 says the opt-out governs the recruiting surface only and folding it down would silently empty a future public leaderboard. **D5** no migration: both columns exist and migration 003's `(github_id)` index already serves the probe. **D6** the ownership query JOINs `platform_identity_sso_clients` on `status='active'` — a membership row never expires and nothing ages it out, so suspending the client (the lever that already stops a project signing anyone in) had to revoke the read it derives, or suspending a rogue project would leave its owner reading every builder on the platform forever. The task's own adversarial review also found the sole-owner drift guard was matching only the UNALIASED spelling of the reach COALESCE — i.e. not the one that ships — and two fail-open defaults (a prototype-reachable `alsoAdmits`, and an alias guard resting on template evaluation order); all three fixed and mutation-checked. ⚠ Honest limits recorded, not fixed: the hall NAV still hides People from a project owner (task 1003349, sequenced with R15 which owns that surface), the `touchMembership` write path stays as ADR 0205 left it, and `openapi.json` cannot express "or owner". ⚠ And DELEGATES do not reach the directory yet (blocker 1000122 + task 1003350, linked) — an instance reports `owner` for its first admin only, so the registrant half works and the delegate half needs the instance to report `owner` for any archon, which changes a cross-version wire contract and a shipped bucketing; filed as blocker 1000122, and nothing here changes when it is answered. Rejected: lowering the floor further (a floor low enough to admit a registrant excludes nobody); a `project.owner` atom (ADR 0201 D3 rejected it); minting `project.recruit` here; gating on `owner_github_id`; folding reach into the rollup predicate; widening `membershipKind()` on our own judgement; shipping the route without the page.](<redacted>.md) | platform identity / authz + privacy |
|
|
303
|
+
| 0215 | [**The pre-accept recruiter sliver is a CEILING, not a step: a whitelist keyed by consent-and-reach, on the recruiting surface’s own door** ([task 1002968](https://cloudbongos.com/builders#/task/1002968), PV3 · goal 1000045 criteria C2/C5; privacy spec D3, owner-signed 2026-08-16). Privacy spec D2 has a row nothing could serve — **private · discoverable** — and ADR 0210 D4 named the reason: *“the full rollup is never its disclosure — the D3 sliver is”*. Decisions: **D1** the audience predicate is `recruiterSliverVisibleSql` = `accountActiveSql AND recruiterReachSql`, composed in `account-visibility.js` (its sole owner) and the ONE composed answer that deliberately **omits the existence axis** — ANDing `accountVisibleSql` would empty the sliver of exactly the account it serves; dropping it is safe only because reach is `COALESCE(recruiter_discoverable, visibility=’public’)`, so a private account reaches this surface only by its owner’s explicit opt-IN — and, after adversarial review, that opt-IN must be the one they MEANT: `setAccountPrivacy` now resets `recruiter_discoverable` to NULL when a PATCH turns an account private without naming reach, because a `true` set while PUBLIC meant “recruiters may see my public profile” and this predicate would have activated that stale consent silently. `profile_state=’active’` still floors it (a provisional account is never recruiter-visible) and `hide_stats` is absent, because hide changes the sliver’s SHAPE, never who appears in it; the guard PINS that existence-less predicate to its one reader, since a future public read joining it would look adopted while serving private accounts. **D2** the projection is a literal whitelist — `handle`, `display_name`, `avatar_url`, `disciplines`, `active_recently`, and under `hide_stats` the last two are **absent, not null**, with the activity query never issued at all (the cheapest way for a later edit to leak a number is for it to already be in hand). `last_active` is compared to the 30-day window IN SQL and only the boolean returns, so the date never enters the process; `github_id`/`github_login` are never KEYS, every count and any profile URL stay out — with one limit stated rather than glossed: the avatar D3 grants is GitHub’s own URL and embeds the account id, so the proof pins WHERE the id may appear instead of claiming an absence the code does not deliver. **D3** the handle is an ADDRESS, not a door — `GET /profiles/:handle` joins `accountVisibleSql` and 404s for the very account whose sliver was just read (asserted, with a 200 control), and a PREVIOUS handle resolves to nothing here unlike the public page’s 301, because a recruiting read has no shared links to preserve and a redirect would confirm a rename. **D4** one route, `GET /scouting/:handle`, beside the directory in `routes/scouting.js` but deliberately NOT sharing its gate: **no `project.recruit` atom is minted** (ADR 0201 D3 and ADR 0210 both reserve it for the console wave that defines it), and until it exists the sliver holds spec D1’s declared floor for that atom — `api.requireRank('archon')`. The first draft reused the directory’s door and that was WIDER than the owner-signed floor on both halves (`project.curate` at metic, OR any project owner — typically a bare xenos), on the first surface that discloses a PRIVATE account; narrowing after people are disclosed is not recoverable, widening later is. The audience question is the owner’s and is FILED, not taken — blocker 1000126, with the C5 tension it carries and a one-line swap either way. 404 never 403 (a 403 confirms the handle), `no-store` (ADR 0171 D5). **D5** it grants nothing (ADR 0016): the module is required by exactly ONE first-party server file — the route that serializes it — enumerated from source, and no rank/role/permission/membership travels with it. **D6** the Settings copy widens back from “the People directory” (narrowed by task 1002290 while this was unbuilt) to name **both** recruiting surfaces — “both” and not “every”, because a guard asserts `routes/scouting.js` mounts exactly two routes and that both readers compose `recruiterReachSql`. The half that was actually WRONG was the grant itself: the copy promised a hidden account “your name and nothing else” while the sliver also ships the AVATAR, never named the picture in the shown branch, and never told a private account this is the one thing a recruiter sees while their page answers “not found”. The guard now iterates SLIVER_KEYS from the module instead of checking transcribed phrases, so a sixth granted field cannot ship undescribed. **D7** no migration; the port lives beside `getPublicProfileExtras` in the MODULE, not the file, which is on the 1500-line ratchet. The proof is a whitelist over the module’s own exported key list, planted improbable sentinels asserted absent from the whole body with controls against vacuity, and a fake pool that reads boolean STRUCTURE — the house interpreter collects terms and ANDs them, so rewriting this predicate’s `AND` to `OR` (which in Postgres serves EVERY active account) passed all three test files green until each term was made to be CONSUMED and the residue required to be pure conjunction. That hole is still open in five sibling proofs (idea 1000877). Four further defects came out of the same review: the credits/karma sentinels sat on rows the sliver never reads, a “control” compared a fixture to itself, and the one-reader pin missed the predicate’s JS twin. ⚠ Honest limits: **no UI consumes it yet** (the recruiting view is the console wave’s and task 1002972’s); **the audience is UNRESOLVED** (blocker 1000126) and the archon floor is narrower than goal C5 describes, so project owners cannot use the sliver today; the two-route guard counts only `routes/scouting.js`, so a recruiting read added elsewhere would not trip it; the route is unmetered (idea 1000876); and `active_recently` understates for a builder whose only project never reports a rollup. Rejected: flooring on `accountVisibleSql`; folding reach into `rollupVisibleSql`; minting `project.recruit`; **reusing the directory’s door**; leaving a stale `recruiter_discoverable = true` to read as consent after an account goes private; a second route file; null-instead-of-absent rollup keys; a profile URL / `github_login` / a project count / a raw `last_active`; 301-ing a previous handle; 403 for a non-discoverable builder.](<redacted>.md) | platform identity / privacy |
|
|
303
304
|
| 0213 | [**The platform T&C acceptance is the hub's own witness, written once, and consent becomes two columns** ([task 1002913](https://cloudbongos.com/builders#/task/1002913), goal 1000045). ADR 0141 §4 deferred consent for cross-project aggregation to "the platform T&C" and ADR 0171 D3 wrote its own definition around the moment that acceptance "can later be captured" - but no acceptance record existed, and while `/terms` DOES exist (task 1003251) it says nothing about work crossing between projects, so the public-profile premise ("already carries platform T&C consent") was untrue for every account. The scouting.js:6 pointer the task named had also been overwritten by ADR 0210, so the debt was going invisible rather than getting paid. Decision: `terms_accepted_at` + `terms_version` on `platform_identity_accounts` (migration 019), written ONLY by `upsertAccount`'s `activate` branch - one caller, /sso/authorize, where `activate: true` is a source literal and every field comes from the hub's resolved session (the ADR 0205 D3 property; a record a caller could assert is evidence of nothing). COALESCE makes it write-once, so the column keeps meaning WHEN consent was given. The consent axis in `account-visibility.js` becomes `profile_state = 'active' AND terms_accepted_at IS NOT NULL`, composed into every other predicate, which is what makes the tie structural rather than a promise. NO backfill (D4): existing active accounts re-accept on their next hub sign-in - ADR 0171 D3's own rule and P03's ratified rationale - and that visible consequence, plus the wording itself, went to the owner on blocker 1000123. Rejected: an acceptances TABLE (no event stream yet), a click-through gate (an interstitial in a redirect built to be invisible; additive later), backfilling (records a consent that never happened), deriving profile_state from the timestamp, and putting the predicate in `terms-acceptance.js` (a second owner of an effective-visibility answer, which ADR 0202 D4 forbids).](<redacted>.md) | platform identity / consent / privacy |
|
|
304
305
|
|
|
305
306
|
> ⚠️ **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.
|
package/docs/api/openapi.json
CHANGED
|
@@ -12089,6 +12089,58 @@
|
|
|
12089
12089
|
]
|
|
12090
12090
|
}
|
|
12091
12091
|
},
|
|
12092
|
+
"/scouting/{handle}": {
|
|
12093
|
+
"get": {
|
|
12094
|
+
"operationId": "get_scouting_handle",
|
|
12095
|
+
"tags": [
|
|
12096
|
+
"scouting"
|
|
12097
|
+
],
|
|
12098
|
+
"summary": "GET /scouting/:handle",
|
|
12099
|
+
"description": "the PRE-ACCEPT SLIVER for ONE builder (privacy spec D3, ADR 0215 D4, task 1002968). This is the FIRST surface on the platform that discloses a PRIVATE account, and its audience is deliberately NOT the directory's. WHY A RANK GATE AND NOT THE RECRUITING DOOR ABOVE. Spec D3 gates this read on `project.recruit`, an atom whose declared shape is FLOOR ARCHON, widenable per instance (spec D1). That atom does not exist — ADR 0201 D3 and ADR 0210 both refuse to mint it outside the project-admin-console wave that defines it (spike 1002786 R3), and this task does not either. The directory's door (`project.curate` at metic, OR any project owner — ADR 0210 D2) is WIDER than the signed floor on both halves, so adopting it here would widen an owner-signed privacy decision by implementation convenience. Until the atom lands, the honest reading of D3 is its floor, held by rank. Whether the wider recruiting audience is authorized for this surface is the owner's call and is filed as a blocker, NOT resolved here; when it is answered, this one line moves and nothing else does. 404, never 403, for a builder who is not recruiter-reachable: a 403 would confirm the handle exists, which is the disclosure the opt-out removes. The sliver's own predicate does the deciding, inside the module.\n\n**Rank:** `archon` — Archon only (rank and identity management + the escalation keys — the trust boundary).",
|
|
12100
|
+
"x-rank": "archon",
|
|
12101
|
+
"x-source": "modules/platform-identity/routes/scouting.js",
|
|
12102
|
+
"parameters": [
|
|
12103
|
+
{
|
|
12104
|
+
"name": "handle",
|
|
12105
|
+
"in": "path",
|
|
12106
|
+
"required": true,
|
|
12107
|
+
"schema": {
|
|
12108
|
+
"type": "string"
|
|
12109
|
+
},
|
|
12110
|
+
"description": "Path parameter `handle`."
|
|
12111
|
+
}
|
|
12112
|
+
],
|
|
12113
|
+
"responses": {
|
|
12114
|
+
"200": {
|
|
12115
|
+
"description": "Success.",
|
|
12116
|
+
"content": {
|
|
12117
|
+
"application/json": {
|
|
12118
|
+
"schema": {
|
|
12119
|
+
"$ref": "#/components/schemas/GetScoutingHandleResponse"
|
|
12120
|
+
}
|
|
12121
|
+
}
|
|
12122
|
+
}
|
|
12123
|
+
},
|
|
12124
|
+
"400": {
|
|
12125
|
+
"$ref": "#/components/responses/BadRequest"
|
|
12126
|
+
},
|
|
12127
|
+
"401": {
|
|
12128
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
12129
|
+
},
|
|
12130
|
+
"403": {
|
|
12131
|
+
"$ref": "#/components/responses/Forbidden"
|
|
12132
|
+
},
|
|
12133
|
+
"404": {
|
|
12134
|
+
"$ref": "#/components/responses/NotFound"
|
|
12135
|
+
}
|
|
12136
|
+
},
|
|
12137
|
+
"security": [
|
|
12138
|
+
{
|
|
12139
|
+
"builderSession": []
|
|
12140
|
+
}
|
|
12141
|
+
]
|
|
12142
|
+
}
|
|
12143
|
+
},
|
|
12092
12144
|
"/search": {
|
|
12093
12145
|
"post": {
|
|
12094
12146
|
"operationId": "post_search",
|
|
@@ -16606,11 +16658,13 @@
|
|
|
16606
16658
|
"type": "boolean"
|
|
16607
16659
|
},
|
|
16608
16660
|
"settings": {},
|
|
16661
|
+
"planet": {},
|
|
16609
16662
|
"options": {}
|
|
16610
16663
|
},
|
|
16611
16664
|
"required": [
|
|
16612
16665
|
"ok",
|
|
16613
16666
|
"settings",
|
|
16667
|
+
"planet",
|
|
16614
16668
|
"options"
|
|
16615
16669
|
]
|
|
16616
16670
|
},
|
|
@@ -16802,6 +16856,15 @@
|
|
|
16802
16856
|
"page"
|
|
16803
16857
|
]
|
|
16804
16858
|
},
|
|
16859
|
+
"GetScoutingHandleResponse": {
|
|
16860
|
+
"type": "object",
|
|
16861
|
+
"properties": {
|
|
16862
|
+
"sliver": {}
|
|
16863
|
+
},
|
|
16864
|
+
"required": [
|
|
16865
|
+
"sliver"
|
|
16866
|
+
]
|
|
16867
|
+
},
|
|
16805
16868
|
"GetScoutingResponse": {
|
|
16806
16869
|
"type": "object",
|
|
16807
16870
|
"properties": {
|
|
@@ -17576,6 +17639,12 @@
|
|
|
17576
17639
|
},
|
|
17577
17640
|
"joinability": {
|
|
17578
17641
|
"type": "string"
|
|
17642
|
+
},
|
|
17643
|
+
"planet_template": {
|
|
17644
|
+
"type": "string"
|
|
17645
|
+
},
|
|
17646
|
+
"planet_accent": {
|
|
17647
|
+
"type": "string"
|
|
17579
17648
|
}
|
|
17580
17649
|
},
|
|
17581
17650
|
"additionalProperties": false
|
|
@@ -17587,11 +17656,13 @@
|
|
|
17587
17656
|
"type": "boolean"
|
|
17588
17657
|
},
|
|
17589
17658
|
"saved": {},
|
|
17659
|
+
"planet": {},
|
|
17590
17660
|
"push": {}
|
|
17591
17661
|
},
|
|
17592
17662
|
"required": [
|
|
17593
17663
|
"ok",
|
|
17594
17664
|
"saved",
|
|
17665
|
+
"planet",
|
|
17595
17666
|
"push"
|
|
17596
17667
|
]
|
|
17597
17668
|
},
|
|
@@ -21366,9 +21437,9 @@
|
|
|
21366
21437
|
"description": "A required dependency/feature is not configured or is temporarily down."
|
|
21367
21438
|
}
|
|
21368
21439
|
},
|
|
21369
|
-
"x-endpoint-count":
|
|
21370
|
-
"x-schema-count":
|
|
21440
|
+
"x-endpoint-count": 339,
|
|
21441
|
+
"x-schema-count": 375,
|
|
21371
21442
|
"x-undocumented-bodies": 9,
|
|
21372
|
-
"x-response-schemas":
|
|
21443
|
+
"x-response-schemas": 255,
|
|
21373
21444
|
"x-generated-by": "scripts/gds/gen-api-docs.js"
|
|
21374
21445
|
}
|
package/docs/api-reference.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Bongos API reference
|
|
4
4
|
|
|
5
|
-
> **Generated from the live route files** — the route file is authoritative.
|
|
5
|
+
> **Generated from the live route files** — the route file is authoritative. 339 endpoints across 54 route files.
|
|
6
6
|
> Machine-readable spec: [`docs/api/openapi.json`](api/openapi.json) (OpenAPI 3.1). Rendered docs site: **`/docs`** (e.g. `cloudbongos.com/docs`).
|
|
7
7
|
|
|
8
8
|
Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/<redacted>.md)): `public` < `any-builder` < `metic+archon` < `archon`.
|
|
@@ -455,7 +455,7 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/<redacted>
|
|
|
455
455
|
| POST | `/api/bongos/provisioning/instances/:id/github-app` | `any-builder` | `account` | POST /provisioning/instances/:id/github-app — mint a GitHub-App-Manifest onboarding link for the caller's OWN instance (task 2080, ADR 01… |
|
|
456
456
|
| POST | `/api/bongos/provisioning/instances/:id/restart` | `any-builder` | — | POST /provisioning/instances/:id/restart — restart an ACTIVE project the heartbeat cannot reach (task 1003238). |
|
|
457
457
|
| GET | `/api/bongos/provisioning/instances/:id/settings` | `any-builder` | — | GET /provisioning/instances/:id/settings — read a project's effective settings + the allowed values (so a form can render its choices). |
|
|
458
|
-
| PATCH | `/api/bongos/provisioning/instances/:id/settings` | `any-builder` | `platform_visibility`, `joinability` | PATCH /provisioning/instances/:id/settings — change a project's settings. |
|
|
458
|
+
| PATCH | `/api/bongos/provisioning/instances/:id/settings` | `any-builder` | `platform_visibility`, `joinability`, `planet_template`, `planet_accent` | PATCH /provisioning/instances/:id/settings — change a project's settings. |
|
|
459
459
|
| POST | `/api/bongos/provisioning/instances/:id/teardown` | `any-builder` | — | POST /provisioning/instances/:id/teardown — request teardown of the caller's OWN instance. |
|
|
460
460
|
| GET | `/api/bongos/provisioning/onboard-plan` | `public` | — | GET /provisioning/onboard-plan?mode=greenfield\|adopt&domain=<host> — the CANONICAL onboarding step sequence (task 2085; goal 35 / criteri… |
|
|
461
461
|
| GET | `/api/bongos/provisioning/slug-available` | `any-builder` | — | GET /provisioning/slug-available?slug=<handle> — is this handle free to create under? rank: any authenticated builder (same gate as the c… |
|
|
@@ -484,11 +484,12 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/<redacted>
|
|
|
484
484
|
| GET | `/api/bongos/public/uptime` | `public` | — | Uptime: current status + 90-day history bucketed by hour. |
|
|
485
485
|
| GET | `/api/bongos/public/versions` | `public` | — | read-only surface for the status dashboard (status.<apex>). |
|
|
486
486
|
|
|
487
|
-
## `scouting` (
|
|
487
|
+
## `scouting` (2)
|
|
488
488
|
|
|
489
489
|
| Method | Path | Rank | Body | Description |
|
|
490
490
|
|---|---|---|---|---|
|
|
491
491
|
| GET | `/api/bongos/scouting` | `metic+archon` | — | the internal talent directory across every project. |
|
|
492
|
+
| GET | `/api/bongos/scouting/:handle` | `archon` | — | the PRE-ACCEPT SLIVER for ONE builder (privacy spec D3, ADR 0215 D4, task 1002968). |
|
|
492
493
|
|
|
493
494
|
## `search` (2)
|
|
494
495
|
|