Skip to content

os migrate meta --from 17 — the invocation the spec 17 tombstones prescribe — reports Nothing to migrate for the conversions it is meant to list, because --to defaults to the current major and the conversions are toMajor: 18 #17134

Description

@claude

Found while migrating hotcrm onto the 17.4.0 line (hotcrm#1807, hotcrm PR #1814). Filed unassigned for triage.

What happens

@objectstack/spec@17.4.0's dashboard.refreshInterval tombstone tells the author, verbatim:

Rename the key to refreshIntervalSeconds; the value (seconds) is unchanged. Run os migrate meta --from 17 to list the mechanical edits for existing sources; apply them by hand.

Running exactly that command, on a stack that authors the retired key five times, lists nothing:

$ os migrate meta --from 17
  ✗ dashboards.0.refreshInterval: `dashboard.refreshInterval` was renamed to `refreshIntervalSeconds` … Run `os migrate meta --from 17` to list the mechanical edits …
  … (five of these)
  → Replaying chain: protocol 17 → 17…
  ℹ Chain:  protocol 17 → 17 (this runtime implements protocol 17)

  ✓ Nothing to migrate — the metadata is already canonical for this range.

Exit code 0. The same command with an explicit --to 18 lists all five:

$ os migrate meta --from 17 --to 18
  Applied 5 mechanical change(s):
    • dashboards[0].refreshIntervalSeconds: refreshInterval → refreshIntervalSeconds (dashboard-refresh-interval-to-refresh-interval-seconds)
    … (five)

Why

The conversion is registered with toMajor: 18. --to defaults to this runtime's protocol major, which is 17. So the default range 17→17 excludes the only conversion the tombstone is telling the reader to run the command for. The command is correct about its own range; the tombstone prescribes a range that cannot contain the conversion it belongs to.

Why it matters more than the one flag

The failure is silent and reads as success: ✓ Nothing to migrate — the metadata is already canonical for this range, exit 0, immediately under five refusals naming that exact command. A reader following the tombstone concludes the migration registry has no entry for their key and hand-writes the rename — which is what the ADR-0087 registry exists to stop. In hotcrm#1807 the acceptance criterion was literally "the rename was produced by os migrate meta, ⛔ not hand-written", and the prescribed invocation would have failed it.

This is not the tombstone-wording family already closed (#6914, #10831, #10418) — those are about whether the command exists and whether it rewrites sources. Here the command exists, does the right thing, and is invoked exactly as instructed, and still reports nothing.

Candidate fixes, not a prescription

  1. Have retiredKey() render the command with the range that actually contains the conversion (--from 17 --to 18 for a toMajor: 18 entry), so each tombstone names an invocation that works.
  2. Or, when the requested range yields zero conversions but conversions exist for the authored surfaces just outside it, say so instead of Nothing to migrate — naming the range that would list them.

(1) is the narrower change and fixes every tombstone at once; (2) also catches the reader who typed the range themselves.

Reproduction

Any 17.4.0 stack authoring dashboard.refreshInterval. Measured on @objectstack/cli/17.4.0 linux-x64 node-v22.22.2, runtime 17.0.0 (the protocol major).


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

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions