# Upgrade Guide — vNEXT

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

## What Changed

The verified topic operator is now recorded automatically on BOTH inbound
ingress paths (Know Your Principal standard, security-build increment 2e — the
final operator-binding gap). Increment 2d covered only the lifeline-forward
route; the adapter long-poll (no-lifeline) path never bound. The bind now lives
at the shared `onTopicMessage` seam (`wireTelegramRouting`), guarded by
`isAuthorizedSender` — load-bearing there, because the seam also fires for
unauthorized senders. The seam resolves the server's own store instance
late-bound (a second instance on the same file would lose updates between the
two in-memory caches), and `TopicOperatorStore.setOperator` now skips the disk
write when the record is unchanged (per-message re-binds become pure reads).

`POST /pool/transfer` of a QUIET topic (never-seen or released ownership
record) previously journaled NOTHING: the placement pin is router-local and
the handler's release half only fires when the router itself held ownership.
The pinned-to machine therefore could never prove the topic was its to serve —
its working-set fetch reflex answered `not-owner` even after the #926 (pin
fallback) and #930 (journal-placement fallback) read-side fixes deployed,
because no machine ever PRODUCED the evidence those fallbacks read (coherence
live-proof finding #5, proven on v1.3.372).

The transfer handler now lands the PLACE half: it CASes `place→claim` for the
target as one synchronous pair (the bug-#11 confirmClaim precedent — the
record never rests at `placing`, the shape that queues every later message as
ownership-contention), and each landed CAS journals a topic-placement entry at
its real epoch (§3.3 call-site pairing) so the evidence replicates to the
target machine. A resting `placing` record naming the target is repaired via
claim. An active record held by a non-target machine is never stolen; any
other in-flight shape is left strictly untouched.

## What to Tell Your User

Nothing user-facing changes. Foundation wiring (experimental) for the identity
isolation security work: the agent now learns its verified operator from
authorized inbound messages no matter how its Telegram connection is set up.
Only authorized senders are ever recorded, and a recording failure never
affects message handling.

Nothing proactively — this is internal coherence plumbing. If they previously
moved a quiet conversation between machines and the receiving machine couldn't
fetch its files, that path now works: the move itself writes the ownership
record and it travels to the receiving machine automatically.

- audience: agent-only
- maturity: stable

## Summary of New Capabilities

- Operator auto-bind at the `onTopicMessage` convergence seam (covers the
  polling path; authorized senders only; fail-soft; pre-boot messages bind
  nothing, fail-safe).
- `AgentServer.getTopicOperatorStore()` — public accessor for the seam's
  late-bound store resolution.
- `TopicOperatorStore.setOperator` idempotency: identical record → no disk
  write.

- Quiet-topic transfers journal ownership evidence (place + claim halves, real
  epochs, `reason: 'user-move'`) that replicates to the pinned-to machine —
  unblocking its working-set fetch reflex (#930 fallback finally has a producer).
- Half-placed leftovers (resting `placing` records naming the target) are
  repaired on the next transfer of that topic.
- `POST /pool/transfer` response gains `placedOwnership` (whether confirmed
  ownership landed on the target as part of the move).

## Evidence

Verified by 6 Tier-1 unit tests (`topic-operator-polling-bind`: authorized
binds, unauthorized Caroline refusal, null store / getter throw / setOperator
throw all fail-soft with routing continuing, missing uid no-op), 2 Tier-1 store
tests (idempotent skip both sides), and 3 Tier-2 integration tests
(`topic-operator-polling-bind`: full Caroline replay through the seam,
single-instance no-clobber across two topics on disk, pre-construction →
post-construction lifecycle). All 60 existing topic-operator/session-context
canaries and 13 e2e lifecycle tests stay green. Clean `tsc --noEmit`.

- `tests/integration/pool-placement-transfer-routes.test.ts` — 6 new boundary
  tests: quiet/never-seen (both halves journaled, record lands `active`),
  self-owned (release + place + confirm, 3 entries), active-other (never
  stolen), active-target (no-op, no epoch bump), resting-placing-target
  (claim repair), placing-other (strictly untouched). 17/17 in file.
- `lint-cas-emit-placement` clean — 8 CAS call sites, all paired.
- Typecheck clean; full suite green on pre-push.
