Uh oh!
There was an error while loading. Please reload this page.
test(client,runtime): the last wildcard was wrong evidence, not weak — AI ratchet 3 → 0 (#3718) - #3727
Merged
Merged
Conversation
…— AI ratchet 3 → 0 (#3718) The capstone (#3642) ratcheted "matched only by a `**` family" as WEAKER evidence, to be driven down by enumerating each dynamic family. 60 → 3 after #3656. The last 3 were `ai.nlq` / `ai.suggest` / `ai.insights` on `* /ai/**`. Enumerating that family — in `cloud`, where service-ai lives — answered the question the ratchet was really asking. `buildAIRoutes()` mounts 12 routes (chat, chat/stream, complete, models, status, effective-model, six conversations) and NONE is `/nlq`, `/suggest` or `/insights`. client.ai methods: 3 answered by any repo: 0 real AI routes: 12 expressed by the SDK: 0 The two sets are disjoint. So the wildcard was not weak evidence, it was WRONG evidence: it certified three URLs nothing anywhere serves. Its note even asserted the client "expresses nlq/suggest/insights against the REST AI routes" — never verified, and false. `DEFAULT_AI_ROUTES` declares all three but has no runtime consumer (only the spec's own test reads it), and `aiNlq?`/`aiSuggest?`/`aiInsights?` are optional protocol methods nothing implements. Declared, never built (#3718) — instances 7-9 of the `the method exists != the method can be called` class. `/api/v1/ai/` becomes a bounded prefix exemption alongside the control plane: two cross-repo surfaces, both ledgered in `cloud`. Only `ai.*` may use it, and the namespace must still be reaching it, so the hole cannot widen. The wildcard assertion becomes `toBe(0)`, not a ratchet. Zero is the point: every matched call now rests on an exact enumerated route, and reintroducing a `**` match reintroduces the one kind of evidence this audit family has caught being wrong. Mutation-checked both ways: removing the exemption re-exposes exactly the three methods, and running the PRE-change capstone with the bound at 0 confirms the old wildcard set was exactly `ai.insights`, `ai.nlq`, `ai.suggest` and nothing else. Adds audit §14 with the lesson worth carrying out of §1-§14: a claim about a family is not a claim about a member. Wildcards, prefixes and "the service handles that" all read as coverage in a green suite, and every one this audit opened was hiding something. Test-and-comment changes only; no runtime behaviour is affected. Co-Authored-By: Claude <noreply@anthropic.com>
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 2 package(s): 26 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
The docs-drift advisory on this PR prompted a check of whether any published doc advertises the three dead `ai.*` methods. It does, and the AI docs turn out to be backwards in both directions at once: - `plugin-endpoints.mdx` tabled `/ai/nlq`, `/ai/suggest`, `/ai/insights` as the AI plugin's endpoints. None of the three is mounted by anything. - The same section's callout stated "There is no `/ai/chat` route". `/api/v1/ai/chat` IS mounted, along with `/chat/stream`, `/complete`, `/models` and six `/conversations` routes. So the documentation named the three routes that do not exist and explicitly denied the one that does — while `client-sdk.mdx` carried three copy-pasteable examples that 404 on every call. That is Prime Directive #10 in the literal sense: advertising a capability the runtime does not deliver. Corrected: - `client-sdk.mdx` — the three examples are marked declared-but-unimplemented with the reason, and the chat note now says the chat endpoint exists and it is the SDK that lacks a method for it. - `plugin-endpoints.mdx` — status column on the three, plus the real 12-route table and a pointer to cloud's ai-route-ledger.ts. The callout's surviving point (use `useChat()` directly) is kept; only its false premise is fixed. - `services-checklist.mdx` — notes that all three are optional protocol methods nothing implements. Deliberately does NOT decide #3718 (implement vs remove vs express the real surface). Every edit here states what is true today and stays true whichever way that lands. Co-Authored-By: Claude <noreply@anthropic.com>
os-zhuang
marked this pull request as ready for review
July 28, 2026 00:44
Uh oh!
There was an error while loading. Please reload this page.
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 freeto 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.
Closes the last family of the #3563 route audit. Paired with objectstack-ai/cloud#891, which carries the real ledger. Finding filed as #3718.
Test-and-comment changes only — no runtime behaviour is affected.
What the ratchet was really asking
§10's capstone ratcheted "matched only by a
**family" as weaker evidence, to be driven down by enumerating each dynamic family. 60 → 3 after #3656. The last 3 wereai.nlq/ai.suggest/ai.insightson* /ai/**.Enumerating that family — in
cloud, whereservice-ailives — answered the question.buildAIRoutes()mounts 12 routes:chat,chat/stream,complete,models,status,effective-model, and sixconversationsroutes.None of them is
/nlq,/suggestor/insights.client.aimethodsThe two sets are disjoint. So the wildcard was not weak evidence — it was wrong evidence, certifying three URLs nothing anywhere serves. Its note even asserted the client "expresses nlq/suggest/insights against the REST AI routes"; never verified, and false.
DEFAULT_AI_ROUTESdeclares all three but has no runtime consumer (only the spec's own test reads it), andaiNlq?/aiSuggest?/aiInsights?are optional protocol methods nothing implements. Declared, never built — instances 7–9 of thethe method exists ≠ the method can be calledclass, after #3584, #3611, #3636, #3702.The change
/api/v1/ai/becomes a bounded prefix exemption alongside the control plane — two cross-repo surfaces, both ledgered incloud. Onlyai.*may use it, and the namespace must still be reaching it, so the hole cannot widen.* /ai/**ledger row stays (the/aidomain is registered on the dispatcher, so removing it fails the domain-coverage guard) but its note is corrected and now points at cloud'sai-route-ledger.ts.toBe(0), not a ratchet. Zero is the point: every matched call now rests on an exact enumerated route, and reintroducing a**match reintroduces the one kind of evidence this audit family has caught being wrong.Mutation-checked both directions
ai.insights,ai.nlq,ai.suggest— nothing else was resting on a wildcard, so the 3 → 0 claim is measured, not assumed.Audit §14
Adds the section, and with it the lesson worth carrying out of §1–§14:
Not fixed here
Whether to implement the three endpoints, remove the namespace, or express the real surface instead is a product decision — #3718, with a recommendation. The guard is already in place either way: cloud's
UNMOUNTED_AI_CLIENT_METHODSasserts all three still match nothing, so implementing any of them fails that test and forces ansdkrow.Tests
client-url-conformance3 passed ·route-ledger.conformance4 passed ·turbo run test --filter=@objectstack/runtime --filter=@objectstack/client— 28 tasks successful.🤖 Generated with Claude Code
https://claude.ai/code/session_01K35y3ovfWtCkBHYFCqUfAt
Generated by Claude Code