# Upgrade Guide — vNEXT

<!-- assembled-by: assemble-next-md -->
<!-- bump: patch -->

## What Changed

Audit fix #3 under "No Unbounded Loops" (P19, Eternal Sentinel condition 4):
the live-tail flusher's capped backoff (#867) correctly retries a failing topic
forever, but a topic whose standby copy went stale never said so. Now a
per-topic episode latch (the `SlowRetrySentinelEscalation` shape) fires once
per outage when flushes have failed ≥30min: one log line + one
`DegradationReporter` record (`LiveTail.standbyFreshness`, topic NAME included,
housekeeping channel — the reporter's per-feature 1h cooldown bounds even an
all-topics-stale storm to a single alert). Success clears the episode. The
`reportStaleStandby` dep is optional — omitted, behavior is byte-identical.

Presence reports no longer confabulate activity from codex's input-box ghost
text. The pane sanitizer (`sanitizeTmuxOutput`) strips input-box lines whose
content is recognizably template text — a `{placeholder}`/`@filename` token or
the known codex suggestion set — before the assessment LLM summarizes the
pane. Real typed-but-unsubmitted commands, prose mentioning the tokens, and
chevron-prefixed output lines are preserved: only text the user never wrote is
stripped.

Why: ANSI-stripping erases the dim styling that distinguishes ghost
suggestions from typed input, so an IDLE session was reported as "preparing to
write tests for the referenced file" (2026-06-06 incident, ledger d0fd5483).

Made the three `telegram-reply.sh` test harnesses hermetic against a live
agent session's environment: each script-spawn now blanks
`INSTAR_AUTH_TOKEN` so the script exercises the config-file auth fallback
the tests intend, instead of inheriting the runner's real session token
(which the test servers' auth middleware correctly rejects, failing the
tests only when run inside an agent session). Same hermeticity class as
the #862 unit-suite fix, applied to the reply-script family.

## What to Tell Your User

Only relevant if I run on more than one machine: when the standby machine's
copy of a conversation falls behind for over half an hour (because syncs to it
keep failing), that fact is now recorded in my health/degradation log instead
of being invisible. Nothing pings you — but if a machine takeover ever resumes
a conversation from an older point, there's now a checkable record explaining
exactly which conversation was behind and since when.

Nothing user-visible changes unless you were affected: "what is my agent
doing?" answers no longer mistake an idle codex session's input-box example
text for real work.

## Summary of New Capabilities

- Stale-standby visibility: one degradation record per conversation per outage
  when cross-machine sync has been failing ≥30min (`LiveTail.standbyFreshness`
  in the degradation log / Process Health surfaces); retries continue
  unchanged. No configuration needed.

None — internal correctness fix to presence summarization.

## Evidence

Gap noted by #867's own second-pass reviewer ("backoff but no breaker") and
resolved per the ratified Eternal Sentinel clause: persistence kept, silence
removed. Focused adversarial second-pass: CONCUR (episode timing, firing bound
= threshold + one backoff window, recordNoNewContent edge traced safe,
DegradationReporter flood analysis). Tests: 21 green in LiveTailSource.test.ts
incl. the P19 sustained-failure bound (~100 failing windows → exactly 1
signal) and the server.ts wiring pin; tsc clean.

New 6-test suite with the real incident pane as fixture (both sides of every
boundary); all 9 existing presence-proxy suites green (96 tests); tsc clean.

- Bisected: `tests/integration/telegram-reply-end-to-end.test.ts` fails
  with `INSTAR_AUTH_TOKEN` exported, passes without; single-var culprit.
- Post-fix: all 4 reply-script test files (32 tests) green BOTH under a
  live agent env and a stripped env.
