Repository navigation
fix(dev): start the git-token worker and seed the credential envelope keypairs - #8576
Conversation
The local web stack never started git-token-service, and a fresh `pnpm dev:setup-env` left the provider credential envelopes unconfigured. Both make every code-review read answer BAD_GATEWAY while the account still reports the provider as connected, so the PR review inbox and overview show a service outage with no rows. - `nextjs` depends on `cloudflare-git-token-service`, so the web stack starts the worker the review reads resolve credentials through. - `dev:setup-env` generates a local 4096-bit RSA keypair for each unconfigured envelope (GitHub user token, Bitbucket/GitLab platform credential) and writes the key ID plus both halves into `.env.local`; the existing passthrough copies the private halves into the worker's `.dev.vars`. A configured pair is kept as is, so a rerun never rotates a keypair the worker already stored credentials under, and a half-configured one is reported. - `.env.local.example` documents the two dev-only private-key slots, and `DEVELOPMENT.md` names both behaviors.
|
bot: Verified on the local stack with the Android dev client and the hermetic GitHub API stub, using an owned fake account and stub fixtures only. After deleting
|
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Executive SummaryThe follow-up commit resolves the earlier half-configured-envelope finding: every provisioning status now records its keypair in Assumptions: Files Reviewed (4 files)
Previous Review Summary (commit 14b2b77)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit 14b2b77)Status: 1 Issue Found | Recommendation: Address before merge Executive SummaryThe dev-stack wiring and keypair generation are sound, but Assumptions: Overview
Issue Details (click to expand)WARNING
Files Reviewed (7 files)
Reviewed by deepseek-flash-latest · Input: 41K · Output: 7K · Cached: 393.5K Review guidance: REVIEW.md from base branch |
The setup write path rebuilds `.env.local` from the example and writes back only the keys it collected, so an envelope whose half was configured outside that file was dropped: the warning said the values stayed while the write erased them, and the next `pnpm dev:env` emptied the Worker's copy too. Every provisioning status now records the pair it decided on, and the lookup skips empty slots, so a private half that lives only in the Worker's `.dev.vars` is read back into `.env.local` instead of being lost. An incomplete pair keeps exactly its own values and reports the gap.


What changed
The PR review inbox listed nothing and showed the generic load error whenever the local web stack was started the documented way, even with a connected GitHub account. Two dev-stack gaps produced that, and both are fixed here.
git-token-service.nextjshad no dependency on it, and the group is not always-on, sopnpm dev:startandpnpm dev:start core mobileleft port 8802 dead. Every code-review read and write resolves the caller's provider credential through that Worker (apps/web/src/lib/integrations/platforms/{github,gitlab,bitbucket}/,apps/web/src/lib/provider-review/), sogithubPrReview.listInboxansweredBAD_GATEWAY— "GitHub authorization is temporarily unavailable" — whilegithubApps.getUserAuthorizationstill reportedconnected: truefrom its own database read.nextjsnow depends oncloudflare-git-token-service, with the same reason comment the session-ingest dependency carries.pnpm dev:setup-envleft the credential envelopes unconfigured.USER_GITHUB_APP_TOKEN_ACTIVE_KEY_ID/_PUBLIC_KEYstayed empty and no private half existed, so even a running Worker answeredPOST /internal/github-user-authorizations/tokenwith 503 ("Active GitHub user-token private key is not configured"), and the dev GitHub token seed failed with 500 ("GitHub user token envelope encryption is not configured").dev:setup-envnow generates a local 4096-bit RSA keypair for each unconfigured envelope — the GitHub user-token one and the Bitbucket/GitLab platform-credential one — and writes the key ID plus the base64 SPKI public and base64 PKCS#8 private halves into.env.local; the existing passthrough copies the private halves into the Worker's.dev.vars, and the local Secrets Store picks up the Bitbucket key ID. Existing values are kept: the lookup reads.env.localfirst and the Worker's.dev.varssecond and skips empty slots, so a rerun neither rotates a keypair the Worker already stored credentials under nor drops a half that lives only in the Worker file, and every status records the pair it decided on so the file rebuild cannot erase it.Supporting changes:
.env.local.exampledocuments the two dev-only private-key slots and that setup generates the pairs, andDEVELOPMENT.mdstates that the dev stack starts the token Worker and what setup provisions.The mobile side needed no change:
classifyPrReviewQueryStatealready mapsFORBIDDENto the permission state,NOT_FOUNDto not-found,PRECONDITION_FAILED/UNAUTHORIZEDto reconnect andBAD_GATEWAYto the localized service-unavailable state, and the inbox renders the empty state when a provider answers with no rows.End-to-end evidence
Environment: this work VM, local dev stack on
localhost, Android emulatoromp36with the cachedmobile-native-android-e6da57a618c0776d1d5e04375263c56c9991422cdev client, Metro on 8081, and the hermetic GitHub API stub (apps/mobile/e2e/github-stub.sh) seeded with an owned fake account. No production data, no real provider credentials..env.localand ranCI=1 pnpm dev:setup-env --ci: it reported✓ Generated github-user-token-local-v1and✓ Generated platform-credential-local-v1and wrote the file.pnpm dev:start --no-attachwith no extra targets: the stack came up withcloudflare-git-token-service :8802 upinpnpm dev:status, without naming it on the command line.pnpm dev:env:mobileplus a stack restart served the app;services/git-token-service/.dev.varscarried all six envelope values.kiloapp:///pr-review): the INBOX listed the three stub pull requests (kilo-stub/discussion-mixed#1,kilo-stub/discussion-conversation-only#2,kilo-stub/discussion-empty#3) in organization scope, and the same three after switching the account sheet to Personal.user_github_app_tokens.revoked_at) and relaunched: the inbox showed the reconnect state with Check connection instead of a generic failure. Clearingrevoked_atand tapping Check connection opened a stub pull request; Back returned to an inbox that listed all three rows again..env.localbut still present inservices/git-token-service/.dev.vars(the layout that file documents), apnpm dev:setup-envrerun reported the envelope as incomplete and wrote the private half back into.env.localfrom the Worker file (PKCS#8 length 4364, unchanged hash); a second rerun reported the pair as kept and changed no value, and the Worker's.dev.varsstill held both private halves.Proof published in the comments below: the organization-scope inbox, and the personal-scope inbox after the reconnect round trip.
Unit checks:
pnpm exec tsx --test dev/local/envelope-keys.test.ts dev/local/services.test.tspasses (49 tests). Thedev/localsuite (dev/local/*.test.ts,dev/local/env-sync/*.test.ts,dev/local/scripts/*.test.ts,dev/seed/lib/*.test.ts) passes 417 tests; the only failure isdev/local/tmux.test.ts("decoy session must have an attached client"), which fails identically atmainin a clean worktree because the test needs an attached tmux client, so it is unrelated to this change.oxlintandoxfmt --checkare clean on every touched file.Not covered
.env.local.exampleslots are read only by local tooling.Proxy answers
The owner's proxy gave these answers in the owner's place.
pnpm dev:startnever starts git-token-service and a freshdev:setup-envleaves the GitHub user-token envelope keypair empty, so everygithubPrReview.listInboxread answers BAD_GATEWAY while the account still reads connected. Both reproduced here. Where should the fix land?Answer: Dev-stack wiring only (recommended)
Confidence: 0.77 · Precedent: Fix the root cause and the class of the issue: session 7f3470e0ba6f, "fix class of issue preventing progress"; least work with no drop in quality: session 00eb2a1d3e4b, "skip work that doesn't need to be done, do not redo work that was already done" (fix(mobile): surface review service outages with their own localized state #8100 already added the mobile states)
Answer: Generate into root .env.local (recommended)
Confidence: 0.80 · Precedent: Speed and least work: "do the least amount of work possible, with no drop in quality" (session 7f3470e0ba6f). This option reuses the existing passthrough and the NEXTAUTH_SECRET generation pattern.
Answer: Both tests (recommended)
Confidence: 0.70 · Precedent: Proof and verification: "we want to catch errors in PRs, as early as possible" (session 99e88001c4b4). Fix the class: "fix class of issue preventing progress" (session 7f3470e0ba6f).
Answer: Both envelopes
Confidence: 0.60 · Precedent: Fix the root cause and the class of the issue on every affected surface: session 00eb2a1d3e4b, "if anything repeats the same mistake over and over again, fix the class"; also session 89824a222897, "if you saw a gap, fix it"
Answer: Update DEVELOPMENT.md (recommended)
Confidence: 0.70 · Precedent: Trust the code over documents and update stale documents when you find them: session 05f959cc4baa, "if any of the docs are stale, we should update them"