Skip to content

feat(spec)!: drop the @objectstack/spec/cloud subpath — control-plane contracts leave, the package format moves to @objectstack/spec/marketplace - #17372

Merged
hotlong merged 3 commits into
mainfrom
claude/issue-16325-spec-drops-cloud-subpath
Sep 10, 2026
Merged

feat(spec)!: drop the @objectstack/spec/cloud subpath — control-plane contracts leave, the package format moves to @objectstack/spec/marketplace#17372
hotlong merged 3 commits into
mainfrom
claude/issue-16325-spec-drops-cloud-subpath

Conversation

@hotlong

@hotlong hotlong commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Fixes #16325

Step 3 of 3 of the cloud-contracts chain (steps 1 and 2 merged: objectstack-ai/cloud#2037, objectstack-ai/objectui#8360). Ruling: option B "cut by owner" (director batch #62, comment 5563914257, maintainer 「同意」; direction verbatim 「我一直觉得 cloud 的协议应该放在云端,没必要开源」), and option A on the four consumer-less files (#16526, 「其他同意」, re-confirmed 「同意 A」). No alias, no deprecation window (2026-08-27: 「项目在创业阶段,用户也很少,短期不考虑渐进。」).

What changes

  • @objectstack/spec/cloud is deleted — the exports-map entry, the tsup entry, packages/spec/src/cloud/** whole (24 files).
  • The cloud control plane's contracts leave the open-source spec: environment.zod, environment-package.zod, tenant.zod, developer-portal.zod, marketplace-admin.zod, app-store.zod and their tests. 62 JSON-Schema defs are declared retired in RETIRED_DEFS_BY_MAJOR[18] (one entries/retired-defs/18.cloud__*.ts each); one semantic entry, cloud-subpath-retired, carries the prescription. environment/tenant already live in the cloud repo (step 1); the other four had zero consumers anywhere and are recoverable from d5d8d50db.
  • The package & marketplace FORMAT stays, relocated to packages/spec/src/marketplace/ and published as @objectstack/spec/marketplace: package.zod, package-version.zod, marketplace.zod, package-l10n, template-manifest.zod (+ their 4 tests). 30 defs move category through RENAMED_DEFS (cloud/X → marketplace/X), so every authorable key and default is carried and nothing leaves the author-facing contract. Why marketplace and not package: src/package/ would have produced a shard literally named package.json inside api-surface/, export-origins/, declaration-map/, json-schema.manifest/, authorable-surface/ and authorable-defaults/ — a footgun for every tool that treats that filename specially.
  • EnvironmentType(Schema) is re-declared in spec/api (api/discovery.zod.ts, its only open-source reader — the NODE_ENV fold table is a Record keyed by EnvironmentType); discovery.test.ts and the DiscoveryEnvironment ⊂ EnvironmentType pin import it from there. cloud/EnvironmentType → api/EnvironmentType and cloud/Sha256Digest → system/Sha256Digest (the re-export's second emission) go through RENAMED_DEFS as 0-key carries.
  • packages/metadata/src/plugin.ts reads EnvironmentArtifactSchema from @objectstack/spec/system (the one declaration; cloud/environment-artifact.zod.ts was a pure re-export).
  • spec/api/package-api.zod.ts imports ArtifactReferenceSchema from ../marketplace/marketplace.zod; packages/cli (package/publish.ts + 2 tests) imports from @objectstack/spec/marketplace.
  • Generated artifacts regenerated (check:generated --fix): cloud.json shards leave, marketplace.json shards arrive, api.json gains EnvironmentType; content/docs/references/cloud/content/docs/references/marketplace/. The retirement itself is registered in RETIRED_DEFS_BY_MAJOR[18] (the 62 entries/retired-defs/18.cloud__*.ts) and in the cloud-subpath-retired semantic entry, both in src/migrations/registry.ts. docs/protocol-upgrade-guide.md and spec-changes.json do not project protocol 18 at all — the guide's last section is Protocol 16 → 17, and pre-existing 18-bucket entries such as api/CrudEndpointPattern are equally absent from both — so neither file carries this retirement and neither is stale (check:generated: 15/15 current). An earlier revision of this body said those two files "carry the retirement"; that was wrong — see Patch round 1.
  • Changeset: @objectstack/spec minor + **BREAKING** banner with adr-0087: registered cloud-subpath-retired (see Deviations for why not major); @objectstack/cli / @objectstack/metadata patch (import paths only).

The counters — the class that FAILed step 2, re-swept for this repo

Everything in this repo that named cloud as a category, subpath, module path or count. The PM's three are the first three; the rest is this sweep's:

counter what it pinned how it moved
packages/runtime/src/spec-subpath-alias-coverage.pin.test.ts:126 PUBLISHED_SUBPATHS contains cloud names marketplace; floor >= 15 still clears at 16 (19 − 1 + 1 keys, minus . and the two .json)
packages/runtime/vitest.config.ts, packages/metadata/vitest.config.ts alias tables no edit needed — both use the anchored regex rule ^@objectstack\/spec\/([a-z-]+)$ → src/$1/index.ts (#9457), so marketplace resolves and cloud only survives in the incident prose
packages/spec/scripts/export-origins.test.ts:53 ['./cloud', import('../src/cloud/index')] ./marketplace
packages/spec/src/kernel/package-dependency-dual-source.test.ts PackageDependency owned by ./cloud, origin src/cloud/package-version.zod.ts ./marketplace, src/marketplace/package-version.zod.ts
packages/spec/src/system/environment-artifact.test.ts ./cloud re-exports the envelope to the ./system declaration replaced by the stronger form: holdersOf(name) equals ['./system'] — no other entry may name it
packages/spec/src/cloud/tenant.test.ts (#4739 pin) ./system must not re-grow the provisioning family; ./cloud holds TenantPlan the system/contracts half survives as src/system/tenant-provisioning-family-retired.test.ts, plus the new fact holdersOf('TenantPlan') is empty
packages/spec/src/type-alias-convention.pin.test.ts (ADR-0122 registry + check:spec-parsed-alias) M45–M54 cloud modules, 30 pins, count 811 six modules' 30 pins leave, M50–M53 re-point to marketplace/, EnvironmentTypeSchema pinned again under api/discovery (Iso871); count 811 → 782 with the history note
packages/spec/scripts/file-description.test.ts PAGES.cloud, the cloud/package link fixture, openingOf('cloud/template-manifest…'), corpus floor > 140, exact 37 level-1 openers marketplace/…; measured 138 (floor → 130) and 31 (six of the seven deleted cloud/*.zod.ts opened at level 1 — tenant opened at level 2)
packages/spec/scripts/root-meta.test.ts:70 14-category list cloudmarketplace, still 14
packages/spec/scripts/build-docs.ts CATEGORY_SECTIONS / CATEGORY_BLURBS, lib/category-title.ts per-category tables the docs generator holds equal to the tree marketplace rows
packages/spec/scripts/build-schemas.ts, check-yaml-examples.ts import * as Cloud from '../src/cloud' namespace maps Marketplace
packages/spec/scripts/lib/renamed-defs.ts cloud/PackageDependency "deliberately absent" now a source (category move); 32 entries added
packages/spec/scripts/check-template-manifests.ts:44 imports TemplateManifestSchema from ../src/cloud/… ../src/marketplace/…
packages/spec/unemitted-schemas.baseline.json Cloud.EnvironmentArtifactSchema (duplicate of the System. row, keyed by export) row deleted
packages/spec/browser-reachable-entries.json ./cloud unjudged ./marketplace unjudged
packages/spec/tsup.config.ts entry + browserConditionedEntries entry renamed; not browser-conditioned (see Deviations)
packages/spec/llms.txt:96 (check:llms-txt re-derives counts) cloud / 11 marketplace / 4; heading 205 → 198
content/docs/getting-started/quick-reference.mdx (check:quick-reference-counts) ## Cloud Protocol (3 of 11 schemas) ## Marketplace Protocol (2 of 4 schemas)
scripts/check-system-context-census.mjs NON_READ_ANCHORS + content/docs/permissions/system-context.mdx Environment.isSystem at packages/spec/src/cloud/environment.zod.ts#isSystem — "four declarations" row retired with a note; page says three
packages/client/src/return-type-precision.test.ts Environment from @objectstack/spec/cloud as the near-miss binding the guard moves from a member read to a @ts-expect-error'd import from @objectstack/spec/marketplace — it goes red the day a row type called Environment reappears there (⚠️ not silently deleted; the old environmentIsNotTheCloudWireRow had no subject left)
apps/docs/redirects.mjs (check:docs-redirects) references/cloud/{marketplace,package,package-version,template-manifest}references/marketplace/…, environment-artifactreferences/system/…, the rest → the references index (the file's own convention for pages with no successor)
prose only, updated: packages/client/src/index.ts (the #11925/#12036 docblock — ruling text untouched), client.environments-namespace.test.ts, spec/src/system/index.ts, contracts/index.ts, kernel/plugin-security.zod.ts, system/environment-artifact.zod.ts, cli/src/utils/protocol-version-gap.ts, create-objectstack test message, content/docs/concepts/north-star.mdx, docs/design/marketplace-publishing.md; patch round 1 adds content/docs/deployment/troubleshooting.mdx, content/docs/plugins/packages.mdx, content/docs/getting-started/glossary.mdx — enumerations no gate reads

Still naming cloud, deliberately: docs/adr/** (history, governed), docs/plans/m1-project-artifact-schema.md (a historical plan), CHANGELOGs, the #9457 incident prose in the two vitest configs and the runtime pin header, and AGENTS.md's Protocol Domains row — governed surface, filed as #17370 rather than converting this PR to human-merge-only.

objectui's two exports-map pins (vite-objectstack-spec-dist.test.ts:152/:608, both 19) are that repo's bump PR's, as the card records — not touched here.

A gate fix, in place — carryDefaultsThroughRenames

gen:schema's #4666 defaults ratchet carried the baseline's KEY set through RENAMED_DEFS but not its DEFAULTS map, so the category move read as 22 (none) → value (added) flips — declaring them in DEFAULT_CHANGES_BY_MAJOR would have been 22 false claims (a rename riding the acknowledged-change table, exactly what renamed-defs.ts forbids). Fix: scripts/lib/authorable-defaults.ts#carryDefaultsThroughRenames, applied at both baseline sites in build-schemas.ts, with four discrimination tests in scripts/authorable-defaults.test.ts (carry → zero findings; negative control: the uncarried baseline reproduces the added flip; a default that really moves across a rename is still caught; undeclared defs pass through). In-place under the bounded exemption: same defect class as this card (rename-blind counters), the form is pinned by the key-carry two lines above, no other claim declares packages/spec/scripts/**, same gate family. File surface added to the claim by this PR.

Deviations

  1. Changeset level minor, not major. The dispatch said "MAJOR"; scripts/check-changeset-no-major.mjs refuses major under the launch-window convention (recorded on .github/workflows/pr-automation.yml and in .changeset/engine-verb-result-declarations.md). Breaking-ness is carried by the **BREAKING** banner + the ADR-0087 registered disposition; the gate printed ✓ 1 declared-breaking changeset(s), each carrying an ADR-0087 disposition and ✓ This diff introduces no major bump.
  2. ./marketplace publishes without a browser condition. ./cloud was browser-conditioned because its module graph reached pg-connection-string; the poisoned members were the deleted environment/tenant modules. Measured on the rebuilt dist: dist/marketplace/index.mjs links it 0 times (dist/kernel/index.mjs: 4, the control). check:browser-reachable-entries is green with it unconditioned.
  3. Two 0-key defs carried by rename rather than retired: cloud/EnvironmentType → api/EnvironmentType (re-declared) and cloud/Sha256Digest → system/Sha256Digest (a rename onto a def that already existed — the case build-schemas.ts's manifest rewrite explicitly handles). Retiring them would have claimed they left the published set; they did not.
  4. Docs redirects added for the retired references/cloud/ pages — the table exists for exactly this, and the deleted control-plane pages follow its own "section index" convention.
  5. Verify-lock wrapper reported UNLOCKED (declared) on every run: no usable flock on this host, so nothing was serialized (declared here as the wrapper asks).
  6. Local verification narrowed, declared: turbo ls --affected lists 77 packages (spec is the root of the graph). Run locally in full: @objectstack/spec (467 files / 13163 tests), @objectstack/runtime (251 / 3532), @objectstack/client (41 / 492), @objectstack/metadata (53 / 788), create-objectstack (15 / 195); @objectstack/cli --project unit (190 passed / 2 failed files — all 5 failing cases are /var/folders vs /private/var/folders tmpdir-realpath mismatches in published-subpath-console.pin.test.ts / published-subpath-hook-body.pin.test.ts, host-environmental, nothing this diff touches); cli integration tier declared to CI. Typecheck green: spec, metadata, runtime, cli, client, create-objectstack. The remaining affected packages and pnpm lint are CI's.
  7. Two gate self-tests fail identically on clean main (cca1dc0bf): check:bash32-floor (mapfile: command not found in the simulated-3.2 harness) and check:merge-driver — host shell, not this diff; NOT MEASURED locally.

Console Pin Gate — measured, not assumed

AGENTS.md Post-Task #4 asks whether the pinned sibling imports what is removed. It does: .objectui-sha = 53ded82bf predates step 2's merge cb847fd6d (merge-base --is-ancestor exit 1 on a full clone; control leg pin→origin/main exit 0), and at the pin packages/types/src/index.ts:1105 still reads export type * as Cloud from '@objectstack/spec/cloud'. So scripts/build-console.sh was run against THIS tree: green — 8817 modules, ✓ Bundle canary present, ✓ Console bundle carries THIS tree's @objectstack/spec, and only it. Mechanism: @object-ui/types is built through turbo from objectui's own vendored spec (17.3.0, which still exports ./cloud) and the re-export is type-only, erased in the injected SPA build. ⇒ main does not go red on merge. The pin bump (with pnpm sdui:manifest and objectui's 19→18 pins) remains the objectui-side follow-up the card already records — not a precondition.

Reverse verification

On the committed head, packages/metadata/src/plugin.ts's import was flipped back to @objectstack/spec/cloud (on-disk proof: grep -c 0→1 for cloud, 1→0 for system), tsc --noEmit in packages/metadata went red with TS2307 (Cannot find module '@objectstack/spec/cloud'), the file was restored with git checkout HEAD -- <path> and git diff HEAD is empty (blob hash equal before/after). Direction: red, as expected. The client-side guard is the second leg: check:test-typecheck for @objectstack/client reports 0 file(s) / 0 error(s), i.e. the @ts-expect-error on the Environment import is consumed — the name really is gone.

Gates

Derived by node scripts/pm/dispatch-gates.mjs --commands on the actual changed set: 147 commands, all run; 141 exit 0. The six non-zero: check:skill-examples (exit 1 until @objectstack/client-react was built, then ✅ 258 prose examples type-check), check:dual-build-cjs-loads and check:i18n-coverage (exit 3 PREREQUISITE NOT MET until the full pnpm build, then 0check-i18n-coverage: OK (13 config(s), 621 baselined, none new)), and the two host self-tests above. Ratchet families re-run on the final head after the last commit — see the PR comment / report for the sha line. pnpm --filter @objectstack/spec check:generated: 15/15 artifacts current.

Patch round 1 — contract review (head ef1fda259)

Two items from the contract-review PASS, both landed in ef1fda259 (docs only: 3 files, 7 lines).

  1. Published docs advertised the deleted subpath. content/docs/deployment/troubleshooting.mdx's "Available subpaths" enumerated cloud and did not list marketplace. It now lists the ./* entries of packages/spec/package.json's exports map in the map's own order (16, meta-spelling included) and names that source so the next editor derives it. The sweep the review asked for — the same controlled shape as the code sweep, over content/docs/** — found two more enumerations of the same set that no gate reads: content/docs/plugins/packages.mdx's 15-namespace list, and content/docs/getting-started/glossary.mdx (its 15-namespace list, the layers table — namespaces column, plus tenantspackages in the purpose column beside it — the ### Cloud Protocol section, now ### Marketplace Protocol, and the Tenant entry, which named cloud/tenant.zod.ts as the schema's home). All corrected.

    Sweep readings on ef1fda259, each zero beside a same-shape control that fires:

    pattern over content/docs/** hits control (same shape)
    import-shaped @objectstack/spec/cloud (from / import / require( then a quote) 0 spec/data 131 · spec/marketplace 8
    namespace lists naming Cloud (Kernel, Cloud · Security, Cloud · the backticked cloud-then-qa list fragment) 0 the same shapes naming Marketplace: 4
    spec source paths cloud/NAME.ts / cloud/NAME.zod.ts 0 marketplace/NAME…: 8
    any spec/cloud mention 2, both historical — permissions/system-context.mdx:54 ("left this repo with the … subpath") and the generated references/system/environment-artifact.mdx:12 ("re-exported this file until") spec/marketplace: 9 lines / 5 files

    Reported, not edited: concepts/architecture.mdx still carries a "Cloud Protocol" card in its six-card conceptual layering — a framing choice, not a namespace list — filed as content/docs/concepts/architecture.mdx still presents a "Cloud Protocol" card after the ./cloud subpath left @objectstack/spec #17387; and the fact that no gate holds these three enumerations equal to the exports map, filed as No gate holds the hand-written docs enumerations of @objectstack/spec subpaths and protocol namespaces equal to the exports map #17388. docs/qa/platform-checklist/FOLLOW-UPS.md:269 records a historical path in a governance note and is correct as history — untouched.

  2. A claim in this body was wrong and is corrected in "What changes" above: docs/protocol-upgrade-guide.md and spec-changes.json do not carry the retirement; they do not project protocol 18 at all.

Gates for this round: node scripts/pm/dispatch-gates.mjs --commands over the three files derives 39 families; all 39 ran on ef1fda259 and all exit 0 (four first returned 3 / 1 as PREREQUISITE NOT MET until @objectstack/lint and @objectstack/client-react were built, then 0: ✅ 258 prose examples type-check across 3 surface(s), ✓ check-docs-transcript-drift: 4 declared transcript value(s) across 401 page(s) … equal what the registry derives today, ✓ check:doc-formula-expressions: 22 record-scoped formula example(s) across 438 files, ✅ 27 ObjectSchema.create example(s) … carry an os validate-clean security posture). --ran reconciliation: 39 derived, 39 run, 0 unrun. The 108 code-derived families of the full changed set derive from files unchanged since edfbc7f22, where they ran (CI on that head: 35 success / 6 skipped, 0 failures) — a declared narrowing for a docs-only delta, not a re-run. The verify-lock wrapper again reported UNLOCKED (declared) (no usable flock on this host).

维护者速读(草稿)

改了什么 —— 开源包 @objectstack/spec 里的 cloud 子路径整个删掉了。云端控制面自己的数据结构(环境、租户、开发者门户、市场后台、应用商店,62 个 schema)从开源包里离开:环境和租户已经在云端仓库里重新声明(第一步),另外四个文件在任何仓库里都没有使用者,直接删除(可从历史 d5d8d50db 找回)。「包与市场格式」这一半(包、版本、市场发布/安装、模板清单,30 个 schema)留在开源包里,从 cloud/ 搬到 marketplace/,以 @objectstack/spec/marketplace 发布,内容一字不改。

为什么改 —— 你 9 月 6 日的方向:「我一直觉得 cloud 的协议应该放在云端,没必要开源」,决策批次 #62 定了 B「按归属切开」。控制面 schema 的生产者和消费者都在云端仓库,开源这边只用到一个类型(EnvironmentType,已经搬到 api/)。留在开源包里的坏处是:SDK 的 client.environments.* 故意返回 any,而旁边就放着一个看起来正好能接上的 Environment 类型,接上去编译能过、运行时读到空值。删掉之后这个类型在开源包里根本不存在,接错在结构上不可能。

风险与代价(含回滚) —— 这是删除已发布子路径的破坏性变更,不留别名、不留过渡期(按你 8 月 27 日的裁决)。仓库的发布约定不允许 major,所以 changeset 标 minor 并带 BREAKING 横幅和 ADR-0087 登记,迁移说明写在 changeset 和升级指南里。云端仓库还有 4 处 PackageSchema@objectstack/spec/cloud 导入,要在这个版本发布后改到 /marketplace(云端席位的活);objectui 那边两处「19 个导出项」的钉子会在它升级 spec 依赖时变 18(那张 PR 的活)。当前钉住的 objectui 版本还有一行只导出类型的 Cloud,实测 Console Pin Gate 仍然绿(类型导出被擦除)。回滚:整个 PR 一次 revert 即可,生成物会跟着回来。

席位意见 ——

你要做的 —— 确认两点:① marketplace 这个名字可以接受(比 package 好的理由:package 会在六个生成物目录里各生出一个叫 package.json 的分片文件,工具链会把它当包清单);② 这个 PR 走人工合并还是队列——它不触及受管面(AGENTS.md 那一行另开了 #17370)。

Generated by Claude Code

hotlong and others added 2 commits September 10, 2026 16:54
…ve, package format moves to `./marketplace`

WIP for the step-3 card of the cloud-contracts chain: the cloud control
plane's own contracts (environment, environment-package, tenant,
developer-portal, marketplace-admin, app-store) leave `@objectstack/spec`;
the package & marketplace format relocates to `src/marketplace/` and is
published as `@objectstack/spec/marketplace`; `EnvironmentType` is
re-declared in `api/discovery.zod.ts`; `packages/metadata` reads the
environment-artifact envelope from `@objectstack/spec/system`.

Claude-Session: https://claude.ai/code/session_f95e3874-e532-4748-a921-044aa2752a2b
Co-authored-by: Claude <noreply@anthropic.com>
…d carry defaults through def renames

- `gen:schema` / `check:generated --fix` output: `cloud.json` shards leave,
  `marketplace.json` shards arrive, `api.json` gains `EnvironmentType`, the
  reference docs move to `content/docs/references/marketplace/`.
- `scripts/lib/authorable-defaults.ts`: `carryDefaultsThroughRenames` — the
  #4666 defaults ratchet carried the baseline's KEY set through RENAMED_DEFS
  but not its DEFAULTS, so a declared category move read as 22
  `(none) -> value (added)` flips; both halves are carried now, with the
  discrimination pinned in `authorable-defaults.test.ts`.
- `./marketplace` publishes without a `browser` condition: its bundles link
  no `pg-connection-string` (the poisoned members were the deleted
  `environment` / `tenant` modules); `browser-reachable-entries.json` lists
  it as unjudged.
- Count pins that describe the corpus move with it: 811 -> 782 isomorphic
  aliases, 37 -> 31 level-1 openers, description floor 140 -> 130.
- `unemitted-schemas.baseline.json` drops the `Cloud.EnvironmentArtifactSchema`
  duplicate of the surviving `System.` row.

Claude-Session: https://claude.ai/code/session_f95e3874-e532-4748-a921-044aa2752a2b
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 4 package(s): @objectstack/cli, @objectstack/client, @objectstack/metadata, @objectstack/spec, touching 265 documentable anchor(s). ⚠️ 91 changed file(s) yielded no anchor (packages/cli/src/utils/protocol-version-gap.ts, packages/spec/api-surface/api.json, packages/spec/api-surface/cloud.json, …), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

51 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: node scripts/docs-audit/affected-docs.mjs --json eb7406ca25715085dece907d413af9e76b72c0e4.

9 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails.

What this run could not see
  • 91 changed file(s) yielded no anchor (packages/cli/src/utils/protocol-version-gap.ts, packages/spec/api-surface/api.json, packages/spec/api-surface/cloud.json, …) — pages documenting those are invisible to this run
  • 9 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 60 of 215 client-bound route-ledger rows — the other 155 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 155: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 100 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 143 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json eb7406ca25715085dece907d413af9e76b72c0e4packageMentionDocs.

Which tree this was computed on

This run read content/docs from a452cc671aa0fa9f6ff2557a6153189d93c69c89 — the merge of head ef1fda259072f6ca043d5d7c9ee4c1cea5057206 into base eb7406ca25715085dece907d413af9e76b72c0e4, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin a452cc671aa0fa9f6ff2557a6153189d93c69c89 && git checkout a452cc671aa0fa9f6ff2557a6153189d93c69c89
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin eb7406ca25715085dece907d413af9e76b72c0e4 ef1fda259072f6ca043d5d7c9ee4c1cea5057206 && git checkout -B drift-repro eb7406ca25715085dece907d413af9e76b72c0e4 && git merge --no-ff ef1fda259072f6ca043d5d7c9ee4c1cea5057206

node scripts/docs-audit/affected-docs.mjs --json eb7406ca25715085dece907d413af9e76b72c0e4

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs eb7406ca25715085dece907d413af9e76b72c0e4 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

…the deleted `cloud`

Contract-review patch round 1 of the cloud-subpath retirement PR. No gate
reads a hand-written docs enumeration of `@objectstack/spec`'s subpaths,
so three published pages kept advertising `cloud` after the exports-map
entry left, and none listed `marketplace`:

- `content/docs/deployment/troubleshooting.mdx` "Available subpaths" — now
  the `./*` entries of `packages/spec/package.json`'s `exports` map, in its
  order (16 entries, `meta-spelling` included), and the sentence names that
  source so the next editor derives it rather than retypes it.
- `content/docs/plugins/packages.mdx` — the 15-namespace list.
- `content/docs/getting-started/glossary.mdx` — the 15-namespace list, the
  layers table (its namespaces column, and `tenants` -> `packages` in the
  purpose column beside it), the `### Cloud Protocol` entry (now
  `### Marketplace Protocol`: the package & marketplace format), and the
  Tenant entry, which named `cloud/tenant.zod.ts` as the schema's home.

Controlled sweep of `content/docs/**` after the edit: zero import-shaped
`@objectstack/spec/cloud` (same-shape controls: 131 `spec/data`, 8
`spec/marketplace`), zero namespace lists naming Cloud (control: 4 naming
Marketplace), zero `cloud/*.zod.ts` source paths (control: 8
`marketplace/*`). The two remaining `spec/cloud` mentions are historical
("left with", "re-exported until"). `concepts/architecture.mdx`'s six-card
conceptual layering still carries a "Cloud Protocol" card; that is a
framing question for the maintainer and is reported, not edited.

Claude-Session: https://claude.ai/code/session_f95e3874-e532-4748-a921-044aa2752a2b
Co-authored-by: Claude <noreply@anthropic.com>
@hotlong
hotlong marked this pull request as ready for review September 10, 2026 11:16
@hotlong
hotlong enabled auto-merge September 10, 2026 11:16
@hotlong
hotlong added this pull request to the merge queue Sep 10, 2026
Merged via the queue into main with commit 776d64c Sep 10, 2026
51 checks passed
@hotlong
hotlong deleted the claude/issue-16325-spec-drops-cloud-subpath branch September 10, 2026 11:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation needs:contract-review protocol:system size/xl tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Decision] Should the cloud control-plane contracts leave @objectstack/spec and live in the cloud repo? (upstream of #12036)

1 participant