@bongos/core 1.21.94 → 1.21.96

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.
@@ -59,7 +59,23 @@ This table replaces the blended flow's table below for every hub-side capability
59
59
  - **The trip.** "Connect GitHub ↗" posts the app manifest to GitHub. The manifest now carries a `setup_url` (the hub's `/provisioning/github-app/setup`). After the approval GitHub returns to the manifest callback, which waits until the runner has placed the app's keys and recorded its name, then sends the same tab straight to `github.com/apps/<app>/installations/new`. When GitHub will describe the repo to an anonymous caller (a public repo), the link is narrowed with `/permissions?suggested_target_id=<owner id>&repository_ids[]=<repo id>`, so the founder only has to confirm. After the install, GitHub sends them to the `setup_url` with the attempt's `state`, and that page hands them back to the checklist.
60
60
  - **The ticks are server facts, never clicks.** *Approve*: GitHub made the app and the runner placed its keys (the slug is recorded only after the placement write). *Install*: the runner asks GitHub `GET /repos/{owner}/{repo}/installation`, signed as the app with the app's own key. The `installation_id` GitHub appends to the `setup_url` is never trusted, because GitHub's docs warn it can be spoofed; it only makes the runner look again. *Builders can sign in*: the runner saw `auth_configured` on the project's `/api/bongos/healthz`. The root `/healthz` answers a plain "ok", and reading that one is why every setup used to be recorded as failed (task 1004577). *Command-line sign-in*: the runner starts a device sign-in with the app's client id, and GitHub does not refuse it with `device_flow_disabled`. The facts are rows in `provisioning_events`, so no new column was needed. The checklist is derived in `modules/provisioning/github-setup.js`; the runner's check is `scripts/gds/provision-github-setup.js`.
61
61
  - **Device flow cannot be switched on for the founder (spike, task 1004649).** GitHub's manifest parameters are `name`, `url`, `hook_attributes`, `redirect_url`, `callback_urls`, `setup_url`, `setup_on_update`, `request_oauth_on_install`, `public`, `default_permissions`, `default_events` and `description`, and none of them is device flow. The REST API for apps (`/app`, `/app/installations…`, `/app-manifests/{code}/conversions`) has no endpoint that changes an app's registration. GitHub's own guide says device flow has to be enabled in the app's settings first. So the fourth step is **optional**: it reads "Optional — turn it on later" with a link to the app's settings, ticks itself when the runner sees it on, and never holds back "connected" or "is alive". Web sign-in works without it, and the CLI falls back to a web token meanwhile (`scripts/gds/device-flow-help.js`).
62
- - **Left as seams for the sibling tasks.** The hand-back from any tab or device, and checking while the page is hidden (task 1004650). The page already re-learns the checklist from the owner's instance read (`github_setup`), and that read never carries the state token. A personal or an organisation account (task 1004651). Resuming a stopped step, and a fixing button for every failure, including "check again" after the runner's two-hour window (task 1004652).
62
+ - **Left as seams for the sibling tasks.** The hand-back from any tab or device, and checking while the page is hidden (task 1004650, built: see below). The page already re-learns the checklist from the owner's instance read (`github_setup`), and that read never carries the state token. A personal or an organisation account (task 1004651). Resuming a stopped step, and a fixing button for every failure, including "check again" after the runner's two-hour window (task 1004652).
63
+
64
+ ### Coming back from any tab or device, as built (task 1004650)
65
+
66
+ - **The server names the project.** The callback page and the setup page no longer send the founder to `/projects?view=new#ghstate=…` and trust the tab to know which project that was. They send them to `/api/bongos/provisioning/github-app/return?state=…`. That route looks the one-time state up, finds the project it was minted for, and, if the person signed in owns that project, sends them to `/projects?view=new&id=<project>#ghstate=…`. Nothing is read from browser storage, so approving on a phone, in another window or in a fresh tab lands on the right project at part 03.
67
+ - **Only the owner lands.** Not signed in: through the web sign-in and back to the same return. Signed in as anyone else, an unknown or malformed state, or a project that is gone: one page that names no project ("This isn't your project"), the same for each case. There is no Archon override here. The state is still used once where it matters: only the manifest callback's code exchange uses it up, and the return route changes nothing.
68
+ - **The page asks the server when its tab cannot say.** `GET /provisioning/github-app/resume?id=<project>` (signed in, own projects only) answers with what part 03 needs: id, slug, address, kind and repo. A hand-back named by the return route always opens that project's part 03. Without an id, the read names the founder's newest project whose GitHub checklist is not connected yet, if it was made or last tried within a week. Opening the create page later then reopens part 03 for it, unless the founder is typing a new project or clicked "New project" (then it is offered on the "still watching" line). "Start another project" sets it down for that tab. The hub's other views are unchanged.
69
+ - **The page keeps checking while hidden.** Both of part 03's polls (the state-keyed checklist and the owner's project read) keep going while the tab is hidden, every 20 seconds instead of every 4 to 5. When the tab is seen again, a waiting check runs at once. They still stop when the founder leaves the create view (C8).
70
+ - **Left for the sibling tasks.** A personal or an organisation account (task 1004651, built: see below). Picking up a stopped step, and a fixing button for every failure (task 1004652); the resume read already reopens part 03 for a failed attempt, which is where those buttons go.
71
+
72
+ ### A personal or an organisation account, as built (task 1004651)
73
+
74
+ - **Two choices, one picker.** Part 03 shows the mockup's "On my account" / "On an organisation" select beside Connect GitHub, while Connect is offered. Part 02's Code row has the same picker under the new repo's name ("Whose account"), so a new repo can be made under an organisation too. The founder's own account is the default in both, and it sends exactly what it always did: `{}` to mint the app, `{name}` to make the repo. Part 03 starts on the organisation the new repo went to, when it went to one.
75
+ - **The organisations come from GitHub.** `GET /github/orgs` lists them with whether the founder can make apps there. Only an organisation's owners can; one the founder only belongs to (or is still invited to) is listed with the reason and cannot be picked. "Another organisation…" opens a typed name with a **Check** button (`GET /github/orgs/<name>`).
76
+ - **The scope limit.** The hub's sign-in asks GitHub for `read:user repo`, not `read:org`, so GitHub may refuse to show the founder's memberships. Then the list falls back to the organisations the founder's repos sit in, with the role unknown, and the typed name is always there. A role GitHub did not give is said as such ("GitHub didn't tell us your role…"), never guessed, and GitHub's own page still refuses a non-owner. Asking for `read:org` at sign-in is the fix for a full list; it is `src/bongos/auth-config.js`'s call (a protected surface), so it was not made here.
77
+ - **The server checks the name, never the page's copy.** The mint route takes `{ account: 'org', org }`, checks the name against GitHub's login rules (letters, digits and single inner dashes, up to 39), and builds `github.com/organizations/<org>/settings/apps/new`. `account: 'org'` with no usable organisation is refused (`org_required`) rather than quietly made personal. The organisation is recorded as a `github-app-org` event, and the checklist reads give it back as `app_org`, so the app's settings link points at the organisation from any tab or device. The repo route makes the repo with `POST /orgs/{org}/repos`, private and empty like the personal one. GitHub's refusals come back as a 409 with the reason (the organisation restricts which apps may act for it; the founder may not create repos there; no such organisation), never as a 403, which the page reads as "sign in again".
78
+ - **The install follows the repo.** The install step already targets the repo's owner (the project's `target_ref`), so an organisation-owned repo installs there. Proof: `tests/github_org_account.mjs`.
63
79
 
64
80
  ### Who builds it
65
81
 
@@ -3025,5 +3025,9 @@ is load-bearing: the script throws rather than guess if it is missing, and
3025
3025
  landed since 1.21.92 with no explicit bump. run 37898035856. (task 1002620)
3026
3026
  1.21.94 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
3027
3027
  landed since 1.21.93 with no explicit bump. run 37901444360. (task 1002620)
3028
+ 1.21.95 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
3029
+ landed since 1.21.94 with no explicit bump. run 37907054923. (task 1002620)
3030
+ 1.21.96 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
3031
+ landed since 1.21.95 with no explicit bump. run 37914843597. (task 1002620)
3028
3032
  ---------------------------------------------------------------------------
3029
3033
  ```