Skip to content

spec(system): DataMigrationFlagSchema gains the nullable datetime that attests ADR-0104 step 3 ran on this deployment #16185

Description

@claude

What this card is

ADR-0104's addendum needs a deployment to be able to say "my media columns have been
moved"
, separately from "the backfill's self-check passed". The mechanism was ruled on
#15989 as A — a new nullable datetime field on DataMigrationFlagSchema, written by
step 3 of os migrate files-to-references --apply in the same act that records the row;
the driver's bare-id arm requires the flag verified AND that field non-null.

The same ruling refused to let the driver card carry it:

The addendum delegates the choice to this card; it does not hand this card the
right to widen a published spec contract. ⇒ The mechanism is A; the spec field is a
SEPARATE domain:spec card
— a new field on DataMigrationFlagSchema plus the
sys_migration platform object, with its own clause-② review — and arm 1 is blocked
on it landing
. ⛔ Do not smuggle a spec contract field into a driver card.

⇒ This is that card. Nothing in packages/drivers/** changes here.

The surface

  • packages/spec/src/system/migration.zod.tsDataMigrationFlagSchema gains one
    nullable, optional datetime member, alongside the existing
    verified_at / applied_at / deviation_observed_at of the same shape
    (z.string().datetime().nullable().optional()), with a .describe() that says what it
    attests and what its absence means.
  • packages/platform-objects/src/system/sys-migration.object.ts — the matching column on
    the sys_migration platform object. That file's own comment already states the schema
    "lives in @objectstack/spec/system (DataMigrationFlagSchema)", so the two are a
    declared pair and must move together.

Binding constraints

  1. Absence must mean the JSON arm. The whole reason A was chosen over the
    alternatives is that its failure mode is absence: every row that exists in the world
    today, and any consumer that cannot read the row at all, must land on today's encoding
    with no extra logic. Optional + nullable is therefore not a style choice — it is the
    contract.
  2. Do not touch isDataMigrationFlagVerified. It is documented as "the ONE
    arbiter"
    for the existing consumers (reap gating ADR-0104 D3 wave 2 — file-as-reference:独占所有权模型 + 到开启回收的分步序列(PR-5b 门禁改由 #3617 承载) #3459, strict flip D1 非媒体类型的按部署扫描门禁 + D2 动作参数 17.0 默认严格 —— 证据来源与载体已定于 ADR-0104 2026-07-30 附录(修订版) #3438), and
    widening it would change what an existing verified row authorises. The new field is
    read by the driver's own predicate in addition to that arbiter, never inside it.
    Pin that its return value is unchanged for a row that omits the new field.
  3. This card writes nothing to the field. No migration step, no --apply arm, no
    engine read. It adds the declaration and the column and stops. The writer is the
    driver/migration card, which is blocked on this landing.
  4. Clause-②: expect yes. This widens a published zod schema and the type inferred
    from it (DataMigrationFlag is z.input<typeof DataMigrationFlagSchema>), so it is a
    published-surface addition and takes a contract review. ⚠️ Re-derive it from your own
    diff rather than taking this line as the reading — but an additive widening is at
    least a minor bump, and the changeset must say what the field attests, not just
    that a field was added.
  5. ⚠️ Naming is yours and must be argued. Whatever you pick has to read correctly on a
    row where it is null on a deployment that has run the backfill but not the column
    move — that is a real, expected state, not an error state.

Boundaries

  • ⛔ Do not edit docs/adr/** (the ruling is not in question) or
    content/docs/releases/**.
  • ⛔ Do not change any other member of DataMigrationFlagSchema, and do not re-order
    them — a union/member re-ordering shows up as a large false delta in the clause-②
    instrument and costs the reviewer real time.
  • packages/spec is published: this is not a skip-changeset diff. ⚠️ Measure it, do not
    assume.

Provenance

Ruling on #15989: #15989 (comment)

Part-of #15989. Blocks the ADR-0104 driver arm-1 work.


Generated by Claude Code

Activity

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

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions