Skip to content

Nightly improver: eval-gated learning over the run ledger (item 5 of 6) #136

Description

@catomean

Item 5 of the "Ledger and the Loop" sequence. Items 1–4 and 6 shipped 2026-08-02 (#133, #134, #135 here; orangecat#547, orangecat#556). This one was deliberately held back: it learns from the run ledger, and on the day the ledger shipped it was empty. Building an improver against zero rows produces a plausible-looking job that has never once been exercised on real data.

Why it waits (measured, not guessed)

As of 2026-08-02 15:20 UTC, on prod:

signal count
runs created, last 7d 34
runs with cost_usd (metered) 0
run_escalations rows 0
non-success closes, last 7d 31

The zeros are not a bug: usage reporting and the ladder both deployed after the last nightly autopilot (04:00 UTC). The first real data lands on the next nightly run.

Note the 31/34 non-success rate — mostly partial and timeout (reaper closes at +1h). That is precisely the signal the improver is supposed to metabolize, and it means there is a real problem here worth learning from, not a synthetic one.

Start condition

Build when all hold (one query, below):

  • >= 25 runs with non-null cost_usd
  • >= 5 rows in run_escalations
  • >= 7 distinct days covered by metered runs
select
  (select count(*) from orchestration_runs where cost_usd is not null)                        as metered_runs,
  (select count(*) from run_escalations)                                                      as escalations,
  (select count(distinct date_trunc('day', created_at))
     from orchestration_runs where cost_usd is not null)                                      as metered_days;

What to build

A nightly job (after the autopilot window, not inside it) that reads the last 7 days of orchestration_runs + run_escalations + OrangeCat outcomes and emits:

  1. A brief — spend by project, cost per successful outcome, failure clusters by error signature, which escalation rungs were reached and whether escalating actually helped (success rate at rung N vs N-1).
  2. Exactly one proposed change — a prompt/config/gate edit, as a draft PR. Not a list; one, with the evidence that motivated it.

Non-negotiables

  • Propose-only. It opens a PR; it never self-applies. An agent that edits its own prompt on its own evidence has no outside check.
  • Eval-gated. A proposal needs a measurable before/after on replayed history, or it doesn't ship. Without a scoring function, "improvement" is indistinguishable from drift. The eval harness is the real prerequisite and can be built before the threshold is met.
  • One change per night, max. Compounding unverified edits is how you lose the ability to attribute a regression.

Order of work

  1. Eval harness + replay over historical runs (buildable now — does not need the threshold).
  2. The brief (read-only, no proposals) — run it for a few nights and check it says true things.
  3. Proposal generation + draft PR, gated on the eval.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions