Repository navigation
Commit 9e2722a
fix(runtime): the organization-ownership boot refusals say what 18.0 supports and name no step of the withdrawn ceremony command (#24682)
Fixes #24651
Clause-②: no (refusal text only: the refusal code
`ORGANIZATION_OWNERSHIP_MIGRATION_REQUIRED`, the refused tables and the
boot outcome do not move)
In 18.0, `os migrate organization-ownership` refuses plan and apply on
every database (`ORGANIZATION_OWNERSHIP_UPGRADE_UNAVAILABLE`,
`NOT_IMPLEMENTED`). Three branches of the v18 boot refusal in
`packages/runtime/src/organization-ownership-boot-guard.ts` still sent
the operator to that command's `--out PLAN` and `--apply --plan-file
PLAN --backup-taken`. Each branch now closes on the sentence the landed
member of this family (PR #24635, `f89d29e38`) put into `os migrate
apply`'s drop gate and `os dev`'s way on:
> 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 upgrade it there.
A development boot (`{ dev: true }`, as `os serve --dev` composes the
guard) says "a v17 development database", the exact wording of the
landed `os dev` text. No branch names the command or any step of it.
`ceremonyCommand()` (which only built the `--dev` command name) is gone.
The `dev` option stays, and still changes the text. The refusal code,
the refused tables, `isOrganizationOwnershipBootRefusal`, the plugin's
ordering and every boot outcome are unchanged. This is the `domain:cli`
row of the family close-out #24637.
## Branch map
| branch | selected when | source | refused tables |
|:--|:--|:--|:--|
| **A, v17 shape** | `findV17ShapeTables` finds a table whose object
declares no organization column (`systemFields.tenant: false`, no
declared `organization_id`) but still has a physical `organization_id`,
and the marker is absent, unverified or unreadable |
`organizationOwnershipRefusalMessage`, `tables` not empty (was about
`:252`–`:258`) | the tables found |
| **B1, marker not verified** | no table in the v17 shape, and the
`sys_migration` row `adr-0131-organization-ownership` exists but is not
verified: a ceremony ran every step and its post-check found
discrepancies | `organizationOwnershipRefusalMessage`, `tables` empty,
marker `unverified` (was about `:239`–`:243`) | none |
| **B2, marker unreadable** | no table in the v17 shape, and a store
serves the ledger but its read of the marker threw | the same return as
B1, marker `unreadable` (was about `:239`–`:243`) | none |
| **C, column read failed** | `findV17ShapeTables` itself threw while
reading a table's columns | `assertOrganizationOwnershipMigrated`'s
`catch` (was about `:339`–`:344`) | none |
The card's ":242" is B1 and B2 (one return statement), ":256–257" is A,
and ":342–343" is C. A marker that is absent with no v17 table, and a
verified marker, still boot.
## Before and after, per branch
Rendered by importing the guard at `bfc1539fe` (before) and at this PR's
head (after) and calling it. TABLES stands for the table list. The
`--dev` before-texts are the same with `os migrate
organization-ownership --dev`.
**A, v17 shape** (marker absent; unverified and unreadable differ only
in the state clause)
- Before: "This database is still in the v17 organization-ownership
shape: TABLES still carry a physical organization_id column, and the
ceremony has not run on it. The server refuses to start rather than
serve v17 data with v18 semantics. 18.0 does not upgrade a v17 database:
keep this one on a 17.x release until the 18.x release that carries the
upgrade path, and run these steps there. Run 'os migrate
organization-ownership --out PLAN' to write and review its plan, take a
backup, then run 'os migrate organization-ownership --apply --plan-file
PLAN --backup-taken', and start again. To keep 17.x semantics, run a
17.x runtime."
- After: "This database is still in the v17 organization-ownership
shape: TABLES still carry a physical organization_id column, and the
ceremony has not run on it. The server refuses to start rather than
serve v17 data with v18 semantics. 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 upgrade it
there."
- What was kept: everything up to "v18 semantics", and the 17.x answer.
What was dropped: the two steps, "run these steps there", and "To keep
17.x semantics, run a 17.x runtime.", which now repeats "keep a v17
database on a 17.x release".
**B1, marker not verified**
- Before: "The organization-ownership ceremony has not finished on this
database: its marker (sys_migration 'adr-0131-organization-ownership')
is not verified: the post-check still found rows the ceremony has not
carried. The server refuses to start rather than serve rows of an
organization-owned object with no organization. Resolve what the apply
report names, then run 'os migrate organization-ownership --out PLAN'
again, review it, run 'os migrate organization-ownership --apply
--plan-file PLAN --backup-taken', and start again."
- After: "The organization-ownership ceremony has not finished on this
database: its marker (sys_migration 'adr-0131-organization-ownership')
is not verified: the post-check still found rows the ceremony has not
carried. The server refuses to start rather than serve rows of an
organization-owned object with no organization. 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 upgrade it there."
- Dropped: "Resolve what the apply report names", the re-plan and the
re-apply. In 18.0 nothing can verify the marker, so resolving the
report's rows does not let this database boot. The 18.x release finishes
the ceremony.
**B2, marker unreadable**
- Before: the B1 text with "its marker (sys_migration
'adr-0131-organization-ownership') could not be read" as the state. It
prescribed the same re-plan and re-apply.
- After: "The organization-ownership ceremony has not finished on this
database: its marker (sys_migration 'adr-0131-organization-ownership')
could not be read. The server refuses to start rather than serve rows of
an organization-owned object with no organization. Fix the read, then
start again. 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 upgrade it there."
- Added: "Fix the read, then start again." This branch also reaches a
fresh 18.0 database whose ledger read failed: no v17 table, and a marker
the guard could not read. On that database the true way on is the read.
Once the read answers, a database with no marker boots. The old text
sent it to an apply report it never had.
**C, column read failed**
- Before: "The server refuses to start: it could not read whether this
database is still in the v17 organization-ownership shape (ERROR), and
an unread answer is never taken for a migrated database. Fix the read,
or run the ceremony ('os migrate organization-ownership --out PLAN',
then 'os migrate organization-ownership --apply --plan-file PLAN
--backup-taken'), then start again."
- After: "The server refuses to start: it could not read whether this
database is still in the v17 organization-ownership shape (ERROR), and
an unread answer is never taken for a migrated database. Fix the read,
then start again. 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 upgrade it there."
- Kept: "Fix the read". Dropped: the command as the alternative.
## Census: `packages/runtime`
`git grep -n -E "migrate organization-ownership|--plan-file|--out
PLAN|backup-taken|ceremony" -- packages/runtime` at the base, every hit
read:
| location | what it is | disposition |
|:--|:--|:--|
| `organization-ownership-boot-guard.ts` about `:242`, `:256`–`:257`,
`:342`–`:343` | the three branches | changed (above) |
| `organization-ownership-boot-guard.ts:110` `ceremonyCommand()` | built
the command name the refusals interpolated | removed. The `dev` option
now selects "development database". |
| `organization-ownership-boot-guard.ts:19`, `standalone-stack.ts:336` |
code comments that describe the ceremony | excluded (comments). The
module docblock sentence beside `:19` ("says which command to run") was
corrected anyway, because it described this behaviour. |
| `packages/runtime/CHANGELOG.md` `:473`, `:481`, `:912` (and `:296`,
`:444`, `:900`, `:913`) | released entries naming the ceremony's steps |
not changed. Release-owned, never edited in a code PR (AGENTS.md,
Documentation Guardrails). Each entry records what its release shipped.
|
|
`seed-loader-null-organization-holder-real-driver.integration.test.ts:215`
| a runtime test pinning `'os migrate organization-ownership'` in
`@objectstack/metadata-protocol`'s seed-loader refusal | not changed.
The string lives in `packages/metadata-protocol/src/seed-loader.ts`,
outside this lane (see Acceptance notes) |
| everything else (`action-execution.ts`, `domain-handler-registry.ts`,
`flow-clone.ts`, `sandbox/quickjs-runner.ts`,
`security/security-catalog.testkit.ts`) | the word "ceremony" in
unrelated comments | not this family |
| `docs/qa/platform-checklist/areas/platform-core.json`, item
`platform-core.v18-boot-refusals` (outside `packages/runtime`) | a QA
checklist item whose title and `acceptance[1]` expected the refusal to
name the command | changed in patch round 1 (revision 4, `21f7e90f4`) |
**Met and not pre-empted:** branch A also reaches a database that 18.0
itself created, when one of its objects newly declares `systemFields: {
tenant: false }`. This PR still calls such a database "still in the v17
organization-ownership shape". The 17.x sentence is false for that
database, and this PR adds no sentence for it. That wording is the open
maintainer decision in #24638, and #24638 remains open.
## Pins and the ablation
- `organization-ownership-boot-guard.test.ts`: the old pins on the
command text are rewritten. A new block holds one pin per branch: A
(absent, unverified and unreadable markers), B1, B2, C, and a
development boot across all four. Each asserts the refusal code, the
closing text (B2 and C with "Fix the read, then start again." before
it), and that the message matches none of `os migrate
organization-ownership`, `--plan-file`, `--out PLAN`, `--backup-taken`.
- `organization-ownership-boot-guard.kernel.test.ts`: case 4 (B1 on a
real kernel) asserted `--apply --plan-file PLAN --backup-taken`. It now
asserts the 18.0 sentence and the absence.
-
`packages/qa/dogfood/test/organization-ownership-boot-refusal-order.dogfood.test.ts`
step 1 asserted the refusal contains `'os migrate
organization-ownership'`. It now asserts the 18.0 sentence and the
absence. Dogfood runs only on `main`'s full battery, not on this PR's
CI, so it was run locally (below).
- `docs/qa/platform-checklist/areas/platform-core.json`, item
`platform-core.v18-boot-refusals`, revision 3 to 4 (patch round 1,
commit `21f7e90f4`): the title and `acceptance[1]` (clause, verify)
asserted that the refusal names `os migrate organization-ownership`.
They now assert the named tables, the closing 18.0 sentence, and 0 hits
for `--out PLAN`, `--plan-file` and the command. The ⛔ on the code
literal is kept, and a history row cites #24682.
- **Ablation**, on the committed head `7ac4f50e9`: `node
scripts/ablation-replace.mjs` put branch C's old "Fix the read, or run
the ceremony ('os migrate organization-ownership --out PLAN', then '…
--apply --plan-file PLAN --backup-taken'), then start again." back. On
disk: anchor x1 to x0, replacement x0 to x1, blob `65f1c9e2` to
`dad453f6`. The unit file then ran 2 failed and 20 passed. The red pins
were "a column read that failed: fix the read first" and "a development
boot says the same … in every branch". The restore leg: blob back to
`65f1c9e2` (HEAD), `git diff HEAD` empty. The unit test imports the
guard by relative path (source), so no build or `dist` leg applies.
## Tests and gates (code at `7ac4f50e9`; the union, wide families, lint
and dogfood re-run at `21f7e90f4`, the final commit)
- `@objectstack/runtime`, every project: `pnpm --filter
@objectstack/runtime test` (project `local`) passed 425 files, 6676
tests, 19 skipped. `test:repo` (project `repo`) passed 3 files, 808
tests. `typecheck` passed: `tsc --noEmit`, plus `check:test-typecheck`
OK with the debt ledger held. `tsc -p tsconfig.test.json
--listFilesOnly` lists both edited test files.
- `@objectstack/cli`, the tests that read the boot refusal
(`apply.organization-ownership-refusal.test.ts`,
`organization-ownership.no-organization.integration.test.ts`,
`organization-ownership.declared-rule-mirrors.integration.test.ts`),
against runtime's rebuilt `dist`: 3 files and 8 tests passed. The
runtime `dist` carries the new sentence and has 0 hits of `--apply
--plan-file PLAN`.
- `@objectstack/dogfood`,
`test/organization-ownership-boot-refusal-order.dogfood.test.ts`, run
once at this head after its closure built (66 tasks, exit 0): 1 file and
5 tests passed.
- Derived gates: `node scripts/pm/dispatch-gates.mjs --commands` named
68 commands, and each exit was captured before any pipe. 67 exited 0 on
the first pass. `pnpm check:dual-build-cjs-loads` first answered
PREREQUISITE NOT MET (exit 3), because not every package had a `dist`.
After the whole-repo build it was re-run and exited 0 (111 require entry
points across 69 packages load). `--ran` reconciliation: "68 derived, 68
run, 0 NOT-MEASURED, 0 UNRUN". At `21f7e90f4` the new path adds `pnpm
check:platform-checklist` and `pnpm --filter @objectstack/lint run
check:doc-formula-expressions`. The derivation named 70 commands, and
all 70 exited 0 after the whole-repo build was restored from cache.
`--ran`: "70 derived, 70 run, 0 NOT-MEASURED, 0 UNRUN".
- Declared-wide families, all 11 exited 0:
`check:init-service-contract`, `check:live-db-isolation`,
`check:meta-type-normalized`, `check:optional-error-sink`,
`check:resume-authority-declared`, `check:route-envelope`,
`check:runner-env-posture`, `check:settings-bind-window`,
`check:startup-registry-verdict`, `check:verify-stand-in`,
`check:wildcard-fallthrough`. `pnpm lint` (`eslint .
--no-inline-config`) exited 0. At `21f7e90f4` all 11 and `pnpm lint`
were re-run and exited 0.
- `node scripts/check-platform-checklist.mjs --changed-from origin/main`
exited 0 at both heads: 3 anchors judged, 0 lost. At `21f7e90f4`, `pnpm
check:platform-checklist` exited 0 ("16 areas, 327 items").
`@objectstack/plugin-auth`'s
`checklist-refusal-envelope-consistency.test.ts`, which reads every area
file, passed 1 file and 5 tests. The dogfood file re-run at `21f7e90f4`
passed 1 file and 5 tests.
- `origin/main` has moved since this branch was cut, but nothing new
touches these files, so `main` was not merged in.
## Acceptance notes
- **Same family, outside `packages/runtime` and outside #24637's rows.**
The parent's census regex does not match a backtick right after the
command name, so it misses two strings.
`packages/metadata-protocol/src/seed-loader.ts:1739` (the seed loader's
unowned-holder refusal) says "(`os migrate organization-ownership`, then
the same command with --apply)".
`packages/metadata-core/src/legacy-organization-row.ts:78`
(`LegacyOrganizationRowsUnreadable`) says "Run `os migrate
organization-ownership` on this database first." Both are reported to
the seat to fold into #24637. They are not changed here.
- **The QA checklist clause this PR made stale is fixed here.** Patch
round 1 used the seat's in-place exemption: conditions ① to ④ hold, and
the seat measured ③. See Pins.
- The pending changeset `15214-c11-fresh-install-messages.md` (#24506)
put the 18.0 sentence ahead of the steps. It is left as it is: it
correctly describes its own change, and this PR's changeset describes
the removal of the steps.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01SYEJqDL3NXxrJRBVqaMu9T)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 045dae8 commit 9e2722a
6 files changed
Lines changed: 174 additions & 59 deletions
File tree
- .changeset
- docs/qa/platform-checklist/areas
- packages
- qa/dogfood/test
- runtime/src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3042 | 3042 | | |
3043 | 3043 | | |
3044 | 3044 | | |
3045 | | - | |
| 3045 | + | |
3046 | 3046 | | |
3047 | 3047 | | |
3048 | | - | |
| 3048 | + | |
3049 | 3049 | | |
3050 | 3050 | | |
3051 | 3051 | | |
| |||
3070 | 3070 | | |
3071 | 3071 | | |
3072 | 3072 | | |
3073 | | - | |
| 3073 | + | |
3074 | 3074 | | |
3075 | | - | |
| 3075 | + | |
3076 | 3076 | | |
3077 | 3077 | | |
3078 | 3078 | | |
| |||
3123 | 3123 | | |
3124 | 3124 | | |
3125 | 3125 | | |
| 3126 | + | |
| 3127 | + | |
| 3128 | + | |
| 3129 | + | |
| 3130 | + | |
| 3131 | + | |
3126 | 3132 | | |
3127 | 3133 | | |
3128 | 3134 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
19 | | - | |
| 19 | + | |
| 20 | + | |
20 | 21 | | |
21 | 22 | | |
22 | 23 | | |
| |||
109 | 110 | | |
110 | 111 | | |
111 | 112 | | |
112 | | - | |
| 113 | + | |
113 | 114 | | |
114 | 115 | | |
115 | 116 | | |
| |||
121 | 122 | | |
122 | 123 | | |
123 | 124 | | |
124 | | - | |
| 125 | + | |
| 126 | + | |
125 | 127 | | |
126 | 128 | | |
127 | 129 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
19 | | - | |
| 19 | + | |
| 20 | + | |
20 | 21 | | |
21 | 22 | | |
22 | 23 | | |
| |||
181 | 182 | | |
182 | 183 | | |
183 | 184 | | |
184 | | - | |
| 185 | + | |
185 | 186 | | |
186 | 187 | | |
187 | 188 | | |
| |||
191 | 192 | | |
192 | 193 | | |
193 | 194 | | |
194 | | - | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
195 | 199 | | |
196 | 200 | | |
197 | 201 | | |
| |||
0 commit comments