Repository navigation
feat(migrate): ote-migrate, for the version bump a sed gets wrong - #112
Merged
Merged
Conversation
Closes the last open part of #97, and the last package checkbox on #101. What it does to the JSON is one field. Every published OTE release has been additive — 0.1→0.4 added optional fields, 0.5 added six, 0.6 changed no schema at all — so no valid document has ever needed a structural rewrite to move up. Verified rather than assumed: the output is validated against the target version before it is returned, so a future release that breaks the pattern fails here instead of shipping bad feeds. The reason it is a package and not `sed -i s/0.4.0/0.6.0/` is D032. Before 0.5 a part of a multi-part event carried its own complete `offers`; there was no way to say "this workshop costs 60 on top of the conference ticket". From 0.5 there is — `partOf.offers` plus `scope: "add-on"` — and the old document stays **valid** either way, because an offer with no `scope` reads as `admission`. So a workshop that really costs 240 + 60 goes on publishing, validly and machine-readably, that it costs 60. Nothing can detect that: whether the number is the whole price or an extra is a fact about the event, not about the JSON. `ote-migrate` names the events and asks; it never rewrites pricing, per the repo-wide rule that connectors do not invent data. On the spec's own multipart example it raises all three questions. Two things worth flagging, both decided here rather than in the issue: **Scope is every published version, not just 0.4→0.6.** The tracker scoped this 0.4→0.6, but the adopter it flags as the live problem — corunajug.org — is on 0.3, which left the support window when 0.5 and 0.6 published the same day. Checked empirically: that feed and a 0.1 feed both become valid 0.6 by changing `specVersion` alone, so the wider range cost nothing and is the only version of this tool that helps the person who most needs it. **It validates against the declared version directly, not through `validateDocument`.** `validateDocument` applies the support policy, which calls an out-of-window version an error — so routing through it would refuse exactly the documents that have to be migrated. `loadValidators` is exported for this. Refuses rather than guessing: a missing or never-published `specVersion`, an unpublished target, a downgrade (dropping fields a newer version added is silent data loss), and input already invalid at the version it claims — migrating that produces an invalid document wearing a newer label. Warnings never change the exit code. They are decisions, not faults. Fixtures are derived from the spec's own 0.6 examples with the 0.5 fields removed, so the "0.4 document" is one the 0.4 schemas actually accept rather than one invented by hand. 27 tests; `pnpm lint`, `build`, `typecheck` and `test` green across the workspace. Note for release: `pnpm publish -r` picks the package up by itself, but npm trusted publishing cannot be configured for a package that does not exist yet. The first release has to be published by hand, then the trusted publisher added in its npm settings — as publish.yml already warns. Co-Authored-By: Claude Opus 5 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes the last open part of #97, and the last package checkbox on #101.
What it actually does, and why that needs a package
It rewrites
specVersion. That is the whole JSON change — every published OTE release has been additive, so no valid document has ever needed a structural rewrite to move up. That is verified rather than assumed: the output is validated against the target version before it is returned, so a future release that breaks the pattern fails loudly here instead of shipping bad feeds.The reason it is not
sed -i s/0.4.0/0.6.0/is D032.Before 0.5 a part of a multi-part event carried its own complete
offers; there was no way to say "this workshop costs 60 on top of the conference ticket". From 0.5 there is —partOf.offersplus"scope": "add-on". The trap is that the old document stays valid: an offer with noscopeis read asadmission, a complete way to attend that part. So a workshop that really costs 240 + 60 goes on publishing, validly and machine-readably, that it costs 60.Nothing can detect that automatically — whether the number is the whole price or an extra is a fact about the event, not about the JSON. So
ote-migratenames the events and asks. It never rewrites pricing, per the repo-wide rule that connectors do not invent data. On the spec's own multipart example it raises all three questions:Warnings never change the exit code. They are decisions, not faults.
Two decisions made here rather than in the issue
Scope is every published version, not just 0.4→0.6. #101 scopes this 0.4→0.6, but the adopter it flags as the live problem —
corunajug.org— is on 0.3, which left the support window when 0.5 and 0.6 published the same day. Checked empirically: that feed and a 0.1 feed both become valid 0.6 by changingspecVersionalone, so the wider range cost nothing and is the only version of this tool that helps the person who most needs to run it. Easy to narrow if you'd rather.It validates against the declared version directly, not through
validateDocument.validateDocumentapplies the support policy, which calls an out-of-window version an error — so routing through it would refuse exactly the documents that have to be migrated.loadValidatorsis exported for this. Before/after on the 0.3 fixture:Refuses rather than guessing
A missing or never-published
specVersion; an unpublished target; a downgrade (dropping fields a newer version added is silent data loss); and input already invalid at the version it claims — migrating that produces an invalid document wearing a newer label, and a later reader cannot tell the damage came from here.Spec version
No spec-version change. The repo stays on OTE Spec 0.6.0; this package spans 0.1.0 → 0.6.0, which is why its own version is
0.1.0rather than tracking the spec minor like the exporters do.Testing
27 tests (
migrate.test.ts,cli.test.ts).pnpm lint,build,typecheckandtestgreen across the workspace.Fixtures are derived from the spec's own 0.6 examples with the 0.5 fields removed, so the "0.4 document" is one the 0.4 schemas actually accept rather than one invented by hand.
Before merging — release note
pnpm publish -rpicks the package up by itself, but npm trusted publishing cannot be configured for a package that does not exist yet. The first release has to be published by hand, then the trusted publisher added in its npm settings — aspublish.ymlalready warns. A missed OIDC config surfaces as a confusing 404.🤖 Generated with Claude Code