Skip to content

docs: rule on the account surface once, in the glossary - #111

Merged
os-elon merged 2 commits into
mainfrom
claude/issue-108-account-surface-ruling
Aug 18, 2026
Merged

docs: rule on the account surface once, in the glossary#111
os-elon merged 2 commits into
mainfrom
claude/issue-108-account-surface-ruling

Conversation

@os-elon

Copy link
Copy Markdown
Collaborator

Fixes#108

/_account/ was retired upstream when the standalone account-portal SPA was removed under ADR-0048. Six lines across four pages still documented it as a live HTTP surface; every one of those URLs returns 404. This PR carries three of the six. The other three are on content/docs/quickstart.mdx and belong to #94, which is held for this ruling — #94 remains open and is not addressed here.

The ruling, recorded once

Per the card, this is one answer to "what is the account surface now", written into the Surface entry in content/docs/resources/glossary.mdx, with the other two pages made to agree with it rather than restating it. Restating is what let these pages drift apart in the first place.

The account surface is not a surface. There are two HTTP entry points, not three: / (REST API) and /_console/ (the UI). Sign-in, registration and account self-service are routes inside the UI:

Account surfaceWhere it lives
Sign in/_console/login — where every protected page sends you when you are not signed in
Register/_console/register — unless the deployment disables self-service sign-up
Account self-service/_console/apps/account — the Account app, alongside Setup at /_console/apps/setup

How the evidence bar was met

裁决 3 forbids writing a /_console/login or /_console/register URL on the strength of a 200, because SPA fallback 200s everything under /_console/ (#94's zzz-nonexistent-garbage control). No probe was used here. Two independent sources, in two repos, compose to give the wire path:

1. The console router source (objectstack-ai/objectui@6c68b13, apps/console/src/App.tsx:139-140) — this is the first item on 裁决 3's list, and it is explicit that these routes are public:

/*
* Public auth surfaces — render OUTSIDE ProtectedRoute so
* unauthenticated visitors can reach them.
*/
Route path="/login" element={LoginPage}
Route path="/register" element={RegisterPage}

The same file resolves the React Router basename from an injected base href tag (App.tsx:69-95, resolveBasename), so these are basename-relative, not absolute.

2. The mount prefix, from the other repo (objectstack-ai/objectstack@f6c71ea, packages/cli/src/utils/console.ts) — CONSOLE_PATH = '/_console' at line 43, and lines 506-516 inject base href="/_console/" into the served index.html.

Basename /_console + router path /login gives the wire path /_console/login. Two sources that agree, neither of them a probe.

Corroborating detail from the same router source:

  • ProtectedRoute.tsx:26-30 (LoginRedirect) — an unauthenticated visitor to any protected route is sent to /login, router-relative. App.tsx:357-361 puts the console root / behind ProtectedRoute, so opening the UI unauthenticated lands the reader on sign-in. This is the redirect contract, read from source rather than traced.
  • App.tsx:340 declares Route path="/apps/:appName/*", which is what makes /_console/apps/account resolve.
  • Registration is conditional, which is why the glossary row is hedged: RegisterPage.tsx bounces to /login when the server reports emailPassword.disableSignUp === true, and calls the server-side gate the source of truth.

Half (a) of the card is confirmed as stated: packages/apps/account/src/index.ts says the standalone account-portal SPA was removed and Account is now a console navigation-shell app with package id com.objectstack.account. The premise held.

The three files

  • content/docs/resources/glossary.mdx — the Surface entry is the ruling. It now names two entry points and carries the table above. docs: retire "Console" as the end-user surface name; keep Setup for administration #100's entry was reusable as-is; only the third clause needed replacing, plus a closing sentence recording that /_account/ is retired and 404s, so a reader arriving from an old link is not left guessing. /_account/ survives on that one line as a retirement notice, which is the opposite of asserting the surface exists.
  • content/docs/index.mdx:52 — the Account row's dead URL parenthetical becomes a link to the ruling: **Account** ([inside the UI](/docs/resources/glossary#surface)). The row's value is its capability list, which is unchanged and still correct; only the URL was wrong. This is the page where pointing beats restating.
  • content/docs/build/marketplace.mdx:90/_account/register becomes /_console/register. This one restates the URL rather than linking, deliberately: it is step 2 of a numbered install flow, and a reader mid-install needs the URL in front of them, not a definition one click away. It agrees with the ruling by using the ruling's URL.

For #94 — apply verbatim, no re-derivation

#94 owns content/docs/quickstart.mdx:47, :59 and :152. The ruling above resolves all three:

:59 — the "What's running" table row. Replace:

| http://localhost:3000/_account/register | Create your first account |

with:

| http://localhost:3000/_console/register | Create your first account |

:47 and :152 — the two sample banner lines:

 ➜ Account: http://localhost:3000/_account/
➜ Account: http://localhost:3002/_account/

Delete both. They do not need a replacement URL, because the real CLI does not print an Account: line at all — #94's own measured boot transcript shows the banner printing API:, Console: and MCP: and nothing else. Repointing these two at /_console/apps/account would produce a correct URL in a fabricated banner line, on the one page whose entire subject is that the sample does not match reality. The 404 and the phantom banner line are two defects on the same lines, and deleting fixes both.

That also settles the related line #94's PM ruling flagged: quickstart.mdx:13, "Both produce a running server with the UI + Account", is false only in its implication that Account is a second server surface. Account is inside the UI.

Gates

Run on the tree at 632834f, which is this PR's head. The working tree was clean at commit time, so the tested tree and the committed tree are the same tree.

GateResult
pnpm install --frozen-lockfileexit 0
pnpm turbo run type-check --continue --concurrency=2 --forceexit 0 — cache bypass, force executing, 0 cached
pnpm turbo run build --concurrency=2 --forceexit 0 — 0 cached, 53.8s
check-translation-ownership.mjs --actor ... --files ...exit 0 — "0 translation artifact(s) and 3 other file(s)"
check-translations.mjsexit 0 — stale siblings reported, not blocking, per AGENTS.md
check-translation-output.mjs --self-testexit 0 — 20 cases, every rule demonstrated able to fail
check-translation-output.mjs --files ...exit 0 — 127 pre-existing findings reported, none from this diff

--force on both turbo tasks is deliberate, not belt-and-braces: content/docs/ sits outside the apps/docs package and AGENTS.md documents turbo replaying cached greens for content-only changes. Both runs report 0 cached, so these are real runs on this content, not a replayed green.

The gate list in my dispatch named check-translation-ownership.mjs and check-translation-output.mjs --report as bare invocations; both are wrong for a PR. --report is the push-to-main path, and the ownership gate exits 1 with "--files is required" when called bare. I re-derived the real invocations from .github/workflows/translations.yml (the gates live there, not in ci.yml) and ran the pull-request path.

Rendering verified from the build output, not assumed — a markdown table inside a glossary entry is new for that page:

  • apps/docs/.next/server/app/en/docs/resources/glossary.html renders a real table element in the Surface section and carries id="surface", so the citation anchor is live.
  • docs.html renders the index row's link as href="/docs/resources/glossary#surface".

Scope

English only. No locale sibling was touched — the ownership gate confirms 0 translation artifacts in the diff. No page is retired or renamed, so the locale-sibling deletion rule does not apply and stale siblings are reported-not-blocking by design. content/docs/quickstart.mdx is untouched.

Left in draft.


Generated by Claude Code

/_account/ was retired upstream when the standalone account-portal SPA was
removed (ADR-0048). Six lines across four pages still documented it as a live
HTTP surface; every one of those URLs 404s.
Record the replacement once, in the glossary Surface entry, and have the two
other pages in this PR's scope agree with it instead of restating it:
- resources/glossary.mdx — Surface now names two entry points, not three, and
carries the account routes as a table the other pages can cite.
- index.mdx:52 — the Account row points at the ruling rather than a dead URL.
- build/marketplace.mdx:90 — the install step's register URL is corrected.
quickstart.mdx's three occurrences are #94's and are deliberately untouched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Yaqu7kmKZM3tRPd9Y4xivo
@os-elon
os-elon marked this pull request as ready for review August 18, 2026 15:58
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

/_account/ is retired — four pages still send readers to a 404

2 participants

@os-elon@claude