SIGN IN SIGN UP

fix(historian): break stuck "compacting history" notification loop

Closes #85.

Symptom: the `⏳ Context at 95% — Magic Context is compacting history`
notification fired on every turn even though real context usage was
tiny (3.7% in the reporter's case), with zero historian failures
recorded.

Root cause: an earlier transient overflow error armed
`needs_emergency_recovery=true` on the session_meta row. The flag was
cleared in only two places:

  1. inside the publish transaction, after historian successfully
     wrote new compartments
  2. on a model switch

The 95%-block transform path:
  - bumped synthetic percentage to 95% because the flag was armed
  - started a real historian run
  - historian hit one of two SILENT no-op returns at the top of
    `runCompartmentAgent`:
      - `protectedTailStart <= offset`  (no eligible raw history)
      - `chunk.text empty || chunk.messageCount === 0`  (everything
        filtered out as noise — ignored notifications, structural
        messages)
  - returned before any publish path could clear the flag, AND
    without recording any historian failure
  - notification + run repeated next turn forever

Oracle analysis confirmed via `transform-compartment-phase.ts:125-163`
that `awaitCompartmentRun` reports "completed" for any settled promise,
which is why the user's log showed `compartmentPhase elapsed=24.3ms`
followed by "completed" — that's the silent return path bailing
before the first real await at `client.session.get(...)`.

Fix:
  - both silent no-op returns now log a clear reason AND call
    `clearEmergencyRecovery(db, sessionId)` before returning. The
    detected context limit stays — that's authoritative provider data
    that remains useful for pressure math.
  - while in here, also record `incrementHistorianFailure()` on two
    other previously-silent paths that Oracle flagged
    (`existing-validation`, `chunk-coverage`). These ARE real
    failures (corrupt stored state, unsafe chunk shape) — without
    recording them, `doctor --issue` reports a clean session while
    the user is stuck.

Verification:
  - plugin: 1431 tests pass (no new tests needed — the existing
    coverage of the publish-side clear is the regression suite; this
    fix just propagates the same call to the no-op return sites)
  - lint, typecheck, build all clean
U
ualtinok committed
9267af60f93f2b453ed944fd3404e6cd86d63d83
Parent: 801802f