# Upgrade Guide — vNEXT

<!-- bump: patch -->

## What Changed

Self-Propagation, Part 1 — **structural fix for the Telegram "two listeners" clash (409 dual-poll)**. Telegram allows exactly one long-poller per bot token; instar has two potential pollers (the lifeline and the server). Until now, the server only stayed quiet when started with `--no-telegram` (or on a standby machine) — operator discipline, not structure. Start the server without that flag while the lifeline polled the same token → guaranteed 409 (the failure mode the 2026-05-27 live test hit).

This release introduces a tiny "I am polling" lease the lifeline refreshes each successful poll tick. The server checks for it before starting its own polling; if a live lease for the same bot token is present, the server auto-demotes to send-only with a clear log line. Then dual-polling cannot happen regardless of how the server is started. The lease stores the bot token's SHA-256 hash, never the raw token. Every read path is fail-OPEN — a missing/stale/mismatched lease means the server polls as today, so setups without a lifeline see ZERO behavioral change.

Pairs with Part 2 (the `instar test-as-self` harness — shipping under the same approved spec in a separate PR).

## What to Tell Your User

- A whole class of "two things trying to listen at once" Telegram errors is fixed structurally — it can no longer happen on a single machine no matter how the server got started.

## Summary of New Capabilities

| Capability | How to Use |
|-----------|-----------|
| Server auto-demotes to Telegram send-only when the lifeline owns the poll slot | Automatic; the lifeline writes the lease, the server reads it on startup |

## Evidence

- New module: `src/lifeline/TelegramPollOwnerLease.ts` (atomic write, fail-OPEN read, SHA-256 tokenHash).
- Wired: `src/lifeline/TelegramLifeline.ts` writes the lease on each successful poll; `src/commands/server.ts` checks it before `telegram.start()`.
- Tests: `tests/unit/TelegramPollOwnerLease.test.ts` (16 — both sides of every boundary + security contract) + `tests/unit/poll-owner-lease-wiring.test.ts` (4 — no dead code).
- Spec: `docs/specs/SELF-PROPAGATION-HARNESS-SPEC.md` (approved). Side-effects: `upgrades/side-effects/self-propagation-poll-owner-lease.md`.
