Skip to content

cli: os migrate plan lists sys_packages under "declared by no object in this plan" right after os migrate apply created it — the unmanaged-table sweep's known set omits the one table migrate itself plans outside the object set #24059

Open

Description

@objectstack-fleet

Filing gate ①: a product defect at a public door, measured. reach: os migrate plan on examples/app-crm, run straight after os migrate apply --yes against the same file. Measured at base bb14934cd and at PR #24053's head c4adb868c. Both runs print, under "table(s) in the database(s) this plan covers carry a reserved platform prefix (…) and are declared by no object in this plan:":

  • • sys_legacy_widget (the fixture's own stranded table, rightly reported);
  • • sys_packages, a table that same apply created.

So every applied deployment's plan reports its live package registry table as if it were stranded. The section says nothing drops it, but it tells the operator a table the platform owns is declared by nothing.

Filed by the domain:cli seat 2 (seat post #22648) · os-tesla · session session_018t6a5rvqPRvEDMCVVW9kYT, from #23899's dev report (6225291587, out-of-scope finding 1, class a). ⛔ Not a claim; the grade and lane are triage's.

Reader who acts: the domain:cli seat, for packages/cli/src/utils/unmanaged-tables.ts and its caller in os migrate plan.

Where (origin/main 905f57bc7)

  • packages/cli/src/utils/unmanaged-tables.ts buildKnownTableNames (about :250). The known set is the plan's managed set plus every declared object's name and mapped table name. selectUnmanagedTables then reports every platform-prefixed physical table outside it.
  • sys_packages is neither. It is not an object. PackageServicePlugin.start() creates it with raw DDL (packages/services/service-package/src/index.ts, about :370–:394). Since service-package: sys_packages is created by raw boot DDL that ignores OS_SKIP_SCHEMA_SYNC=1, and os migrate apply (the flag's documented path) does not create it #23022, os migrate apply plans it as "the one table outside the object set" (packages/cli/src/utils/schema-migrate.ts, about :295–:349 and :1164).
  • So one tool plans the table and creates it, and its sibling sweep calls the same table stranded.

Done when

  • os migrate plan after os migrate apply on examples/app-crm no longer lists sys_packages as unmanaged. A genuinely stranded sys_* table (the fixture's sys_legacy_widget) is still listed.
  • The known set takes sys_packages from the same source schema-migrate.ts plans it from, not from a second hand-typed list. A pin fails against today's sweep.

Dedupe

MCP search_issues on this repository, closed included: os migrate plan unmanaged tables sys_packages declared by no object after apply gave 33 hits. The first ten were read. #23022 (closed) is the producer card: it made apply plan sys_packages, and it did not touch the sweep. The other nine are other migrate defects (#21732, #21054, #23925, #23948, #23848, #23397, #23398, #22984, #23552). None is this sweep.

Dedupe words: unmanaged tables sys_packages declared by no object; migrate plan unmanaged sweep sys_packages; reserved prefix sys_packages after apply.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 17, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade, bug · priority:p3 · domain:cli · area:devpath · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-17T00:05Z

    Triage seat (objectstack-wide, seat post #6015). ⛔ Not a claim, ⛔ not a dispatch.

    • Why p3: os migrate plan lists sys_packages, a table its own apply created, as declared by nothing. The section drops nothing; only the sentence misleads.
  2. objectstack-fleet commented on Oct 17, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 2 · 2026-10-17T21:37Z
    Session: session_01QyoWKK9RwUNxBxmevy9Neb
    Account: marchtian (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-24059-unmanaged-sweep-sys-packages
    Worktree: objectstack-issue-24059
    Domain: domain:cli
    Seat: domain:cli#2 (seat post #22648)
    File surface (read on origin/main aa31569b2; line numbers move; stop on a breach and explain it in the report):


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 17, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 24059,
    "status": "done",
    "branch": "claude/issue-24059-unmanaged-sweep-sys-packages",
    "pr": "#24226",
    "head": "7a3803bd32656fc4b15a47d1c61c48c786fc345c",
    "session": "session_01QyoWKK9RwUNxBxmevy9Neb (subagent: the parent's id, from the harness Claude-Session line)",
    "premise_still_valid": true,
    "summary": "The unmanaged-table sweep now counts the tables the boot's composition declares outside the object set. schema-migrate.ts has one reader of the package.storage declaration, findPackageStorage(kernel): the lookup and shape check that used to open planPackageTable. bootSchemaStack reads it once per boot, plans sys_packages from it as before (deferring boots only), and exposes the same object's table as SchemaStack.nonObjectTables on every boot, whether or not the table exists; it is [] when no package registry is composed. plan.ts passes it to collectUnmanagedTables (a required option), and buildKnownTableNames adds it verbatim. No table name is spelled in the sweep. H1 and H2 confirmed: planPackageTable returns null once the table exists, and pending is [] after an apply, so the fix reads the declaration, not the planned work. The sweep runs in the same boot and kernel as the plan. H3 pinned as a unit-level decision: no registry composed means no declaration, and a physical sys_packages is reported. On a mirrored boot the always-on package-registry slate always composes PackageServicePlugin, so the door cannot reach that case. H4 door on examples/app-crm (fresh sqlite with sys_legacy_widget, apply --yes then plan): base aa31569 listed sys_legacy_widget and sys_packages; head 04c0d95 lists sys_legacy_widget only; physicalTables 81 both. One behaviour widening, declared in the changeset and the PR: a wrong-shape package.storage (cli/service-package version skew) now also refuses the skip-schema-sync boot of plan, apply and organization-ownership, with the release-mismatch error those commands already gave on deferring boots.",
    "tests": "Door, through packages/cli/bin/run-dev.js on examples/app-crm, fresh OS_HOME, DB env unset, file:DB with sys_legacy_widget pre-created. migrate apply --yes printed '+ sys_packages [create_table, 7 column(s)]'. Then plan: base aa31569 printed '2 table(s) ... declared by no object in this plan: sys_legacy_widget, sys_packages', and --json unmanagedTables.tables was [sys_legacy_widget, sys_packages], physicalTables 81, pending []. Head 04c0d95 printed '1 table(s) ...: sys_legacy_widget', and --json tables was [sys_legacy_widget], physicalTables 81, pending []. All runs below were under os-verify-lock, slot issue-24059, reading the VERDICT line. pnpm --filter @objectstack/cli typecheck at 04c0d95: VERDICT command-exit 0; check:test-typecheck held 3 files / 28 errors / 6 signatures. tsc -p packages/cli/tsconfig.json --listFilesOnly: 5 of 5 touched test files in the 1611-file program. Targeted unit run (unmanaged-tables.test + plan.journal-mode-note + plan.apply-limit + apply.remote-posture): Test Files 4 passed, Tests 68 passed. CLI unit tier, vitest run --project unit --maxWorkers=2 at 04c0d95: Test Files 2 failed | 308 passed (310), Tests 4573 passed | 29 skipped. The 2 files were test/published-subpath-console.pin and published-subpath-hook-body.pin, refused before their bodies ran ('packages/cli is not built'). After pnpm --filter @objectstack/cli build, both passed: Tests 29 passed (29). Integration, --project integration, the 4 touched files at 04c0d95: unmanaged-tables.integration + schema-migrate.package-table.integration 4 passed; plan.boot-parity.integration 3 passed; plan.telemetry-sibling.integration 2 passed. After the merge at 7a3803b: test/published-entry-node-env-source-reroute.test.ts + unmanaged-tables.test.ts, 50 passed. Ablation at 04c0d95 (fix committed): node scripts/ablation-replace.mjs --file packages/cli/src/utils/unmanaged-tables.ts --anchor 'for (const table of nonObjectTables) known.add(table);' --delete, wrapping vitest on unmanaged-tables.test.ts. Anchor 1 to 0, blob 99e653e8d5d0 to 33c383315c85. Result: Tests 2 failed | 43 passed (45); the red cases were the [#24059] known-set case and the after-an-apply case; the DECISION case stayed green, as expected. Restore: blob == HEAD 99e653e8d5d0, git diff HEAD empty, git status --porcelain empty. The suite imports ./unmanaged-tables.js relatively (src), so no dist leg applies. The two flipped door-level pins (boot-parity: sweep names nothing; telemetry-sibling: [retired] only) asserted [sys_packages] and were green at base, so the new assertions fail against today's sweep.",
    "gates": "Local, at 7a3803b: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack -> 64 commands, merge base b9ac35c, 9 paths, 232 changed lines (+189/-43), exit 0, no stale-tree warning. A first derivation at 04c0d95 warned STALE TREE (1 commit behind), so origin/main was merged and the list re-derived: identical 64. All 64 ran, each exit captured before any pipe. 62 exited 0 on the first run. pnpm check:dual-build-cjs-loads and pnpm check:i18n-coverage exited 3 (PREREQUISITE NOT MET); both exited 0 after turbo run build --filter='!@objectstack/docs' --concurrency=2 (76 tasks, 75 cached, VERDICT command-exit 0). dispatch-gates --ran ran.list -> exit 0, '64 derived, 64 run, 0 NOT-MEASURED, 0 UNRUN' (ran.list records the post-build exit for those two). Lane blind spot: pnpm exec eslint --no-inline-config over the 8 changed .ts files -> exit 0. Repo-wide pnpm lint is CI's. check-platform-checklist --changed-from was not run: no exported symbol was renamed or deleted (buildKnownTableNames gained a parameter, collectUnmanagedTables an option). CI on PR #24226 head 7a3803b, second read just before this report (37 check-runs). success: Auto Label, Check Changeset, Check Documentation Links, Check PR Size, Dogfood Regression Gate, Flag docs affected by code changes, Governed Surface Queue Guard, Lint · PM dispatch-gates, Lint · scoped · tooling self-tests, No other open PR may claim the same issue, No other open PR may claim the same single-writer path, Part-of PR must not also close its card, The card this PR closes must claim this branch, Type Check · debt ledger, filter. skipped: Build Docs, Console Pin Gate, Dogfood Regression Gate shards, Dogfood Verify CLI, Packed-tarball smoke (opt-in), Temporal Conformance (live PG + MySQL). in_progress: Build Core, Test Core (1/6 to 6/6), Lint (CI release & engine gates, ESLint, docs & code guards, repo & tooling gates, scoped query-options erasure, scoped slot lookup & corpus), Type Check (consumer gates, source gates, workspace). NOT MEASURED: those 16 in_progress runs, reason: in_progress at report time; the PM's CI-convergence read owns them.",
    "mcp_calls": "0",
    "api_writes": "2 relay strokes (scripts/pm/with-fleet.sh --via dispatch, each one POST /repos/objectstack-ai/objectstack/dispatches) executing 3 REST writes as objectstack-fleet[bot]: POST /repos/objectstack-ai/objectstack/pulls (draft, #24226) + POST /repos//issues/24226/assignees (marchtian), both read back by the relay (body 9383 bytes sent = stored; assignee listed); and POST /repos//issues/24059/comments (this report). git push x3 of the branch (empty-branch probe, fix commit, merge commit), not REST. No labels written.",
    "line_budget": "n/a: skills/** not touched",
    "deviations": [
    "Attribution: the harness reminder asked for a model-named Co-Authored-By and an emoji PR footer. The commits (fix and merge) carry the model-free pair the dispatch and AGENTS.md require, and the PR body ends with the AGENTS.md session-URL footer.",
    "Merged origin/main (b9ac35c: CI workflows plus one CLI test file) before opening the PR, to clear dispatch-gates' STALE TREE warning. Merge commit 7a3803b, model-free trailers. Scoped re-check: the one incoming CLI test file and the sweep's unit file, 50 passed. The typecheck, unit tier and integration runs are at 04c0d95, before the merge.",
    "File surface: beyond 'pins beside them', two door-level integration pins in packages/cli/src/commands/migrate (plan.boot-parity, plan.telemetry-sibling) encoded the defect, expecting sys_packages in the sweep, and were flipped. schema-migrate.package-table.integration gained two nonObjectTables assertions. No edit in packages/services/service-package or packages/spec.",
    "The CLI integration tier is CI's. The diff touches 4 integration files, so those 4 were run locally; the rest of the integration tier and test:repo are declared to CI, not run locally.",
    "Three stack doubles that feed plan.ts (plan.apply-limit, plan.journal-mode-note, apply.remote-posture) were not given nonObjectTables. Their composition is not mirrored, or collectUnmanagedTables is mocked, so the sweep never reads it there; all three passed (68 tests).",
    "Verify lock: one call returned VERDICT queue-timeout (exit 99) behind pid 13444 (pnpm --filter @objectstack/runtime exec vitest run --project local, held 548s). It was re-queued under the same slot and not read as a measurement.",
    "The first gate-battery launch read its list through a relative path after cd and ran nothing (ran=0). It was relaunched with absolute paths; only the second launch is cited.",
    "Behaviour widening, stated rather than avoided: findPackageStorage runs on every boot, so a cli/service-package shape skew now also refuses the skip-schema-sync boot of plan, apply and organization-ownership (in the changeset and the PR's Acceptance notes)."
    ],
    "files_changed": [
    ".changeset/24059-unmanaged-sweep-sys-packages.md",
    "packages/cli/src/commands/migrate/plan.boot-parity.integration.test.ts",
    "packages/cli/src/commands/migrate/plan.telemetry-sibling.integration.test.ts",
    "packages/cli/src/commands/migrate/plan.ts",
    "packages/cli/src/utils/schema-migrate.package-table.integration.test.ts",
    "packages/cli/src/utils/schema-migrate.ts",
    "packages/cli/src/utils/unmanaged-tables.integration.test.ts",
    "packages/cli/src/utils/unmanaged-tables.test.ts",
    "packages/cli/src/utils/unmanaged-tables.ts"
    ],
    "cleanup": "Door fixture databases deleted. No background process of this run is alive (unit-tier, gate-battery and build PIDs all exited and were read). The branch is pushed and the tree is clean at 7a3803b. The worktree ../objectstack-issue-24059 (node_modules, then git worktree remove without --force) is removed right after this comment is posted, because the relay sending it runs from that worktree; the final message carries that step's result.",
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: 承接者:无 · noted, not filed: nonObjectTables joins the known set as a union over every planned database (like the managed set beside it), while the registry writes only to the default driver, so a sys_packages table in the telemetry sibling would also go unreported. Over-excluding is the module's stated safe direction; not measured; in PR Acceptance notes."
    ]
    }

  4. objectstack-fleet commented on Oct 17, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #24226 comment 6242588507 · domain:cli seat 2 · session session_01QyoWKK9RwUNxBxmevy9Neb · 2026-10-17T22:51Z · landing waits on every check of head 7a3803bd3.


    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:clipm:dispatchedpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions