Skip to content

fix(spec): 18.0 upgrade-guide entries say 18.0 supports fresh installs only - #24661

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-24637-spec-entries-18-fresh-install-only
Oct 19, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-24637-spec-entries-18-fresh-install-only

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Refs #24637

Clause-②: no

The domain:spec row of #24637. The parent closes once this PR and its three children land (#24651, #24652, #24653 are not addressed here), so this PR does not close it.

What changes

In 18.0, os migrate organization-ownership refuses plan and apply on every database (exit 1, NOT_IMPLEMENTED, nothing read or written), and 18.0 supports fresh installs only. Seven ADR-0087 semantic entries under packages/spec/src/migrations/entries/semantic/ compile into the 18.0 upgrade guide, and they still prescribed --out PLAN then --apply --plan-file PLAN as if 18.0 upgraded a v17 database.

Each entry now says what 18.0 supports for a v17 database, in the words PR #24635 (f89d29e382) landed in the CLI and the boot refusal:

18.0 supports fresh installs only and does not upgrade a v17 database: keep a v17 database on a 17.x release until the 18.x release that carries the upgrade path.

Each entry keeps the plan and apply steps, now introduced as "In that 18.x release, ...".

entry fields changed
sys-metadata-organization-column-retired, -audit-, -commit-, -history- replacement and acceptanceCriteria lead with the 18.0 sentence and qualify the ceremony as 18.x; in reason, "the v18 ceremony" becomes "the 18.x ceremony", and the boot-refusal clause says it refuses in 18.0 on every such database
ups-permission-set-id-column-retired replacement and acceptanceCriteria the same way; reason names "the 18.x ceremony"
sharing-rule-declared-mirror-retired replacement leads with the 18.0 sentence; surface and acceptanceCriteria name the ceremony as 18.x
cli-organization-ownership-apply-plan-file-required see below

The cli-organization-ownership-apply-plan-file-required entry

The command itself is this entry's whole subject. I kept the entry and rewrote the guidance rather than deleting it:

  • The upgrade guide renders each entry as `surface` → replacement, then "Why not automatic" (reason) and "Done when" (acceptanceCriteria) (packages/spec/scripts/build-upgrade-guide.ts). Nothing checks the prose against the CLI. The entry's id and step are registered, and .changeset/pre/15211-cli-apply-reviewed-plan.md cites it.
  • The surface stays as it is: the bare --apply --backup-taken invocation that @objectstack/cli 18.0.0-next.1 shipped. A script written against that prerelease is still a real reader, and in 18.0 the invocation is refused.
  • The replacement now opens with "nothing in 18.0: 18.0 refuses this invocation, as it refuses every plan and apply of os migrate organization-ownership on every database". Then it gives the 18.0 sentence, then the plan-file rule, introduced as "In that 18.x release".
  • reason adds one sentence on why 18.0 holds the ceremony back. The ceremony is knowingly incomplete, and an incomplete ceremony must never certify a v17 database that the boot would then serve. This paraphrases the docblock on ORGANIZATION_OWNERSHIP_UPGRADE_UNAVAILABLE.
  • acceptanceCriteria now opens with what holds on 18.0, then keeps the 18.x plan-file criteria.

Deleting the entry would drop the 18.x plan-file rule from the guide, and it would leave a next.1 script with no entry that names its invocation.

Only text changes. Every entry keeps its id, its step and its fields.

Census

git grep -n -E "organization-ownership (--apply|--out|--dev)|--plan-file" -- packages/spec/src ':!*.test.ts'

At a58972d67b, every hit in the seven entries sits after the 18.0 sentence or under an "In that 18.x release" / "In the 18.x release that carries the upgrade path" qualifier. The one hit not in an entry is the code comment at system/migration.zod.ts:174, which is out of scope by the card's rule. The cli entry's surface (line 10) names the refused invocation and prescribes nothing.

In a rendered single-file guide (tsx scripts/build-upgrade-guide.ts --out, written to a scratch path), the sentence "18.0 supports fresh installs only" appears 12 times: 7 replacements and 5 acceptance criteria. sharing-rule-declared-mirror-retired's acceptance criteria say "18.0 upgrades no v17 database" instead.

Verification (head a58972d67b)

  • pnpm --filter @objectstack/spec build: VERDICT command-exit 0.
  • pnpm --filter @objectstack/spec test: Test Files 702 passed (702), Tests 21349 passed | 1 todo (21350).
  • pnpm --filter @objectstack/spec typecheck: exit 0. check:test-typecheck reports OK.
  • pnpm --filter @objectstack/spec check:generated: "All 14 generated artifacts are up to date", with no tracked file changed. No baseline pins this text.
  • node scripts/pm/dispatch-gates.mjs --commands derived 83 commands, and all of them were run:
    • 80 exit 0, including check:upgrade-guide, check:spec-changes, check:adr-0087-registration --base origin/main, check:doc-authoring, check:nul-bytes, check:empty-changeset and check:changeset-no-major.
    • 3 exit 3, PREREQUISITE NOT MET, so NOT MEASURED here: check:doc-formula-expressions (@objectstack/formula not built), check:dual-build-cjs-loads (workspace dist/ absent) and check:lean-entry-closure (@objectstack/objectql not built). None reads these entries. They are declared to CI.
  • No open PR touches packages/spec/src/migrations/entries/semantic/. I checked all 14 open PRs' file lists over REST.

Acceptance notes


Generated by Claude Code

…s only

Seven ADR-0087 semantic entries prescribed `os migrate organization-ownership
--out PLAN` then `--apply --plan-file PLAN`, which 18.0 refuses on every
database. Each now leads with the landed CLI wording (18.0 supports fresh
installs only and does not upgrade a v17 database: keep a v17 database on a
17.x release until the 18.x release that carries the upgrade path) and marks
the plan/apply ceremony as the 18.x release's.

Claude-Session: https://claude.ai/code/session_01D6F9axfoPzR7t8G1J7Ytzz
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tooling labels Oct 19, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

1 anchor(s) derived from 1 changed package(s); no hand-written page names any of them, so this run has nothing to list — not a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run.

What this run could not see
  • 3 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 54 of 206 client-bound route-ledger rows — the other 152 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 152: 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; 97 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.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

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 cc95f5e63e3c96acafa55378a57d06c086e7d639 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from b89566a02024b3900c10b1693c96f1fa3fa22e24 — the merge of head a58972d67b151679bb521ca9268526e242ce9bf8 into base cc95f5e63e3c96acafa55378a57d06c086e7d639, 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 b89566a02024b3900c10b1693c96f1fa3fa22e24 && git checkout b89566a02024b3900c10b1693c96f1fa3fa22e24
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin cc95f5e63e3c96acafa55378a57d06c086e7d639 a58972d67b151679bb521ca9268526e242ce9bf8 && git checkout -B drift-repro cc95f5e63e3c96acafa55378a57d06c086e7d639 && git merge --no-ff a58972d67b151679bb521ca9268526e242ce9bf8

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

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

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 19, 2026 22:02
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 19, 2026 22:02
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 19, 2026
Merged via the queue into main with commit a789148 Oct 19, 2026
42 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-24637-spec-entries-18-fresh-install-only branch October 19, 2026 23:01
os-steve pushed a commit that referenced this pull request Oct 20, 2026
Conflicts and restatements, the ceremony being open on this branch:

- runtime boot guard, its unit, kernel and dogfood pins: #24682's 18.0
  "fresh installs only" refusal gives way to the marker-based refusal that
  names the ceremony's plan and apply.
- cli.mdx: the open-ceremony text kept; #24678 and step 4's "until then the
  ceremony refuses" sentences restated; #24722's audit-mail-bodies row and
  section kept beside it.
- B2: #24661's seven 18.0 upgrade-guide entries prescribe the ceremony again
  (the ups entry keeps the full apply), pinned in
  organization-ownership-upgrade-entries.test.ts.
- metadata-lifecycle, metadata-service, capabilities, permission-sets: the
  18.0 deferral restated.
- platform-core.v18-boot-refusals revision 5.
- objectql: WALLED_ORGANIZATION_LESS_BRIDGE, isWalledOrganizationLessBridgeObject
  and the engine reader are deleted (sys_secret and sys_flow_credential are
  column-less here); the refusal names systemFields: { tenant: false }. The
  tripwire is deleted; the flow-credential walled pin is kept, renamed
  walled-flow-credential-write.test.ts.
- #24688's principal x door matrix restated over a ceremonied fixture.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014UATXWqAXqkaZkbG92ox6V
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 tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants