Story Script — “Seed Once, Update Everywhere”

Format: Live demo narration (90–150 seconds) for a single terminal session. Audience: Technical evaluators / security engineers. Theme: Deterministic, airgapped OTA for edge AI systems.


Setting

You are running a fleet of edge nodes. Each node runs a policy-governed AI runtime (autonomy). The nodes are offline-first: they accumulate telemetry in a WAL and drain when the collector is reachable. You update them by publishing a release to a control plane; each node verifies the update cryptographically before doing anything.

The story has four beats:

1. Day 0  — Policy loaded, identity established, runtime enforcing deny-by-default
2. Day 1  — Release published, node detects it, verifies supply chain, stays on previous
3. Day N  — OS replaced during maintenance window; node reconstructs itself automatically
4. Always — Any of the above can fail; the system fails closed, not open

Act 1 — Policy Enforcement (15 seconds)

Setup: Demo stack is up. Policy bundle is loaded. Runtime is running.

[OPERATOR] $ curl -s http://localhost:7777/health | jq .

Output marker:

{"status":"ok","mode":"normal"}

Narration: “Runtime is up, policy loaded, mode normal.”

[OPERATOR] $ curl -s -X POST http://localhost:7777/v1/tool \
  -H 'Content-Type: application/json' \
  -d '{"kind":"tool.echo","params":{"message":"hello"}}' | jq .decision

Output marker: "allow"

[OPERATOR] $ curl -s -X POST http://localhost:7777/v1/tool \
  -H 'Content-Type: application/json' \
  -d '{"kind":"tool.shell","params":{"command":"id"}}' | jq .decision

Output marker: "deny"

Narration: “The policy allows echo, denies shell. Every tool call is logged to the WAL before the response is returned — fsynced, durable.”


Act 2 — Supply Chain: Seed Once, Propagate Verified (30 seconds)

Setup: Registry is running. Release published to control plane. OCI artifacts are signed with cosign.

[OPERATOR] $ autonomy verify \
  --image registry.local:5000/myapp:v1.0.0 \
  --pubkey demo/keys/cosign.pub \
  --require-lock

Output marker:

[PASS] Step 1: cosign signature valid
[PASS] Step 2: agent binary digest matches lock
[PASS] Step 3: behavioral fingerprint matches BLAKE3(canonical(lock))
[PASS] Step 4: policy bundle semver compatible with runtime
verification OK

Narration: “Four verification steps: signature, binary digest, BLAKE3 behavioral fingerprint, semver compatibility. All four must pass. Fail any one — reject.”

[OPERATOR] $ # Now load the verified policy bundle
autonomy policy load --bundle demo/policies/bundle.tar.gz

Output marker:

policy loaded: echo_allow.rego + shell_deny.rego
bundle hash: sha256:...

Narration: “Policy loaded from the verified bundle. The runtime is now running with verifiable provenance all the way back to the signed OCI image.”


Act 3 — WAL Durability: Offline Collection, No Data Loss (20 seconds)

Setup: OTLP collector is stopped. 5 tool calls accumulate in the WAL.

[OPERATOR] $ docker compose -f demo/docker-compose.yml stop otel-sink

[OPERATOR] $ for i in 1 2 3; do
  curl -s -X POST http://localhost:7777/v1/tool \
    -H 'Content-Type: application/json' \
    -d "{\"kind\":\"tool.echo\",\"params\":{\"message\":\"offline-$i\"}}" | jq -r .decision
done

Output markers: allow × 3

[OPERATOR] $ # Drain attempt fails, but events survive
autonomy telemetry drain --dir /data/wal --endpoint http://otel-sink:4318

Output marker:

[drain] OTLP error: connection refused
drain failed: could not reach endpoint
[OPERATOR] $ docker compose -f demo/docker-compose.yml start otel-sink
[OPERATOR] $ autonomy telemetry drain --dir /data/wal --endpoint http://otel-sink:4318

Output marker:

[drain] priority queue: 5 events (0 errors, 5 decisions, 0 lifecycle)
[drain] batch 1 accepted: 5 events
drain complete: 5 events sent

Narration: “Five events written before collector outage, zero deleted on failure, five delivered after recovery. WAL is append-only, fsynced before each response.”


Act 4 — OS Replacement: Reconstruct and Continue (25 seconds)

Setup: edge daemon precheck is available. State root is populated with fingerprint and a signed manifest.

[OPERATOR] $ # Simulate OS replacement: zero the stored fingerprint
python3 -c "
import json, pathlib
fp = json.loads(pathlib.Path('/data/state/bootstrap/os_fingerprint.json').read_text())
fp['composite_hash'] = '0' * 64
pathlib.Path('/data/state/bootstrap/os_fingerprint.json').write_text(json.dumps(fp))
print('fingerprint tampered — OS replacement simulated')
"

Output marker: fingerprint tampered OS replacement simulated

[OPERATOR] $ edged --config /etc/edge/edge.toml precheck

Output markers:

level=WARN msg="edge.os.update_detected" previous_hash="000...000" current_hash="a3f...d91"
level=INFO msg="edge.os.reconstruction_started"
level=INFO msg="edge.os.reconstruction_completed" duration_seconds=0.003 boot_epoch=1
[OPERATOR] $ cat /data/state/bootstrap/os_fingerprint.json | python3 -c "
import sys, json; fp=json.load(sys.stdin); print('BootEpoch:', fp['boot_epoch'])
"

Output marker: BootEpoch: 1

Narration: “Fingerprint mismatch detected. Manifest signature verified with Ed25519. Operations executed from the verified manifest bytes — same bytes, no re-read, TOCTOU closed. BootEpoch advanced to 1. Node reconstructed. edged starts normally.”


Fail-Closed Coda (10 seconds)

Narration: “What if something goes wrong? The system fails closed.”

[OPERATOR] $ # Remove the manifest verify key and retry
mv /data/state/identity/manifest-verify.pub /tmp/
edged --config /etc/edge/edge.toml precheck; echo "Exit: $?"

Output markers:

level=ERROR msg="precheck: manifest verify key missing on reconstruction path"
Exit: 5
[OPERATOR] $ # Runtime in strict mode: all calls denied regardless of policy
AUTONOMY_STRICT_MODE=1 curl -s http://localhost:7777/health | jq .mode

Output marker: "strict"

Narration: “Missing key: exit 5. Strict mode: deny everything. The system never proceeds with unverifiable state.”


Summary Line (5 seconds)

“Seed once with a verified OCI image. The runtime enforces it everywhere — airgapped, across OS replacements, through collector outages. Every event durable, every action logged, every recovery cryptographically gated.”


Exact Make Targets for Live Demo

# Start full stack
make demo-up

# Load unsigned policy (for environments without cosign)
make demo-run-unsigned

# Full supply-chain demo (cosign required)
make demo-run

# WAL offline accumulation + priority drain
make demo-offline-drain

# All 5 failure injection drills
make demo-drills

# Release poll loop + lifecycle events
make demo-poll-loop

Pause Points

After Act

Pause reason

What to show

Act 1

Verify policy enforcement

GET /v1/events?event_type=ai.policy.decision&limit=5

Act 2

Verify tamper detection

Run demo/scripts/05_failure_drills.sh Drill 4

Act 3

Verify WAL count

autonomy telemetry export --dir /data/wal --out - | grep -c '"seq"'

Act 4

Show epoch evidence

cat /data/state/epoch/current/evidence.json