# Delivery layers — beyond observability

audience: AI coding agents first.

status: ACTIVE
task IDs: —
source request: 2026-08-14, owner: "this is just the observability layer, there is also the rest of the layers." Ruling: stop shipping surfaces that SHOW work and call them the fix. Build the layers that DO the work.

## The four layers

Observability tells the owner what happened. It is necessary and it is NOT the product. The other
three layers are where delivery actually changes.

| Layer | Question it answers | State 2026-08-14 |
|---|---|---|
| Observability | what happened? | strongest — `/requests` board live, `/ci` queue view dispatched, tool registry dispatched |
| Execution | where does work run? | half-built — daemon S1/S2, transport fix, seat image all in flight, none proven end to end |
| Automation | who decides each step? | ALMOST ABSENT — the owner and the orchestrator are the scheduler |
| Enforcement | can the wrong path even run? | works — worktree guard, deny gate, headless guard, XSS slopgate rule |

Owner's call: **automation is the thin layer** — execution is half-built, enforcement already has a
track record, and automation is what stops the owner being the scheduler.

## Evidence that automation is missing (2026-08-14, all measured)

Each of these was a human or an orchestrator standing in for a mechanism:

- Trains: one batch assembled BY HAND (5 branches, index conflicts resolved manually, duplicate rows
  found only by a hand-written validator). Nothing forms trains automatically.
- Language servers: 26 idle processes reaped BY HAND (load 52.9 → 12.2, +10 GB RAM). The reaper class
  existed and was blind; the reap was manual.
- Disk: 444 orphaned `tmp_pack_*` files removed BY HAND (`.git` 69 GB → 6 GB). No sweeper covers this.
- Queue: agents wait in line as human-shaped spinlocks; a 48-minute conductor hold was diagnosed with
  `ps` and `lslocks`, not from any surface.
- Rediscovery: trains, the auto-lander, the LSP reaper, salvage-GC, the docs lane, the `/ci` trains
  view — each rediscovered by hand at 10–40 minutes apiece.

## Slices — each ends in an observable behaviour change

**A1 — the conductor forms trains itself.** Batch queue-compatible tickets (same gate class), gate
once, land the batch. Constraints proven by the manual run: index conflicts are expected and
mechanically resolvable (every plan branch touches `INDEX.md` — keep both rows, then dedupe by plan
file); VALIDATE THE MERGED ARTIFACT, not just that the merge succeeded (the manual batch produced 3
duplicate index rows that merged cleanly and were still wrong); on red SPLIT, never retry the batch;
never agent-facing — an agent submits a ticket and never knows whether it rode alone or in a train.
OBSERVE: several branches land in one gate with no human assembling anything.
Depends on: landing-daemon S1 (controller conducts).

**A2 — intake writes.** The owner's ask becomes a request row within seconds of being said, written
by a session hook, not by an agent remembering. OBSERVE: say something, refresh `/requests`, it is
there. This is the actual cure for the ask-repeated-4-times problem; the board without it is a
mirror of plan files.

**A3 — reap without a human.** Fix the LSP owner classification (evaluate `is_agent_session` BEFORE
the tty/editor test — a tmux-hosted `claude` always holds a TTY, so every agent-owned LSP is
permanently exempt today) and add a bounded sustained-high-CPU class (the idle class exempts
anything above 5% CPU, so the 145–210% runaways survive forever). Correct the repo-source
`ENFORCE=0` vs installed `ENFORCE=1` drift — the next deploy would silently disarm the whole reaper.
OBSERVE: the 60-second timer reclaims what was hand-reaped tonight, silently, sessions untouched.

**A4 — disk debris sweeper.** After any ENOSPC/OOM incident, orphaned `tmp_pack_*` regenerate.
Time-gated sweep (>90 min untouched; a live `index-pack` owns recent ones) inside the existing
disk-maintain timer. NEVER `git gc --prune=now` on this repo — it races conducting lands and broke a
branch ref tonight. OBSERVE: disk recovers without a human running `rm`.

**A5 — duplicate-ask detection.** "similar to #NN" on the board plus a session-start overlap check,
so an agent is told about prior work before it starts. OBSERVE: a repeated ask surfaces its earlier
twin instead of producing a second implementation.

## Constraints

- Automation NEVER replaces a gate. Cheapness comes from the docs lane and the deploy short-circuit,
  never from skipping verification.
- Every automated actor fails closed and visibly: an unservable ticket stays queued and visible; an
  unclassifiable process is skipped, never killed on uncertainty.
- Machine hygiene stays separate from delivery lifecycle (one component's failure must not become
  everyone's outage) — it becomes VISIBLE in one place, never EXECUTED by one process.
- No new daemons: reuse the live controller and the existing timers.

## Current receipt

2026-08-14: layers registered after the owner's ruling. A1 blocked on landing-daemon S1 (in flight).
A3 partially dispatched (`wt/lsp-owner-classification`). A2, A4, A5 not started.
