Uh oh!
There was an error while loading. Please reload this page.
fix(service-settings): say the AI runtime is cloud-only instead of telling operators to mount it - #11467
Conversation
…lling operators to mount it The `ai/test` fallback handler answered all three real-provider branches with "Mount @objectstack/service-ai to exercise live calls", while this platform's own roster — PLATFORM_CAPABILITY_PROVIDERS.ai in @objectstack/spec/kernel — declares edition: 'cloud', defined as "no installable version in the open edition". The instruction is kept and gains the boundary it was missing. The sentence is read from the roster (package + note verbatim) rather than hand-written a fourth time, matching how packages/cli's capability preflight already surfaces the same note. The three provider prefixes stay distinct; only the shared trailing sentence converges. Fixes#11318 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01APWX2AwT3a4xDcjPCe8bk4
…-manifest-cloud-only-boundary
📓 Docs Drift Check2 anchor(s) derived from 1 changed package(s); no hand-written page names any of them. ✅ What this run could not see
Coarse fallback — 7 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 66eb82b4ec67c3fc3b281cb9b2a3aa6dca1bb80c && git checkout 66eb82b4ec67c3fc3b281cb9b2a3aa6dca1bb80c
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 8542bd457765444626023db6ffeb6f8105f7f83e 2e4f999b19408712b58bee77e2e27a7d1fc86a39 && git checkout -B drift-repro 8542bd457765444626023db6ffeb6f8105f7f83e && git merge --no-ff 2e4f999b19408712b58bee77e2e27a7d1fc86a39
node scripts/docs-audit/affected-docs.mjs --json 8542bd457765444626023db6ffeb6f8105f7f83e |
Uh oh!
There was an error while loading. Please reload this page.
Fixes#11318
What was wrong
packages/services/service-settings/src/manifests/ai.manifest.ts'sai/testfallback handler told an operator, on all three real-provider branches, to
"Mount
@objectstack/service-aito exercise live calls." This platform's owncapability roster —
PLATFORM_CAPABILITY_PROVIDERS.aiin@objectstack/spec/kernel(packages/spec/src/kernel/platform-capabilities.ts:127-131)— declares that capability
edition: 'cloud', whichCapabilityEdition'sdocblock defines as "realized only by a cloud runtime tier; there is no
installable version in the open edition." The instruction was not merely
unhelpful — it was impossible to follow.
Worse than a 404: the package name still resolves on the public npm registry
(
@objectstack/service-ai, 57 versions, latest10.3.0), entirely below the11.3.0cut the roster's ownnotenames. An operator following the oldinstruction installs a seven-major-old runtime that pins a second
@objectstack/specbeside this repo's.The fix
The instruction is kept — an operator may genuinely have a cloud tier —
and now carries the boundary the roster already records, read from the roster
(
package+note, verbatim) rather than hand-written a fourth time, matchinghow
packages/cli's capability preflight already surfaces the same note(PR #11266 precedent). The three provider branches (Vercel AI Gateway,
Cloudflare AI Gateway, plain SDK provider) stay distinct; only the shared
trailing sentence changes.
The embedder hint at a separate site in the same file
(
@objectstack/embedder-openai) is deliberately untouched — that package isbuilt in this repo, so its mount instruction is followable as written. Pinned
by a contrast test so a future edit cannot blanket-reword every hint in the
file.
Where the boundary was verified
Read directly from the roster, not from the card's paraphrase:
CapabilityEdition's docblock:'cloud' — realized only by a cloud runtime tier; there is **no installable version in the open edition**.The new message interpolates
ai.packageandai.noteverbatim and states"no open-edition version to install" — agreeing with the roster's own words
rather than a hand-typed paraphrase.
Consumer check (Clause-②)
SettingsActionResult.message(packages/spec/src/system/settings-manifest.zod.ts)is documented as a
Toast message— free-form prose a human reads in theSettings → AI panel after pressing "Test connection."
okandseverityarethe fields any caller could switch on, and neither changes in this diff. No
caller in this repo (server or client) parses
message's contentprogrammatically. This is a message, not a consumed contract — Clause-②
grades
no.Tests
packages/services/service-settings/src/manifests/ai.manifest.test.ts— newdescribeblock, 5 cases:aiwithpackage/edition: 'cloud'/note(thepremise the rest rests on)
states the boundary: message contains
ai.packageandai.noteverbatim,matches
/no open-edition version to install/, and does not match theold bare
Mount @objectstack/service-ai to exercise live calls.stringis operator-mountable) still gets its plain mount line, unedited — pins
that this fix narrows to the cloud-only site and does not strip every mount
hint in the file
Checks run (this worktree, final commit
2e4f999b19)pnpm --filter '@objectstack/service-settings^...' build— dependencyclosure (spec, metadata-protocol, objectql, …) — pass,
VERDICT command-exit 0pnpm --filter @objectstack/service-settings test— 27 test files / 488tests pass (verbose run on
ai.manifest.test.tsalone: 25/25, all 5 newcases named and green —
VERDICT command-exit 0)pnpm --filter @objectstack/service-settings typecheck(tsc --noEmit) —pass,
VERDICT command-exit 0, 0error TSlines in outputnode scripts/pm/dispatch-gates.mjs, no hand-supplied paths) —16 of 18 named gates run and green:
check:changeset-gate-self-tests,check:objectui-changeset,check:published-files,check:slot-lookup,check:test-source-alias,check:type-source-resolution,check:type-check-coverage,check:engine-double-contract,check:cross-package-test-inputs,check:where-matcher,check-adr-0087-registration,check-changeset-no-major,check-ci-filter-parity,check-empty-changeset,check-plugin-teardown-shape,docs-audit/check-affected-docs(no drift —service-settings/ai.manifestdo not appear in its UNREACHABLE rows,and this repo's own docs already state the cloud-only boundary correctly:
content/docs/kernel/services-checklist.mdx,skills/objectstack-ai/SKILL.md).check:query-options-erasureandcheck:type-check-debt(its--re-measureclosure build) are NOT MEASURED locally — both are whole-
packages/**ESLint/tsc sweeps, and under this container's contention today (6+ parallel
agents queued on the shared verify lock, one holding a full-workspace
turbo build) the erasure gate's real pass was killed by SIGTERM twice —once at a 5-minute foreground cap, once 69s after acquiring the shared lock.
Declared narrowing, not a skip: CI runs the full farm regardless.
Generated by Claude Code