Repository navigation
fix(cli): os dev's in-place upgrade line names no origin for a refused development database - #24935
Conversation
…d database The line os dev prints before it upgrades a development database the organization-ownership boot guard refused said the database was "still in the v17 organization-ownership shape" for every refusal. It now names no origin and points at the guard's refusal printed above it; the copy's path stays on the verdict line. Claude-Session: https://claude.ai/code/session_01LmjU2x1faLZ39DVTFyVca6 Co-authored-by: Claude <noreply@anthropic.com>
…e line Claude-Session: https://claude.ai/code/session_01LmjU2x1faLZ39DVTFyVca6 Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift Check2 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
Coarse fallback — 29 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 5a1c586d32fa215de689bd6cc88f6bcd55f2b08a && git checkout 5a1c586d32fa215de689bd6cc88f6bcd55f2b08a
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 71696121a64d8bd057fac969a72a84295890ed37 0f9e4ca00dcd7c7b4482bdaab3f76886eb9ff9a4 && git checkout -B drift-repro 71696121a64d8bd057fac969a72a84295890ed37 && git merge --no-ff 0f9e4ca00dcd7c7b4482bdaab3f76886eb9ff9a4
node scripts/docs-audit/affected-docs.mjs --json 71696121a64d8bd057fac969a72a84295890ed37 |
席位核对 · ACCEPT
Accepted deviations:
Acceptance notes (one line each):
Landing: through the merge queue by this seat once every check on this head reads Generated by Claude Code |
Fixes #24833
Clause-②: no
Basis for the Clause-② line (the claim's, comment 6294842538): printed text of
os devonly. 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 devprints 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'srecoverprinted "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:The line names no origin.
recoverruns for everyOrganizationOwnershipBootRefusal, 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.recovercalls it withconsole.logand 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, fromupgradeDevelopmentDatabase's own result.One comment beside the coordinator no longer says "the v17 organization-ownership shape".
Changeset:
@objectstack/clipatch,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 bootsos devrecovers; 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 0once; theadr-0131-organization-ownershiprow deleted fromsys_migration(tables, no marker: the guard's "absent" refusal); thenos devagain.NODE_ENVunset,bin/run.js,OS_TELEMETRY_DB=0.main19484af53(the card's base;packages/cliis byte-identical atb42c621c0):This head (
0f9e4ca00d): the same two kernel lines and frames, thenThe server then reached "Server is ready" and printed "✓ server started on the upgraded database", as on
main.Tests
packages/cli/src/commands/dev-organization-ownership-recover.test.ts(unit tier): drivesupgradeRefusedDevelopmentDatabasewith a fake upgrade and records each printed line. 4 cases:os dev, "in place" and "copy first", and prints before the upgrade runs;✗lines and boots nothing.The sentence is not pinned verbatim.
main: the test file run againstmain'sdev.ts(blob17fc74e9, restored into the tree from19484af53withgit restore --source, so not staged): 4 of 4 red,TypeError: upgradeRefusedDevelopmentDatabase is not a function, becausemainhas no seam. Restored withgit checkout HEAD; blob back to3485d18c,git diff HEADempty.main's sentence in the seam (node scripts/ablation-replace.mjs, the anchor hit once; the replacement ismain's two source lines byte for byte): the anchor went from 1 to 0 and the blob from3485d18cto4e8a1f86. 2 of 4 red:expected ' ⟳ This development database is stil…' not to match /v17/iand… to match /refus/i. The other 2 stayed green. Restore: blob equalsHEAD(3485d18c),git diff HEADempty.src/utils/dev-organization-ownership-upgrade.test.ts, 2 files, 10 passed.commands/dev, plus thedev-*utilities,port-contract-single-source,console-route-ledger.conformanceandtest/vitest-tiers-partition.test.ts: 18 files, 246 passed.@objectstack/cliunit project did not finish inside the 10-minute foreground cap here; it is left to CI'sTest 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 --noEmitandcheck:test-typecheck): exit 0. The new test is in thetsconfig.jsonprogram (--listFilesOnly: 1 hit).Control: a bare
os serverefusal is unchangedos serve objectstack.config.ts -p 0over the same unmarked file,OS_DATABASE_URL=file:A.db,NODE_ENVunset. It exited 1 on both trees. Its whole output on19484af53and on this head, with timestamps and the temp directory normalised, is byte-identical: 23 lines,diffexit 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.tsdoes not importdev.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/objectstackderived 67 commands from the 3 changed paths (merge baseb42c621c0). All 67 exited 0. Two of them,pnpm check:dual-build-cjs-loadsandpnpm check:i18n-coverage, first exited 3 (PREREQUISITE NOT MET: nodistfor packages outside the CLI closure). After a fullturbo run build, both exited 0 (check-i18n-coverage: OK (14 config(s), 621 baselined untranslated string(s), none new)).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-inandcheck: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.Test Core(the full@objectstack/cliunit project and the integration tier included) andBuild Core.Acceptance notes
os devover 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 toprocess.stderr,packages/core/src/logger.ts:351and: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 onlyprocess.stdout.write,console.logandconsole.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 theos devchild sets, so the bareos serveoutput stays as Zone 1 ruled.os serveprints 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.19484af53. Measured:os migrate apply --yeson an empty file writes the birth marker, andos devover that file reaches "Server is ready" with no refusal and no upgrade.utils/dev-organization-ownership-upgrade.tsand a comment inserve.tsstill say "the v17 organization-ownership shape". Neither is printed.examples/app-showcasedatabase. It takes the same "absent" refusal and the samerecoverbranch. It has no retired column, so no[schema-drift]lines appear.Generated by Claude Code