# Routine self-sustainment audit — the loops did not close (2026-08-08)

Six-lens multi-agent audit of the five-routine ecosystem (panel / triage /
implementer / daily audit / weekly audit), on the owner's question: *are we
cyclically self-sustained, with no gaps?* 44 raw findings, 52 clean checks;
the verify fleet was cut short by a session-quota wall, so verification was
finished by hand against the files. Everything below was confirmed by direct
evidence before being fixed.

## Verdict

**Not yet — the pipeline's stages were sound in isolation, but the loop did
not close at either end: nothing that the routines produced could reach the
owner, and several wedge states had no actor to unwedge them.** All of the
closable gaps are now closed; three items need the owner and are listed at
the end.

## The headline finding: a pipeline with no transport

Three independent lenses converged on the same discovery, and a live probe
confirmed it:

1. The claude.ai Gmail connector **cannot send email** — drafts only (no send
   scope exists in its toolset; probed live).
2. Routine PRs are **authored by the owner's own GitHub account** (verified:
   PR #90's author), and GitHub never notifies you of your own actions.
3. Quiet days write no artifact *by design*.

Sum: every channel the routines believed they had — "email the owner", "the
owner will see the PR" — was silent. A triage decide-list would have sat as
an unsent draft; an implementer PR would have waited unseen. **Fix:** the
fleet digest (the one push channel the owner demonstrably reads daily, sent
by GitHub Actions SMTP which CAN send) now carries a research-pipeline
section: queue counts per section, the open self-authored PR list with ages,
and a stalled-PR flag at ≥7 days. Fail-soft: a missing queue file or absent
`gh` can never touch the digest. Every routine's prompt and procedure now
states the delivery reality instead of the fantasy.

## Wedge states confirmed and closed

- **Queue PR pile-up / self-shadowing.** Each panel run branched off main and
  appended at the same section anchors — so unmerged panel PRs conflicted
  with each other, and the next panel (reading main only) re-deliberated
  entries sitting in its own unmerged PR, defeating the ## Dismissed
  anti-amnesia design. Fix: ONE standing `research-queue` branch; every
  queue-writing routine appends to it if its PR is open; queue truth = main +
  that PR.
- **Rejection loop.** A closed-unmerged implementer PR erased its own
  queue-move, leaving the item in ## Approved — to be rebuilt every
  Wednesday forever. Fix: closed-unmerged = owner rejection; the item moves
  to ## Dismissed with the PR number; the implementer checks `--state all`.
- **Stalled-PR blindness.** An Approved item with an open PR is skipped by
  the implementer by rule, and triage's old check ("Approved with no PR")
  never fired because a PR existed. Fix: triage now flags open PRs older
  than two implementer cycles.
- **Sub-week expiries unwatched.** Expiry enforcement ran Mondays only; item
  PC-1's "before #88 merges" condition lapsed exactly this way. Fix: the
  panel — the queue's only daily reader — now runs an expiry watch every
  run, quiet or not.
- **Uncountable kill criteria.** Both eight-week cadence criteria were
  unfireable: fresh sessions, nothing counting windows. Fix: triage computes
  both counters every run from the queue file's git history and reports them
  against their limit; at 8 it states the criterion has FIRED.

## Continuity and environment fixes

Daily audit: carried-forward items now must live in drafts/PR bodies (which
the next fresh session reads via `list_drafts` + `audit/*` PRs), never only
in session output. Procedures no longer point cloud agents at `memory/`
(owner-side, absent from checkouts) or at broker-gated commands they cannot
run; the pip incantation that actually works in clean checkouts is recorded
where the failing one was.

## Registry and doc drift (fixed)

CLAUDE.md said two routines exist (there are five); the implementer's diagram
said three-stage (it is four); the queue header said two sections (it has
four); one stale "daily audit runs opus" survived the fable-5 re-tiering; the
registry's connector column was missing an attached connector on two rows;
and the registry tripwire test could not detect deletion of the three
research-pipeline rows — it now name-asserts all five live routines
(negative-controlled).

## Goal-strengthening (owner request, same pass)

Every procedure now opens with a **"What matters here"** section — the goal
the rules serve, for the fresh session that meets a situation the rules did
not anticipate. The panel's is the sharpest: its product is not ideas but
**experiments designed to die cheaply**; every dismissal must carry its
resurrection condition; the frontier lens watches **activation conditions**
of the deferred directions rather than seeking inspiration; the
change-reviewer treats changed code as guilty until its negative control
convinces it; and between Mondays, the clocks are the panel's.

## Still open — the owner's three

1. ~~**Cloud-routine liveness beacons**~~ — **CLOSED 2026-08-09.** The owner
   created five healthchecks.io cron checks (one per routine: no shared ping,
   because a shared one lets a live routine mask a dead one — the rule
   RUNBOOK already applied to the trading workflows). Each routine now pings
   as the literal LAST action of its session, quiet days included, so "ran
   and found nothing" is finally distinguishable from "did not run". The URLs
   live only in the trigger prompts — cloud routines have no secrets store —
   and two new guards enforce it: a committed ping URL fails the build, and a
   registry routine with no beacon row fails the build. Both
   negative-controlled; the leak guard immediately caught a real lapse (the
   publish-scrubber's own fixture had been using a live ping-URL prefix).
2. **Charter meta-loop runners**: gauges G1–G3 and the §6 deadline ledger
   still have no runner (charter cycles 2–3, unbuilt by design order).
3. **Queue decisions** now surfaced daily by the digest: 8 Open + 1 Approved
   await triage's Monday draft.

*Method note: the multi-agent verify pass died on a shared session-token
quota — the same quota the routines themselves draw on. That is itself a
finding: routine capacity is a shared resource, and the fallback policy
(fable→opus on exhausted quota) is recorded in the registry.*
