# Robot software release record

**Version 0.1 — 14 November 2026**
Published by Embodied Software Labs (Synthari AI LLC).
Licensed [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/). Use it, change it,
publish your filled-in copy. No attribution is required in the filled-in document itself.

---

## Read this first

**One record per release, filled in as you go.** A release record written afterwards is a
report. Written as it happens, it is the thing that lets somebody roll back at two in the
morning without guessing.

**This is not a safety assessment and it does not make a release safe.** It records what
was validated, by whom, and what the plan is if it goes wrong. Whether the change is safe
to make at all is determined by a competent assessor for your specific application, and
that assessment governs regardless of anything written here.

**No automatic motion is prescribed anywhere in this document.** Nothing here tells a
robot to move, re-home, resume or recover on its own. Every step that produces motion is
a step a person initiates, because a recovery sequence that runs unattended is a design
decision for your assessor and not a default.

**Rollback is not guaranteed.** Reverting software does not revert firmware, calibration,
a changed fixture, or a robot that is now holding something. Section 4 asks you to write
down what rollback actually restores on your machine, which is often less than people
assume. See the note at the end of that section.

**Three rules while filling it in:**

1. **A version is a number plus where it came from.** "The latest build" is not a
   version. A tag, a commit and a build artefact identifier are.
2. **Record what you did not test.** It is the first thing you will want when something
   fails in a way nobody predicted.
3. **Name a person for each approval.** A role is not a person, and at two in the morning
   a role cannot be telephoned.

---

## 0. The change

| Field | Answer |
| --- | --- |
| 0.1 Release identifier | |
| 0.2 Date raised | |
| 0.3 Raised by | |
| 0.4 What is changing, in one sentence | |
| 0.5 Why now | |
| 0.6 Is this a fix, a feature, a dependency bump or a configuration change? | |
| 0.7 Is it reversible? *(see 4.6 before answering)* | |
| 0.8 Which robots and which sites does it reach? | |
| 0.9 Does it change anything a person can observe from outside the cell? | |

**0.10 — Change class.** Pick one. The class decides how much of the rest applies.

| Class | Meaning | Minimum path |
| --- | --- | --- |
| `config` | A parameter or tuning value, no new code. | 1, 2, 4, 5, 6 |
| `patch` | Backward-compatible fix, no interface change. | all |
| `minor` | New behaviour, existing interfaces unchanged. | all |
| `major` | An interface or behaviour change callers must adapt to. | all, plus a re-assessment trigger in 2.6 |
| `dependency` | An upstream version moves. | all, and 1.6 in full |
| `firmware` | Anything below your software. | all, and **see 4.6 — this is usually not reversible by you** |

---

## 1. The validated configuration

What is running now, and what will be running after. Fill both columns; the diff is the
release.

| Component | Now | After | How identified |
| --- | --- | --- | --- |
| 1.1 Capability / application version | | | tag + commit |
| 1.2 Build artefact | | | image digest or package version |
| 1.3 Middleware distribution | | | name and version |
| 1.4 Middleware packages that matter | | | package + exact version |
| 1.5 Robot controller firmware | | | vendor version string |
| 1.6 Every dependency that moved | | | lockfile diff |
| 1.7 Sensor firmware and drivers | | | make, model, version |
| 1.8 Operating system and kernel | | | |
| 1.9 Calibration set in force | | | identifier + date performed |
| 1.10 Parameter and configuration files | | | commit |
| 1.11 Model weights, if any | | | identifier + hash |

> **1.3 and 1.4 are a pair, and the pairing is the point.** A package name is not a
> version. The same package carries a different version on every distribution — on one
> day in November 2026 the ROS 2 `hardware_interface` package was at 2.54.4 on Humble,
> 4.50.0 on Jazzy and 5.20.0 on Kilted. "We run hardware_interface" says nothing. Record
> the distribution and the package version together or neither is useful.

**1.12 — Distribution support window.** The one field people only fill in once.

| Field | Answer |
| --- | --- |
| Which distribution? | |
| When does its support window end? | |
| Is that date inside the expected life of this deployment? | |
| If not, what is the plan, and who owns it? | |

> ROS 2 publishes a new distribution every twelve months, alternating long-term and
> short-term support. An LTS release is supported for about five years; a non-LTS release
> for roughly eighteen months. Those windows are published in advance, so a robot running
> on a short-support distribution has a known expiry date from the day it is commissioned
> — and it is usually nobody's job to notice. Check the current dates against the primary
> record rather than this document; they are the kind of fact that moves.

**1.13 — What the version number means here.** Semantic versioning requires a declared
public API before a version number carries any meaning at all, and major version zero
means anything may change at any time.

| Field | Answer |
| --- | --- |
| Is there a declared public interface for this capability? Where? | |
| Does the physical envelope form part of it? *(it should)* | |
| Is this capability at 0.x? If so, does everyone consuming it know that? | |

> A version number is a promise about an interface. On a robot the interface includes the
> operating envelope and the refusal behaviour, not only the message types — so a change
> that narrows what the robot will accept is a breaking change even if no code signature
> moved. If nobody wrote the envelope down, no version number can describe a change to it.

---

## 2. Approvals and preconditions

| # | Precondition | Met? | Evidence | Who confirmed | Date |
| --- | --- | --- | --- | --- | --- |
| 2.1 | The current configuration is recorded and recoverable | | | | |
| 2.2 | The change is in version control, tagged | | | | |
| 2.3 | Tests that exist have been run, and the result is attached | | | | |
| 2.4 | The rollback plan is written and someone has read it | | | | |
| 2.5 | Operators who will see new behaviour have been told | | | | |
| 2.6 | A re-assessment trigger has been checked *(see below)* | | | | |
| 2.7 | A maintenance window is agreed | | | | |
| 2.8 | The support owner knows this is happening | | | | |

**2.6 — Re-assessment triggers.** Tick anything this release touches. **Any tick is a
question for whoever owns the risk assessment, before deployment, not after.**

- [ ] Operating envelope — speed, force, reach, payload, keep-out zones
- [ ] Refusal behaviour, or the conditions that cause a refusal
- [ ] What happens on loss of a sensor, the network, the caller or power
- [ ] Stop behaviour, stop category, or how the system resumes afterwards
- [ ] Anything a safety function depends on
- [ ] Anything that changes where people can be while it runs
- [ ] Calibration, frames, or the tool centre point
- [ ] Nothing above

> This document does not tell you what re-assessment is required. It tells you to ask,
> and it records the answer so that the next person can see the question was put.

**2.9 — Approvals.** Names, not roles.

| Approval | Name | Date | Signature / reference |
| --- | --- | --- | --- |
| Engineering | | | |
| Operations | | | |
| Safety ownership *(if any box in 2.6 is ticked)* | | | |

---

## 3. Staged validation

The order matters, and so does recording what each stage did **not** cover.

**3.1 — Simulation.**

| Field | Answer |
| --- | --- |
| What was run | |
| What the simulation does not model that matters here | |
| Result | |
| Who ran it, when | |

**3.2 — Bench or off-line hardware.**

| Field | Answer |
| --- | --- |
| On what hardware — is it the same revision as the fleet? | |
| What was exercised | |
| Worst observed timing | |
| Result | |
| Who ran it, when | |

**3.3 — One robot, out of production.**

| Field | Answer |
| --- | --- |
| Which robot, which site | |
| How many cycles, over how long | |
| Deliberate out-of-envelope trials — did it refuse cleanly? | |
| Interventions required, and of what kind | |
| Result | |
| Who ran it, when | |

**3.4 — What was not tested at all.**

> Free text, and the honest answer is usually longer than the tested list. Shift
> patterns not covered, product variants not tried, failure modes not induced,
> robots at other revisions, the night shift, the cold start on Monday.

**3.5 — Stage exit.** The release does not advance until each row is `yes` or has a named
person accepting the gap.

| Gate | Yes / accepted by |
| --- | --- |
| Simulation passed, and its limits are recorded | |
| Hardware check passed on representative hardware | |
| One robot ran the change out of production without an unexplained failure | |
| Nothing in 3.4 blocks proceeding, in the judgement of a named person | |

---

## 4. Deployment and rollback

**4.1 — The plan.**

| Field | Answer |
| --- | --- |
| Order — which robots, in what sequence | |
| How long between each, and what is watched in between | |
| Who is physically present | |
| Is the cell empty of people during the change? | |
| How the robot is brought to a known state first | |
| Who initiates each step *(a person, in every case)* | |
| Communication channel during the window | |

**4.2 — The abort condition.** Write this before you start, when nobody is invested.

| Field | Answer |
| --- | --- |
| What we will see that means stop | |
| Who may call it | |
| How long we watch before accepting the release | |

**4.3 — The rollback procedure.** Numbered steps, each one somebody can follow cold.

| # | Step | Who | Expected result |
| --- | --- | --- | --- |
| 1 | | | |
| 2 | | | |
| 3 | | | |
| 4 | | | |

**4.4 — Rollback rehearsal.**

| Field | Answer |
| --- | --- |
| Has this rollback been performed, not just written? | |
| On what, by whom, when? | |
| How long did it take? | |
| What did it turn out not to restore? | |

> An untested rollback is a hope. **4.4 is the single most skipped field in this
> document** and the one that decides whether the plan is worth anything.

**4.5 — What rollback restores.** Tick only what reverting the software actually reverts
on *your* machine.

- [ ] Application and capability code
- [ ] Configuration and parameters
- [ ] Model weights
- [ ] Middleware package versions
- [ ] Controller firmware
- [ ] Calibration
- [ ] Any state written to the robot during the release
- [ ] The physical position and attachment state of the robot

**4.6 — What it does not.** Anything unticked above, written out plainly.

> **This is where the honest answer usually lives.** Reverting a software package does
> not revert firmware a vendor flashed, a calibration that was redone, a fixture that was
> moved, or a robot that is now holding a load it picked up under the new version. On
> many controllers a firmware step is not reversible by the operator at all. Rollback is
> also not instantaneous: it takes the time it takes, and on a machine that holds a load
> or maintains balance the sequence matters.
>
> Write what is true for your machine here rather than assuming. If the answer is "we do
> not know", that is the answer, and it is a finding.

---

## 5. Operator and support handover

| Field | Answer |
| --- | --- |
| 5.1 What changes that an operator will notice | |
| 5.2 What they should do differently, if anything | |
| 5.3 What a new behaviour looks like versus a fault | |
| 5.4 Who they call, and on what number | |
| 5.5 How a problem gets reported, and to where | |
| 5.6 Has the briefing happened, or only been written? | |
| 5.7 Who briefed the shift that was not on duty? | |
| 5.8 Is the documentation updated, or only the software? | |

> 5.3 is the one that prevents false alarms and missed real ones. If a capability now
> refuses in a situation where it used to try, an operator who has not been told will
> report a broken robot &mdash; and the next time it refuses for a real reason, nobody
> will look.

---

## 6. Monitoring and closing the record

**6.1 — What is watched after deployment, and for how long.**

| Signal | Baseline before | Watched until | Who watches | Observed |
| --- | --- | --- | --- | --- |
| Task completion | | | | |
| Interventions | | | | |
| Clean refusals | | | | |
| Worst cycle time | | | | |
| Unplanned stoppages | | | | |
| Operator reports | | | | |

> The *baseline before* column is why this is filled in before deployment rather than
> after. Without it, "it seems fine" is the only available verdict.

**6.2 — Closing.**

| Field | Answer |
| --- | --- |
| Outcome — accepted, accepted with conditions, rolled back | |
| Date closed | |
| Closed by | |
| Was the rollback used? If so, what happened? | |
| What would be done differently next time | |
| Does the compatibility matrix need updating? | |
| Does the capability specification's status drop back to *declared*? | |

> That last question is the one with teeth. A capability whose specification says
> *tested* is making a claim about a configuration. Change the configuration without
> re-testing and the claim is no longer true, so the status drops back until somebody
> re-tests. A specification that stays at *tested* through a firmware upgrade nobody
> re-validated is actively misleading.

**6.3 — Unresolved, carried forward.**

| # | Issue | Owner | Must be resolved before… |
| --- | --- | --- | --- |
| 1 | | | |
| 2 | | | |

---

## Appendix A — Release states

The state a release is in, and what moves it. **Nothing in this appendix advances on its
own**; every transition is a person deciding, and every transition is recorded above.

| State | Means | Leaves it by |
| --- | --- | --- |
| **Candidate** | Exists, builds, is tagged. Nothing has been checked. | Review. |
| **Reviewed** | A person other than the author has read the change and the record. | Staging, or back to candidate. |
| **Staged** | Section 3 is complete, including what was not tested. | Approval, or back to candidate. |
| **Approved** | Section 2.9 is signed. A window is agreed. | Deployment. |
| **In service** | Deployed and inside its watch period. | Closing, or rollback. |
| **Rolled back** | The abort condition was met and 4.3 was executed. | Back to candidate, with 6.2 filled in. |
| **Withdrawn** | Abandoned before deployment. | Nothing. It stops here. |

Failure at any gate returns the release to **candidate**. It does not sit in the state it
failed in, because a release that is "staged but failing" is the one somebody deploys by
accident on the following shift.

---

## Appendix B — A worked release (HYPOTHETICAL)

**This example is entirely fictional.** The organisation does not exist, the release never
happened, no robot ran any of it, and every value was invented to show what a filled-in
record looks like. **None of it is field evidence and none of it should be cited.**

### 0. The change

| Field | Answer |
| --- | --- |
| 0.1 | `REL-2026-014` |
| 0.4 | Tighten the tote-presence check so the capability refuses when the tote is more than 40 mm off the marked position, instead of attempting the pick. |
| 0.5 | Three attempts in two weeks picked at a tote that had been nudged, and one dropped it. |
| 0.6 | A behaviour change. |
| 0.8 | One robot, one site. |
| 0.10 | **`minor`** — new refusal behaviour, interfaces unchanged. |

### 1. Configuration

| Component | Now | After |
| --- | --- | --- |
| Capability | `v0.4.2` (`a19c7f1`) | `v0.5.0` (`7de4b02`) |
| Middleware distribution | Jazzy | Jazzy — unchanged |
| Controller firmware | unchanged | unchanged |
| Calibration | `CAL-2026-10-02` | unchanged |

**1.12** — Jazzy is a long-term-support distribution and its window runs well past the
expected life of this cell. *Checked against the primary record, not assumed.*

**1.13** — The capability is at `0.x`, and this release is `0.4.2 → 0.5.0` rather than a
patch, **because the envelope narrowed.** No code signature changed; the robot now
declines work it previously attempted. Under the project's own rule that the envelope is
part of the interface, that is a minor bump at minimum. Everyone consuming it has been
told it is pre-1.0.

### 2. Preconditions

All met except 2.5, which was completed the following morning after the night shift was
briefed.

**2.6** — Two boxes ticked: *refusal behaviour* and *the operating envelope*. Raised with
the engineering manager who owns the risk assessment. Her answer, recorded here: the
change narrows what the robot will attempt and adds no new motion, so no re-assessment
was required — **but she wanted that in writing, which is the point of the field.**

### 3. Validation

| Stage | Result |
| --- | --- |
| Simulation | 500 synthetic offsets; refused correctly at every offset over 40 mm. **Does not model** tote deformation or the morning daylight on the east side. |
| Bench | Same robot revision. 40 cycles, 10 deliberately off-position. Refused 10 of 10. |
| One robot, out of production | 180 cycles over two days, both shifts. 6 refusals, all correct. 2 interventions, both re-presenting a tote after a correct refusal. |

**3.4 What was not tested** — the deformable polybag variant, the cold start on Monday,
and any robot at the older controller revision. Two of three accepted by the engineering
lead; the polybag variant was out of scope because this capability does not handle it.

### 4. Deployment and rollback

| Field | Answer |
| --- | --- |
| 4.1 | One robot. Line stopped, cell cleared of people, robot brought to its home pose by an operator, software replaced, operator restarts the capability. |
| 4.2 | **Abort if** any refusal happens with a correctly positioned tote, or any attempt happens with a tote over 40 mm off. The line engineer may call it. Watch 50 cycles before accepting. |
| 4.4 | **Rehearsed.** Rolled back on the bench on 11 November, took 6 minutes, restored the capability and its parameters cleanly. |
| 4.5 | Restores: application code, configuration, parameters. |
| 4.6 | **Does not restore:** anything about firmware or calibration, neither of which this release touches — and not the physical state. If the robot is holding a tote when the abort is called, an operator takes it before anything is reverted. That step is in 4.3 as step 1, deliberately, because it was forgotten during the rehearsal. |

### 6. Close

Accepted. 50 cycles watched, 2 correct refusals, no incorrect attempts, interventions
within baseline. Rollback not used.

**Carried forward:** the older controller revision on the second robot was never tested
against this change, so the second robot is **not** on this version and the compatibility
matrix now records that explicitly rather than by omission.

**The capability specification status** dropped from *tested* to *declared* at the moment
the change was staged, and returned to *tested* only when the 50-cycle watch closed.

---

## Change log

| Version | Date | Change |
| --- | --- | --- |
| 0.1 | 14 November 2026 | First publication. |

## Review status

This document has **not been reviewed by a qualified robotics professional** and is not a
safety assessment. The interaction between software rollback, firmware, calibration and
the physical state of a machine is the part most in need of review by someone qualified,
and section 4.6 is written as questions for that reason. Corrections are welcome at
`support@embodiedsoftwarelabs.com`.

## References

- REP 2000, ROS 2 releases and target platforms — <https://reps.openrobotics.org/rep-2000/>
- Semantic Versioning 2.0.0 — <https://semver.org/>
- `hardware_interface` package summary, for the per-distribution versions —
  <https://index.ros.org/p/hardware_interface/>
- CC BY 4.0 — <https://creativecommons.org/licenses/by/4.0/>
