v0.9 — Reference Runtime Implementation (single .life, 5-stage assembly)
Status: Tracking epic. Implements the life-runtime v0.1.1 protocol
(docs/LIFE_RUNTIME_STANDARD.md §1–10 + Part B) as a working reference
runtime that can mount a single .life archive end-to-end.
Released as DLRS v0.9 when the 7 sub-issues below are merged + tagged.
Does NOT include multi-.life sessions, .world, federation, or DLRS
Extension Architecture — those are v0.10 (a separate epic, already designed
and documented in /home/ubuntu/.life-embodiment-notes.md).
Why now
v0.6 → v0.8 delivered the spec stack: life-format v0.1.1 (Genesis +
Lifecycle + Binding + Tier) and life-runtime v0.1.1 Part B (5-stage
assembly + Provider Registry + sandboxing + hosted-API AND-gate). What
the spec stack lacks is a conformant reference runtime that any
downstream user can install and use to mount a .life.
v0.9 closes that gap. It is intentionally minimal: one .life per
process, pluggable LifeCapabilityProvider interface, deterministic
audit emission, no networked peers, no GUI. v0.10 builds on it.
Goals
A lifectl run minimal-life-package.life command that:
- Loads the
.life zip and runs the full 5-stage assembly pipeline.
- Emits all required audit events with deterministic hash-chain ordering.
- Enforces the v0.7 + v0.8 runtime obligations (disclosure / forbidden uses /
withdrawal polling / lifecycle watching / hosted-API AND-gate).
- Mounts a single in-process
LifeCapabilityProvider for text_chat
(built-in echo provider) so the assembled .life actually responds.
- Tears down cleanly on Ctrl-C, expiry, withdrawal trigger, or
lifecycle transition (superseded / frozen / withdrawn).
- Passes a conformance harness exercised in CI against
examples/minimal-life-package/.
Non-goals (explicitly deferred)
- Multi-
.life sessions / shared world (→ v0.10)
.world archive standard (→ v0.10)
- Cross-runtime federation (→ v0.10 EXPERIMENTAL spec, v0.11 impl)
- Plugin / DLRS Extension Architecture (→ v0.10)
- VR / haptic / body-tracking surfaces (→ v0.10 Q12)
- Voice cloning, TTS, video generation (→ v0.11+ via plugin Providers)
- Encrypted-mode
.life decryption (→ life-format v0.2.0)
- Federation withdrawal registry (→ life-format v0.3.0)
The minimum bar for v0.9 is: a .life author can hand someone a .life
and that someone, with the reference runtime installed, can have a text
conversation with the digital life instance, see the disclosure label,
revoke consent and have the runtime tear down within 24 h.
Scope (7 sub-issues)
| # |
Sub-issue |
Stage / Surface |
Ref §§ |
| #120 |
runtime/ Python package scaffold + lifectl CLI entrypoint + pyproject + dev tooling |
Bootstrap |
n/a |
| #121 |
Stage 1 — Verify (zip open / schema / time / identity / integrity / audit-chain hash / consent / withdrawal pre-flight / lifecycle gate) |
Stage 1 |
§2.1–§2.5 + B.1 row 1 |
| #122 |
Stage 2 — Resolve (Provider Registry + LifeCapabilityProvider interface + tier-aware fallback + bundled_in_life defence-in-depth refusal) |
Stage 2 |
B.2 + B.3 |
| #123 |
Stage 3 — Assemble (graded sandbox: built_in in-process + user_installed OS-process IPC + capability_bound audit emission + hard_constraints injection) |
Stage 3 |
B.4 + B.7 |
| #124 |
Stage 4 — Run (forbidden_uses key-namespace gate + disclosure label injection + hosted-API AND-gate + per-turn invoke() loop) |
Stage 4 |
§4 + B.5 |
| #125 |
Stage 5 — Guard (withdrawal watcher ≥24h + lifecycle watcher + expiry watcher + audit emitter + clean teardown) |
Stage 5 |
§4.3 + §5 + §6 + B.7 |
| #126 |
Built-in text_chat echo Provider + end-to-end conformance harness + lifectl run integration + Quickstart docs |
Provider + tests + docs |
end-to-end |
Hard-rules carried over (must NOT regress)
These v0.7 + v0.8 invariants are spec-locked. Every sub-issue PR MUST
preserve them; reviewers MUST treat any regression as a release blocker:
- D1=C graded sandbox enforced at Stage 3 (built_in / user_installed
classes; bundled_in_life REFUSED).
- D2=B bundled_in_life Provider rejection at Stage 2 + Stage 3.
- D5=mixed hosted-API AND-gate (binding allows AND user policy permits;
default allowed: false).
- D6=fail-close stage gating: any failure aborts assembly + emits
assembly_aborted{stage, reason} + tears down partial state + surfaces
structured rejection (no opaque "failed to load" messages).
- No raw-asset extraction (LIFE_RUNTIME_STANDARD §3.3): runtime exposes
inference outputs only, never the underlying assets.
- Forbidden hard rules (§9 ethical positioning): never claim to be the
real person; never fabricate identifiers; always honour withdrawal.
- Single-package, single-instance (§3.1): exactly one
.life per
runtime process for v0.9. (Multi-instance is v0.10.)
Audit events MUST be emitted
Per LIFE_RUNTIME_STANDARD §5 + B.7. Every event chained to the prior via
prev_hash (v0.4 hash chain) and signed with the runtime's identity:
| Event |
Stage |
Required fields |
mount_attempted |
Stage 1 begin |
package_id, runtime_version |
assembly_aborted |
any stage fail |
stage, reason |
capability_bound |
Stage 3 success per cap |
capability, provider_name, provider_version, sandbox_class |
mount_succeeded |
end of Stage 3 |
package_id, capabilities_bound[] |
withdrawal_poll |
every Stage 5 poll |
endpoint, result |
lifecycle_transition_observed |
superseded/frozen/withdrawn detected |
old_state, new_state, package_id |
unmount |
Stage 5 teardown |
reason (one of: user_quit / withdrawal / expiry / lifecycle / error) |
All events validated against schemas/audit-event.schema.json.
Conformance test plan (sub-issue 7)
Single end-to-end harness tools/test_runtime_conformance.py:
- Build
examples/minimal-life-package/ via existing
tools/build_life_package.py (already shipped in v0.8).
- Spawn
lifectl run --no-tty --once against the built .life.
- Send one canned prompt; assert echo Provider returns the expected
response with disclosure label prefix.
- Assert all required audit events emitted in correct order with valid
hash chain.
- Trigger withdrawal-endpoint mock to return
revoked: true; assert
unmount{reason: withdrawal} emitted within 24 h (test uses
--poll-interval-override 1s for speed).
- Assert process exits cleanly with no orphaned subprocess sandbox children.
CI: extend .github/workflows/validate.yml with a runtime-conformance
job. Existing matrix unchanged.
Tracking
Each sub-issue gets a single PR. Each PR title prefixed
v0.9: … per project convention (mirrors v0.8 PRs #107–#118).
This epic closes when all 7 sub-issues + their post-merge follow-ups are
green and master is tagged v0.9-runtime-impl.
After v0.9 ships
v0.10 epic kicks off immediately. Scope already designed in
/home/ubuntu/.life-embodiment-notes.md:
.world standard + multi-.life sessions
- Embodiment capabilities (avatar.* enum + memorial_authorization)
- DLRS Extension Architecture (full P1: 8 components, plugin-native day 1)
- 14 well-known surface types + 5 latency tiers + 9 hardware consents
- Tier IX–XII hard floors + per-world physics 3-layer schema
- Cross-world traversal v0.10 baseline (snapshot carry, no concurrent presence)
- 7 schema reservations for E_full forward compatibility
- EXPERIMENTAL federation spec appendix
v0.9 — Reference Runtime Implementation (single
.life, 5-stage assembly)Why now
v0.6 → v0.8 delivered the spec stack:
life-format v0.1.1(Genesis +Lifecycle + Binding + Tier) and
life-runtime v0.1.1Part B (5-stageassembly + Provider Registry + sandboxing + hosted-API AND-gate). What
the spec stack lacks is a conformant reference runtime that any
downstream user can install and use to mount a
.life.v0.9 closes that gap. It is intentionally minimal: one
.lifeperprocess, pluggable
LifeCapabilityProviderinterface, deterministicaudit emission, no networked peers, no GUI. v0.10 builds on it.
Goals
A
lifectl run minimal-life-package.lifecommand that:.lifezip and runs the full 5-stage assembly pipeline.withdrawal polling / lifecycle watching / hosted-API AND-gate).
LifeCapabilityProviderfortext_chat(built-in echo provider) so the assembled
.lifeactually responds.lifecycle transition (
superseded/frozen/withdrawn).examples/minimal-life-package/.Non-goals (explicitly deferred)
.lifesessions / shared world (→ v0.10).worldarchive standard (→ v0.10).lifedecryption (→ life-format v0.2.0)The minimum bar for v0.9 is: a
.lifeauthor can hand someone a.lifeand that someone, with the reference runtime installed, can have a text
conversation with the digital life instance, see the disclosure label,
revoke consent and have the runtime tear down within 24 h.
Scope (7 sub-issues)
runtime/Python package scaffold +lifectlCLI entrypoint + pyproject + dev toolingLifeCapabilityProviderinterface + tier-aware fallback +bundled_in_lifedefence-in-depth refusal)capability_boundaudit emission + hard_constraints injection)invoke()loop)text_chatecho Provider + end-to-end conformance harness +lifectl runintegration + Quickstart docsHard-rules carried over (must NOT regress)
These v0.7 + v0.8 invariants are spec-locked. Every sub-issue PR MUST
preserve them; reviewers MUST treat any regression as a release blocker:
classes; bundled_in_life REFUSED).
default
allowed: false).assembly_aborted{stage, reason}+ tears down partial state + surfacesstructured rejection (no opaque "failed to load" messages).
inference outputs only, never the underlying assets.
real person; never fabricate identifiers; always honour withdrawal.
.lifeperruntime process for v0.9. (Multi-instance is v0.10.)
Audit events MUST be emitted
Per LIFE_RUNTIME_STANDARD §5 + B.7. Every event chained to the prior via
prev_hash(v0.4 hash chain) and signed with the runtime's identity:mount_attemptedpackage_id,runtime_versionassembly_abortedstage,reasoncapability_boundcapability,provider_name,provider_version,sandbox_classmount_succeededpackage_id,capabilities_bound[]withdrawal_pollendpoint,resultlifecycle_transition_observedold_state,new_state,package_idunmountreason(one of: user_quit / withdrawal / expiry / lifecycle / error)All events validated against
schemas/audit-event.schema.json.Conformance test plan (sub-issue 7)
Single end-to-end harness
tools/test_runtime_conformance.py:examples/minimal-life-package/via existingtools/build_life_package.py(already shipped in v0.8).lifectl run --no-tty --onceagainst the built.life.response with disclosure label prefix.
hash chain.
revoked: true; assertunmount{reason: withdrawal}emitted within 24 h (test uses--poll-interval-override 1sfor speed).CI: extend
.github/workflows/validate.ymlwith aruntime-conformancejob. Existing matrix unchanged.
Tracking
Each sub-issue gets a single PR. Each PR title prefixed
v0.9: …per project convention (mirrors v0.8 PRs #107–#118).This epic closes when all 7 sub-issues + their post-merge follow-ups are
green and
masteris taggedv0.9-runtime-impl.After v0.9 ships
v0.10 epic kicks off immediately. Scope already designed in
/home/ubuntu/.life-embodiment-notes.md:.worldstandard + multi-.lifesessions