Skip to content

feat(client)!: remove the ai namespace — three methods, none of which ever worked (#3718) - #3736

Merged
os-zhuang merged 4 commits into
mainfrom
claude/remove-dead-sdk-surface
Jul 28, 2026
Merged

feat(client)!: remove the ai namespace — three methods, none of which ever worked (#3718)#3736
os-zhuang merged 4 commits into
mainfrom
claude/remove-dead-sdk-surface

Conversation

@os-zhuang

@os-zhuang os-zhuang commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Resolves the removal half of #3718.

Rescoped. This PR originally removed four methods. While it sat un-CI'd, #3702 landed on main independently and removed projects.listTemplates with near-identical reasoning — that was the merge conflict (both sides deleted the method and left a comment in its place; I took main's wording). Three methods now, not four.

Three methods, none of which ever worked

Removed Built Why it 404ed
client.ai.nlq POST /api/v1/ai/nlq declared in DEFAULT_AI_ROUTES, which has no runtime consumer — only the spec's own test reads it; aiNlq? is an optional protocol method nothing implements
client.ai.suggest POST /api/v1/ai/suggest same
client.ai.insights POST /api/v1/ai/insights same

Found by the AI route ledger (#3718, in cloud, where service-ai lives), which reads the table buildAIRoutes() returns and matches the SDK's URLs against it.

The two sets are disjoint. The real AI surface is 12 routes — chat, chat/stream, complete, models, status, effective-model, and six conversations routes. The SDK expressed none of them.

Removed, not deprecated

A typed method that always throws is worse than no method: it costs a runtime round-trip to discover, where absence is a compile error. No working code can break, because there was no working behaviour.

On the major bump: I hesitated, then checked .changeset/@objectstack/client is already taking a major on the v17 train. So this is not forcing a major, it is landing a breaking removal in the window already open for one, which is when it should land.

Expressing the real surface is tracked on #3718 as new API, not a rename of this one. For chat, useChat() (@ai-sdk/react) already speaks the Data Stream Protocol POST /api/v1/ai/chat serves.

Two things removed that I had added hours earlier

  • The AI_PLANE capstone exemption (from test(client,runtime): the last wildcard was wrong evidence, not weak — AI ratchet 3 → 0 (#3718) #3727). With no method targeting /api/v1/ai/, an exemption there is a hole with nothing to cover. The wildcard-only bound stays 0 and now reaches 0 with nothing exempted to get there.
  • The four AI tests in client.test.ts — replaced, not deleted. They were the exact shape this audit keeps finding behind green suites: mock fetch, assert the URL the client built, never assert that anything answered it. They passed against three endpoints that did not exist. The replacement asserts the one thing worth defending — the namespace is gone and must not return without a route behind it.

Types kept

Ai{Nlq,Suggest,Insights}{Request,Response} are still re-exported straight from @objectstack/spec/api, so anyone holding those types keeps them. Retiring the spec-side declarations (DEFAULT_AI_ROUTES, the optional protocol methods) is a separate change.

Docs

client-sdk.mdx carried three copy-pasteable examples that 404ed. plugin-endpoints.mdx had the AI surface inverted — it tabled the three phantom routes and explicitly denied /ai/chat, which is mounted. It now lists the 12 real ones.

⚠️ Required follow-up in cloud, which cannot be done before this merges

UNMOUNTED_AI_CLIENT_METHODS pins these exact three methods as existing-but-unmounted. When cloud's .objectstack-sha moves past this commit, that guard goes red — correctly, by design — and the pin must be emptied in the same PR as the bump.

That coupling is the ledgers working: an SDK surface change forces the control plane to acknowledge it. Flagging it so the next pin bump isn't surprised. (The pin moved three times during this session alone.)

Why this PR had no CI for an hour

It had a merge conflict, so GitHub could not compute the merge ref and never fired pull_request workflows — zero runs, while Vercel (a different integration) fired on every push. I chased the trigger config instead of checking mergeable_state: "dirty", which was sitting in the API response the whole time. Noted here because "CI never started" and "CI failed" look identical from a distance and are diagnosed in completely different places.

Tests

@objectstack/client122 passed on the merged tree (client.test.ts + client-url-conformance.test.ts); full package 173 passed before the merge.

🤖 Generated with Claude Code

https://claude.ai/code/session_01K35y3ovfWtCkBHYFCqUfAt

…projects.listTemplates` (#3718, #3702)

Four public methods, every one of them building a URL that NO server in any
repo has ever mounted. All four 404ed from the release that shipped them:

  client.ai.nlq                  -> POST /api/v1/ai/nlq
  client.ai.suggest              -> POST /api/v1/ai/suggest
  client.ai.insights             -> POST /api/v1/ai/insights
  client.projects.listTemplates  -> GET  /api/v1/cloud/templates

The three `ai.*` were declared in `DEFAULT_AI_ROUTES` — which has no runtime
consumer, only the spec's own test reads it — and typed as optional protocol
methods (`aiNlq?` …) nothing implements. `listTemplates` targeted a control-plane
route that never existed; templates are a filtered `sys_package` view.

All four were found by the #3563 audit's cross-repo guards, which match the URL
each SDK method BUILDS against the routes each surface MOUNTS: `listTemplates`
by the control-plane ledger (#3655), the three `ai.*` by the AI ledger (#3718),
both living in `cloud` because that is the only repo where the mounted route
set and the SDK are both in scope.

REMOVED, NOT DEPRECATED. A typed method that always throws is worse than no
method: it costs a runtime round-trip to discover, where absence is a compile
error. No working code can break, because there was no working behaviour.

Lands in the v17 major `@objectstack/client` is already taking. That is the
right window for removing public API — not a reason to defer it.

Also removed: the `AI_PLANE` prefix exemption added to the capstone hours ago.
With no method targeting `/api/v1/ai/`, an exemption there is a hole with
nothing to cover. The wildcard-only bound stays 0 and now reaches 0 with
nothing exempted to get there.

The four AI tests in `client.test.ts` are replaced rather than deleted. They
were the exact shape this audit family keeps finding behind green suites: mock
`fetch`, assert the URL the client BUILT, never assert anything answered it —
so they passed for three endpoints that did not exist. The replacement asserts
the one thing worth defending: the namespace is gone and must not return
without a route behind it.

`Ai{Nlq,Suggest,Insights}{Request,Response}` stay re-exported straight from
`@objectstack/spec/api`, so anyone holding those types keeps them; retiring the
spec-side declarations is a separate change.

Docs corrected in the same pass: `client-sdk.mdx` carried three copy-pasteable
examples that 404ed, and `plugin-endpoints.mdx` had the AI surface INVERTED —
it tabled the three phantom routes and explicitly denied `/ai/chat`, which is
mounted. It now lists the 12 routes service-ai really serves.

FOLLOW-UP REQUIRED IN `cloud`, and it cannot be done before this merges:
`UNMOUNTED_CLIENT_METHODS` and `UNMOUNTED_AI_CLIENT_METHODS` pin these exact
four methods as existing-but-unmounted. When cloud's `.objectstack-sha` moves
past this commit, those guards go red — correctly, by design — and the pins
must be emptied in the same PR as the pin bump.

client: 173 passed (13 files), tsc --noEmit clean, build 27/27.

Co-Authored-By: Claude <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 28, 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 28, 2026 2:08am

Request Review

@os-zhuang os-zhuang closed this Jul 28, 2026
@os-zhuang os-zhuang reopened this Jul 28, 2026
claude added 3 commits July 28, 2026 01:24
GitHub Actions never fired for this branch — zero workflow runs across every
workflow, only the Vercel check appeared. Close/reopen did not wake it either.
An empty commit forces a `synchronize` event so the breaking change in this PR
is actually verified rather than merged on an untested branch.

Co-Authored-By: Claude <noreply@anthropic.com>
…k-surface

# Conflicts:
#	packages/client/src/index.ts
…oved listTemplates

While this branch sat un-CI'd, #3702 landed on main independently and removed
`projects.listTemplates` with near-identical reasoning. That was the merge
conflict: both sides deleted the method and left a comment in its place. Took
main's wording.

So this PR no longer removes four methods, it removes three. The changeset said
four; it now says what the diff does.

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added documentation Improvements or additions to documentation tests tooling size/m labels Jul 28, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/client.

13 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)
  • 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)
  • content/docs/getting-started/your-first-project.mdx (via @objectstack/client)
  • 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)
  • content/docs/plugins/packages.mdx (via @objectstack/client)
  • content/docs/protocol/kernel/realtime-protocol.mdx (via @objectstack/client)
  • content/docs/releases/implementation-status.mdx (via @objectstack/client)
  • 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 changed the title feat(client)!: remove the dead SDK surface — the ai namespace and projects.listTemplates (#3718, #3702) feat(client)!: remove the ai namespace — three methods, none of which ever worked (#3718) Jul 28, 2026
@os-zhuang
os-zhuang marked this pull request as ready for review July 28, 2026 02:37
@os-zhuang
os-zhuang merged commit a137bbc into main Jul 28, 2026
16 checks passed
@os-zhuang
os-zhuang deleted the claude/remove-dead-sdk-surface branch July 28, 2026 02:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants