Solutions and packages
Review semantic changes and adopt a demo execution contract
Inspect the effect of a solution-package change before applying it, then explicitly adopt a compatible State/Action contract in the hot-rolling simulator. This is an opt-in, bounded workflow with separate registry and runtime confirmations.
Worked example
Example: review a maintenance transition
A package maintainer prepares a newer package artifact that changes the destination of an explicit Action in an existing State model. The operator reviews known consumers before applying the registry change. An instance owner then provisions the exported contract, and an operator separately adopts it in the simulator. Updating a binary alone performs none of these steps.
Defines permitted simulator states and transitions. This is separate from a live MQTT observation or an asset location.
Pins the exact active and candidate snapshots and rechecks changed dependencies before a bounded transaction.
The demo retains its current state until an explicit allowed Action changes it. Adoption does not reset the state.
Retain the journal, contract files, trusted digests and pending requests across restarts.
Procedure
Follow the task in order
- 1Prepare compatible versions and an authorized operatorUse a separate clean local Runtime for this worked example, with two authorized administrators for independent profile review. Begin with Hot rolling example — start. Do this before installing Archiver/API or unrelated integrations: opaque API contracts and unresolved Catalog bindings correctly block executable changes. Install the official MQTT and OPC UA bridge add-ons with their development Podman configurations and no external connections, so authenticated inspection can verify empty configurations; a missing route is not proof that no mappings exist. This is a bounded simulator exercise, not permission to ignore consumers in an existing installation.
- 2Use the concrete versioned exampleThe initial profile hot-rolling-example 1.0.0 pins examples.hot-rolling 1.0.0. A successor must retain the same profile ID and package composition. The 1.1.0 package changes only example.hrm.request-rolling from idle → busy to idle → maintenance. Its State model, idle initial state, maintenance → idle edge and all other packages stay identical. The corrective 1.2.0 retargets idle → busy. The immutable package versions are supplied by Controller 2.2.31 or newer. The profiles below are candidates to review, not automatic installation permits.Same-profile candidate 1.1.0 for Advanced administration
{ "schemaVersion": 1, "kind": "solution-profile", "id": "hot-rolling-example", "version": "1.1.0", "displayName": "Hot rolling example — maintenance review", "description": "Exact reviewed successor of the same optional example profile; does not install or change a running service.", "packages": [ { "id": "examples.hot-rolling", "version": "=1.1.0" } ], "capabilityChoices": [ { "capability": "source.telemetry", "required": false, "suggestedProviders": [ "source.mqtt", "source.opcua", "source.rest" ] } ], "namespaceTemplate": "organization/site/area/line/entity", "pathTerminology": { "assetLabel": "Asset", "assetHelp": "A station, cassette or work roll in this optional fictional example." } }Same-profile candidate 1.2.0 for Advanced administration{ "schemaVersion": 1, "kind": "solution-profile", "id": "hot-rolling-example", "version": "1.2.0", "displayName": "Hot rolling example — return review", "description": "Exact reviewed successor of the same optional example profile; does not install or change a running service.", "packages": [ { "id": "examples.hot-rolling", "version": "=1.2.0" } ], "capabilityChoices": [ { "capability": "source.telemetry", "required": false, "suggestedProviders": [ "source.mqtt", "source.opcua", "source.rest" ] } ], "namespaceTemplate": "organization/site/area/line/entity", "pathTerminology": { "assetLabel": "Asset", "assetHelp": "A station, cassette or work roll in this optional fictional example." } } - 3Review and publish the exact successor profileIn Solutions & packages → Advanced administration → Authoring. Save the 1.1.0 manifest above as a JSON file and use Import JSON draft (or replace an existing draft under Advanced JSON). Choose Validate and resolve, Save draft, Record validation and Submit for review. A different administrator opens Reviews & publications, inspects the unchanged profile ID, version, exact package pin and digest, and records approval. Publish the approved candidate to the local catalog. Publication does not install it. Return to Installed packages → Manage examples.hot-rolling, choose the newly published hot-rolling-example 1.1.0 target and Preview impact. Never substitute a different profile ID to get an executable plan. For 1.2.0, reopen your existing owned draft, replace its manifest under Advanced JSON, save the next revision, record a fresh validation and submit a new independent review. One active draft per owner and profile ID is allowed. Earlier validations, reviews and publications stay retained. Refresh the installed-package page after publication before reviewing the next target. The equivalent protected REST sequence below is available to API operators with normal administrator sessions. Use the independently authorized reviewer for the decision; never share one administrator session between reviewers. These requests publish only to this Controller catalog, not the public add-on catalog.Equivalent protected profile review API sequence
Author session: POST /api/solution-profiles/candidate-drafts { "manifest": <the complete 1.1.0 profile JSON above> } → retain data.draftId and data.revision POST /api/solution-profiles/candidate-drafts/<draftId>/validations { "expectedRevision": <the saved revision> } → retain data.validation.validationId POST /api/solution-profiles/candidate-drafts/<draftId>/reviews { "validationId": "<validationId>", "submissionNote": "Review the exact successor and package pins." } → retain data.reviewId Independent approver session, after inspecting that review: POST /api/solution-profiles/candidate-reviews/<reviewId>/decision { "decision": "approved", "decisionNote": "Independent review completed." } Author session: POST /api/solution-profiles/candidate-reviews/<reviewId>/publication {} For 1.2.0, update the same owned draft before a new validation/review: PUT /api/solution-profiles/candidate-drafts/<draftId> { "expectedRevision": <current revision>, "manifest": <complete 1.2.0 profile JSON> } - 4Inspect changed definitions and known consumersReview field changes, compatibility and references to asset bindings, saved views, dashboards, archive mappings, Triggers/Captures, declared API/Catalog contracts and inspected bridge mappings. Private references are filtered by visibility. Missing, incomplete or truncated inspection is uncertainty. The preview cannot discover every undeclared external consumer; a clean list is not proof that no external integration exists.
- 5Review the plan and understand blocked resultsPrepare and review the migration plan, then acknowledge the review separately. The plan is tied to the operator and exact snapshots. It is rechecked if dependencies change. Bounded execution supports adding new legacy-projected Attribute definitions, changing existing top-level display labels/descriptions without executable changes, or one restricted owned State/Action migration. Unit/type/aggregation conversions, removals and ownership transfers need separate work. Unknown or unadapted consumers and incomplete bridge evidence can block execution; there is no override checkbox that makes them safe.
- 6Confirm one bounded registry executionUse the confirmation for the supported execution class. Applying the reviewed package and recording its receipt happen transactionally. If the plan becomes stale, prepare and inspect a new plan before confirming. If a reply is lost, recover using the same saved operation ID and exact request; do not treat a timeout as failure or invent a second operation. Interruption before commit rolls back. After commit, corrections use a newer reviewed artifact rather than an automatic package downgrade.
- 7Export the exact committed demo contractFor a supported State/Action migration, choose Prepare demo contract export in the committed result, download the JSON, and retain the displayed SHA-256 digest through a trusted operator channel. Export rechecks that the receipt still matches the active definitions. Retain the original operation request if API export will be needed later; there is no browser for historic committed operations. The export contains no credentials, is unsigned and is not an execution permit. A digest copied from an untrusted file is insufficient.
- 8Provision the stopped demo instanceFor the first registry execution apply the reviewed 1.0.0 → 1.1.0 maintenance change and export its committed contract. Install the compatible demo normally through Micro services and choose its development Podman configuration. For this contract-only sandbox omit the optional hrm.productionLine.furnace.identity and hrm.productionLine.rollingStand.mobileCassette sections until the exercise is complete; this avoids registering unresolved identity Catalog offers. Keep the demo stopped, keep its existing simulator journal, and have its instance owner copy that downloaded credential-free JSON into the instance directory. Use a different persistent file for the lifecycle journal. Set hrm.reviewedLifecycle to those absolute paths and the separately recorded displayed digest. File delivery is an explicit local instance operation; there is no automatic registry-to-runtime distribution. The example below uses the ordinary Controller-managed instance layout; replace the container name, exact installed version and instance ID from Micro services before running.Copy the first trusted export while the demo is stopped
CONTROLLER_CONTAINER=<your-local-controller-container> DEMO_INSTANCE_DIR=/usr/src/app/controller-override/rtt-nodes/rtt-demo-app/v6.1.27/instances/<instance-id> podman cp ./reviewed-demo-contract.json "$CONTROLLER_CONTAINER:$DEMO_INSTANCE_DIR/reviewed-demo-contract.json"Optional section inside the existing hrm configuration"reviewedLifecycle": { "contractFile": "/usr/src/app/controller-override/rtt-nodes/rtt-demo-app/v6.1.27/instances/<instance-id>/reviewed-demo-contract.json", "contractDigest": "sha256:<displayed trusted export digest>", "stateFile": "/usr/src/app/controller-override/rtt-nodes/rtt-demo-app/v6.1.27/instances/<instance-id>/reviewed-lifecycle-state.json", "maintenanceState": "maintenance" } - 9Prepare the demo namespace before its first startOpen Hot rolling demo → Setup and data journey. Under Prepare the namespace, choose Review preparation and inspect the four proposed topics: forge-group, system, forge-group/novasteel and forge-group/novasteel/hot-rolling. Choose Prepare; existing topics are reused. Select Check progress and verify that namespace preparation is Ready before starting the demo instance. Installing the schema profile installs definitions, not these concrete namespace topics. If a first start reports publication paused, check this preparation as well as the displayed service-access and MQTT diagnostics; preserve the instance journal and let retained publications retry after the cause is corrected. This namespace preparation does not approve an external identity source or attach individual Asset identities.
- 10Exercise maintenance, then prepare the corrective successorStart the same demo normally. Status and Execution contract must show accepted example version 1.1.0, ready and idle. To demonstrate the hold, use the registered POST reviewed-lifecycle-action with the single actionKey example.hrm.request-rolling and fresh executor/revision/accepted-digest pins from GET status; save its operation ID before sending. The first action enters maintenance. Do not press the same action again yet, because its explicit maintenance → idle edge would leave the hold. In the package dialog review/apply 1.1.0 → 1.2.0 through the same impact/plan/confirmation procedure and export that new current contract. When upgrading a pre-update material journal, first install demo 6.1.27 or newer and restart once with the exact original configuration. This verifies and narrows its old configuration pin while retaining jobs, receipts and queued publications. A previously changed pin must be restored before that restart. Then stop only the same demo, retain both journals and the first export, copy the successor to a distinct file, and update contractFile plus its independently recorded digest. Restart offers 1.2.0 while retaining maintenance. Replacing a file does not itself adopt it.
- 11Review and explicitly adopt the offered successorStart the instance normally and open Hot rolling demo → Execution contract. Inspect the accepted and offered versions, current state and eligibility. The first start without a journal initializes the reviewed model; an existing journal retains its accepted contract and state. A direct successor is offered for adoption. Choose Review adoption to fetch fresh status, inspect it, then select the separate acknowledgement and confirm Adopt reviewed contract. Cancel sends no command. Adoption requires an empty rolling stand and preserves the current state. A separate permitted Action is needed to leave maintenance; this panel does not execute Actions or deliver files.
- 12Recover an unknown response without a duplicate commandThe UI saves the full adoption request in this tab’s session storage before sending. If storage fails, it sends nothing. A lost, rejected or uncertain reply keeps the same request and blocks a fresh adoption. Use Check saved result or Retry identical operation. Reload checks the saved result without automatically posting again. A restarted healthy original executor can resolve durable journal state. Keep the tab’s recovery data: no cross-device history picker exists. An unavailable or different journal cannot confirm the original outcome.
- 13Close an unresolved attempt only through its original journalIf the healthy original executor permits closure, choose Review closing this attempt, inspect fresh status, acknowledge separately and confirm Close reviewed attempt. Closure records a durable negative receipt for the original adoption ID; it does not erase state or revert an applied adoption. If the original already applied, its applied receipt is returned. Once closure was sent, recover its result or retry the identical closure rather than retrying adoption. Only a confirmed terminal result permits a fresh operation ID and review. The old closed adoption stays rejected even if it arrives late after restart.
- 14Preserve evidence during restart and recoveryKeep the accepted/offered bundles, journal and exact pending requests. A corrupt, full, missing-original or uncertain journal must not be reset to bypass a block. The journal is bounded to 256 receipts and 1 MiB and never silently evicts evidence. Diagnose with the instance stopped and retain the original files. Do not run older demo journal readers after writing new receipt fields or closed outcomes; recover with this or a newer compatible reader. Binary update, registry migration, file provisioning and runtime adoption are distinct operations.
Expected result
What you should have
Boundaries
Important boundaries
- The example artifacts require Controller 2.2.31 or newer and are not in Runtime 2.2.30. The material-journal pin correction requires demo 6.1.27 or newer; the original 6.1.26 material journal blocks a changed contract file or digest. The two successor profile manifests use the existing independent candidate-review and publication procedure. They keep the same profile ID; switching to an unrelated profile is not this bounded package upgrade.
- An existing installation with opaque API contracts, unresolved identity offers, unavailable bridges or undeclared consumers can remain blocked. Do not delete registrations or weaken inspection to force this exercise; prepare the example in its separate clean sandbox and review a real rollout separately.
- The runtime provides restricted migrations and an opt-in simulator executor, not automatic delivery, fleet coordination, arbitrary consumer adaptation or distributed rollback.
- The single-writer journal protects one canonical local path on one host. Do not share or copy the same active journal across hosts; it is not an NFS or fleet lock.
- The reviewed lifecycle has a separate journal. Demo 6.1.24+ also retains its simulator jobs and publication queue in its own journal; neither journal proves end-to-end MQTT delivery.
- Local acceptance covers registered service discovery, proxy/JWKS authentication, allowed and denied paths, lost responses, process interruption and restart. It does not certify host power loss, physical-device safety or complete external-consumer discovery.
- A required component version does not prove that every published Runtime image already contains it. Check the version of the Runtime you install before following these steps.
- Controller source releases and Runtime image/artifact publication are separate. Before starting, verify that the Runtime you download actually contains Controller 2.2.31 or newer; a component release alone does not establish that availability.
FAQ
Common questions
Why is the plan blocked?
Read its dependency or unsupported-change reason. No change needs no apply. Incomplete runtime inspection or an unadapted consumer requires evidence or adaptation before a fresh review; repeated confirmation cannot remove that uncertainty.
Does adoption change the current state?
No. It changes the accepted rules while retaining the current state. A separate allowed Action changes state, with its own operation ID and permission.
Can I clear browser storage and start again?
Do not clear recovery data to bypass an unknown result. Keep the original ID and request, recover its durable result, or use acknowledged closure on the original healthy executor. Losing the tab’s data needs an operator-assisted recovery using retained evidence.
Can the new contract be adopted automatically after restart?
No. Restart loads the configured offered file, validates its trusted pin and reads the accepted journal. A successor still needs explicit review and adoption.
This versioned public guide is maintained with the UNS OpenHub website and linked directly from the controller where the task applies.