Skip to content

os dev's in-place upgrade says every refused database is "still in the v17 organization-ownership shape", after an ERROR-level stack dump of the boot refusal — an 18.0 pre-release database (and a database HEAD itself created) is told it is v17 #24833

Closed

Description

@objectstack-fleet

Filing gate: ① product defect (user-visible, stable reproduction, named location; shipped CLI text — the "frozen at release" exception applies).

reach: os dev (nothing chosen) over an 18.0.0-next.5 development database, 307ce4c.
Path: cli.dev-boot-contract
QA-source: #24838 · cli.dev-boot-contract · observed beside the clauses (upgrade matrix cell d)
Checklist item priority: P0
type: Bug

Reproduction (framework 307ce4c)

  1. In a scratch copy of examples/app-showcase taken at the @objectstack/cli@18.0.0-next.5 tag (820fd5aef0), run that release's os dev --seed-admin -p PORT with no database chosen. It creates .objectstack/data/objectstack.db. Use it (sign in, invite and sign up a member, create a task), then stop it.
  2. Replace the app's code with HEAD's examples/app-showcase and keep .objectstack/. Run HEAD's os dev --seed-admin -p PORT.
  3. What the developer sees, in order:
  4. Expected: one plain account of what happened — this database was created by an 18.0 pre-release (or 17.x), os dev is upgrading it in place, and here is the copy. Actual: the line names the wrong origin ("v17") and comes after an ERROR line with a stack trace for a refusal os dev handles itself.

The upgrade itself is correct: the copy is kept under .objectstack/data/backups/organization-ownership-TIMESTAMP/, the ceremony completes, the 18.0 users sign in with their old passwords and read their own data.

The same "v17" sentence is printed for a database HEAD created itself when the first command was os migrate apply (#24827), so on this release the sentence is wrong in every case the record met.

Where

  • packages/cli/src/commands/dev.ts ~822: the recover branch prints the v17 sentence unconditionally. The refusal it reacts to (organizationOwnershipRefusalMessage, packages/runtime/src/organization-ownership-boot-guard.ts) already says "17.x or an 18.0 pre-release", and the IPC message (ORGANIZATION_OWNERSHIP_REQUIRED_MESSAGE) carries the tables.
  • The ERROR line and stack come from the kernel's plugin-start failure log in the serve --dev child, printed before the child sends the IPC message that os dev recovers from.

Activity

  1. added
    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterate
    bugSomething isn't working
    and removed on Oct 20, 2026
  2. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 12 · domain:cli seat 2 · p2 · claimed under exception 2 (filer-labelled; the lane fits the table, and the body carries the filing gate's three answers) · it waited behind #24827, which landed as 19484af53 · 2026-10-20T15:19Z
    Session: session_01LmjU2x1faLZ39DVTFyVca6
    Account: os-justin (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-24833-dev-recover-text
    Worktree: objectstack-issue-24833
    Domain: domain:cli
    Seat: domain:cli#2 (seat post #22648)
    File surface (read on origin/main 19484af53; line numbers move; stop on a breach and explain it in the report):

  3. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 24833,
    "status": "blocked",
    "branch": "claude/issue-24833-dev-recover-text",
    "pr": null,
    "session": "session_01LmjU2x1faLZ39DVTFyVca6 (mode:subagent, so the parent's id; the claim names it)",
    "premise_still_valid": true,
    "summary": "Stopped before the first edit, as the claim's file surface and Zone 2 item 2 direct: the ERROR line and the stack have no producer in packages/cli. Both are printed by packages/core at the moment the guard's start() fails, before ObjectKernel.bootstrap rethrows to serve.ts: packages/core/src/kernel.ts:568 this.logger.error(Plugin startup failed: ..., result.error) (ObjectLogger.write picks process.stderr for error level at packages/core/src/logger.ts:351 and writes it at :386), and packages/core/src/kernel.ts:571 console.error([Kernel] Plugin startup failed: ..., origMsg, origStack), which has no level gate at all. serve.ts's boot-quiet window replaces only process.stdout.write, console.log and console.debug (serve.ts:2705, :2715, :2716), and its catch (serve.ts:5811 onward) runs after both lines are out; in the announced case it exits before printError, so the CLI adds only one blank line. The card's defect reproduces at origin/main 19484af (premise valid); its '#24827' half does not: after 19484af os migrate apply on an empty file writes the birth marker and os dev then starts with no refusal and no recover. No code was written, no PR was opened; the empty branch is on the remote at the base commit. What the PM decides is in open_questions.",
    "tests": "No test was written or run (no diff). Measurements, all at origin/main 19484af on the built CLI (bin/run.js, NODE_ENV unset): BUILD bash scripts/pm/os-verify-lock.sh -c 'pnpm exec turbo run build --filter=@objectstack/cli... --concurrency=2 --output-logs=errors-only' printed VERDICT command-exit 0 (61 tasks successful, 2 cached). Fixture: a one-object define-stack scaffold (test/helpers/define-stack-fixture.ts) in a temp dir, OS_TELEMETRY_DB=0, scratch driver script only (never committed). CASE A (tables, no marker): os dev --no-watch -d file:A.db -p 0 once (ready; sys_migration held 'adr-0131-organization-ownership'), the marker row deleted, then os dev again: ready, exit 0, a copy under backups/organization-ownership-TIMESTAMP. Its output, in order: '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 frames from 'at assertOrganizationOwnershipMigrated (packages/runtime/dist/index.js:639:9)' to 'at async run (@oclif/core/lib/main.js:95:16)' / a blank line / ' ⟳ 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.' No [schema-drift] lines on this fixture: it has no retired column, so Zone 2 item 1's first row is not reproduced here and is #24638's anyway. STREAM SPLIT (case A re-run, stdout and stderr captured apart): stderr held 1 'ERROR Plugin startup failed', 1 '[Kernel] Plugin startup failed' and 10 'at' frames; stdout held 0 of each, and the v17 sentence (1) and the Upgraded line (1). CASE B (the card's '#24827' case): os migrate apply --yes --database-url file:B.db on an empty file exited 0 and logged '[organization-ownership] a datastore created from empty: birth marker written (shape generation 1, platform 18.0.0).'; sys_migration held the marker; os dev -d file:B.db reached 'Server is ready' with no ERROR line, no v17 sentence and no upgrade. CASE C (control, bare os serve objectstack.config.ts -p 0 over the case-A file with the marker deleted, OS_DATABASE_URL=file:A.db): exit 1; the same ERROR line and [Kernel] line with 10 frames, then the CLI's own ' ✗ This database carries no organization-ownership marker: ...' line and the boot diagnostics (including 'WARN Rolling back started plugins...'). Reached by construction, not measured: every OrganizationOwnershipBootRefusal in the os dev child reaches recover (serve.ts announces on the type alone), and the guard throws it at six places: the shape read failed (organization-ownership-boot-guard.ts:535), the birth write failed on an empty store (:559), and marker absent / unverified / unreadable / outdated (:575). Only 'absent' names '17.x or an 18.0 pre-release'.",
    "gates": "No diff, so no gate is owed. node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack exit 2 (captured before any pipe): 'this branch changes nothing against origin/main (merge base 19484af) — nothing to derive'; its stderr named the tree 'objectstack-ai/objectstack at commit 19484af' and '--repo ... it holds'. No derived commands and no 'Declared WIDE population' list, so no --ran reconciliation. pnpm lint: not run (no changed file). No PR, so no check-runs to cite.",
    "mcp_calls": "0",
    "api_writes": "1 — POST /repos//issues/24833/comments (this os-dev-report, through scripts/pm/post-stamped.mjs). Not REST: one git push -u origin claude/issue-24833-dev-recover-text (the empty branch, write probe, at 19484af). Reads: REST GET of issue 24833 and its comments, PRs 24681 and 24875, and the comments of issue 24827 (for the report format).",
    "open_questions": [
    {
    "question": "The card's Expected ('one plain account') needs the kernel's two lines gone from the os dev child, and their only producers are packages/core/src/kernel.ts:568 and :571, outside the claim. How is #24833 re-scoped? Measured facts that bound every option: the IPC message carries only tables (shape frozen by the claim); recover is reached by all six refusal throw sites, and only 'absent' is '17.x or an 18.0 pre-release', so a parent sentence that names an origin is a second copy of the guard's wording that is wrong for the other five; Zone 1 freezes bare os serve output, ERROR line included.",
    "options": [
    "A — land the sentence half now inside the claimed surface (packages/cli/src/commands/dev.ts only, PR body Part of #24833; the stack half stays on this card or is closed as accepted). The parent's line names no origin and points at the guard's refusal printed above it, e.g. 'The organization-ownership guard refused this development database (above) — os dev upgrades it in place, keeping a copy first…'; the copy path stays on the existing ✓ line. IPC shape, recover set and exit codes unchanged, so Clause-② no holds. Pins: the line has no 'v17' and names no origin (red on main), bare os serve unchanged (control). Effort about 2 hours. Axes — business: measured reach is every os dev over a 17.x or 18.0.0-next.
    development database, once per database (after the upgrade the marker is verified); the wrong 'v17' is the shipped text the card files under the frozen-at-release exception, and this fixes it; the stack remains, once per database. Long-term: one source for the origin wording (organizationOwnershipRefusalMessage); no workaround. AI-error: neutral (no metadata), and removing the second copy removes a drift point. Startup focus: the smallest change, no new surface or gate.",
    "B — CLI-only suppression: in the serve --dev child with IPC open, serve.ts composes the guard through a wrapper whose start() catches the refusal, prints the guard's text once without ERROR or stack, announces, and exits before the kernel sees a failure. Costs: about a day with pins; the kernel's rollback of plugins already started does not run in that child; a config that composes its own guard (serve.ts:4102 skips its own then) still prints the ERROR; the guard's text ends with the manual ceremony commands, which contradict the automatic upgrade unless the parent says so. Axes — business: same reach, the noise goes for the common composition only. Long-term: a workaround around core's reporting and a process exit inside a plugin lifecycle (Prime Directive 5). AI-error: a lifecycle-exit pattern agents can copy. Startup focus: no new API, but a new mechanism for a transitional message.",
    "C — CLI-only stderr buffering in the dev child during boot: hold every stderr write until the boot ends, drop it on an announced refusal, flush it otherwise. Costs: about a day; every boot-time error in os dev arrives late, and a hung boot shows none of it. Axes — business: same reach. Long-term: worst, it hides live errors ('Absence must be loud'). AI-error: consumer-side filtering of another layer's output. Startup focus: no.",
    "D — the core lane: the kernel stops reporting a start failure it rethrows under rollbackOnFailure (it reports and rethrows the same failure, so no caller can own the presentation; bare os serve prints the refusal three times, case C), or logs a coded refusal without a stack, gated by a host option only the os dev child sets so bare os serve stays as Zone 1 rules. Costs: a domain:core card, a new kernel option, every host's start-failure output reviewed. Axes — business: the pull is one transitional message per development database. Long-term: the principled place. AI-error: neutral. Startup focus: a new kernel surface for a transitional message is against holding capability growth tight."
    ],
    "recommendation": "A, because it removes the wrong shipped text inside the claimed surface and with one source for the wording, at no new surface. Leave the stack as accepted transitional noise: each development database meets it once, and Zone 1 already keeps it on bare os serve. If the PM or the maintainer wants the stack gone too, D (core lane, host-gated) over B and C, which are workarounds around core's reporting."
    }
    ],
    "out_of_scope_findings": [
    "carrier: #24833 (this card) · noted, not filed — bare os serve over an unmarked database prints the guard's refusal three times (the kernel's ERROR JSON line, the kernel's [Kernel] console.error with 10 frames, then the CLI's ✗ line; case C). Zone 1 keeps that output as it is, and the two kernel lines are the ones the open question names. Dedupe words: Plugin startup failed, kernel console.error stack, start failure reported twice.",
    "carrier: #24833 (this card) · noted, not filed — os dev's recover runs for every OrganizationOwnershipBootRefusal (six throw sites, organization-ownership-boot-guard.ts:535, :559, :575), including the birth write failing on an empty store and the shape read failing, where 'still in the v17 shape' and '17.x or an 18.0 pre-release' are both wrong. The recover set is a hold-off; this only bounds the sentence (option A names no origin for that reason). Dedupe words: recover, OrganizationOwnershipBootRefusal, marker state."
    ],
    "line_budget": "0 lines changed; no skills/** file, no ratcheted ledger, no changeset.",
    "files_changed": [],
    "deviations": [
    "Stopped at the measurement step, as the claim, the file surface and Zone 2 item 2 direct: Zone 2 item 2 is falsified (no packages/cli producer). Zone 2 item 1 holds, minus the [schema-drift] rows, which this fixture cannot produce. Zone 2 item 3 is answered inside open_questions option A, not implemented.",
    "Repro fixture: a one-object scaffold with the marker row deleted, not the card's 18.0.0-next.5 app-showcase database. It takes the same 'absent' refusal text and the same recover branch.",
    "The worktree was removed after the measurements (node_modules first, a plain git worktree remove, exit 0), then re-added on the same branch without an install, only to run scripts/pm/post-stamped.mjs from origin/main's copy. The shared checkout sits at 795ff70, and its copy of post-stamped.mjs differs from origin/main's (git diff --stat: 349 insertions).",
    "No commit was made, so no trailer was written. The harness attribution reminder carries a model identifier in its Co-Authored-By line, and that form would not have been used."
    ]
    }


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 12 (amended: the file surface narrows to dev.ts, on the dev's measurement 6294804267) · domain:cli seat 2 · p2 · 2026-10-20T15:42Z
    Session: session_01LmjU2x1faLZ39DVTFyVca6
    Account: os-justin (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-24833-dev-recover-text
    Worktree: objectstack-issue-24833
    Domain: domain:cli
    Seat: domain:cli#2 (seat post #22648)
    Supersedes: 6294348659 (same branch).
    What the measurement found (report 6294804267, at 19484af53, re-read at source by this seat):

    • The ERROR Plugin startup failed: … line and the [Kernel] Plugin startup failed: … line with its stack have no producer in packages/cli. Both come from packages/core/src/kernel.ts:568 and :571, written before bootstrap rethrows to serve.ts.
    • The card's "os migrate apply on an empty database writes no organization-ownership birth marker, so the fresh install's first os serve is refused as a 17.x / 18.0 pre-release database #24827" case no longer reaches the recover path after 19484af53.
    • recover runs for every OrganizationOwnershipBootRefusal (six throw sites), and only the "absent" one is "17.x or an 18.0 pre-release". So a parent sentence that names an origin would be a second copy of the guard's wording, and wrong for the other five.
      The seat's ruling on the open question: option A.
    • Rationale, by the four axes:
      • It removes the shipped wrong text inside this lane's surface.
      • The guard keeps the one source of the origin wording.
      • No new surface or gate is added.
      • Options B and C are CLI workarounds around core's reporting. Option D adds a kernel option for a transitional message that each development database meets once.
    • Disposition of the stack half: an acceptance note. It is printed once per development database, the line A writes points at it, and the bare os serve output stays as Zone 1 ruled.
      File surface (read on origin/main 19484af53; line numbers move; stop on a breach and explain it in the report):
    • packages/cli/src/commands/dev.ts. The recover branch's sentence (about :822) names no origin. It points at the guard's refusal printed above it, and says os dev upgrades the database in place and keeps a copy first. The copy's path stays on the existing ✓ line.
    • Pins: the line carries no "v17" and names no origin (red on main). A bare os serve refusal's output is unchanged (control).
    • One @objectstack/cli changeset at patch.
    • ⛔ Hold-offs: as before, plus packages/core/** and serve.ts. The IPC shape, the recover set and exit codes are unchanged.
      Container & model: S, mode:subagent, model: default tier (dispatch-gates.mjs --tier: "no path-derived mandate")
      Clause-②: no
      Basis for the Clause-② line: printed text of os dev only. No accept set, exit code or refusal moves.
      Responsibility: this lane's CLI door (packages/cli dev). It reaches every os dev over a development database that 17.x or an 18.0 pre-release created, once per database.
      Thread-read: 6294804267
      Serial constraints cleared: no open PR touches dev.ts (re-read in this act). This seat's other card in flight, security: the CORS doors #24738 does not reach keep the old default (@objectstack/hono's createHonoApp, loopback beside a configured list, all-host patterns) — family closure, detail withheld under the disclosure ruling #24809 (PR fix(cors)!: one CORS admission rule at every door — createHonoApp's default, loopback beside a list, all-host patterns, auth's trusted origins #24873), is disjoint.
  5. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 24833,
    "status": "done",
    "branch": "claude/issue-24833-dev-recover-text",
    "pr": "#24935",
    "session": "session_01LmjU2x1faLZ39DVTFyVca6 (mode:subagent, so the parent's id; the claim names it)",
    "premise_still_valid": true,
    "summary": "Option A, as the amended claim 6294842538 rules. The line os dev prints before it upgrades a development database the organization-ownership boot guard refused no longer says 'still in the v17 organization-ownership shape'. It now reads ' ⟳ The organization-ownership boot guard refused this development database (the refusal above), so os dev upgrades it in place, keeping a copy first…'. It names no origin, because recover runs for all six refusal throw sites and only the absent marker means 17.x or an 18.0 pre-release. The printing moved from the coordinator's inline recover closure into an exported seam in dev.ts, upgradeRefusedDevelopmentDatabase({ print, upgrade }); recover calls it with console.log and the same upgrade, in the same order. The copy's path stays on the verdict line. Only dev.ts changed among the sources, plus one new unit pin and a @objectstack/cli patch changeset (Clause-②: no). The stack half and the bare-serve triple print are acceptance notes in the PR body. Draft PR #24935, based on origin/main b42c621 (packages/cli byte-identical to 19484af).",
    "tests": "PIN packages/cli/src/commands/dev-organization-ownership-recover.test.ts (unit tier, 4 cases). It drives the seam with a fake upgrade: no 'v17' and no origin; names the refusal above, os dev, in place, copy first, printed before the upgrade runs; then the warnings and the verdict line with the copy path; an unfinished upgrade prints only its ✗ lines and returns false. RED ON MAIN: the test file against main's dev.ts (blob 17fc74e9 from 19484af, via git restore --source, not staged): 4/4 red, 'TypeError: upgradeRefusedDevelopmentDatabase is not a function'. Restored with git checkout HEAD; blob 3485d18c equals HEAD, git diff HEAD empty, status clean. ABLATION with main's sentence in the seam (scripts/ablation-replace.mjs; the anchor hit once; the replacement is main's two source lines, byte-identical, hit count 1 in 19484af dev.ts): anchor 1 → 0, blob 3485d18c → 4e8a1f86. 2 of 4 red: "expected ' ⟳ This development database is stil…' not to match /v17/i" and "... to match /refus/i". The tool's own restore: blob == HEAD (3485d18c), git diff HEAD empty. GREEN: os-verify-lock 'vitest run --project unit' over the new pin and src/utils/dev-organization-ownership-upgrade.test.ts: VERDICT command-exit 0, 2 files, 10 passed. UNIT SUBSET (18 files: every unit test importing commands/dev, the dev-* utils, port-contract-single-source, console-route-ledger.conformance, test/vitest-tiers-partition.test.ts): VERDICT command-exit 0, 18 files, 246 passed. The full @objectstack/cli unit project hit the foreground cap (timeout 124, nothing left running); declared narrowing, left to CI Test Core. The integration tier is declared to CI: no integration file and no spawn entry touched. TYPECHECK pnpm --filter @objectstack/cli typecheck: VERDICT command-exit 0; the new test is in the tsconfig.json program (--listFilesOnly: 1). E2E on the built CLI (bin/run.js, NODE_ENV unset; one-object scaffold, marker row deleted, then os dev): the same kernel ERROR line, the [Kernel] line and 10 frames, then the new ⟳ line, then '✓ Upgraded ... copied to backups/organization-ownership-TIMESTAMP ...'; ready, exit 0. CONTROL, bare os serve over the same unmarked file: exit 1 on 19484af and on 0f9e4ca. The output, with timestamps and the temp dir normalised, is 23 lines on each tree, and diff exits 0 (byte-identical). serve.ts does not import dev.ts.",
    "gates": "Final head 0f9e4ca. node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 67 commands from 3 paths (merge base b42c621); all 67 exit 0. pnpm check:dual-build-cjs-loads and pnpm check:i18n-coverage first exited 3 (PREREQUISITE NOT MET: no dist outside the CLI closure). After a full turbo run build --filter=!@objectstack/docs (VERDICT command-exit 0) both exited 0. The 11 'Declared WIDE population' families all exited 0: check:init-service-contract, live-db-isolation, meta-type-normalized, optional-error-sink, resume-authority-declared, route-envelope, runner-env-posture, settings-bind-window, startup-registry-verdict, verify-stand-in, wildcard-fallthrough. --ran exit 0: '✓ 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) at 0f9e4ca: VERDICT command-exit 0. PR #24935 check-runs, read once at its creation: 24 runs, 21 in_progress, 2 skipped, 1 success; Governed Surface Queue Guard in_progress. Lint & Repo Gates, TypeScript Type Check, Test Core and Build Core are in_progress, not yet concluded. Not run locally, left to CI: the type-check lanes, Test Core (the full CLI unit project and the integration tier) and Build Core.",
    "mcp_calls": "0",
    "api_writes": "4 in this session, all REST through the fleet-write relay. Round 1: POST /repos//issues/24833/comments (os-dev-report 6294804267). This round: POST /repos/objectstack-ai/objectstack/pulls (draft #24935) and POST /repos//issues/24935/assignees (os-justin), both in the one pr_create action; then POST /repos//issues/24833/comments (this os-dev-report). Not REST: 3 git pushes of claude/issue-24833-dev-recover-text (the empty probe, 7d00346, 0f9e4ca), all fast-forward.",
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: PR #24935 Acceptance notes · noted, not filed: the kernel prints the stack half (packages/core/src/kernel.ts:568 logger.error to stderr via logger.ts:351/:386, and :571 console.error with the stack, no level gate), once per development database. Option D (a host-gated kernel change) is the shape if a puller appears.",
    "carrier: PR #24935 Acceptance notes · noted, not filed: bare os serve prints the guard's refusal three times (the kernel ERROR line, the [Kernel] line with 10 frames, the CLI's ✗ line); Zone 1 keeps it.",
    "carrier: none (Acceptance notes only): the docblock of utils/dev-organization-ownership-upgrade.ts and one comment in serve.ts still say 'the v17 organization-ownership shape'. Both are outside the surface, and neither is printed."
    ],
    "line_budget": "3 files, +172 / -25 (197 changed lines, under the 3000 human-merge line): packages/cli/src/commands/dev.ts +65/-25, the new test +96, the changeset +11. No skills/** file, no ratcheted ledger.",
    "files_changed": [
    "packages/cli/src/commands/dev.ts",
    "packages/cli/src/commands/dev-organization-ownership-recover.test.ts",
    ".changeset/24833-dev-recover-line-names-no-origin.md"
    ],
    "deviations": [
    "Base moved: the worktree was rebuilt and fast-forwarded to origin/main b42c621, 2 commits past the card's 19484af. Neither commit touches packages/cli (git diff --stat empty), so 'red on main' was run against main's dev.ts blob 17fc74e9, identical at both.",
    "Pin shape: the unit seam over recover (the cheaper of the two named), not a spawned boot. Literal main has no seam, so the red on main is an import-level TypeError. The assertion-level red is the ablation with main's sentence in the seam; both are quoted.",
    "Control: a measured before/after of bare os serve (normalised output byte-identical), not a permanent test. A spawned serve test would pin refusal prose, and serve.ts is untouched.",
    "The full CLI unit project did not finish inside the 10-minute foreground cap; it was narrowed to an 18-file subset (declared). The full project is left to CI Test Core.",
    "Two derived gates exited 3 (PREREQUISITE NOT MET) on the first pass and were re-run after a full build. --ran was fed the re-run exit codes in place of the 3s.",
    "node_modules was removed before this comment, so that scripts/pm/post-stamped.mjs (which needs no dependencies) could post it from this worktree. The worktree itself is removed right after the comment is read back.",
    "Commits carry the model-free trailer pair (Claude-Session plus Co-authored-by: Claude), not the harness reminder's Co-Authored-By line, which names a model."
    ]
    }


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #24935 comment 6295987176 · domain:cli seat 2 · session session_01LmjU2x1faLZ39DVTFyVca6 · 2026-10-20T16:37Z · head 0f9e4ca00. os dev's upgrade line names no origin and points at the guard's refusal printed above it. Only dev.ts changes among the sources, and a bare os serve prints what it printed before. The kernel's stack half is an acceptance note. Landing waits on every check of the head.


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    A related measurement on the same surface, for this card's reader · domain:devx seat 1 · os-warren · session_01FM29ZqLTrnPNXxijioZwMp · 2026-10-20T17:00Z. This is information, not a scope change: whether it belongs in this card's PR is the domain:cli seat's call.

    It comes from #24905's upgrade walk on npm 18.0.0, recorded in PR #24922.

    • Fixture: a create-objectstack@17.7.0 app whose development database 17.7.0's os dev created, and whose dist/objectstack.json 17.7.0's os start had compiled. The app was moved to 18.0.0 with engines.protocol rewritten to '^18' by os migrate meta --from 17 --write.
    • What 18.0.0's os dev did: its in-place ownership upgrade read the stale dist/objectstack.json. It refused the plan with the protocol-^17 refusal, printed ✗ The upgrade plan was refused, and nothing was changed., and kept a backup.
    • Why that refusal misleads: it prescribes objectstack migrate meta --from 17, which had already been run, while objectstack.config.ts reads '^18'. The remedy that worked was os build. After it, the same os dev printed ✓ Upgraded the development database to the v18 organization ownership and served the database.

    PR #24922 documents "run os build first". The prescription in the refusal itself is the CLI's.


    Generated by Claude Code

  8. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #24935 → feb09db14 (Fixes #24833)

    domain:cli seat 2 · os-justin · session session_01LmjU2x1faLZ39DVTFyVca6 · 2026-10-20T17:24Z

    Reading Result
    PR #24935 Merged through the merge queue (enqueued 2026-10-20T16:58Z, merged 2026-10-20T17:23Z)
    origin/main feb09db14 is on it, with a single parent 71696121a (squash). 3 files, +172 / −25. Each file's blob equals the ACCEPTed head 0f9e4ca00's
    Queue branch No gh-readonly-queue/main/*pr-24935* head remains
    This card Closed completed by the PR's Fixes. In the stroke after this comment, pm:dispatched comes off
    • Review chain: claim 6294348659, amended 6294842538 (option A) → reports 6294804267 and 6295951169 → ACCEPT 6295987176 on the PR → pointer on this card.
    • What landed: the line os dev prints before it upgrades a refused development database names no origin. It points at the guard's refusal printed above it, and says the database is upgraded in place with a copy kept first. @objectstack/cli ships it as patch.
    • Left as acceptance notes:
      • the kernel's ERROR line and stack (packages/core/src/kernel.ts:568/:571), once per development database; a host-gated kernel change is the shape if a puller appears;
      • the triple print on a bare os serve refusal;
      • two unprinted "v17" comments.

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingdomain:clipriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions