feat(cd): add migration subject and events - #322
Open
sol-duara wants to merge 1 commit into
Open
Conversation
A migration is a versioned change applied to a stateful resource - a database schema, the data it holds, or a configuration store. What distinguishes it from other versioned work is that undoing it may not be possible. For a service, recovery is a deployment of an earlier artifact: another forward action, always available. For stored state it may not be, since dropped columns and deleted rows do not come back by running the same step again. A consumer that automates recovery, or that decides whether to page a human, needs to know which case it is at the moment the event arrives, and that cannot be inferred from a versioned run in general nor from the tool that emitted it. reversible declares that per occurrence. When absent, reversibility is undeclared and consumers MUST NOT read the absence as true. Three predicates: queued, started, finished. A reversal, where possible, is itself a later migration carrying the earlier version in toVersion, so no reverted predicate is defined. A migration that finds nothing to apply emits nothing, keeping the subject an occurrence model. toVersion is required and fromVersion is optional: a producer always knows the version it applied, but frequently does not know the version it overwrote without querying prior state. The change object is reused from the existing change subject. Event versions start at 0.1.0-draft. Signed-off-by: Dadisi Sanyika <dadisi@solduara.com>
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.
Changes
Adds a
migrationsubject to the Continuous Deployment vocabulary, withqueued,startedandfinishedpredicates.A
migrationis a run-to-completion, versioned change applied to a stateful resource — a database schema, the data it holds, or a configuration store.Why a new subject
This came from a DataOps request: a GitOps-governed database schema change, where the operator needed to know from the event stream whether what had just landed could be undone.
Nothing in the current vocabulary answers that. For stateless work, recovery is a redeploy of a prior revision — another forward action that needs no declaration, because the option always exists. For persistent state it may not: dropped columns and deleted rows do not come back by re-running anything. A consumer that automates recovery, or that decides whether to page a human, needs to know which case it is at the moment the event arrives.
That property is routing-relevant rather than payload, which is the bar for a distinct subject. It cannot be inferred from a versioned run in general, and it cannot be inferred from the tool that emitted it.
reversibleis the field the subject exists to carryIt is tri-state by design:
false— no clean reversal exists; recovery must be a new forward migration.true— a clean reversal exists.reversiblemeanstrue.Producers that can determine reversibility — tools that keep an explicit undo or rollback script alongside each change — SHOULD declare it. The schema does not make it required, because a producer that cannot determine it should not be forced to guess.
Scope
migrationis scoped to stateful, persistent resources: the class where recoverability is genuinely in question. The broader alternative — any versioned forward step — was considered and not taken, because where recoverability is not in question there is nothing for a consumer to route on, and the subject would then overlap worktaskRunalready describes.Design decisions
targetcarries atypealongsideidandsource, so consumers can route on the kind of resource that was changed, and so target references are shaped consistently across subjects.typeis a free string —database,configStore— rather than a closed enum, so the subject is not coupled to a fixed list of storage kinds.toVersionis required andfromVersionis optional. It was put to us that migration tools often do not expose "from" and "to" in their output, and that an adapter would be unable to fill them. The asymmetry is deliberate and answers that: a producer always knows the version it applied — that is the artifact it carries, and in most tools it is the subject id itself (V12__add_order_status). What a producer frequently does not know is the version it overwrote, which requires querying prior state. RequiringtoVersionasks a producer only for what it has in hand; requiringfromVersionwould turn the event into a pre-processing step.There is no
revertedpredicate. A reversal, where possible, is itself a forwardmigration— a later occurrence withtoVersionset to the earlier version. Whenreversibleisfalse,migration.finishedwithoutcome: successis a non-reversible commitment, so verification belongs before it fires. Applying a change against a temporary database in CI is atestCaseRun, not amigration.A migration that finds nothing to apply emits nothing. No migration occurred, so there is no occurrence to report. This keeps the subject an occurrence model rather than a polling report.
No field describes a partially applied migration. Why a migration stopped where it did is answerable only from the surrounding workflow — the emitting step does not observe its siblings, and cannot report on them. Consumers needing it should read the enclosing workflow's completion.
targetis singular, not an array. A single logical change spanning several stores was considered. One event covering N targets cannot report an outcome for each, and near-atomicity across stores is a claim the vocabulary cannot verify. These remain N occurrences; whether they form one logical unit is a property of the workflow that produced them.No attempt identifier. A retry is a new occurrence with its own identity, and numbering attempts asks a producer to carry correlation state it would have to compute. This is also not specific to
migration; if attempt identity is wanted, it belongs in the context for every subject.changeis reused unchanged from the existingchangesubject. No new common objects are introduced.Out of scope
approvalalready covers accountable authorization decisions that gate execution. A migration gated by an approval is two occurrences.Notes on this change
Event versions start at
0.1.0-draft.schemas/_defs/entries andx-cdevents-semanticsare not included here. The predicate definitions this subject would need (queued,finished) are already being added by #319, and further subjects we are proposing would needcreatedandmodified; adding them here would collide. We will follow up with them once #319 lands.Submitter Checklist
As the author of this PR, please check off the items in this checklist:
0.1.0-draft; the spec version is unchanged