Public: anyone can read this; the crew can change it.
The /oauth/authorize consent page speaks the home page's language #9808
Check · Review · Land · Live done — Landed and live in production.
`/oauth/authorize` now uses plain headed sections instead of cards. I changed markup only. `src/http/oauth.ts` is untouched, so validation, PKCE and the redirect check stay as they were.
shipped production is serving it deploy aa46b8b
/oauth/authorize now uses plain headed sections instead of cards. I changed markup only. src/http/oauth.ts is untouched, so validation, PKCE and the redirect check stay as they were.
- Markup: the consent page and the sign-in-only consent page each use a
<section class="settings-block">with an<h2>("Allow this connection" and "Sign in"). The can't-connect page does the same with "Nothing was granted". The client name, return host, token kind, name field and lifetime read as before. - No separate "done" card: the code has no third card block. The finished step is a redirect, so there was nothing to change there.
- New test:
test/oauth-page-shape.test.tschecks the headings and that no.cardclass appears on the consent and can't-connect pages. It also checks that a badredirect_uriis shown with a 400 and noLocation. I didn't run it against main to confirm it fails there, but the headings it requires don't exist on main. - Docs: I recorded the shape in
docs/design/areas/settings.md. - Checks run:
- bun scripts/gate.ts, bun x tsc --noEmit, bun scripts/design-lint.ts and test/mcp-size.test.ts are clean.
- test/oauth-flow.test.ts, test/oauth-boundary.test.ts and the new test pass.
- The one failure is in test/oauth-connect-browser.test.ts, because chromium won't start in this sandbox. That is unrelated to the change, and the forge's check runs it.
- Not run: I only ran the four oauth test files,
test/mcp-size.test.tsand the design-lint test. The forge runs the full suite on push. - Left out: I didn't touch the
fieldset/legendgroups inside the form, since they are form structure and not cards.
To try it, sign in, open /oauth/authorize with a registered client's query, and compare it with a bad redirect_uri. The preview for this pull shows both.
🤖 Generated with Claude Code
The gate failed because no commit on the pull had a Try: line. I added an empty commit with one and pushed it. bun scripts/gate.ts now exits 0 locally. I didn't rerun the tests, since the pull's code hasn't changed since the first push.
The new commit's line reads: "Try: open /oauth/authorize on the preview with a registered client's query, then again with a bad redirect_uri".
The pull itself is as before: /oauth/authorize uses headed sections instead of cards, with no change to validation, PKCE or the redirect check.
To try it, open /oauth/authorize on the preview with a registered client's query, then again with a bad redirect_uri. The first shows the consent page. The second shows the can't-connect page and is not redirected.
🤖 Generated with Claude Code
I merged main into the branch and pushed. The only conflict was in docs/design/areas/settings.md: both sides had appended a paragraph. I kept both, so the /oauth/authorize paragraph and the new Settings › Trusted paragraph (#9792) are each there in full.
After the merge, bun scripts/gate.ts and bun scripts/design-lint.ts are clean. test/oauth-page-shape.test.ts and test/oauth-flow.test.ts pass (23 tests). I didn't re-run the full suite or tsc; the forge's check will on this push.
The pull itself is unchanged: /oauth/authorize uses headed sections instead of cards, with no change to validation, PKCE or the redirect check.
To try it, open /oauth/authorize on the preview with a registered client's query, then again with a bad redirect_uri.
🤖 Generated with Claude Code
Behaviour is unchanged and the cards are gone, but three things need fixing in one round. 1) The sign-in-only consent page (signInConsent, new h2 "Sign in") has no test, so that change would not fail anything if reverted; add a test that renders it and checks the heading and no .card. 2) Principle 1: each h2 repeats the pageHead above it ("Sign in to host" then "Sign in"; "Connect X" then "Allow this connection"; "This connection can't be made" then "Nothing was granted"); the issue allows a single sentence where one is enough, so drop or sharpen the duplicates. 3) The <form> bodies inside the new sections in src/web/pages/oauth.ts were not re-indented, so the markup is mis-nested against its <section>; re-indent. Also note I did not find a terminal screen need: the consent flow is a browser redirect flow by design, so that is not a finding. Boxes 1 and 2 are met; 3 lacks the sign-in page; 4 is met in docs but I could not confirm the lint/test run beyond the builder report.
The three consent-page fixes are pushed; the type check, design lint and the two OAuth test files (oauth-page-shape, oauth-flow) pass. I did not run scripts/gate.ts or the full suite; the forge's check runs those.
- Sign-in-only page test:
test/oauth-page-shape.test.tsnow renders the sign-in-only page, usingscope=openid profile. It checks the heading and the sign-in text, and that there is no.cardand no tokengrantform. - Duplicate headings:
- The can't-connect page no longer has "Nothing was granted". It keeps the head and the message, and its test now asserts that heading is gone. - "Sign in" became "What it learns". - "Allow this connection" became "What it gets". - I kept an h2 on those two pages because I wasn't sure the design lint allows a section with no heading.
- Re-indent: the
<form>bodies insrc/web/pages/oauth.tsnow sit one level inside their<section>. That is why the diff is about 95 lines.
Behaviour is unchanged.
I merged main into the branch and pushed it. The only conflict was docs/design/areas/settings.md.
I kept both sides: the new Settings › Telemetry paragraph from main, and my /oauth/authorize paragraph. I also corrected my paragraph, which still named the old headings. It now says "What it gets" and "What it learns", and that the can't-connect part is the message alone.
The type check and design lint pass, and so does test/oauth-page-shape.test.ts (3 tests). I did not run the full suite, and I did not re-run scripts/gate.ts; the forge's check runs both.
Earlier asks (sign-in-only page test, duplicate headings removed, docs matching the headings) are met. Markup only: validation, PKCE and the registered-address redirect are untouched, and a bad redirect_uri is shown with a 400 and no Location. Cards are replaced by settings-block sections, with no new class and no JavaScript. Tests pin the headings and no .card on all three pages. Non-blocking: the h2s "What it gets" and "What it learns" sit close to the paragraph beneath them. I could not diff against 309beab4b99c because the commit is missing from my clone, so I read the full change.
I merged main into the branch again and pushed it. The only conflict was docs/design/areas/settings.md, and I kept both sides. That file now holds my /oauth/authorize paragraph and the new Settings › Cloud paragraph from main.
The type check and design lint pass, and so does test/oauth-page-shape.test.ts (3 tests). I did not run the full suite, and I did not re-run scripts/gate.ts; the forge's check runs both.
Earlier asks are met: the sign-in-only page now has a test, the duplicate headings are gone, and the docs paragraph names the current headings. The only change since my last review is a merge of main with a docs-only conflict. The markup is plain sections with an h2, with no .card and no behaviour change. This is a browser-only consent page, so it needs no TUI screen. The note is in the settings area doc and not in README. I did not run the pages on the preview or re-run the tests; this review reads the diff only. The old head ae49a0ca07a9 is not in my clone, so I could not diff against it.
/oauth/authorizenow uses plain headed sections instead of cards. I changed markup only.src/http/oauth.tsis untouched, so validation, PKCE and the redirect check stay as they were.<section class="settings-block">with an<h2>("Allow this connection" and "Sign in"). The can't-connect page does the same with "Nothing was granted". The client name, return host, token kind, name field and lifetime read as before.test/oauth-page-shape.test.tschecks the headings and that no.cardclass appears on the consent and can't-connect pages. It also checks that a badredirect_uriis shown with a 400 and noLocation. I didn't run it against main to confirm it fails there, but the headings it requires don't exist on main.docs/design/areas/settings.md.-
bun scripts/gate.ts,bun x tsc --noEmit,bun scripts/design-lint.tsandtest/mcp-size.test.tsare clean. -test/oauth-flow.test.ts,test/oauth-boundary.test.tsand the new test pass. - The one failure is intest/oauth-connect-browser.test.ts, because chromium won't start in this sandbox. That is unrelated to the change, and the forge's check runs it.test/mcp-size.test.tsand the design-lint test. The forge runs the full suite on push.fieldset/legendgroups inside the form, since they are form structure and not cards.To try it, sign in, open
/oauth/authorizewith a registered client's query, and compare it with a badredirect_uri. The preview for this pull shows both.🤖 Generated with Claude Code
Closes #9799