feat(rest): REST route ledger + conformance guard — route audit tranche 2 PR-1 (#3587) - #3609
Merged
Merged
Conversation
…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
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 3 package(s): 30 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
This was referenced Jul 27, 2026
os-zhuang
marked this pull request as ready for review
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>
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.
First PR of #3587 (route audit tranche 2). The dispatcher tranche (#3569…#3579) closed its 27 gaps and guards them;
@objectstack/restmounts 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:sdkmeta.deleteItem/meta.getHistory(REST-only — the dispatcher/metabranch can't serve them)gapserver-onlyGET /api/v1alias,openapi.json,/docspublic/forms/:slugget/submit/lookup)mismatchpackages/rest/src/rest-route-ledger.conformance.test.ts— the guard enumerates both sources for real, no pinned-by-hand list:RestServer.getRoutes()introspection seam (already existed — the "new problem" Route audit tranche 2: the @objectstack/rest surface (search / forms / reports / sharing / …) — #3563 follow-up #3587 anticipated mostly didn't materialize);package-routes.ts,external-datasource-routes.ts) by capturing their registrations on a mockIHttpServer.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: everysdkrow's dotted method path resolves to a real function. Same package-boundary split as tranche 1 (rest→clientedge 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)
POST /api/v1/packagesshape collision: REST's handler is registry publish ({manifest, metadata}); the dispatcher/packagesdomain gives the same verb+path install semantics with a different body. REST registers first in the production stack (serve.ts), sopackages.installtraffic lands on the publish handler. Ledgeredmismatch.GET /ui/view/:object/:type(path params); the SDK'smeta.getViewspeaks/ui/view/:object?type=(query param), which only the dispatcher/uidomain answers. Ledgeredmismatch.service-storage(the SDK's whole storage surface) andservice-i18nmount routes autonomously on the hostIHttpServer, 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
@objectstack/rest: 394/394.@objectstack/client: 150/150 + baretsc -pclean.@objectstack/runtimeledger suite: 4/4. ESLint clean on the three new files.🤖 Generated with Claude Code
https://claude.ai/code/session_01LX9ut3MK3KykE11S9bJmv5
Generated by Claude Code