feat(deploy): Phase-1 signed-out go-live for agentculture.org/learn#6
Conversation
Cut over the signed-out learning experience to production, same-origin at agentculture.org/learn: - Deployed Cloudflare Pages project `agentculture-learn` (the built site-astro/ tree wrapped under /learn/). - Deployed the learn-api Worker as a proxy owning the `agentculture.org/learn/*` zone route: /learn/api/* handled by the worker (401 without a session, zero inference), everything else reverse-proxied to the Pages origin. No KV/D1/secrets — the signed-out tier touches no storage. - Verified 38/38 by `LIVE_ORIGIN=https://agentculture.org` launch gate (signed-out phone+desktop walk against the deployed site). Fixes a real config trap and documents the phased rollout: - wrangler.toml: `routes` moved ABOVE [vars]. Under [vars], TOML scoped it as vars.routes and wrangler silently bound no route ("No targets deployed"). Vars/PAGES_ORIGIN now filled from the live deploy. - Add wrangler.signedout.toml — the committed Phase-1 config. - README: two-phase go-live table + the exact token permissions each phase needs (Pages+Workers Scripts now; +KV+D1 for signed-in). - .gitignore: repo-root .wrangler/ (wrangler pages deploy scratch). Phase 2 (signed-in) remains: broaden the token with Workers KV + D1, create the GitHub OAuth app, deploy the full wrangler.toml. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jkvh4uxSi6AsBJYPjiurze
|
/agentic_review |
PR Summary by QodoGo-live signed-out /learn via Cloudflare Worker proxy + phase docs
AI Description
Diagram
High-Level Assessment
Files changed (5)
|
|
Code Review by Qodo
Context used✅ Compliance rules (platform):
9 rules 1. OAuth callback missing /learn
|
| routes = [ | ||
| { pattern = "agentculture.org/learn/*", zone_name = "agentculture.org" }, | ||
| { pattern = "agentculture.org/learn", zone_name = "agentculture.org" }, | ||
| ] |
There was a problem hiding this comment.
1. Oauth callback missing /learn 🐞 Bug ≡ Correctness
With the worker now bound only on the /learn route, handleLogin() still generates the GitHub redirect_uri as https://agentculture.org/api/auth/callback (no /learn), so the OAuth callback will land outside this worker and the web login flow cannot complete.
Agent Prompt
## Issue description
The worker is now mounted at `agentculture.org/learn/*`, but `handleLogin()` constructs the GitHub OAuth `redirect_uri` at `/api/auth/callback` (no `/learn` prefix). This will cause GitHub to redirect to a path that does not hit this Worker route.
## Issue Context
- Requests arrive as `/learn/api/auth/login`, but the router strips `/learn` only for internal dispatch.
- GitHub must be configured to call back into the mounted worker path: `/learn/api/auth/callback`.
## Fix Focus Areas
- workers/learn-api/src/index.js[63-79]
- workers/learn-api/src/index.js[125-133]
- workers/learn-api/src/index.js[310-312]
- workers/learn-api/README.md[97-104]
## Notes
Implement a mount-aware callback builder, e.g. derive a `mountPrefix` from the incoming request pathname (`/learn` when mounted) and build:
- `redirectUri = `${publicOrigin(env,url)}${mountPrefix}/api/auth/callback``
Then ensure README and GitHub OAuth app config remain aligned.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| [vars] | ||
| # Placeholder client id: harmless in phase 1. The sign-in button is only | ||
| # reachable by direct navigation (org's Learn nav link is held until phase 2), | ||
| # so a non-functional OAuth start has no public surface yet. | ||
| GITHUB_CLIENT_ID = "REPLACE_ME_github_oauth_client_id" | ||
| PUBLIC_URL = "https://agentculture.org" |
There was a problem hiding this comment.
2. Signed-out config hits github 🐞 Bug ☼ Reliability
wrangler.signedout.toml sets a non-empty placeholder GITHUB_CLIENT_ID, so phase-1 deployments will still allow direct requests to /learn/api/auth/login and /learn/api/auth/device which attempt GitHub OAuth/device-flow network calls instead of being cleanly disabled.
Agent Prompt
## Issue description
Phase-1 (signed-out) config includes a placeholder `GITHUB_CLIENT_ID`, which keeps the public auth endpoints callable and triggers outbound GitHub requests if hit directly.
## Issue Context
Even if the UI link is withheld, these endpoints remain reachable by URL and can create noisy failures and unexpected external traffic in the signed-out tier.
## Fix Focus Areas
- workers/learn-api/wrangler.signedout.toml[31-40]
- workers/learn-api/src/index.js[125-188]
- workers/learn-api/src/github.js[25-35]
- workers/learn-api/src/github.js[79-90]
## Notes
Preferred low-effort fix: remove `GITHUB_CLIENT_ID` from `wrangler.signedout.toml` (or set it empty) so `requireConfig()` returns a controlled 503 and no outbound GitHub calls occur.
Alternative: add a phase flag (e.g. `SIGNED_OUT=1`) and have the router return 401/404 for `/api/auth/*` and `/api/health` as desired in phase 1.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| PUBLIC_URL = "https://agentculture.org" # origin used to build the OAuth callback | ||
| APP_URL = "https://agentculture.org/learn/" # where the web callback redirects post-login | ||
| CORS_ORIGIN = "https://agentculture.org" # allow the /learn site to call the API with creds | ||
| PAGES_ORIGIN = "https://agentculture-learn.pages.dev" # static-site origin the /learn zone mount proxies to |
There was a problem hiding this comment.
3. Prod vars hinder wrangler dev 🐞 Bug ⚙ Maintainability
wrangler.toml now hard-codes PUBLIC_URL/APP_URL/CORS_ORIGIN to production, so wrangler dev will emit production OAuth redirect URIs and CORS headers (breaking localhost auth/browser testing) unless developers override these vars.
Agent Prompt
## Issue description
Production defaults for `PUBLIC_URL`, `APP_URL`, and `CORS_ORIGIN` in `wrangler.toml` make local `wrangler dev` behave like production (wrong OAuth redirect URIs and CORS allow-origin), which is error-prone for contributors.
## Issue Context
README directs developers to use `wrangler.toml` for `wrangler dev`, and the runtime code prefers these env vars over the request origin.
## Fix Focus Areas
- workers/learn-api/wrangler.toml[33-46]
- workers/learn-api/README.md[64-66]
- workers/learn-api/src/index.js[125-133]
- workers/learn-api/src/index.js[322-335]
## Notes
Options:
1) Add a `wrangler.dev.toml` (or `wrangler.local.toml`) with localhost values and document `wrangler dev -c wrangler.dev.toml`.
2) Document explicitly that `.dev.vars` should also override these non-secret vars for local runs.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



What this is
The signed-out learning experience is now live in production at
https://agentculture.org/learn/ — same-origin, org's design system, no
whole-site reload. This PR records the deploy and fixes the one real config
bug the cutover surfaced.
Deployed with the repo's
.envCloudflare token (Pages: Edit + WorkersScripts: Edit):
agentculture-learn— the builtsite-astro/tree wrapped under
/learn/.agentculture.org/learn/*zoneroute.
/learn/api/*is handled by the worker (returns401without asession, zero inference); every other path reverse-proxies to the Pages
origin. No KV, no D1, no secrets — the signed-out tier touches no storage.
Verification
LIVE_ORIGIN=https://agentculture.org bash tools/launch-gate/run.sh-> 38/38 PASS,including the production signed-out walk (phone + desktop) asserting a story
page fires only
GET /learn/api/me. Rootagentculture.org/is untouched(still org); the route is scoped strictly to
/learn/*. Worker node suite 39/39.Fix
wrangler.toml: theroutesarray was positioned after[vars], so TOMLscoped it as
vars.routesand wrangler silently bound no route ("Notargets deployed"). Moved it above
[vars]; filled the now-known vars(
PAGES_ORIGINetc.) from the live deploy. Addedwrangler.signedout.toml(the committed Phase-1 config) and a two-phase README with the exact token
permissions each phase requires.
Not in this PR — Phase 2 (signed-in), pending two operator credentials
Edit (the
.envtoken lacks both — proven bycode: 10000onkv namespace create/d1 create). Then I can provision KV + D1 anddeploy the full
wrangler.tomlautonomously.https://agentculture.org/learn/api/auth/callback) — no GitHub API createsOAuth apps, so this is UI-only. Its client id + secret light up sign-in.
org's Learn-nav link (org PR #8) stays held until Phase 2, so
/learnhas nopublic inbound link yet — the incomplete sign-in button has no surface.