Skip to content

21 client SDK methods target routes no server surface mounts — delete on the open major train, or build the servers (#3587 finding) #3612

Description

@os-zhuang

Found by the #3587 tranche-2 audit (client-side sweep for PR #3609). Five client surface families build URLs that exist on no server surface — not the dispatcher, not @objectstack/rest, not the autonomous service mounts. Every call is a guaranteed 404. They are the SDK-side siblings of the disease #3595 just deleted server-side: each family is underwritten only by a spec DEFAULT_*_ROUTES table that nothing consumes.

The dead families (packages/client/src/index.ts)

Surface Methods Client lines Ghost spec table
permissions check, getObjectPermissions, getEffectivePermissions (3) :2775, :2784, :2793 DEFAULT_PERMISSION_ROUTES (plugin-rest-api.zod.ts:962-1012 — and its prefix is /api/v1/auth, so it wouldn't even match)
realtime connect, disconnect, subscribe, unsubscribe, setPresence, getPresence (6) :2807-:2863 DEFAULT_REALTIME_ROUTES; service-realtime registers zero HTTP routes; the dispatcher deliberately never advertises /realtime (http-dispatcher.ts:1128-1133)
workflow getConfig, getState, transition (3) :2877-:2895 DEFAULT_WORKFLOW_ROUTES
views list, get, create, update, delete (5) :3024-:3066 DEFAULT_VIEW_ROUTES — no /ui/views route anywhere (both surfaces serve only /ui/view/:object…); note the client even disagrees with its own ghost table (PUT vs the table's PATCH, plugin-rest-api.zod.ts:1077)
notifications devices/prefs registerDevice, unregisterDevice, getPreferences, updatePreferences (4) :3082-:3114 ADR-0012:376 describes the intended /notifications/devices server that was never built; dispatcher mounts only '', read, read/all

(client.events is fine — it's an explicitly local in-memory buffer, no HTTP.)

Why now

A major/breaking train is loading (#3562, #3581, #3593, #3595 all shipped feat(…)! this window). Deleting these methods is client-breaking and will never be cheaper. Leaving them means the #3587 reverse-direction guard ("every client method's target route provably exists") must carry 21 permanent exemptions — the guard would be born lying.

Proposal

  1. Delete the five families from the client (+ their tests/README rows), changeset per the launch-window convention (minor + feat(client)!).
  2. Delete the four ghost DEFAULT_*_ROUTES tables from plugin-rest-api.zod.ts (same tombstone treatment as DEFAULT_DISPATCHER_ROUTES, feat(spec)!: delete DEFAULT_DISPATCHER_ROUTES + sweep last graphql fixture debris (#3586) #3595); regenerate api-surface.json.
  3. Where a product story exists (realtime per ADR; notification devices per ADR-0012), re-adding the surface comes back with its server and a ledger row — the guard then keeps it honest.
  4. Then land the reverse-direction guard with zero exemptions.

Alternative — implement the missing servers instead — is a per-family product decision (views CRUD, device registry, workflow FSM HTTP, realtime HTTP session protocol); nothing in the audit suggests these are imminent, and the guard shouldn't wait on them.

Acceptance

  • No client method builds a URL that no server surface mounts (guard-enforced, no exemption list).
  • api-surface.json regenerated; docs sweep for the removed namespaces.

Refs: #3587, PR #3609; precedent #3595/#3586.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions