Skip to content

feat(rest): REST route ledger + conformance guard — route audit tranche 2 PR-1 (#3587) - #3609

Merged
os-zhuang merged 1 commit into
mainfrom
claude/screen-flow-submit-resume-v9dqjx
Jul 27, 2026
Merged

feat(rest): REST route ledger + conformance guard — route audit tranche 2 PR-1 (#3587)#3609
os-zhuang merged 1 commit into
mainfrom
claude/screen-flow-submit-resume-v9dqjx

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

First PR of #3587 (route audit tranche 2). The dispatcher tranche (#3569#3579) closed its 27 gaps and guards them; @objectstack/rest mounts a second, larger surface the client also reaches — 89 routes, never audited. This PR is the audit + guard, zero behavior change; gap closures follow in batches like tranche 1.

What

packages/rest/src/rest-route-ledger.ts — every route the package mounts, with a reviewed disposition:

disposition count examples
sdk 38 data CRUD ×6, import jobs ×7, batch ×5, approvals ×6, meta.deleteItem/meta.getHistory (REST-only — the dispatcher /meta branch can't serve them)
gap 43 reports ×8, sharing rules ×5, external-datasource ×5, approvals thread ops ×6, meta admin (diagnostics/audit/publish/rollback/diff/references/book-tree/compound ×2), search, email, record shares ×3, security explain ×2, clone, export, analytics dataset
server-only 3 GET /api/v1 alias, openapi.json, /docs
public 3 anonymous forms (/forms/:slug get/submit/lookup)
mismatch 2 see below

packages/rest/src/rest-route-ledger.conformance.test.ts — the guard enumerates both sources for real, no pinned-by-hand list:

Both directions each (missing entry / stale entry), plus hygiene (sdk rows name methods, non-sdk rows carry rationale) and a 43-gap ratchet.

packages/client/src/rest-route-ledger-coverage.test.ts — the client half: every sdk row's dotted method path resolves to a real function. Same package-boundary split as tranche 1 (rest→client edge is unbuildable; each package verifies its own half), same relative-source import of the pure-data ledger.

packages/runtime/src/route-ledger.ts — scope-note refresh only: the "REST audit is follow-up work" pointer now points at the new ledger.

Findings ledgered, not fixed (follow-up material)

  1. POST /api/v1/packages shape collision: REST's handler is registry publish ({manifest, metadata}); the dispatcher /packages domain gives the same verb+path install semantics with a different body. REST registers first in the production stack (serve.ts), so packages.install traffic lands on the publish handler. Ledgered mismatch.
  2. UI view dialect split: REST mounts GET /ui/view/:object/:type (path params); the SDK's meta.getView speaks /ui/view/:object?type= (query param), which only the dispatcher /ui domain answers. Ledgered mismatch.
  3. A third route surface exists: service-storage (the SDK's whole storage surface) and service-i18n mount routes autonomously on the host IHttpServer, outside both the dispatcher and @objectstack/rest. Explicitly scoped out in the ledger header; auditing it is remaining Route audit tranche 2: the @objectstack/rest surface (search / forms / reports / sharing / …) — #3563 follow-up #3587 work.

Verification

  • All five guard directions negative-tested — each fails naming the offending route (missing RouteManager entry, stale RouteManager entry, missing direct-mount entry, stale direct-mount entry, nonexistent client method); the ratchet also fired on the +1 during the negative test.
  • @objectstack/rest: 394/394. @objectstack/client: 150/150 + bare tsc -p clean. @objectstack/runtime ledger suite: 4/4. ESLint clean on the three new files.
  • Changeset: rest/client/runtime patch.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LX9ut3MK3KykE11S9bJmv5


Generated by Claude Code

…he 2 PR-1 (#3587)

The dispatcher tranche (#3569..#3579) closed its 27 gaps and guards them;
this brings the same regime to the second, larger surface. All 89 routes
@objectstack/rest mounts now carry a reviewed disposition in
rest-route-ledger.ts: 38 sdk, 43 gap (ratcheted), 3 server-only, 3 public,
2 mismatch.

The guard enumerates BOTH sources for real — RouteManager routes via the
getRoutes() introspection seam that already existed, and the two
RouteManager-bypassing registrars (package-routes.ts,
external-datasource-routes.ts) via captured mock-server registrations —
so no pinned-by-hand list anywhere. The client-method direction lives in
packages/client next to the SDK (same package-boundary split as tranche 1;
a rest->client edge is unbuildable). All five guard directions were
negative-tested and fail with the offending route named.

Mismatches the audit surfaced, ledgered not fixed: POST /api/v1/packages
is a publish-vs-install shape collision between REST and the dispatcher
(REST registers first and wins); REST's GET /ui/view/:object/:type path
dialect is unreachable by the SDK's query-param dialect. The
service-storage / service-i18n autonomous mounts are a third surface,
explicitly scoped out and noted in the ledger header.

No behavior change: data + tests only, plus a scope-note refresh in the
runtime ledger.

Refs #3587

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LX9ut3MK3KykE11S9bJmv5
@vercel

vercel Bot commented Jul 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Jul 27, 2026 9:16am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests tooling size/m and removed documentation Improvements or additions to documentation tests tooling labels Jul 27, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 3 package(s): @objectstack/client, @objectstack/rest, @objectstack/runtime.

30 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/skills-reference.mdx (via packages/client)
  • content/docs/api/client-sdk.mdx (via @objectstack/client, packages/runtime)
  • content/docs/api/data-flow.mdx (via @objectstack/client)
  • content/docs/api/environment-routing.mdx (via @objectstack/client)
  • content/docs/api/error-catalog.mdx (via @objectstack/client, @objectstack/rest)
  • content/docs/api/error-handling-server.mdx (via @objectstack/rest)
  • content/docs/api/index.mdx (via @objectstack/rest, @objectstack/runtime)
  • content/docs/api/wire-format.mdx (via @objectstack/runtime)
  • content/docs/automation/hook-bodies.mdx (via @objectstack/runtime)
  • content/docs/concepts/north-star.mdx (via packages/runtime)
  • content/docs/data-modeling/drivers.mdx (via @objectstack/runtime)
  • content/docs/deployment/index.mdx (via @objectstack/runtime)
  • content/docs/deployment/production-readiness.mdx (via @objectstack/runtime)
  • content/docs/deployment/single-project-mode.mdx (via @objectstack/runtime)
  • content/docs/deployment/vercel.mdx (via @objectstack/runtime)
  • content/docs/getting-started/your-first-project.mdx (via @objectstack/client, @objectstack/runtime)
  • content/docs/kernel/runtime-services/data-service.mdx (via packages/client)
  • content/docs/kernel/runtime-services/index.mdx (via packages/client)
  • content/docs/permissions/authentication.mdx (via @objectstack/client, @objectstack/runtime)
  • content/docs/permissions/authorization.mdx (via packages/runtime)
  • content/docs/plugins/index.mdx (via @objectstack/rest)
  • content/docs/plugins/packages.mdx (via @objectstack/client, @objectstack/rest, @objectstack/runtime)
  • content/docs/protocol/kernel/http-protocol.mdx (via @objectstack/runtime)
  • content/docs/protocol/kernel/i18n-standard.mdx (via packages/rest)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/runtime)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/runtime)
  • content/docs/protocol/kernel/realtime-protocol.mdx (via @objectstack/client)
  • content/docs/releases/implementation-status.mdx (via @objectstack/client, @objectstack/rest, @objectstack/runtime)
  • content/docs/releases/v12.mdx (via @objectstack/rest)
  • content/docs/releases/v16.mdx (via @objectstack/client)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@os-zhuang
os-zhuang marked this pull request as ready for review July 27, 2026 09:27
@os-zhuang
os-zhuang merged commit 3d5f726 into main Jul 27, 2026
16 checks passed
@os-zhuang
os-zhuang deleted the claude/screen-flow-submit-resume-v9dqjx branch July 27, 2026 09:27
os-zhuang added a commit that referenced this pull request Jul 27, 2026
… tables under them (#3612) (#3616)

Five client families built URLs no server surface mounts (dispatcher, REST,
and autonomous service mounts all checked in the #3587 audit): permissions
x3, realtime x6, workflow x3, views x5, notifications device/prefs x4.
Every call was a guaranteed 404. Each family was underwritten only by an
unconsumed spec DEFAULT_*_ROUTES table — the same disease
DEFAULT_DISPATCHER_ROUTES had (#3586) — so DEFAULT_PERMISSION/VIEW/
WORKFLOW/REALTIME_ROUTES go with them; getDefaultRouteRegistrations()
returns 9. ApiRouteType loses its client-only 'views'|'permissions' extras.

Kept: events (local buffer, no HTTP), notifications list/markRead/
markAllRead (dispatcher-served), approvals.* (ADR-0019), and
meta.getLegalNextStates (the real FSM read). Docs/README/integration-test
spec swept; api-surface.json regenerated (-4 exports).

Re-adding any of these surfaces now requires the server route to exist and
a route-ledger row proving it (#3569/#3609 guards). The one external
consumer (objectui useClientNotifications dead delegates) is trimmed in a
companion objectui change.

Closes #3612


Claude-Session: https://claude.ai/code/session_01LX9ut3MK3KykE11S9bJmv5

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants