Skip to content

[finding] The three kernel:ready runtime index migrations are invisible to os migrate plan by construction — #3728's class, re-created through a different door #8725

Description

@hotlong

Filed unassigned and unlabelled beyond finding, from the PM seat reviewing PR #8719 (#8629). Grading and routing are triage's field. Duplicate-checked first — and the nearest hit is closed, which is the interesting part.

The observation

packages/metadata-protocol now issues three unique-index migrations at kernel:ready:

migrationtable
ensureOverlayIndexsys_metadata
ensureViewDefinitionActiveIndexsys_view_definition
ensureSysSettingIdentityIndex (new, PR #8719)sys_setting

Each folds a NULL-safe key the declared-index vocabulary cannot express, and each must be excluded from detectManagedDrift() — otherwise the reconciler would propose rebuilding the tightened index back into its NULL-distinct declared form on the next boot. That exclusion is correct and is deliberately pinned in PR #8719 ("is NOT reported as drift — the reconciler must never propose rebuilding it away").

The consequence is the finding: because they are invisible to the drift differ, os migrate plan does not report them, or the duplicate rows that block them. An operator who reaches for the CLI before reading the boot log is told nothing. The refusal is reported at error in the boot's conflict report, with the exact row-listing query — so the information exists, but only on one channel.

Why this is NOT a duplicate of #3728

#3728"unique 索引迁移在启动时静默执行 DDL,os migrate plan 看不到 —— 运维无预检手段" — describes this symptom exactly. It was closed completed by merged PR #3737, "feat(driver-sql)!: index drift is planned, not silently executed at boot".

That fix was real, and it addressed a different mechanism: SqlDriver.syncTableIndexes()dropLegacyGlobalUniques(), inside schema sync. The three migrations above arrive through a different doorkernel:ready hooks in metadata-protocol, not driver schema sync — and #3737's remedy cannot cover them, because the remedy is drift detection and these must be excluded from drift detection to survive at all.

So the class #3728 closed has re-accreted through a channel whose correctness requires the very exclusion that makes it invisible. Recording it by symptom against current main rather than by issue number, which is what the shared-infrastructure re-check rule asks for.

⚠️ Note the direction of travel: #3728 is one instance, this is three, and each new NULL-safe key the declared vocabulary cannot express adds a fourth. #8629's own ruling deferred the vocabulary fix (Route 2 — declaring NULL-safe uniqueness in the spec, which would let the declared index say what it means and stop needing a runtime migration at all) to v18. If Route 2 lands, this finding shrinks or disappears; if it slips, this grows.

Not claimed

  • No user-facing defect is demonstrated. The refusal is loud on the boot channel and deletes nothing; this is about a second channel being silent.
  • No opinion on the fix. Whether os migrate plan should run the three migrations' duplicate probes is a decision about the CLI's contract, not a defect to patch — the PM seat explicitly did not decide it, and it would land in domain:cli.
  • Not measured beyond the read above: I did not stand up a duplicate-carrying database and run os migrate plan against it to confirm the empty output end to end. The exclusion is established from the pinned drift assertion and the differ's design, not from a CLI run.

Related

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions