Skip to content

Upgrading

Upgrading Engineering Runtime is replacing one file. There is no migration step, no database, no daemon to restart.

# same download + verify flow as a fresh install, then:
sudo install -m 0755 engineering-runtime-$VERSION-linux-$ARCH/runtime /usr/local/bin/runtime
runtime version
runtime bootstrap

See Installation for the per-platform download commands.

What changes and what survives

The next command you run after replacing the binary refreshes the Runtime Home automatically.

Path On upgrade
specs/, commands/ Replaced. Files the new version no longer ships are deleted
version Updated to the new binary's version
config.yaml Never touched
policy-config.yaml Never touched
context.yaml Never touched
capabilities directory Existing files never touched; newly shipped examples appear
logs/, cache/ Untouched

Your policy edits, your context definitions and your capabilities survive every upgrade. That is the guarantee the ownership split exists to provide.

The first command consumes the refresh

Bootstrap runs before every command. If you run runtime version first, a subsequent runtime bootstrap prints no refresh line — the refresh already happened. That is success, not failure.

The upgrade trap worth knowing

New policy defaults do not reach existing installs.

policy-config.yaml is user-owned, so a release that adds allowed_binaries entries or new deny rules changes nothing for anyone who already has the file. This has bitten real installs: a machine sat at 6 allowed binaries while the release shipped 21, and runtime command run helm was denied for what looked like no reason at all.

This is a deliberate trade — never clobbering your policy is worth more than auto-delivering defaults — but you have to know about it.

Diagnose it

runtime config validate lists the binaries the active policy allows:

runtime config validate

See what a release added

Bootstrap a throwaway home from the new binary and diff:

TMP=$(mktemp -d)
ENGINEERING_RUNTIME_HOME=$TMP runtime bootstrap >/dev/null

diff ~/.engineering-runtime/policy-config.yaml $TMP/policy-config.yaml
diff ~/.engineering-runtime/config.yaml        $TMP/config.yaml
diff ~/.engineering-runtime/context.yaml       $TMP/context.yaml

Then merge in whatever you want by hand. Copying the new file wholesale discards your own rules — diff, don't overwrite.

Do this after every upgrade

Three diff commands take ten seconds and explain a whole class of "why is this suddenly denied" confusion before you hit it.

Verify the upgrade

runtime version
runtime config validate

# a capability that validated before must still validate
runtime capability validate files/notes-roundtrip

Validation resolves every step against the provider surface of the installed binary, so re-validating your capabilities after an upgrade is the fastest way to find an operation that changed or was removed.

If you keep capabilities in a shared directory, validate all of them:

export RUNTIME_CAPABILITIES_DIR=~/work/team-capabilities
for f in $(find "$RUNTIME_CAPABILITIES_DIR" -name '*.md'); do
  runtime capability validate "$f" || echo "FAILED: $f"
done

Downgrading

Downgrading works and is symmetric: specs/ and commands/ refresh back down to what the older binary ships, because the refresh triggers on any version difference, not just a newer one. Your user-owned files are untouched in that direction too.

The one thing to check is capabilities. A capability written against an operation that only exists in the newer binary will fail validation after a downgrade — which is exactly the intended behaviour, caught before execution rather than during it.

Upgrading in CI

Pin a version in the setup action and bump it deliberately:

- uses: kishore-gutta/engineering-runtime-samples/.github/actions/setup-runtime@main
  with:
    runtime_github_token: ${{ secrets.RUNTIME_GITHUB_TOKEN }}
    version: v0.5.2        # empty string installs the latest release

CI jobs build a fresh Runtime Home every run, so the upgrade trap above does not apply there — a new job always gets the release's current defaults. That asymmetry is worth remembering when a pipeline works and a laptop doesn't.

See CI/CD.