This recipe adds a required fulfillment state to an order while preserving one current contract line and planning the stored-data transition explicitly.
The .one and command examples below are illustrative end-product syntax.
1. Propose the semantic change
semantic parcelhub.orders
domain one.contracts@1
struct Order@1
id: OrderId
customer_id: CustomerId
status: OrderStatus
fulfillment: FulfillmentState
Because existing stored values lack fulfillment, checking cannot invent a
default silently.
2. Inspect impact before changing data
$ one check --impact
changed parcelhub.orders#Order@1
affected roots OrdersApi, OrdersWeb, FulfillmentWorker
affected state parcelhub.order_state#Orders@1
required transition parcelhub.migrations#AddFulfillment@13. Declare one explicit transition
semantic parcelhub.migrations
domain one.data@1
migration AddFulfillment@1
state parcelhub.order_state#Orders@1
from revision:sha256:old…
to revision:sha256:new…
transform order
fulfillment from status.to_fulfillment()
verify every_order_has_fulfillment
reversible within 7d
This is a current transition, not a compatibility reader or permanent old/new model.
4. Plan coexistence and cutover
one plan --root OrdersRelease
one inspect plan:sha256:… --subject migrationexpand storage -> deploy dual-capable readers -> migrate -> verify
-> switch writers -> retire superseded representationEach transition has its own authority, artifact, checkpoint, observation, rollback window, and removal condition.
5. Verify the accepted state
one test --root OrdersRelease --scenario old-data-to-current-contract
one apply plan:revision:sha256:…
one inspect migration:operation:sha256:…Once every caller and stored value uses the current contract, the retired material is removed rather than retained as a parallel lane.
See change and evolution.