| name | bootc |
| version | 1.0 |
| last_updated | 2026-07-20 |
| id | bootc |
| one_line_purpose | Write bootc upgrade, rollback, and migration tests. |
| entry_point | docs/skills/test-authoring/bootc/SKILL.md |
| category | test-authoring |
| mcp_compliance_level | partial |
| status | active |
| dependencies | [] |
| tags | ["bootc","lifecycle","rollback"] |
| description | How to write bootc upgrade, rollback, and migration tests for the testsuite repo. Load when editing bootc-related .feature files or steps. |
| metadata | {"type":"pattern","audience":"agents","maturity":"stable"} |
bootc Lifecycle Testing Reference
Load when: writing or debugging lifecycle, upgrade, or rollback tests.
bootc status JSON schema (v1alpha1)
bootc status --format=json
| Field | Path |
|---|
| Active deployment | .status.booted |
| Pending reboot | .status.staged (null if none) |
| Active image digest | .status.booted.image.imageDigest |
| Active image ref string | .status.booted.image.image.image |
| Pinned (won't auto-prune) | .status.booted.pinned (bool) |
Wrong paths that cause silent test skips:
.staged (missing .status prefix)
.active.imageDigest
.active.image
Always validate the outer structure before accessing:
payload = json.loads(output)
assert isinstance(payload.get("status"), dict), "bootc status JSON malformed"
booted = payload["status"]["booted"]
Bare payload.get("status", {}) silently accepts malformed JSON — don't use it as a guard.
Lifecycle capture pattern
Capture digests at the right moments or verification steps silently skip:
original_digest = get_booted_digest(context)
expected_upgrade_digest = get_staged_digest(context)
Without step 3, the post-reboot assertion has nothing to compare against and silently passes or skips.
ostree admin status parsing