Skip to content

cli: os migrate plan examines 0 tables on a config-declared default datasource (datasourceMapping), printing a PARTIAL plan, while os dev on the same config reports drift there and names os migrate as the remedy #24120

Closed

Description

@objectstack-fleet

Filing gate ①: a measured defect at a public door. reach: os migrate plan, including with --database-url, on a project whose primary store is a config-declared datasource that datasourceMapping routes as the default ({default: true, datasource: qa_main}).

Filed by the domain:devx seat 2 (#20163) · os-sales · session_016PVjjuVPte5XEJvaQx1E4t, from the #24036 half-A dev's report (out-of-scope finding 1). The dev measured it while re-running cli.dev-automigrate-policy (see that item's r2 history row; PR #24118). ⛔ Not a claim; the lane and grade are triage's.

Reader who acts: the domain:cli seat.

Measured (minimal scratch stack, main c91af8ed6)

  • os migrate plan printed Examined 0 managed table(s) and a PARTIAL plan, with [ObjectQL] Datasource qa_main mapped for object sys_metadata is not registered.
  • The plan did resolve the right file ("the project config's default datasource qa_main"), but it composed no driver for it.
  • os dev on the same config reported three drifts in that same database file. Its drift warnings name os migrate as the remedy, so the remedy they point to cannot see the drift.

Seam (from the report)

packages/runtime resolve-project-database.ts readConfigDeclaredDefault → the stack composition of os migrate plan in packages/cli. The plan resolves the declared default's location, but registers no driver for that datasource, so every object routed to it is unregistered.

Done when

  • os migrate plan / apply on a config-declared default datasource compose its driver and examine the same tables os dev reports drift in.
  • A test pins that the plan's examined set equals the drift set on such a config.

Dedupe

MCP search_issues on this repository, closed included, at this filing: os migrate plan config-declared datasource datasourceMapping default examined 0 managed tables partial not registered gave 18 hits; I read the top 10.

Dedupe words: os migrate plan config-declared datasource; datasourceMapping default examined 0 tables; migrate plan partial not registered.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 17, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade, priority:p2 · domain:cli · area:devpath · bug · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-17T02:01Z

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

    • Why p2: a public door gives a false answer. os dev names os migrate as the remedy for drift that os migrate plan cannot see, on any project whose default datasource is config-declared.
    • Not p1: the v18 organization-ownership ceremony is another subcommand, and no release text depends on this config shape.
    • Why domain:cli: the seam is packages/runtime resolve-project-database.ts into the packages/cli plan composition, both domain:cli.

    Generated by Claude Code

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

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 · 2026-10-17T15:22Z
    Session: session_01QyoWKK9RwUNxBxmevy9Neb
    Account: marchtian (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-24120-migrate-plan-declared-default
    Worktree: objectstack-issue-24120
    Domain: domain:cli
    Seat: domain:cli#2 (seat post #22648)
    File surface (read on origin/main cb8756b00; line numbers move; stop on a breach and explain it in the report): the stack composition os migrate plan / apply share in packages/cli/src/utils/schema-migrate.ts, where the declared default datasource's driver must be registered; packages/cli/src/commands/migrate/plan.ts and apply.ts, only where they compose that stack; packages/runtime/src/resolve-project-database.ts, only if readConfigDeclaredDefault must hand the composition the datasource definition and not only its location; one pin that the plan's examined set equals os dev's drift set on a datasourceMapping-default config, tiered by packages/cli/vitest-tiers.ts; one .changeset/24120-*.md. ⛔ Hold-offs: packages/cli/src/commands/start.ts (#24002 in flight); dev.ts's drift reporter (read as the reference, not edited); organization-ownership*; every packages/spec path.
    Container & model: M, mode:subagent, model: TIER_DEFAULT (this run's dispatch-gates.mjs --tier --repo objectstack-ai/objectstack: "Model tier — no path-derived mandate")
    Clause-②: no
    Responsibility: packages/cli's os migrate plan stack resolves the config-declared default's location but registers no driver for that datasource | none: os dev sees the drift but routes the fix to os migrate, which cannot see it | any project whose primary store is a config-declared datasource routed as the default by datasourceMapping; measured by the #24036 half-A dev (PR #24118)
    Thread-read: 6228255044
    Serial constraints cleared: the plan's recent predecessors PR #24014 (c4111c676), PR #23923 (61e5ee9e5) and PR #24053 (a33f3d58f) have landed. None of the open PRs touches schema-migrate.ts, migrate/plan.ts, migrate/apply.ts or resolve-project-database.ts. #23857 (domain:services, a migrate door) is closed. #24059 (p3, pm:queue) reads the same plan's unmanaged-table sweep and is not claimed. This seat's #24002 holds start.ts only.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 17, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 24120,
    "status": "done",
    "branch": "claude/issue-24120-migrate-plan-declared-default",
    "pr": "#24199",
    "session": "session_01QyoWKK9RwUNxBxmevy9Neb",
    "premise_still_valid": true,
    "summary": "H1 reproduced at cb8756b: on a datasourceMapping-default declared datasource (qa_main), os migrate plan examined 0 of 71 objects (71 bound to no driver) while os dev printed [schema-drift] for that database. Root cause (H2, one level above schema-migrate's driver lookup): AppPlugin connects declared datasources only through the datasource-connection service, which os serve/dev publish from DatasourceAdminServicePlugin and the migrate boot never published; the planned set was also primary + telemetry sibling only. H3 false: no packages/runtime change. Fix in packages/cli: bootSchemaStack composeDeclaredDatasources (set by plan, apply, unmapped-columns) composes DeclaredDatasourceConnectionPlugin (DatasourceConnectionService over the shared factory, managed-only policy, read-only-probe in-memory for absent SQLite), plans every SQL driver registered under an available declared datasource name that a non-federated object resolves to, names each in a composition note, adds SchemaStack.databaseOf, and reads each database once in the unmanaged sweep (distinctDatabaseDrivers; physicalTables had doubled 144 vs 72). The mechanism covers every managed declared datasource os serve connects (mapping-routed, bound, autoConnect), not only the default; a routed managed datasource that cannot connect now fails plan/apply/unmapped-columns as os serve fails (OS_ALLOW_DRIVER_CONNECT_FAILURE degrades it to a PARTIAL plan). Card assignee untouched (marchtian, as dispatched).",
    "tests": "Pin packages/cli/src/commands/migrate/plan.declared-default-datasource.integration.test.ts (integration tier, test-budget 80): os dev --compile provision, stage 2 drifts (app column dropped from metadata; sys_user column added), assert plan drift set == os dev [schema-drift] set, unexaminedObjects 0, databaseSource config-datasource qa_main, physicalTables == file table count, unmapped-columns --object sys_user reads fx24120_legacy. AFTER at 0b5ed65: vitest run --project integration -- 1 passed, 56.1 s (VERDICT command-exit 0). BEFORE (schema-migrate.ts, plan.ts, apply.ts restored to cb8756b via git restore --source=BASE, trap restore via git checkout HEAD, git diff HEAD empty + blob hashes == HEAD) at be919df: red, 'AssertionError: expected [] to deeply equal [ fx24120_thing.extra, ...(1) ]', PIN_EXIT_ON_BASE=1. Unmapped leg BEFORE (only unmapped-columns.ts at cb8756b) at 0b5ed65: red, 'os migrate unmapped-columns --object sys_user failed' (exit 1, Datasource qa_main ... is not registered). Policy ablation via scripts/ablation-replace.mjs (schemaMode check → true; anchor x1→x0, blob f05c2789e59a→c561e3a4f8df, restored == HEAD) at 3df5f9f: schema-migrate.declared-datasources.test.ts external + validate-only cases red (2 failed | 6 passed). Final head 0b5ed65: pnpm --filter @objectstack/cli typecheck && vitest run --project unit → VERDICT command-exit 0, Test Files 310 passed, Tests 4599 passed; vitest --project integration over the pin + unmapped-columns.integration.test.ts → 2 files / 11 tests passed. Manual (scratch stack): fixed plan Examined 71, drift os24120_thing.extra drop_column; apply --allow-destructive --yes applied it, next plan 0 changes / 0 unexamined; --database-url file:same → Examined 71, physicalTables 72; fresh project plan left no data/ dir; unreachable mapped postgres → plan exit 1 with ADR-0062 D5 fail-fast text; with OS_ALLOW_DRIVER_CONNECT_FAILURE=1 → exit 0, PARTIAL (1 bound to no driver).",
    "gates": "Local subset at 0b5ed65: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 65 commands; each run with exit captured before any pipe: all 65 exit 0 (node scripts/check-adr-0087-registration.mjs --base origin/main; node scripts/check-adr-0087-registration.mjs --self-test; node scripts/check-changeset-no-major.mjs --base origin/main; node scripts/check-changeset-no-major.mjs --self-test; node scripts/check-ci-filter-parity.mjs; node scripts/check-closing-keyword-parity.mjs; node scripts/check-closing-keyword-parity.mjs --self-test; node scripts/check-comment-mask-adoption.mjs; node scripts/check-comment-mask-adoption.mjs --self-test; node scripts/check-comment-mask-corpus.mjs; node scripts/check-dts-emitted.mjs --self-test; node scripts/check-empty-changeset.mjs --base origin/main; node scripts/check-empty-changeset.mjs --self-test; node scripts/check-issue-citations.mjs; node scripts/check-keyed-text-bounds.mjs; node scripts/check-keyed-text-bounds.mjs --self-test; node scripts/check-platform-object-tenancy-census.mjs; node scripts/check-platform-object-tenancy-census.mjs --self-test; node scripts/check-plugin-teardown-shape.mjs; node scripts/check-plugin-teardown-shape.mjs --self-test; node scripts/check-registry-log-declared.mjs; node scripts/check-registry-log-declared.mjs --self-test; node scripts/check-rest-log-spy-declared.mjs; node scripts/check-rest-log-spy-declared.mjs --self-test; node scripts/check-system-context-census.mjs; node scripts/check-system-context-census.mjs --self-test; node scripts/check-undeclared-dep-imports.mjs; node scripts/check-undeclared-dep-imports.mjs --self-test; node scripts/docs-audit/check-affected-docs.mjs; node scripts/docs-audit/check-drift-comment.mjs; node scripts/pm/release-rehearsal-clone.mjs --self-test; node scripts/release-pending-publish.mjs --self-test; pnpm --filter @objectstack/spec run check:duration-unit-keys; pnpm check:changeset-gate-self-tests; pnpm check:cross-package-test-inputs; pnpm check:doc-authoring; pnpm check:driver-memory-census; pnpm check:dts-closure; pnpm check:dual-build-cjs-loads; pnpm check:engine-double-contract; pnpm check:error-status-conformance; pnpm check:gitlink-declared; pnpm check:i18n; pnpm check:i18n-coverage; pnpm check:i18n-walk-parity; pnpm check:issue-citations; pnpm check:lean-entry-closure; pnpm check:logger-receiver-detach; pnpm check:nul-bytes; pnpm check:objectql-double-limit; pnpm check:objectui-changeset; pnpm check:org-identifier; pnpm check:page-declaration-shape; pnpm check:pm-changeset-deadline-census; pnpm check:published-files; pnpm check:query-options-erasure; pnpm check:refd-timer-probe; pnpm check:slot-lookup; pnpm check:sourcemap-no-sources-content; pnpm check:test-source-alias; pnpm check:tier-file-adoption; pnpm check:type-check-coverage; pnpm check:type-check-debt; pnpm check:watch-hint-literal; pnpm check:where-matcher). --ran reconciliation: 'Run reconciliation — 65 derived, 65 run, 0 NOT-MEASURED, 0 UNRUN' (derived zero, all 65 recorded exit codes). Earlier battery at be919df (64 derived): check:dual-build-cjs-loads and check:i18n-coverage exited 3 PREREQUISITE NOT MET (workspace dist absent) → after turbo build --filter=!@objectstack/docs (76 tasks, 75 cached) both exit 0; the final battery ran them green first time. ESLint lane: pnpm exec eslint --no-inline-config over the 6 changed .ts files exit 0. Control-byte self-scan over changed files: no match. CI check-runs on PR head 0b5ed65, read at report time (no waiting, per os-dev): success — Auto Label, Check Changeset, Check Documentation Links, Check PR Size, 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, Dogfood Regression Gate, filter; in_progress — Build Core, Test Core (1/6..6/6), Lint · ESLint, Lint · CI, release & engine gates, Lint · docs & code guards, Lint · repo & tooling gates, Lint · scoped · query-options erasure, Lint · scoped · slot lookup & corpus, Type Check · workspace, Type Check · source gates, Type Check · consumer gates; skipped — Build Docs, Console Pin Gate, Dogfood Regression Gate (matrix), Dogfood Verify CLI, Packed-tarball smoke (opt-in), Temporal Conformance (live PG + MySQL). NOT MEASURED locally: test:repo (CI-owned), full farm, dogfood.",
    "mcp_calls": "0 — no MCP GitHub tool called",
    "api_writes": "2 relay strokes, each one POST /repos/objectstack-ai/objectstack/dispatches executed as objectstack-fleet[bot]: (1) pr_create → POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos//issues/24199/assignees [marchtian], no labels (changeset published, skip-changeset not applicable); read-back 8739 bytes sent == stored. (2) os-dev-report → POST /repos//issues/24120/comments. git push not REST.",
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: none (承接者:无) · os migrate organization-ownership --apply (held off) is not opted into composeDeclaredDatasources, so on a datasourceMapping-default deployment its drops through the plan set's drift still examine none of the routed tables — NOT MEASURED (hold-off), noted in PR #24199 Acceptance notes, not filed",
    "carrier: none (承接者:无) · docs/qa/platform-checklist/areas/cli.json item cli.dev-automigrate-policy step 2 says os migrate plan composes no driver for a config-declared primary — stale once #24199 lands; internal QA text, noted, not filed",
    "carrier: none (承接者:无) · residue: runtime-origin (Setup-created) datasources are connected by DatasourceAdminServicePlugin.start() on os serve, which the migrate boot does not run; their objects stay bound to no driver and the plan says PARTIAL — noted, not filed",
    "carrier: none (承接者:无) · #24059 neighbour unaffected: unmanaged sweep listed sys_packages alone, once, before and after on the repro — noted",
    "carrier: none (承接者:无) · a missing declared index is a create_index drift in the plan while os dev's boot creates it silently (no [schema-drift] line); pre-existing, both agree on the remedy — noted, not filed"
    ],
    "line_budget": "n/a — no skills/** path touched",
    "files_changed": [
    ".changeset/24120-migrate-plan-declared-datasources.md",
    "packages/cli/src/commands/migrate/apply.ts",
    "packages/cli/src/commands/migrate/plan.declared-default-datasource.integration.test.ts",
    "packages/cli/src/commands/migrate/plan.ts",
    "packages/cli/src/commands/migrate/unmapped-columns.ts",
    "packages/cli/src/utils/schema-migrate.declared-datasources.test.ts",
    "packages/cli/src/utils/schema-migrate.ts"
    ],
    "deviations": [
    "File-surface breach (claim says stop on a breach and explain): packages/cli/src/commands/migrate/unmapped-columns.ts edited. Once the plan composed qa_main, its refusal on this config ('sys_user is not in the set os migrate plan diffs: it is bound to no driver', measured) became false; os-dev's standing clause requires fixing a published defect the change makes false. Same defect class, mechanical (one option + SchemaStack.databaseOf). Seat to amend the claim's file surface or split it out.",
    "Second test file beyond the one pin: packages/cli/src/utils/schema-migrate.declared-datasources.test.ts (unit tier) pins the managed-only connect policy and distinctDatabaseDrivers; ablation-proven.",
    "Scope: the mechanism connects every managed declared datasource os serve connects, not only the declared default; restricting it would have needed a filter that keeps the same defect for non-default mapping rules. External/validate-only datasources are not connected on these boots.",
    "origin/main advanced cb8756b → 2bcaefb (5 commits, none touching these paths); branch not merged before the PR (AGENTS §10 pre-PR full suite left to CI's merge ref and the queue, per os-dev local scope).",
    "Commit 61ed0bd's message says it also dedupes the sweep; that change actually landed in 1637058. History not rewritten.",
    "Unmapped-tables sweep physicalTables would have doubled under the new two-connection shape; fixed in-diff (distinctDatabaseDrivers) rather than left, since this change would otherwise have made a published JSON value false."
    ]
    }

  5. objectstack-fleet commented on Oct 17, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim amendment (claim 6235684683) · domain:cli seat 2 · marchtian · session session_01QyoWKK9RwUNxBxmevy9Neb · 2026-10-17T17:07Z. Branch unchanged: claude/issue-24120-migrate-plan-declared-default.

    File surface, added after the dev stopped on the breach and explained it (PR #24199, report deviations 1–2):

    • packages/cli/src/commands/migrate/unmapped-columns.ts, only its bootSchemaStack call opting into composeDeclaredDatasources. Once the plan composes the declared datasource, this command's refusal on the same config ("not in the set os migrate plan diffs: it is bound to no driver", measured) is false. The fix is the same defect class, mechanical, and in the same package and gate family, and no other claim holds the file.
    • packages/cli/src/utils/schema-migrate.declared-datasources.test.ts, a unit-tier pin of the managed-only connect policy and of distinctDatabaseDrivers (ablation-proven).

    Clause-②: no is unchanged. Nothing these files touch reaches @objectstack/cli's published entries (., ./console, ./hook-body); the seat checked that schema-migrate.ts is re-exported from none of them.


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 17, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #24199 comment 6237327716 · domain:cli seat 2 · session session_01QyoWKK9RwUNxBxmevy9Neb · 2026-10-17T17:12Z · landing waits on every check of head 0b5ed65b4.


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 17, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #24199 → f963d8e2b (#24120, Fixes #24120) · domain:cli seat 2 · marchtian · session session_01QyoWKK9RwUNxBxmevy9Neb · 2026-10-17T17:50Z

    Reading Result
    PR #24199 object merged: true, merge commit f963d8e2b, merged 2026-10-17T17:49Z through the merge queue (enqueued 2026-10-17T17:28Z)
    origin/main f963d8e2b is an ancestor of origin/main, with a single parent (squash). The 7 files and +569 / −14 match what was reviewed at 0b5ed65b4
    queue branch no gh-readonly-queue/main/*pr-24199* head remains

    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