Repository navigation
Commit feb09db
fix(cli): os dev's in-place upgrade line names no origin for a refused development database (#24935)
Fixes #24833
Clause-②: no
Basis for the Clause-② line (the claim's, comment 6294842538): printed
text of `os dev` only. No accept set, exit code, refusal, recovered boot
or IPC message moves.
The seat ruled option A on the measurement in comment 6294804267: the
line `os dev` prints before it upgrades a refused development database
names no origin and points at the guard's own refusal. The stack half is
an acceptance note (below).
## What changed
- **`packages/cli/src/commands/dev.ts`**. The coordinator's `recover`
printed "This development database is still in the v17
organization-ownership shape — upgrading it in place (a copy is kept
first)…" for every refusal. It now prints:
```text
⟳ The organization-ownership boot guard refused this development
database (the refusal above), so os dev upgrades it in place, keeping a
copy first…
```
The line names no origin. `recover` runs for every
`OrganizationOwnershipBootRefusal`, and the guard throws one at six
places (`packages/runtime/src/organization-ownership-boot-guard.ts`: the
shape read failed, the birth write failed on an empty store, and a
marker that is absent, unverified, unreadable or from an older shape
generation). Only the absent marker means "17.x or an 18.0 pre-release
created it". The guard's own text, printed just above by the failed
boot, names what it found, so it stays the one source of that wording.
- The printing moved out of the inline closure into an exported seam,
`upgradeRefusedDevelopmentDatabase({ print, upgrade })`, so a unit test
can drive the real line. `recover` calls it with `console.log` and the
same upgrade as before. The order is unchanged: the line, then the
runtime import and the upgrade, then the warnings and the verdict lines.
The verdict line still carries the copy's path, from
`upgradeDevelopmentDatabase`'s own result.
- One comment beside the coordinator no longer says "the v17
organization-ownership shape".
- **Changeset**: `@objectstack/cli` patch, `Clause-②: no`.
Not touched (hold-offs): the guard, its refusal text and rule; the
ceremony; `utils/dev-organization-ownership-upgrade.ts` (its behaviour,
its IPC message shape and its "v18" verdict line); `serve.ts`;
`packages/core/**`; `packages/spec/**`; the `[schema-drift]` line
(#24638's); which boots `os dev` recovers; exit codes;
`content/docs/releases/`.
## End to end, on the built CLI
Fixture: a one-object define-stack scaffold; `os dev --no-watch -d
file:A.db -p 0` once; the `adr-0131-organization-ownership` row deleted
from `sys_migration` (tables, no marker: the guard's "absent" refusal);
then `os dev` again. `NODE_ENV` unset, `bin/run.js`,
`OS_TELEMETRY_DB=0`.
- `main` `19484af53` (the card's base; `packages/cli` is byte-identical
at `b42c621c0`):
```text
TIMESTAMP ERROR Plugin startup failed:
com.objectstack.organization-ownership-boot-guard
{"error":{"message":"This database carries no organization-ownership
marker: 17.x or an 18.0 pre-release (18.0.0-next.*) created it, …
[Kernel] Plugin startup failed:
com.objectstack.organization-ownership-boot-guard This database carries
no organization-ownership marker: … (plus 10 stack frames)
⟳ This development database is still in the v17 organization-ownership
shape — upgrading it in place (a copy is kept first)…
✓ Upgraded the development database to the v18 organization ownership.
The database as it was before the upgrade is copied to
backups/organization-ownership-TIMESTAMP, beside the ceremony's log. The
plan and the report are there too.
```
- This head (`0f9e4ca00d`): the same two kernel lines and frames, then
```text
⟳ The organization-ownership boot guard refused this development
database (the refusal above), so os dev upgrades it in place, keeping a
copy first…
✓ Upgraded the development database to the v18 organization ownership.
The database as it was before the upgrade is copied to
backups/organization-ownership-TIMESTAMP, beside the ceremony's log. The
plan and the report are there too.
```
The server then reached "Server is ready" and printed "✓ server started
on the upgraded database", as on `main`.
## Tests
- **New pin**,
`packages/cli/src/commands/dev-organization-ownership-recover.test.ts`
(unit tier): drives `upgradeRefusedDevelopmentDatabase` with a fake
upgrade and records each printed line. 4 cases:
- the first line carries no "v17" and names no origin (no 17.x, 18.0,
pre-release or "created");
- it names the refusal above, `os dev`, "in place" and "copy first", and
prints before the upgrade runs;
- the warnings, then the verdict line with the copy's path, and the
server boots again;
- an upgrade that did not finish prints its `✗` lines and boots nothing.
The sentence is not pinned verbatim.
- **Red on `main`**: the test file run against `main`'s `dev.ts` (blob
`17fc74e9`, restored into the tree from `19484af53` with `git restore
--source`, so not staged): 4 of 4 red, `TypeError:
upgradeRefusedDevelopmentDatabase is not a function`, because `main` has
no seam. Restored with `git checkout HEAD`; blob back to `3485d18c`,
`git diff HEAD` empty.
- **Red with `main`'s sentence in the seam** (`node
scripts/ablation-replace.mjs`, the anchor hit once; the replacement is
`main`'s two source lines byte for byte): the anchor went from 1 to 0
and the blob from `3485d18c` to `4e8a1f86`. 2 of 4 red: `expected ' ⟳
This development database is stil…' not to match /v17/i` and `… to match
/refus/i`. The other 2 stayed green. Restore: blob equals `HEAD`
(`3485d18c`), `git diff HEAD` empty.
- **Green on this head**: the new pin plus
`src/utils/dev-organization-ownership-upgrade.test.ts`, 2 files, 10
passed.
- **Unit subset**: every unit test that imports `commands/dev`, plus the
`dev-*` utilities, `port-contract-single-source`,
`console-route-ledger.conformance` and
`test/vitest-tiers-partition.test.ts`: 18 files, 246 passed.
- The full `@objectstack/cli` unit project did not finish inside the
10-minute foreground cap here; it is left to CI's `Test Core`. The
integration tier is left to CI as well: the diff touches no integration
file and no spawn entry.
- `pnpm --filter @objectstack/cli typecheck` (`tsc --noEmit` and
`check:test-typecheck`): exit 0. The new test is in the `tsconfig.json`
program (`--listFilesOnly`: 1 hit).
## Control: a bare `os serve` refusal is unchanged
`os serve objectstack.config.ts -p 0` over the same unmarked file,
`OS_DATABASE_URL=file:A.db`, `NODE_ENV` unset. It exited 1 on both
trees. Its whole output on `19484af53` and on this head, with timestamps
and the temp directory normalised, is byte-identical: 23 lines, `diff`
exit 0. That output is the kernel's ERROR line, the `[Kernel]` line with
its frames, the CLI's `✗` refusal line and the boot diagnostics.
`serve.ts` does not import `dev.ts`.
## Gates
All on the final head `0f9e4ca00d`, each exit code captured before any
pipe.
- `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` derived 67 commands from the 3 changed paths
(merge base `b42c621c0`). All 67 exited 0. Two of them, `pnpm
check:dual-build-cjs-loads` and `pnpm check:i18n-coverage`, first exited
3 (`PREREQUISITE NOT MET`: no `dist` for packages outside the CLI
closure). After a full `turbo run build`, both exited 0
(`check-i18n-coverage: OK (14 config(s), 621 baselined untranslated
string(s), none new)`).
- The 11 families listed under "Declared WIDE population" all 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` and
`check:wildcard-fallthrough`.
- `--ran`: `✓ dispatch-gates --ran: 67 derived famil(ies) accounted for
— 67 run, 0 NOT-MEASURED (a DERIVED zero — all 67 recorded an exit code
and none of them is 3).`
- `pnpm lint` (`eslint . --no-inline-config`): exit 0.
- Left to CI, not run here: the four type-check lanes, `Test Core` (the
full `@objectstack/cli` unit project and the integration tier included)
and `Build Core`.
## Acceptance notes
- **The stack half stays, by the seat's ruling (option A).** On an `os
dev` over a refused development database, two lines still precede the
new one, both from the kernel: `packages/core/src/kernel.ts:568`
(`this.logger.error('Plugin startup failed: …', result.error)`; the
logger writes error level straight to `process.stderr`,
`packages/core/src/logger.ts:351` and `:386`) and `:571`
(`console.error('[Kernel] Plugin startup failed: …', origMsg,
origStack)`, with no level gate). Measured with stdout and stderr
captured apart, the two lines and the 10 frames are all on stderr.
`serve.ts`'s boot-quiet window replaces only `process.stdout.write`,
`console.log` and `console.debug`, and its catch runs after the kernel
has printed. A developer meets this once per development database: after
the upgrade the marker is verified. If a puller appears, the shape is
option D of comment 6294804267: a host-gated kernel change that only the
`os dev` child sets, so the bare `os serve` output stays as Zone 1
ruled.
- **Bare `os serve` prints the guard's refusal three times**: the
kernel's ERROR line (its JSON carries the message and the stack), the
kernel's `[Kernel]` line with 10 frames, and then the CLI's own `✗` line
(case C in comment 6294804267, re-measured above). Zone 1 keeps this
output as it is, and the same two kernel lines are the ones in the note
above.
- **The card's "#24827" case no longer reaches this path** since
`19484af53`. Measured: `os migrate apply --yes` on an empty file writes
the birth marker, and `os dev` over that file reaches "Server is ready"
with no refusal and no upgrade.
- **Not edited, outside the surface**: the docblock of
`utils/dev-organization-ownership-upgrade.ts` and a comment in
`serve.ts` still say "the v17 organization-ownership shape". Neither is
printed.
- **Repro fixture**: a one-object scaffold with the marker row deleted,
not the card's 18.0.0-next.5 `examples/app-showcase` database. It takes
the same "absent" refusal and the same `recover` branch. It has no
retired column, so no `[schema-drift]` lines appear.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01LmjU2x1faLZ39DVTFyVca6)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 7169612 commit feb09db
3 files changed
Lines changed: 172 additions & 25 deletions
File tree
- .changeset
- packages/cli/src/commands
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 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 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
19 | | - | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
20 | 24 | | |
21 | 25 | | |
22 | 26 | | |
| |||
247 | 251 | | |
248 | 252 | | |
249 | 253 | | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
250 | 290 | | |
251 | 291 | | |
252 | 292 | | |
| |||
725 | 765 | | |
726 | 766 | | |
727 | 767 | | |
728 | | - | |
729 | | - | |
| 768 | + | |
| 769 | + | |
730 | 770 | | |
731 | 771 | | |
732 | | - | |
| 772 | + | |
| 773 | + | |
733 | 774 | | |
734 | 775 | | |
735 | 776 | | |
| |||
818 | 859 | | |
819 | 860 | | |
820 | 861 | | |
821 | | - | |
822 | | - | |
823 | | - | |
824 | | - | |
825 | | - | |
826 | | - | |
827 | | - | |
828 | | - | |
829 | | - | |
830 | | - | |
831 | | - | |
832 | | - | |
833 | | - | |
834 | | - | |
835 | | - | |
836 | | - | |
837 | | - | |
| 862 | + | |
| 863 | + | |
| 864 | + | |
| 865 | + | |
| 866 | + | |
| 867 | + | |
| 868 | + | |
| 869 | + | |
| 870 | + | |
| 871 | + | |
| 872 | + | |
| 873 | + | |
| 874 | + | |
| 875 | + | |
| 876 | + | |
| 877 | + | |
| 878 | + | |
| 879 | + | |
838 | 880 | | |
839 | | - | |
840 | | - | |
841 | | - | |
842 | | - | |
| 881 | + | |
| 882 | + | |
843 | 883 | | |
844 | 884 | | |
845 | 885 | | |
| |||
0 commit comments