Repository navigation
[finding] GraphQL residue outside #10583's site list: api/index.mdx still documents a /graphql route that the dispatcher removed #10710
Copy link
Copy link
Labels
documentationImprovements or additions to documentationImprovements or additions to documentationdomain:devx
Description
Activity
- addeddocumentationImprovements or additions to documentationImprovements or additions to documentation
on Aug 21, 2026 Triage (finding concentration round): promoted to
pm:queue· type Task. The api/index.mdx rows are a documented behaviour contract that is false twice over (a named contract that doesn't exist, a route that isn't mounted) on a module landing page — the sharpest kind of docs defect. Scope: the three non-generated sites named in the card. Thecontent/docs/references/**residue is generator territory (packages/spec/scripts/build-docs.ts) — the dev should file that as a separatedomain:specfollow-up card per the out-of-scope-findings protocol, not widen this PR. S,mode:subagent, sonnet; Clause-②: no.
Generated by Claude Code
claude commented
on Aug 21, 2026 claudeboton Aug 21, 2026 – with ClaudeContributorAuthorMore actions{ "issue": 10710, "status": "done", "branch": "claude/issue-10710-graphql-residue-api-index", "pr": "https://github.com/objectstack-ai/objectstack/pull/10828", "premise_still_valid": true, "summary": "All three facts re-derived at origin/main f4e5d916d6 and all three still held: IGraphQLService exists nowhere in packages/**/src (only three CHANGELOGs, packages/spec/llms.txt:171 and the doc page itself); packages/runtime/src/http-dispatcher.ts:2026 is the whole of the route ('// /graphql removed - GraphQL is not in the product plan (#2462 follow-on)'); and no handleGraphQL exists in the runtime (only three Hono test doubles). DECISION - remove, not rewrite, on both sites. packages/runtime/src/domains/unavailable.ts is the canonical statement of what the :172 table's two rows are ('the route is not there' = 404 vs 'the route is there; the implementation is not - every domain mounted unconditionally' = 501); every other 501 entry (/automation, /notifications, /ui/*, /ai/*, /auth/*, /i18n/*) has a domain module registered unconditionally at http-dispatcher.ts:556-574, and there is no createGraphQLDomain - so /graphql is in NEITHER state and belongs in neither row. content/docs/permissions/authorization.mdx:53 already says '/graphql now 404s' in prose. The :19 row was deleted rather than rewritten to 'not available' for the reason the card gave: in a table headed 'Status in this repo', such a row still tells a reader GraphQL was a surface worth listing. SCOPE NOTE: the dispatch prompt scoped me to api/index.mdx 'both sites', while the PM triage comment on the issue says 'the three non-generated sites named in the card'. I took the superset that satisfies both readings - api/index.mdx :19 and :172, plus :28 ('REST and GraphQL are how code consumes your app') which is the same false claim on the same page and would have left the page contradicting its own surfaces table, plus the two lower-severity residues the card's body names (quick-reference.mdx:135, fields.mdx:320, one token each). quick-reference.mdx is also touched by open PR #10695 at line ~51; I inspected that patch first and confirmed a disjoint hunk 84 lines away. Fixes #10710 is therefore truthful under either scope reading. Nothing in packages/** was touched.", "tests": "No ablation applies - this is a docs-only change with no guard under test, so there is nothing to mutate or rebuild; stating that rather than filling the slot. GATE DERIVATION: `node scripts/pm/dispatch-gates.mjs` with no path args (script derives its own change set from merge-base) - run twice, once on the working tree and again at the final commit, identical 15-family set both times; second run reported 'change set derived from git - 3 path(s) vs merge base f4e5d916d of origin/main and HEAD (committed 3, working tree 0, untracked 0)'. It named check:quick-reference-counts, a family the dispatch prompt's list did not carry - it only matches because quick-reference.mdx is in the diff. GATE UNION: all 15 families run GREEN at HEAD=6f17c36947 (the head of the branch; runner printed HEAD_AT_RUN itself). Every gate redirected to its own file with `ec=$?` captured immediately - no exit code read through a pipe or off a tail. Verdict lines quoted from the gates' own output: check:doc-anchors '272 internal #fragment link(s) across 408 source file(s) all resolve to a real heading' (the deleted table 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 (both spellings), and spec/check:{empty-state, liveness, strictness-ledger, variant-docs}. ONE FIRST-RUN RED, NOT MINE: lint/check:doc-formula-expressions exited 1 with ERR_MODULE_NOT_FOUND on @objectstack/formula/dist/index.mjs - the fresh-worktree unbuilt-dependency-closure trap, not a defect in the diff. Green after `pnpm --workspace-concurrency=2 --filter '@objectstack/lint^...' build`. Filtered script names were verified to exist in package.json before running, so no zero-match pnpm --filter could exit 0 and read as green. Control-byte self-scan (grep -naP) clean on all three edited files and on every PR/issue body posted. All heavy work went through scripts/pm/os-verify-lock.sh (waits of 64s and 82s behind another agent's build; holds of 6s/24s/155s/24s).", "open_questions": [ { "question": "Merging PR #10828 closes #10710. Is that the intended scope boundary? The dispatch prompt said 'Correct content/docs/api/index.mdx. Both sites'; the PM triage comment on the issue said 'the three non-generated sites named in the card'. I shipped the superset (api/index.mdx :19/:172/:28 + quick-reference.mdx:135 + fields.mdx:320), so every non-generated site the card names is now corrected.", "options": [ "A - Accept as is: Fixes #10710 is truthful under both readings, the card closes with no residue among the sites it names.", "B - If the intended scope really was api/index.mdx alone, the two extra one-token edits should be split into their own PR (cost: a rebase and a second review for two deleted tokens)." ], "recommendation": "A. The superset costs two token deletions in files no other in-flight PR edits in the same hunk, and it is the only version under which closing #10710 leaves none of its own named sites broken. Under B the card would close while quick-reference.mdx:135 and fields.mdx:320 - both named in its body - stayed wrong." } ], "out_of_scope_findings": [ "filed as #10832: content/docs/api/plugin-endpoints.mdx:145-149 documents a full `POST /graphql` endpoint table (plus frontmatter) and declarative-endpoints.mdx:16 lists /graphql among built-in routes - sharper than either site this card names, but named nowhere in it; also five protocol/** drift sites [documentation, domain:devx]", "filed as #10833: packages/spec/llms.txt:171 still advertises IGraphQLService to AI consumers - MEASURED HAND-KEPT, NOT GENERATED (no script in scripts/ or packages/spec/scripts/ writes it; only check-published-files.mjs references it, to assert it is in the files array; hand-typed 'Last Updated: 2026-02-12' header), so the generator is not the cause and the fix belongs on the file [documentation, domain:spec]", "filed as #10834: content/docs/references/index.mdx:23,:66 'REST/GraphQL contracts...' is generator territory as triage predicted - the string is one line, packages/spec/scripts/build-docs.ts:624 in CATEGORY_BLURBS, emitted at :891; the page cannot be fixed directly (script header: 'DO NOT place hand-written content in content/docs/references/ - it WILL be' overwritten) [documentation, domain:spec]", "filed as #10835: handleGraphQL test doubles outlive the removed route (adapters/hono/src/__mocks__/runtime.ts:6 and two Hono tests) plus a stale packages/core/src/security/anonymous-deny.ts:7 comment naming two surfaces that are both gone [finding, domain:devx]" ] }
Generated by Claude Code
- added a commit that references this issue
on Sep 28, 2026
Metadata
Metadata
Assignees
Labels
documentationImprovements or additions to documentationImprovements or additions to documentationdomain:devx
Found while implementing the #10616 docs-audit sweep (member #10583). Filed
separately per that sweep's gate 4 — not folded into the sweep PR.
What #10583 covered
#10583 named five sites (
getting-started/index.mdx:99,:133, and the// Expose via REST/GraphQLgloss on three pages). All five are fixed in the sweep PR.What it did not
content/docs/api/index.mdxis the sharpest remaining instance, and #10583 explicitlyparked it ("Out of this card's scope, flagged for whoever fixes it") without filing it
anywhere. It is not a stale gloss — it is a documented behaviour contract:
content/docs/api/index.mdx:19— table row: "GraphQL | Route is wired butbring-your-own service:
/graphqlreturns 501 unless an implementation of theIGraphQLServicecontract is registered"content/docs/api/index.mdx:172— the 501 table lists/graphqlamong routes that are"mounted; nothing implements it"
Both claims are false in the same two ways:
IGraphQLServicedoes not exist anywhere inpackages/**. It survives only inCHANGELOG history and
packages/spec/llms.txt.The route is not mounted at all, so it cannot return 501.
packages/runtime/src/http-dispatcher.ts:2026is the whole of it:There is no
handleGraphQLin the runtime dispatcher; the only survivors are testdoubles under
packages/adapters/hono/src/__mocks__/runtime.tsand two Hono testfiles.
packages/spec/src/system/core-services.zod.tsrecords thatgraphqlwasdeleted as a
CoreServiceNamein discovery 的 workflow / graphql 槽位还声明着两条无人挂载的 route —— #4318 同款,但目前"上了膛没击发" #4451 (v17) precisely because it named "a/graphqlsurface the dispatcher had already removed".
A reader of the API module's landing page is told to register a contract that does not
exist, to reach a route that does not exist.
Two lower-severity residues, same family
content/docs/getting-started/quick-reference.mdx:135— "REST/GraphQL endpoints,real-time subscriptions, and discovery."
content/docs/data-modeling/fields.mdx:319—readonlydescription glosses the writepath as "(REST/GraphQL/MCP/import, at the DataProtocol ingress)".
Generator territory, named but not filed here
content/docs/references/index.mdx:23and:66carry "REST/GraphQL contracts, endpoints,routing, realtime, batch, discovery." Per #10563 and the #10616 exclusion list,
content/docs/references/**is generated — that string has to be fixed at the generator(
packages/spec/scripts/build-docs.tsand its inputs), not on the page.Back-link: #10616, #10583
Generated by Claude Code