feat(obs): apiHelpers on 5 more routes + drop "Commander" default name#168
Merged
operatoruplift merged 1 commit intomasterfrom Apr 27, 2026
Merged
feat(obs): apiHelpers on 5 more routes + drop "Commander" default name#168operatoruplift merged 1 commit intomasterfrom
operatoruplift merged 1 commit intomasterfrom
Conversation
Trust-gate coverage 16/44 -> 21/44, plus one more sci-fi cosplay
residual fixed.
## Routes adopting apiHelpers
| Route | Lines |
|---|---|
| app/api/gold/route.ts | 17 |
| app/api/risk/route.ts | 19 |
| app/api/auth/login/route.ts | 30 |
| app/api/auth/signup/route.ts | 36 |
| app/api/sns/resolve/route.ts | 35 |
Each adopts `withRequestMeta` for the X-Request-Id header. The two
auth routes plus risk also pick up `validationError()` for clean 400
responses with `{ missing: [...] }` details. Gold + risk pick up
`errorResponse()` for the 500 path.
## Drop "Commander" default name
`app/api/auth/signup/route.ts` was setting
data: { display_name: name || 'Commander' }
PR #163 already removed "Commander" from the dashboard h1 ("Good
{greeting}, Commander."), and #166 cleaned up the rest of the
sci-fi cosplay vocabulary. Signup was the last surface where a fresh
user got "Commander" as their default display name.
Now: derives a default from the email's local part (jane.doe@x.com
-> "jane.doe"), falling back to "Friend" if email is missing.
## Verified
- pnpm exec tsc --noEmit: clean
- pnpm check: 3 passed, 0 failed
- trust-gate: 21/44 route files (was 16/44)
## Rollback
Single git revert. 5 files.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
operatoruplift
added a commit
that referenced
this pull request
Apr 27, 2026
) Continuing the broadening from #167 / #168. Five more routes adopt the withRequestMeta / errorResponse / validationError pattern. | Route | Lines | Audience | |---|---|---| | app/api/waitlist/route.ts | 40 | Public signup | | app/api/access/check/route.ts | 52 | Beta access gate | | app/api/access/verify-payment/route.ts | 62 | On-chain payment confirm | | app/api/integrations/google/connect/route.ts | 65 | OAuth start | | app/api/integrations/google/callback/route.ts | 59 | OAuth complete | The two integrations routes are notable because they redirect to `/integrations?error=...` instead of returning JSON. Both now append `&ref=<requestId>` to the redirect URL so support can correlate the oauth-failure URL the user sees with the server log line, and `withRequestMeta` still attaches `X-Request-Id` to the redirect. The Google callback also gets a structured one-line JSON log on the error path (matching the shape `errorResponse()` would produce, but in-line because the response is a redirect, not a JSON envelope). ## Verified - pnpm exec tsc --noEmit: clean - pnpm check: 3 passed, 0 failed - trust-gate: 26/44 route files (was 21/44) ## Rollback Single git revert. 5 files.
operatoruplift
added a commit
that referenced
this pull request
Apr 27, 2026
) Continuing the broadening from #167 / #168 / #169. Four more routes adopt the withRequestMeta / errorResponse / validationError pattern. | Route | What it does | |---|---| | app/api/profile/briefing/route.ts (GET + PUT) | Daily-briefing toggle on Profile | | app/api/tools/notes/route.ts | Tier-1 notes tool (Supabase) | | app/api/tools/tasks/route.ts | Tier-1 tasks tool (Supabase) | | app/api/tools/imessage/route.ts | Photon iMessage send | The four /api/tools/* routes already had a clean honest-status flow (503 + action_required when an adapter is inactive, no fake success on demo callers); this PR adds the X-Request-Id + structured error envelope on top so the diagnostic line in CI logs and the response header agree on the request identifier. The imessage route's adapter-not-configured response now also carries the canonical fields (errorClass: 'provider_unavailable', requestId, timestamp, nextAction) so the chat UI can render it the same way it renders calendar/gmail provider errors. ## Verified - pnpm exec tsc --noEmit: clean - pnpm check: 3 passed, 0 failed - trust-gate: 30/44 route files (was 26/44) ## Rollback Single git revert. 4 files.
operatoruplift
added a commit
that referenced
this pull request
Apr 27, 2026
Locks in the plain-English voice and removed-feature-claim guarantees shipped across PRs #147-#168. If a future PR drifts back toward dev or sci-fi vocabulary, CI fails before merge. ## tests/e2e/consumer-copy.spec.ts (new) Six scoped specs, each asserts BOTH the new consumer phrasing IS present AND the retired developer/jargon phrasing is absent. | Test | Surface | Asserts | |---|---|---| | homepage hero | / | "stay in charge" + "Try it free" present | | navbar labels | / | "HOW IT WORKS / HELPERS / WATCH DEMO" present | | /paywall | /paywall | "Drafts your replies" + "Pick a plan" present | | /store | /store | h1 "Helpers", "Free in beta", "Install" button | | /pricing | /pricing | "Pricing for teams" + "Personal plans start free" | | OG metadata | / | meta description leads with daily job | Each test also runs `assertNoBannedPhrases()` against the rendered DOM text. The banned list covers: - Sci-fi cosplay: Commander, Uplift Core, Warp Network, Blackwall, CodePilot Pro, Founder Ops, Gold Agent, DeepRepo Orchestration - Dev jargon: Multi-agent orchestration, AI Operating System, On-chain Merkle audit trail, agent orchestration, Self-Hosted - Council fabrication: LLM Council, 5 agents debate, Chairman, Contrarian, First Principles thinker, Expansionist, Outsider Plus the existing chat-honesty.spec.ts (which already covered /chat + /paywall + /swarm against the council list) is now unconditionally part of the CI hermetic spec set. ## .github/workflows/ci.yml Both consumer-copy.spec.ts and chat-honesty.spec.ts are added to the hermetic Playwright run. Both can fail the PR check. ## Verified - pnpm exec tsc --noEmit: clean - pnpm check: 3 passed, 0 failed - pnpm exec playwright test consumer-copy.spec.ts: 6 passed (30.3s) ## Rollback Single git revert. 2 files.
operatoruplift
added a commit
that referenced
this pull request
Apr 28, 2026
…s) (#186) The /settings page had a 17-line useEffect that read localStorage at mount and called 7 separate setStates. Replaced with a single useMemo lazy load + lazy-initializer useStates that pull from it. The theme effect stays as a real DOM side effect (sets data-theme on <html>), but it now only reacts to `theme` state changes - no synchronous setState in the effect body. The 'Commander' default display name (last sci-fi cosplay residual, post-#163/#168) became 'Friend'. AdvancedSettings inner panel had its own setState-in-effect that read advanced_mode from localStorage. Hoisted to a lazy initializer the same way. | Change | File:line | |---|---| | 7-setState mount effect → useMemo + lazy initializers | settings/page.tsx:38-56 | | 'Commander' default → 'Friend' | settings/page.tsx:23 | | AdvancedSettings setAdvancedMode in effect → lazy initializer | settings/page.tsx:412-417 | ## Verified - pnpm exec tsc --noEmit: clean - pnpm check: 3 passed, 0 failed - pnpm lint: 85 problems / 19 errors (was 87 / 21) ## Rollback Single git revert.
operatoruplift
added a commit
that referenced
this pull request
Apr 28, 2026
The README was last updated before the consumer-copy sweep (PRs #152-#168), so it still: - Used "Your Life, Automated." tagline (retired) - Called the product "a local-first AI agent operating system" ("AI Operating System" is on the banned-phrases list, #158) - Pitched "Multi-agent swarms" / "Agent marketplace" (retired in #156, #154) - Had only the boilerplate Next.js create-next-app text below the header, no project-specific guidance Now reads in the same voice as the homepage: "AI for your inbox and calendar. You stay in charge." Adds: - Project-layout section (app/, src/sections/, src/components/, lib/, tests/e2e/) - CI checks summary (the 11 hermetic specs that block PRs) - Mention of the honesty regression tests that lock in PRs #147-#185 The banned-phrase grep on README is now clean except for the line that explicitly DOCUMENTS what those tests guard against, which is fine. ## Verified - pnpm exec tsc --noEmit: clean - pnpm check: 3 passed, 0 failed - README banned-vocab grep: only matches the "tests guard against" line ## Rollback Single git revert.
operatoruplift
added a commit
that referenced
this pull request
Apr 28, 2026
…#188) The sitemap was missing three public consumer surfaces that PRs #152-#168 rewrote into shape: - /store - the helpers store landing page (#154) - /docs - the in-repo /docs help site (#158 metadata + nav rename) - /press-kit - the press kit + media-resources page Search engines couldn't discover them, so the consumer pitch on those pages wasn't being indexed. Also: - Hosts the URL prefix in a HOST const so future entries can't drift - Bumps homepage changeFrequency from `yearly` to `weekly` to match reality (the consumer copy + OG image have shipped repeatedly) - Adds a comment block explaining the priority ordering ## Verified - pnpm exec tsc --noEmit: clean - pnpm check: 3 passed, 0 failed - After deploy, /sitemap.xml will list 10 URLs (was 7) ## Rollback Single git revert.
operatoruplift
added a commit
that referenced
this pull request
Apr 28, 2026
…190) Last residual of the dev-jargon vocabulary that #152-#168 retired. Four user-visible surfaces still said "Local-first": | File | Surface | Was -> Now | |---|---|---| | app/layout.tsx (JSON-LD) | Google search snippet description | "Local-first AI agent platform with secure, private memory. Build, deploy, and monetize autonomous agents, no cloud required." -> "AI assistant that drafts your email, schedules your meetings, and sends your follow-ups. Runs on your computer; every action waits for your tap." | | src/sections/CloudVsLocal.tsx | Homepage column subhead | "Local-first, your infrastructure" -> "Runs on your computer" | | app/(auth)/login/page.tsx | Login footer pill row | "Local-first / Privacy-first / On-chain" -> "Your computer / Encrypted / Signed receipts" | | app/(auth)/signup/page.tsx | Signup footer pill row | "Local-first / Privacy-first / Open source" -> "Your computer / Encrypted / Open source" | The JSON-LD fix is the most impactful, that's what Google reads to generate the search-result snippet. Replacing "DeveloperApplication" with "ProductivityApplication" in the same blob also matches the audience the rest of the site now targets. Editorial blog content (`app/blog/[id]/page.tsx`) stays unchanged, that's the writer's voice describing past decisions, not marketing claims. Same policy as #153. The slug `'local-first-threat-model'` in `app/blog/page.tsx` stays since it's a URL identifier; renaming would 404 any inbound link. ## Verified - pnpm exec tsc --noEmit: clean - pnpm check: 3 passed, 0 failed - grep "Local-first" outside app/blog returns 0 hits ## Rollback Single git revert. 4 files.
operatoruplift
added a commit
that referenced
this pull request
Apr 28, 2026
PR #168 retired the "Commander" default in /api/auth/signup. PR #186 retired it in /settings page. But four more places still stamped "Commander" on a fresh user's account: | File | Surface | |---|---| | app/(auth)/signup/page.tsx:35 | localStorage 'user' write after Supabase signup | | app/(auth)/login/page.tsx:60 | userName fallback after Privy login | | app/(auth)/login/page.tsx:165 | localStorage 'user' write after wallet payment | | app/(dashboard)/profile/page.tsx:11 | initial useState for the profile page | | app/(dashboard)/onboarding/page.tsx:43 | onboarding's saved user.name | Each now derives a default from the email's local part (jane@x.com -> "jane") or falls back to "Friend" -- matching the pattern set in #168. The two comment hits left in the repo (chat/page.tsx + the auth/signup route) explicitly DOCUMENT what was retired and stay. After this merges: grep -rnE "'Commander'" app/ src/ returns zero non-comment hits. ## Verified - pnpm exec tsc --noEmit: clean - pnpm check: 3 passed, 0 failed - Banned-vocab grep: 0 user-facing hits ## Rollback Single git revert. 4 files.
operatoruplift
added a commit
that referenced
this pull request
Apr 28, 2026
… pages (#192) Two new specs added to consumer-copy.spec.ts so the post-#190/#191 state can't drift back. ## "JSON-LD structured data uses the consumer pitch" PR #190 rewrote the schema.org SoftwareApplication description blob that Google reads for rich-result snippets. The old text was: "Local-first AI agent platform with secure, private memory. Build, deploy, and monetize autonomous agents, no cloud required." Now the test: - Asserts the new "drafts your email" pitch IS in the JSON-LD - Asserts the old "Local-first AI agent platform" + "autonomous agents" strings are NOT ## "/login + /signup auth pages do not show 'Commander'" PRs #168, #186, and #191 retired "Commander" across the API + 5 client surfaces. The auth pages are the funnel where a fresh user landed - this spec verifies neither /login nor /signup ever shows the word, and also verifies "Local-first" stays out (the auth footer pill rows used to say it; #190 fixed that). ## Verified - pnpm exec tsc --noEmit: clean - pnpm exec playwright test consumer-copy.spec.ts: 8 passed (37.3s) ## Rollback Single git revert. One file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Trust-gate coverage 16/44 → 21/44
Continuing the broadening from #167. Five more routes adopt the
withRequestMeta/errorResponse/validationErrorpattern.app/api/gold/route.tsapp/api/risk/route.tsapp/api/auth/login/route.tsapp/api/auth/signup/route.tsapp/api/sns/resolve/route.ts.soldomain resolutionEach adopts
withRequestMetafor theX-Request-Idheader. The two auth routes plus risk also pick upvalidationError()for clean 400 responses with{ missing: [...] }details. Gold + risk pick uperrorResponse()for the 500 path.Auth routes are the entry point for every signed-in session, so getting them on the same request-id contract is high value for support diagnostics.
Bonus: drop "Commander" default name
app/api/auth/signup/route.tswas setting:PR #163 already removed "Commander" from the dashboard h1 ("Good {greeting}, Commander."). PR #166 cleaned up the rest of the sci-fi cosplay vocabulary. Signup was the last surface where a fresh user got "Commander" as their default display name.
Now: derives a default from the email's local part (
jane.doe@x.com→"jane.doe"), falling back to"Friend"if email is missing.Verified
Net diff
Rollback
Single
git revert.