docs(testbed): 51-04 step-2 L0-L5 verification runbooks (host-side, evidence-defined)

Step-2 (plan §2): the L1-L4 live legs authored as host-executed, evidence-defined
runbooks (the 51-09 live-legs pattern; the VM seat has no runtime per the locus ruling).
Each leg = exact commands + real-byte capture + PASS/FAIL verdict-on-bytes (never from
memory) + hashed evidence dir (census-receipt discipline):
- L0 resolve inputs (base-image digest + stub-assets.list census — the two host-resolved slots)
- L1 PTY allocation (docker run -t + tmux capture real bytes + resize propagation)
- L2 tmux server lifecycle (detach-survive, multi-pane, exact send-keys/capture round-trip)
- L3 daemon-in-container (container-local sqlite, healthz on published port, rig up stub
  topology settles — where stub-assets.list is grounded/finalized; zero tokens)
- L4 hermetic fail-closed (foreign OPENRIG_URL hard-refused INSIDE the container; grounding
  note flags the packaged-vs-runner-mode form honestly)
- L5 multi-host (N named self-hosts on one docker network via the host registry, plan §3)
  + the 51-09 live-leg RIDER: executes the shipped collision/alignment RUNBOOK.md (LEG A
  cross-host triple, LEG B founder-collision) against the testbed containers in one session.
Fences carried on every leg: no real-HOME mounts, network-only shared surface, scenarios
byte-unchanged, docker-gap-watch routes to PM.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
v-openrig-buildandClaude Opus 4.8 committed 2026-08-06 05:23:49 +00:00
1 parent 7b6b9f8f19
commit 49a8e6b588
7 files changed
+387

No files matched your search

@@ -0,0 +1,54 @@
# L0 — resolve the host-side build inputs (prerequisite to every build)
**Runs host-side.** Populates the two documented slots the build verb refuses-until-resolved, so the
image is byte-reproducible against a pinned base + a known stub census. Do this once per base/stub
change; commit the resolved slots so the pin is durable.
## L0.1 — resolve the digest-pinned base
The VM seat cannot pull/inspect a registry digest; do it on the host with a runtime present.
```bash
# Pull the intended LTS-slim base, then read its immutable RepoDigest.
docker pull debian:bookworm-slim
BASE_REF="$(docker inspect --format '{{index .RepoDigests 0}}' debian:bookworm-slim)"
echo "${BASE_REF}" # e.g. debian@sha256:<64-hex> (or docker.io/library/debian@sha256:...)
```
Write the single resolved reference into the slot (replacing the comment block):
```bash
printf '%s\n' "${BASE_REF}" > docker/testbed/base-image
# Prove the fence accepts it (readBaseImage returns the digest, or exits non-zero):
node -e 'import("./scripts/testbed-build-inputs.mjs").then(m=>console.log(m.readBaseImage("docker/testbed/base-image")))'
```
**PASS:** `readBaseImage` prints `{ ref, name, digest: 'sha256:<64-hex>' }`. **FAIL:** any non-zero /
"tag-floating" / "unresolved" — the slot is not a valid digest pin; do not proceed to a build.
## L0.2 — finalize the stub-assets census list
The zero-token stub payload (plan §1 layer 4) is the container-local stub `rig.yaml` + its agent
fixture + `culture.md` that L3 boots. Add each repo-relative path, one per line, to
`docker/testbed/stub-assets.list` (comments/blanks ignored). Ground the exact set against L3 (the
`rig up` stub topology it settles) — do not guess; the list IS the census scope the manifest hashes.
```bash
# After populating the list, prove the census resolves over the staged set the build will stage:
node -e 'import("./scripts/testbed-build-inputs.mjs").then(m=>{
const fs=require("fs");
const files=fs.readFileSync("docker/testbed/stub-assets.list","utf8").split("\n").map(s=>s.replace(/#.*/,"").trim()).filter(Boolean);
console.log(m.deriveStubAssetsHash(".", files).receipt);
})'
```
**PASS:** the receipt lists exactly the intended stub assets, each with a 64-hex content digest.
**FAIL:** empty set / a missing file / a path escaping the root — fix the list, never a partial census.
## L0.3 — record evidence
```bash
GIT_SHA="$(git rev-parse HEAD)"; EVID="dist/testbed-image/evidence/${GIT_SHA}"; mkdir -p "${EVID}"
{ echo "docker: $(docker --version)"; echo "base: ${BASE_REF}"; echo "stub-assets.list:"; cat docker/testbed/stub-assets.list; } > "${EVID}/L0-inputs.txt"
echo "VERDICT: PASS — base digest pinned + stub census resolved" >> "${EVID}/L0-inputs.txt"
```
@@ -0,0 +1,47 @@
# L1 — PTY allocation (docker run -t + tmux capture returns real bytes; resize propagates)
**Runs host-side, after L0 + a build.** Proves the image gives a real PTY and that tmux inside it
produces genuine captured bytes — the TUI-spike fixed-viewport pattern, reused. Never assert the
observable from memory; verdict against the captured bytes.
## Setup
```bash
GIT_SHA="$(git rev-parse HEAD)"; IMAGE="openrig-testbed:${GIT_SHA}"; EVID="dist/testbed-image/evidence/${GIT_SHA}"; mkdir -p "${EVID}"
docker image inspect "${IMAGE}" >/dev/null # built by scripts/build-testbed-image.sh (FAIL loudly if absent)
NAME="orig-l1-${GIT_SHA:0:8}"
```
## L1.1 — allocate a PTY + start a tmux session inside
```bash
# -t allocates a PTY; the entrypoint (tini) holds the container. Detached, fixed 80x24 viewport.
docker run -d -t --name "${NAME}" "${IMAGE}"
docker exec "${NAME}" tmux new-session -d -s l1 -x 80 -y 24
docker exec "${NAME}" tmux send-keys -t l1 'printf "PTY-OK:%s\n" "$TERM"; tty' Enter
sleep 1
docker exec "${NAME}" tmux capture-pane -p -t l1 | tee "${EVID}/L1-capture.txt"
```
**PASS:** the capture contains a real `PTY-OK:` line and `tty` prints a real pts device
(`/dev/pts/...`), not "not a tty". **FAIL:** "not a tty" / empty capture.
## L1.2 — resize propagates
```bash
docker exec "${NAME}" tmux resize-window -t l1 -x 120 -y 40
docker exec "${NAME}" tmux display-message -p -t l1 '#{window_width}x#{window_height}' | tee "${EVID}/L1-resize.txt"
```
**PASS:** reports `120x40` (the resize propagated to the in-container tmux). **FAIL:** stays `80x24`.
## Teardown + evidence
```bash
docker rm -f "${NAME}" >/dev/null
{ grep -q 'PTY-OK:' "${EVID}/L1-capture.txt" && grep -q '/dev/pts/' "${EVID}/L1-capture.txt" && grep -q '120x40' "${EVID}/L1-resize.txt" \
&& echo "VERDICT: PASS — PTY allocated, real capture bytes, resize propagated" \
|| echo "VERDICT: FAIL — see L1-capture.txt / L1-resize.txt"; } | tee "${EVID}/L1-verdict.txt"
```
**Fence:** no `-v` HOME/workspace mounts; the container is disposable (fresh HOME).
@@ -0,0 +1,55 @@
# L2 — tmux server lifecycle (detach-survive, multi-pane, send-keys + capture round-trip)
**Runs host-side, after L1.** Proves the tmux server — the substrate the whole product rides —
behaves in-container: sessions survive client detach, multiple panes coexist, and a send-keys →
capture round-trip returns the exact bytes.
## Setup
```bash
GIT_SHA="$(git rev-parse HEAD)"; IMAGE="openrig-testbed:${GIT_SHA}"; EVID="dist/testbed-image/evidence/${GIT_SHA}"; mkdir -p "${EVID}"
NAME="orig-l2-${GIT_SHA:0:8}"; docker run -d -t --name "${NAME}" "${IMAGE}"
```
## L2.1 — server survives detach
```bash
docker exec "${NAME}" tmux new-session -d -s l2 -x 80 -y 24
docker exec "${NAME}" tmux send-keys -t l2 'echo persist-marker-$$ > /tmp/l2.marker' Enter
sleep 1
# A detached session is the default with -d; confirm the server + session still list after a beat.
docker exec "${NAME}" tmux ls | tee "${EVID}/L2-sessions.txt"
docker exec "${NAME}" cat /tmp/l2.marker | tee "${EVID}/L2-marker.txt"
```
**PASS:** `tmux ls` shows `l2` still alive; the marker file exists. **FAIL:** "no server running" / no `l2`.
## L2.2 — multiple panes
```bash
docker exec "${NAME}" tmux split-window -t l2 -h
docker exec "${NAME}" tmux list-panes -t l2 -F '#{pane_index}' | tee "${EVID}/L2-panes.txt"
```
**PASS:** at least two pane indices (`0`,`1`). **FAIL:** one pane / error.
## L2.3 — send-keys + capture round-trip (exact bytes)
```bash
TOKEN="roundtrip-$(date +%s 2>/dev/null || echo fixed)-marker"
docker exec "${NAME}" tmux send-keys -t l2.0 "printf '%s\n' '${TOKEN}'" Enter
sleep 1
docker exec "${NAME}" tmux capture-pane -p -t l2.0 | tee "${EVID}/L2-roundtrip.txt"
```
**PASS:** the capture contains `${TOKEN}` verbatim (the exact bytes round-tripped through the server).
**FAIL:** token absent / garbled.
## Teardown + evidence
```bash
docker rm -f "${NAME}" >/dev/null
{ grep -q 'l2' "${EVID}/L2-sessions.txt" && [ "$(wc -l < "${EVID}/L2-panes.txt")" -ge 2 ] && grep -q "${TOKEN}" "${EVID}/L2-roundtrip.txt" \
&& echo "VERDICT: PASS — server survives detach, multi-pane, exact round-trip" \
|| echo "VERDICT: FAIL — see L2-*.txt"; } | tee "${EVID}/L2-verdict.txt"
```
@@ -0,0 +1,52 @@
# L3 — daemon-in-container (boots vs container-local sqlite; healthz on the published port; `rig up` settles a zero-token stub topology)
**Runs host-side, after L2.** This is the leg that exercises the stub payload — and where
`docker/testbed/stub-assets.list` is finalized (L0.2): the exact stub `rig.yaml` + agent fixture +
`culture.md` this `rig up` settles ARE the census scope. Zero tokens by construction (runtime: stub).
## Setup
```bash
GIT_SHA="$(git rev-parse HEAD)"; IMAGE="openrig-testbed:${GIT_SHA}"; EVID="dist/testbed-image/evidence/${GIT_SHA}"; mkdir -p "${EVID}"
NAME="orig-l3-${GIT_SHA:0:8}"
# Publish the daemon port to an ephemeral host port; container-local HOME/DB only (no mounts).
docker run -d -t --name "${NAME}" -p 127.0.0.1:0:7433 -e OPENRIG_SELF_HOST_ID=testbed-l3 "${IMAGE}"
HOSTPORT="$(docker port "${NAME}" 7433/tcp | head -n1 | sed 's/.*://')"
```
## L3.1 — daemon boots vs a container-local sqlite + healthz answers
```bash
docker exec "${NAME}" bash -lc 'rig daemon start && sleep 2 && rig status || true'
curl -fsS "http://127.0.0.1:${HOSTPORT}/healthz" | tee "${EVID}/L3-healthz.txt"; echo
docker exec "${NAME}" bash -lc 'ls -l "${OPENRIG_HOME:-$HOME/.openrig}"/*.sqlite* 2>/dev/null || find "$HOME" -name "*.sqlite*" 2>/dev/null' | tee "${EVID}/L3-db.txt"
```
**PASS:** `/healthz` returns healthy JSON on the published port; a container-local sqlite exists.
**FAIL:** no healthz / DB outside the container / a mounted real HOME (fence breach).
## L3.2 — `rig up` settles a zero-token stub topology
Ship a minimal `runtime: stub` `rig.yaml` (+ agent fixture + culture.md) as the staged stub assets;
copy it into a container-local workspace and `rig up`.
```bash
docker exec "${NAME}" bash -lc '
set -e
mkdir -p ~/work && cp -r /opt/openrig-testbed/stub-assets/* ~/work/ 2>/dev/null || true
cd ~/work && rig up && sleep 3 && rig ps --json' | tee "${EVID}/L3-topology.txt"
```
**PASS:** the stub seat(s) reach a settled/ready state (zero LLM tokens consumed — `runtime: stub`).
**FAIL:** topology never settles / a non-stub runtime is invoked.
## Teardown + evidence
```bash
docker exec "${NAME}" bash -lc 'rig down || true' ; docker rm -f "${NAME}" >/dev/null
{ grep -qi 'health' "${EVID}/L3-healthz.txt" && echo "VERDICT: PASS — daemon boots vs container-local sqlite, healthz answers, stub topology settles" \
|| echo "VERDICT: FAIL — see L3-*.txt"; } | tee "${EVID}/L3-verdict.txt"
```
**Note:** the exact `rig ps` shape / ready predicate is grounded against the shipped stub adapter at
execution time — do not assert a remembered field name; read the real `--json` output.
@@ -0,0 +1,51 @@
# L4 — the 51-02 hermetic contract holds INSIDE the container (fail-closed not weakened)
**Runs host-side, after L3.** The hermeticity floor is "fresh container = fresh HOME" **by
construction** — no real-HOME/workspace mounts (verified in L1–L3 by the no-`-v` fence). This leg
proves the *active* half: the 51-02 env-helper still **REFUSES an injected foreign `OPENRIG_URL`**
inside the container. The container is not an excuse to weaken the fail-closed guard — a leaked daemon
target must hard-refuse exactly as it does host-side (the `DAEMON_TARGET_ENV_VARS` guard class).
## Claim
With a foreign `OPENRIG_URL` (a daemon target the helper did not set itself) present in the
environment, the 51-02 hermetic env prep **hard-refuses** (non-zero + a refusal naming the foreign
target) rather than silently adopting it — inside the container, same as host-side.
## Grounding note (confirm at execution — do NOT assert from memory)
Where the helper runs depends on whether the 51-02 hermetic-env module is **packaged** in the openrig
tarball the image installs (it currently lives at `packages/daemon/test/helpers/hermetic-env.ts` — a
test helper, which may not be in the pack set):
- **If packaged / resolvable in-container:** invoke the assertion directly in the container (L4.1).
- **If not packaged:** this leg is exercised via the **runner's container-execution mode (step-3)**,
which drives a scenario into the container with the foreign target injected and the helper (host-side
in the runner) refusing — record that as the L4 form and cross-link the step-3 runbook. Either way,
the leg is real; pick the form the shipped surface supports and say which.
## L4.1 — in-container assertion (when the helper is resolvable)
```bash
GIT_SHA="$(git rev-parse HEAD)"; IMAGE="openrig-testbed:${GIT_SHA}"; EVID="dist/testbed-image/evidence/${GIT_SHA}"; mkdir -p "${EVID}"
NAME="orig-l4-${GIT_SHA:0:8}"; docker run -d -t --name "${NAME}" "${IMAGE}"
# Inject a foreign daemon target and drive the hermetic prep; expect a LOUD non-zero refusal.
docker exec -e OPENRIG_URL='http://foreign-daemon.invalid:9999' "${NAME}" bash -lc '
node --input-type=module -e "
import { prepareHermeticEnv } from \"@openrig/daemon/test/helpers/hermetic-env.js\";
try { prepareHermeticEnv({ baseEnv: process.env }); console.log(\"NO-REFUSAL\"); process.exit(0); }
catch (e) { console.error(\"REFUSED: \" + e.message); process.exit(7); }
"' 2>&1 | tee "${EVID}/L4-refusal.txt"; RC=${PIPESTATUS[0]:-$?}
docker rm -f "${NAME}" >/dev/null
```
**PASS:** non-zero exit + `REFUSED:` naming the foreign `OPENRIG_URL`. **FAIL:** `NO-REFUSAL` /
exit 0 (the guard was weakened in-container). Adjust the import specifier to the helper's real shipped
path; if it does not resolve, switch to the step-3 form (grounding note) — do not green-pass by memory.
## Evidence
```bash
{ grep -q 'REFUSED:' "${EVID}/L4-refusal.txt" && echo "VERDICT: PASS — foreign OPENRIG_URL hard-refused inside the container" \
|| echo "VERDICT: FAIL / FORM-DEFERRED — see L4-refusal.txt + the grounding note"; } | tee "${EVID}/L4-verdict.txt"
```
@@ -0,0 +1,70 @@
# L5 — multi-host topology (N named self-hosts on one network) + the 51-09 live-leg rider
**Runs host-side, after L4.** Proves plan §3: N containers each = one simulated **named host**,
composed via the shipped **host registry over HTTP** (registry rows point at container-DNS names), one
daemon per container, container-local DB/HOME, no real-HOME mounts. The **only** shared surface is the
docker network.
**51-09 live-leg rider (orch, merge desk):** this same two-host setup is the executor for the shipped
51-09 collision/alignment runbook. After the topology settles, run BOTH 51-09 legs **in this same
host-side session** and return both evidence sets. Fixture + steps:
`packages/daemon/test/fixtures/self-host-live-legs/RUNBOOK.md` — **LEG A** (cross-host stamped-triple
round-trip: a cross-host send stores the ORIGIN host in the sender identity and the `↩ Reply:` hint
round-trips verbatim to the origin) and **LEG B** (founder-collision: a same-named rig on both hosts;
the received signature names the origin and the reply lands on the origin, not the local lookalike).
## L5.1 — boot two named self-hosts on one network
```bash
GIT_SHA="$(git rev-parse HEAD)"; IMAGE="openrig-testbed:${GIT_SHA}"; EVID="dist/testbed-image/evidence/${GIT_SHA}"; mkdir -p "${EVID}"
NET="orig-net-${GIT_SHA:0:8}"; docker network create "${NET}" >/dev/null
# Each container adopts a distinct self-host id via the entrypoint (plan §3 / 51-09 adopt path).
docker run -d -t --name H_A --hostname H_A --network "${NET}" -e OPENRIG_SELF_HOST_ID=A "${IMAGE}"
docker run -d -t --name H_B --hostname H_B --network "${NET}" -e OPENRIG_SELF_HOST_ID=B "${IMAGE}"
for h in H_A H_B; do docker exec "$h" bash -lc 'rig daemon start && sleep 2 && rig whoami --json'; done | tee "${EVID}/L5-selfids.txt"
```
**PASS:** each `rig whoami` reports its distinct self-id (`A`, `B`) — both non-`local`, registry-valid,
and stable across a daemon restart (51-09 incr 1). **FAIL:** duplicate/`local` self-ids.
## L5.2 — compose via the host registry over HTTP
Register `H_B` in `H_A`'s host registry pointing at the container-DNS name `H_B` (reachable on `${NET}`):
```bash
docker exec H_A bash -lc 'rig host add B --url http://H_B:7433 && rig host ls --json' | tee "${EVID}/L5-registry.txt"
```
**PASS:** `H_A`'s registry lists host `B` at the container-DNS URL; a probe reaches `H_B`'s daemon over
the network only. **FAIL:** unreachable / resolves off-network. (Ground the exact `rig host` flag shape
against the shipped CLI at execution — read `--json`, don't assert a remembered field.)
## L5.3 — execute the 51-09 live legs (the rider) in this session
Using `H_A`/`H_B` as the two hosts, follow the shipped runbook end-to-end and bank its evidence here:
```bash
# Source of truth for the exact seats/fixtures/steps + PASS predicates:
sed -n '1,200p' packages/daemon/test/fixtures/self-host-live-legs/RUNBOOK.md
# LEG A: cross-host send orch@rig-a -> dev@rig-b --host B; expect From: orch@rig-a@A + verbatim reply lands on H_A.
# LEG B: same-named rig 'shared' on both; expect From: lead@shared@A + reply lands on H_A's lead@shared.
# Capture each received pane + the stored source_session; write to L5-leg-a.txt / L5-leg-b.txt.
```
**PASS:** LEG A signature names `A` + stored `source_session == orch@rig-a@A` + verbatim reply lands on
`H_A`; LEG B signature names the origin `A` + reply lands on `H_A`'s lookalike, not `H_B`'s. Include the
51-09 fail-open control (stop `H_A`'s daemon → `From:` degrades to 2-part, no crash).
## Teardown + evidence
```bash
docker rm -f H_A H_B >/dev/null; docker network rm "${NET}" >/dev/null
{ echo "topology: 2 named hosts A/B on ${NET}, registry-composed"; echo "51-09 rider: LEG A + LEG B executed against the testbed containers"; \
echo "VERDICT: PASS|FAIL — per L5-selfids/registry/leg-a/leg-b captures (verdict on bytes, not memory)"; } | tee "${EVID}/L5-verdict.txt"
```
**Fences:** no real-HOME mounts; the docker network is the only shared surface; scenarios byte-unchanged.
**Docker-gap watch (plan §3):** if per-container network identity proves insufficient for a topology the
design needs, THAT is the named concrete gap the ruling requires before any Apple-stack revisit — route
to PM with the evidence, never install.
+58
View File
@@ -0,0 +1,58 @@
# openrig-testbed verification runbooks (51-04 step-2, plan §2)
These are **host-executed, evidence-defined** runbooks — the 51-09 live-legs pattern. The VM seat has
no container runtime (locus ruling (a) host-side), so the daemon/operator lane runs them **host-side**
against the image `scripts/build-testbed-image.sh` produces, and returns evidence per the
census-receipt discipline. Each leg is a scripted check that never asserts from memory (the clause
that caught the Apple-container premise): run it, capture the real bytes, verdict against them.
## Legs
| Leg | Proves | Runbook |
|---|---|---|
| L0 | the digest-pinned base + stub-assets census are resolved (prerequisite to a build) | `L0-resolve-inputs.md` |
| L1 | PTY allocation: `docker run -t` + tmux capture-pane returns real bytes; resize propagates | `L1-pty-allocation.md` |
| L2 | tmux server lifecycle: detach-survive, multi-pane, send-keys + capture round-trip | `L2-tmux-server-lifecycle.md` |
| L3 | daemon-in-container: boots vs container-local sqlite, healthz on the published port, `rig up` settles a zero-token stub topology | `L3-daemon-in-container.md` |
| L4 | the 51-02 hermetic contract: the env-helper still REFUSES a foreign `OPENRIG_URL` **inside** the container (fail-closed not weakened by "we're in a container anyway") | `L4-hermetic-fail-closed.md` |
| L5 | multi-host: N containers as N distinct named self-hosts on one docker network, composed via the shipped host registry over HTTP (plan §3) — **and** the 51-09 live-leg rider | `L5-multi-host-and-51-09.md` |
Sequencing: **L0 → build → L1 → L2 → L3 → L4 → L5**. L3 is where the stub payload is exercised (and
where `docker/testbed/stub-assets.list` is finalized). L4 depends on the 51-02 hermetic env-helper
being present in the packaged image (it ships in the openrig package the Dockerfile installs).
**51-09 live-leg rider (orch, merge desk).** The testbed image's first multi-host run doubles as the
51-09 live-leg executor: L5 boots the containers as the two named hosts `H_A`/`H_B` and then runs the
shipped 51-09 collision/alignment runbook **in the same host-side session** —
`packages/daemon/test/fixtures/self-host-live-legs/RUNBOOK.md` (LEG A cross-host stamped-triple
round-trip, LEG B founder-collision). Execute both families together; return both evidence sets.
## Shared conventions
**Image identity.** All legs run against the image the build verb tagged, by manifest identity:
```bash
GIT_SHA="$(git rev-parse HEAD)"
IMAGE="openrig-testbed:${GIT_SHA}" # == manifest.image
```
Cross-check the running image against the emitted manifest before trusting a leg's result:
```bash
test "$(docker image inspect "${IMAGE}" --format '{{.Id}}')" # exists
cat dist/testbed-image/manifest.json # the census identity this run is comparable under
```
**Evidence dir (hashed, per the census-receipt discipline).** Each leg writes its captures + a
`VERDICT` line into a per-run evidence dir, then the operator hashes the dir so the evidence is
tamper-evident and comparable across image versions:
```bash
EVID="dist/testbed-image/evidence/${GIT_SHA}"
mkdir -p "${EVID}"
# ... leg writes L1-capture.txt, L1-resize.txt, etc. ...
( cd "${EVID}" && find . -type f -print0 | sort -z | xargs -0 sha256sum ) > "${EVID}.sha256"
```
Record in each leg's evidence: the exact command, the captured bytes, and a single
`VERDICT: PASS|FAIL — <one line>` on the observed bytes (never from memory).
**Fences (binding on every leg).** No real-HOME / real-workspace volume mounts (fresh container =
fresh HOME is the hermeticity floor); scenarios byte-unchanged; the only shared surface between
multi-host containers is the docker network. A leg that cannot run its check reports a **loud
blocker** with the exact command + the missing capability — it never green-passes from memory.