Repository navigation
os migrate apply --allow-destructive cannot drop sys_account.issuer on a 17.4.0-created SQLite database, while os migrate account-issuer and the boot's schema-drift line keep prescribing it (17.7.0) #22506
Description
Activity
objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsTriage: first grade,
bug·priority:p3·domain:cli·area:devpath·pm:queue. This is the closing pass for "os migratecomposes less than the boot", with a parity pinTriage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-09T16:54Z. ⛔ Not a claim, ⛔ not a dispatch.Triage:
os migrate plan/applylive inpackages/cli. That puts it indomain:cli.-
Why p3: low runtime impact on the measured database (the column is nullable, and sign-in works). But a published upgrade step cannot be completed, and a boot warning cannot be cleared by following its own advice.
-
The family, third occurrence:
os migrate plan/applycompose neither the host config nor PlatformObjectsPlugin — they diff a five-table subset and cannot apply the drift their own message names #12938 (closed): plan/apply composed neither the host config norPlatformObjectsPlugin;- cli: os migrate plan / apply cannot boot the stock showcase or a fresh blank app — Dependency 'com.objectstack.service-automation' not found for the connector plugins #21732 (closed): plan/apply could not boot the showcase for a missing dependency;
- here: plan composes 0 plugins for an app declaring
requires: ['auth'], sosys_accountis "undeclared" and its retired column is never a destructive drop.
Each fix so far patched one composition list, so this card closes the class.
-
Direction:
os migrate plan/applycompose the stack through the same composer the boot andserveuse, the shared composition verify: the in-process handle boots a leaner stack thanserveand has no door for eight things an app's tests need (requires[] capabilities, system/predicate update, the form door, user-less triggers, …), measured by hotcrm#2013 #22301 item 1 stage 2 landed (PR feat(core,cli,verify): bootStack composes what serve composes — item 1 stage 2 of #22301 (HELD at stop conditions) #22381). ⛔ Not a second list that grows by incident.- Then the retired
sys_account.issuer(Adopt better-auth's account-issuer rollback: drop sys_account.issuer, retire the backfill, raise the family to 1.7.3 #17440) is a destructive drop under--allow-destructive, andos migrate account-issuerreaches zero. - If a host shape still cannot be composed, the prescription names the command that works. A loop with no exit is the defect either way.
-
The pin that closes the family: for each example app shape (a host config, a standalone stack, an app with
requires: [...]), the set of objectsos migrate planexamines equals the set the boot registers. A composition gap then fails one test instead of being found on an upgrade. -
Measure first: the hotclm shape (a 17.4.0-created SQLite database,
requires: ['auth']) reproduces in a fixture, and the plan showssys_accountas declared after the fix.
-
- addedarea:devpathThe road — create, dev, verify, publish/install, connect an agent, iterateThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingSomething isn't working
on Oct 9, 2026 objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsDeferred by the
domain:cliseat, not claimed · seatdomain:cli#1(#6024) ·session_01BmsuLyUeuG5CNpZFMH1jzS· 2026-10-09T19:59Z. ⛔ Not a claim; the card stayspm:queue.Thread-read: 6085386483
Why it waits: draft PR #22523 (#22371,
domain:specseat 3, claim6083206634, declared on #6024 in6083616680) is in flight on the files this card's direction runs through. REST file list, read in this act:packages/cli/src/utils/schema-migration-plugins.ts(+193 / -4): the plugin setos migrate plan/applycompose, imported bycommands/migrate/plan.ts;packages/cli/src/utils/schema-migrate.ts(+43): the one-shot boot both commands run;packages/cli/src/commands/serve.ts(+64 / -45):serve's auth-gated security-plugin composition, which moves to a newpackages/core/src/stack-auth.ts.
Two claims editing the plan/apply composition at once is the cross-lane intersection the lane rules serialise. This card is next in this lane once PR #22523 merges.
What the claimant inherits (known now, so it is on the card rather than in a session):
- Re-read
schema-migration-plugins.tsandschema-migrate.tson the merged ref. PR feat(cli): os migrate security-catalog-overlays — list, and with --apply delete, the environment rows a v18 cold boot refuses #22523 widens what the one-shot composes, and it may already close part of the "plan composes 0 plugins" gap for an app withrequires: ['auth']. Measure the hotclm shape first, and state what is left. - Triage's direction (
6085386483) stands: one shared composer, the one PR feat(core,cli,verify): bootStack composes what serve composes — item 1 stage 2 of #22301 (HELD at stop conditions) #22381 landed. ⛔ No second list. If PR feat(cli): os migrate security-catalog-overlays — list, and with --apply delete, the environment rows a v18 cold boot refuses #22523's newstack-auth.tsis part of that composition, use it; do not copy it. - The parity pin is "the objects
os migrate planexamines equal the objects the boot registers, per example app shape". It will touchcommands/migrate/*tests that PR feat(cli): os migrate security-catalog-overlays — list, and with --apply delete, the environment rows a v18 cold boot refuses #22523 also adds beside.
Generated by Claude Code
objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsClaim: PM loop round 3
Session:session_01BmsuLyUeuG5CNpZFMH1jzS
Account:os-elon-musk(the seat's linked user asGET /useranswers it; always the card's assignee)
Branch:claude/issue-22506-migrate-composes-boot
Worktree:objectstack-issue-22506
Domain:domain:cli
Seat:domain:cli#1
File surface (read atorigin/main4638625e07):packages/cli/src/commands/migrate/plan.tsandapply.ts: how they compose the stack.packages/cli/src/utils/schema-migration-plugins.tsandschema-migrate.ts: the one-shot boot's plugin set, moved onto the shared composer thatserveandbootStackuse (PR feat(core,cli,verify): bootStack composes what serve composes — item 1 stage 2 of #22301 (HELD at stop conditions) #22381). ⛔ No second list that grows by incident (triage).packages/cli/src/commands/migrate/account-issuer.ts: only if its prescription must change for the loop to end.- The parity pin and the hotclm-shape pin, beside the existing
commands/migrate/*tests, plus.changeset/22506-*.md(@objectstack/clipatch). - ⛔ Not the shared composer in
packages/core(domain:engine's), and not the retirement ofsys_account.issueritself (Adopt better-auth's account-issuer rollback: drop sys_account.issuer, retire the backfill, raise the family to 1.7.3 #17440). A need for either is a stop-and-report.
Stop on breach; explain in the report.
Container & model:M,mode:subagent,model: default (opus). It is not mechanical: it is a composition seam with a parity pin across the example apps.dispatch-gates --tierprints "no path-derived mandate".
Clause-②: no
os migrate plan/applystart composing what the boot composes, so a retired column the published upgrade step names as a destructive drop becomes one. No accepted input, flag, key or export changes.
Responsibility:os migrate plan/applycompose their plugin set from their own list inpackages/cli/src/utils/schema-migration-plugins.ts, which has grown by incident (#12938, #21732). For an app declaringrequires: ['auth']the plan composes 0 plugins,sys_accountreads as undeclared, and its retiredissuercolumn is never a destructive drop | the shared composition PR #22381 landed (bootStackcomposes whatservecomposes) | every upgrader following the 17.5 checklist stepos migrate apply --allow-destructive(measured once on 17.7.0 by therepo:hotclmseat)
Thread-read: 6088292679
Serial constraints cleared:- PR feat(cli): os migrate security-catalog-overlays — list, and with --apply delete, the environment rows a v18 cold boot refuses #22523 ([decision] after #22307 a cold boot refuses any environment row over a package-held permission set or position, so the 2026-08-24 legacy-overlay remedies (boot overlay reading, drift overlay_shadow, Discard Overlay) find nothing on v18: keep or retire? #22371,
domain:specseat 3), which heldschema-migration-plugins.tsandschema-migrate.ts, merged asdb9cf804d6. This card re-reads both on the merged ref. - No open PR touches
commands/migrate/plan.ts,apply.ts,schema-migration-plugins.tsorschema-migrate.ts(REST file lists of all 9 open PRs, read in this act). - In flight in this lane: [finding] cli(console mount): every refused Console mount answers a bare 404 at /_console/ and / — the family closing card; open position: the objectui-pin drift refusal #22420 (claimed in the same act; the Console mount files,
area:devpath, disjoint) and PR fix(runtime)!: the /i18n dispatcher domain refuses an anonymous caller, with the console pin moved past the sign-in companion (#22432) #22496 (in the queue), both disjoint.
Direction: triage
6085386483, with the seat's deferral notes6088292679. Review of record: the seat's ACCEPT and CI. No contract-tier review is owed (by face).
Generated by Claude Code
objectstack-fleet commented
on Oct 10, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 22506,
"status": "blocked",
"branch": "claude/issue-22506-migrate-composes-boot",
"pr": null,
"session": "session_01BmsuLyUeuG5CNpZFMH1jzS (subagent of the domain:cli PM seat; claim 6091247664, newest Claim: verified to name this branch)",
"premise_still_valid": true,
"summary": "Measure-first reproduced the card exactly on main 4638625, and the Zone 1 direction works when implemented: os migrate plan/apply now compose, through the shared rules, what os serve mounts around the stack (the auth family behind resolvePlatformAuthComposition, the provider of every requires token plus the PLATFORM_ALWAYS_ON_CAPABILITIES slate through CAPABILITY_PROVIDERS/providesCapability, the REST API plugin, host plugins entries through materializeStackPlugin), each provider in a new init-only posture, plus the config's pinyin-search stamp. With that WIP (pushed as 9cad3ea, no PR yet) the hotclm-shape fixture plans sys_account as declared, apply --allow-destructive drops sys_account.issuer and its unique index, account-issuer reads zero collisions, and the next real boot prints no schema-drift line. BLOCKED on one thing outside the claim's file surface: driver-sql's deferred-DDL preview (previewDeferredSchemaWork) does not recognise rotation-declared objects (ADR-0057 P2), so sys_activity, whose base name is a VIEW over shard sys_activity__r20261010, is listed as create_table on every plan and apply performs it as a no-op every run (measured: re-plan after apply still lists it). The audit plugin serve composes behind its auth gate registers sys_activity, so landing this composition would put that unclearable finding into the plan of every auth-enabled deployment. The PM decides between extending this claim to the driver preview or sequencing a driver card first (open_questions). Tests, the parity pin, docs, changeset and gates are not written or run yet. NOT MEASURED: cli typecheck of 9cad3ea (verify lock never acquired: exit 99 twice, holder pid 29585, ALIVE, held about 30 min running pnpm --filter @objectstack/cli exec vitest run --project integration --maxWorkers=2). The worktree is kept, clean, at ../objectstack-issue-22506 for the resume.",
"tests": "READINGS BEFORE (main 4638625, public doors, hotclm-shape fixture: app config with requires ['auth'], no plugins, SQLite created by a realos serveboot (run-dev, OS_AUTH_SECRET set), then ALTER TABLE sys_account ADD COLUMN issuer plus CREATE UNIQUE INDEX uniq_sys_account_issuer_account_id ON sys_account (issuer, account_id)). Harness: scratchpad measure.mjs (boot via bin/run-dev.js serve, then migrate plan --json, migrate apply --allow-destructive --yes --json, migrate account-issuer, then a second serve boot). (a) plan: exit 0, notes 'Composed the host stack from objectstack.config.ts: 0 plugin(s)' + PlatformObjectsPlugin; coverage registeredObjects 9 / examinedObjects 9; total drift 0; sys_account listed under unmanagedTables (60 undeclared platform tables of the 68 the boot created). (b) apply --allow-destructive --yes: exit 0, applied 0, destructive applied 0; issuer column and uniq_sys_account_issuer_account_id still present. (c) account-issuer: exit 0, ok true, 0 collisions, prints 'Pre-flight clean. Take a backup, then run os migrate apply --allow-destructive to drop the column.'; the next boot logs '[schema-drift] sys_account.issuer: column exists in the database but not in metadata (orphaned) -- os migrate apply --allow-destructive to drop it' and the same for the orphaned index. Loop confirmed. READINGS AFTER (WIP 9cad3ea, same harness, OS_TELEMETRY_DB=0 on both sides): (a) plan: registeredObjects 74 / examinedObjects 74, sys_account declared, 2 destructive: drop_column sys_account.issuer and drop_index uniq_sys_account_issuer_account_id; unmanagedTables only sys_packages (raw DDL in PackageServicePlugin.start(), not a registered object); pending sys_activity create_table (the blocker). (b) apply: applied both, issuer column and index gone from PRAGMA table_info/index_list. (c) account-issuer: exit 0, ok true, 0 collisions, scanned 1; next boot: zero schema-drift lines for sys_account. No-secret production leg (in-process bootSchemaStack, NODE_ENV=production, OS_AUTH_SECRET unset): sys_account not registered (34 objects) and the note names the remedy: re-run with the deployment's OS_AUTH_SECRET exported (os migrate reads no .env). PARITY READINGS (WIP, real boot viaos serve --no-serverwith OS_MIGRATE_AND_EXIT=1 on a fresh DB, thenos migrate plan --jsonon that DB): examples/app-crm 82/82 examined, drift [], pending [sys_activity create_table], unmanaged [sys_packages]; examples/app-todo 77/77, same residue; examples/app-multi-package 75/75, same residue; examples/app-showcase NOT MEASURED (both doors exit 1: connector-slack dist absent in this worktree; the showcase closure build never acquired the verify lock, exit 99). Before the pinyin stamp the app-crm reading carried 49 destructive drop_column __search entries; with it, drift []. Dispatcher safety reading: with the host-plugin posture (kernel:ready kept) MessagingServicePlugin's notification-dispatcher and http-dispatcher ticked during plan (two 'tick failed' warnings); with the init-only provider posture, zero dispatcher lines. Re-plan after apply on the applied DB: total 0, pending still [sys_activity create_table]; sqlite_master: sys_activity is a view, sys_activity__r20261010 the table. HYPOTHESES: H1 true (plan.ts imports bootSchemaStack from utils/schema-migrate.ts and the composition types from utils/schema-migration-plugins.ts; the one-shot boot is createStandaloneStack plus buildSchemaMigrationPlugins). H2 measured: of the shared composition the migrate path called CAPABILITY_PROVIDERS/providesCapability only for providers a composed plugin hard-depends on (through the Serve handles), bypassed materializeStackPlugin (string entries dropped silently, bundles composed raw), and called resolvePlatformAuthComposition only for security-catalog-overlays; stackSuppliesAuthPlugin only through the gate. The WIP calls all four for plan/apply. H3 not triggered: no packages/core change needed; the change needed outside the surface is in packages/drivers/driver-sql instead. H4 partly false: serve's composition is inline in the oclif run() and has no in-process compose entry, and bootStack's set is the verify harness's, not serve's (it always mounts Auth/Security/Settings/Analytics/Sharing and mounts the slate only as hard dependencies), so the faithful 'boot registers' reading is serve's own OS_MIGRATE_AND_EXIT=1 door against a fresh database, which the parity readings above use. NOT MEASURED: cli typecheck, cli unit layer, cli integration layer, pnpm lint, the 64 derived gates, check:type-check-debt and check:dual-build-cjs-loads: none run, because no tests, changeset or final diff exist yet and the lock was never acquired. Dogfood: git grep for migrate plan/apply, MigratePlan, MigrateApply, bootSchemaStack, buildSchemaMigrationPlugins over packages/qa/dogfood exits 1 (zero hits), so dogfood stays declared to CI.",
"mcp_calls": "0",
"api_writes": "1: POST /repos//issues/22506/comments (this os-dev-report, through scripts/pm/post-stamped.mjs). Not REST: two git push of claude/issue-22506-migrate-composes-boot (the empty-branch probe at 4638625, then 9cad3ea). No pr_create, no label-write.",
"open_questions": [
{
"question": "The composition cannot land until driver-sql's deferred-DDL preview stops listing a rotation-declared object (sys_activity, ADR-0057 P2: shard tables plus a read view under the base name) as create_table: previewDeferredSchemaWork asks knex hasTable(base), which is false for the view, while flushDeferredSchemaDdl re-enters syncSchema, which takes the rotation branch and creates nothing new. That file is outside claim 6091247664's surface. Which sequencing?",
"options": [
"A: extend this claim's surface to packages/drivers/driver-sql/src/sql-driver.ts (previewDeferredSchemaWork answers a rotation-declared object from the rotator's own facts: current shard and read view present means no pending work) with a driver pin, one PR, changesets for @objectstack/cli and @objectstack/driver-sql (patch).",
"B: file the driver preview defect as its own card (sub-issue of #22506; it is reachable on main through any composition that registers sys_activity, e.g. a host config mounting AuditPlugin, though not measured there) and dispatch it first; this card resumes from 9cad3ea with Blocked-by on it.",
"C: land the composition without the audit plugin until the driver fix, leaving sys_audit_log/sys_activity/sys_comment unexamined; not recommended, because it lands a composition that knowingly differs from serve's and the parity pin would have to carry a residue."
],
"recommendation": "B when the driver lane can take it at once, otherwise A. Business need: measured, the published upgrade step cannot complete today, and either option ends it. Long-term: B keeps the lanes clean, and the fix is the driver's own #3978 obligation that the plan must not promise work apply cannot do. AI-error prevention: equal, since both pin the invariant where it lives. Startup focus: A costs one round instead of two, so prefer it if B would queue."
},
{
"question": "Composition inputs that differ from the serving boot, left out of this card unless the PM folds them in: os migrate reads no project .env while os serve/start/dev load it through dotenv-flow (measured: plan targets .objectstack/data/objectstack.db while .env names another OS_DATABASE_URL, and an OS_AUTH_SECRET kept in .env leaves the auth family out of the plan); plan/apply take no --preset/--dev, so a deployment served with --preset minimal gets the slate examined; and the one-shot boot provisions no telemetry sibling datasource (dev boots and OS_TELEMETRY_DB), so lifecycle-classed objects are planned against the primary. Fold any into this card?",
"options": [
"A: keep them out; the no-secret note already names the command that works, and the other two are filed as findings below.",
"B: fold the .env load into this card (a behaviour change: os migrate would start targeting the database a .env names, which needs a maintainer ruling).",
"C: add --preset/--dev to plan/apply as security-catalog-overlays has them (a new accepted flag, so Clause-② becomes yes and the changeset at least minor)."
],
"recommendation": "A. Each of B and C changes an accepted input or the target database of a migration command, which is a maintainer decision this card's Clause-② no does not cover. The telemetry sibling is a multi-driver plan change (deferral must arm the second driver, drift and apply run on one driver today) and belongs to its own card."
}
],
"out_of_scope_findings": [
"class: a · reach: public door, measured on this branch: os migrate plan --json lists pending sys_activity create_table on every run and os migrate apply --yes reports 'Created/extended 1 table(s)' while sqlite_master shows sys_activity is a view over sys_activity__r20261010 and no table is added; reachable on main through any composition that registers sys_activity (not measured on main) · evidence: packages/drivers/driver-sql/src/sql-driver.ts previewDeferredSchemaWork asks hasTable(tableName), the deferral in syncSchema records the object before the ADR-0057 P2 rotation branch, flush re-enters syncSchema which calls ensureRotation · this is the blocker above, a sub-issue of #22506 · dedupe words: previewDeferredSchemaWork rotation shard, sys_activity create_table phantom, deferred DDL rotation view, os migrate plan never in sync",
"class: a · reach: public door, measured on main: after a development boot (run-dev, telemetry sibling on by default) os migrate plan lists sys_metadata_audit create_table and os migrate apply --yes creates it in objectstack.db while the boot keeps it in objectstack.telemetry.db; with this branch's composition the same holds for sys_audit_log, sys_activity, sys_job_run, sys_notification, sys_notification_delivery and sys_http_delivery (OS_TELEMETRY_DB opt-in production deployments too) · evidence: utils/telemetry-datasource.ts provisionTelemetryDatasource is called by every serving boot and not by bootSchemaStack; resolveTelemetryDbPath is on for dev and for OS_TELEMETRY_DB · this branch widens it from 1 object to 7, so it needs its own card before or with this one · dedupe words: telemetry datasource os migrate, objectstack.telemetry.db migrate apply, lifecycle-classed objects primary database, provisionTelemetryDatasource one-shot",
"class: a · reach: public door, measured on main: a fixture whose .env sets OS_DATABASE_URL=file:from-dotenv.db,os migrate plan --jsonreports database .objectstack/data/objectstack.db, while os serve loads that .env (serve.ts dotenvFlow.config) and opens from-dotenv.db · evidence: dotenv-flow is loaded only in commands/serve.ts, start.ts, dev.ts and doctor.ts; the migrate commands read process.env only (--database-url env: OS_DATABASE_URL) · dedupe words: os migrate dotenv, .env OS_DATABASE_URL migrate plan, migrate targets different database than serve, dotenv-flow migrate",
"class: a · reach: public door, measured on this branch after the drop: os migrate account-issuer prints 'sys_account.issuer is safe to drop' and 'Pre-flight clean. Take a backup, then run os migrate apply --allow-destructive to drop the column.' on a database where the column is already gone; on main the same text prints whenever the pre-flight is clean · evidence: commands/migrate/account-issuer.ts success branch never asks whether the column still exists · carrier: this card's resume round (account-issuer.ts is in the claim's surface 'only if its prescription must change'; the loop ends without it, so it is optional there) · dedupe words: account-issuer already dropped, issuer safe to drop after drop, account-issuer post-check prescription",
"carrier: this card's resume round · noted, not filed: the composition notes and the unmanaged-tables block report sys_packages as an undeclared platform table on every served deployment; it is created by raw DDL in PackageServicePlugin.start(), not a registered object, so the statement is true and needs no fix, but the parity pin must name it as outside the object set",
"carrier: this card's resume round · noted, not filed: the kernel prints 'CORE: Core service missing, functionality may be degraded: auth' during plan/apply once the auth family is composed through createIdentityObjectsPlugin (no auth service by design); cosmetic stderr noise on a declaration boot"
]
}
Generated by Claude Code
objectstack-fleet commented
on Oct 10, 2026 ContributorAuthorMore actionsSurface extension to claim
6091247664: driver-sql's deferred-DDL preview (the seat answers the dev's open questions: 1 → A, 2 → A)domain:cliseat (#6024) ·session_01BmsuLyUeuG5CNpZFMH1jzS· 2026-10-10T01:00Z.Thread-read: 6091898600
What stopped the dev (report
6091898600; the WIP is pushed as9cad3eaef7, with no PR yet):- The direction works.
plan/applynow compose through the shared rules, and on the hotclm shapesys_accountreads declared,apply --allow-destructivedropsissuerand its unique index,account-issuerreads zero, and the next boot prints no drift line. - But the composed audit plugin registers
sys_activity. That object is rotation-declared (ADR-0057 P2: shard tables plus a read view under the base name).previewDeferredSchemaWorkinpackages/drivers/driver-sql/src/sql-driver.tsaskshasTable(base), which is false for a view, so everyplanlistssys_activity create_table, andapplythen creates nothing. Measured: a re-plan afterapplystill lists it. - Landing the composition as it stands would put an entry nobody can clear into the plan of every auth-enabled deployment.
Question 1, answered A: this claim widens to the preview. The driver's preview must not promise work
applycannot do. It is this card's acceptance blocker, the dev has already diagnosed it, and one round beats two now that the maintainer has made dispatch serial (6091889844on #6024).- Added surface:
packages/drivers/driver-sql/src/sql-driver.ts, onlypreviewDeferredSchemaWork(about:13497at4638625e07). A rotation-declared object answers from the rotator's own facts: the current shard and the read view present means no pending work. Plus a driver pin beside its existing preview tests, and.changeset/22506-*.mdgains an@objectstack/driver-sqlpatchentry. - ⛔ Not the rotator, not
syncSchema's rotation branch, notflushDeferredSchemaDdl. A need for any of them is a stop-and-report. - Cross-lane:
packages/drivers/driver-*isdomain:engine's. It is declared on [PM seat] domain:engine · seat 2 — ⏳ vacant #20966 in this act. No open PR touchespackages/drivers/driver-sql/(REST file lists of all 10 open PRs, read in this act). Clause-②: nostands: a preview that stops listing work that does not exist changes no accepted input. No contract-tier review is owed by face (nopackages/spec, no governed text).
Question 2, answered A: keep
.envloading,--preset/--devand the telemetry sibling out of this card. The first two change a migration command's accepted input or its target database, which is the maintainer's call. The telemetry sibling is a multi-driver plan change. The seat files the measured findings at the ACCEPT. Note for the PR body: this card's composition widens the telemetry-sibling mismatch from one object to seven; say so, with the reading.
Generated by Claude Code
- The direction works.
objectstack-fleet commented
on Oct 10, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 22506,
"status": "done",
"branch": "claude/issue-22506-migrate-composes-boot",
"pr": "#22574",
"session": "session_01BmsuLyUeuG5CNpZFMH1jzS (subagent of the domain:cli PM seat; claim 6091247664 with surface extension 6091922191; round 2, resumed from 9cad3ea)",
"premise_still_valid": true,
"summary": "os migrate plan/apply now compose, through the rules os serve reads, what serve mounts around the stack, each piece for its declarations only: the auth family behind resolvePlatformAuthComposition (plugin-auth's objects through createIdentityObjectsPlugin, plus security and audit), the provider of every requires token plus the always-on slate (CAPABILITY_PROVIDERS/providesCapability), and the REST API plugin; every plugins entry goes through materializeStackPlugin, and the config's pinyin stamp is applied. A new init-only provider posture (composeProviderForDeclarations) keeps dispatchers and schedulers out of a dry run. Per the surface extension, driver-sql's previewDeferredSchemaWork answers a rotation-declared object from the rotator's facts, so sys_activity is no longer a phantom create_table, and account-issuer's clean prescription got its one-line fix. Pinned by: the hotclm shape (plan names both drops, apply performs them, account-issuer reaches zero, re-plan in sync), a parity pin per app shape against a real os serve OS_MIGRATE_AND_EXIT=1 boot naming sys_packages as raw DDL, a driver pin red against base, and unit cases. Draft PR #22574 at 4782330, assigned os-elon-musk. Its body states that this composition widens the telemetry-sibling mismatch from 1 object to 7, with the reading.",
"tests": "HEAD 4782330 (source unchanged since 143f14e; later commits touch two test files only). DRIVER PIN (pnpm --filter @objectstack/driver-sql exec vitest run --maxWorkers=2 src/sql-driver-deferred-ddl.test.ts src/sql-driver-rotation.test.ts, under the verify lock, at 306a75d): 2 files, 23 passed. RED AGAINST BASE (sql-driver.ts at 4638625 written to the tree only, marker count 0, trap-restored): 2 failed ('already sharded ... previews no work', 'converges ...'), 16 passed (the never-sharded control among them); restore: git diff HEAD empty, hash 01edeb164c equals the HEAD blob. driver-sql dist rebuilt; the fix's SQL string is present once in dist/index.js and once in dist/index.mjs. CLI TYPECHECK (pnpm --filter @objectstack/cli typecheck, at 143f14e): exit 0, test-layer debt held. CLI UNIT LAYER (vitest run --project unit, at 143f14e): 276 files, 4085 passed; at 4782330, schema-migration-plugins.test.ts plus test/exit-signal.pin.test.ts: 2 files, 160 passed. CLI INTEGRATION, through the lock, as a declared narrowing: the integration-tier files that boot the schema stack or drive the migrate commands (filters src/commands/migrate/, src/utils/schema-migrat, unmanaged-tables, platform-migrations-arming, artifact-boot-migration, sqlite-occupancy, test/migrate-, test/dev-standalone-self-heal). At 143f14e: 34 files, 317 passed, 2 skipped, 2 failed, both in the new parity pin (host-config fixture had no data stack; the sweep is unreadable on an artifact project), fixed in 4782330, where the parity file passes 3/3. The one-shot family's no-write pin passed, so plan still moves no byte. The rest of the integration project is declared to CI; the filter test/json-stdout-purity matched no file, and test/exit-signal is unit-tier (ran there). HOTCLM-SHAPE PIN apply.account-issuer-retirement.integration.test.ts: 4/4 passed in the subset (plan names drop_column issuer plus drop_index uniq_sys_account_issuer_account_id; apply drops both, verified by PRAGMA; account-issuer ok, collisions [], scanned 1; re-plan changes [] and pending []). PARITY ABLATION (scripts/ablation-replace.mjs, composeServedPlatform: false in plan.ts, anchor 1 to 0, blob c355ffc8 to 9776b976): 3/3 red, boot tables 78/76/75 against examined-plus-raw 10/11/10; restored (diff HEAD empty, hash equal). READINGS BEFORE (main 4638625, public doors, hotclm shape over a serve-created DB plus the legacy column and index): plan examined 9 of 68 tables with sys_account undeclared; apply applied 0; account-issuer ok and re-prescribed apply; the next boot printed 2 schema-drift lines. AFTER: plan 74 examined, sys_account declared, 2 destructive drops; apply drops both; account-issuer 0 collisions; next boot no sys_account drift line; re-plan in sync (pinned). No-secret production leg: sys_account not registered, and the note names the remedy (export OS_AUTH_SECRET). EXAMPLE PARITY (scratch, real serve OS_MIGRATE_AND_EXIT=1 then plan --json): app-showcase at 4782330, drift [] pending [] unmanaged [sys_packages], 105/107 examined (2 federated), 107 boot tables = 105 + sys_packages + _objectstack_sequences (driver auto-number table); app-crm 82/82, app-todo 77/77, app-multi-package 75/75 with drift [] (measured before the driver fix, each then with the sys_activity phantom now pinned away). LINT, proven narrowing at 4782330: population is eslint.config.mjs's **/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs} minus the global NEVER_LINTED; the 10 changed source files with --no-inline-config --format json give 10 files, 0 errors, 0 warnings; the config never enables type-aware linting (no parserOptions.project, no typed rules), so untouched files' verdicts cannot move. GATES: dispatch-gates --commands derives 69 (the dispatch's 64 plus check:dispatcher-error-vocabulary, check:driver-conformance, check:error-status-conformance, check:object-def-param-keys, check:tenant-chokepoint); all 69 exit 0 at 4782330. check:i18n-coverage and check:dual-build-cjs-loads first exited 3 (PREREQUISITE NOT MET: showcase's connector-slack, and 8 unrelated packages with no dist/, in this worktree) and re-ran green after building those under the lock. check:type-check-debt and check:dual-build-cjs-loads ran last. dispatch-gates --ran with the recorded exit codes: 69 derived, 69 run, 0 NOT-MEASURED (a derived zero). Dogfood is declared to CI: git grep for migrate plan/apply, MigratePlan, MigrateApply, bootSchemaStack, buildSchemaMigrationPlugins over packages/qa/dogfood exits 1 (zero hits). CI on #22574 at report time: 13 checks completed with no failure, 18 in_progress.",
"mcp_calls": "0",
"api_writes": "3 this round, all through scripts/pm and the fleet-write relay: POST /repos/objectstack-ai/objectstack/pulls (pr_create, draft forced, relay run 38015853249, #22574, body read back 14572 bytes identical); POST /repos//issues/22574/assignees (label-write --assign os-elon-musk, relay run 38015899581, read back MATCHES); POST /repos//issues/22506/comments (this os-dev-report, round 2). Round 1 posted one os-dev-report (comment 6091898600). Not REST: git push of 306a75d, 143f14e, 87603d4 and 4782330. Worktree ../objectstack-issue-22506 removed after the PR (node_modules first, no --force; branch fully pushed).",
"open_questions": [],
"out_of_scope_findings": [
"class: a · reach: public door, measured on main: after a development boot (telemetry sibling on by default) os migrate plan lists sys_metadata_audit create_table and os migrate apply --yes creates it in objectstack.db while the boot keeps it in objectstack.telemetry.db; this branch's composition widens it to 7 objects (sys_activity, sys_audit_log, sys_http_delivery, sys_job_run, sys_metadata_audit, sys_notification, sys_notification_delivery) for dev and OS_TELEMETRY_DB deployments, stated in the PR body per the seat's note · evidence: utils/telemetry-datasource.ts provisionTelemetryDatasource is called by every serving boot and not by bootSchemaStack · the seat files it at ACCEPT (ruling 6091922191) · dedupe words: telemetry datasource os migrate, objectstack.telemetry.db migrate apply, lifecycle-classed objects primary database, provisionTelemetryDatasource one-shot",
"class: a · reach: public door, measured on main: a fixture whose .env sets OS_DATABASE_URL=file:from-dotenv.db gets a plan --json reporting database .objectstack/data/objectstack.db, while os serve loads that .env (dotenv-flow) and opens from-dotenv.db; the same gap leaves an OS_AUTH_SECRET kept in .env out of the auth gate · evidence: dotenv-flow is loaded only in commands/serve.ts, start.ts, dev.ts and doctor.ts · the seat files it at ACCEPT · dedupe words: os migrate dotenv, .env OS_DATABASE_URL migrate plan, migrate targets different database than serve",
"class: a · reach: public door, measured on this branch: os migrate plan --json on a compiled-artifact project with no config reports unmanagedTables status unreadable, reason 'this project has no host config, so the composed object set is the compiled artifact plus the platform floor rather than what os serve registers', while the same run composed 74 objects including the served platform; the reason this branch makes false is conservative in effect (no wrong finding, a sweep withheld) · evidence: utils/unmanaged-tables.ts collectUnmanagedTables gates on composition.hostConfigLoaded alone · outside this claim's surface · carrier: none (the seat decides; the fix is to gate on whether the composition mirrors the served boot) · dedupe words: unmanaged tables unreadable artifact project, declared by nothing artifact no host config, unmanagedTables reason platform floor",
"carrier: PR #22574 Acceptance notes · noted, not filed:--preset/--devare absent on plan/apply (a --preset minimal deployment gets the slate examined); the rotation preview does not diff the current shard's columns (the rotator column-syncs on flush); a plan across UTC midnight can list the new day's shard as create_table (real flush work);CORE: Core service missing ... authstderr noise once identity objects compose without AuthPlugin; plugin-auth's formatter still prints 'sys_account.issuer is safe to drop.' after the drop; sys_packages (raw DDL) and _objectstack_sequences (driver auto-number) are non-object tables"
]
}
Generated by Claude Code
objectstack-fleet commented
on Oct 10, 2026 ContributorAuthorMore actionsReview of PR #22574 (head
47823309b): one change before the ACCEPT, so claim6091247664widens toos migrate unmapped-columnsdomain:cliseat (#6024) ·session_01BmsuLyUeuG5CNpZFMH1jzS· 2026-10-10T02:39Z.Thread-read: 6092569265
CI is green on
47823309b: 34 runs, 31 success and 3 roster skips.git merge-treeagainstmain25be87612dis clean. The rest of the review holds. One divergence stops the ACCEPT.os migrate unmapped-columnsno longer reads the plan's object set- Its boot comment in
packages/cli/src/commands/migrate/unmapped-columns.ts(about:286at47823309b) reads: "Theos migrate planboot, so the differ runs over the plan's object set". content/docs/deployment/cli.mdx(:1078atmain) makes the same promise: "It reads exactly the columnsos migrate planreports asunmapped_columnfor that object's table: the same differ, the same boot."- This PR passes
composeServedPlatform: truefromplanandapplyonly.unmapped-columnsstill boots withcomposeHostStackalone.
Failure path (read from the code, not run):
- Once this lands,
os migrate plandeclares the platform objects the deployment serves, such assys_account. - An undeclared column on one of their tables is now reported as
unmapped_column. - The documented read step is
os migrate unmapped-columns --object sys_account. It looks the name up instack.allObjects(), does not find it, and throwsOBJECT_NOT_FOUND. - Before this PR, both commands drew on the same narrower set, so their answers agreed.
Surface extension
- Boot flag: in
packages/cli/src/commands/migrate/unmapped-columns.ts, itsbootSchemaStackcall passescomposeServedPlatform: true, and the comment names it. Nothing else in the command changes. - Pin: a pin beside its existing tests. A platform object that
plandeclares on an auth-enabled fixture is resolved byunmapped-columns --object, not refused. Removing the flag turns the pin red. - Changeset: the
@objectstack/cliline names the third command. - ⛔ Not the other
bootSchemaStackcallers. Their comments claim the plan's read-only posture ([finding] seven more dry-run / report-only CLI commands boot the app seed loader and rewrite seeded rows (the family of #21349) #21391), not its object set.value-shapesandfiles-to-referencesrecord deployment flags over their own registry, and widening that registry is a separate question. A need to change any of them is a stop-and-report. - No conflicting PR: no open PR touches
unmapped-columns*(REST file lists of all 12 open PRs, read in this act). Clause-②: nostands. The command's documented contract already is the plan's object set, and this keeps it true. No contract-tier review is owed by face: nopackages/spec, no governed text.
The dev resumes on the same branch and PR. The seat re-reads the head and CI, then posts the ACCEPT.
Generated by Claude Code
- Its boot comment in
objectstack-fleet commented
on Oct 10, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 22506,
"status": "done",
"branch": "claude/issue-22506-migrate-composes-boot",
"pr": "#22574",
"session": "session_01BmsuLyUeuG5CNpZFMH1jzS (subagent of the domain:cli PM seat; claim 6091247664, widened in 6091922191 and 6092886177; review round, resumed from 4782330)",
"premise_still_valid": true,
"summary": "Step 1, read before changing anything: the seat's failure path holds. unmapped-columns.ts resolves --object only through stack.allObjects() (about :326); with composeHostStack alone nothing registers sys_account for an app that mounts no AuthPlugin, and no other route registers it. Measured with the pin's flag-removed leg: OBJECT_NOT_FOUND, exit 1. unmapped-columns.ts now passes composeServedPlatform: true from its bootSchemaStack call, with the comment naming it; nothing else in the command changes. The composeServedPlatform docs in schema-migrate.ts and schema-migration-plugins.ts, which said plan and apply only, name the third caller, and the changeset's @objectstack/cli line names it. Head 5bdfba6 is pushed to the same PR; CI there reads 34 completed, 0 failed. CONFLICT, stated not silently chosen: the order says to update the PR body, but the role file says the dev writes the PR body once, at pr_create, never PATCHes it, and names later changes for the seat to write; the role file governs on a conflict, so the body is unchanged (14559 chars). The full updated body is at /tmp/claude-0/-home-user/297ae329-0faf-5db9-a494-f807d046b9f2/scratchpad/issue-22506/pr-body-r3.md (16701 bytes, no angle brackets, one closing keyword on line 1). Its three changes: a 'commands/migrate/unmapped-columns.ts' paragraph before the account-issuer one; an 'unmapped-columns' bullet first under Pins (with the red/green reading below); and a 'Review round, head 5bdfba6' block opening Verification, with the round-1 block kept under it.",
"tests": "HEAD 5bdfba6, under the verify lock unless noted. Fresh worktree: pnpm install, then the @objectstack/cli closure built (VERDICT command-exit 0; driver-sql dist carries the preview fix's SQL once). TYPECHECK (pnpm --filter @objectstack/cli typecheck): exit 0. UNIT (vitest run --project unit src/commands/migrate/unmapped-columns.test.ts src/utils/schema-migration-plugins.test.ts; the tier module classifies both as unit): 2 files, 67 passed. INTEGRATION (vitest run --project integration with unmapped-columns.integration.test.ts, plan.boot-parity.integration.test.ts and apply.account-issuer-retirement.integration.test.ts): 3 files, 17 passed. That includes the new case 'a platform object the plan declares (#22506)': the seed adds sys_account from today's definition plus the retired issuer column and one row; on an auth-enabled stack, --object sys_account --json exits 0 with records [{id: acc_os22506, values: {issuer: 'local:credential'}}], and its columns equal plan --json's unmapped_column set for sys_account (['issuer']). The existing 'writes nothing' case still passes with the door's widened boot. FLAG REMOVED (scripts/ablation-replace.mjs --delete of ' composeServedPlatform: true,' in unmapped-columns.ts; anchor 1 to 0, blob 6213fba8 to 810add42): 1 failed, 9 passed. The failure is exactly the new case, AssertionError {"error":"Object 'sys_account' not found","code":"OBJECT_NOT_FOUND"}, exit 1. Restored: blob back to HEAD, git diff HEAD empty, hash 6213fba8 equals HEAD's (verified by the tool and again by the script). LINT, the proven narrowing at 5bdfba6: population eslint.config.mjs's **/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs} minus NEVER_LINTED; the 12 changed source files with --no-inline-config --format json give 12 files, 0 errors, 0 warnings; type-aware linting is never enabled, so untouched files' verdicts cannot move. GATES: dispatch-gates --commands at 5bdfba6 derives the same 69 families as round 2 (sorted diff empty). After building the showcase closure and the 8 packages those gates read, so none answered PREREQUISITE NOT MET: 67 exit 0, then check:dual-build-cjs-loads exit 0 (107 entry points across 66 packages load) and check:type-check-debt exit 0, last. dispatch-gates --ran with recorded exit codes: 69 derived, 69 run, 0 NOT-MEASURED (a derived zero). Not re-run this round, and unchanged since round 2: the full cli unit layer and the wider integration subset; this round's diff is unmapped-columns.ts, its integration test, docs comments and the changeset.",
"mcp_calls": "0",
"api_writes": "1: POST /repos//issues/22506/comments (this os-dev-report, round 3, through scripts/pm/post-stamped.mjs and the fleet-write relay). No PR body write (see summary). Not REST: git push of 5bdfba6. Earlier rounds: 6091898600 (round 1); #22574 pr_create, the assignee label-write, and 6092569265 (round 2).",
"open_questions": [],
"out_of_scope_findings": [
"carrier: this card's ACCEPT or the seat · noted, not filed: schema-migrate.ts's composeHostStack doc still says it is 'Set by the two SCHEMA commands, os migrate plan and os migrate apply, and by nothing else', which was already false on main (unmapped-columns and security-catalog-overlays pass it); left as is, because this round's order limits the change to the composeServedPlatform statements"
]
}
Generated by Claude Code
objectstack-fleet commented
on Oct 10, 2026 ContributorAuthorMore actionsACCEPT: PR #22574 (head
5bdfba6bc), triage's direction6085386483, with the claim widened by6091922191and6092886177domain:cliseat (#6024) ·session_01BmsuLyUeuG5CNpZFMH1jzS· 2026-10-10T03:20Z. Reviewed against GitHub and the dev's reports, not against the summary.Thread-read: 6093221889
- PR shape: draft, base
main. The first line isFixes #22506, then a line-initialClause-②: nowith the claim's reason. 13 files,+1205 / -30, all inside the claim plus its two extensions:plan.ts,apply.ts,schema-migrate.ts,schema-migration-plugins.ts;- the one-line
account-issuer.tsprescription; driver-sql'spreviewDeferredSchemaWork;unmapped-columns.ts's boot flag (the review round);- their tests;
- a changeset for
@objectstack/cliand@objectstack/driver-sql.
Nopackages/spec, no governed path, so no contract-tier review is owed. Assigneeos-elon-musk.
- The fix, read:
plan/applypasscomposeServedPlatform, andbootSchemaStackcomposes whatservemounts around the stack, each piece for its declarations only:- the auth family behind
resolvePlatformAuthComposition; - the provider of every
requirestoken plus the always-on slate, throughCAPABILITY_PROVIDERS/providesCapability; - the REST API plugin;
- every
pluginsentry throughmaterializeStackPlugin.
- the auth family behind
- A new init-only posture (
composeProviderForDeclarations) keeps dispatchers and schedulers out of a dry run. - Read and accepted: the auth family's three members (identity objects, Security, Audit) are named here as
servenames them inline. The decision to compose them is the shared rule's, and the parity pin is the guard: a memberserveadds and this omits reds there.
- The review round, read (
5bdfba6bc, asked in6092886177):os migrate unmapped-columnspassescomposeServedPlatform: truetoo, so it resolves the platform objects the plan now reports on. It keeps its documented promise (content/docs/deployment/cli.mdx: "the same differ, the same boot"). Nothing else in the command changed; the option's docblocks and the changeset name the third caller.- The dev read the failure path first, and it held: with
composeHostStackalone,--object sys_accountansweredOBJECT_NOT_FOUND, exit 1. - The pin (
unmapped-columns.integration.test.ts, "a platform object the plan declares") seedssys_accountwith the retiredissuercolumn and one row. It reads that row on an auth-enabled stack, and its columns equalplan --json'sunmapped_columnset for the table. With the flag removed, exactly that case goes red (1 failed, 9 passed); restored, it is green.
- The dev read the failure path first, and it held: with
- The driver fix, read:
previewDeferredSchemaWorkanswers a rotation-declared object from the rotator's facts: the current shard and the read view present means no pending work. Itssqlite_masterquery runs only wheresupportsRotation, which isisSqlite, so other dialects are untouched. - Direction met (the hotclm shape, public doors):
- Before:
planexamined 9 of 68 tables,sys_accountundeclared;applyapplied 0;account-issuerre-prescribedapply; the next boot printed 2 drift lines. - After:
planexamines 74 and names both drops;applydrops the column and its index;account-issuerreads zero; the next boot prints nosys_accountdrift line; and a re-plan is in sync, with no phantomsys_activity. - No secret in production:
sys_accountis not composed, and the note names the remedy.
- Before:
- Pins and evidence (from the reports):
- The hotclm-shape pin: 4 / 4.
- The parity pin per app shape, against a real
os serveOS_MIGRATE_AND_EXIT=1boot: 3 / 3, red 3 / 3 when the served-platform composition is ablated. It namessys_packagesas raw DDL outside the object set. - The driver pin: red against base (2 failed / 16 passed, the control green) and 23 / 23 green.
- Example readings: app-showcase 105 of 107 examined (2 federated), app-crm 82 / 82, app-todo 77 / 77, app-multi-package 75 / 75, each with drift
[]. - Checks, round 2 (
47823309b): cli typecheck exits 0, and the unit layer gives 4085 passed. Lint ran as the proven narrowing. All 69 derived gates exit 0, with--rana derived zero. - Checks, the review round (
5bdfba6bc, report6093221889): typecheck exits 0. The two unit files give 67 passed, and the three integration files (unmapped-columns, the parity pin, the hotclm pin) give 17 passed. Lint on the 12 changed source files reads 0 / 0.dispatch-gatesderives the same 69 families; all 69 exit 0, and--ranreads 0 NOT-MEASURED.
- CI on
5bdfba6bc: 34 check runs: 31 success and 3 skipped, all three on the roster (Packed-tarball smoke (opt-in),Console Pin Gate,Build Docs), 0 failed.git merge-treeagainst currentmain99801d831fis clean, and no filemaingained since the base4638625e07is in this PR.check-governed-merges --pr 22574, run frommain99801d831f: 0 of 13 paths governed, 1235 changed lines, under the 3000 threshold. - Review of record: this ACCEPT plus CI.
- Accepted deviations:
- The PR body was rewritten by the seat, not the dev. The rework order asked the dev to update the body, but
os-dev.mdsays the dev writes it once, atpr_create, and the seat writes later changes. The dev stated the conflict and followed the role file. The seat posted the dev's prepared text, with one stale sentence corrected ("which onlyplanandapplyset"). The order's wording was the seat's error. - The integration layer was a declared narrowing: the 34 files that boot the schema stack or drive the migrate commands, 317 passed; the rest of the project is CI's.
- The
account-issuer.tsone-liner: its clean prescription now says to drop only whileplanstill lists the drop.
- The PR body was rewritten by the seat, not the dev. The rework order asked the dev to update the body, but
- The telemetry-sibling widening is known and stated: this composition widens the existing mismatch from 1 object to 7 (the PR body has the reading). It creates empty tables in the primary database, and no data is lost. Filed as [finding] cli(migrate):
os migrate plan/applynever provision the telemetry sibling datasource, so lifecycle-classed objects a dev orOS_TELEMETRY_DBboot keeps inobjectstack.telemetry.dbare planned and created in the primary database #22579. - Out of scope:
- filed [finding] cli(migrate):
os migrate plan/applynever provision the telemetry sibling datasource, so lifecycle-classed objects a dev orOS_TELEMETRY_DBboot keeps inobjectstack.telemetry.dbare planned and created in the primary database #22579:os migrateprovisions no telemetry sibling. - filed [finding] cli(migrate):
os migratereads no project.envwhileos serve/start/devload it, so a migration can target another database than the one served, and anOS_AUTH_SECRETkept in.envdrops the auth family from the plan #22581:os migratereads no project.env. - filed [finding] cli(migrate plan): on a compiled-artifact project with no host config,
unmanagedTablesreadsunreadablewith a reason that is false onceplancomposes the served platform (PR #22574): the sweep is withheld for a reason that no longer holds #22580:unmanagedTables'unreadablereason is false on an artifact project once this lands. - Rides the next edit of its file (on seat post [PM seat] domain:cli — 🟢 os-project-manager · session_019SvPnd2bzECRNmAU9i6E4k #6024):
packages/cli/src/utils/schema-migrate.ts'scomposeHostStackdocblock still says it is set byplanandapply"and by nothing else". That was already false onmain:unmapped-columnsandsecurity-catalog-overlayspass it. Raised by the dev in6093221889. - Acceptance notes, carrier none:
--preset/--devare absent onplan/apply;- the rotation preview does not diff the shard's columns;
- a plan across UTC midnight can list the new shard;
CORE: Core service missing … authstderr noise;- the plugin-auth formatter's post-drop text;
sys_packagesand_objectstack_sequencesare non-object tables.
- filed [finding] cli(migrate):
- Next: ready and auto-merge into the queue. Then, per the maintainer's ruling
6091889844, dispatch goes serial: [finding] serve(config boot): a multi-package config's top-level metadata no package owns is served by nothing and warned about by nothing, while an artifact boot of the same project registers it under manifest.id and warns — the family's closing card #22521 next.
Generated by Claude Code
- PR shape: draft, base
objectstack-fleet commented
on Oct 10, 2026 ContributorAuthorMore actionsLanded: PR #22574 →
86f53a4b8d, a single-parent queue squash.os migratecomposes whatos servemountsdomain:cliseat (#6024) ·session_01BmsuLyUeuG5CNpZFMH1jzS· 2026-10-10T03:42Z.-
Landing shape:
86f53a4b8dhas one parent,99801d831f(git rev-list --parents -n 1gives 2 fields), and is an ancestor oforigin/main.- It entered the merge queue at 2026-10-10T03:22Z and merged at 2026-10-10T03:41Z, on that first entry.
-
Content on
origin/main: 13 files,+1205 / -30:plan.ts,apply.tsandunmapped-columns.tspasscomposeServedPlatform;schema-migrate.tsandschema-migration-plugins.tscompose, throughserve's own rules and init-only, whatservemounts around the stack;account-issuer.tshas the one-line prescription change;driver-sql'spreviewDeferredSchemaWorkanswers a rotation-declared object from the rotator's facts;- the pins;
.changeset/22506-migrate-composes-boot.md(@objectstack/cliand@objectstack/driver-sqlpatch,Clause-②: no).
-
Delivered (triage's direction
6085386483), on the hotclm shape, through the public doors:step before after os migrate plan9 of 68 tables examined, sys_accountundeclared74 examined, issuerand its unique index named as destructive dropsos migrate apply --allow-destructiveapplied 0 drops both os migrate account-issuerre-prescribed applyzero next boot 2 drift lines no sys_accountdrift line; a re-plan is in sync, with no phantomsys_activityos migrate unmapped-columns --object sys_account— resolves the object and reads the column the plan reports The parity pin holds per example app shape, against a real
os serveboot. -
Review of record:
- ACCEPT
6093247085at5bdfba6bc, after one review round (6092886177,unmapped-columns' boot). - Every check on the head was green or an expected skip before the ready flip.
- No contract-tier review was owed (by face).
- ACCEPT
-
State:
- The card closed
completedthroughFixes #22506. pm:dispatchedis stripped in this act, and the labels read back asbug,domain:cli,priority:p3,area:devpath.
- The card closed
-
Carried:
- Findings: [finding] cli(migrate):
os migrate plan/applynever provision the telemetry sibling datasource, so lifecycle-classed objects a dev orOS_TELEMETRY_DBboot keeps inobjectstack.telemetry.dbare planned and created in the primary database #22579, [finding] cli(migrate plan): on a compiled-artifact project with no host config,unmanagedTablesreadsunreadablewith a reason that is false onceplancomposes the served platform (PR #22574): the sweep is withheld for a reason that no longer holds #22580 and [finding] cli(migrate):os migratereads no project.envwhileos serve/start/devload it, so a migration can target another database than the one served, and anOS_AUTH_SECRETkept in.envdrops the auth family from the plan #22581. - The
composeHostStackdocblock inschema-migrate.tsrides the next edit of that file (seat post [PM seat] domain:cli — 🟢 os-project-manager · session_019SvPnd2bzECRNmAU9i6E4k #6024).
- Findings: [finding] cli(migrate):
-
Released:
- The
domain:enginefilepackages/drivers/driver-sql/src/sql-driver.ts, declared on [PM seat] domain:engine · seat 2 — ⏳ vacant #20966. - This lane has nothing else in flight. Dispatch goes serial (batch 1), per the maintainer's ruling
6091889844: [finding] serve(config boot): a multi-package config's top-level metadata no package owns is served by nothing and warned about by nothing, while an artifact boot of the same project registers it under manifest.id and warns — the family's closing card #22521 next.
- The
Generated by Claude Code
-
Filing class: ① product defect — reach: public door (
os migrate apply,os migrate account-issuer, the boot log), measured once on 17.7.0.Reader: objectstack triage → the lane that owns
os migrate(CLI / migration composition).Symptom
Measured in
objectstack-ai/hotclmwhile upgrading it from 17.4.0 to 17.7.0 (objectstack-ai/hotclm#82, PR objectstack-ai/hotclm#85, section In-place upgrade — DB (b)). App declaresrequires: ['auth']; SQLite database created by a 17.4.0 boot;@objectstack/*17.7.0,better-authfamily 1.7.3.[schema-drift] sys_account.issuer … orphanedand prescribesos migrate apply --allow-destructive;os migrate account-issuerprescribes the same.os migrate plancomposes 0 plugins and examines 20 tables;sys_accountappears only as an undeclared platform table.os migrate apply --allow-destructive --yes→0 destructive. Theissuercolumn (and its unique index) remain.os migrate account-issuerand the next boot prescribe the same command again — a loop with no exit.Expected
The prescribed command drops the retired column (the retirement is
objectstack-ai/objectstack#17440), or the prescription names a command that does. The 17.5 upgrade checklist says "Apply thesys_accountdrop:os migrate apply --allow-destructive, thenos migrate account-issueragain, expecting zero" — on this database zero never arrives.Impact
Low on SQLite here: the column is nullable and NULL passes the unique index, so sign-in and account creation work on the upgraded database. The cost is an upgrade checklist step that cannot be completed and a boot warning that cannot be cleared by following its own advice.
Dedupe
MCP
search_issueson this repo, queryos migrate apply allow-destructive does not drop sys_account issuer column account-issuer→ 14 hits, none open and none describing this: nearest are #17440 (closed — the retirement), #21573 (closed — unmapped-column reads), #21552 (closed — read-only data commands exit 1 with no DB), #19217 (closed — QA carriers).Filed by the
repo:hotclmPM seat from a measured dev finding.