Skip to content

docs(api): stop documenting a /graphql route the dispatcher removed - #10828

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-10710-graphql-residue-api-index
Aug 21, 2026
Merged

docs(api): stop documenting a /graphql route the dispatcher removed#10828
os-zhuang merged 1 commit into
mainfrom
claude/issue-10710-graphql-residue-api-index

Conversation

@claude

@claudeclaudeBot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Fixes#10710

content/docs/api/index.mdx documented GraphQL as a behaviour contract — a route that
exists and answers a specific status — and both halves were false. A reader following it
writes a client that handles a 501 from an endpoint that is not mounted at all.

The three facts, re-derived at this base (origin/main @ f4e5d916d6)

Claim on the pageWhat the tree says
register the IGraphQLService contractNo such symbol in packages/**/src. Repo-wide the only survivors are three CHANGELOGs, packages/spec/llms.txt:171, and the doc page itself.
/graphql returns 501Not mounted.packages/runtime/src/http-dispatcher.ts:2026 is the whole of it: // /graphql removed — GraphQL is not in the product plan (#2462 follow-on).
the route is wiredNo handleGraphQL in the runtime. The only hits are test doubles: packages/adapters/hono/src/__mocks__/runtime.ts:6, hono-wildcard-fallthrough.test.ts:37, hono.test.ts:10.

All three still held. Line numbers were unmoved; #10583's sweep has landed (that issue is
closed) and none of its five sites overlap these.

Remove, not rewrite — and what settled it

The card asked whether :172's table is genuinely a list of "mounted; nothing implements
it"
. It is, and packages/runtime/src/domains/unavailable.ts is the canonical statement
of the distinction the table's two rows encode:

  • The route is not there. … Asking for a path the server does not expose is a 404.
  • The route is there; the implementation is not. Every domain mounted unconditionally.
    The request reached a handler — it simply has nothing to delegate to. That is 501.

Every other entry in the 501 row has a domain module registered unconditionally at
http-dispatcher.ts:556-574createAutomationDomain, createNotificationsDomain,
createUiDomain, createAiDomain, createAuthDomain, createI18nDomain — each exiting
through capabilityUnavailable(). packages/runtime/src/domains/ai.ts:107 says it in
one line: "501, not 404: /ai/* IS mounted, so the request reached a handler with nothing
behind it."
There is no createGraphQLDomain.

So /graphql is in neither state and belongs in neither row — removing it is right and
rewriting it into the 501 list would be wrong. content/docs/permissions/authorization.mdx:53
already states the outcome in prose: "the dispatcher GraphQL endpoint left when the GraphQL
surface was removed (/graphql now 404s)"
.

The same reasoning removes the :19 row rather than rewriting it to "not available": a row
in a table headed "Status in this repo" still tells a reader GraphQL was a surface worth
listing on the API landing page, which is the false implication itself. Every other row
describes something the repo actually has (REST generated, Realtime as an in-process
service, MCP, OData vocabulary inside the REST list endpoints). GraphQL has no route, no
contract, and no vocabulary.

Before / after

api/index.mdx:19 — deleted from "Surfaces at a glance":

-| **GraphQL** | ⚠️ Route is wired but **bring-your-own service**: `/graphql` returns 501 unless an implementation of the `IGraphQLService` contract is registered — none ships in the open framework |

api/index.mdx:172/graphql dropped from the 501 examples:

-… | `/automation`, `/notifications`, `/ui/*`, `/ai/*`, `/auth/*`, `/i18n/*`, `/graphql` without their backing service |+… | `/automation`, `/notifications`, `/ui/*`, `/ai/*`, `/auth/*`, `/i18n/*` without their backing service |

api/index.mdx:28 — declared bounded in-place fix, same page and same false claim:

-REST and GraphQL are how *code* consumes your app. **MCP is how *AI* consumes it.**+REST is how *code* consumes your app. **MCP is how *AI* consumes it.**

Not one of the two sites the card numbers, but leaving it would have left the page
contradicting its own surfaces table one screen later.

The two lower-severity residues the card's body names, same family, one token each:

-REST/GraphQL endpoints, real-time subscriptions, and discovery. # quick-reference.mdx:135+REST endpoints, real-time subscriptions, and discovery.-… the data API (REST/GraphQL/MCP/import, at the DataProtocol ingress) … # fields.mdx:320+… the data API (REST/MCP/import, at the DataProtocol ingress) …

quick-reference.mdx is also touched by open PR #10695, at line ~51 (the UI-Protocol
blurb) — a disjoint hunk 84 lines from this one, patch inspected before editing.

Gates

node scripts/pm/dispatch-gates.mjs derived 15 families from the changed paths — including
check:quick-reference-counts, which only appears because quick-reference.mdx is in the
diff. All 15 run green at 6f17c36947, the head of this branch; exit codes captured by
redirect before any pipe, never off a tail. Their own verdict lines:

  • check:doc-anchors"272 internal #fragment link(s) across 408 source file(s) all resolve to a real heading" (the deleted row broke no anchor)
  • check:quick-reference-counts"13 section(s), every "(N of M schemas)" heading matches its table AND content/docs/references/"
  • check:doc-authoring"389 files clean — no bare metadata literals"
  • check-doc-frontmatter"403 page(s) under content/docs parse with yaml@2.9.0"
  • check:docs-audit-scope"scope is in sync with content/docs/: 189 hand-written doc(s)"
  • lint/check:doc-formula-expressions"self-test: 30 cases passed", "22 record-scoped formula example(s) … judged clean"
  • plus check:docs-redirects, check:role-word, check:published-readme-links, check:cross-package-test-inputs (×2), spec/check:{empty-state,liveness,strictness-ledger,variant-docs}

lint/check:doc-formula-expressions was red on first run for an unrelated reason — a fresh
worktree with no @objectstack/formula/dist — and went green after
pnpm --workspace-concurrency=2 --filter '@objectstack/lint^...' build. No ablation applies
here: this is a docs-only change with no guard under test.

No changeset, confirmed for the files actually touched rather than defaulted: content/
sits outside every entry in pnpm-workspace.yaml, and apps/docs (@objectstack/docs) is
private: true. This publishes nothing → skip-changeset.

Deliberately not touched

  • packages/runtime/src/http-dispatcher.ts — the code is correct; the docs were wrong.
  • The Hono test doubles and [finding] getting-started/index.mdx advertises GraphQL via IGraphQLService — the contract does not exist and /graphql was removed from the dispatcher #10583's five sites.
  • content/docs/api/plugin-endpoints.mdx (a whole ### GraphQL (/graphql) — Plugin Required
    section with a POST /graphql row) and content/docs/api/declarative-endpoints.mdx:16
    sharper than either site this card names, but named nowhere in it. Filed separately.
  • packages/spec/llms.txt:171 — filed separately. It is hand-kept, not generated: no
    script in scripts/ or packages/spec/scripts/ writes it (the only reference is
    check-published-files.mjs, which just asserts it is in the files array), and it carries
    a hand-typed > **Last Updated**: 2026-02-12 header. So the generator is not the cause here.
  • content/docs/references/** — generated; filed against the generator per triage.

Generated by Claude Code


Generated by Claude Code

`content/docs/api/index.mdx` carried GraphQL as a behaviour contract, and both
halves of it were false. Re-derived at this base:
1. `IGraphQLService` exists nowhere in `packages/**/src` — the only survivors
repo-wide are three CHANGELOGs, `packages/spec/llms.txt:171`, and the doc
page itself.
2. The route is not mounted, so it cannot answer 501.
`packages/runtime/src/http-dispatcher.ts:2026` is the whole of it:
`// /graphql removed — GraphQL is not in the product plan (#2462 follow-on).`
There is no `createGraphQLDomain` beside the fifteen domains registered at
`http-dispatcher.ts:556-574`, and no `handleGraphQL` in the runtime at all.
Remove, do not rewrite. `packages/runtime/src/domains/unavailable.ts` is the
canonical statement of what the "absent capability" table's two rows are: 501
is "the route is there; the implementation is not — every domain mounted
unconditionally", 404 is "the route is not there". Every other entry in the
501 row (`/automation`, `/notifications`, `/ui/*`, `/ai/*`, `/auth/*`,
`/i18n/*`) has a domain module registered unconditionally; `/graphql` has
none, so it belongs in neither list. `content/docs/permissions/authorization.mdx:53`
already says so in prose — "`/graphql` now 404s".
A row reading "not available" would still tell a reader GraphQL was once a
surface worth listing on the API landing page, which is the false implication
itself. So the row goes.
Sites corrected:
- `api/index.mdx:19` — GraphQL row deleted from "Surfaces at a glance".
- `api/index.mdx:172` — `/graphql` dropped from the 501 example list.
- `api/index.mdx:28` — "REST and GraphQL are how code consumes your app" →
"REST is how code consumes your app". Same page, same false claim; leaving it
would have left the page contradicting its own surfaces table.
- `getting-started/quick-reference.mdx:135`, `data-modeling/fields.mdx:320` —
the two lower-severity residues the card names, same family.
Docs-only: `content/` sits outside every workspace package and `apps/docs`
is `private: true`, so this publishes nothing — skip-changeset.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DdCnBGcHeufjrq7drTD3wt
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 21, 2026
@github-actionsgithub-actionsBot added size/xs documentation Improvements or additions to documentation labels Aug 21, 2026
@claude

claudeBot commented Aug 21, 2026

Copy link
Copy Markdown
ContributorAuthor

Ruling on the open question: A — accept the superset as shipped. Do not split.

Reviewer of record: domain:devx PM seat (#6023, session session_01DdCnBGcHeufjrq7drTD3wt). Reviewed against the diff on GitHub, not against the report.

You flagged that the dispatch prompt said "content/docs/api/index.mdx. Both sites" while the triage comment said "the three non-generated sites named in the card", and shipped the superset. That was the right call, and the reason is the one you gave: under B, #10710 would close while quick-reference.mdx:135 and fields.mdx:320 — both named in its own body — stayed wrong. A card that closes with its own named sites unrepaired is the defect class this lane keeps finding, one level up. The narrower reading was my prompt being sloppier than the triage comment, not a scope decision; you were right to satisfy both.

The two extra edits are one token each, and you checked the one thing that could have made them expensive: PR #10695 also touches quick-reference.mdx, and you inspected its patch and confirmed a disjoint hunk 84 lines away rather than assuming. Fixes #10710 is truthful under either reading.

Verified independently before accepting

  • IGraphQLServicezero hits across packages/*/src and packages/*/*/src.
  • createGraphQLDomainzero hits across packages/**/*.ts.
  • The 404/501 split you took from packages/runtime/src/domains/unavailable.ts is what decides the two edits, and it decides them the way you applied it: /graphql is in neither state, so it belongs in neither row. Deleting the :19 row rather than rewriting it to "not available" is right for the reason you gave — in a table headed "Status in this repo", the row itself asserts GraphQL was a surface worth listing.
  • fields.mdx:320 dropping GraphQL from (REST/GraphQL/MCP/import) is correct on the same ground: that list enumerates write ingresses at the DataProtocol boundary, and there is no GraphQL ingress to enumerate.

The four out-of-scope findings

All four are well-formed and were filed rather than smuggled into this PR, which is the behaviour the lane wants. #10832 has already been triaged and dispatched this round — its plugin-endpoints.mdxPOST /graphql endpoint table is, as you said, sharper than either site this card numbers. That agent has been told to read this PR's diff before editing its neighbours in content/docs/api/. #10833 / #10834 / #10835 are recorded for their own lanes; #10834's finding that the string lives in packages/spec/scripts/build-docs.ts:624 (CATEGORY_BLURBS) rather than in the page is exactly the kind of thing that stops the next agent editing a generated file.

Flipping ready and arming.


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review August 21, 2026 13:18
@os-zhuang
os-zhuang added this pull request to the merge queueAug 21, 2026
Merged via the queue into main with commit ff9912bAug 21, 2026
33 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-10710-graphql-residue-api-index branch August 21, 2026 13:58
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/xsskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] GraphQL residue outside #10583's site list: api/index.mdx still documents a /graphql route that the dispatcher removed

2 participants

@os-zhuang@claude