# Project Backlog

_This file owns unresolved project work only. Completed behavior belongs in `CHANGELOG.md`; durable contracts belong in `AGENTS.md` and `/docs`._

- [ ] `Channel multimedia posts` (`0.45.1`, live-acceptance-gated): `telegram_message` channel delivery accepts one local `.jpg`/`.jpeg`/`.png`/`.webp` photo or `.mp4` video, uploads it through the multipart transport as `sendPhoto`/`sendVideo` with `text` as the HTML caption, validates kind and size (photo ≤ 10 MiB, video ≤ 50 MiB) plus ≤ 1024 visible caption characters before issuance, and rejects unsupported types and albums instead of downgrading them to links. The channel-post journal binds kind/file name/byte size/SHA-256 and caption, so duplicate requests and lost acknowledgements never re-upload; media-post edits replace the caption through `editMessageCaption`, and Markdown spoilers render as `<tg-spoiler>`. Live image publication passed on `@llb_log`. Regressions cover confirmed publication, duplicate requests, lost ACK, pre-issuance rejection, caption edits, and reconnect replacement. Remaining: operator-authorized disposable-channel acceptance of rejected upload, duplicate request, and caption edit.
- [ ] `Manual Thread naming` (`gated-but-preparable`, release priority): Local bot-owned `/name Name` and bare `/name` flows avoid model dispatch. One expiring exact-target input dialog immediately accepts the next valid name, always offers cancel, and offers **Reset to automatic** only while a manual override exists; duplicate/stale callbacks cannot repeat mutation. Durable manual override supersedes Letters/Directories, reset is leader/follower generation- and target-fenced, Letters is the default, and legacy Names resolves to Letters without rewriting recovery identity. Local review findings are remediated, including Bot-API-wait target-replacement regressions for leader/follower rename and reset. Remaining: disposable live acceptance for command-menu ordering, dialog, invalid input, duplicate callbacks, leader/follower rename and reset.
- [ ] `OMP schema acceptance` ([#267](https://github.com/llblab/pi-telegram/issues/267), `human-/environment-gated`): Local emitted-schema, Pi process, and llama.cpp source checks now prove explicit recursive JSON values, root `$defs`, only supported local `#/...` references, and no bare boolean schema. Confirm one connected `telegram_bind` request through the reporter's OMP + llama-server build before closing interoperability acceptance; do not treat this progressive external check as a Pi release blocker.
- [ ] [`Workspace operator gates`](./docs/multi-instance-bus.md#approved-next-contract-directory-names-and-reclaimable-slots): Complete the remaining external evidence for display modes, unique slots, and durable recovery. Local recovery and snapshot-equality reviews are closed; do not repeat them without changed relevant inputs. No live deletion, commit, publication, restart, or automatic retirement activation belongs to local implementation authority.
  - [ ] `Bus performance escalation` (`research`, deferred): The [isolated registry/store baselines](./docs/architecture.md#persistence-io-baseline) do not justify secondary indexes, shared mutable views, or IPC multiplexing at 26 slots. Resume full IPC/authenticated registration/routing and allocation-cost measurement only after attributable latency, event-loop blocking, or growing work establishes a concrete claim. Existing local counts are not throughput or end-to-end evidence. Preserve owner/generation fences, journal authority, and unknown-ACK behavior; do not repeat unchanged synthetic measurements merely to sustain the loop.
  - [ ] `Disposable acceptance` (`human-/environment-gated`): Complete the [0.45.0 disposable operator acceptance](./docs/multi-instance-bus.md#0450-disposable-operator-acceptance) for initial title/notice/status correctness in every display mode, leader/follower routing and rename, same-directory concurrency, restore-only restart, stale replacement, unbound forward/Restore, promotion continuity, and cleanup failure retention. Capture mobile/client evidence and complete the linked native Windows checklist separately. Unblock with operator-authorized disposable Threads and identified clients/platforms; local mocks are not live evidence.
  - [ ] `Retirement activation` (`approval-gated`): Keep the locally validated pressure-only executor disconnected. Any future activation requires separate explicit authorization and disposable operator evidence. Full slot pressure, complete protective evidence, exact confirmed absence, durable retirement, and fence completion remain mandatory; neither elapsed time nor heartbeat silence authorizes deletion.
- [ ] `Show Me ownership transfer`: Publish pi-telegram with its bundled `show-me` Skill before publishing `@llblab/skills` without the former copy, then update Pi Kit only after both packages are available. The temporary overlap may warn and retain the first-discovered old Skill, but avoids a provider gap; the coordinated final install must expose exactly one identity. Treat the standalone Skills-package removal as breaking unless its release policy establishes otherwise. Publication requires explicit authorization.
- [ ] `Live-thread continuity and recovery`: Make loss and restoration of a live thread truthful and safe without discarding accepted work or deleting a currently owned target; the initial cause of the observed stale-thread API failures remains unproven. Live Threaded → Singleton → Threaded testing exposed stale process-local leader targeting: confirmed downgrade now suspends live target authority before classic polling starts while retaining durable binding identity for restore/replacement. Remaining live acceptance must prove singleton prompts never publish into the old Thread and re-enable publishes only one current replacement.
  - [ ] Operator-validate that the 15-second stale grace prevents false routing gaps without weakening generation authority or leader election. Local incident replay proved the prior `ETIMEDOUT` / `EPIPE` churn was consistent with a follower event-loop stall: the response deadline won before an already-buffered leader acknowledgement could be consumed. Local IPC now gives pending socket input one poll phase before declaring timeout; genuinely silent peers retain the same bounded failure.
  - [ ] Complete the remaining operator-coordinated live smoke beyond the operator-confirmed successful leader Restore: verify follower Restore, inaccessible callbacks, already-absent chooser cleanup, direct stale-target diagnostics, and preservation of accepted local work/active-turn target. Use disposable test threads. The successful leader flow does not independently prove these failure paths or establish the initial stale-thread failure cause.
- [ ] `Native in-body controls live smoke`: Extend the operator-confirmed successful current-client smoke (singleton CML and mixed JSON/CML rows between paragraphs, ordinary prompt callbacks, labeled disabled control, separate footer callback, and HTML-mode footer fallback) to an independently identified second client, follower routing, blank disabled cells, and app-method dispatch/revision rejection. Do not infer coverage from the confirmed ordinary-button flow; in-body selection uses callback acknowledgement, not body recoloring.
- [ ] [`Operator-confirmed pairing`](./docs/architecture.md#automatic-pairing-confirmation-design): The operator approved automatic confirmation in trusted Pi UI, detached from the journal worker. Preserve configured owners and manual preconfiguration; no live state, credentials, restart, commit, or release belongs to this implementation scope. Execute remaining work inline, without new Actor delegation unless the operator requests it. Iterate evidence → bounded cohort → validation → reconciliation; stop at independently reviewed local correctness with explicit operator/platform gates, or a blocking authority/design uncertainty.
  - [ ] `Named-profile historical paths` (`gated-but-preparable`): Correct the profile-only versus `(agentDir?, profileName?)` mismatches for polling and Workspace-admission paths only after reference/location reconciliation can preserve existing cwd-relative work and leases. Pure probes confirm both mismatches; live contents remain uninspected. Prepare exact-reference guards and real-composition regressions without redirecting storage. Historical discovery/migration requires explicit operator authorization and identified locations; do not infer emptiness or move to a fresh canonical file.
  - [ ] `Source readiness and migration proof` (`local-actionable`, after lifecycle/reference prerequisites): Resolve the reviewed preparation prerequisites in source and existing lifecycle owners: fresh worker dependencies cannot expire behind unchanged keys; donor offer/transfer/discard must not leave executable stale receipt projections; accepted-work pending-mutation checks must preserve safety and an explicit progress contract without recovery-capable preflight. Transport loss alone still cannot revoke valid accepted work. Reconcile canonical namespace evidence with every durable consumer reference and prove any excluded storage cannot feed an automatic consumer. Close namespace creation, recovery and handoff writers through actual serialization or quiescence before readiness can authorize polling migration and consumer preparation. Resolve interrupted mixed-schema cleanup before claiming migration crash completeness. Keep the paired-only follower factory disconnected until readiness and exact lifetime/publication fencing can be composed safely. Preserve Workspace → config → journal ordering, receiver provenance, and post-lock wakeup/ACK. Implement strict polling migration and source readiness: re-resolve/revalidate binding after awaiting old-worker shutdown, prepare before worker construction or lifecycle availability, and gate terminal retry, dead-owner cleanup and handoff consumers. Include Workspace protection capture's recovery-capable journal reader, not only lifecycle startup; discovery must reject symlinks/unknown identities and enforce bounded namespace inspection. Preserve configured work, IDs/revisions/cursor, receipts, births/generations, failures and recovery identities; refuse uncertain authority without recovery/reset. Recheck readiness inside final config grant serialization and audit every writer/reader plus real-process contention. Producer/consumer capability gating and mixed-version/downgrade coordination remain activation requirements.
    - [ ] `Follower delivery custody` (`local-actionable`, priority): Implement the approved [single-authority input custody contract](./docs/architecture.md#input-custody-contract) inline. Extend the disconnected v3 acquisition/start/settlement primitives in the existing journal owner. Logical/physical admission now verifies every current transition class and binds later reserve checks to the exact changing input, covering commit-unknown append and cleanup residue. Branch reserves are reused, not summed; they do not promise simultaneous transitions or tolerate unbounded filesystem failure. Exact same-owner release and process-birth-proven dead-owner recovery now return only `ready` claims to their original unclaimed input; `running` remains outcome-unknown. Journal-level offer/accept/cancel now freezes the donor and transfers the same ready claim under exact context, with stable duplicate acceptance and no post-accept cancellation. Its durable source reference plus stored handoff ID survives restart without persisting raw token entropy; process-birth-proven dead-donor recovery races acceptance atomically and cannot erase an accepted claim. Atomic grouped transition now replaces exact running claims with one Pi queue receipt while retaining only non-authoritative acquisition/binding/payload provenance; commit-unknown retries return the same queue acquisition and stale raw settlement cannot erase it. A disconnected worker-facing execution adapter now acquires and starts one exact source reference before handler execution, completes exact successful input, atomically creates a single-input queue receipt, returns deferred custody, and refuses to rerun a retained running claim after ambiguous execution. A disconnected session adapter now retains deferred receipts and atomically groups them with the current running input into one queue receipt; stale raw completion is rejected after the transition. The same session now settles late deferred `complete` or grouped `queued` outcomes only through retained exact receipts; stale/missing late settlement fails closed. Handler failure and fresh-session observation of `running` no longer populate local settlement authority, so synthetic late completion cannot erase outcome-unknown work. A disconnected custodied admission handle now composes the existing registry/default routing inside the session: immediate outcomes settle there, and late reports settle through the retained exact receipt with diagnostic error capture. The real worker drain now has an optional custodied execution result path: completed inputs are reread without legacy `removeCompleted`, and retained outcome-unknown input blocks without retry/failure mutation. Legacy execution remains the default. The worker now consumes already-durable late custodied completion through generation/signal/exact-claim checks, clears its deferred projection, and resumes draining without legacy mutation. The custodied admission handle emits that late settlement result to an optional worker callback. Lifecycle assembly now forwards an optional binding-owned custody port, and the admission-worker factory selects it only with an exact journal binding key; legacy remains default and production resolvers expose no custody port. A strict v3 worker-journal adapter now exposes custody plus exact queued completion, admits v3 snapshots, and throws before every legacy raw completion/queue/failure mutation. Custodied handler errors block as running outcome-unknown rather than entering legacy retry. Grouped late reporting now preserves one bounded duplicate result per remaining source: each exact source callback observes the same durable queue receipt, while conflicts fail closed. Worker late settlement treats the same exact already-published queue receipt as a duplicate instead of a conflict. An assembled real-v3 worker regression now proves two deferred source reports create and publish one grouped queue receipt without blocking or legacy mutation. It also exposed and fixed source/recipient identity conflation: `recoveryKey` identifies the journal source, while a separate exact `recipientBindingKey` authorizes execution custody; v3 composition requires both. A separately gated lifecycle resolver now supplies strict v3 journal and recipient identities only when enabled; disabled resolution does not read either dependency, and its runtime key includes both source runtime and recipient binding so identity changes force replacement. No production resolver enables it. A real-v3 lifecycle replacement regression now starts from retained `running`, changes recipient identity (forcing runtime-key replacement), and proves neither old nor replacement session executes or settles the input. The leader/follower lifecycle assembly now has real-v3 evidence that follower registration-generation replacement and subsequent follower-to-leader promotion never replay or settle retained running input. The v3 worker now skips retained `running` entries while draining independent pending tail, then reports blocked execution once only unresolved running work remains. Foreign-owner and handoff-frozen `ready` entries now also remain untouched while independent tail drains; once only unavailable custody remains, worker reports `input-custody` rather than executing or taking over. Bounded-tail regression now proves each custodied commit yields and rereads exact journal state across a small batch limit while unresolved running custody is skipped; five independent entries complete before the final blocked state. Blocked worker state now reports only update ID plus `running-outcome-unknown`, `foreign-ready`, or `handoff-frozen`; owner, process birth, acquisition, binding, payload, path, and token remain absent. Diagnostics clear on each scan. Status rendering now proves the redacted custody line, mixed foreign-ready/running evidence prioritizes `running-outcome-unknown`, and v3 `retry-wait`/`failed` is quarantined as `legacy-retry-state` while pending tail drains. No legacy retry mutation or handler replay occurs. The strict v3 store and gated lifecycle binding now expose existing queued receipt offer/accept/cancel through the same serialized admission boundary, distinct from raw input handoff. Lifecycle lookup now accepts one exact queued handoff into recipient ownership through the gated v3 binding; acceptance signals the worker and retained journal authority identifies only the recipient. Cancelling a frozen raw-input handoff, then signaling, drains that input and clears blocked diagnostics. Recipient queue-owner projection now reconciles after lifecycle replacement when queried with the mandatory exact journal binding key; an exact duplicate acceptance (the lost-ACK retry shape) returns the same recipient owner without another transfer. Legacy mutation cannot reconcile a v3 retry quarantine: strict source-version selection rejects it before mutation, so any future operator disposition must be an explicit v3 authority distinct from worker settlement, not a downgrade escape hatch. A disconnected follower source-reference admission now validates exact delivery/source/recipient identity and wakes existing durable custody without appending the forwarded carrier as another executable journal copy. Receiver selection is separately gated and fails closed when enabled without wake authority; legacy durable-copy admission remains default and production supplies no source-reference port. Receiver regressions now prove duplicate delivery produces only repeatable wake, stale registration generation cannot wake, and enabled reference mode without a port cannot fall back to legacy copy admission. The gated delivery identity now carries an optional bounded non-secret source `recoveryKey` without changing the legacy delivery hash. Reference admission requires it, includes it in wake evidence, rejects mixed legacy envelopes, and receiver selection additionally requires explicit authenticated-transport proof. Legacy copy mode neither requires nor fabricates the key. Reference evidence now also requires bounded exact `acquisitionId` plus `handoffId`; parser and admission reject missing/malformed claims before wake while the legacy delivery hash remains unchanged. Wake receives recovery, claim, source update, and recipient identities but does not yet assert them against journal state. Reference evidence now additionally carries bounded exact acquisition and handoff IDs; absent claim evidence is rejected before wake while legacy identity/hash remains unchanged. A disconnected binding-owned wake runtime now resolves the exact recovery key, recipient binding and live recipient owner, then requires one accepted `ready` claim with matching update/acquisition/handoff IDs before signaling; frozen, stale, running, missing, or mismatched evidence cannot wake or mutate. An authenticated receiver now composes source-reference admission with binding-owned lookup against one real shared v3 journal: exact and duplicate deliveries only signal the accepted claim, while stale acquisition and replaced registration generation receive negative ACKs without legacy append or wake. A dedicated `input-custody-reference-v1` capability now requires mutual local/remote support, and a sender helper constructs recovery/acquisition/handoff evidence only from an accepted claim; absent handoff fails closed while legacy delivery identity remains stable. A new `leader.wakeInputCustody` envelope serializes only recipient generation and exact durable reference—no callback, message, reaction, or edited-message carrier. Receiver dispatch forces it through authenticated source-reference admission and legacy durable admission explicitly rejects it. The foreign-owned update forwarder now selects payload-free custody wake only when both peers advertise the capability and an exact accepted source reference resolves. Missing reference fails retryably before transport; mixed/legacy peers retain the original carrier envelope, and production advertises neither capability nor resolver. A leader-side forward-reference resolver now reads shared v3 state without mutation and returns recovery/update/acquisition/handoff evidence only for the exact recipient-owned unfrozen `ready` claim; donor-frozen and recipient-binding mismatch return no reference. A real shared-v3 regression now composes accepted raw handoff, binding-owned resolver, mutually capable foreign forwarder, authenticated payload-free receiver and exact wake; exact request replay returns the same settlement/reference from receiver dedupe without another signal; a new-request duplicate may only repeat the safe signal. Frozen pre-acceptance lookup returns no reference, so the forwarder’s missing-reference gate prevents transport. A recipient-side acceptance runtime now resolves recovery/binding/live-owner authority, invokes the existing exact journal acceptance CAS, verifies returned handoff identity, then exposes the accepted reference and signals only after durable success. Binding mismatch fails before mutation. A payload-free `leader.offerInputCustodyHandoff` envelope now carries exact recovery/source/handoff and recipient binding/generation evidence. Parsing rejects malformed or cross-recovery sources; the receiver requires authenticated transport, enabled custody-reference capability, exact local identity and a dedicated acceptance handler. A duplicate accepted handoff returns durable duplicate evidence through ACK. A disconnected donor client now durably offers before send, validates exact acceptance ACK, and leaves unknown outcomes frozen. Lost ACK after recipient acceptance cannot re-offer because donor authority moved; the client first reconciles the exact accepted shared-journal reference and returns duplicate settlement without transport or new authority. The real v3 fixture now composes donor client with authenticated handoff receiver: one transport acceptance durably transfers and signals, then client replay reconciles locally without a second request. A mandatory immediate wake was removed from the design because acceptance already signals after CAS; payload-free wake remains an idempotent recovery nudge for accepted custody. A disconnected bus-binding runtime now derives acceptance, wake and forward-reference resolution from one recovery-key lookup carrying the same recipient binding/live owner, journal and signal authority, preventing independently sourced port identities. Lifecycle assembly/runtime binding now optionally exposes the one custody bus bundle; production omits it. Bundle replacement evidence proves one authority loss simultaneously disables forward lookup and makes acceptance/wake fail closed without signaling. A follower transport adapter now derives capability state, handoff handler, wake admission and leader forward resolver from `getInputCustodyBus()` on every call. Bundle removal (downgrade/reconnect/replacement) disables capability/resolution and makes stale acceptance/wake fail closed without cached signal authority. A disconnected real receiver now spreads the lifecycle-derived ports: active g1 accepts, bundle removal rejects before handler, and g2 reconnect with a replacement bundle accepts only g2 handoff/wake while stale g1 remains rejected. No legacy fallback or cached first-bundle call occurs. Live follower target ownership now carries the exact current registration protocol identity into forwarding selection. Regression proves durable-only registration selects legacy, capability upgrade selects custody reference, and downgrade returns to legacy; persisted bindings still grant nothing. The forwarder now supports a final current-ownership check after reference resolution and before transport. A TOCTOU regression downgrades capability and changes generation inside resolution; forwarding returns `recipient-ownership-stale` and sends no envelope, so an old capable snapshot cannot cross reconnect. The production follower-client composition now revalidates every forward against the current live registry generation, profile binding and negotiated protocol immediately before transport; this strengthens legacy forwarding too, while the receiver’s generation check remains independent. Focused production/index evidence passes. Production now uses one canonical live-registry validator. Registry removal, same-generation protocol downgrade, and generation replacement all invalidate the old ownership snapshot; only ownership freshly projected from the current registration validates. This fence applies before both legacy and gated transport. A post-accept retry regression now changes registry generation/protocol after the first exact wake reached the receiver; retry with the old request/ownership stops at live-registry validation, sends nothing, and cannot retrieve cached ACK across replacement. Remaining activation gates are source readiness/historical migration, exclusion of legacy writers, capability rollout, and production bus/lifecycle bundle composition. A disconnected activation-readiness evaluator now enables only requested absent/v3 source with proven legacy-writer exclusion, completed historical migration and all relevant peers capability-ready. Disabled, legacy/unsupported/ambiguous source, unknown/mixed peers, writer presence and incomplete migration return bounded blockers. A disconnected lazy readiness resolver now orders evidence reads: disabled, writer-exclusion, and migration blockers read neither source nor peers; strict inspection loss maps to `source-unready`; inventory loss maps to peer mismatch; only complete evidence enables. It creates no journal/lifecycle binding. Read-only evidence adapters now map real strict journal-family inspection to absent/v3/legacy/ambiguous and current follower generation/protocol inventory to ready/legacy/unknown. Corrupt source and missing live protocol fail closed; neither adapter mutates or enriches evidence. The lazy resolver now has real disk/registry composition evidence: absent and v3 source with fully capable live peers enable; same-generation peer downgrade blocks; replacement upgrade re-enables; later source corruption blocks. Every call rereads evidence. Peer readiness now requires both durable-admission and custody-reference capabilities. Readiness now has typed writer-exclusion and migration evidence contracts bound to exact profile/recovery identity and version; missing, unknown, incomplete, present-writer or mismatched evidence maps to the existing blockers before source/peer inspection. Providers remain read-only abstractions, not claims of durable storage. A disconnected retained-evidence store now has a bounded strict v1 codec, exact revisions, serialized CAS publication, kind-specific validation, and an injected publication-authority check; malformed, stale, unauthorized or cross-kind evidence never publishes. Persistence remains an injected atomic port rather than a production path. Writer/migration records in one retained snapshot now must share the same exact profile/recovery identity; authorized cross-identity publication fails before persistence. No current owner can truthfully mint writer exclusion: existing closure evidence explicitly cannot prove arbitrary writer/consumer absence. The production reference inventory now identifies the single legacy binding factory and every repository-visible holder: leader/follower lifecycle workers, retirement protection/discovery, polling offset/cutover/bootstrap reads, and queue-handoff recipient resolution. None has close acknowledgement or a lifetime lease; external/old-build/historical consumers remain unknowable, so writer-exclusion cannot be minted. Lifecycle runtime now supports an injected exact source-reference lease: first bind acquires, replacement releases then reacquires, shutdown releases even while retaining the reusable binding object, and restart reacquires. Release failure cannot preserve runtime authority and is diagnostic-only. This tracks participating lifecycle consumers but is explicitly not whole-root/writer-exclusion proof. One bounded exact-release process-local reference registry now backs production leader/follower lifecycle leases. Capacity and stale-release fail closed; shutdown/restart/replacement update the inventory. It remains non-durable and cannot prove external absence. The registry now provides sync/async scoped leases that release on return, throw or Promise rejection. Production status/polling cursor reads, cursor cutover and bootstrap entry reads use short-lived leader references; missing binding acquires nothing. Workspace-retirement journal protection now accepts a scoped read port; production wraps shared, retained-binding and discovered journal reads in short-lived leases from the same registry, with release on read success/failure before planning continues. The resolver no longer implies unleased read scope. The remaining production resolver inventory is now classified: lifecycle uses long-lived leased bindings, retirement and polling/bootstrap reads are scoped, and queue-handoff recipient lookup reads only computed recovery identity without journal I/O. A composition invariant rejects reintroduced direct resolver `.journal.read()`. Arbitrary external package consumers remain unprovable. Composition invariants now prove production creates no raw legacy/input store directly: worker and follower durable admission writes delegate through leased lifecycle runtimes, while the sole direct cursor append remains inside a scoped async lease. Exported legacy factories and arbitrary external package consumers are still not closable from process-local evidence. Current supported package boundaries do not export any journal mutation factory: exports are root/default plus stable API domains, and root/API sources contain no legacy/input store types or constructors. A new invariant locks this. Prior installed versions, unregistered old processes and source-checkout deep imports remain unverifiable, so global writer exclusion still requires operator-governed retirement/closure. Writer-exclusion evaluation now requires a caller-proven complete writer inventory bound to exact profile/recovery identity plus process-birth liveness for every listed writer. Any alive writer is present; mismatch, incomplete inventory, liveness failure or unverifiable writer is unknown; only all-proven-dead yields excluded. Registry absence contributes nothing. The single journal transaction owner now has an optional outer writer-admission seam propagated through leader/follower/path factories. It gates append, all mutations, and ordinary `read()` because read may repair; strict read-only inspection remains separate. Denial occurs before source serialization/locking and publishes nothing. Production leaves the seam unset. Design fixed point: reuse the Workspace ledger with a third `journal-writer-closure` discriminant and identity-only payload, never cleanup/retirement fields or a second ledger. Closure acquisition requires zero ordinary leases; writer admission holds one ordinary profile lease before config/journal locks, so no config nesting occurs. Lock-order evidence now proves denied writer admission never enters pairing/source serialization, while allowed append enters writer admission before config serialization. The third kind and strict identity-only closure payload codec now exist independently; extra deletion fields, wrong profile/kind, malformed owner/timestamps or missing recovery identity are rejected, while deletion fence types remain narrowed to their two existing kinds. The top-level ledger fence union is now integrated atomically across `workspace-admission`, `workspace-retirement`, and the cleanup-manager ledger port. Closure state round-trips, blocks all profile admission and competing retirement, reserves no Thread slot, and deletion APIs fail closed before target/permit access; compile-time deletion permit authority is narrowed to retirement/cleanup and cannot contain writer closure; existing retirement and cleanup suites remain green. Exact closure acquire/release authority requires zero leases and exact identity. An optional journal-writer adapter now acquires one ordinary profile lease before the journal seam, retains its operation identity across ambiguous acquisition, never executes without durable admission, releases in `finally`, and reports release ambiguity without masking a settled journal outcome. Production factories do not install it. Existing optional binding composition is regression-proven across leader, follower, recipient and discovered journals; omission remains the production default. In-fence publication is blocked by a proven stale-evidence contradiction: releasing closure permits a newly started legacy writer, while retaining it blocks every current writer because admission has no protocol class; retained v1 `excluded` evidence binds neither closure nor startup authority. A strict standalone startup-exclusion authority schema now binds profile/recovery identity, exact closure operation, writer-inventory SHA-256, `custody-v3` as the sole allowed protocol, operator authority ID, status and authorization time; wrong identity/protocol/digest and extra fields fail closed, and revocation is explicit. The readiness store now retains startup exclusion through the same strict revisioned CAS and injected publication authorization, enforces identity agreement with writer/migration evidence, rejects malformed fields, and durably records explicit revocation. Proven readiness now requires writer evidence linked to a matching `enforced` startup authority by authority ID, closure operation and inventory digest; legacy unlinked v1 evidence, revocation, digest drift and authority mismatch all remain blocked. The store rejects conflicting linked authorities. Workspace now has a strict standalone `custody-v3` writer-protocol mode codec binding profile/recovery, startup authority, closure operation, inventory digest, installer owner and install time; wrong protocol/identity/digest and extra fields fail closed. The ledger now atomically replaces an exact zero-lease closure with that protocol mode, rejects fence+mode state, resumes exact lost-ACK installation, blocks new closure while mode is active, and admits only exact-authority v3 writers. Generic `journal-write`/`journal.*` admission then requires an already-held same-owner dedicated v3 profile lease, closing operation-name bypass while preserving nested append/input admission. Production does not install a mode. The former one-way mode now has an optional production-unset reclosure authorizer: zero leases and exact recovery authority atomically replace mode with closure; active writers block before callback and denial retains mode. A fresh-ledger lost-ACK regression proves exact closure recovery without a second authorization callback or protocol-mode resurrection. The composition invariant also forbids production authorization. Proven readiness now additionally requires an installed protocol mode matching profile/recovery, startup authority, closure operation and inventory digest. Thus crashes before mode installation or before linked exclusion publication remain disabled. The non-nesting operator coordinator now verifies retained enforced authority, evaluates exact inventory/liveness under closure, installs the exact mode, rereads authority, then CAS-publishes linked writer exclusion. Revocation/race after installation leaves mode without readiness evidence; exact retry reconciles mode/evidence. Production has no caller. A strict standalone migration-completion authority now binds profile/recovery, startup authority, closure operation, complete historical inventory/disposition digest, resulting `absent|v3` source family, operator authority, and explicit revocation; legacy family, malformed digest, extra disposition fields or identity drift fail closed. The readiness store validates and cross-links the complete candidate before invoking publication authorization, so malformed or extra-field evidence never reaches the authority callback. It retains migration completion through authorized revisioned CAS and rejects cross-profile, startup/closure and linked migration-authority conflicts. Proven readiness requires linked authorized migration evidence and a live source family equal to the authorized `absent|v3` result on every resolution; legacy unlinked evidence, revocation and source drift block activation. A disconnected non-nesting migration publisher now rechecks retained authorization, exact historical inventory digest and live resulting source before CAS publication; exact retry does not advance revision, while revocation or drift blocks. No operator command exists and custody remains disabled by default. A strict standalone legacy-custody evidence/authority schema now hashes immutable retry/failed metadata without update payload, rejects claimed/provenanced entries, and binds exact update/evidence, operator authority, timestamp and explicit `requeue-v3|discard` action; generic terminal `retry` is not accepted. The existing bounded segmented operator audit now carries a discriminated legacy-custody record rather than a second log. A v3-only atomic mutation requires injected authorization (production unset), exact current evidence and profile admission; `requeue-v3` clears failure metadata to unclaimed pending, `discard` removes the entry, exact retry returns the same audit, and terminal-disposition ID collision fails closed. The strict worker port projects an explicit four-method custody object, so runtime reflection exposes no operator capability. A disconnected operator runtime requires a caller-owned binding-reference scope spanning each redacted list/apply operation; exact recovery mismatch, removal or replacement fails closed, and no store reference escapes. This prevents Workspace retirement/source pruning from racing a merely pre-resolved operator binding. The shared bounded reference registry now includes an `operator-disposition` class, so future composition reuses the existing tracker rather than creating parallel reference authority; it remains process-local, not global exclusion. Production and Telegram commands remain unbound. A composition invariant now forbids `index.ts` from acquiring closure, installing mode, executing cutover/migration publication, supplying legacy disposition authorization, or constructing the operator runtime. A deterministic redacted candidate port now uses strict v3 source inspection rather than ordinary repair-capable `read()`, enters no writer/source mutation serialization, and lists only update ID, retry/failed state, attempt count, bounded failure class and evidence SHA-256; payload, summary and execution authority stay internal. Duplicate reconciliation now strictly normalizes retained authority before invoking the authorizer, so malformed extra fields cannot reach authorization callbacks or trigger another mutation. Commit-unknown publication regression proves retry observes the durable audit and does not repeat disposition; a second disposition against the now-pending entry is rejected, preserving the same no-replay rule used for running custody. Production custody capability remains unadvertised. V3 queue-handoff exposure and outcome-unknown running recovery remain explicit follow-ups. Reuse exact owner/acquisition validation rather than adding a parallel ledger. Falsify unclaimed versus owned execution, stale-owner settlement, duplicate/lost-ACK transfer and role-independent ownership before consumer wiring; preserve legacy format behavior and fixed receipt identity. Then integrate reference-bound bus/worker ownership with independent-entry progress and actual unsettled-handler barriers, and replace the owned counterexample probes with project-native regressions. Do not repeat the unchanged replay investigations. Raw-owner recovery must distinguish not-started from outcome-unknown work; do not silently adopt queued-owner discard or automatic replay. Historical data, migration, capability rollout and activation remain separately gated.
    - [ ] `Polling migration candidate` (`gated-but-preparable`, deferred behind replay/lifetime/reference boundaries): The read-only prefix matrix from `run:telegram-polling-migration-contract` supports a constrained empty-current-state v1 consolidation → verified redundant cleanup → v2 publication candidate, not implementation or activation. Reuse its retained counterexamples and constraints from architecture docs; do not rerun the same design matrix. Any implementation still requires a selected contract, independent evidence review, exact startup/lifetime references, producer compatibility and final-grant gates.
    - [ ] `Legacy v1 publication exposure` (`local-actionable`, deferred to writer closure): The cursor-omission and attempt-overflow weaknesses also exist outside `sourceAccess`, which this opt-in cohort deliberately preserves. Establish actual legacy caller exposure and choose a separate compatible correction or proven retirement during factory/writer closure; do not imply the new-mode guard fixed production or silently fabricate a follower cursor.
    - [ ] `Startup/source readiness integration` (`local-actionable`, after migration and lifetime prerequisites): Integrate controlled journal preparation with exact startup authority and close participating writer/consumer references before final grant readiness. Keep `/telegram-connect` bootstrap recovery distinct: owners/state repair can precede role acquisition; first arrival or singleton/leader status alone does not prove source/root quiescence. Preserve accepted work and existing lifetime gates; whole-profile discovery, historical-path reconciliation and migration remain separate proof/activation requirements.
  - [ ] `Bounded confirmation runtime` (`local-actionable`, after design): Implement one expiring candidate/dialog with native Pi confirmation, duplicate suppression/cooldown, cancellation, and exact identity checks. Validate with injected clock and held UI/publication promises; prove that journal worker progress does not await approval and stale Yes cannot grant. Keep SDK mechanics and final publication with their existing owners.
  - [ ] `Admission integration and acceptance` (`local-actionable`, after runtime): Wire pending/denied/allowed decisions before every user-content routing shortcut and bootstrap path, apply the reviewed durable grant boundary, update setup/UI documentation, and cover backlog/restart, no-UI, conflicting owner, failure/retry, and configured-owner compatibility. Run full validation and independent post-integration review. Actual terminal-dialog and Telegram acceptance remain operator-authorized disposable tests, not local-mock claims.
- [ ] `Agent-owned channel posts` (`external-blocked`, required for 0.45.0): Extend explicit numeric/`@username` channel delivery with one bounded profile-scoped durable journal containing only posts created by this agent path. A disconnected v1 store now validates exact profile/token identity, capacity and records; its idempotent prepare/begin/confirm CAS leaves issued work outcome-unknown until an exact Bot API result is recorded and survives restart. The public-`@username` direct-leader path now prepares and begins the exact tool-call operation before `sendRichMessage`, confirms the returned numeric channel/message identity, and refuses replay of retained unknown outcomes. `telegram_channel_posts` now exposes bounded local listing without Bot API reads. `telegram_channel_post` now drives exact retained edit/delete transitions through direct-leader `editMessageText`/`deleteMessage`; tool-call identity fences unknown outcomes and successful confirmation is idempotent. Numeric channel delivery now requires explicit `channel: true`, direct-leader ownership, and matching `getChat` channel identity before using the same journal; confirmed records retain bounded observed username/title metadata. Cross-process races now prove one durable publication/edit/delete issuance and no post-restart regrant. Strict reads reject links, foreign/loose files, identity races, unsupported no-follow platforms, and oversized input before parse. There is no legacy post schema to migrate: absent state starts empty, unknown versions/fields fail closed, and the 0.44 downgrade check leaves the inert file byte-for-byte untouched because old code cannot issue post effects. Explicit successful listing is the only tool surface that returns retained authored Markdown; channel send/list/mutation failures and runtime events now use fixed messages without content, token, path, or arbitrary transport detail. The production-wired publication helper now proves lost-success-ACK and ambiguous-send retries invoke transport once, then return retained success or refuse from outcome-unknown. Fresh replacement-store regressions now prove lost successful ACK and ambiguous send cannot replay across helper instance replacement/restart. A native entrypoint regression now disconnects/reconnects the direct leader and proves both lost success and ambiguous outcomes reuse durable authority without a second send. Local implementation and evidence are complete. Closure requires operator-authorized live create/edit/delete checks against a disposable channel with real sender rights; no live channel effect is authorized by this backlog work. Persist intent before the non-idempotent send; after a successful Bot API response retain canonical numeric channel ID, observed username/title when available, exact message ID, authored content, timestamps and current state. Commit-unknown publication must remain outcome-unknown and never auto-replay; edit/delete retries require exact current records. Do not enumerate admin channels, ingest arbitrary channel history, or treat missing local records as Telegram absence. Direct leader ownership, explicit user intent, sender rights, redaction, cross-process serialization, retention limits, migration/downgrade behavior and lost-ACK duplicate prevention are release gates.
- [ ] `Thread Cleanup Manager` (`local-actionable`): A disconnected pure planner now returns candidates only from unique exact inactive binding/target snapshots with matching all-clear live-owner, accepted-work, and delivery-authority evidence; malformed/unknown/competing reservation, provision, or cleanup state yields no candidate, and ordering never treats age as authority. A disconnected strict profile/token-scoped work-set now persists exact candidates, records one exact Workspace deletion permit as `prepared → outcome-unknown` across restart, rejects mismatched permits, and records idempotent `deleted` confirmation under bounded atomic serialization. A disconnected executor now requires an injected exclusive Workspace deletion boundary across fresh evidence planning, exact retained-snapshot comparison, permit acquisition/recording, delete callback, and confirmation; the future fence owner must acquire/recheck in ledger order rather than nesting fence acquisition inside an admission lease; regressions prove drift stops before permit, blocked/already-issued cannot fabricate deletion authority, and ambiguous delete remains outcome-unknown without replay. A production-shaped evidence adapter now preserves each full Workspace record while resolving external protection, then snapshots exact cleanup fields plus reservations, provisions, and cleanup intents; resolver failures become `unknown` and source failures propagate fail-closed. Production composition now runs a truthful **Review inactive tabs** control under profile-wide Workspace admission, durably prepares one canonical 128-bit-digest work-set, and opens a separate summary with proven count, explicit no-deletion state, and Back navigation. An exact 62-byte confirmation callback contract now accepts only canonical work-set IDs and renders **Clean inactive tabs** only when a destructive port exists; production intentionally omits that port, so review remains non-destructive. Do not route manual cleanup through `acquireRetirementFence()`: retirement remains pressure-only. The single admission-ledger fence now accepts discriminated `pressure-retirement | manual-thread-cleanup` authority, resolves legacy missing kind as pressure, exposes `acquireThreadCleanupFence()`, carries kind into exact permit identity, and still allows only one profile-wide fence. Kind-specific cleanup adopt/issue/absence/release/complete APIs now preserve existing retirement callers; pressure methods reject manual fences and cleanup methods reject pressure fences before mutation. A disconnected permit runtime now acquires cleanup fences, revalidates under them, releases drifted unissued fences, returns already-issued without replay, and retains `commit-ready` until an injected durable commit succeeds. `threads` now exposes an exact inactive-binding cleanup commit that refuses stale/protected snapshots, atomically removes one binding, and treats fence-protected absence as commit-unknown retry success. Commit composition removes the binding first, then confirms the work-set; failure retains `commit-ready`. A hidden coordinator now validates canonical review identity, resolves full bindings, records the sole permit before one injected delete call, commits binding then work-set, and completes the fence. Fake-port regressions prove successful completion, commit-ready recovery without a second delete, and permanent no-replay after ambiguous delete. A typed Settings-port adapter now exposes this coordinator only when explicitly composed; Settings reports deleted, outcome-unknown, and blocked counts. Fake-port tests exercise the full callback lifecycle while production composition still omits `cleanInactiveThreads`. Settings-port recovery now adopts only an exact retained cleanup fence when an injected authority proof permits takeover; a live/unverifiable predecessor remains outcome-unknown. A proven successor preserves phase, resumes `commit-ready`, completes binding/work-set commit, and never repeats deletion. The retained candidate is now sufficient exact commit evidence: `threads` compares its cwd/workspace/instance/global-slot/binding/target/inactivity/update identity before removal and accepts fence-protected absence on retry. `commit-ready` recovery no longer needs the deleted full binding or calls its resolver. Cross-process worker races now prove two stale `prepared` contenders cause exactly one fake transport deletion. The work-set permit CAS is authoritative: a loser cannot delete after its permit record is rejected, and a redundant fence over an already-deleted entry settles without transport replay. Work-set publication fault hooks now prove both pre-rename failure and lost post-rename acknowledgement: `commit-ready` survives, durable `deleted` is reconciled, the redundant fence completes, and transport remains one-shot. Fence acquisition authority-change races return blocked rather than escaping the Settings callback. Binding-snapshot fault tests now cover the existing synchronous commit fence: pre-rename ownership loss reloads and restores the exact binding for `commit-ready` retry, while a thrown post-rename acknowledgement reloads durable absence and reports success. Together with work-set prefixes, every local binding/work-set/fence commit order now avoids transport replay. Focused security/recovery review found and closed a profile-composition wedge: candidate/work-set profile must equal the runtime profile before fence acquisition, retained fences include the same profile in exact recovery, and adoption captures one stable successor owner snapshot. Cross-profile input now blocks before revalidation or ledger mutation. Local mechanics are approved with notes. The optional Settings port now returns redacted operator recovery classes (`commit-ready`, `deletion-outcome-unknown`, `authority-blocked`) derived from exact retained fence authority; no target, path, token, or transport detail is exposed. Production remains gated on disabled composition and authorized live acceptance. Review admission must release before cleanup-fence acquisition; under that fence, revalidate exact full binding/protection, issue the sole permit, record it in the work-set, call delete once, confirm absence, commit binding/work-set, then complete the fence. Admit only exact bindings with durable inactivity evidence, matching profile/slot/target/generation, no live or unverifiable owner, and no accepted/active work, provisioning, handoff, or competing cleanup. Revalidate immediately before server-side `deleteForumTopic`; retain outcome-unknown attempts without replay, and never infer eligibility from age, silence, delayed heartbeat, or client cache state. Bot API deletion may converge clients but cannot prove mobile/desktop tab synchronization.
- [ ] `Environment-backed bot tokens` (`live-acceptance-gated`): Each profile stores an exact `$ENV_VAR` or `${ENV_VAR}` reference in `telegram.json` instead of copying the resolved secret. The config store resolves references only at validation/activation boundaries, including pairing identity hashing and workspace admission keys, while persistence keeps the reference; `/telegram-setup` prefills the first supported alias, validates the resolved value, and persists the alias; literal tokens remain compatible; unresolved or malformed references fail closed with a redacted named-variable diagnostic in setup, connect, locked-polling start, and status. Tests cover default and named profiles, reload/persistence, resolved pairing admission, setup prefill/validation/diagnostic, and status rendering. Remaining: on the live bridge, run `/telegram-setup` with no stored token and `TELEGRAM_BOT_TOKEN` set and confirm `telegram.json` stores `$TELEGRAM_BOT_TOKEN`; then unset the variable and confirm setup and `/telegram-status` name the variable without exposing a value; finally switch a named profile to an env reference. Operator-authorized disposable checks only.
- [ ] [`Inference bypass Generative Apps`](./docs/generative-apps.md): Let the agent install and bind one managed JavaScript app owner for a generated-prompt prefix so deterministic controls can bypass model inference without creating another button grammar.
  - [ ] Harden the implemented `telegram_bind` installation/invocation kernel with removal operations, stronger cross-process replacement recovery, and bounded diagnostics while preserving lifecycle cancellation, worker-isolated methods, explicit staged replacement, canonical `<agent-dir>/genapps/<app>/<app>.mjs` identity, mandatory named `init`, no manifest/package metadata, non-symlink roots/sources, and fail-closed silent replacement.
  - [ ] Harden the implemented pre-queue `app::method` / strict-JSON bound-action route with revision capture for agent-mediated initial surfaces, profile/target authority, follower transport evidence, voice output delivery, and commit-unknown diagnostics while preserving generation-plus-revision stale-click rejection, fail-closed malformed/absent methods, ordinary model prompts, and native single-colon callbacks.
  - [ ] Harden the implemented cross-process transition lock, dead-owner recovery, expected-generation/revision comparison, repaired partial-tail/current-state recovery, transactional `init` reset, and output-only methods with process-birth proof, bounded lock diagnostics, more interruption points, and explicit commit-unknown evidence.
  - [ ] Complete the capability-owned Music Player adapter evidence beyond the successful real `ffplay` singleton install and no-model-turn bound `next`, `pause`, resume/`play`, and terminal `stop` Controls: exercise generated relative-volume controls over arbitrary absolute Actor percentages, `toggle`, `previous`, `status`, compatible singleton reuse, checkpoint restart, missing/terminal Run, unavailable backend, process timeout/cancellation/stream bounds, and redacted errors while keeping actor reality authoritative and rejecting generic remote-terminal methods.
  - [ ] Extend the implemented new-message default plus opt-in `viewMode: "edit"` bound-action update into optional output-only `refresh` scheduling from `refreshAfterMs`, clamped to at least two seconds and serialized after prior completion; retain one latest logical view handle per app/profile/target, skip unchanged frame digests, honor Telegram retry/backoff, cancel on lifecycle replacement, stop and forget the handle on known deletion or message-not-found, and never recreate a deleted live view without a fresh user action.
  - [ ] Cover CML and JSON equivalence, both mutually exclusive Tool shapes, direct agent-authored app discovery, install/copy and existing-app `init`, scalar/object/no-argument methods, agent-side diagnostic invocation, bounded CLI adaptation, refresh coalescing/rate limits/backoff/deletion, identity/path traversal, duplicate/overlapping prefixes, state recovery, handler failure, stale clicks, session replacement, follower routing, and the invariant that bound actions perform no model turn. `tests/generative-apps.test.ts` now covers scalar/object/no-argument argument shapes, throwing-method failure containment (state and journal untouched), and bounded argument/output/state/module limits before durable mutation; the remaining items stay open.
