Skip to content

Upgrade every earlier seed starter with upgrade_from baseline lists - #16

Merged
callumalpass merged 2 commits into
mainfrom
feat/seed-upgrade-baselines
Oct 3, 2026
Merged

callumalpass merged 2 commits into
mainfrom
feat/seed-upgrade-baselines

Conversation

@callumalpass

Copy link
Copy Markdown
Contributor

Why

mdbase spec 05A (mdbase-dev/mdbase-spec#59) lets a seed type's upgrade_from be a list of every starter a publisher shipped, and has engines merge an edited seed only against the baseline its lock records as origin_digest. A starter that isn't listed is never upgraded: it is preserved with a reason. The offered packs listed only one earlier starter each, so collections seeded by most earlier TaskNotes packs, and by People 1.1.0, could not be upgraded.

What

  • Authoring: upgrade_from in packs/<id>/<version>.pack.yaml can be one path or a list. scripts/build.mjs emits a list as [{ digest, version, document }], newest first, with version read from each baseline's frontmatter. At build time it rejects baselines on anything but a seed type, an empty list, duplicates, the resource's own document, and a type kind or name that differs from the desired starter. The single form emits exactly as before, so every published provision is byte-identical.
  • New packs (baselines computed from what every earlier pack version shipped at the same target, catalog: false versions included):
    • tasknotes.task 0.3.0-rc.18: rc.17's starter (revision 5); upgrade_from = task revisions 4 (rc.16, v4), 3 (rc.15), 2 (rc.13/rc.14), 1 (rc.12). rc.17 is now hidden.
    • mdbase.contact 1.4.0: Person v3; upgrade_from = Person v2 (1.2.0), v1 (1.1.0). 1.3.0 is now hidden.
    • These need no new version: mdbase.comment 1.0.1 and mdbase.view 1.0.1 already list their only earlier starter. obsidian.base, mdbase.runtime.standard and mdbase.jscontact have no earlier starter at the same target.
  • Invariant (scripts/seed-baselines.test.mjs): for every offered (non-hidden) pack and seed target, upgrade_from covers every starter digest that an earlier version shipped there. It fails on today's rc.17 (missing revisions 2, 3, 4) and contact 1.3.0 (missing Person v1). It also checks every published baseline against the 05A rules.
  • Upgrades through the selected engine (scripts/seed-upgrade.test.mjs): for each pack with a baseline list, it installs each earlier version and then upgrades:
    • unedited: an update to the exact desired bytes with upgrade_baseline = { digest, version } of the installed starter, and lock origin_digest = the desired digest (preserve when the earlier pack already shipped the desired starter);
    • edited (a body line plus a schema property): an update merged against the installed starter's baseline (upgrade_baseline.version = the installed starter's version), with both edits kept and the type otherwise equal to the new starter.
  • Pins: mdbase-ts v0.3.0-rc.9. The CLI is mdbase-connect 4797ba08 (the head of Upgrade seed types from any declared starter baseline mdbase-connect#567, which pins mdbase-rs 056db73), built with mdbase-rs 056db73 (main, #108). The previous Connect pin (62242c21) built against mdbase-rs c456e71, which predates baseline lists.

Changed expectations in existing tests

  • person-pack: the catalog now offers only 1.4.0, and 1.3.0's provision digest joins the byte-identical list. New sequences cover 1.4.0 fresh and after 1.0.0, 1.1.0, 1.2.0 and 1.3.0. 1.1.0 → 1.4.0 changes outcome: a Person type customised under 1.1.0 is no longer kept byte-for-byte. 1.4.0 lists Person v1, so the customisation is merged into v3 (mdbase.person 2.0.0) and the doc line is kept. Earlier packs still keep it unchanged.
  • tasknotes-upgrade: adds rc.18 as a target and a customized-without-origin scenario, which is a customised rc.12 type under a lock without origin_digest, as engines before 05A wrote it. Under the new rules this type is preserved instead of merged. It still requires contract rc.3, so the whole upgrade fails closed with nothing written, the same as the other-reference scenario. The existing scenarios' outcomes are unchanged.
  • tasknotes-plugin-collections: now targets rc.18 and asserts the planned action. These collections have no lock, so a task type equal to a listed starter is updated, and any other type is preserved with "no upgrade baseline applies". Earlier engines merged these types against the single baseline. All fixtures already carry rc.5 types, so the existing assertions still hold.

Verification

  • npm test with mdbase-ts v0.3.0-rc.9 (tag build): 27 + 101 tests pass, and verify installs all 14 packs.
  • MDBASE_VERIFY_CLI=<mdbase-connect 4797ba08 + mdbase-rs 056db73>/target/debug/mdbase npm test: 27 + 101 tests pass, and verify installs all 14 packs with the mdbase CLI.
  • npm run build leaves every existing dist/packs/** provision byte-identical. Only catalog.json and the two new provisions change.

Do not merge until mdbase-dev/mdbase-connect#567 lands, so rust_cli.ref can be repinned to a main commit; the current pin is that PR's head.

callumalpass and others added 2 commits October 3, 2026 09:36
mdbase spec 05A (mdbase-dev/mdbase-spec#59) lets a seed type's upgrade_from
list every starter a publisher shipped, and has engines merge an edited seed
only against the baseline its lock records as origin. A starter that is not
listed is never upgraded, and the offered TaskNotes and People packs each
listed only one of their earlier starters.

- Pack definitions accept upgrade_from as one path or a list. The build emits
  a list as [{ digest, version, document }], newest first, with version from
  each baseline's frontmatter, and rejects non-seed baselines, duplicates, the
  resource's own document, and a different type kind or name. The single form
  emits as before, so published provisions are byte-identical.
- tasknotes.task 0.3.0-rc.18 lists task starters 4, 3, 2 and 1; mdbase.contact
  1.4.0 lists Person starters 2 and 1. rc.17 and 1.3.0 are hidden.
- seed-baselines.test.mjs checks that every offered pack's seed upgrade_from
  covers every starter any earlier version shipped at that target (it fails on
  rc.17 and 1.3.0), and that every published baseline follows 05A.
- seed-upgrade.test.mjs installs each earlier version through the selected
  engine and upgrades it, unedited (exact bytes, origin_digest = desired) and
  customised (merged against its own baseline, edits kept).
- Existing tests cover 1.4.0 and rc.18; an edited task type under a lock with
  no origin is now preserved, which blocks the contract upgrade for review.
- Pin mdbase-ts v0.3.0-rc.9, and the CLI to mdbase-connect 4797ba08 with
  mdbase-rs 056db73.

Co-Authored-By: Claude <noreply@anthropic.com>
mdbase-connect#567 merged; ab936db5 pins mdbase-rs 056db73, matching engine_ref.
@callumalpass
callumalpass merged commit 5c06f15 into main Oct 3, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant