# Runtime v2 — implementation status

Date: September 6, 2026. Status: additive starter; **not ready for production cutover**.
This document supersedes implementation-status claims in the archived design documents,
not the user's intended experience. Keep the scratchpad, deliberate speech, social Discord
participation, and Rust-mechanism/Python-policy split.

## Evidence, not aspirations

The producer ran `python tools/check_runtime.py --report docs/runtime-v2/evidence/checks.json`.
The report and its adjacent full log are included. A second invocation with `--rust` is
recorded in `evidence/full-checks.json`: Python passed again, and the requested combined
check exited nonzero because Cargo/rustc were unavailable. It does not report a green Rust
build. The Python suite contains:

- 26 tests using the **real** workbench/hook subprocesses with a **test-only** host peer.
- 22 tests for framing, typed Python values, content identity and the exact shipped SQL migration.

All 48 passed. This is not 48 Rust tests. The peer does not exercise `SessionRuntime`, Rust
process timeouts, rusqlite transactions, epoch compare-and-swap, or direct-child reaping.

Seventeen Rust tests are written in `klbr-runtime/tests/` (3 protocol, 6 storage/release,
8 session tests). None ran here. Cargo, rustc, rustfmt, Clippy and Nushell were unavailable.
Rust source was reviewed manually, but syntax/type errors remain possible until compiled.
The original `Cargo.lock` was given a local `klbr-runtime` package stanza; the helper verifies
that its named dependencies uniquely resolve to existing lock entries. That is not Cargo
resolver validation. `cargo test --locked` is a first-agent gate, not an already-passed claim.

Python tests used Python 3.13.5 and Python-linked SQLite 3.46.1. The latter is used **only for
serial, in-memory schema tests**. The proposed Rust deployment checks the actual SQLite
runtime for the documented WAL-reset fix (3.51.3+, or the 3.50.7/3.44.6 fixed branches).
Do not relax this guard to make an older test host green. Verify the bundled library on the
machine that first runs Rust. See https://sqlite.org/wal.html for the upstream advisory.

No real model calls, Discord traffic, production database migration, NixOS deployment,
resource benchmark, backup restore, filesystem fault injection or long-duration soak was run.

## What is implemented in source

**Python runtime, executed in tests.** Separate workbench/hook process roles share bounded
JSON framing over a Unix-domain socket. Workbench globals and future flags survive cells;
there is top-level await, expression display, typed outcomes and background asyncio work.
The control channel is independent of stdout/stderr. Python output has byte/record bounds;
late background output retains an origin instead of becoming the next cell's output.
`SystemExit` and ordinary exceptions become cell outcomes; native process death remains death.

`local.send` is an explicit RPC, not `print`. `runtime.wait` is a terminal yield, not a long
Python sleep. Execution scopes expire, including references inherited by background tasks.
Late replies after cancellation do not satisfy another execution's request. The SDK offers
`hooks.list` and `hooks.describe`. Hook handlers receive typed snapshots and return typed
decisions; no active effect scope is supplied to the hook role.

**Rust host, authored but unexecuted.** `Worker` supervises the real Python executable,
validates handshake/identity, keeps a bounded request queue and diagnostic tails, enforces
absolute deadlines and invalidates a broken generation. A separate control path stops the
worker without asking a hook. Mid-exchange cancellation kills the process instead of trying
to reuse a potentially half-read frame. The first Rust stop implementation is hard-stop;
Python supports cooperative interruption, but host-driven in-place reuse is not yet shipped.

`Store` opens a new-format SQLite file, takes a cooperating single-owner lock, and routes
transactions through bounded blocking tasks. Dropping the caller does not cancel an accepted
SQLite write or release its owner lock before the write finishes. Originals are append-only.
Source keys deduplicate within a session, not by identical content. Unfinished executions
are reconciled on reopen without replaying Python. The old memory database is refused, not
implicitly migrated.

Local sends have proposal, confirmed or held records. Required review runs outside any
transaction/session mutation lock in the separate hook worker. Final local publication,
receipt and review trace commit together. Here confirmed means durably published to the
operator lane, **not** that a client connected or a human read it. There are no remote effects
in this implementation, so the local ledger must not be advertised as a Discord outbox.

Host waits check pending input in the same transaction as changing wait state; admission
wakes an existing wait. Persisted deadlines can be consumed idempotently with `wake_due`.
There is no autonomous scheduler calling that function yet. Input consumption is an explicit
host API, not automatically inferred from a cell or scratchpad.

`SessionRuntime` binds these mechanisms into a host-side slice. It owns accepted execution
rather than the caller's connection, pins a policy revision for each cell and its sends,
and rejects a second foreground cell. Hard interruption can be followed by a fresh workbench;
shutdown cannot silently revive it. Hook-only activation starts and checks a candidate worker
before a database epoch switch. Old cells retain their policy reference; compatible workbench
globals remain intact. At most one activation is admitted per session at a time.

## The two actual hook slots

`attention.plan`: Python defaults prioritize operator input and directed Discord-shaped
inputs, and propose an eight-second ambient defer. Rust validates results, including operator
priority. It is an exposed/tested policy primitive, **not yet integrated into real ingress or
a model scheduler**. Source classification must come from a future authenticated adapter,
never from an arbitrary text label supplied by an external participant.

`delivery.review`: Allow or hold an explicit local send. A handler exception, malformed
result or unavailable/timed-out worker causes a held operation. No accidental approval.
This hook is connected to the authored Rust send path, and its Python side was executed.

No empty registrations were added for every future design slot. Ordered transforms and
durable observers require their own state/commit contracts and are deliberately absent.

## Limits that must remain visible

- Output beyond the preview bound is **discarded with a truncation count**, not spooled to
  an artifact. Therefore this slice is not a lossless-output or LCM implementation.
- Background tasks are ephemeral. Direct filesystem/network/subprocess effects are not
  transactional and are never automatically replayed. No heap checkpoint exists.
- Processes are trusted same-user Unix processes, not sandboxes. The host clears the worker
  environment to a limited set, but filesystem access can still expose user credentials.
  No cgroup/RLIMIT quotas or process-group descendant cleanup are implemented.
- A deadline kills the direct Python child. Descendant process ownership needs an explicit
  deployment/job design before untrusted or unattended arbitrary workloads.
- The hook worker is not automatically restarted after a deadline. Subsequent required
  reviews hold until a fresh policy worker is activated/restarted. Core control stays usable.
- Candidate import/signature/handshake validation is not semantic validation. A Python
  handler returning an invalid decision can pass startup and fail at invocation, then hold.
  There is no complete draft/publish/test UI or SDK, persisted last-good boot fallback, or
  durable observer state migration/rollback workflow yet.
- Source snapshots cover a small `.py`/`.json`/`.md` tree, reject symlinks, and exclude bytecode
  by requiring clean source. Published bytes must be protected by deployment permissions.
  Hash verification is not a defense against a malicious same-user writer during import.
  Release files/directories are synced before activation, but storage crash durability was
  not tested. No garbage collection or environment fingerprint/lock migration exists yet.
- One `SessionRuntime` per session must be owned by a future daemon registry. Global worker
  budgets, fairness, authentication, reconnect replay and a permanent service lifecycle are
  not provided by the library alone. Database uniqueness is not that whole registry.
- SQL state transitions and Rust supervision still need real integration/fault tests.
  Manually invoking the migration with Python is not a substitute for them.

## Boundaries preserved for the next agent

The legacy `klbr-core`, `klbr-daemon`, `klbr-discord`, `klbr-ipc`, UI and production schema
are unchanged. Root Cargo files merely include the new crate and its existing dependencies.
The new crate is separate on purpose so it can be compiled/tested before touching the old
runtime. It is not intended to become a second permanent competing orchestration dialect.

## Addendum: the instruction head and its revisions

The sections above describe the pack as its producer left it. This tree has since had the
instruction head built out and executed. These checks ran here, with this machine's toolchain:

- `cargo nextest run --workspace --no-fail-fast`: 199 tests, 199 passed. `cargo fmt --all` and
  `cargo clippy --workspace --all-targets` are clean.
- The Python suite in a bare 3.11 interpreter (no site-packages): 125 tests passed. Run it that
  way: `test_remote_sdk.test_closure_serialization_failure_is_not_source_fallback` asserts a
  behaviour that only holds where `dill` is not importable, so a venv that happens to carry
  `dill` fails a test that is not about this work.
- A live session (`headercheck`, real provider route, session-local SQLite) recorded its
  instruction change as `form: diff`, one 2-line hunk, 340 bytes of patch for 8451 bytes of
  instruction text. In the same turn, `runtime.instructions()` returned exactly the digest the
  host had just recorded for the current text.
- The failure mode is in that database too. Revision 342 was written by an earlier build that
  emitted per-source patches against a base whose sources were never recorded. It does not
  reconstruct, so the chain stops at revision 328 and the next change is patched against that
  text instead. Nothing ran under a text nobody wrote; the cost of a broken link is a larger
  patch, which is the trade the design names.

What the head does now, in one paragraph: a transcript pins the text it starts under, and a later
change is appended as an observation at the sequence where it was noticed, rendered as a verified
patch. The head's bytes move only at `session_start` and at a fold that covered the observation
supporting it. Reading the head and recording what it depends on are one host call, so a request
cannot run under a text no later request can reproduce. `runtime.inspect` reports the pinned and
this transcript runs under - `instructions.head_digest`, `head_reason`, `head_pinned_at_ms`,
`revisions_since_head` - beside `instructions.known_digest`, the newest text the transcript can
reconstruct. `runtime.instructions` resolves that chain for a reader that wants the exact text.
Both read the transcript's own records, so neither asks the model to hash a context it cannot
reproduce byte for byte.
