diff --git a/BOOK_PLAN.md b/BOOK_PLAN.md
index d69e67c..60dc697 100644
--- a/BOOK_PLAN.md
+++ b/BOOK_PLAN.md
@@ -1,718 +1,196 @@
# T3 Code Decoded — editorial and implementation plan
-This plan is pinned to T3 Code commit
-`fa219001dc2f14cfd9c7774c2c03c153359144be` (2026-08-23). It is both an
-editorial contract and a build checklist: every chapter must explain one coherent
-slice of the system, show the relevant runtime boundaries, and let the reader jump
-to the exact source revision that supports the explanation.
+This file is the editorial contract for the product guide and technical field guide.
+The immutable upstream revision, capture date, and inventory live in
+`sources/t3code.lock.json`.
-## 1. Outcome
+## Outcome
-The finished book should let a technical reader answer five questions without
-reading the monorepo in repository order:
+The book serves two readers without splitting into separate sites.
-1. What does T3 Code own, and what remains owned by Codex, Claude, Cursor, Grok,
- OpenCode, Git, the shell, or the operating system?
-2. How does one user intent travel from a client, through authorization and the
- durable domain kernel, into a provider process, then return as ordered UI state?
-3. How do local web, hosted web, desktop, and mobile share semantics while keeping
- different process, storage, rendering, and native-integration designs?
-4. How do pairing, remote access, updates, packaging, telemetry, and release
- channels work beyond the happy path?
-5. Which behaviors are guaranteed, best effort, latent, transitional, or explicit
- future work, and where do the important failure and retention seams remain?
+The product reader should be able to install T3 Code, choose a client and connection
+path, configure a provider, organize parallel work, give an agent useful context,
+supervise it locally or remotely, inspect files and terminals, use previews and
+devices, review changes, understand usage, update safely, and recover from common
+failures.
-The book is explanatory, not a replacement for the upstream user guide. It covers
-implementation, invariants, failure handling, and design consequences. It does not
-invent a product roadmap or present repository clues as commitments.
+The technical reader should be able to trace those behaviors through typed contracts,
+the environment server, durable orchestration, provider adapters, work services,
+client convergence, remote access, native integrations, packaging, and operations.
-## 2. Source and claim contract
+## Source and claim contract
-### 2.1 Four claim classes
+Every non-trivial technical claim uses one of four labels:
-Every non-trivial claim belongs to exactly one class:
-
-| Label | Meaning | Required evidence |
+| Label | Meaning | Evidence |
| --- | --- | --- |
-| **Verified behavior** | Executable behavior at the pinned revision | Code, test, schema, migration, or workflow |
-| **Documented intent** | A maintainer's explanation or operating rule | Pinned internal/user/operations document |
-| **Inference** | A design consequence derived from several sources | All inputs cited; inference named explicitly |
-| **Future / proposed** | An explicit unshipped idea or limitation | Pinned future-work text or issue; never phrased as shipped |
-
-Release notes and the public docs may establish product wording, but code wins when
-describing current mechanics. A discrepancy is shown, not silently reconciled.
-
-### 2.2 Source lock
-
-- Canonical checkout: the path in `T3CODE_SOURCE_DIR`, or the sibling `../t3code`
-- Full source SHA: stored in `sources/t3code.lock.json`
-- Exact excerpts: declared in `sources/excerpts.manifest.json`
-- Generated excerpt text, line numbers, checksums, and permalinks:
- `src/generated/excerpts.json`
-- Refresh: `npm run source:sync`
-- Drift check: `npm run source:check`
-
-No prose author copies a source block by hand. The synchronizer extracts it from the
-pinned checkout; the validator rejects unknown IDs, changed checksums, invalid
-ranges, and a checkout whose SHA no longer matches the lock.
-
-### 2.3 Status vocabulary
-
-- `draft`: narrative or visual is incomplete.
-- `source-checked`: material claims have a pinned source trail and exact excerpts
- have passed validation.
-- `verified`: source checks, production build, interaction checks, links, and an
- editorial review all pass.
-
-### 2.4 Roadmap vocabulary
-
-The book keeps these categories separate:
-
-- **Shipped at the source lock** — present in executable code.
-- **Latent capability** — builder or contract supports it, but current distribution
- or UI does not ship it.
-- **Transition / compatibility path** — old and new behavior coexist.
-- **Explicit future work** — upstream docs say it is planned or desired.
-- **Community idea** — discussed externally but not committed by maintainers.
-
-There is no milestone-derived roadmap in the pinned repository. The known explicit
-future items in `docs/internals/remote.md` are handled as future work, while the
-implemented OAuth callback path is called out as a stale-document discrepancy.
-
-## 3. Reader routes
+| Verified behavior | Executable behavior in the source lock | Code, test, schema, migration, or workflow |
+| Documented intent | A maintainer's explanation or operating rule | User, internal, or operations documentation |
+| Inference | A design consequence derived from cited inputs | Every input cited; interpretation named |
+| Future / proposed | Explicitly unshipped or recommended work | Clearly separated from supported behavior |
-The canonical route follows runtime causality:
+Exact excerpts are generated from the locked Git object. Authors edit ranges in
+`sources/excerpts.manifest.json`, run `npm run source:sync`, and commit the generated
+checksums in `src/generated/excerpts.json`. Broader evidence lives in
+`sources/references.manifest.json`. Source validation rejects a checkout mismatch,
+missing object, invalid range, stale generated excerpt, or unknown citation id.
-```text
-ownership → vocabulary → boot/auth → command/event kernel → provider boundary
-→ work lifecycle → client projection → remote path → distribution/operations
-```
+Product chapters use plain language, task paths, decision guidance, and immutable
+links to the applicable user documentation. They do not expose contributor tooling
+or implementation detail unless it changes a user decision.
-Alternative routes are surfaced in the reading guide:
-
-- **System designer:** 1, 4, 7, 9–15, 20, 26, 29, 34, 36, 40.
-- **Provider integrator:** 1, 7, 9–20, 23–27, 39.
-- **Client engineer:** 2, 7–8, 11, 23–24, 29–36, 39.
-- **Release/operator:** 4–8, 13, 34–40.
-- **Architecture auditor:** 1, 3, 9–15, 20, 23–26, 29, 36, 39–40.
-
-The front matter includes a complete spatial architecture map and a step-through
-request trace, so readers have both a map and a causal story before Chapter 1.
-
-## 4. Chapter specification
-
-Each chapter entry below specifies the question it must settle, its primary source
-anchors, and the visual or interactive artifact that makes the mechanism testable.
-All paths are relative to the pinned T3 Code checkout.
+## Reading order
### Start here
-#### Cover
-
-- **Purpose:** establish the edition, source revision, and independent, public,
- source-locked nature.
-- **Artifact:** responsive use of the supplied cover, with an accessible text
- alternative and no derivative asset generation.
-
-#### How to read a changing system
-
-- **Question:** how can a reader distinguish a fact, an interpretation, and a plan?
-- **Sources:** source-lock and generated-excerpt pipeline in this repository.
-- **Visual:** evidence ladder and freshness model.
-
-#### Contents and learning route
-
-- **Question:** why is the book ordered by causality instead of folders?
-- **Artifact:** part roadmap plus role-specific routes.
-
-#### The complete system map
-
-- **Question:** where do clients, trust, domain logic, work services, adapters, and
- provider processes live?
-- **Sources:** `docs/internals/overview.md`, `apps/server/src/server.ts`,
- `packages/contracts/src/rpc.ts`, `packages/client-runtime/src/connection`.
-- **Visual:** interactive ownership bands and intent/state flow.
-
-#### One request, every boundary
-
-- **Question:** what happens between pressing Send and seeing a settled answer?
-- **Sources:** orchestration contracts, normalizer, engine, reactors, provider
- service, projectors, client thread reducer, checkpoint settlement.
-- **Artifacts:** an interactive phase lab and a full sequence diagram.
-
-### Part I — Boundaries and vocabulary
-
-#### 1. Control surface, not agent brain
-
-- **Settles:** T3 Code owns orchestration, durable product state, work surfaces, and
- transport; each provider still owns its native reasoning/context engine.
-- **Sources:** `docs/internals/overview.md:5-28`, `ProviderAdapter.ts`, provider
- drivers, orchestration contracts.
-- **Visual:** responsibility matrix for T3, provider, OS, Git, and client.
-
-#### 2. Environment, project, thread, turn, session
-
-- **Settles:** the vocabulary and cardinalities that later chapters assume.
-- **Sources:** `packages/contracts/src/environment.ts`, `project.ts`,
- `orchestration.ts`, server projection schemas.
-- **Visual/lab:** clickable entity relationship map; lifecycle vocabulary quiz.
-
-#### 3. Repository and dependency atlas
-
-- **Settles:** what each app/package/infra/native directory builds and which edges
- are runtime, build-time, protocol, generated, or deployment-only.
-- **Sources:** root/package manifests, workspace graph, Vite/Electron/Expo/Astro
- configurations, native crates and packages.
-- **Visual:** filterable monorepo graph and a reproducible production/test inventory by area.
-
-#### 4. Runtime topologies and technology placement
-
-- **Settles:** the five delivery shapes: local CLI web, hosted web, Electron,
- React Native, and marketing; why Effect, SQLite, React, Expo, Astro, Electron,
- native Ghostty, and typed contracts appear where they do. Unrecorded rationale is
- labeled as inference; code proves placement and consequences, not author intent.
-- **Sources:** each app entrypoint/config, server composition, runtime manifests.
-- **Visual:** topology switcher showing process and trust boundaries per surface.
-
-### Part II — Boot and connect
-
-#### 5. The `npx t3` bootstrap path
-
-- **Settles:** CLI argument/config resolution, server startup, address selection,
- browser/local client behavior, and bundled web assets.
-- **Sources:** `apps/server/src/bin.ts`, `apps/server/src/cli/config.ts`,
- `apps/server/src/cli/server.ts`, `apps/server/src/config.ts`,
- `apps/server/vite.config.ts`, and `apps/server/package.json`.
-- **Visual:** CLI bootstrap swimlane; package-content exploder.
-
-#### 6. Server composition and execution boundary
-
-- **Settles:** how Effect layers assemble HTTP, RPC, auth, orchestration,
- providers, VCS, terminal, files, assets, usage, relay, and telemetry services.
-- **Sources:** `apps/server/src/server.ts`, runtime-startup files, layer constructors.
-- **Visual:** layer-construction DAG with startup and shutdown ownership.
-
-#### 7. Effect RPC, subscriptions, and wire contracts
-
-- **Settles:** request/response versus subscription semantics, schemas,
- serialization, errors, capabilities, snapshots, and cursors.
-- **Sources:** `packages/contracts/src/rpc.ts`, domain contract files,
- server WebSocket router, `packages/client-runtime/src/rpc`.
-- **Lab:** inspect a command, acknowledgement, snapshot, and event frame.
-
-#### 8. Pairing, scopes, credentials, and WebSocket upgrade
-
-- **Settles:** environment auth policy, browser/bearer/DPoP credentials, pairing
- grants, session/ticket lifetimes, per-method scopes, secret handling, and the
- authenticated WebSocket upgrade. Target resolution and reconnect stay in Chapter 29.
-- **Sources:** `docs/internals/environment-auth.md`, server auth/session/pairing/
- secret-store layers, HTTP credential exchange, and RPC scope enforcement.
-- **Lab:** credential, scope, TTL, one-use, persistence, and replay-resistance ladder.
-
-### Part III — Transactional domain core and post-commit delivery
-
-#### 9. Commands and invariants
-
-- **Settles:** external/internal commands, normalization, authorization, the
- decider's persistence- and provider-I/O-free boundary despite clock/UUID Effect
- dependencies, aggregate validation, the atomic event batch for an existing turn,
- and multi-step bootstrap with compensating cleanup outside that transaction.
-- **Sources:** orchestration contracts, `Normalizer.ts`, deciders, aggregate tests.
-- **Lab:** choose valid/invalid command transitions and inspect emitted events.
-
-#### 10. Events, receipts, and idempotency
-
-- **Settles:** event envelope, command receipt, retry behavior, event publication,
- and why acknowledgement does not mean provider work is complete.
-- **Sources:** `OrchestrationEngine.ts`, persistence schemas, command receipt tests.
-- **Visual:** transaction boundary and duplicate-command timeline.
-
-#### 11. Projection tables and read models
-
-- **Settles:** how events update shell/thread/activity/plan/checkpoint/runtime views,
- then become HTTP snapshots and live subscriptions.
-- **Sources:** projector registry/implementations, read stores, snapshot handlers.
-- **Lab:** fold the same event stream into several projections.
-
-#### 12. Post-commit reactors: serialized handling without durable delivery
-
-- **Settles:** intent events trigger side effects only after commit, internal results
- re-enter the command queue, workers serialize handling, scopes interrupt work on
- shutdown, and the hot stream does not durably replay pending side effects.
-- **Sources:** reactor layers, drainable worker utilities, engine dispatch tests.
-- **Visual:** commit/publish/react/ingest timing diagram with crash points; contrast
- the non-durable server bridge with mobile's durable client outbox.
-
-#### 13. SQLite, files, settings, secrets, migrations, and recovery
-
-- **Settles:** SQLite schema/WAL/migrations, settings JSON, secret files,
- attachments/logs/terminal history, hidden Git refs, tombstones/retention, and
- startup reconstruction. Provider adoption semantics wait for Chapter 15.
-- **Sources:** persistence package, migrations, recovery services and tests.
-- **Lab:** crash at selected phases and show the recoverable state.
-
-### Part IV — Five harnesses, one product model
-
-#### 14. The `ProviderAdapter` contract
-
-- **Settles:** discovery, sessions, turns, steer/interrupt, approval/input, modes,
- canonical event streams, errors, and capabilities.
-- **Sources:** `ProviderAdapter.ts`, provider contracts, adapter conformance tests.
-- **Visual:** normalized boundary with required and optional capability lanes.
-
-#### 15. Drivers, instances, registries, and multi-instance routing
-
-- **Settles:** provider identity versus binary/driver/instance/native account/session,
- discovery and health, registry lookup, managed processes, and recovery.
-- **Includes:** legacy provider settings merged into explicit opaque instance configs
- (explicit wins), secret-backed/redacted environment values, live child-scope
- replacement, unavailable shadow entries, and the plaintext OpenCode password exception.
-- **Sources:** provider registry/instance layers, driver discovery, ProviderService.
-- **Lab:** route several threads across installed providers and accounts.
-
-#### 16. Codex through app-server JSON-RPC
-
-- **Settles:** app-server process lifecycle, initialize/account/model/config,
- thread resume, turn calls, approvals, streaming notifications, and normalization.
-- **Sources:** Codex driver and `packages/effect-codex-app-server`.
-- **Visual:** native JSON-RPC to canonical event mapping.
-
-#### 17. Claude through the Agent SDK
-
-- **Settles:** SDK session lifecycle, permissions, models/modes, skills/commands,
- resume metadata, tool events, and result handling.
-- **Sources:** Claude driver, Claude skills scanner, adapter tests.
-- **Visual:** Claude SDK event-to-product mapping and skill precedence.
-
-#### 18. Cursor and Grok through ACP
-
-- **Settles:** shared ACP client/transport, provider-specific launch/configuration,
- session calls, capabilities, request forwarding, and notification mapping.
-- **Sources:** Cursor/Grok drivers and `packages/effect-acp`.
-- **Visual:** shared ACP spine with provider-specific forks.
-
-#### 19. OpenCode and the normalization matrix
-
-- **Settles:** OpenCode transport/session path and a five-provider comparison of
- resume, models, plans, approvals, input, commands, skills, subagents, usage, and
- failure semantics.
-- **Sources:** OpenCode driver plus all adapter conformance fixtures.
-- **Lab:** capability matrix that explains UI enablement and fallback.
-
-#### 20. Two usage systems: live context telemetry and transcript accounting
-
-- **Settles two separate pipelines:** (1) live per-thread token/context-window
- telemetry normalized from provider runtime events; and (2) the historical Usage
- page, which scans provider-owned transcript files independently of T3's
- orchestration projections. The chapter never treats one as the source of the other.
-- **Provider coverage:** the historical scanner supports Codex and Claude at this
- revision; Cursor, Grok, and OpenCode contribute no Usage-page transcript source.
- Live context telemetry is likewise emitted only by the Codex and Claude adapters
- at this revision; the generic runtime event contract can represent it for a future
- adapter, but Cursor, Grok, and OpenCode do not currently emit it. The five-adapter
- matrix from Chapter 19 makes that implementation gap explicit.
-- **Scanner pipeline:** provider home resolution → transcript discovery with mtime
- window slack → provider-specific parse → within-file and cross-file de-duplication
- → canonical timestamped records → `(day, hour?, provider, model)` aggregate
- buckets → session counts and source diagnostics → persisted
- `(path, size, mtime, provider)` scan cache. The contract can represent partial and
- failed scans, while the current implementation predominantly reports `ok` or
- `missing` and leaves malformed-record accounting at zero.
-- **Accounting rules:** IANA-time-zone day buckets and an exact rolling 24-hour mode;
- cached input and cache creation remain disjoint from uncached input; reasoning is a
- subset of output and is never added twice; cost is provider-reported, LiteLLM
- model-priced, or explicitly unpriced; cache savings are estimated alongside cost;
- API-equivalent cost is not subscription billing.
-- **Cross-environment composition:** raw transcripts never cross the wire. Each
- environment returns typed aggregate buckets and a physical-source fingerprint.
- Web and mobile use the shared merge to claim duplicate transcript directories once,
- exclude incompatible contract versions, count distinct sessions without summing
- per-bucket duplicates, and expose partial/failed coverage honestly.
-- **Sources:** `packages/contracts/src/usage.ts`, `apps/server/src/usage/UsageService.ts`,
- `usageTranscriptReader.ts`, `usageTranscripts.ts`, `usageAggregation.ts`,
- `usagePricing.ts`, `usageScanCache.ts`, `packages/shared/src/usageMerge.ts`, the
- usage RPC, web/mobile usage state and presentation, and their tests.
-- **Third usage path:** Codex and Claude can also report per-task/subagent usage for
- the Agents surface. It is neither the context meter nor historical cost input and
- is deferred to Chapter 25 with provider tasks.
-- **Visual:** two-lane topology separating live thread telemetry from transcript
- accounting all the way through their distinct product presentations; there is no
- joining or summation arrow.
-- **Lab:** usage-accounting workbench. Choose provider records, duplicates, session
- boundaries, cache categories, model-rate availability, time zone, and two
- environments that may share a source fingerprint; step through parse, normalize,
- deduplicate, bucket, price, summarize, and merge while every total shows its formula.
-
-### Part V — The work lifecycle
-
-#### 21. Project discovery and `t3.json`
-
-- **Settles:** roots, discovery, project identity, configuration precedence,
- explicit registration entry points, checked-in-script import boundaries, setup
- commands, environment labels, and project projection.
-- **Sources:** project contracts/services, config loader, discovery tests and docs.
-- **Visual:** filesystem decision lab, checked-in-action import flow, and project
- identity projection.
-
-#### 22. Current checkout versus isolated worktrees
-
-- **Settles:** workspace kinds, branch/base selection, creation/setup/cleanup,
- Git invariants, normal thread-deletion versus optional worktree cleanup, and
- failure recovery.
-- **Sources:** workspace/worktree services, VCS contracts, orchestration decider.
-- **Lab:** choose a task topology and inspect checkout/branch consequences.
-
-#### 23. Start, stream, steer, interrupt, settle
-
-- **Settles:** complete thread/turn state machine and provider runtime states,
- including buffering, steering, interruption, retries, compaction, and completion.
-- **Sources:** orchestration contract/decider/reactors, ProviderService, reducers.
-- **Lab:** event timeline with illustrative teaching controls at each state; it is
- explicitly not presented as the server's complete legality matrix.
-
-#### 24. Permission modes, approvals, and structured input
-
-- **Settles:** approval-required, auto-accept-edits, auto, full-access; how provider
- prompts become canonical pending requests and how clients resolve them.
-- **Sources:** runtime mode contracts, provider adapters, approval/input reactors,
- web/mobile components.
-- **Visual:** security-responsibility matrix and multi-provider mapping.
-
-#### 25. Threads, provider tasks, plans, skills, and subagents
-
-- **Settles:** threads as durable work items; provider-emitted tasks/subagents as
- normalized durable activity; ephemeral liveness and live plan progress; lifecycle/
- pin/snooze overlays; per-task token/tool/duration rollups currently normalized by
- Codex and Claude; and why this is not a durable cross-provider scheduler. Task
- usage is not fed into either live context telemetry or Chapter 20's historical
- transcript accounting.
-- **Sources:** orchestration/settings contracts, provider skills, work-log logic.
-- **Lab:** quiet work-log projector for web, Agents surface, and mobile.
-
-#### 26. Who owns context, compaction, and memory
-
-- **Settles:** provider-owned prompt context and compaction versus T3-owned thread
- history, resume cursor, and context-window telemetry, with client drafts/outbox
- deferred to Chapter 33. It explicitly documents that no universal T3 long-term
- memory subsystem exists at this revision and cross-links the separate historical
- accounting pipeline in Chapter 20 instead of conflating usage with memory.
-- **Sources:** provider sessions, runtime context-window events, thread state/reducer,
- provider compaction paths, and client cache ownership.
-- **Lab:** ownership and restart ledger covering provider context, T3 projections,
- live telemetry, client cache, drafts, and provider-session recovery.
-
-#### 27. Hidden-ref checkpoints, diffs, and revert
-
-- **Settles:** before/after turn checkpoints, hidden Git refs, changed-file summary,
- turn/branch/working-tree diffs, destructive restore semantics, `ready`/`missing`/
- `error`, provider-specific rollback, and partial failure. Client history-epoch
- implementation is deferred to Chapter 29.
-- **Sources:** checkpoint service/reactor/contracts, diff state, web/mobile review.
-- **Lab:** Git graph before a turn, after a turn, and after revert.
-
-#### 28. Terminals, files, previews, MCP, VCS, and pull requests
-
-- **Settles:** the workbench services surrounding chat, their authorization and
- streaming models, signed assets, desktop-only preview, and surface parity.
-- **Sources:** terminal/files/assets/MCP/VCS/PR contracts and services; Ghostty
- implementations; desktop preview APIs.
-- **Visual:** capability matrix plus terminal and signed-asset data paths.
-
-### Part VI — Client architectures: shared semantics, platform edges
-
-#### 29. The shared client runtime
-
-- **Settles:** Primary/Bearer/Relay/SSH target taxonomy, connection registry/resolver/
- supervisor/one-attempt session, Effect Atom registry,
- shell/thread factories, snapshot/cursor algorithms, cache ownership, and retry.
-- **Sources:** `packages/client-runtime/README.md` and `src/connection`, `src/rpc`,
- `src/state`.
-- **Lab:** snapshot, duplicate, gap, reconnect, revert, and older-page races.
-
-#### 30. Web routes, state, and rendering performance
-
-- **Settles:** hosted/local/Electron runtime choice, router history, providers,
- atoms, virtualization, row-local updates, trace export, and browser terminal.
-- **Sources:** `apps/web/src/main.tsx`, `AppRoot.tsx`, route tree, atom registry,
- `MessagesTimeline.tsx`, `ChatView.tsx`.
-- **Visual:** React composition and hot-path rendering diagram.
-
-#### 31. Composer, work log, review, and sidebar lifecycle
-
-- **Settles:** message composition/attachments/commands/skills, optimistic states,
- quiet timeline and Agents surface, review modes, thread ordering and pinning.
-- **Sources:** web composer, session logic, diff panel, thread sort/sidebar.
-- **Lab:** same canonical thread projected into focused product surfaces.
-
-#### 32. Desktop: Electron, IPC, server ownership, browser, and SSH
-
-- **Settles:** main/preload/renderer boundary, the host-local primary, Windows
- WSL-only versus dual-instance modes, backend-pool ownership, fd 3/4/5 bootstrap
- and telemetry, exposure, the separate SSH gateway, preview webviews, menus, and
- updates.
-- **Sources:** desktop main/app/preload/backend/preview/SSH/update modules.
-- **Visual/lab:** mutually exclusive primary choices, optional WSL secondary,
- separate SSH authority, and the boot/readiness/shutdown lifecycle.
-
-#### 33. Mobile: persistence, outbox, sharing, and native systems
-
-- **Settles:** Expo app composition, native navigation/feed choices, durable drafts
- and intent outbox, share reservation, native terminal/diff/keyboards/widgets,
- iOS notification capability, and OTA coordination.
-- **Sources:** app config, connection runtime, outbox, ThreadFeed, native modules,
- awareness, updates.
-- **Lab:** offline command-outbox state machine and guarded foreground/background
- OTA update handoff.
-
-### Part VII — Reach and ship
-
-#### 34. Primary, paired bearer, Tailscale endpoints, and SSH access
-
-- **Settles:** launch transport versus access transport, bind/exposure policy,
- one-time pairing, bearer registration, Tailscale endpoint provisioning, and
- desktop SSH gateway behavior.
-- **Sources:** remote/environment-auth docs, Tailscale/SSH packages, resolver,
- desktop exposure and gateway code.
-- **Visual:** primary/direct, paired bearer over LAN or Tailscale, and desktop-managed
- SSH sequences. Tailscale is an endpoint provider, not a connection target kind.
-
-#### 35. T3 Connect: OAuth, DPoP, relay, and tunnel
-
-- **Settles:** Clerk session, device key, DPoP, environment registration, relay
- broker, tunnel provisioning, OAuth callback path, and what traffic does *not*
- traverse the relay.
-- **Sources:** `docs/internals/t3-connect.md`, relay infra, hosted routes, remote auth.
-- **Visual/lab:** credential ladder and launch/data-plane toggle.
-
-#### 36. Reconnect, multi-environment state, notifications, and version skew
-
-- **Settles:** environment catalog, generation leases, shell/thread reconciliation,
- background demand, multi-environment merge, awareness relay/APNs, and capability/
- exact-version recovery.
-- **Sources:** client supervisor/state, background contracts/policy, relay awareness,
- client version skew and self-update state.
-- **Labs:** connection supervisor and notification throttling/fallback.
-
-#### 37. Distribution artifacts: CLI, hosted app, desktop, mobile, marketing, and AUR
-
-- **Settles:** npm CLI plus copied web build, hosted static web, Electron artifact
- matrix/signing/native staging, mobile stores, marketing, AUR, and the difference
- between builder support and artifacts actually shipped.
-- **Sources:** build configs/scripts, package manifests, release workflow, marketing
- download resolver, AUR scripts.
-- **Visual:** artifact factory from source tree to installable products.
-
-#### 38. Release graph, three update systems, and observability/privacy
-
-- **Settles in three explicit acts:** (1) release DAG, two version domains, and the
- npm-before-clients invariant; (2) Electron updater, managed-server exact-version
- preflight, and EAS fingerprint/OTA as three independent state machines; (3)
- PostHog product analytics, local/OTLP tracing, browser trace ingestion, and local
- desktop resource telemetry with precise identities, destinations, and controls.
-- **Sources:** release/mobile workflows, updater state machines, self-update,
- analytics/observability/resource telemetry.
-- **Labs:** release-channel resolver, OTA eligibility grid, update handshake.
-
-### Part VIII — Synthesis
-
-#### 39. Six complete traces
-
-- **Traces:** local first turn; relay-connected mobile turn; approval round-trip;
- offline mobile task drain; checkpoint diff/revert; stable release and exact-version
- update.
-- **Artifact:** synchronized swimlanes whose steps link back to the owning chapters
- and exact sources.
-
-#### 40. Decisions, trade-offs, limitations, and an honest roadmap
-
-- **Settles:** why server authority, the transactional event core, hot post-commit
- reactors, snapshot + cursor, adapters, one reconnect owner, durable mobile intent,
- exact-version updates, and scope-driven background work are valuable—and what
- complexity each choice creates.
-- **Includes:** verified discrepancies, platform asymmetries, latent artifact targets,
- transitional plan UI, no universal memory layer, and explicitly documented future
- remote work. It also covers tombstone deletion/selected cleanup, retained event/
- binding/worktree/checkpoint state, attachment cleanup outside the projection
- transaction, the replay-marker retention inference, and the server reactor crash window.
-- **Visual:** decision ledger with pressure, choice, benefit, cost, alternative, and
- reversal trigger.
-
-## 5. Visual system
-
-Visuals use a consistent grammar rather than decorative diagrams:
-
-- navy = client/product surface;
-- blue = typed transport or contract;
-- amber = durable intent/state;
-- green = post-commit side effect or external execution;
-- violet = provider-native protocol;
-- red = failure, trust, or destructive boundary;
-- dashed edge = asynchronous, retryable, or eventual;
-- solid edge = synchronous call or transactional relation.
-
-Every figure has a title, numbered caption, text equivalent, source trail, keyboard
-operation where interactive, and a static print state. Mermaid is reserved for
-sequences/flows whose source is clearer as text. Bespoke Astro components handle
-state machines, comparisons, timelines, and simulations.
-
-## 6. Interaction inventory
-
-The final book contains, at minimum:
-
-1. ownership layer map;
-2. end-to-end request trace;
-3. entity/cardinality explorer;
-4. monorepo graph filters;
-5. runtime topology switcher;
-6. connection supervisor state machine;
-7. RPC frame inspector;
-8. command/decider lab;
-9. projection fold lab;
-10. crash/recovery lab;
-11. provider capability matrix;
-12. work lifecycle controller;
-13. quiet work-log projector;
-14. usage accounting and cross-environment de-duplication workbench;
-15. context/compaction/memory ownership ledger;
-16. checkpoint Git graph;
-17. cursor/reconnect race lab;
-18. mobile outbox lab;
-19. notification delivery lab;
-20. artifact/release explorer;
-21. OTA/update eligibility lab;
-22. synchronized six-trace ownership and failure-boundary stepper;
-23. decision ledger;
-24. background demand/power-policy lab;
-25. three-updater failure comparison;
-26. telemetry identity/destination/privacy flow.
-
-An interaction is included only when changing an input reveals a state transition,
-invariant, or trade-off that static prose would obscure.
-
-## 7. Book engine
-
-The old `codex-decoded` engine supplied the useful visual precedent: source cards,
-architecture diagrams, and linear chapter navigation. This edition replaces its
-eager Vite/hash/HTML-string architecture with:
-
-- Astro static routes and typed MDX content;
-- one content collection as the navigation/search/metadata authority;
-- build-time excerpt extraction and source-lock validation;
-- Pagefind full-text search with development metadata fallback;
-- lazy Mermaid and no framework runtime for ordinary pages;
-- accessible sidebar, keyboard search, theme, heading navigation, previous/next,
- reduced motion, and print styles;
-- responsive source cards with real line numbers, checksums, copy, and immutable
- GitHub permalinks;
-- `BASE_PATH` support for repository-scoped GitHub Pages without changing links.
-
-The target is a content-first static site: JavaScript is paid only for search,
-diagrams, and genuine simulations.
-
-## 8. Authoring waves and review gates
-
-### Wave A — mental model and kernel
-
-- Front matter and Chapters 1–15.
-- Gate: one request can be traced from RPC to committed event, reactor, provider,
- runtime ingestion, projection, and client cursor with no unexplained jump.
-
-### Wave B — providers, usage, and work lifecycle
-
-- Chapters 16–28.
-- Gate: every provider is compared against the actual adapter contract; context,
- memory, task, plan, live token telemetry, historical usage accounting, and
- checkpoint ownership are not conflated.
-
-### Wave C — clients and remote access
-
-- Chapters 29–36.
-- Gate: every surface difference is explicit; shared runtime algorithms and
- presentation-specific algorithms are both explained.
-
-### Wave D — distribution and synthesis
-
-- Chapters 37–40 and six end-to-end traces.
-- Gate: current stable, nightly, builder-only, mobile, and managed-server paths are
- distinct; roadmap statements are evidence-classified.
-
-### Review loop for every wave
-
-1. Source audit against the pinned checkout.
-2. Claim/excerpt/source-trail validation.
-3. Cross-chapter vocabulary and forward-reference review.
-4. Diagram and simulator invariant review.
-5. Production build, search index, internal links, and responsive static checks.
-6. Editorial pass for causal order, repetition, and unstated assumptions.
-7. Local commit. Merge authored waves through pull requests once the public remote
- and branch protection are active.
-
-## 9. Automated quality gates
-
-Required local commands:
-
-```sh
-npm run source:check
-npm test
-npm run build
-```
-
-The validation suite will grow to enforce:
-
-- unique slugs and chapter order;
-- a complete 1–40 chapter table of contents;
-- valid excerpt IDs and source-lock SHA;
-- no source-checked chapter without a source trail;
-- no broken internal route/heading/source permalink;
-- alt text and accessible names for visual/interactive components;
-- all simulations usable by keyboard and meaningful in print;
-- Pagefind indexing every non-cover chapter;
-- bounded client bundles, with Mermaid and labs split by route;
-- zero external analytics or network dependency in the local book.
-
-## 10. Definition of done
-
-The project is complete when all 40 chapters and front matter are present, all are
-`source-checked` or `verified`, every planned flow has either a figure or lab, exact
-source references resolve at the pinned revision, the six synthesis traces agree
-with their detailed chapters, the static build and validation suite pass, and a
-fresh reader can progress from ownership to deployment without requiring knowledge
-that appears later in the book.
-
-## 11. Public repository and GitHub Pages
-
-The publication target is a public GitHub repository named `t3code-decoded` with
-GitHub Pages serving the validated static build. It is owned by the personal
-`BenAlaa` account, not an EasyGenerator organization.
-
-- Default branch: `main` (no parallel `master` branch).
-- Pages source: GitHub Actions artifact from `npm ci`, source validation, tests,
- and `npm run build`.
-- Pull requests: required before any authored book commit reaches `main`; the only
- bootstrap exception is GitHub's generated placeholder commit used to create the
- base branch before protection is enabled.
-- Reviews: at least one approving review; stale approvals dismissed when new
- commits are pushed; latest-push approval and conversation resolution required.
- The owner account `BenAlaa` receives **pull-request-only** bypass so a solo-owned
- PR can merge without self-approval while still leaving a PR and bypass audit
- trail. It receives no routine direct-push exemption.
-- Checks: `Validate and build` and `Conventional changes` must pass; the latter
- enforces the PR title/body and every fine-grained commit subject. Force pushes
- and branch deletion are disabled, and history stays linear through rebase merges.
-- Community files: detailed `README.md`, `CONTRIBUTING.md`, code of conduct,
- security policy, issue forms, pull-request template, and `CODEOWNERS`.
-- Licensing/attribution: distinguish original book prose/site code from short
- MIT-licensed T3 Code excerpts, and state clearly that this is an independent,
- unofficial study guide.
-
-The public repository and Pages pipeline are active. The complete source-validated
-edition is published from protected `main`. New work remains on local or topic
-branches until it is pushed and opened as a pull request, then merges only after
-the required checks and review policy are satisfied. No authored project work is
-pushed directly to `main`; every change keeps its pull-request audit trail.
-
-Commits inside a part remain fine-grained: shared engine capability, individual
-chapter or tightly coupled chapter pair, source manifest change, lab/figure, and
-review correction are separate when they can be understood and reverted alone.
-Pull-request bodies use the repository template and explain outcome, non-goals,
-evidence, interactions, validation, and the review's riskiest assumptions.
+- Cover and source synchronization
+- Reading routes and evidence labels
+- Complete contents
+
+### Part I — Product guide
+
+1. T3 Code as a product
+2. Install and reach a useful first thread
+3. Environments, clients, and connection paths
+4. Organize projects, threads, and worktrees
+5. Compose tasks with the right context
+6. Choose providers, models, accounts, and permissions
+7. The workbench: files, terminals, browser preview, and SnapShots
+8. Source control: checkpoints, pull requests, reviews, and stacks
+9. Remote environments and unattended work
+10. Mobile: supervise agents from anywhere
+11. Device lab: simulators, emulators, and agent-driven testing
+12. Personalize, measure usage, update, and protect privacy
+13. Complete recipes and troubleshooting
+
+Each product chapter must answer four questions: what the capability does, how to
+start, why it helps, and what is easy to misunderstand. The complete guide covers
+web, desktop, iOS, Android, local and remote environments, six providers, parallel
+work, rich context, review, recovery, and device verification.
+
+### Part II — Architecture orientation and boundaries
+
+14. The complete system map
+15. One request, every boundary
+16. Control surface, not agent brain
+17. Environment, project, thread, turn, and session
+18. Repository and dependency atlas
+19. Runtime topologies and technology placement
+
+This part establishes ownership before implementation detail. It includes provider
+control services, agent-session import, device hosts and sessions, review graphs, and
+all client surfaces.
+
+### Part III — Boot and connect
+
+20. The `npx t3` bootstrap path
+21. Server composition, activation, and readiness
+22. HTTP, WebSocket RPC, snapshots, and resume
+23. Pairing, credentials, TTLs, and scopes
+
+This part explains configuration, process ownership, Effect layers, typed methods,
+subscriptions, cursors, version negotiation, pairing, bearer and DPoP credentials,
+and method authorization.
+
+### Part IV — Transactional domain core
+
+24. Commands, invariants, and the boundary of atomicity
+25. Events, receipts, idempotency, and the post-commit gap
+26. Projection tables and read models
+27. Post-commit reactors and the delivery gap
+28. Persistence, reconstruction, and crash recovery
+
+This part keeps the SQLite transaction boundary precise. It distinguishes accepted
+intent from completed provider work, synchronous projections from hot reactors, and
+durable records from files, Git refs, settings, secrets, or live processes.
+
+### Part V — Six providers, one product model
+
+29. The `ProviderAdapter` contract
+30. Drivers, instances, registries, and multi-instance routing
+31. Codex through app-server JSON-RPC
+32. Claude through the Agent SDK
+33. ACP transport, Cursor, and Grok
+33A. Antigravity through ACP, managed auth, and account catalogs
+34. OpenCode ownership, recovery, and six-provider normalization
+35. Usage accounting and provider limits without a false ledger
+
+Provider chapters preserve native differences in authentication, models, sessions,
+steering, approvals, input, tasks, skills, attachments, compaction, usage, and rewind.
+The usage chapter keeps live context, transcript history, custom prices, and pooled
+subscription windows separate.
+
+### Part VI — Work lifecycle and integrated tools
+
+36. Project discovery, onboarding import, and `t3.json`
+37. Current checkout versus isolated worktrees
+38. Start, stream, steer, interrupt, settle
+39. Permission modes, approvals, and structured input
+40. Threads, provider tasks, plans, skills, and subagents
+41. Context is provider-owned; history is T3-owned
+42. Hidden-ref checkpoints, diffs, and revert
+43. Terminals, files, previews, MCP, VCS, and review graphs
+43A. Device hosts, targets, sessions, and agent control
+
+This part follows a work item through discovery, workspace selection, provider work,
+interaction, context, checkpointing, workbench tools, several linked reviews, GitHub
+stacks, local or SSH device hosts, and agent device tools.
+
+### Part VII — Client architectures
+
+44. Shared runtime: connections, state, and convergence
+45. One React renderer, three runtime edges
+46. One thread, many deliberate projections
+47. Electron desktop: one renderer, explicit native authority
+48. Mobile: adaptive workspaces, persistence, and native systems
+
+The client chapters explain shared settings, environment selection, load balancing,
+snapshot and stream convergence, browser and desktop edges, adaptive mobile layouts,
+offline drafts and uploads, native review and terminal surfaces, media, notifications,
+voice input, and OTA compatibility.
+
+### Part VIII — Reach and ship
+
+49. Reachability is a route; authority is a separate proof
+50. T3 Connect: OAuth, DPoP, relay, and tunnel
+51. Reconnect, environments, notifications, and version skew
+52. Distribution: artifacts, channels, and what actually ships
+53. Release, update, and observability: three safety boundaries
+
+This part separates endpoint reachability from authorization, covers direct, Tailscale,
+T3 Connect, and SSH paths, then traces reconnection, packaging, stores, hosted surfaces,
+nightlies, reversible server updates, analytics, tracing, and resource diagnostics.
+
+## Visual and interaction contract
+
+Every chapter must contain or point to a diagram, interactive lab, comparison, state
+machine, or decision table that clarifies the mechanism. Motion is reader-triggered,
+bounded, and disabled or simplified under `prefers-reduced-motion`. Every visual has
+a text equivalent, works with keyboard input when interactive, remains meaningful in
+print, and does not fetch data at runtime.
+
+The site keeps one readable measure, persistent chapter navigation, full-text search,
+light/dark/system themes, responsive tables, linkable headings, and previous/next
+navigation. Product diagrams show tasks and choices; technical diagrams show ownership,
+durability, data flow, and failure boundaries.
+
+## Validation contract
+
+Completion requires:
+
+- unique slugs and display order;
+- complete product and technical contents;
+- valid source lock, excerpt ids, checksums, references, and immutable links;
+- no draft chapters;
+- accessible names and text equivalents for visuals;
+- keyboard-safe interactions and reduced-motion behavior;
+- all source, content, test, build, Pagefind, and built-site checks passing;
+- no external runtime dependency for local reading; and
+- a clean reading path from product task to implementation boundary.
+
+## Publication
+
+The repository publishes the validated static Astro build through GitHub Pages. The
+public site follows protected `main`; local work can remain ahead until it is reviewed.
+Commits remain focused and conventional, and pull requests explain the problem,
+resulting behavior, evidence, interaction changes, and validation.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index bcbc5c4..9396ba0 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -161,7 +161,7 @@ For commands, side effects, persistence, transport, updates, and cleanup, answer
Quote only the minimum source required to explain the design. Do not copy upstream
documentation or substantial source files into the book. Preserve attribution and
immutable links. Never include credentials, local paths containing personal data,
-private downstream implementation details, or unpublished repository content.
+private Easy Code implementation details, or unpublished repository content.
## Diagrams and interactive labs
diff --git a/NOTICE.md b/NOTICE.md
index 5fdcba0..94a5830 100644
--- a/NOTICE.md
+++ b/NOTICE.md
@@ -7,8 +7,8 @@ architecture. The upstream project is available at:
https://github.com/pingdotgg/t3code
-The source snapshot used by this edition is commit
-`fa219001dc2f14cfd9c7774c2c03c153359144be`. T3 Code is licensed under the MIT
+The referenced T3 Code source is commit
+`859304b7808ab9a4be87b1bddcd07c6485bf9c4f`. T3 Code is licensed under the MIT
License. The following upstream notice and permission terms remain applicable to
every included excerpt:
diff --git a/README.md b/README.md
index 7fab792..6dfaaf1 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
# T3 Code Decoded
- **A source-grounded, interactive guide to the architecture and implementation of T3 Code.**
+ **A complete product guide and source-grounded interactive guide to T3 Code's architecture and implementation.**
[Read the book](#read-the-book) · [Explore the plan](./BOOK_PLAN.md) ·
[Contribute](./CONTRIBUTING.md) · [Source policy](#source-grounding)
@@ -18,25 +18,31 @@ Created and maintained by [Ahmed Alaa (`@BenAlaa`)](https://github.com/BenAlaa).
> [!NOTE]
> The public Pages site is deployed from protected `main`. It reflects the latest
-> merged revision; topic branches remain local or unmerged until their reviewed
-> pull requests are ready.
+> merged milestone; stacked local authoring branches can be ahead while later parts
+> wait for their own reviewed pull requests.
> No authored work is pushed directly to `main`.
## Read the book
[Read the published book](https://benalaa.github.io/t3code-decoded/). When reviewing
-an unmerged change, run that branch locally with the instructions below—the
-published site intentionally tracks protected `main`, not unpublished work.
+an unmerged milestone, run that branch locally with the instructions below—the
+published site intentionally tracks protected `main`, not local stacked work.
-The current edition is pinned to
-[`pingdotgg/t3code@fa219001d`](https://github.com/pingdotgg/t3code/tree/fa219001dc2f14cfd9c7774c2c03c153359144be).
+The book is synchronized with
+[`pingdotgg/t3code@859304b78`](https://github.com/pingdotgg/t3code/tree/859304b7808ab9a4be87b1bddcd07c6485bf9c4f),
+captured on 11 September 2026.
Every exact excerpt in the book is generated from that revision, checksum-verified,
and linked back to immutable GitHub source lines.
## What this book explains
-T3 Code is not the reasoning engine inside Codex, Claude, Cursor, Grok, or
-OpenCode. It is the server-authoritative control plane around them: it normalizes
+The product guide explains installation, onboarding, environments, projects,
+threads, worktrees, composing with rich context, providers, permissions, files,
+terminals, previews, SnapShots, source control, remote access, mobile, device
+testing, usage, updates, privacy, complete workflows, and troubleshooting.
+
+The technical guide explains that T3 Code is not the reasoning engine inside Codex,
+Claude, Cursor, Grok, OpenCode, or Antigravity. It is the server-authoritative control plane around them: it normalizes
intent, durably records product state, starts and supervises provider runtimes,
projects ordered state to several clients, and surrounds the conversation with
worktrees, Git checkpoints, terminals, files, previews, remote access, usage, and
@@ -48,30 +54,29 @@ Web · Desktop · Mobile
▼
T3 server: command → event → projection → reactor
│ │
- │ └─ files · Git · terminal · tunnel
+ │ └─ files · Git · terminal · devices · tunnel
▼
ProviderAdapter
│ native protocol
▼
-Codex · Claude · Cursor · Grok · OpenCode
+Codex · Claude · Cursor · Grok · OpenCode · Antigravity
```
-The book follows that causal path instead of mirroring repository folders. Its
-eight parts cover:
-
-1. ownership boundaries, vocabulary, repository topology, and runtime shapes;
-2. CLI/server boot, Effect RPC, pairing, authorization, subscriptions, and resume;
-3. commands, events, receipts, projections, reactors, SQLite, and recovery;
-4. the provider adapter contract, all five harness integrations, and both usage
- systems;
-5. projects, worktrees, turns, permissions, plans, tasks, context, memory,
- checkpoints, terminals, files, VCS, MCP, preview, and pull requests;
-6. the shared client runtime plus web, Electron, and React Native clients;
-7. direct/relay/Tailscale/SSH access, reconnection, packaging, releases, updates, and telemetry;
-8. complete end-to-end traces, architectural trade-offs, limitations, and
- evidence-bounded roadmap analysis.
-
-See [BOOK_PLAN.md](./BOOK_PLAN.md) for the complete 40-chapter specification,
+The book starts with product tasks, then follows that causal path instead of
+mirroring repository folders. Its eight parts cover:
+
+1. the complete product guide and task recipes;
+2. architecture orientation, ownership boundaries, vocabulary, repository topology, and runtime shapes;
+3. CLI/server boot, Effect RPC, pairing, authorization, subscriptions, and resume;
+4. commands, events, receipts, projections, reactors, SQLite, and recovery;
+5. the provider adapter contract, all six provider integrations, historical usage,
+ live context, and subscription limits;
+6. projects, worktrees, turns, permissions, plans, tasks, context, memory,
+ checkpoints, terminals, files, VCS, MCP, previews, pull requests, and devices;
+7. the shared client runtime plus web, Electron, and React Native clients;
+8. direct/relay/Tailscale/SSH access, reconnection, packaging, releases, updates, and telemetry.
+
+See [BOOK_PLAN.md](./BOOK_PLAN.md) for the complete 53-chapter specification,
figure/lab inventory, review gates, and definition of done.
## Why another set of docs?
@@ -82,7 +87,7 @@ answers a different class of questions:
- Where is the transaction boundary?
- What does a command receipt actually prove?
- Which state survives a server restart?
-- How do five provider protocols become one product vocabulary?
+- How do six provider integrations become one product vocabulary?
- Why does reconnect logic live above a one-attempt RPC session?
- What is shared across clients, and what deliberately differs?
- Which remote component allocates credentials, and where does application traffic
@@ -192,7 +197,7 @@ checkout:
```sh
git clone https://github.com/pingdotgg/t3code.git ../t3code
-git -C ../t3code checkout fa219001dc2f14cfd9c7774c2c03c153359144be
+git -C ../t3code checkout 859304b7808ab9a4be87b1bddcd07c6485bf9c4f
npm run source:check
```
diff --git a/sources/excerpts.manifest.json b/sources/excerpts.manifest.json
index f39f958..e4e938c 100644
--- a/sources/excerpts.manifest.json
+++ b/sources/excerpts.manifest.json
@@ -1,3 +1,4 @@
+
[
{
"id": "architecture-boundary",
@@ -26,24 +27,24 @@
{
"id": "provider-adapter-core",
"path": "apps/server/src/provider/Services/ProviderAdapter.ts",
- "start": 47,
- "end": 71,
+ "start": 67,
+ "end": 94,
"language": "typescript",
"label": "Provider adapter lifecycle contract"
},
{
"id": "provider-adapter-interactions",
"path": "apps/server/src/provider/Services/ProviderAdapter.ts",
- "start": 73,
- "end": 94,
+ "start": 97,
+ "end": 117,
"language": "typescript",
"label": "Provider approval and input contract"
},
{
"id": "provider-adapter-stream",
"path": "apps/server/src/provider/Services/ProviderAdapter.ts",
- "start": 126,
- "end": 134,
+ "start": 149,
+ "end": 157,
"language": "typescript",
"label": "Canonical provider event stream"
},
@@ -395,7 +396,7 @@
"id": "usage-web-context-meter",
"path": "apps/web/src/lib/contextWindow.ts",
"start": 50,
- "end": 96,
+ "end": 90,
"language": "typescript",
"label": "Latest valid context-window snapshot derivation"
},
@@ -1258,8 +1259,8 @@
{
"id": "resource-telemetry-demand-history",
"path": "docs/internals/resource-telemetry.md",
- "start": 129,
- "end": 170,
+ "start": 9,
+ "end": 50,
"language": "markdown",
"label": "Bounded native history and diagnostics-driven telemetry streaming"
},
@@ -1290,8 +1291,8 @@
{
"id": "connect-environment-link-handshake",
"path": "apps/web/src/cloud/linkEnvironment.ts",
- "start": 402,
- "end": 493,
+ "start": 256,
+ "end": 347,
"language": "typescript",
"label": "Client-side relay challenge, environment proof, link, and runtime setup"
},
diff --git a/sources/references.manifest.json b/sources/references.manifest.json
index c68320b..503199b 100644
--- a/sources/references.manifest.json
+++ b/sources/references.manifest.json
@@ -1,3 +1,4 @@
+
[
{
"id": "rpc-group",
@@ -662,10 +663,8 @@
{
"id": "stale-startup-overview",
"path": "docs/internals/overview.md",
- "start": 124,
- "end": 130,
"kind": "file",
- "label": "stale documented startup sequence"
+ "label": "current server boundaries and startup constraints"
},
{
"id": "orchestration-snapshot-contracts",
@@ -1022,10 +1021,8 @@
{
"id": "auth-doc-ticket-overclaim",
"path": "docs/internals/environment-auth.md",
- "start": 95,
- "end": 111,
"kind": "file",
- "label": "documentation claim that WebSocket tickets carry scopes"
+ "label": "current environment authentication contract"
},
{
"id": "decider-effect-dependencies",
@@ -1634,8 +1631,8 @@
{
"id": "provider-adapter-registry-live",
"path": "apps/server/src/provider/Layers/ProviderAdapterRegistry.ts",
- "start": 36,
- "end": 100,
+ "start": 30,
+ "end": 85,
"kind": "file",
"label": "live adapter facade excludes unavailable instances"
},
@@ -1778,8 +1775,8 @@
{
"id": "codex-app-server-child-process",
"path": "packages/effect-codex-app-server/src/client.ts",
- "start": 212,
- "end": 268,
+ "start": 213,
+ "end": 264,
"kind": "file",
"label": "Codex app-server child process and stdio client construction"
},
@@ -2166,8 +2163,8 @@
{
"id": "claude-provider-skills-commands",
"path": "apps/server/src/provider/Layers/ClaudeProvider.ts",
- "start": 920,
- "end": 962,
+ "start": 526,
+ "end": 588,
"kind": "file",
"label": "Claude snapshot combines discovered skills and initialization commands"
},
@@ -2334,16 +2331,16 @@
{
"id": "turn-lifecycle-settlement-guards",
"path": "packages/client-runtime/src/state/threadSettled.ts",
- "start": 286,
- "end": 312,
+ "start": 14,
+ "end": 45,
"kind": "file",
- "label": "Thread settlement eligibility guards"
+ "label": "queued turn-start guard used by thread lifecycle decisions"
},
{
"id": "turn-lifecycle-waiting-ui-test",
"path": "apps/web/src/components/chat/ComposerPrimaryActions.test.tsx",
- "start": 214,
- "end": 219,
+ "start": 95,
+ "end": 109,
"kind": "file",
"label": "Stop action retained while provider waits for input"
},
@@ -2957,7 +2954,7 @@
},
{
"id": "workbench-terminal-mobile",
- "path": "apps/mobile/src/features/terminal/ThreadTerminalPanel.tsx",
+ "path": "apps/mobile/src/features/terminal/ThreadTerminalRouteScreen.tsx",
"start": 31,
"end": 210,
"kind": "file",
@@ -3463,7 +3460,7 @@
"id": "client-connection-resolver",
"path": "packages/client-runtime/src/connection/resolver.ts",
"start": 51,
- "end": 280,
+ "end": 252,
"kind": "file",
"label": "Target-specific preparation into a prepared connection"
},
@@ -3951,7 +3948,7 @@
"id": "release-server-update-architecture",
"path": "docs/internals/server-updates.md",
"start": 1,
- "end": 99,
+ "end": 58,
"kind": "file",
"label": "Stable launcher, reversible trial, database snapshot, and client correlation"
},
@@ -3991,7 +3988,7 @@
"id": "telemetry-browser-client-tracing",
"path": "apps/web/src/observability/clientTracing.ts",
"start": 16,
- "end": 133,
+ "end": 125,
"kind": "file",
"label": "Web tracer delegates OTLP batches through the selected primary environment"
},
@@ -4007,7 +4004,7 @@
"id": "telemetry-resource-architecture",
"path": "docs/internals/resource-telemetry.md",
"start": 1,
- "end": 352,
+ "end": 51,
"kind": "file",
"label": "Native resource telemetry topology, demand, retention, and packaging"
},
@@ -4043,7 +4040,7 @@
"id": "access-connection-resolver",
"path": "packages/client-runtime/src/connection/resolver.ts",
"start": 51,
- "end": 277,
+ "end": 252,
"kind": "file",
"label": "Route-specific target resolution into a common prepared connection"
},
@@ -4146,10 +4143,8 @@
{
"id": "remote-explicit-future-work",
"path": "docs/internals/remote.md",
- "start": 223,
- "end": 229,
"kind": "file",
- "label": "Explicitly unbuilt remote endpoint-provider, callback-broker, and multi-environment work"
+ "label": "Current remote endpoint, SSH, Tailscale, and T3 Connect architecture"
},
{
"id": "plan-ui-transition",
@@ -4163,7 +4158,7 @@
"id": "plan-ui-capability-filter",
"path": "apps/web/src/providerModels.ts",
"start": 80,
- "end": 112,
+ "end": 108,
"kind": "file",
"label": "Legacy plan-mode capability filtering before model dispatch"
},
diff --git a/sources/t3code.lock.json b/sources/t3code.lock.json
index 58584c2..af8b2b5 100644
--- a/sources/t3code.lock.json
+++ b/sources/t3code.lock.json
@@ -1,14 +1,15 @@
+
{
"repository": "https://github.com/pingdotgg/t3code",
- "commit": "fa219001dc2f14cfd9c7774c2c03c153359144be",
- "shortCommit": "fa219001d",
+ "commit": "859304b7808ab9a4be87b1bddcd07c6485bf9c4f",
+ "shortCommit": "859304b78",
"branch": "main",
- "capturedAt": "2026-08-24T00:00:00+03:00",
+ "capturedAt": "2026-09-11T00:00:00+03:00",
"sourceDirHint": "../t3code",
"inventoryRulesVersion": 1,
- "productionFiles": 1844,
- "productionLines": 533213,
- "testFiles": 881,
- "testLines": 247766,
- "notes": "Recomputed from pinned Git objects by scripts/inventory-source.mjs. Counts include tracked implementation/build source extensions, exclude assets and .repos, and classify test/spec/fixture paths separately; generated protocol source remains included."
+ "productionFiles": 2288,
+ "productionLines": 669059,
+ "testFiles": 1170,
+ "testLines": 404139,
+ "notes": "Recomputed from pinned Git objects by scripts/inventory-source.mjs. Counts include tracked implementation and build-source extensions, exclude assets and .repos, and classify tests, specs, and fixtures separately."
}
diff --git a/src/components/BookCover.astro b/src/components/BookCover.astro
index 70c2e1e..95a9f08 100644
--- a/src/components/BookCover.astro
+++ b/src/components/BookCover.astro
@@ -1,3 +1,4 @@
+
---
import { Image } from "astro:assets";
import cover from "../../cover.png";
@@ -8,20 +9,20 @@ const base = import.meta.env.BASE_URL.endsWith("/") ? import.meta.env.BASE_URL :
-
+
- Source-level field guide
-
Follow the control plane all the way down.
-
From a tap on a phone to a provider subprocess, persisted event, hidden Git checkpoint, and streamed UI update—every layer is explained against one pinned source revision.
+ Product guide + source-level field guide
+
Use the whole product. Then follow it all the way down.
+
Start with installation, daily workflows, remote work, reviews, mobile, and device testing. Continue from one user action into provider processes, durable events, checkpoints, clients, and recovery.
Select a complete trace, then advance deliberately. The marker crosses the owner that acts next; its final boundary says what does—and does not—converge.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Step 1 of 6
-
-
-
-
-
-
Trace 1 · Local first turn
-
Client sends one existing-thread command
-
The user action enters the environment through an authorized RPC method; no provider work has happened yet.
exact package publication, then launcher pending/trial/commit state
publish does not replace a machine; launcher can roll back a failed trial before commit
-
-
-
-
-
-
-
-
-
diff --git a/src/content/book/00-cover.mdx b/src/content/book/00-cover.mdx
index f432c60..b908268 100644
--- a/src/content/book/00-cover.mdx
+++ b/src/content/book/00-cover.mdx
@@ -6,14 +6,14 @@ part: Start here
partOrder: 0
title: T3 Code Decoded
shortTitle: Cover
-summary: A source-grounded, end-to-end field guide to T3 Code's control plane, provider adapters, clients, remote access, and distribution system.
+summary: A complete product guide and source-grounded technical field guide to T3 Code across web, desktop, mobile, six providers, remote environments, reviews, previews, and device testing.
status: source-checked
gates: [sources]
objectives: []
-keywords: [T3 Code, architecture, agent harness, control plane]
-sourceAreas: [apps/server, apps/web, apps/desktop, apps/mobile, packages/contracts]
+keywords: [T3 Code, product guide, user documentation, architecture, agent harness, control plane]
+sourceAreas: [docs/user, apps/server, apps/web, apps/desktop, apps/mobile, packages/contracts]
visuals: [book cover]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import BookCover from "../../components/BookCover.astro";
@@ -22,10 +22,21 @@ import Callout from "../../components/Callout.astro";
- This edition is locked to [`pingdotgg/t3code@fa219001d`](https://github.com/pingdotgg/t3code/tree/fa219001dc2f14cfd9c7774c2c03c153359144be). “Shipped,” “supported,” and “implemented” always mean that revision unless a dated release or roadmap note says otherwise.
+ The book is synchronized with [`pingdotgg/t3code@859304b78`](https://github.com/pingdotgg/t3code/tree/859304b7808ab9a4be87b1bddcd07c6485bf9c4f), captured on **11 September 2026**.
-## What this book is trying to make obvious
+## Two paths through T3 Code
+
+The product guide explains what T3 Code offers and how to use it: installation,
+onboarding, projects, threads, worktrees, providers, permissions, files, terminals,
+previews, SnapShots, source control, remote environments, mobile clients, usage,
+updates, and simulator or emulator testing.
+
+The technical guide opens the implementation behind those workflows: server and
+client ownership, durable orchestration, provider adapters, persistence, recovery,
+connection routes, native integrations, packaging, and release operations.
+
+## What the technical path makes obvious
T3 Code is easy to mistake for an agent. It is more useful—and more technically
interesting—to see it as a **control surface and execution boundary around several
@@ -35,4 +46,5 @@ operations, and gives clients shared semantics with deliberate platform-specific
capabilities. Some delivery and side-effect machinery remains intentionally
ephemeral; the book marks those seams instead of calling all server state durable.
-That division of ownership is the spine of the book. Every later module connects back to it.
+That division of ownership is the spine of the technical path. The product path gives
+each boundary a concrete user purpose before the implementation chapters name it.
diff --git a/src/content/book/01-how-to-read.mdx b/src/content/book/01-how-to-read.mdx
index be1994b..1fcc7c9 100644
--- a/src/content/book/01-how-to-read.mdx
+++ b/src/content/book/01-how-to-read.mdx
@@ -4,67 +4,85 @@ order: 1
kind: front
part: Start here
partOrder: 0
-title: How to read a changing system
+title: How to read this guide
shortTitle: Reading guide
-summary: The evidence rules, source labels, revision contract, and reading paths used throughout the book.
+summary: Choose a product, workflow, or architecture route and understand the evidence labels used throughout the book.
status: source-checked
-gates: [sources]
+gates: [sources, links, editorial]
objectives:
- - Distinguish verbatim source, abridged source, diagrams, and interpretation.
- - Choose a linear, feature-first, or implementation-first reading path.
- - Understand what the pinned revision does and does not promise.
-keywords: [evidence, source references, revision, reading path]
-sourceAreas: [sources/t3code.lock.json, sources/excerpts.manifest.json]
-visuals: [evidence legend]
-updatedAt: 2026-08-24
+ - Choose the shortest reading path for your goal.
+ - Move from a product task to the implementation that supports it.
+ - Distinguish verified behavior, documented intent, inference, and proposals.
+keywords: [product guide, evidence, source references, reading path]
+sourceAreas: [sources/t3code.lock.json, sources/excerpts.manifest.json, docs/user]
+visuals: [reading routes, evidence legend]
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
-import EvidenceClaim from "../../components/EvidenceClaim.astro";
-import SourceExcerpt from "../../components/SourceExcerpt.astro";
-import SourceSnapshot from "../../components/SourceSnapshot.astro";
-
-This is a field guide to a moving codebase. It therefore treats provenance as part of the interface, not a footnote.
-
-
-
-## Four evidence labels
-
-1. **Verified behavior** is backed by executable code, a test, schema, migration, or workflow at the pinned revision.
-2. **Documented intent** reports what a maintainer document says without silently upgrading prose into runtime behavior.
-3. **Inference** names a design consequence derived from cited evidence. The sources prove the inputs; the book owns the interpretation.
-4. **Future / proposed** is explicitly unshipped. A builder capability, community request, or future-work paragraph is never called a supported feature.
-
-Exact source cards are a separate presentation device. Their code is read directly
-from the locked Git object—not the possibly dirty working tree—and shows real line
-numbers, a visible checksum prefix, and an immutable GitHub permalink.
-
-
-
-
- A stable source lock makes an explanation reproducible. It does not make it permanently current; later editions must deliberately refresh and review the evidence.
-
-
-## Three reading paths
-
-### Linear: follow one task
-
-Start with **The request trace**, then read the numbered chapters in order. This follows a user action from client state through authenticated RPC, commands, events, provider I/O, checkpoints, and back to every UI.
-
-### Architecture-first: map then zoom
-
-Open **The complete system map**, choose a layer, and follow its cross-links. This is useful when you already know event sourcing, provider protocols, or Electron/React Native and want the unfamiliar seams.
-
-### Transfer-first: design another orchestrator
-
-Read the ownership model, adapter boundary, domain kernel, connection runtime, and final transfer guide. Those chapters separate reusable patterns from choices that only make sense for T3 Code's bring-your-own-subscription model.
-
-
- The live repository moves quickly. A source link with `fa219001d` is intentionally historical and stable. A link to `main` may be newer, but it cannot prove what this edition read. The book prefers reproducibility over silently chasing HEAD.
+import Mermaid from "../../components/Mermaid.astro";
+
+The book has a product path and a technical path. Read them in order for the full
+story, or enter through the task you need to complete.
+
+ P{Need to use T3 Code?}
+ P -->|yes| PG[Product guide\nChapters 1–13]
+ PG --> R[Complete recipes\nand troubleshooting]
+ P -->|understand or extend it| M[System map\nand request trace]
+ M --> T[Technical guide\nChapters 16–53]
+ PG -. product question .-> T`} />
+
+## Product-first route
+
+Read Chapters 1–13 if you want a complete operating guide. They move from first
+installation to parallel tasks, rich prompts, provider choice, workbench tools,
+source control, remote access, mobile supervision, device testing, personalization,
+usage, updates, and troubleshooting. No architecture knowledge is assumed.
+
+## Workflow-first route
+
+Use Contents or search to jump directly to the relevant product chapter. The final
+product chapter includes complete recipes for local feature work, parallel worktrees,
+remote supervision, pull-request review, and device verification. Follow its links
+backward when a recipe needs setup or a feature decision.
+
+## Architecture-first route
+
+Open **The complete system map**, then **One request, every boundary**. Continue with
+Chapter 16 to follow execution ownership, boot, RPC, authorization, the durable
+domain kernel, six providers, work lifecycle, clients, access routes, distribution,
+and operations.
+
+## From product questions to technical chapters
+
+| Product question | Technical destination |
+| --- | --- |
+| Why can I close one client and continue elsewhere? | Turn lifecycle, projections, shared client runtime, and reconnect. |
+| Why do providers expose different choices? | ProviderAdapter, provider instances, and the provider-specific chapters. |
+| What exactly does revert restore? | Checkpoints and context ownership. |
+| Why does remote setup belong to one machine? | Environment auth, access transports, and T3 Connect. |
+| How can a simulator run on another host? | Device hosts, targets, sessions, and agent control. |
+| Why can a thread hold several reviews? | Projections, workbench services, and source-control integration. |
+
+## Evidence labels
+
+1. **Verified behavior** is backed by executable code, a test, schema, migration,
+ or workflow.
+2. **Documented intent** reports what a maintainer document says without turning
+ prose into runtime behavior.
+3. **Inference** names a design consequence derived from cited evidence. The
+ sources prove the inputs; the book owns the interpretation.
+4. **Future / proposed** is explicitly unshipped. A builder capability, community
+ request, or idea is never called a supported feature.
+
+Exact source cards are read from the locked Git object and show line numbers,
+checksum prefixes, and immutable permalinks. When documentation and executable
+behavior disagree, the book calls out the discrepancy and follows the executable
+contract for statements about behavior.
+
+
+ **Draft** means the explanation still needs a source pass. **Source checked** means
+ claims and diagrams were reconciled to the locked checkout. **Verified** adds link,
+ interaction, build, and editorial review.
-
-## Status words
-
-- **Draft**: structured and cited, but still awaiting a second source pass.
-- **Source checked**: claims and diagrams have been reconciled to the pinned checkout.
-- **Verified**: source checked, link checked, and reviewed in the end-to-end narrative.
diff --git a/src/content/book/02-contents.mdx b/src/content/book/02-contents.mdx
index e56a7a8..f167875 100644
--- a/src/content/book/02-contents.mdx
+++ b/src/content/book/02-contents.mdx
@@ -4,94 +4,112 @@ order: 2
kind: front
part: Start here
partOrder: 0
-title: Contents and learning route
+title: Contents and learning routes
shortTitle: Contents
-summary: "The complete ordered reading route: establish ownership, then trace the durable control plane, adapters, work lifecycle, clients, remote paths, shipping system, and architectural synthesis."
+summary: "The complete product-first route through T3 Code, followed by its control plane, six providers, work lifecycle, clients, device hosts, remote paths, and shipping system."
status: source-checked
gates: [sources, links, editorial]
objectives:
- - See why the order follows runtime causality instead of repository folders.
- - Understand the scope of every completed part and its visual explanations.
-keywords: [contents, chapters, roadmap, learning path]
-sourceAreas: [BOOK_PLAN.md]
+ - Choose a product, workflow, or implementation route.
+ - See every product and technical chapter in the guide.
+keywords: [contents, product guide, chapters, learning path]
+sourceAreas: [BOOK_PLAN.md, docs/user]
visuals: [chapter roadmap]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
-The old book introduced several keystone concepts long after depending on them. This edition orders the material by **causal distance from one user request**. The repository atlas remains available as reference, but it does not dictate the story.
+The product guide comes first. The technical guide then follows one request from
+the client through authorization, durable state, provider execution, work services,
+client convergence, remote access, and release operations.
## Start here
-- **How to read a changing system** — evidence, revision, and reading paths.
-- **The complete system map** — the same architecture in spatial form.
-- **One request, every boundary** — a step-through trace before the zoomed chapters.
-
-## Part I · Boundaries and vocabulary
-
-1. Control surface, not agent brain
-2. Environment · project · thread · turn · session
-3. Repository and dependency atlas
-4. Runtime topologies and technology choices
-
-## Part II · Boot and connect
-
-5. The `npx t3` bootstrap path
-6. Server composition and execution boundary
-7. Effect RPC, subscriptions, and wire contracts
-8. Pairing, scopes, credentials, and WebSocket upgrade
-
-## Part III · The durable domain kernel
-
-9. Commands and invariants
-10. Events, receipts, and idempotency
-11. Projection tables and read models
-12. Post-commit reactors: serialized handling without durable delivery
-13. SQLite, files, settings, secrets, migrations, and recovery
-
-## Part IV · Five harnesses, one product model
-
-14. The `ProviderAdapter` contract
-15. Drivers, instances, registries, and multi-instance routing
-16. Codex through app-server JSON-RPC
-17. Claude through the Agent SDK
-18. Cursor and Grok through ACP
-19. OpenCode and the normalization matrix
-20. Two usage systems: live context telemetry and transcript accounting
-
-## Part V · The work lifecycle
-
-21. Project discovery and `t3.json`
-22. Current checkout vs isolated worktrees
-23. Start, stream, steer, interrupt, settle
-24. Permission modes, approvals, and structured input
-25. Threads, provider tasks, plans, skills, and subagents
-26. Who owns context, compaction, and memory
-27. Hidden-ref checkpoints, diffs, and revert
-28. Terminals, files, previews, MCP, VCS, and pull requests
-
-## Part VI · Client architectures: shared semantics, platform edges
-
-29. The shared client runtime
-30. Web routes, state, and rendering performance
-31. Composer, work log, review, and sidebar lifecycle
-32. Desktop: Electron, IPC, server ownership, browser, SSH
-33. Mobile: React Native, persistence, outbox, sharing, notifications
-
-## Part VII · Reach and ship
-
-34. Primary, paired bearer, Tailscale endpoints, and SSH access
-35. T3 Connect: OAuth, DPoP, relay, and tunnel
-36. Reconnect, multi-environment state, notifications, version skew
-37. Distribution artifacts: CLI, hosted app, desktop, mobile, marketing, and AUR
-38. Release graph, three update systems, and observability/privacy
-
-## Part VIII · Synthesis
-
-39. Six complete traces: ownership, convergence, and failure boundaries
-40. Decisions, trade-offs, limitations, and an honest roadmap
-
-
- `BOOK_PLAN.md` is the authoring contract for this repository. Product roadmap claims inside the book use a stricter split: shipped code, explicit maintainer future work, and community ideas are three different categories.
+- **Cover** — scope and source synchronization.
+- **How to read this guide** — product, workflow, and architecture routes.
+- **Contents and learning routes** — this complete map.
+
+## Part I · Product guide
+
+1. T3 Code as a product
+2. Install and reach a useful first thread
+3. Environments, clients, and connection paths
+4. Organize projects, threads, and worktrees
+5. Compose tasks with the right context
+6. Choose providers, models, accounts, and permissions
+7. The workbench: files, terminals, browser preview, and SnapShots
+8. Source control: checkpoints, pull requests, reviews, and stacks
+9. Remote environments and unattended work
+10. Mobile: supervise agents from anywhere
+11. Device lab: simulators, emulators, and agent-driven testing
+12. Personalize, measure usage, update, and protect privacy
+13. Complete recipes and troubleshooting
+
+## Part II · Architecture orientation and boundaries
+
+14. The complete system map
+15. One request, every boundary
+16. Control surface, not agent brain
+17. Environment · project · thread · turn · session
+18. Repository and dependency atlas
+19. Runtime topologies and technology choices
+
+## Part III · Boot and connect
+
+20. The `npx t3` bootstrap path
+21. Server composition, activation, and readiness
+22. HTTP, WebSocket RPC, snapshots, and resume
+23. Pairing, credentials, TTLs, and scopes
+
+## Part IV · The durable domain kernel
+
+24. Commands, invariants, and the boundary of atomicity
+25. Events, receipts, idempotency, and the post-commit gap
+26. Projection tables and read models
+27. Post-commit reactors and the delivery gap
+28. Persistence, reconstruction, and crash recovery
+
+## Part V · Six providers, one product model
+
+29. The `ProviderAdapter` contract
+30. Drivers, instances, registries, and multi-instance routing
+31. Codex through app-server JSON-RPC
+32. Claude through the Agent SDK
+33. ACP transport, Cursor, and Grok
+33A. Antigravity through ACP, managed auth, and account catalogs
+34. OpenCode ownership, recovery, and six-provider normalization
+35. Usage accounting and provider limits without a false ledger
+
+## Part VI · The work lifecycle and integrated tools
+
+36. Project discovery, onboarding import, and `t3.json`
+37. Current checkout versus isolated worktrees
+38. Start, stream, steer, interrupt, settle
+39. Permission modes, approvals, and structured input
+40. Threads, provider tasks, plans, skills, and subagents
+41. Context is provider-owned; history is T3-owned
+42. Hidden-ref checkpoints, diffs, and revert
+43. Terminals, files, previews, MCP, VCS, and review graphs
+43A. Device hosts, targets, sessions, and agent control
+
+## Part VII · Client architectures: shared semantics, platform edges
+
+44. Shared runtime: connections, state, and convergence
+45. One React renderer, three runtime edges
+46. One thread, many deliberate projections
+47. Electron desktop: one renderer, explicit native authority
+48. Mobile: adaptive workspaces, persistence, and native systems
+
+## Part VIII · Reach and ship
+
+49. Reachability is a route; authority is a separate proof
+50. T3 Connect: OAuth, DPoP, relay, and tunnel
+51. Reconnect, environments, notifications, and version skew
+52. Distribution: artifacts, channels, and what actually ships
+53. Release, update, and observability: three safety boundaries
+
+
+ Press `Cmd/Ctrl+K` to search product tasks, concepts, source paths, provider names,
+ and implementation terms across the entire guide.
diff --git a/src/content/book/03-architecture-map.mdx b/src/content/book/03-architecture-map.mdx
index 0d7aee9..1787db3 100644
--- a/src/content/book/03-architecture-map.mdx
+++ b/src/content/book/03-architecture-map.mdx
@@ -1,9 +1,10 @@
---
slug: architecture-map
-order: 3
-kind: front
-part: Start here
-partOrder: 0
+order: 140
+number: "14"
+kind: chapter
+part: Part II · Architecture orientation
+partOrder: 2
title: The complete system map
shortTitle: System map
summary: A spatial map that separates client surfaces, transport, transactional state, hot delivery, side effects, provider routing, and external execution.
@@ -15,7 +16,7 @@ objectives:
keywords: [architecture map, components, packages, boundaries]
sourceAreas: [apps/server, packages/contracts, packages/client-runtime, apps/web, apps/desktop, apps/mobile, apps/marketing, infra/relay]
visuals: [interactive layer map, ownership table]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -30,7 +31,7 @@ behind that environment's server boundary. A client can supervise several such
environments, while Electron and mobile also own device-local storage, navigation,
notifications, preview, update, and operating-system integrations.
-
+
+|typed command| W[WebSocket RPC + scope]
W --> Q[Serialized in-memory queue]
@@ -59,7 +60,7 @@ notifications, preview, update, and operating-system integrations.
B -.->|best effort; not replayed| R[Provider command reactor]
R --> V[ProviderService + instance registry]
V --> A[Provider adapter]
- A --> P[Codex · Claude · Cursor · Grok · OpenCode]
+ A --> P[Codex · Claude · Cursor · Grok · OpenCode · Antigravity]
P -->|native notifications| A
A -->|canonical runtime events| I[Runtime ingestion]
I -->|internal commands| Q
diff --git a/src/content/book/04-request-trace.mdx b/src/content/book/04-request-trace.mdx
index 5d71bd2..681906f 100644
--- a/src/content/book/04-request-trace.mdx
+++ b/src/content/book/04-request-trace.mdx
@@ -1,9 +1,10 @@
---
slug: request-trace
-order: 4
-kind: front
-part: Start here
-partOrder: 0
+order: 150
+number: "15"
+kind: chapter
+part: Part II · Architecture orientation
+partOrder: 2
title: One request, every boundary
shortTitle: Request trace
summary: Step through a user turn from a client command to an ordered SQL commit, provider-native execution, canonical event ingestion, checkpoint diff, and streamed UI state.
@@ -16,7 +17,7 @@ objectives:
keywords: [turn lifecycle, command, event, provider, checkpoint, stream]
sourceAreas: [packages/contracts/src/orchestration.ts, apps/server/src/orchestration, apps/server/src/provider]
visuals: [interactive request stepper, sequence diagram]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -78,12 +79,12 @@ existing thread—optional lifecycle resets, then message and turn-start—is de
and committed atomically.
- Attachment normalization persists decoded bytes before the engine transaction. A command can therefore fail after external filesystem work has begun; Chapter 9 models that branch explicitly.
+ Attachment normalization persists decoded bytes before the engine transaction. A command can therefore fail after external filesystem work has begun; Chapter 24 models that branch explicitly.
## The full causal loop
-
+ D[Choose environment and project]
+ D --> T[Start or resume a thread]
+ T --> C[Compose task plus context]
+ C --> P[Choose provider, model, and permission mode]
+ P --> A[Agent works on environment machine]
+ A --> Q{Needs attention?}
+ Q -->|question or approval| U
+ Q -->|continues| A
+ A --> R[Inspect messages, tools, files, diff, terminal, or device]
+ R --> O{Outcome}
+ O -->|follow up| C
+ O -->|restore| T
+ O -->|review or PR| S[Source-control workflow]
+ O -->|done| X[Settle thread]`} />
+
+The loop is intentionally durable. Closing a browser does not redefine the task;
+the environment remains the authority for its threads. Mobile can queue a message
+while offline and upload it after reconnecting. Supported provider sessions can
+resume after a server restart when continuation is enabled.
+
+## The five objects you should know
+
+**A client** is the interface in front of you. The desktop and web clients expose
+the fullest setup and review surfaces. Mobile is optimized for supervising work,
+responding to questions and approvals, and sending follow-ups while away.
+
+**An environment** is one running T3 server plus its machine, filesystem, provider
+credentials, projects, and state. “Local,” “office workstation,” and “cloud VM”
+are common environments. A client may connect to several at once.
+
+**A project** points to a workspace directory inside one environment. Checkouts of
+the same repository can be grouped in the UI, while each machine still owns its
+own files and provider setup.
+
+**A thread** is a durable unit of work inside a project. It contains the
+conversation, agent activity, selected provider settings, workspace choice,
+checkpoints, and related review links.
+
+**A turn** begins when you send a message and includes the agent's response and
+work. A thread normally contains many turns: initial task, correction, test run,
+review response, and final cleanup.
+
+
+ When something is missing, ask two questions: “Which environment owns this
+ project?” and “Which thread owns this task?” Most setup and navigation mistakes
+ become obvious once both answers are explicit.
+
+
+## Three good starting workflows
+
+### Focused local task
+
+Install the desktop app, add a repository, start a thread in the current checkout,
+attach the relevant issue or screenshot, and use **Supervised** or **Auto** while
+you learn the agent's behavior. Inspect the diff, then commit or continue from the
+same thread.
+
+### Parallel feature work
+
+Create one **New worktree** thread per independent change. Start background tasks
+with `Cmd/Ctrl+Enter`, then use the sidebar to move between them. Keep a task in
+one thread so its branch, decisions, approvals, and pull request remain connected.
+
+### Remote supervision
+
+Run T3 Code on the machine that has the repositories and provider logins. Keep it
+available with the desktop host or a background service, expose it through T3
+Connect or a private network, and connect from mobile. Notifications can take you
+straight to a completed turn, failure, question, or approval request.
+
+## Product boundaries that affect daily use
+
+- Work executes on the environment machine. Install provider CLIs, Git hosting
+ tools, SDKs, and credentials there—not merely on the device displaying the UI.
+- A phone does not become the host. It controls a server elsewhere.
+- Provider capabilities differ. Plan modes, rewind support, questions, attachment
+ limits, and approval behavior are not identical across runtimes.
+- T3 Code preserves product history and file diffs, but provider-native context
+ remains subject to that provider's continuation and compaction behavior.
+- Estimated usage cost is an analytical view, not a subscription invoice.
+
+## Where the rest of this guide goes
+
+The next chapters turn this map into tasks: install and first run; choose clients
+and environments; organize projects, threads, and worktrees; write context-rich
+requests; choose providers, models, and permissions; then use terminals, previews,
+devices, Git, remote access, recovery, and customization. The technical part of
+the book later explains why these product behaviors are reliable.
+
+### Source trail
+
+Sources:
+[product README](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/README.md),
+[installation](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/install.md),
+[remote access](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/remote-access.md), and
+[working with threads](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/thread-sidebar.md).
diff --git a/src/content/book/06-install-onboarding.mdx b/src/content/book/06-install-onboarding.mdx
new file mode 100644
index 0000000..6eff2d8
--- /dev/null
+++ b/src/content/book/06-install-onboarding.mdx
@@ -0,0 +1,196 @@
+---
+slug: install-onboarding
+order: 20
+number: "2"
+kind: chapter
+part: Part I · Product guide
+partOrder: 1
+title: Install and reach a useful first thread
+shortTitle: Install and onboarding
+summary: Choose a host, install the right T3 Code surface, connect a provider, import useful projects, and verify the first agent task.
+status: source-checked
+gates: [sources, links, interaction, editorial]
+objectives:
+ - Select an installation path for local, WSL, SSH, and mobile use.
+ - Complete the welcome flow without confusing client and environment machines.
+ - Verify a provider and project with a small first task.
+keywords: [installation, onboarding, welcome wizard, providers, import, updates]
+sourceAreas: [docs/user/install.md, docs/user/welcome-wizard.md, docs/user/background-service.md, docs/user/updating.md]
+visuals: [installation decision flow]
+updatedAt: "2026-09-11"
+---
+
+import Callout from "../../components/Callout.astro";
+import Mermaid from "../../components/Mermaid.astro";
+
+Your first decision is where agents will run. Choose the machine that already has
+the repositories, build tools, and credentials you want the agent to use. That
+machine becomes the environment host. You may operate it from the same desktop,
+a browser, or a phone later.
+
+## Choose an installation path
+
+ L{This desktop?}
+ L -->|yes| D[Install desktop app]
+ L -->|quick trial| N[Run npx t3 at latest]
+ L -->|no, SSH host| H[Add SSH environment from desktop]
+ L -->|no, persistent Linux or macOS host| B[Install user background service]
+ D --> W{Use WSL workspace?}
+ W -->|yes| WS[Select distro in Connections; install Node and providers inside WSL]
+ W -->|no| P[Configure provider on host]
+ N --> P
+ H --> P
+ B --> P
+ WS --> P
+ P --> O[Run welcome wizard and import projects]
+ O --> F[Send a small first task]`} />
+
+| Path | Best for | Requirement or tradeoff |
+|---|---|---|
+| Desktop app | Everyday local use, native integrations, easiest host setup | Bundles the server runtime; provider tools still need setup where projects run. |
+| `npx t3@latest` | Fast trial or foreground command-line host | Requires a supported Node.js release and stops with the terminal process. |
+| Background service | Always-available Linux or macOS host | Runs as your user; Windows services are not supported. |
+| Desktop-managed SSH | Projects and credentials on another machine | Remote host needs supported Node.js and provider tools visible to non-interactive SSH. |
+| Mobile app | Supervision away from the host | Connects to another environment; it does not run agents locally. |
+
+Command-line and SSH environments require Node.js 22.16+ in the 22 line, 23.11+
+in the 23 line, or 24.10+. The desktop app includes its own server runtime.
+
+## Install the client or server
+
+For a no-install trial, run:
+
+```bash
+npx t3@latest
+```
+
+It starts the server and opens its local web client. Use
+`npx t3@latest --help` to see launch options.
+
+For desktop, install a release from GitHub or use the supported platform package:
+
+| Platform | Command |
+|---|---|
+| Windows | `winget install T3Tools.T3Code` |
+| macOS | `brew install --cask t3-code` |
+| Arch Linux stable | `yay -S t3code-bin` |
+| Arch Linux nightly | `yay -S t3code-nightly-bin` |
+
+With desktop already running, `npx t3 app` opens a new thread for the current
+directory. Pass a path to open another directory. This command talks to the local
+desktop app; it is not a general command for a standalone or SSH server.
+
+### WSL
+
+In **Settings → Connections**, choose the WSL distribution that should own your
+projects. Install Node.js and provider CLIs inside that distribution. Desktop
+installs its matching T3 server there. The first start after an app update can take
+longer while that runtime catches up.
+
+### Background host
+
+On Linux or macOS, install and inspect the user service with:
+
+```bash
+npx t3@latest service install
+npx t3@latest service status
+```
+
+Use `service update` to repair or update it and `service uninstall` to stop and
+remove startup. Uninstalling leaves project, thread, and setting data intact.
+Linux uses a systemd user service and normally needs lingering; macOS starts at
+login and requires the machine to remain logged in and awake.
+
+## Connect at least one provider
+
+Open **Settings → Providers**, select the environment, enable a provider, and
+complete its installation and login on that machine.
+
+| Provider | Host-side setup |
+|---|---|
+| Codex | Install Codex CLI; run `codex login`. |
+| Claude | Install Claude Code; run `claude auth login`. |
+| Cursor | Install Cursor CLI; run `agent login` (the executable is `cursor-agent`). |
+| Grok Build | Install Grok Build CLI; run `grok login`. |
+| OpenCode | Install OpenCode; run `opencode auth login`. |
+| Antigravity | Install its managed runtime and sign in from provider settings. |
+
+If a CLI is not on the server process's `PATH`, set **Binary path**. This is common
+with language version managers. Provider cards can detect available upgrades;
+**Update now** appears only when T3 Code recognizes the installer that owns the
+binary. Mark API keys and other private instance variables as **Sensitive**. After
+you save them, Settings keeps the value available to the provider but no longer
+shows the original text.
+
+
+ When you connect from mobile, a browser, or another desktop, install and
+ authenticate providers on the selected environment machine. Settings sends the
+ setup intent there; credentials do not migrate from the client device.
+
+
+## Use the welcome wizard deliberately
+
+The welcome flow has three useful stages:
+
+1. **Connect computers.** Select the environments you want to set up. Add hosts
+ through T3 Connect or a direct pairing link if needed. Removing a computer from
+ this setup selection does not disconnect it.
+2. **Check agents.** The wizard checks Codex and Claude on each selected computer
+ and can open a terminal with the relevant install or login command. Other
+ providers remain available in Settings.
+3. **Import projects.** Select directories discovered from recent Codex and Claude
+ use. Git repositories appear first and matching remotes are grouped.
+
+The initial project selection favors Git repositories active in the last 30 days
+with at least three conversations. Linked worktrees, Codex scratch directories
+under `Documents/Codex`, and paths under `Downloads` are excluded. You can change
+every checkbox or skip import entirely.
+
+Imported history is a practical bridge, not a byte-for-byte archive. T3 Code
+imports recent visible conversation content, omits tool activity and attachments,
+and keeps at most 200 messages per conversation. One import attempt reads up to
+100 conversation files and 64 MiB per project, with at most 100,000 input records;
+individual files larger than 16 MiB are skipped. Large histories may require
+another pass. Completed conversations are not duplicated, and navigation pauses
+while an import is running.
+
+The setup terminal uses the selected provider instance's home and environment.
+Sensitive settings stay redacted in the interface and terminal metadata while the
+process can use them.
+
+
+ **Still connecting** means the workspace could not yet be confirmed; choose
+ **Reload**. **Could not read settings** means storage is unavailable or unreadable;
+ restore access and choose **Retry**. T3 Code does not replace unreadable settings
+ with defaults.
+
+
+## Verify the installation
+
+Create or import one small project, then start a thread with a bounded prompt such
+as: “Read the repository README and tell me the test command. Do not change
+files.” Choose **Supervised** for this check. A healthy setup proves four things:
+
+- the client reaches the intended environment;
+- the environment can read the project directory;
+- the provider is authenticated and can start a session;
+- questions, responses, and permission requests return to the thread.
+
+After that, try a small edit and inspect the diff. Do not diagnose Git, SDK, and
+provider failures at once; the read-only task separates basic connectivity from
+toolchain setup.
+
+## Keep client and server versions aligned
+
+The app in front of you and the environment server can be on different versions.
+When a mismatch appears, update the machine named in the notice after active work
+finishes. The update choices and recovery behavior live in
+[Personalize, measure usage, update, and protect privacy](../personalize-usage-updates/).
+
+### Source trail
+
+Sources: [install](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/install.md),
+[welcome wizard](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/welcome-wizard.md),
+[background service](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/background-service.md), and
+[updating](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/updating.md).
diff --git a/src/content/book/07-environments-surfaces.mdx b/src/content/book/07-environments-surfaces.mdx
new file mode 100644
index 0000000..9ef5583
--- /dev/null
+++ b/src/content/book/07-environments-surfaces.mdx
@@ -0,0 +1,180 @@
+---
+slug: environments-surfaces
+order: 30
+number: "3"
+kind: chapter
+part: Part I · Product guide
+partOrder: 1
+title: Environments, clients, and connection paths
+shortTitle: Environments and surfaces
+summary: Decide where work executes, which client to use, and how to connect securely through local, direct, Tailscale, T3 Connect, or SSH paths.
+status: source-checked
+gates: [sources, links, interaction, editorial]
+objectives:
+ - Distinguish the environment host from the client displaying it.
+ - Choose a connection route for local and remote work.
+ - Operate multiple machines without losing track of execution location.
+keywords: [environment, web, desktop, mobile, T3 Connect, Tailscale, SSH, pairing]
+sourceAreas: [AGENTS.md, docs/user/remote-access.md, docs/user/background-service.md, docs/user/mobile-notifications.md, docs/user/devices.md]
+visuals: [multi-surface environment topology]
+updatedAt: "2026-09-11"
+---
+
+import Callout from "../../components/Callout.astro";
+import Mermaid from "../../components/Mermaid.astro";
+
+An environment is the machine-side boundary of T3 Code: one running server, its
+filesystem, provider credentials, project records, threads, terminals, Git tools,
+and device integrations. A client is a view and control surface for one or more
+environments.
+
+This is why the same thread can appear on a laptop and phone without moving its
+workspace. Both clients address the environment that already owns it.
+
+ L
+ D --> T
+ D --> C
+ D --> S
+ W --> L
+ W --> T
+ W --> C
+ M --> L
+ M --> T
+ M --> C
+ L --> E[Environment server]
+ T --> E
+ C --> E
+ S --> E
+ E --> F[(workspace files and Git)]
+ E --> P[provider runtimes and credentials]
+ E --> H[terminals, browsers, and device hosts]
+ E --> R[(threads and settings)]`} />
+
+## Choose the client for the moment
+
+| Surface | Strongest use | Product limits to remember |
+|---|---|---|
+| Desktop | Primary workstation, local hosting, SSH environments, SnapShots, native preview/browser integration | Native features and host setup are machine-specific. |
+| Local web | Quick command-line launch and full browser-based workspace | The terminal process or background service must keep the server alive. |
+| Hosted web at `app.t3.codes` | Reach HTTPS-exposed environments without installing a client | It connects directly to your endpoint; it cannot make an unreachable server reachable. |
+| Mobile | Notifications, approvals, questions, follow-ups, diffs, and remote supervision | Provider setup and some authoring features remain on web/desktop. |
+
+Mobile stores drafts and queued messages locally, so a temporary disconnect does
+not force you to rewrite a prompt. Upload and delivery resume when the environment
+reconnects. This is valuable on unreliable networks, but a queued instruction has
+not affected the workspace until it actually sends.
+
+## Choose a connection route
+
+### Same machine or private LAN
+
+The local desktop and `npx t3@latest` paths are simplest for one machine. For a
+second device on a reachable private network, start the server on a reachable
+address and create a one-time pairing link:
+
+```bash
+npx t3 serve --host
+npx t3 pair
+```
+
+Scan the QR code or paste the URL into **Add environment**. A `127.0.0.1` URL only
+works on the host itself. Each new device needs a fresh pairing link, but an
+already paired device reconnects without the original token.
+
+### Tailscale HTTPS
+
+If both devices share a tailnet, enable **Tailscale HTTPS** in desktop Connections
+or run `npx t3 serve --tailscale-serve`. For an existing server,
+`npx t3 pair --tailscale` creates a persistent Tailscale Serve mapping and a
+pairing URL. This path is especially useful for the hosted web client because it
+provides HTTPS.
+
+### T3 Connect
+
+T3 Connect links environments and clients signed into the same T3 account without
+router forwarding. Enable it in desktop Connections or run:
+
+```bash
+npx t3@latest connect
+```
+
+Signing in saves the connection identity; it does not keep the server running.
+Use the desktop host, `npx t3 serve`, or a background service as well. T3 Connect
+is required for background mobile push notifications; a direct or Tailscale link
+alone does not deliver those pushes.
+
+### Desktop-managed SSH
+
+Use **Settings → Connections → Add environment → SSH** when a remote machine
+already holds the repository and provider login. Desktop starts or reuses a T3
+server over SSH and manages the port forward. Node and providers must work in a
+non-interactive shell. A version manager configured only in an interactive shell
+is a common source of “binary not found” errors.
+
+
+ Treat pairing URLs and returned authorization codes like passwords. Do not put
+ them in screenshots, logs, issues, or documentation. Revoke unused links and
+ client sessions from the host's Connections settings.
+
+
+## Work across several environments
+
+The same repository may exist on a laptop, workstation, and VM. T3 Code can group
+those checkouts for presentation, but each one remains an independent workspace.
+Provider logins, environment variables, settings, uncommitted files, running
+processes, and available models can differ.
+
+New-thread **Auto balance** can select among grouped environments using current CPU
+and memory signals. Give each machine a preference: **Prefer**, **Normal**, **Less
+often**, or **Manual only**. The chosen environment becomes stable for that draft;
+selecting a specific branch or worktree also fixes the choice. Existing threads
+never migrate.
+
+Use manual selection when data locality matters—for example, a secret exists only
+on one host, an emulator runs on a Mac, or a large build cache lives on a
+workstation. Load balancing is a convenience for equivalent checkouts, not a file
+or credential synchronization mechanism.
+
+## Remote devices and notifications
+
+The Device panel streams iOS Simulators and Android Emulators from the environment
+or a configured SSH device host. Secure pages (HTTPS or localhost) support live
+video. Plain HTTP remote access degrades iOS to still images and cannot show
+Android video. The simulator's `localhost` is not automatically the environment's
+development server; arrange Metro or other dev-server reachability separately.
+
+With T3 Connect and **Device Notifications** enabled, mobile alerts when work
+finishes, fails, asks a question, or needs approval. iOS Live Activities and
+Android ongoing activity can show progress. Normal alerts stay quiet while the app
+is foregrounded. Viewing the thread on another device does not silence the phone.
+
+## Operate a host responsibly
+
+- Keep an always-on host awake and its service running.
+- Install Git, providers, SDKs, and device tools on the environment or configured
+ device host.
+- Update the server named in a version-mismatch notice.
+- Use **Settings → Connections** or `t3 connect status` to inspect configuration;
+ use service status and logs to diagnose reachability.
+- Revoke a client session when a device is lost or should no longer connect.
+- Deregister unused T3 Connect environments; unlinking exposure and uninstalling a
+ background service are separate actions.
+
+### Source trail
+
+Sources: [remote access](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/remote-access.md),
+[background service](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/background-service.md),
+[mobile notifications](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/mobile-notifications.md), and
+[devices](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/devices.md).
diff --git a/src/content/book/08-projects-threads-worktrees.mdx b/src/content/book/08-projects-threads-worktrees.mdx
new file mode 100644
index 0000000..4232aa2
--- /dev/null
+++ b/src/content/book/08-projects-threads-worktrees.mdx
@@ -0,0 +1,172 @@
+---
+slug: projects-threads-worktrees
+order: 40
+number: "4"
+kind: chapter
+part: Part I · Product guide
+partOrder: 1
+title: Organize projects, threads, and worktrees
+shortTitle: Projects and threads
+summary: Structure agent work so each task has a clear project, durable conversation, workspace, branch, review link, and lifecycle.
+status: source-checked
+gates: [sources, links, interaction, editorial]
+objectives:
+ - Choose between the current checkout and a new worktree.
+ - Run parallel tasks without mixing branches or conversations.
+ - Use thread states and links to keep active work understandable.
+keywords: [projects, threads, worktrees, branches, parallel work, settlement]
+sourceAreas: [docs/user/thread-sidebar.md, docs/user/project-settings.md, docs/user/source-control.md, docs/user/welcome-wizard.md]
+visuals: [work organization lifecycle]
+updatedAt: "2026-09-11"
+---
+
+import Callout from "../../components/Callout.astro";
+import Mermaid from "../../components/Mermaid.astro";
+
+A project answers “which repository or folder?” A thread answers “which task and
+conversation?” A workspace answers “which working directory and branch?” Keep
+those three choices aligned and T3 Code can support many simultaneous agents
+without turning their output into an undifferentiated queue.
+
+## Pick the workspace before sending
+
+| Choice | Use it when | Main risk |
+|---|---|---|
+| Current checkout | The task is exclusive, read-only, or intentionally continues its current branch | Parallel agents can edit the same files and Git index. |
+| New worktree | The task should have its own branch and working directory | More local checkouts consume disk and need normal branch cleanup later. |
+| Existing worktree | A second thread should inspect or continue work already isolated there | Two writing agents can still conflict if they operate concurrently. |
+
+For most independent implementation tasks, **New worktree** is the safest default.
+It isolates both the branch and filesystem changes. A new thread alone isolates the
+conversation; it does not necessarily isolate files.
+
+ W{Workspace choice}
+ W -->|current checkout| C[Use existing directory and branch]
+ W -->|new worktree| N[Create separate directory and branch]
+ W -->|existing worktree| E[Select that checkout]
+ C --> T[Start durable thread]
+ N --> T
+ E --> T
+ T --> A[Agent turns, approvals, questions, checkpoints]
+ A --> I[Inspect diff, tools, terminal, and delegated agents]
+ I --> F{More work?}
+ F -->|follow-up| A
+ F -->|review| R[Commit, push, or link pull requests]
+ R --> M{Work complete?}
+ M -->|no| A
+ M -->|yes| S[Settle thread]
+ S -->|resume later| U[Un-settle and continue]
+ U --> A`} />
+
+## Start a thread with explicit intent
+
+On web and desktop, a new thread keeps the current project and carries the current
+model and permission selections. Project defaults can override the remembered
+model, while configured workspace defaults determine branch and checkout behavior.
+Changing the project keeps the current environment when that project exists there;
+otherwise T3 Code selects an environment that has it.
+
+Use **New thread in this worktree** from the branch toolbar when a new conversation
+should share an existing isolated checkout. This is useful for a review pass after
+the implementation agent finishes. Avoid concurrent edits unless you explicitly
+want both threads writing the same files.
+
+To dispatch several tasks, press `Cmd+Enter` on macOS or `Ctrl+Enter` on Windows
+and Linux. T3 Code starts the task and immediately gives you another draft. With
+**New worktree**, every background submission gets its own worktree.
+
+
+ Two threads in the same checkout can overwrite each other's files, change the
+ same index, or move the branch underneath one another. Use worktrees for
+ simultaneous coding tasks; use extra threads in one checkout mainly for staged
+ handoffs or read-only analysis.
+
+
+## Configure projects at the right scope
+
+Open **Settings → Projects** to set defaults for model, workspace behavior,
+automatic pull, agent browser access, and project actions.
+
+- **All projects** defines values inherited by projects without overrides.
+- Selecting one project creates or removes explicit overrides.
+- **All machines** writes defaults to connected machines; offline machines keep
+ their previous values.
+- `t3.json` workspace preferences beat machine defaults when the project has no
+ explicit workspace override.
+- Shared project actions remain inherited until you edit a project's list; reset
+ it to inherit again. Editing the list creates an independent copy and preserves
+ existing actions.
+
+Project grouping is a client-level presentation choice across machines. Names,
+icons, removal, and imported actions still apply to selected checkouts. When
+several checkouts exist, use the checkout picker and inspect mixed-value markers
+before changing settings.
+
+Choose an icon, emoji, or project image to make similar checkouts recognizable
+across connected clients. **Automatic** returns to T3 Code's detection. Agent
+browser-access changes take effect when a new agent session starts, so restart the
+session before testing a changed policy.
+
+Enable **Automatically pull** only for a clean default-branch checkout with an
+upstream. T3 Code fast-forwards; it skips a dirty checkout, untracked files, local
+commits, another branch, or missing upstream. The skip protects local work—it is a
+signal to reconcile the checkout yourself.
+
+## Treat the sidebar as a work queue
+
+Thread states express attention, not repository state:
+
+| State | Meaning | Use |
+|---|---|---|
+| Pinned | High-priority active work | Keep a task above the active list. |
+| Active | Current work | Normal place for running and recently handled threads. |
+| Snoozed | Intentionally hidden until a wake time | Park a dependency or scheduled follow-up. |
+| Settled | Finished or no longer needing attention | Clear the active queue without deleting history. |
+
+Drag threads within and between sections on web/desktop; use **Arrange threads** on
+mobile. Ordering persists across connected clients. New threads appear above
+manually arranged active work. Activity does not continuously reorder the list.
+
+By default, environments can settle inactive threads after three days and settle
+threads after linked pull requests merge. Live work, pending approval, unanswered
+questions, and background work prevent automatic settlement. Tune these rules in
+**Settings → General**. Un-settling restores a thread and temporarily protects it
+until new activity resumes normal rules.
+
+Pinning does not prevent settlement, and settling clears the pin. Manually settling
+an idle thread dismisses unanswered asynchronous questions without sending an
+answer. An open pull request does not block inactivity settlement; a closed pull
+request settles only idle work and does not settle a thread whose work resumed
+after that review closed. If reordering is unavailable for one environment, update
+that environment's server.
+
+## Keep review context with the task
+
+T3 Code detects a pull request for an unsettled thread's saved branch. You can also
+link several pull requests—including reviews from another repository on the same
+host—from the command palette, the Linked pull requests panel, or a PR context
+menu. Creating a PR through thread Git actions links it automatically.
+
+This makes the thread the operational record for the change: prompt, agent work,
+branch, diffs, review discussion, and completion state. For stacked GitHub work,
+the Pull Requests surface shows layers and can merge or rebase a stack when the
+environment supports it. Rebase-stack rewrites remote branch history and can
+restart checks, so inspect its confirmed scope first.
+
+## Find and inspect work
+
+- Open the command palette with `Cmd/Ctrl+K` to search threads across connected
+ environments. Message search begins after two characters and includes user
+ prompts and final agent responses.
+- Copy a thread reference when another task needs it. T3 Code prefers its pull
+ request URL when one is available.
+- Expand tool calls to see full commands and results.
+- Open **Agents** on web or desktop to follow delegated subagent activity.
+- Drag files onto a thread row to open it and attach the files to its composer.
+
+### Source trail
+
+Sources: [working with threads](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/thread-sidebar.md),
+[project settings](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/project-settings.md), and
+[source control](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/source-control.md).
diff --git a/src/content/book/09-composer-context.mdx b/src/content/book/09-composer-context.mdx
new file mode 100644
index 0000000..bddec62
--- /dev/null
+++ b/src/content/book/09-composer-context.mdx
@@ -0,0 +1,209 @@
+---
+slug: composer-context
+order: 50
+number: "5"
+kind: chapter
+part: Part I · Product guide
+partOrder: 1
+title: Compose tasks with the right context
+shortTitle: Composer and context
+summary: Write actionable prompts and add files, citations, skills, commands, SnapShots, and follow-up answers without losing drafts or overloading a turn.
+status: source-checked
+gates: [sources, links, interaction, editorial]
+objectives:
+ - Build a task message from goal, constraints, evidence, and finish condition.
+ - Choose the right context mechanism for each kind of information.
+ - Recover and reuse prompts safely across devices and environments.
+keywords: [composer, context, attachments, citations, skills, commands, snapshots, prompts]
+sourceAreas: [docs/user/composer.md, docs/user/question-attachments.md, docs/user/snap-shot.md, docs/user/keybindings.md]
+visuals: [context selection flow]
+updatedAt: "2026-09-11"
+---
+
+import Callout from "../../components/Callout.astro";
+import Mermaid from "../../components/Mermaid.astro";
+
+The composer turns intent into an agent turn. A strong request says what outcome
+you want, names the relevant boundary, supplies evidence the agent cannot infer,
+and defines how to know the work is done. T3 Code then lets you attach different
+kinds of context without flattening everything into pasted prose.
+
+## Build a useful task
+
+A practical message has four parts:
+
+1. **Outcome:** the behavior, answer, or artifact you want.
+2. **Scope:** the project area and what is in or out.
+3. **Evidence and constraints:** files, screenshots, quoted responses, issue text,
+ compatibility needs, or repository instructions.
+4. **Finish condition:** tests, review evidence, file format, or an explicit report.
+
+For example: “Fix the empty search result state in the mobile project. Match the
+attached design and preserve tablet layout. Run the focused component tests and
+report the files changed.” The task is concrete without prescribing an internal
+implementation before the agent inspects the code.
+
+ F{A file or media asset?}
+ F -->|yes| A[Attach or paste it]
+ F -->|no| R{Exact part of an earlier response?}
+ R -->|yes| C[Cite selected text]
+ R -->|no| V{Another app window is the evidence?}
+ V -->|yes| S[Capture a SnapShot on desktop]
+ V -->|no| K{Reusable provider workflow?}
+ K -->|yes| SK[Select a skill with dollar]
+ K -->|no| M{Provider or T3 operation?}
+ M -->|yes| CMD[Select a slash command]
+ M -->|no| P[Write it directly in the prompt]
+ A --> Q[Review task, model, and permission mode]
+ C --> Q
+ S --> Q
+ SK --> Q
+ CMD --> Q
+ P --> Q
+ Q --> SEND[Send when uploads finish]`} />
+
+## Attach files and media
+
+Each message accepts up to eight files. Images may be up to 10 MB and other files
+up to 50 MB, subject to the selected environment's upload support and limit.
+Uploads start immediately but the message cannot send until all finish. Retry or
+remove a failed upload.
+
+Web and desktop accept dragged or pasted images. HEIC and HEIF photos become JPEG
+in those clients and when selected from iOS; the size limit applies after
+conversion. Mobile also accepts files through the system share sheet.
+
+Attachments upload to the environment machine. That matters for two reasons:
+
+- a remote provider receives environment-side paths, not paths on your phone;
+- a stash containing uploaded files can only be restored in its original
+ environment.
+
+Mobile keeps local draft attachments and queued messages through disconnects and
+app restarts, then resumes uploads. Signing out of T3 Connect keeps that work on
+the device, but it is restored only after signing back into the same account. On
+web and desktop, reloading during an upload means attaching that file again.
+
+### Preview and keep message files
+
+Select an image or video to preview it. On web and desktop, its context menu can
+save the media or copy its path or URL; on mobile, touch and hold to save or share.
+Playback support depends on the client, so save a video when its format cannot play
+in place. A linked environment file remains the original file: moving or deleting
+it can break the preview.
+
+Agent links can open files outside the workspace read-only. An outside-workspace
+HTML file cannot load neighboring scripts, styles, or images. Web and desktop can
+render HTML and PDF; switch HTML to source when markup matters, and a line link
+opens source automatically. Rendered HTML cannot access the T3 Code session.
+Mobile opens PDFs through the native iOS viewer or Android's system chooser.
+
+## Cite, recall, or stash instead of rewriting
+
+On web and desktop, select text inside one assistant response and choose **Cite in
+composer**. Add a comment explaining what should change. The quote remains readable
+even if its source later becomes unavailable; selecting it navigates back when the
+source still exists. Mobile displays citations but does not create them.
+
+Press `ArrowUp` in an empty composer to recall sent prompt text in the current
+thread, and `ArrowDown` to move forward. Recall restores only typed text—not
+attachments, terminal context, or other extras. Once you edit recalled text it
+becomes a normal draft.
+
+Use `Cmd+S` or `Ctrl+S` on web/desktop to stash the current prompt and attachments.
+With an empty composer, the shortcut restores one stash or opens the stash menu.
+Uploaded files remain available for 24 hours; after expiry, restore the text and
+attach the missing file again.
+
+
+ Text can be reused broadly, but an uploaded file belongs to the environment that
+ received it and expires from a stash after 24 hours. Keep the source file if the
+ task may move machines or wait longer.
+
+
+## Use commands and skills
+
+Type `/` to open commands and `$` to select a skill available for the chosen
+environment and provider. Mobile exposes both on **New task** as well.
+
+Provider-native commands must begin the message. T3 Code commands such as
+`/model` and `/plan`, plus skill mentions, can appear on any line. `/compact`
+reduces context for a supported existing conversation; web and desktop also expose
+this action from the context meter.
+
+Skills are best for repeatable procedures with their own instructions or tools.
+Choose one when the task matches it; do not add skills merely because they are
+available. Provider configuration controls which skills appear, and provider rules
+can affect whether several named skills run in one message. Provider-specific skill
+rules are collected in [Choose providers, models, accounts, and permissions](../providers-models-permissions/).
+
+## Dictate a draft on iPhone
+
+On a supported iPhone with iOS 26 or later, choose the microphone, record for up to
+five minutes, and confirm to transcribe. The text is inserted at the selection you
+had when recording began; review names, paths, and commands before sending.
+
+The first use may download Apple's speech model and needs a network connection.
+Later transcription for that language runs on the device and can work offline.
+Canceling, leaving the screen, or an audio interruption discards the recording but
+keeps the existing draft. T3 Code deletes temporary audio after transcription or
+cancellation; the submitted message contains the text.
+
+## Capture visual context with SnapShots
+
+The desktop app can capture another application window and attach the image to the
+current draft. A SnapShot carries the app name and window title and can include
+accessibility text, controls, and element positions. That richer context helps an
+agent reason about an error dialog or target interface beyond raw pixels.
+
+Enable **Settings → SnapShots**, grant platform permissions, and choose a global
+shortcut. The default on macOS and Windows is both Shift keys. Switch to the target
+window and press the shortcut; T3 Code attaches the capture and returns to the
+draft. Captures persist on disk until attached, so closing the app during handoff
+does not necessarily lose them.
+
+Turn **Include app text** off when the screenshot alone is appropriate. Accessible
+content varies by application, and T3 Code falls back to the image if an app is too
+slow. SnapShots support macOS, Windows, and Wayland Linux; X11 is unsupported and
+individual Wayland desktops have different setup requirements.
+
+## Answer questions without disturbing the main draft
+
+When an agent asks a question with custom input, its answer can include up to eight
+attachments across the answer set. Each question keeps its own files, separate from
+the normal composer draft. Files upload to the thread's environment and remain in
+history after submission. Questions restricted to fixed choices do not accept
+attachments.
+
+A failed response keeps its answer draft so you can retry. Reverting a thread
+removes files attached to discarded answers; deleting the thread applies the same
+cleanup as other message attachments. If attachment controls do not appear on a
+custom-answer question, update the environment server.
+
+This is useful when the agent discovers missing evidence mid-turn: attach the
+failing screenshot or sample document directly to the question rather than canceling
+the task and rebuilding the main prompt.
+
+## Context hygiene for long-running work
+
+- Start a new thread for a separate task; context relevance usually matters more
+ than conversation length.
+- Use a follow-up in the same thread when it depends on its decisions and changes.
+- Cite the exact disputed sentence instead of pasting a whole response.
+- Attach source evidence; summarize what the agent should learn from it.
+- Compact a supported long conversation when the context meter or provider suggests
+ it, then restate any constraint that must survive summarization.
+- Remember that links to environment files can break if those files move or are
+ deleted. Save durable artifacts inside the project when appropriate.
+
+Messages support up to 120,000 characters. An oversized draft stays in the composer
+so you can split it. Several focused turns are usually easier to review than one
+message that combines unrelated work.
+
+### Source trail
+
+Sources: [messages and context](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/composer.md),
+[question attachments](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/question-attachments.md),
+[SnapShots](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/snap-shot.md), and
+[keybindings](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/keybindings.md).
diff --git a/src/content/book/10-control-surface.mdx b/src/content/book/10-control-surface.mdx
index 030f93e..4b2e1b3 100644
--- a/src/content/book/10-control-surface.mdx
+++ b/src/content/book/10-control-surface.mdx
@@ -1,10 +1,10 @@
---
slug: control-surface
-order: 10
-number: "1"
+order: 160
+number: "16"
kind: chapter
-part: Part I · Boundaries and vocabulary
-partOrder: 1
+part: Part II · Boundaries and vocabulary
+partOrder: 2
title: Control surface, not agent brain
shortTitle: The ownership boundary
summary: For each environment, T3 Code authoritatively coordinates repository and provider execution without replacing a provider's model loop, native context, or authentication.
@@ -17,7 +17,7 @@ objectives:
keywords: [control surface, harness, ownership, server, provider adapter]
sourceAreas: [docs/internals/overview.md, apps/server/src/server.ts, apps/server/src/provider/Services/ProviderAdapter.ts]
visuals: [ownership matrix, server capability assembly]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -61,9 +61,9 @@ binding and recovery state.
## A normalized, deliberately bounded seam
-
+
-
+
The contract is not a promise of feature equality. Its lifecycle, interaction,
history, rollback, feedback, and event-stream surface is deliberately bounded, but
diff --git a/src/content/book/100-events-receipts.mdx b/src/content/book/100-events-receipts.mdx
index 86fa0a1..2022825 100644
--- a/src/content/book/100-events-receipts.mdx
+++ b/src/content/book/100-events-receipts.mdx
@@ -1,10 +1,10 @@
---
slug: events-receipts
-order: 100
-number: "10"
+order: 250
+number: "25"
kind: chapter
-part: Part III · Transactional domain core and post-commit delivery
-partOrder: 3
+part: Part IV · Transactional domain core and post-commit delivery
+partOrder: 4
title: Events, receipts, idempotency, and the post-commit gap
shortTitle: Events and receipts
summary: Events record durable domain facts, command receipts bind an id to one aggregate but not its payload, and hot publication after commit leaves a crash window that an acknowledgement cannot close.
@@ -18,7 +18,7 @@ objectives:
keywords: [events, command receipts, idempotency, retry, sequence, publication, PubSub, crash window]
sourceAreas: [packages/contracts/src/orchestration.ts, apps/server/src/persistence/Layers/OrchestrationEventStore.ts, apps/server/src/persistence/Services/OrchestrationCommandReceipts.ts, apps/server/src/orchestration/Layers/OrchestrationEngine.ts, apps/server/src/orchestration/Layers/ProviderCommandReactor.ts]
visuals: [event envelope ledger, transaction boundary, duplicate-command matrix, crash-window explorer]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -75,7 +75,7 @@ The event store therefore has two orders with different visibility:
- a per-stream `stream_version`, computed and stored internally.
The per-stream version is not an expected-version token in the command protocol.
-As Chapter 9 showed, one serialized command worker prevents concurrent decisions
+As Chapter 24 showed, one serialized command worker prevents concurrent decisions
inside a server process.
## A receipt is smaller than the command it deduplicates
@@ -111,7 +111,7 @@ cannot catch changed intent within the same aggregate.
-
+ T
subgraph T[one SQL transaction]
diff --git a/src/content/book/11-providers-models-permissions.mdx b/src/content/book/11-providers-models-permissions.mdx
new file mode 100644
index 0000000..8066895
--- /dev/null
+++ b/src/content/book/11-providers-models-permissions.mdx
@@ -0,0 +1,250 @@
+---
+slug: providers-models-permissions
+order: 60
+number: "6"
+kind: chapter
+part: Part I · Product guide
+partOrder: 1
+title: Choose providers, models, accounts, and permissions
+shortTitle: Providers and permissions
+summary: Configure agent runtimes per environment, select models and account instances, and choose a permission mode that matches the task and provider.
+status: source-checked
+gates: [sources, links, interaction, editorial]
+objectives:
+ - Choose a provider and model based on capability and environment setup.
+ - Configure separate accounts or endpoints without mixing provider state.
+ - Set a permission mode with a clear understanding of provider differences.
+keywords: [providers, models, accounts, Codex, Claude, Cursor, Grok, OpenCode, Antigravity, permissions]
+sourceAreas: [docs/user/install.md, docs/user/permission-modes.md, docs/user/providers-codex.md, docs/user/providers-claude.md, docs/user/providers-opencode.md, docs/user/providers-antigravity.md, docs/user/usage.md]
+visuals: [turn configuration decision tree]
+updatedAt: "2026-09-11"
+---
+
+import Callout from "../../components/Callout.astro";
+import Mermaid from "../../components/Mermaid.astro";
+
+Every thread combines four decisions: the provider runtime, a configured provider
+instance, a model and its options, and a permission mode. They are related but not
+interchangeable. “Codex Work” and “Codex Personal” can be separate instances of
+one provider; each can expose several models; the thread can run any of them under
+Supervised, Auto-accept edits, Auto, or Full access.
+
+ H{Which provider is installed and suited to task?}
+ H --> I[Choose configured instance and account]
+ I --> M[Choose catalog or custom model]
+ M --> O[Set supported options: reasoning, tier, variants]
+ O --> R{How much review does this task need?}
+ R -->|inspect every action| S[Supervised]
+ R -->|edits can flow| AE[Auto-accept edits]
+ R -->|provider can review routine actions| A[Auto]
+ R -->|trusted task and environment| F[Full access]
+ S --> T[Send turn]
+ AE --> T
+ A --> T
+ F --> T
+ T --> Q{Native provider request or question?}
+ Q -->|yes| U[Respond in conversation]
+ Q -->|no| X[Agent continues]`} />
+
+## Start with environment reality
+
+Provider installation and authentication live on the environment machine. Enable
+instances in **Settings → Providers** for that environment. If the executable is
+not on the server's `PATH`, set its binary path. Environment variables on an
+instance are appropriate for API keys, base URLs, and router configuration; launch
+arguments are for CLI arguments.
+
+| Provider | Important product behavior |
+|---|---|
+| Codex | Supports shared-home account switching, asynchronous questions, app-access approvals, and `/feedback`. |
+| Claude | Supports separate config-directory instances, configurable auto-compaction, skills, and router endpoints. |
+| Cursor | Uses Cursor CLI and participates in automatic permission review. |
+| Grok Build | Supports remembered matching approvals for a session. |
+| OpenCode | Can run a local managed server or connect to an external one; Auto falls back to supervised behavior. |
+| Antigravity | Uses an account-specific ACP runtime and T3-managed sign-in; lacks T3 Plan mode and thread rewind. |
+
+Choose for the task and the account you actually want charged. A familiar model
+name does not imply equivalent tools or continuation semantics across providers.
+
+## Configure more than one account
+
+Provider instances let one environment expose separate accounts, endpoints, or
+presets. Give instances names that communicate their boundary, such as **Claude
+Work**, **Claude Router**, or **Codex Personal**.
+
+### Codex shared and separate homes
+
+Codex can switch accounts in an existing thread when instances share the same
+`CODEX_HOME`. A shadow home supplies another account's login and model catalog
+while shared sessions and configuration remain available. Keep the primary home
+at `~/.codex`, sign the second account into a fresh directory, and configure both
+instances with the same main home plus the second instance's shadow path.
+
+Use completely separate `CODEX_HOME` paths when sessions and configuration must
+also be isolated. Those instances cannot continue one another's threads. Do not
+populate a shadow home by copying the whole primary Codex directory; start fresh
+and log in. The shadow account needs its own `auth.json`; configure Codex to store
+credentials in a file if the login otherwise lives in an OS credential store.
+
+If an account is absent from the thread picker, compare the instances' main and
+shadow paths, refresh provider status, and verify the account each reports. Two
+instances unexpectedly showing the same account usually means the shadow directory
+was copied instead of created fresh.
+
+Codex app tools can request access for one operation, the current session, or
+permanently; read the named app and scope before approving. A usage-limit message
+can name its window and reset time. Retry after reset, or follow the workspace-plan
+instruction to add credits or raise its spend limit. `/feedback` deliberately
+uploads the conversation and Codex logs to OpenAI and returns an ID for support.
+
+### Claude config directories
+
+Claude isolates accounts and presets with `CLAUDE_CONFIG_DIR`. Sign in using the
+same directory that the provider instance will set. Changing `HOME` is not an
+equivalent substitute because credentials can remain in system keychains or other
+locations. Existing threads can switch only among compatible Claude instances
+that use the same config directory.
+
+Claude instances can route through OpenRouter or another compatible endpoint using
+environment variables. Give router presets separate config directories and follow
+the router's current compatibility guidance. For OpenRouter, set
+`ANTHROPIC_BASE_URL`, put the key in `ANTHROPIC_AUTH_TOKEN`, and set
+`ANTHROPIC_API_KEY` to an explicitly empty value. Run `/logout` first if that config
+directory has a cached Anthropic login. Any local router must be reachable from the
+environment machine.
+
+Claude loads skills from the config directory and the project's `.claude/skills`,
+with the config copy winning on duplicate names. A skill marked
+`disable-model-invocation` can still be selected manually, but invoke these one per
+message. When a subscription limit is reached, Claude can hold the turn until the
+window reopens; stop it if you prefer to continue later.
+
+### OpenCode and Antigravity instances
+
+OpenCode can launch locally when **Server URL** is blank or connect to an existing
+server. A configured password applies to the local server and T3 Code's connection;
+without one, the local server can use `OPENCODE_SERVER_PASSWORD`. For an external
+server, configure its URL and password explicitly—T3 Code does not forward that
+local environment value. T3 Code requires OpenCode 1.14.19 or newer at this source
+revision. After a dropped connection, send another prompt to reconnect the same
+session.
+
+Antigravity instances each have their own Google sign-in; managed runtime files
+are shared by the environment. Remote Google callbacks return to `127.0.0.1` on
+the environment. Copy the complete returned URL into the setup form instead of
+changing its hostname. The URL contains a temporary code and should be kept
+private.
+
+Provider setup is available on web and desktop, not mobile. Besides a personal
+Google account, an instance can use Gemini Enterprise, a Gemini API key, or Agent
+Platform / Vertex AI credentials. The selected method and its fields control the
+agent; ambient Gemini credential variables do not override them. The Antigravity
+API-key field is stored as plain text in environment settings. Changing methods
+stops that instance's sessions, so sign out before replacing an account.
+
+Managed installation supports Apple Silicon macOS, Linux x64/ARM64, and Windows
+x64/ARM64 and can need several gigabytes. A manual install requires the ACP binary
+and `localharness_external` helper at the same version in one directory. Intel Macs
+can use a supported remote environment.
+
+## Choose a model and defaults
+
+The composer model picker selects the provider instance, model, and supported
+options for the thread. T3 Code remembers the selection for new threads. A project
+model default takes precedence; resetting the project setting returns to the
+remembered choice.
+
+Web and desktop can add unlisted custom models under **Settings → Providers →
+Models**. Only options implemented by that provider adapter have an effect.
+Antigravity uses its account-provided catalog and does not accept custom models.
+Leaving reasoning level or service tier unset delegates the choice to provider
+configuration.
+
+Refresh provider status after changing credentials, native configuration, or the
+available model catalog. Existing threads retain their selected model even if it
+disappears; if the provider rejects it, pick an available model and retry.
+
+For OpenCode, web and desktop use **Refresh provider status** and mobile uses
+**Refresh models**. Reconnecting also refreshes the catalog; periodic health checks
+do not. Allow the local helper to sit idle for 30 seconds before refreshing native
+configuration again, or restart or reload an external server when it owns the
+cache.
+
+## Choose permission mode per thread
+
+| Mode | T3 Code intent | Good starting use |
+|---|---|---|
+| **Supervised** | Ask before commands and file changes, though some providers allow read-only actions | Unfamiliar repository, sensitive environment, or first run with a provider. |
+| **Auto-accept edits** | Let edits proceed; other actions may still ask | Focused code changes where command execution deserves review. |
+| **Auto** | Ask the provider's automatic reviewer to approve routine actions | Routine work with Codex, Claude, or Cursor. |
+| **Full access** | Permit commands and edits without T3 approval prompts | Trusted, bounded work in an isolated workspace. |
+
+New threads default to **Full access** unless you change the mode before sending.
+A thread created from another thread inherits its mode. Approval cards appear in
+the conversation; approve or reject them there. Permission modes do not stop an
+agent from asking ordinary task questions.
+
+
+ Providers enforce these choices differently. Auto behaves like Supervised for
+ OpenCode and Antigravity because they lack the same automatic reviewer.
+ Antigravity can still issue native approvals in Full access. Always judge the
+ actual request shown in the conversation.
+
+
+OpenCode requires approval for `.env` and `.env.local` reads in restricted modes,
+while `.env.example` is allowed. Its **Allow for workspace** decision can affect
+matching requests in other sessions on the same workspace, especially when using a
+shared external server. Grok's **Always allow this session** remembers a matching
+command or tool input, not blanket authority for every future action.
+
+Denying one OpenCode action does not stop the whole turn. Antigravity fixed-choice
+questions still require one offered answer even in Full access.
+
+## Know the provider-specific limits
+
+- Codex asynchronous questions can remain pending through reconnects; dismissing a
+ question closes it without sending an answer.
+- Claude can auto-compact between 100,000 and 1,000,000 tokens, or compact on
+ demand with `/compact`. This changes timing, not the model context window.
+- OpenCode configuration may remain cached while its local helper stays alive;
+ repeated refreshes can keep that helper alive.
+- Antigravity uses its native `/plan`; T3 Code Plan mode is unavailable. It cannot
+ rewind provider conversation state, so edit-and-resubmit and thread revert are
+ unavailable even though T3 Code retains history and diffs.
+- Antigravity's direct attachment limits can be lower than T3 Code's general upload
+ limits: 1 MiB per text file, 10 MiB per image, 20 MiB per audio clip, and 50 MiB
+ total per message. It accepts supported images, PDFs, text, and audio; a successful
+ T3 upload does not guarantee provider acceptance.
+- Antigravity discovers project skills in `.gemini/skills`, `.agents/skills`, then
+ legacy `.agent/skills` precedence, and global skills under its Gemini config
+ directories. Its subagents appear as batches: individual children cannot be
+ opened or controlled, and an idle batch does not prove every child succeeded.
+
+Disabling an Antigravity instance stops sessions but keeps its login. Signing out
+also removes that instance's saved login; removing the managed runtime keeps logins
+and thread or workspace data. Before runtime removal, disable instances, cancel an
+active installation, and clear paths that point into the managed runtime.
+
+Usage estimates, pooled reset windows, and custom pricing are explained once in
+[Personalize, measure usage, update, and protect privacy](../personalize-usage-updates/).
+
+### A practical selection checklist
+
+Before a consequential turn, verify:
+
+1. the environment contains the intended checkout and credentials;
+2. the provider instance names the right account or endpoint;
+3. the selected model exists and supports the needed capability;
+4. the permission mode matches both workspace isolation and task risk;
+5. provider-specific limitations do not invalidate the workflow;
+6. any usage or reset window is adequate for the task.
+
+### Source trail
+
+Sources: [permission modes](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/permission-modes.md),
+[Codex](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/providers-codex.md),
+[Claude](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/providers-claude.md),
+[OpenCode](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/providers-opencode.md),
+[Antigravity](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/providers-antigravity.md), and
+[usage](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/usage.md).
diff --git a/src/content/book/110-projections-read-models.mdx b/src/content/book/110-projections-read-models.mdx
index 2aaea7c..b53f9eb 100644
--- a/src/content/book/110-projections-read-models.mdx
+++ b/src/content/book/110-projections-read-models.mdx
@@ -1,10 +1,10 @@
---
slug: projections-read-models
-order: 110
-number: "11"
+order: 260
+number: "26"
kind: chapter
-part: Part III · Transactional domain core and post-commit delivery
-partOrder: 3
+part: Part IV · Transactional domain core and post-commit delivery
+partOrder: 4
title: Projection tables and read models
shortTitle: Projections
summary: New events fold through ordered SQLite projectors before the enclosing command commits; bootstrap replays committed events from per-projector cursors, and queries expose deliberately different read-model shapes.
@@ -17,7 +17,7 @@ objectives:
keywords: [projections, SQLite, read model, cursor, snapshot, replay, checkpoint]
sourceAreas: [apps/server/src/orchestration/Layers/ProjectionPipeline.ts, apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.ts, apps/server/src/persistence/Layers/ProjectionState.ts, apps/server/src/ws.ts]
visuals: [ordered projection fold, cursor watermark lab, read-model comparison]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -59,7 +59,7 @@ approval/input counts and whether a plan is actionable from current dependent ro
thread/shell fold last, after the tables it reads to derive shell summary fields.
-
+ P[projects]
P --> M[messages]
@@ -204,6 +204,20 @@ replace the global cursor.
the filesystem into a transactional resource.
+## Pull requests, ordering, and project presentation
+
+The projection schema keeps several user-facing facts independently queryable:
+manual active-thread order, unsettled timestamps, project auto-pull policy, project
+icons, branch-associated reviews, and the many-to-many link between threads and pull
+requests. This is why a review can remain attached to a thread even when it is not the
+branch’s primary review, and why a stack can be rendered as related layers rather than
+flattened into one URL.
+
+The migration sequence makes the ownership clear: migrations 42 and 48 introduce
+singular and branch-aware review state; migration 50 replaces that shape with plural
+thread pull requests. The projector, snapshot query, and clients then agree on the
+same graph. Browse the current [migration directory](https://github.com/pingdotgg/t3code/tree/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/apps/server/src/persistence/Migrations).
+
## Source trail
F[Files and diffs]
+ F --> T[Terminal command]
+ T --> B[Browser preview]
+ B --> O[Observe behavior]
+ O -->|page issue| A[Annotate or describe]
+ O -->|external app issue| S[SnapShot]
+ A --> P
+ S --> P
+ T -->|failure output| P`} />
+
+## Choose the surface that answers the question
+
+| Question | Open | Why it helps | Watch for |
+| --- | --- | --- | --- |
+| “What is in this file?” | **Files** | Browse the project tree and inspect source or media without leaving the thread. | A rendered preview can hide exact source; use the source view when syntax matters. |
+| “Does this command pass?” | **Terminal** | Run a shell on the environment that owns the project. | A remote project's terminal runs remotely, not on the device showing the UI. |
+| “Does the page behave correctly?” | **Preview/Browser** | Exercise the app beside the conversation and give the agent concrete UI feedback. | A server must listen on a reachable port; signed-in state belongs to the selected browser profile. |
+| “What is wrong in this other app?” | **SnapShot** | Capture the active desktop window and attach its visual and, when available, accessibility context. | Review sensitive content before sending; SnapShots are desktop-only and opt-in. |
+
+### Files: inspect before you redirect the agent
+
+Open the thread's right panel and choose **Files**. Navigate the workspace tree,
+select a file, and use the appropriate source, image, video, Markdown, or web
+preview. This is ideal for answering a narrow question—whether the agent edited
+the right component, whether a generated asset looks correct, or where a setting
+lives—without asking it to spend another turn rediscovering the file.
+
+Files are read from the selected environment. If you are controlling a server over
+SSH, Tailscale, or T3 Connect, the phone or laptop is only the viewer; the path and
+contents remain on the host. Treat the panel as an inspection surface, and use the
+conversation to request changes so the thread preserves the reason for the edit.
+
+### Terminal: run on the project's machine
+
+Open the terminal drawer from the thread or command palette, create a terminal,
+and run the smallest command that answers your question. Multiple terminals are
+useful when one process must keep running while another runs tests or Git commands.
+The terminal is a real shell owned by the environment, so its installed tools,
+credentials, filesystem, and network are those of the host.
+
+Terminal history survives client reconnection, within server limits: up to **5,000
+lines and 8 MiB per terminal**. The server removes the oldest output when either
+limit is crossed, and a client may display less than the server retained. Save
+important results in the project or summarize them in the thread; scrollback is a
+working buffer rather than permanent documentation. See the immutable
+[terminal history guide](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/terminal.md).
+
+
+ When a failure is already visible in a terminal, attach or reference that terminal
+ context instead of pasting a huge log. Include the command, the first meaningful
+ error, and what you expected. Long-running noise makes diagnosis harder.
+
+
+### Browser preview: close the implementation loop
+
+Start the application in a terminal, then open its discovered port in the preview.
+Use the preview to navigate, refresh, inspect the current page, and report behavior
+in the same thread that owns the code. If annotation tools are available, point to
+the affected region and describe the intended result. The useful prompt is concrete:
+“This menu clips at this width; keep it inside the viewport,” rather than “fix UI.”
+
+Desktop preview profiles can keep separate browsing identities. To reuse an
+existing signed-in session, open **Settings → Integrations → Browser profiles →
+Add profile**, select **Import from**, close the source browser, and complete any OS
+keyring prompt. Import is a **one-time cookie copy**: future sign-ins diverge, some
+sites require authentication again, and partitioned cookies are skipped. Safari
+import on macOS needs temporary Full Disk Access; Windows supports Firefox and
+Helium profiles with standard profile encryption. The exact platform limits are in
+the [browser import guide](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/browser-import.md).
+
+## SnapShots: bring another window into the draft
+
+A SnapShot captures the active window, records its app name and title, and attaches
+it to the current draft. With **Include app text**, it can also carry accessibility
+data—visible text, controls, and positions—so an agent can reason beyond pixels.
+If an app responds slowly or exposes little accessibility data, capture continues
+with the image.
+
+1. In the desktop app, open **Settings → SnapShots** and enable the feature.
+2. Allow capture and choose a shortcut. macOS asks for Screen Recording and asks
+ for Accessibility only when app text is enabled. Windows needs no setup.
+3. Switch to the window, press the shortcut, then review the attachment in the
+ draft before sending. If no thread is open, T3 Code creates a draft in the
+ current project.
+4. Tune sound, flash, and the fly-to-draft animation independently. Reduced-motion
+ OS settings disable the animation.
+
+Pending captures are saved until the draft attachment is recorded, so closing the
+app mid-capture does not normally lose them. **Finish later** disables capture but
+keeps installed setup pieces. Turning SnapShots off releases the shortcut.
+
+On Linux, SnapShots require Wayland. GNOME uses a bundled extension, KDE Plasma 6
+uses a helper, and Hyprland or Niri asks you to review the exact compositor config
+change before saving. Other Wayland desktops can fall back to a manual window
+picker; X11 is unsupported. Follow the desktop-specific recovery steps in the
+[SnapShots guide](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/snap-shot.md).
+
+## A practical workbench pass
+
+For a UI bug, ask the agent to identify the likely files, inspect the resulting diff,
+start the app in one terminal, and run a focused check in another. Open the preview,
+reproduce the issue, and attach an annotation or a SnapShot when the missing context
+lives outside the preview. Before accepting the work, refresh the preview, inspect
+the final diff, and keep the command result in the thread. That path makes your
+acceptance based on visible evidence rather than a confident status message.
diff --git a/src/content/book/120-post-commit-reactors.mdx b/src/content/book/120-post-commit-reactors.mdx
index bc3fbd5..efeda70 100644
--- a/src/content/book/120-post-commit-reactors.mdx
+++ b/src/content/book/120-post-commit-reactors.mdx
@@ -1,10 +1,10 @@
---
slug: post-commit-reactors
-order: 120
-number: "12"
+order: 270
+number: "27"
kind: chapter
-part: Part III · Transactional domain core and post-commit delivery
-partOrder: 3
+part: Part IV · Transactional domain core and post-commit delivery
+partOrder: 4
title: Post-commit reactors and the delivery gap
shortTitle: Post-commit reactors
summary: Durable intent crosses a non-durable hot-stream seam into independent reactor workers, whose serialized handlers can still fork overlapping provider work and whose progress is not reconstructed after a crash.
@@ -18,7 +18,7 @@ objectives:
keywords: [reactors, PubSub, side effects, delivery gap, DrainableWorker, provider ingestion, crash recovery]
sourceAreas: [apps/server/src/orchestration/Layers, apps/server/src/provider/Layers/ProviderService.ts, apps/server/src/serverRuntimeStartup.ts, packages/shared/src/DrainableWorker.ts]
visuals: [commit publication sequence, crash cursor, reactor topology, worker ownership matrix]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -43,7 +43,7 @@ database can say “accepted” while every side-effect subscriber sees nothing.
-
+ D[decide]
D --> TX[(event + projections + receipt)]
@@ -70,7 +70,7 @@ command execution; it does not repair the post-commit side-effect bridge.
subscriptions are fresh streams created from process-local PubSubs. The provider
reactor explicitly says pending hot-stream work cannot resume. No reactor progress
row, outbox append beside the command transaction, or startup event-store replay
- appears in these paths at the pinned revision.
+ appears in these paths.
diff --git a/src/content/book/13-source-control.mdx b/src/content/book/13-source-control.mdx
new file mode 100644
index 0000000..a8308d6
--- /dev/null
+++ b/src/content/book/13-source-control.mdx
@@ -0,0 +1,141 @@
+---
+slug: source-control
+order: 80
+number: "8"
+kind: chapter
+part: "Part I · Product guide"
+partOrder: 1
+title: "Source control: checkpoints, pull requests, reviews, and stacks"
+shortTitle: Source control
+summary: "Turn agent work into reviewable Git history, inspect per-turn checkpoints, collaborate through hosted pull requests, and manage dependent GitHub stacks."
+status: source-checked
+gates: [sources, links, interaction, editorial]
+objectives:
+ - Distinguish T3 checkpoints from commits and hosted pull requests.
+ - Configure a hosting account on the environment that owns the repository.
+ - Create, link, review, merge, and stack pull requests with the right safeguards.
+keywords: [Git, checkpoints, pull requests, code review, GitHub stacks, GitLab, Bitbucket, Azure DevOps]
+sourceAreas: [docs/user/source-control.md, apps/server/src/checkpointing, apps/server/src/vcs, apps/web/src/components/GitActionsControl.tsx, apps/web/src/components/pullRequest]
+visuals: [source-control promotion path, hosting capability matrix]
+updatedAt: "2026-09-11"
+---
+
+import Callout from "../../components/Callout.astro";
+import Mermaid from "../../components/Mermaid.astro";
+
+T3 Code gives agent work three useful levels of history. A **checkpoint** captures
+the workspace around a turn. A **commit** creates normal local Git history. A
+**pull request** publishes a branch for checks and human review. Promote work from
+one level to the next only when it has earned it.
+
+ C[Hidden checkpoint]
+ C --> D[Inspect turn or branch diff]
+ D -->|wrong direction| R[Revert to checkpoint]
+ R --> T
+ D -->|verified| L[Local commit]
+ L --> P[Push and create PR]
+ P --> V[Checks and review]
+ V -->|changes requested| T
+ V -->|approved| M[Merge]
+ P -. optional .-> K[Link PR to thread]
+ K -. keeps context .-> V`} />
+
+## Checkpoints are the thread's safety net
+
+When a turn changes files, T3 Code records checkpoint metadata and can show a
+turn-scoped diff in the conversation or Changes panel. Use it to answer “what did
+that instruction change?” without mixing the result with every uncommitted edit on
+the branch. If a turn went in the wrong direction, revert from its checkpoint UI.
+
+A checkpoint is not a substitute for a commit. It is an internal restoration point,
+and reverting can affect workspace files and provider conversation state. Before a
+revert, inspect later turns and preserve anything you still need. If the workspace
+contains valuable manual edits, commit or copy them first. After reverting, verify
+the working tree and tell the agent what should happen next.
+
+## Connect the host where Git actually runs
+
+Install Git and authenticate the hosting provider **on the environment server**.
+For a remote project, signing in on your viewing laptop does not authenticate the
+remote host. Then open **Settings → Source Control** and choose **Rescan**.
+
+| Host | Required setup | Product scope and limitations |
+| --- | --- | --- |
+| GitHub | GitHub CLI 2.81.0+ and `gh auth login` | Clone, publish, PRs, review, auto-merge, fork-workflow approval, revert PRs, and stacks. |
+| GitLab | GitLab CLI and `glab auth login` | Merge requests, review, and auto-merge. |
+| Bitbucket | Access token, or email plus API token, in server environment | Restart after environment changes; declined PRs cannot be reopened. |
+| Azure DevOps | Azure CLI, DevOps extension, and `az login` | Use the host website for diff viewing or comment changes. |
+
+API access and Git remote authentication are related but separate. A connected
+provider account can load PR metadata while `git push` still fails because the
+repository remote uses different SSH or HTTPS credentials.
+
+## Clone, publish, and create a pull request
+
+Open the command palette with `Cmd/Ctrl+K`, choose **Add Project**, select a host or
+paste a Git URL, and choose the destination directory. To publish an existing local
+repository, use **Publish Repository**. This creates the hosted repository, adds
+`origin`, and pushes commits; if the repository has no commits, create one before
+the first push.
+
+From a thread's Git actions:
+
+1. Inspect the branch or turn diff. Exclude secrets, generated debris, and unrelated
+ edits.
+2. Run the relevant checks and create a focused local commit.
+3. Push the branch and create the pull request. T3 Code can draft commit subjects,
+ PR titles, and descriptions from the change.
+4. Set the writing model and style in **Settings → Source Control**. **Repository
+ conventions** uses project instructions and recent commit subjects.
+5. Read the generated text before publishing. It should state the user-visible
+ problem, resulting behavior, and validation rather than narrate the conversation.
+
+
+ Creating a remote repository, pushing a branch, posting a review, and merging all
+ change shared state. Inspect the exact repository, branch, diff, and audience
+ before you perform each action.
+
+
+## Review without losing the implementation context
+
+Open **Pull requests** to inspect changes and comments, request reviewers, check out
+a branch, or merge. GitLab names them merge requests. GitHub, GitLab, and Azure
+DevOps can enable auto-merge while checks are pending. Auto-merge still obeys branch
+rules; use it when the change is final and only external gates remain.
+
+A thread may link several PRs, even review work from another repository on the same
+host. Use **Link pull request** from the palette or Linked pull requests panel, link
+from a detected badge, or choose **Link to thread** from a review. PRs created by the
+thread are linked automatically. Linking adds context; it does not copy or merge the
+changes.
+
+The linked panel groups stacks and shows current review state. Unlinking a layer
+keeps it out of later synchronization. With **Auto-settle merged threads**, a thread
+can settle after every linked review reaches a terminal state; an open or unsynced
+link keeps it active. Mobile can open linked reviews and their stacks, while linking
+and unlinking are done on web or desktop.
+
+## GitHub stacks: treat dependencies as dependencies
+
+A stack is an ordered set of PRs where a higher layer depends on work below it.
+Open a stack badge to navigate the layers.
+
+**Merge stack** submits the selected PR and every unmerged layer below it together,
+respecting branch rules and merge queues. Read the confirmation because its scope is
+larger than one visible PR. After a merge, GitHub rebases remaining layers.
+
+**Rebase stack** updates remote branches bottom to top without changing your local
+checkout. It can rewrite remote history and restart checks. The operation is not
+atomic: if layer three fails, layers one and two may already be updated. Resolve the
+failed layer before retrying, and expect a manual conflict after amending a lower
+layer even when the files look independent.
+
+## Recovery checklist
+
+If source control appears disconnected, authenticate on the environment host and
+rescan. For GitHub verification errors, confirm CLI 2.81.0 or newer. If metadata
+loads but pushing fails, inspect the remote URL and its credentials. If a review
+cannot load, use the host website while checking network access, permissions, and
+rate limits. The complete, revision-pinned behavior is in the
+[source-control user guide](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/source-control.md).
diff --git a/src/content/book/130-persistence-recovery.mdx b/src/content/book/130-persistence-recovery.mdx
index ae66ca5..670d9b7 100644
--- a/src/content/book/130-persistence-recovery.mdx
+++ b/src/content/book/130-persistence-recovery.mdx
@@ -1,10 +1,10 @@
---
slug: persistence-recovery
-order: 130
-number: "13"
+order: 280
+number: "28"
kind: chapter
-part: Part III · Transactional domain core and post-commit delivery
-partOrder: 3
+part: Part IV · Transactional domain core and post-commit delivery
+partOrder: 4
title: Persistence, reconstruction, and crash recovery
shortTitle: Persistence and recovery
summary: SQLite is the durable domain core, but settings, secrets, attachments, terminal history, logs, and hidden Git refs cross separate filesystems and recovery protocols with sharply different guarantees.
@@ -18,7 +18,7 @@ objectives:
keywords: [SQLite, WAL, migrations, recovery, settings, secrets, attachments, terminal history, Git refs, tombstones]
sourceAreas: [apps/server/src/persistence, apps/server/src/orchestration/Layers/ProjectionPipeline.ts, apps/server/src/serviceLauncher.ts, apps/server/src/serverSettings.ts, apps/server/src/terminal, apps/server/src/vcs]
visuals: [startup reconstruction DAG, projector replay counter, recovery matrix, retention taxonomy]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -62,8 +62,8 @@ busy timeout waits for locks instead of immediately returning `SQLITE_BUSY`.
## Migrations are a numbered program
-`Migrations.ts` imports every migration and constructs a statically ordered map. At
-this pinned revision the manifest contains 41 migrations. Startup invokes the
+`Migrations.ts` imports every migration and constructs a statically ordered map. The
+current manifest reaches migration 050. Startup invokes the
migration runner after the SQLite pragmas; it does not discover filenames and sort
them at runtime.
@@ -91,8 +91,8 @@ The first migrations establish the architectural core:
legacy evidence, not proof that checkpoint blobs currently drive recovery.
-Selected migration tests exercise upgrades from older shapes. There is no injected
-process-crash test halfway through the full 41-step startup runner.
+Selected migration tests exercise upgrades from earlier shapes. There is no injected
+process-crash test halfway through the full migration program.
## Projectors reconstruct from cursors—with a 1,000-event ceiling
@@ -107,13 +107,13 @@ pages internally. Bootstrap calls it without supplying a larger or unlimited
value. A projector that is 1,001 events behind applies only the first 1,000 during
that startup and the server proceeds with the projector still behind.
-
+|yes| R[restore state.sqlite + WAL + SHM]
U -->|no| O[open SQLite]
R --> O
O --> P[busy timeout + FK + WAL]
- P --> M[run 41 migrations]
+ P --> M[run 50 migrations]
M --> C[read each projector cursor]
C -->|default total limit 1000| F[fold persisted events]
F --> Q[load optimized command model]
@@ -150,6 +150,12 @@ handoff delay, the launcher stops that child, stages and syncs copies of
`state.sqlite`, `state.sqlite-wal`, and `state.sqlite-shm`, and then starts the trial.
It does **not** write the restore marker before the trial.
+Only the stable launcher writes durable service state. It records pending state
+before acknowledging the request, and its same-directory state replacement syncs
+both the file and directory. The trial must finish migrations, acquire startup
+dependencies, bind HTTP, and park its long-running roots at the activation gate
+before reporting `prepared`; a listening socket alone is insufficient.
+
The marker belongs to the rollback path: immediately before copying backup files
over the live triplet, the launcher creates and syncs a marker inside the backup.
On a later boot, pending service state without that marker resumes the trial; a
@@ -236,7 +242,7 @@ garbage collector was found at this revision.
## Terminal history restores text, not a process
-Terminal history is capped at 5,000 lines by default and persisted through a keyed
+Terminal history is capped at 5,000 lines and 8 MiB of UTF-8 text and persisted through a keyed
coalescing worker after a 40 ms debounce. Output updates memory, schedules the
history write, and then reaches live subscribers. The worker directly overwrites the
history file; it does not use the settings atomic-rename helper.
@@ -248,12 +254,17 @@ Because the worker directly overwrites the target instead of using an atomic ren
an abruptly interrupted write also carries a partial-file risk; the exact filesystem
outcome is an inference, not a behavior asserted by the normal write path.
-On first open after restart, the manager reads and sanitizes saved text and then
+On first open after restart, the manager reads only the bounded tail, skips an
+incomplete UTF-8 prefix, applies the line limit, sanitizes saved text, and then
starts a new PTY. Saved text does not encode the old shell process, working job,
input buffer, or terminal emulator state. Tests cover caps, sanitization, deletion,
inactive-history eviction, and legacy filename migration—not crash injection or
scope-finalizer flush.
+The client render buffer has its own 512 KiB limit. Retained device-query traffic is
+removed, and the web renderer detaches its PTY writer during replay, so a historical
+terminal query cannot produce a fresh reply in the replacement shell.
+
## Provider logs are diagnostic, not recovery truth
Provider runtime NDJSON logging declares itself best-effort. It rotates at 10 MiB
diff --git a/src/content/book/14-remote-background.mdx b/src/content/book/14-remote-background.mdx
new file mode 100644
index 0000000..945e41f
--- /dev/null
+++ b/src/content/book/14-remote-background.mdx
@@ -0,0 +1,191 @@
+---
+slug: remote-background
+order: 90
+number: "9"
+kind: chapter
+part: "Part I · Product guide"
+partOrder: 1
+title: "Remote environments and unattended work"
+shortTitle: Remote and background
+summary: "Connect securely through T3 Connect, direct pairing, Tailscale, or desktop-managed SSH, then keep Linux and macOS hosts available with the background service."
+status: source-checked
+gates: [sources, links, interaction, editorial]
+objectives:
+ - Choose a remote connection mode from reachability, setup, and hosting constraints.
+ - Pair and revoke devices without confusing a pairing link with permanent reachability.
+ - Install, update, and troubleshoot the per-user background service.
+keywords: [remote access, T3 Connect, pairing, Tailscale, SSH, background service, load balancing]
+sourceAreas: [docs/user/remote-access.md, docs/user/background-service.md, apps/server/src/cloud, apps/server/src/serviceLauncher.ts, apps/desktop/src]
+visuals: [remote-mode decision tree, reachability path]
+updatedAt: "2026-09-11"
+---
+
+import Callout from "../../components/Callout.astro";
+import Mermaid from "../../components/Mermaid.astro";
+
+A remote T3 Code client controls the environment on another machine. The project,
+Git checkout, provider credentials, agent process, and terminals stay on that host.
+The host must remain running, awake where required, and reachable through the mode
+you choose.
+
+ B{Want managed internet setup?}
+ B -->|yes| C[T3 Connect]
+ B -->|no| D{Both devices share a LAN or private network?}
+ D -->|plain LAN is enough| E[Direct pairing]
+ D -->|tailnet available| F[Tailscale HTTPS]
+ D -->|desktop can SSH to host| G[Desktop-managed SSH]
+ C --> H[Pair client and connect directly to environment]
+ E --> H
+ F --> H
+ G --> H
+ H --> I{Must survive logout or closed terminal?}
+ I -->|Linux or macOS| J[Install user background service]
+ I -->|foreground is acceptable| K[Keep t3 serve session open]`} />
+
+## Compare the four paths
+
+| Mode | Best fit | Host setup | Main limitation |
+| --- | --- | --- | --- |
+| **T3 Connect** | Reach your environments across networks with account-based discovery. | Sign in and enable Connect, or run `npx t3@latest connect`. | A saved login alone does not expose a stopped server; push notifications use this path. |
+| **Direct pairing** | LAN or an existing private network can route directly to the host. | Enable Network access or run `npx t3 serve --host `. | `127.0.0.1` is reachable only on the host; hosted web needs HTTPS. |
+| **Tailscale HTTPS** | Both devices share a tailnet and you want a private HTTPS endpoint. | Enable Tailscale HTTPS or use `--tailscale-serve`. | Requires Tailscale and a free Serve port/mapping. |
+| **Desktop-managed SSH** | Your desktop can SSH to a development machine. | Add an SSH environment; remote Node and provider setup must work non-interactively. | Managed by desktop; password prompts and broken non-interactive version-manager setup block launch. |
+
+## T3 Connect
+
+On a desktop host, open **Settings → Connections**, sign in, and enable **T3
+Connect**. On a command-line host run:
+
+```sh
+npx t3@latest connect
+```
+
+Follow the browser sign-in flow; over SSH, paste the returned authorization code.
+Accept the offered background service when you want unattended access. If you
+decline it, start `npx t3 serve` yourself and keep that process alive. On the other
+device, sign in to the same account and choose the environment.
+
+Connect renews credentials without deliberately dropping a healthy conversation.
+A failed renewal can fail that request while the existing connection remains alive.
+If an environment is offline, `t3 connect status` checks saved authorization and
+link configuration, but it is not a live reachability test; follow with `t3 service
+status` and inspect the reported log.
+
+## Direct pairing and Tailscale
+
+For LAN access, enable **Settings → Connections → Network access** on the desktop
+host; changing it restarts the app. For a CLI server, bind to an address the other
+device can actually route to:
+
+```sh
+npx t3 serve --host 192.168.1.20
+```
+
+Generate a fresh one-time pairing URL with `npx t3 pair`, then scan its QR code or
+paste it into **Add environment**. Settings are under **Connections** on web and
+desktop and **Environments** on mobile. Pairing grants that client a renewable
+session; the original link is not needed for reconnecting. Create a fresh link for
+each device and treat it like a password.
+
+The link and the paired session have different lifetimes. A link created in
+**Settings → Connections** can be copied only by the client that created it, while
+that Connections page remains open. Leaving or reloading the page discards the
+displayed one-time link; create another instead of trying to recover it. This does
+not disconnect devices that already paired. To remove an already paired device,
+revoke its session on the host.
+
+For Tailscale, join both devices to the same tailnet and enable **Tailscale HTTPS**,
+or run `npx t3 serve --tailscale-serve`. For an already running server, `npx t3 pair
+--tailscale` creates a persistent Serve mapping. Choose another port with
+`--tailscale-serve-port` if 443 is occupied. Remove the default mapping with:
+
+```sh
+tailscale serve --https=443 off
+```
+
+[app.t3.codes](https://app.t3.codes) requires an HTTPS server endpoint. A hosted
+pairing link provides credentials; it cannot make a private HTTP endpoint reachable
+or add TLS to it.
+
+## Desktop-managed SSH
+
+Choose **Settings → Connections → Add environment → SSH** and enter an SSH alias or
+`user@host`. T3 Code starts or reuses the remote server and maintains the forwarding
+path. The remote host needs a compatible Node.js and provider credentials. When the
+launch cannot find Node, test the same non-interactive shell T3 uses:
+
+```sh
+ssh user@example.com 'sh -lc "command -v node && node --version"'
+```
+
+Configure the version manager's default for non-interactive shells if this differs
+from your login terminal. Removing the connection stops a server T3 Code launched,
+but leaves a server that was already running. After an app update, retry a failed
+SSH launch once before rebuilding the connection.
+
+## Balance new threads across environments
+
+On web or desktop, enable **Settings → Connections → Load balancing**. Grouped
+projects can then place new drafts on an eligible machine according to **Prefer**,
+**Normal**, **Less often**, or **Manual only**. These are preferences, not reserved
+percentages. Resource checks happen while choosing a new draft; once chosen, its
+environment stays stable. Selecting a branch, worktree, or explicit machine also
+pins it. Existing threads never migrate, and mobile selects manually.
+
+## Run the host in the background
+
+Linux and macOS can install a per-user service:
+
+| Task | Command |
+| --- | --- |
+| Install and start | `npx t3@latest service install` |
+| Inspect state and log path | `npx t3@latest service status` |
+| Update or repair | `npx t3@latest service update` |
+| Stop and remove startup entry | `npx t3@latest service uninstall` |
+
+Uninstalling leaves projects, threads, and settings intact. Update uses the CLI
+version you invoke; use an exact version to pin, or a matching channel such as
+`@nightly`. An older CLI refuses to replace a newer service unless you explicitly
+allow a downgrade. Updates restart the server, so finish active turns and terminal
+commands first.
+
+Linux requires systemd user services and lingering to survive logout. If status
+reports `linger-disabled`, an administrator can run `sudo loginctl enable-linger
+"$(id -un)"`; run T3 itself as your normal user. macOS starts at login and stops at
+logout, so keep the Mac logged in and awake. Installing it over SSH while nobody is
+logged in at the Mac can leave the service installed but unable to start until the
+next graphical login. Windows background services are not supported.
+
+
+ Signing out or deregistering T3 Connect changes cloud access. It does not stop or
+ uninstall the local background service. Likewise, installing a service does not
+ sign the environment into T3 Connect.
+
+
+## Revoke and recover
+
+Use **Settings → Connections** on the host to revoke an unused link or a device's
+existing session. Deregister an environment from the account's **T3 Connect** page
+to remove cloud access and free its slot. CLI hosts can use `t3 connect unlink` to
+disable exposure while keeping login, or `t3 connect logout` to clear login too.
+
+For clock/proof errors, correct time on both devices, update, and restart the host.
+For link limits, deregister an unused environment. For 403 errors, inspect relay,
+proxy, and firewall policy; retain any trace or Cloudflare Ray ID. For transient
+408, 429, or 5xx failures, check reachability and allow startup retry.
+
+For service failures, start with `t3 service status` on the host and use the log
+path it prints. On Linux, `linger-disabled` points to logout persistence;
+`user-manager-unavailable` points to the systemd user session; and
+`service-disabled` or `service-stopped` calls for the reported log and
+`systemctl --user status t3code.service`. Use the repair command T3 prints. On
+macOS, check **System Settings → General → Login Items** when startup disappears.
+If background agent work cannot read Desktop, Documents, or Downloads, grant Full
+Disk Access to the Node executable named in the service's launch-agent plist.
+
+An open connection can remain listed after its access credential expires. That is
+not evidence that a revoked device can reconnect: use the host's session list and a
+fresh connection attempt when verifying revocation. The complete tables live in the
+[remote-access guide](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/remote-access.md)
+and [background-service guide](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/background-service.md).
diff --git a/src/content/book/140-provider-adapter-contract.mdx b/src/content/book/140-provider-adapter-contract.mdx
index 39e0dcb..1c145e4 100644
--- a/src/content/book/140-provider-adapter-contract.mdx
+++ b/src/content/book/140-provider-adapter-contract.mdx
@@ -1,10 +1,10 @@
---
slug: provider-adapter-contract
-order: 140
-number: "14"
+order: 290
+number: "29"
kind: chapter
-part: Part IV · Five harnesses, one product model
-partOrder: 4
+part: Part V · Six providers, one product model
+partOrder: 5
title: The ProviderAdapter contract
shortTitle: ProviderAdapter contract
summary: ProviderAdapter is the narrow provider-native command and event boundary; ProviderService supplies instance routing and recovery, while orchestration remains the durable product model.
@@ -18,7 +18,7 @@ objectives:
keywords: [ProviderAdapter, ProviderService, provider runtime, canonical events, sessions, turns, capabilities, errors]
sourceAreas: [apps/server/src/provider/Services/ProviderAdapter.ts, apps/server/src/provider/Layers/ProviderService.ts, apps/server/src/provider/Errors.ts, packages/contracts/src/provider.ts, packages/contracts/src/providerRuntime.ts, apps/server/src/orchestration/Layers/ProviderCommandReactor.ts, apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts]
visuals: [adapter boundary map, operation ledger, canonical event funnel, round-trip swimlane, interactive contract tracer]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import AdapterContractLab from "../../components/AdapterContractLab.astro";
@@ -48,9 +48,9 @@ event in the canonical union.
## The contract is deliberately smaller than the product
-
+
-
+
The complete shape has fourteen required members and one optional operation.
Reading them by responsibility is more useful than reading them in file order.
@@ -79,7 +79,7 @@ activity, plan changes, requests, usage, completion, and failures arrive later o
There is no steer member in the SPI. A provider can interpret
sendTurn while a turn is already active as steering—OpenCode has a
concrete tested implementation—but the generic contract alone promises only a
- send request. Chapters 16–19 document each adapter's behavior separately.
+ send request. Chapters 31–35 document each adapter's behavior separately.
## A session uses T3 identity and opaque native continuation
@@ -104,29 +104,28 @@ the envelope while the owning adapter remains responsible for decoding it.
it.
-## Capability negotiation is only one field today
+## Capability negotiation stays deliberately small
-The declared capability object contains one property:
-`sessionModelSwitch: "in-session" | "unsupported"`. It tells the provider reactor
-whether a model change may stay within an existing native session or requires a
-restart.
+The declared capability object records whether model changes may stay in-session,
+whether a resumed turn can continue without a synthetic prompt, and whether native
+conversation history supports rollback. Manual compaction is an optional adapter
+operation with either a native start function or a slash command.
-That is the entire SPI capability surface at this revision. Approvals, structured
-input, plans, tasks, skills, usage telemetry, rollback, steering, and native modes
-must not be inferred from this one object. They are concrete adapter behaviors,
+Approvals, structured input, plans, tasks, skills, usage limits, attachments,
+steering, and native modes must not be inferred from those few fields. They are concrete adapter behaviors,
sometimes expressed through typed failure, sometimes absent, and sometimes
implemented through provider-specific extensions.
-
- Codex, Claude, Cursor, Grok, and OpenCode all advertise
- sessionModelSwitch: "in-session" at the pinned commit. The
- unsupported branch is real reactor logic and part of the contract,
- but it is not a current five-provider difference.
+
+ The shared contract gives orchestration explicit switches for operations that can
+ corrupt provider continuity when guessed. Antigravity, for example, declares that
+ conversation rollback is unavailable; the UI and revert path must preserve that
+ distinction.
## Canonical events are a grammar, not a checklist
-
+
Every runtime event shares an id, driver kind, T3 thread, timestamp, optional
instance/turn/item/request ids, provider references, and optional raw provenance.
@@ -136,10 +135,10 @@ configuration, file, warning, and error events.
That breadth provides a stable **target vocabulary** for adapters and consumers.
It is not proof of feature parity. For example, the schema can represent token
-usage for any provider, while Chapter 20 verifies that only Codex and Claude emit
-that event at this revision.
+usage for any provider, while Chapter 35 separates live context snapshots,
+historical transcript accounting, and provider-reported subscription limits.
-
+|hot domain event| R[ProviderCommandReactor]
R --> S[ProviderService]
@@ -218,9 +217,9 @@ events in order. Every concrete adapter has behavior tests for its own transport
normalization.
There is no repository-wide executable conformance suite that feeds the same full
-feature script to all five adapters and proves semantic equivalence. That absence
+feature script to all six adapters and proves semantic equivalence. That absence
is appropriate to surface: one interface gives the product a stable integration
-point, while Chapters 16–19 retain provider differences instead of hiding them.
+point, while Chapters 31–35 retain provider differences instead of hiding them.
A meta-harness benefits from a small command SPI and a rich canonical event
diff --git a/src/content/book/15-mobile.mdx b/src/content/book/15-mobile.mdx
new file mode 100644
index 0000000..e2f7815
--- /dev/null
+++ b/src/content/book/15-mobile.mdx
@@ -0,0 +1,144 @@
+---
+slug: mobile
+order: 100
+number: "10"
+kind: chapter
+part: "Part I · Product guide"
+partOrder: 1
+title: "Mobile: supervise agents from anywhere"
+shortTitle: Mobile
+summary: "Navigate projects and threads, send rich prompts, inspect files and reviews, and use push and live activity updates without keeping the app connected."
+status: source-checked
+gates: [sources, links, interaction, editorial]
+objectives:
+ - Connect the mobile app and navigate efficiently across environments, projects, and threads.
+ - Compose with photos, videos, files, paste, and voice while preserving drafts through interruptions.
+ - Configure notifications and understand what requires T3 Connect.
+keywords: [mobile, iOS, Android, navigation, notifications, live activities, attachments, voice]
+sourceAreas: [docs/user/mobile-notifications.md, apps/mobile/src/Stack.tsx, apps/mobile/src/features/home, apps/mobile/src/features/files, apps/mobile/src/features/review, apps/mobile/src/state/thread-outbox-model.ts]
+visuals: [mobile supervision loop, capability table]
+updatedAt: "2026-09-11"
+---
+
+import Callout from "../../components/Callout.astro";
+import Mermaid from "../../components/Mermaid.astro";
+
+The mobile app is a remote control for real development environments. It is suited
+to checking progress, answering an approval, adding context, reviewing a diff, or
+starting the next task while away from the host. Agent execution and project files
+remain on the connected environment.
+
+ T[Open the thread]
+ T --> R{What is needed?}
+ R -->|approval or answer| Q[Respond to request]
+ R -->|inspect| F[Files or review diff]
+ R -->|redirect work| C[Compose text, voice, or media]
+ Q --> A[Agent continues on host]
+ F --> C
+ C --> A
+ A --> N`} />
+
+## Connect and orient yourself
+
+Use **Settings → Environments** to add a direct pairing URL or manage known
+environments. For T3 Connect, sign in with the same account as the host and select
+the linked environment. A connection indicator tells you whether the selected host
+is reachable; switching environments changes the machine whose projects and threads
+you are viewing.
+
+The Home screen groups work by project and thread and can filter or search the list.
+Open a thread to see its durable conversation, running state, requests, linked pull
+requests, and composer. On wider phones and tablets, adaptive navigation can keep a
+sidebar and detail visible together; on compact layouts, destinations open as a
+stack and Back returns to the previous list. Hardware keyboard commands are
+available on supported devices.
+
+Use swipe and row actions deliberately: archive or settle work when it is finished,
+and use the archived view when you need it again. A thread remains tied to the
+environment where it started; mobile does not move it to another machine.
+
+## Do real review work from a small screen
+
+From a thread, open **Files** to browse its workspace tree and preview source,
+Markdown, images, video, and supported web content. Open the Git overview or a
+linked review to inspect changed files, review state, comments, and stack context.
+Keep the question narrow on a phone: verify one behavior or file, then send a clear
+follow-up. A desktop remains better for a broad, multi-file audit.
+
+Mobile shows provider permission and input requests in the timeline. Read the exact
+tool, path, or question before responding. Approval lets the environment act; the
+phone itself does not perform the command.
+
+## Compose with the context you already have
+
+The composer supports text plus photos, videos, images pasted from the clipboard,
+and files when the connected server advertises attachment uploads. Use the
+attachment menu to choose the camera, photo library, or file picker, review the
+tiles, and remove anything irrelevant before sending. Large or unsupported items
+can be rejected, and a message has an attachment-count limit shown by the app.
+
+On iOS, voice input transcribes speech on the device before placing the text in the
+draft. It is useful for a quick correction but still deserves an edit for filenames,
+commands, and acceptance criteria. Drafts are local to the mobile app and survive
+normal navigation. If a send fails or the connection disappears, T3 Code can retain
+queued intent and retry once the environment has a live synchronized connection.
+Check the final thread state rather than repeatedly tapping Send; duplicate
+instructions can make an agent redo work.
+
+
+ State the target, observed behavior, desired behavior, and how to verify it. Attach
+ one relevant image or file. “The checkout button overlaps the total on this
+ screenshot at 390 px; fix it and verify the mobile breakpoint” is enough to drive
+ a focused turn.
+
+
+## Notifications, ongoing activity, and Live Activities
+
+Sign in to T3 Connect, link the environment, and enable **Device Notifications** in
+Settings. Alerts cover completion, failure, approvals, and input requests; tapping
+one opens its thread. The environment must have agent-activity publishing enabled.
+
+Enable **Ongoing Agent Activity** on Android or **Live Activity Updates** on iOS to
+follow active work outside the app. Finished results can remain visible for up to
+15 minutes. Dismissing Android's activity card does not disable future alerts;
+change the setting to stop future cards.
+
+When several threads change together, T3 Code can combine them into one attention
+alert or one finished-work alert. The summary lists thread titles, prioritizes work
+that needs input or failed, and opens the highest-priority thread when tapped. An
+individual alert continues to open its own thread. This keeps a burst of agent
+updates actionable without requiring one notification per thread.
+
+Ordinary alerts remain quiet while the mobile app is foregrounded, while ongoing
+activity continues to update. Watching the thread on another device does not silence
+the phone. The mobile app does not have to keep a live environment connection for
+push delivery because the notification path uses T3 Connect.
+
+Reopening the app can silently reconcile the current aggregate after a cold start or
+time away. Replaying the same state does not create another alert or extend a
+finished card's deadline, and old completions are not presented as fresh alerts.
+After tapping any notification, treat the synchronized thread as current; the
+notification is a route and attention signal, not a copy of authoritative thread
+state.
+
+| Situation | Expected behavior |
+| --- | --- |
+| Direct or Tailscale connection only | Interactive control works while reachable; background push does not. |
+| Android 7+ with Google Play services | Ordinary notifications are supported. |
+| Android 16+ | The system may promote ongoing activity to a Live Update, depending on settings and device support. |
+| iOS with Live Activity Updates | Current agent state can appear as a Live Activity. |
+| Android app force-stopped in system Settings | Push delivery pauses until the app is opened again. |
+
+OS notification permissions and Android channels remain under system Settings.
+Battery-saving modes can delay cleanup, especially on Android 7. See the pinned
+[mobile-notifications guide](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/mobile-notifications.md).
+
+## A sensible mobile routine
+
+Use notifications as an invitation to inspect, not as proof that the result is
+correct. Open the target thread, read the last agent message and tool state, inspect
+the relevant diff or file, then answer the request or send one bounded follow-up.
+For a visual issue, attach a photo or video and include a reproducible condition.
+When the host is offline, fix host reachability first; changing screens or
+reinstalling the app cannot start a powered-off environment.
diff --git a/src/content/book/150-provider-instances-routing.mdx b/src/content/book/150-provider-instances-routing.mdx
index e4d3303..b520e34 100644
--- a/src/content/book/150-provider-instances-routing.mdx
+++ b/src/content/book/150-provider-instances-routing.mdx
@@ -1,10 +1,10 @@
---
slug: provider-instances-routing
-order: 150
-number: "15"
+order: 300
+number: "30"
kind: chapter
-part: Part IV · Five harnesses, one product model
-partOrder: 4
+part: Part V · Six providers, one product model
+partOrder: 5
title: Drivers, instances, registries, and multi-instance routing
shortTitle: Provider instances and routing
summary: T3 Code separates an open driver kind from configured instance identity, discovery snapshots, durable thread bindings, native sessions, and continuation compatibility so several accounts of one harness can coexist.
@@ -18,7 +18,7 @@ objectives:
keywords: [ProviderDriver, ProviderInstance, registry, multi-instance, routing, settings, secrets, resume, recovery]
sourceAreas: [packages/contracts/src/providerInstance.ts, packages/contracts/src/settings.ts, apps/server/src/provider/ProviderDriver.ts, apps/server/src/provider/Layers/ProviderInstanceRegistryHydration.ts, apps/server/src/provider/Layers/ProviderInstanceRegistryLive.ts, apps/server/src/provider/Layers/ProviderAdapterRegistry.ts, apps/server/src/provider/Layers/ProviderRegistry.ts, apps/server/src/provider/Layers/ProviderService.ts, apps/server/src/provider/Layers/ProviderSessionDirectory.ts]
visuals: [provider identity ladder, settings reconciliation timeline, routing and recovery decision tree, interactive fleet router]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -65,8 +65,8 @@ adapter state.
-`ProviderDriverKind` is intentionally not a closed five-literal union. The shipped
-build registers Codex, Claude, Cursor, Grok, and OpenCode, but settings and persisted
+`ProviderDriverKind` is intentionally not a closed six-literal union. The shipped
+build registers Codex, Claude, Cursor, Grok, Antigravity, and OpenCode, but settings and persisted
state can outlive a build, move between forks, or refer to a driver that is absent
after rollback. Schema decoding accepts any valid slug; the runtime makes absence
visible.
@@ -127,7 +127,7 @@ Enabled state has its own precedence. Explicit `false` in the instance envelope
decoded driver config always disables. Otherwise the envelope value wins, then the
driver config value, then the default is enabled.
-
+
H[explicit map + missing legacy defaults]
H --> Q{unchanged live identity?}
@@ -238,7 +238,7 @@ For an operation such as send, interrupt, approval, structured input, or rollbac
Starting a new session also stops stale live sessions for the same T3 thread on
other current instances.
-
+
B{persisted binding?}
B -->|no| X[validation failure]
diff --git a/src/content/book/16-devices.mdx b/src/content/book/16-devices.mdx
new file mode 100644
index 0000000..a29e0c1
--- /dev/null
+++ b/src/content/book/16-devices.mdx
@@ -0,0 +1,140 @@
+---
+slug: devices
+order: 110
+number: "11"
+kind: chapter
+part: "Part I · Product guide"
+partOrder: 1
+title: "Device lab: simulators, emulators, and agent-driven testing"
+shortTitle: Device lab
+summary: "Watch and control iOS Simulators and Android Emulators beside a thread, configure test conditions, and let agents use the same devices for verification."
+status: source-checked
+gates: [sources, links, interaction, editorial]
+objectives:
+ - Prepare a local or SSH device host and open multiple simulator sessions.
+ - Use the Tools drawer to test appearance, accessibility, permissions, location, and network conditions.
+ - Control agent access and diagnose remote streaming or development-server reachability.
+keywords: [devices, iOS Simulator, Android Emulator, device hub, agent-device, accessibility, SSH device host]
+sourceAreas: [docs/user/devices.md, apps/server/src/device, apps/web/src/components/device]
+visuals: [device ownership topology, verification matrix]
+updatedAt: "2026-09-11"
+---
+
+import Callout from "../../components/Callout.astro";
+import Mermaid from "../../components/Mermaid.astro";
+
+The Device panel places a live iOS Simulator or Android Emulator beside a project
+thread. You and the agent can observe the same device, but through different
+controls: you interact with the video surface and Tools drawer; an authorized agent
+uses `device_*` tools through the managed `agent-device` command line.
+
+|touch, type, toolbar| P[Device panel]
+ A[Coding agent] -->|device tools when enabled| H[Device hub]
+ P -->|stream and control| H
+ H --> D[iOS Simulator or Android Emulator]
+ D -->|runs on| M[Environment machine or SSH device host]
+ D -->|app traffic| S[Metro or development server]
+ R[Remote client] -->|HTTPS or localhost preferred| P`} />
+
+## Prepare the host
+
+Open the right panel in a project thread and choose **Device**. First use walks
+through starting the device hub, checking platform support, and deciding whether
+agents may control devices. Merely opening the panel downloads or starts nothing.
+
+iOS requires macOS and Xcode. Android requires SDK Platform-Tools, Android Emulator,
+the latest Command-line Tools, and a virtual device created in Android Studio's
+Device Manager. T3 detects standard SDK paths; set `ANDROID_HOME` for a custom
+location. After installing a missing dependency, restart the environment server and
+refresh the device list.
+
+The simulator belongs to the environment host, not necessarily the computer showing
+the client. This makes a powerful setup possible: T3 Code can run on one server and
+use a Mac or Android workstation added as an SSH device host.
+
+## Open and operate devices
+
+Choose a running device, or select **Start** beside a stopped one. Every device gets
+its own right-panel tab. Use **+ → Device** for another, and rename a tab from its
+context menu. Only the visible tab streams video; hidden tabs and their devices keep
+running.
+
+Click or drag to touch, type while the screen is focused, and use the toolbar for
+Android Home, Back, and Recents, iOS rotation, and power. Closing a tab stops
+watching but leaves the simulator running; use power when you mean to stop it.
+Closed tabs remain closed after reload and can be reopened from **+ → Device**.
+
+Turning off **Settings → Integrations → Devices** stops T3 helper processes. It does
+not power off simulators or emulators.
+
+## Turn the Tools drawer into a test matrix
+
+Open **Tools** for the active device. The drawer reads values back after each change,
+so a displayed state is the device's reported state rather than an optimistic toggle.
+It shows only controls the selected platform and device support. A missing iOS-only
+or Android-only control is therefore a capability boundary, not a separate setting
+you need to enable.
+
+| Test dimension | Useful check |
+| --- | --- |
+| Light/dark mode and text size | Contrast, truncation, dynamic type, and responsive layout. |
+| Accessibility | Element frames and platform accessibility settings expose missing labels or poor hit targets. |
+| Location | Verify empty, nearby, distant, or permission-denied location behavior. |
+| App permissions | Exercise first-run, granted, denied, and revoked states. |
+| iOS-specific tools | Liquid Glass, color filters, VoiceOver, and a test push notification. |
+| Android-specific tools | Orientation and network toggling for rotation and offline recovery. |
+
+Change one variable at a time, reproduce the behavior, and tell the agent the exact
+state. A useful acceptance pass covers the default state, one adverse state, and a
+recovery back to normal. You and the agent are changing the same simulator: a theme,
+permission, location, orientation, or network change is immediately part of the
+other participant's test conditions. State the condition in the thread before
+asking the agent to verify it.
+
+## Give agents access deliberately
+
+Enable **Agent device access** in **Settings → Integrations → Devices** to install
+and expose the device CLI to newly started agent sessions. Restart an existing agent
+session after enabling it so the session receives the needed environment. The first
+iOS tap may build a small test runner and take a few minutes once per server.
+
+When an agent opens a device, its panel opens for web and desktop clients on that
+thread; mobile shows device activity in the timeline. Disable agent access to hide
+device tools from agents started afterward. Your own panel remains available.
+
+
+ Opening the Device panel does not authorize the coding agent. Enable agent access
+ only when automated taps, screenshots, or inspection are useful, and disable it
+ when the task should stay away from simulators.
+
+
+## Remote streams and SSH device hosts
+
+Device streams travel through the environment server and work over LAN, Tailscale,
+and T3 Connect. Live video requires HTTPS or localhost. Over plain remote HTTP, iOS
+falls back to slower still images and Android cannot display video.
+
+To add another machine, choose an environment under **Settings → Integrations →
+Devices → Device hosts**, then enter an SSH alias or `user@host`, optional identity
+file, and port. The environment server resolves the SSH config and keys; password
+prompts are unsupported. **Test connection** checks SSH, Node, npm, and platform
+tools without installing. First listing installs pinned device tools. Node 22+ and
+npm must work in a non-interactive SSH shell.
+
+Removing a host closes its sessions and stops reachable T3 helpers, but simulators
+keep running. Connections can recover after interruption.
+
+T3 handles discovery, streaming, and control. You still own app builds,
+installation, and access to Metro or another development server. A simulator on a
+different machine cannot reach the environment's `localhost`; bind the dev server
+to a reachable address or establish the required forwarding. The authoritative
+task guide is the [Devices documentation](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/devices.md).
+
+## A repeatable verification session
+
+Ask the agent to boot the target device and install or open the app. Watch its
+reproduction, then test the same path yourself. Switch appearance, text size, and a
+relevant permission or network condition. Have the agent capture evidence and run
+the smallest automated check. Finish by restoring the device state, inspecting the
+code diff, and writing the verified device/OS conditions into the thread or PR.
diff --git a/src/content/book/160-codex-app-server-json-rpc.mdx b/src/content/book/160-codex-app-server-json-rpc.mdx
index 8d00e36..18fc8d2 100644
--- a/src/content/book/160-codex-app-server-json-rpc.mdx
+++ b/src/content/book/160-codex-app-server-json-rpc.mdx
@@ -1,10 +1,10 @@
---
slug: codex-app-server-json-rpc
-order: 160
-number: "16"
+order: 310
+number: "31"
kind: chapter
-part: Part IV · Five harnesses, one product model
-partOrder: 4
+part: Part V · Six providers, one product model
+partOrder: 5
title: Codex through app-server JSON-RPC
shortTitle: Codex app-server
summary: Codex runs as a local app-server child speaking typed JSON-RPC over stdio; T3 translates its volatile native requests and notifications into canonical runtime events without making provider delivery durable.
@@ -14,7 +14,7 @@ objectives: [Trace the Codex process and JSON-RPC lifecycle, Distinguish native
keywords: [Codex, app-server, JSON-RPC, stdio, resume, approvals, plans, token usage]
sourceAreas: [packages/effect-codex-app-server/src, apps/server/src/provider/Layers/CodexAdapter.ts]
visuals: [Codex JSON-RPC normalization flow, native-to-canonical boundary ledger]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -40,7 +40,7 @@ incoming server requests to handlers, and fails pending work when the stream end
Spawn, process-exit, protocol, transport, and native request failures stay typed
until the adapter maps them into T3’s shared provider-error taxonomy.
-
+
R[provider command reactor]
R --> A[Codex adapter]
diff --git a/src/content/book/17-personalize-usage-updates.mdx b/src/content/book/17-personalize-usage-updates.mdx
new file mode 100644
index 0000000..257f518
--- /dev/null
+++ b/src/content/book/17-personalize-usage-updates.mdx
@@ -0,0 +1,187 @@
+---
+slug: personalize-usage-updates
+order: 120
+number: "12"
+kind: chapter
+part: "Part I · Product guide"
+partOrder: 1
+title: "Personalize, measure usage, update, and protect privacy"
+shortTitle: Personalize and operate
+summary: "Tune appearance, motion, and keybindings; understand usage estimates and pooled limits; update clients and servers safely; and control product telemetry."
+status: source-checked
+gates: [sources, links, interaction, editorial]
+objectives:
+ - Personalize each client without confusing device-local and environment-shared settings.
+ - Read estimated costs and provider limits accurately across environments.
+ - Update a client/server pair with minimal disruption and make an informed telemetry choice.
+keywords: [appearance, themes, motion, keybindings, usage, limits, updates, telemetry, privacy]
+sourceAreas: [docs/user/appearance.md, docs/user/keybindings.md, docs/user/keyboard-focus.md, docs/user/usage.md, docs/user/updating.md, docs/user/telemetry.md]
+visuals: [settings ownership map, update decision path]
+updatedAt: "2026-09-11"
+---
+
+import Callout from "../../components/Callout.astro";
+import Mermaid from "../../components/Mermaid.astro";
+
+T3 Code spans clients and environments, so settings do not all live in one place.
+Appearance is usually device-local, keybindings belong to an environment, model
+price overrides are shared by clients of their target environments, and updates may
+need action on a different machine from the one in your hands.
+
+ D[Device or browser]
+ U --> E[Environment server]
+ U --> O[Operating system]
+ D --> A[Theme, mobile typography, panel motion]
+ E --> K[Keybindings and project scripts]
+ E --> P[Price overrides and telemetry setting]
+ O --> R[Reduced motion, notification permissions, app permissions]
+ C[Connected client version] --> V[Server version compatibility]
+ V --> E`} />
+
+## Make the interface comfortable for long sessions
+
+Open **Settings → Appearance** to choose a theme and system, light, or dark mode.
+You can select separate theme variants for light and dark. Preferences are stored
+per device or browser. Mobile has its own theme plus text, code, and terminal
+preferences; Android 12+ can use wallpaper-driven **Material You**, and Material You
+Layout changes spacing and shape separately from color.
+
+Panels open immediately by default. Raise **Panel animations** from 0 up to 400 ms
+to add motion. The OS reduced-motion setting overrides animation, and switching
+threads restores that thread's panel state without replaying transitions.
+
+Web and desktop can create a palette or import T3 Code and VS Code themes. Export
+JSON to share it. An environment can publish themes and set a default with `t3 theme
+set `; connected clients apply that command once and can choose another theme
+later. `t3 theme clear` removes the default without changing current clients. Keep a
+published theme filename stable, write updates atomically, and avoid reserved IDs.
+Environment-published themes come only from the server serving the web app or the
+desktop app's main local environment; app.t3.codes and additional connections do
+not supply them. **Duplicate** makes an editable independent copy, and a custom
+theme with the same ID wins. If a selected published theme disappears, the client
+returns to the standard theme.
+See the [appearance guide](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/appearance.md).
+
+## Build a keyboard layer around your habits
+
+Use **Settings → Keybindings** on web and desktop to inspect command IDs, defaults,
+and conflicts. The environment stores rules in `~/.t3/userdata/keybindings.json`:
+
+```json
+[
+ { "key": "mod+g", "command": "terminal.toggle" },
+ { "key": "mod+shift+g", "command": "terminal.new", "when": "terminalFocus" }
+]
+```
+
+`mod` means Command on macOS and Control elsewhere. Conditions include
+`terminalFocus`, `terminalOpen`, `previewFocus`, `previewOpen`, and
+`modelPickerOpen`, with `!`, `&&`, `||`, and parentheses. The **last matching rule
+wins**, so put a specific rule after a general one. Preserve `!terminalFocus` on
+global bindings that should not steal shell input. Project scripts use
+`script.{id}.run`.
+
+Assign `thread.stop` yourself if you want a dedicated interrupt key. In desktop,
+`mod+w` closes the focused terminal or right-panel tab before the window; in a web
+browser it closes the browser tab, so choose another binding. The palette retains
+focus while open and returns it to the composer when closed. Full syntax and quit
+behavior are in the [keybinding guide](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/keybindings.md).
+
+T3 Code creates the keybinding file with defaults and adds later defaults without
+overwriting your custom commands. Invalid rules are ignored; an unreadable JSON
+document falls back to defaults. `chat.new` can ask for a project, while
+`chat.newLocal` uses the current one. While the palette or model picker is open,
+number shortcuts select its entries, and model shortcuts also work in Settings. A
+terminal becoming ready does not steal focus from a composer you returned to.
+
+Desktop quit uses **Hold** by default: hold `Cmd/Ctrl+Q` for 1.2 seconds or press it
+twice within 500 ms. If keyboard repeat is disabled, use two presses. Settings can
+change this to one **Direct** press or **Double press** only; the app menu quits
+immediately.
+
+## Read Usage as evidence, not an invoice
+
+**Usage** combines available Codex, Claude Code, and Grok Build session history
+across selected environments. It reports tokens, cache savings, model breakdowns,
+and estimated API-equivalent cost. The estimate is not a subscription bill, and
+totals can omit history the server does not have. Filter environments to locate a
+machine or refresh when recent sessions or model prices are missing. Grok turns
+without a saved completed-turn record are absent from totals.
+
+From the environment dropdown, **Model prices** lets you override exact model IDs
+and USD rates per million tokens. Optional cache rates fall back to input price; `0`
+means free. Target one or several environments. Each destination reports success;
+offline destinations are not queued after the dialog closes, so reconnect and use
+**Retry failed saves**. In a mixed multi-environment table, untouched cells keep
+each environment's existing rate.
+
+**Usage → Limits** pools provider-reported subscription accounts, deduplicates the
+same account across environments and hubs, and shows windows, resets, and reset
+credits where available. Account columns stay aligned across windows; a gap means
+that account does not report the window, and a hatched segment shows what the next
+reset restores. Codex accounts with banked reset credits expose **Use reset** from
+their account details. API
+key and proxied accounts may expose no subscription limit. `/usage-limits` opens the
+current cached snapshot above the composer; it does not run the agent or refresh.
+For pooled CLIProxyAPI accounts, add a hub under **Settings → Providers → Usage
+providers**. No plugin is required. This connection reports usage but does not
+route provider requests.
+
+## Update the machine named in the notice
+
+Client and server can be on different versions and machines. When a notice appears,
+identify the environment named by it and finish active agents and terminal commands:
+server updates restart the connection. Projects, threads, settings, and files remain.
+
+ H[Identify named host]
+ H --> W{How does its server run?}
+ W -->|managed service| S[Use Update server or matching service update]
+ W -->|desktop hosted| D[Update desktop app on host]
+ W -->|foreground CLI| C[Copy exact-version command and preserve serve options]
+ S --> R[Restart and reconnect]
+ D --> R
+ C --> R
+ R -->|failure| X[Retry once, check correct host, launch exact version]
+ R -->|success| V[Verify thread and terminal state]`} />
+
+Enable **Settings → General → Continue threads after restarts** when you want
+supported active threads to resume after an update, crash, or reboot. Apply it to
+all connected environments after older servers update. It does not enable startup,
+terminals can still be interrupted, and sessions without provider resume state need
+a new message.
+
+Keep the client open while a remote update installs and reconnects. **Update
+server** can update a supported background service; for a desktop-hosted server it
+also closes and relaunches the desktop app on that host. A failed service update can
+roll back to its previous version. If recovery still fails, retry once, confirm you
+updated the named host, then relaunch a command-line server at the exact client
+version. Older servers may need one local update before remote update, rollback, or
+shared continuation settings are available.
+
+For a service, use `npx t3@ service update`; `@latest` helps only
+when the client is on latest. For a foreground host, relaunch the copied exact
+version and preserve `serve`, `--host`, or `--tailscale-serve`. Mobile store releases
+install normally; background app updates preserve drafts and queued messages and
+apply when you leave, or ask after a long foreground session. Follow the pinned
+[updating guide](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/updating.md).
+
+## Privacy and product telemetry
+
+The server sends PostHog product events tied to a hashed account or installation ID.
+Events can include provider, model, reasoning effort, permission mode, result,
+duration, and main-agent token totals. They exclude prompts, responses, file
+contents, authentication tokens, conversation IDs, raw provider events, and child
+agent output; child token usage is excluded from totals.
+
+Disable collection by setting `T3CODE_TELEMETRY_ENABLED=false` in the **server's
+environment before startup**. Restart the server so the value takes effect. This
+stops product events from being recorded or sent. See the
+[product-usage-data guide](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/telemetry.md).
+
+
+ When a preference appears not to stick, first ask whether it belongs to this
+ device, the selected environment, or the operating system. That single check
+ resolves most multi-environment settings confusion.
+
diff --git a/src/content/book/170-claude-agent-sdk.mdx b/src/content/book/170-claude-agent-sdk.mdx
index 65ac233..2c84278 100644
--- a/src/content/book/170-claude-agent-sdk.mdx
+++ b/src/content/book/170-claude-agent-sdk.mdx
@@ -1,10 +1,10 @@
---
slug: claude-agent-sdk
-order: 170
-number: "17"
+order: 320
+number: "32"
kind: chapter
-part: Part IV · Five harnesses, one product model
-partOrder: 4
+part: Part V · Six providers, one product model
+partOrder: 5
title: Claude through the Agent SDK
shortTitle: Claude Agent SDK
summary: Claude uses an SDK query stream rather than app-server RPC; T3 holds live query context and deferred interactions while normalizing assistant, tool, task, plan, usage, and result observations into one product contract.
@@ -14,7 +14,7 @@ objectives: [Follow Claude query configuration resume steering interruption and
keywords: [Claude, Agent SDK, query stream, permissions, skills, commands, TodoWrite, tasks, resume, usage]
sourceAreas: [apps/server/src/provider/Layers/ClaudeAdapter.ts, apps/server/src/provider/Drivers/ClaudeDriver.ts, apps/server/src/provider/Drivers/ClaudeSkills.ts]
visuals: [Claude SDK message normalization, skill precedence, query lifecycle]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -49,7 +49,7 @@ accepting legacy `sessionId`), optional `resumeSessionAt`, and a turn count, the
supplies those hints to a fresh query. T3 durable history remains an independent
orchestration record.
-
+
Q[Claude SDK query]
Q -->|assistant · tool · TodoWrite · result| A[Claude adapter]
@@ -116,11 +116,11 @@ every installed skill was discoverable.
Claude result and selected message usage can update a per-thread token/context
snapshot, including input/cache/output/reasoning/tool/duration fields where present.
-This supports the live context meter. Chapter 20’s Usage page independently scans
+This supports the live context meter. Chapter 35’s Usage page independently scans
provider-owned transcripts, de-duplicates them, and prices where possible; it does
not use this runtime event as its source of truth.
-At the pinned revision only Codex and Claude emit this live telemetry. A generic
+Only Codex and Claude emit this live telemetry. A generic
runtime schema can represent future data, but that is not evidence Cursor, Grok, or
OpenCode emit it now.
diff --git a/src/content/book/18-recipes-troubleshooting.mdx b/src/content/book/18-recipes-troubleshooting.mdx
new file mode 100644
index 0000000..6b6be46
--- /dev/null
+++ b/src/content/book/18-recipes-troubleshooting.mdx
@@ -0,0 +1,143 @@
+---
+slug: recipes-troubleshooting
+order: 130
+number: "13"
+kind: chapter
+part: "Part I · Product guide"
+partOrder: 1
+title: "Complete recipes and troubleshooting"
+shortTitle: Recipes and troubleshooting
+summary: "Combine projects, agents, workbench tools, source control, remote access, mobile, and devices into repeatable workflows, then diagnose failures from the owning layer."
+status: source-checked
+gates: [sources, links, interaction, editorial]
+objectives:
+ - Run end-to-end feature, review, remote, and mobile verification workflows.
+ - Diagnose failures by separating client, connection, environment, provider, workspace, and host-service state.
+ - Preserve evidence and recover without duplicating work or losing useful changes.
+keywords: [recipes, troubleshooting, workflow, verification, recovery, remote, source control]
+sourceAreas: [docs/user, apps/web/src, apps/mobile/src, apps/server/src]
+visuals: [layered troubleshooting flow, recipe checklists]
+updatedAt: "2026-09-11"
+---
+
+import Callout from "../../components/Callout.astro";
+import Mermaid from "../../components/Mermaid.astro";
+
+The most reliable way to use T3 Code is to keep intent, execution, evidence, and
+review in the same thread. When something breaks, identify which owner failed
+before changing settings: the viewing client, its connection, the environment
+server, the provider, the workspace, or an external service.
+
+ C{Client responsive?}
+ C -->|no| C1[Restart or update the client; preserve drafts]
+ C -->|yes| N{Environment connected?}
+ N -->|no| N1[Check host power, reachability, pairing, clock, and service status]
+ N -->|yes| S{Thread and snapshots synchronized?}
+ S -->|no| S1[Reconnect once; select correct environment and project]
+ S -->|yes| P{Provider can start or resume?}
+ P -->|no| P1[Check provider auth, model, permissions, and host logs]
+ P -->|yes| W{Workspace or test failed?}
+ W -->|yes| W1[Inspect checkpoint diff, terminal output, and device or preview]
+ W -->|no| E[Check external host API, Git credentials, browser profile, or device dependency]
+ W1 --> R[Send one bounded correction and verify]
+ E --> R`} />
+
+## Recipe 1: take a feature from request to reviewed pull request
+
+1. Open or add the project on the environment that has the required tools and
+ credentials. Create a fresh thread and choose the provider, model, and permission
+ mode appropriate to the task.
+2. Describe the problem, constraints, and acceptance checks. Attach the smallest
+ relevant file, image, or SnapShot.
+3. Let the agent inspect and implement. Answer permission or input requests after
+ reading their exact scope.
+4. Inspect per-turn checkpoints and the branch diff. Use Files for exact source,
+ Terminal for focused checks, Preview for browser behavior, or Device for mobile
+ behavior.
+5. If the direction is wrong, preserve unrelated work and revert the appropriate
+ checkpoint. Send a concrete correction.
+6. When behavior and checks pass, create a focused commit. Review the generated
+ message, push, and create a PR only when you intend to publish.
+7. Link the PR to the thread, follow checks and review comments, and return to the
+ same thread for revisions. Merge or enable auto-merge after the final diff and
+ scope are correct.
+
+## Recipe 2: fix a visual bug with browser or SnapShot evidence
+
+Start the app in one terminal and keep a second terminal for tests. Open its port in
+Preview, reproduce at the exact viewport and state, and annotate the affected
+region. If the bug is in another desktop app, capture a SnapShot with app text when
+useful. Ask for the expected visual behavior and a focused verification. Refresh
+after the change, test a nearby breakpoint or theme, inspect the diff, and turn off
+or revoke temporary capture permissions when you no longer want them.
+
+## Recipe 3: supervise a long task from mobile
+
+On the host, enable T3 Connect and a background service; verify `t3 service status`
+before leaving. On mobile, sign in, enable Device Notifications and optional ongoing
+activity, then open the environment and thread. When alerted, read the final message
+and inspect the relevant file or review diff. Answer approvals carefully. Use voice,
+photo, video, or file context for one clear follow-up. If the host goes offline,
+restore host power, login/linger state, and service reachability before resending.
+
+## Recipe 4: verify a mobile UI across adverse states
+
+Open the Device panel, start the target simulator, and authorize agent device access
+only if automation is needed. Establish a baseline, then change one Tools setting at
+a time: dark mode, larger text, accessibility frames, denied permission, fake
+location, rotation, or offline network. Capture the failing condition, ask the agent
+to fix and verify it, and repeat the user path yourself. Restore state afterward and
+record device, OS, orientation, and conditions with the result.
+
+## Recipe 5: work on a remote SSH machine
+
+Add the SSH environment from desktop and confirm non-interactive Node and provider
+commands work. Open the remote project; remember that Files, Terminal, Git, and the
+agent now operate on that host. If you need mobile access later, expose the server
+through T3 Connect or a routable private path and keep it running with the supported
+service. Never diagnose a remote missing binary by installing it on the viewing
+laptop.
+
+## Symptom-to-owner table
+
+| Symptom | Likely owner | First useful evidence | Recovery |
+| --- | --- | --- | --- |
+| Environment is offline | Host/service/network | `t3 service status`, its log path, host clock and route | Start/repair service, wake host, fix route or pairing; restart after permanent Connect rejection. |
+| T3 Connect login exists but host is absent | Exposure/server lifecycle | `t3 connect status` plus service status | Start `t3 serve` or install/start service; login alone is insufficient. |
+| Hosted web cannot connect to LAN URL | TLS/reachability | Endpoint scheme and route from browser | Use HTTPS such as Tailscale Serve/T3 Connect, or a local browser that can open direct HTTP. |
+| Provider does not start | Provider on environment | Provider login command, model availability, server log | Authenticate on host, rescan/restart, choose supported model/provider. |
+| Push metadata loads but Git push fails | Git remote credentials | `git remote -v` and host-side SSH/HTTPS auth | Configure the remote's credentials; provider API login is separate. |
+| Terminal history is missing | Scrollback bounds/client view | Whether output exceeded 5,000 lines or 8 MiB | Rerun focused command or use a saved log; do not rely on scrollback as archive. |
+| Browser preview lacks login | Preview profile | Selected profile and import time | Import once with source browser closed or sign in directly; imports do not stay synchronized. |
+| SnapShot shortcut does nothing | OS/compositor setup | SnapShots Settings status and desktop session | Check permission, shortcut collision, Wayland helper/extension, and compositor config. |
+| Device video is blank remotely | Secure-context/platform path | URL scheme and device platform | Use HTTPS/localhost; plain HTTP gives iOS stills and no Android video. |
+| Simulator cannot reach Metro | Network topology | Simulator host and Metro bind address | Bind or forward Metro to an address reachable from the device host. |
+| Usage totals seem low | Available history/filter | Selected environments and scan state | Wait for scans, refresh, inspect model pricing; estimates remain incomplete if history is absent. |
+| Update notice remains | Wrong host/version | Named environment and client version | Update the server machine with the exact client version and preserve startup options. |
+
+## Recover without compounding the failure
+
+Capture the current thread, environment, command, and first meaningful error. Avoid
+repeated Send, repeated merge, or repeated update actions while state is unknown.
+Inspect the workspace diff before reverting or restarting. A client reconnect does
+not necessarily stop the agent; a server restart can interrupt it. After recovery,
+wait for synchronized thread state and verify files and Git status before issuing a
+new instruction.
+
+
+ When an agent, update, or remote action has an uncertain outcome, first re-read the
+ authoritative thread and workspace state. Repeating the action can create a second
+ turn, duplicate external work, or hide the original failure.
+
+
+## Collect a useful bug report
+
+Record the client surface and version, environment/server version, connection mode,
+host OS, provider, project state, exact action, and visible error. Include a trace ID
+or Cloudflare Ray ID when T3 displays one. Redact pairing URLs, authorization codes,
+tokens, prompts, private source, and unrelated terminal output. Prefer a minimal
+reproduction and a small screenshot or video over a full session dump.
+
+The user-facing facts in these recipes are pinned to the reference repository's
+[user documentation](https://github.com/pingdotgg/t3code/tree/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user).
diff --git a/src/content/book/180-acp-cursor-grok.mdx b/src/content/book/180-acp-cursor-grok.mdx
index d009164..449ffab 100644
--- a/src/content/book/180-acp-cursor-grok.mdx
+++ b/src/content/book/180-acp-cursor-grok.mdx
@@ -1,10 +1,10 @@
---
slug: acp-cursor-grok
-order: 180
-number: "18"
+order: 330
+number: "33"
kind: chapter
-part: Part IV · Five harnesses, one product model
-partOrder: 4
+part: Part V · Six providers, one product model
+partOrder: 5
title: ACP transport, Cursor, and Grok
shortTitle: ACP, Cursor, and Grok
summary: A shared JSON-RPC runtime gives Cursor and Grok one transport skeleton, while their startup, mode/model, extension, interruption, and rollback semantics deliberately diverge.
@@ -18,7 +18,7 @@ objectives:
keywords: [ACP, JSON-RPC, Cursor, Grok, session resume, extension, approval, steering, interrupt, rollback]
sourceAreas: [packages/effect-acp/src, apps/server/src/provider/acp, apps/server/src/provider/Layers/CursorAdapter.ts, apps/server/src/provider/Layers/GrokAdapter.ts]
visuals: [ACP session startup sequence, semantic fork matrix, steering race explorer]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -54,7 +54,7 @@ normalized ACP observations.
-
+
|stdio JSON-RPC| A[effect-acp client]
A --> R[AcpSessionRuntime]
@@ -152,7 +152,7 @@ The rollback row is intentionally asymmetric. Cursor’s implementation removes
from its local `ctx.turns` array; source inspection does not find a Cursor ACP native
revert call in that method. That changes the adapter’s read snapshot, not necessarily
the provider’s remote history. Grok refuses the operation explicitly. Orchestration
-revert still has its own durable events and projection cleanup (Chapter 13); neither
+revert still has its own durable events and projection cleanup (Chapter 28); neither
adapter row should be read as a transaction across that durable model and native
provider state.
diff --git a/src/content/book/185-antigravity-provider.mdx b/src/content/book/185-antigravity-provider.mdx
new file mode 100644
index 0000000..1f93f31
--- /dev/null
+++ b/src/content/book/185-antigravity-provider.mdx
@@ -0,0 +1,119 @@
+---
+slug: antigravity-provider
+order: 335
+number: "33A"
+kind: chapter
+part: Part V · Six providers, one product model
+partOrder: 5
+title: Antigravity through ACP, managed auth, and account catalogs
+shortTitle: Antigravity provider
+summary: How T3 Code turns Antigravity's managed runtime, Google authentication, ACP extensions, attachments, skills, and subagent batches into the shared product model.
+status: source-checked
+gates: [sources, links, interaction, editorial]
+objectives:
+ - Separate Antigravity installation, authentication, ACP transport, and session state.
+ - Trace an account sign-in and a turn through their distinct boundaries.
+ - Identify capability differences that the shared UI must preserve.
+keywords: [Antigravity, ACP, Google auth, Gemini, provider adapter, attachments, subagents]
+sourceAreas: [apps/server/src/provider/Layers/AntigravityAdapter.ts, apps/server/src/provider/acp, docs/user/providers-antigravity.md]
+visuals: [Antigravity control and runtime lanes, capability table]
+updatedAt: "2026-09-11"
+---
+
+import Callout from "../../components/Callout.astro";
+import Mermaid from "../../components/Mermaid.astro";
+
+Antigravity is the sixth built-in provider. Calling it “another ACP adapter” misses
+most of the design. ACP carries session traffic, but installation, Google account
+authentication, callback recovery, model discovery, usage limits, attachments,
+skills, and subagent presentation each cross a separate boundary.
+
+## Four boundaries, one provider card
+
+ I[Managed runtime\ninstallation and version]
+ UI --> AU[Auth controller\nGoogle · ADC · API key]
+ AU --> CB[Browser callback\nor pasted code]
+ AU --> AC[Saved account access]
+ AC --> CAT[Account model catalog\nand usage limits]
+ UI --> T[Start thread]
+ T --> AD[AntigravityAdapter]
+ AD --> ACP[ACP session transport]
+ ACP --> AG[Antigravity runtime]
+ AG --> EV[Native events]
+ EV --> AD
+ AD --> OR[Canonical T3 events]
+ OR --> CL[Web · desktop · mobile]`} />
+
+The driver constructs the configured instance and its presentation. The provider
+snapshot reports installation, account status, models, commands, skills, and limits.
+The adapter owns live sessions and translates native ACP events. Orchestration owns
+the durable T3 thread. A healthy provider snapshot does not prove a particular
+thread’s native session is still alive.
+
+## Authentication is not environment pairing
+
+Environment pairing answers “may this client control the T3 server?” Antigravity
+authentication answers “which Google or API-backed account may this provider use?”
+The web or desktop client asks the server’s provider-auth service to begin sign-in.
+Google normally returns to a loopback callback. When the browser is on another
+device, the user can paste the final callback URL or code so the environment that
+owns the provider finishes the exchange.
+
+The supported sign-in shapes are Google account, Application Default Credentials,
+Gemini API key, and Vertex AI configuration. Their credentials and available models
+are different, so the provider snapshot must come from the configured environment
+and account rather than a static global list.
+
+## Models and capabilities stay account-shaped
+
+Antigravity uses the account catalog and does not support T3 Code custom models. A
+resumed thread keeps its selected model; if the account later loses access, the user
+must choose an available model before continuing. Planning uses Antigravity’s native
+`/plan` command rather than T3’s separate Plan mode.
+
+| Capability | Antigravity behavior | Product consequence |
+| --- | --- | --- |
+| Permissions | Native ACP permission requests are normalized | The UI presents shared choices without claiming identical provider policy. |
+| Attachments | Images, PDFs, text, and supported audio with provider limits | T3 validates and translates before session input. |
+| Skills | User skills are discovered from the Gemini home | Availability belongs to the selected provider instance. |
+| Subagents | Child activity arrives in batches | The client shows the batch; it cannot open or steer every child independently. |
+| Rewind | Provider conversation rewind is unavailable | A filesystem checkpoint must not pretend it also rolled back native context. |
+| Models | Account-discovered catalog | Refresh after account or entitlement changes. |
+
+
+ A shared composer does not imply a least-common-denominator runtime. T3 Code
+ normalizes what can be represented honestly and keeps unsupported operations
+ unavailable. Antigravity’s missing rewind and custom-model paths are visible
+ capability decisions, not errors to hide behind another provider’s behavior.
+
+
+## Session and event path
+
+Starting a thread resolves the exact provider instance, model, working directory,
+mode, attachments, and runtime instructions. The adapter starts or resumes its ACP
+session and consumes native updates. Text, tool calls, permissions, questions,
+plans, usage, errors, and batched child activity become canonical provider events.
+Those observations re-enter orchestration, update projections, and stream to every
+client that follows the thread.
+
+Attachment preparation enforces Antigravity’s own sizes and supported formats. The
+current user contract documents 1 MiB per text file, 10 MiB per image, 20 MiB per
+audio clip, and 50 MiB total per message. Workspace visibility and provider input
+support are separate checks: a file visible in T3 Code is not automatically valid
+provider input.
+
+## Recovery model
+
+Google sign-in is persisted across server restarts. Provider status can be refreshed
+from Settings or mobile thread settings to reload access, models, skills, and limits.
+A live thread still depends on ACP continuation data and the exact configured
+instance. Losing a native session, removing the instance, changing account access,
+and reverting Git state are four different events and require different recovery.
+
+### Current source trail
+
+- [Antigravity adapter](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/apps/server/src/provider/Layers/AntigravityAdapter.ts)
+- [ACP support](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/apps/server/src/provider/acp/AntigravityAcpSupport.ts)
+- [Authentication support](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/apps/server/src/provider/antigravityAuthSupport.ts)
+- [Product guide](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/providers-antigravity.md)
diff --git a/src/content/book/190-opencode-normalization.mdx b/src/content/book/190-opencode-normalization.mdx
index 3b881db..3dd2926 100644
--- a/src/content/book/190-opencode-normalization.mdx
+++ b/src/content/book/190-opencode-normalization.mdx
@@ -1,11 +1,11 @@
---
slug: opencode-normalization
-order: 190
-number: "19"
+order: 340
+number: "34"
kind: chapter
-part: Part IV · Five harnesses, one product model
-partOrder: 4
-title: OpenCode ownership, recovery, and five-provider normalization
+part: Part V · Six providers, one product model
+partOrder: 5
+title: OpenCode ownership, recovery, and six-provider normalization
shortTitle: OpenCode and normalization
summary: OpenCode is an HTTP SDK integration with scoped local-server ownership or external-server attachment; its session adoption and cwd-fork policy show why a common product model must preserve provider-specific recovery semantics.
status: source-checked
@@ -14,11 +14,11 @@ objectives:
- Trace OpenCode’s local/external server ownership and session-scoped event pump.
- Follow resume adoption, not-found handling, cwd equivalence, and history-preserving fork.
- Separate native OpenCode methods from canonical runtime events and durable orchestration state.
- - Read the five-provider matrix as an evidence ledger, not a feature-negotiation protocol.
+ - Read the six-provider matrix as an evidence ledger, not a feature-negotiation protocol.
keywords: [OpenCode, SDK, external server, session adoption, fork, cwd, permissions, promptAsync, rollback, normalization, tasks, skills, usage]
sourceAreas: [apps/server/src/provider/Layers, apps/server/src/provider/opencodeRuntime.ts, apps/server/src/provider/Services/ProviderAdapter.ts, apps/server/src/usage]
visuals: [OpenCode session ownership lifecycle, resume decision tree, provider normalization matrix]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -48,7 +48,7 @@ the SDK event subscription, and exit-watch fibers.
-
+
|yes| E[external server handle\nnot scope-owned]
@@ -146,38 +146,38 @@ durable thread-revert path and any workspace/Git checkpoint restoration.
reconciliation boundary rather than claiming a single atomic undo.
-## Five providers, one comparison language
+## Six providers, one comparison language
-The book’s five harnesses are Codex, Claude, Cursor, Grok, and OpenCode. The matrix is
+The six providers are Codex, Claude, Cursor, Grok, Antigravity, and OpenCode. The matrix is
an evidence ledger with four cell types: **native mapping**, **adapter behavior or
emulation**, **explicitly unsupported**, and **not evidenced in the inspected source**.
It is not the `ProviderAdapter` SPI and not a runtime capability negotiation table.
-The SPI’s declared capability object at this pinned revision contains only
-`sessionModelSwitch`; these five adapters report it as in-session.
+The SPI’s declared capability object contains only
+`sessionModelSwitch`; the adapters report their concrete support through the shared boundary.
-
+
-
Source-grounded normalization categories across five providers
-
Operation
Codex
Claude
Cursor
Grok
OpenCode
+
Source-grounded normalization categories across six providers
+
Operation
Codex
Claude
Cursor
Grok
Antigravity
OpenCode
-
transport
native app-server JSON-RPC mapping
native Agent SDK stream mapping
native ACP stdio mapping
native ACP stdio + XAI extension mapping
native SDK/HTTP event mapping
-
resume
adapter passes a Codex resume cursor to app-server runtime
adapter uses SDK resume metadata
adapter passes native session id to ACP load/new flow
adapter passes native session id to ACP load/new flow
a recognized cursor re-adopts sessionId; confirmed miss starts fresh; absent/malformed/wrong-version cursor means no resume; cwd change forks
-
mid-turn send
calls native turn/start; app-server may queue a new native turn id while interrupt still targets the current one
queues into the live SDK loop and reuses the active product turn id
reuses active product turn while prompts are in flight
reuses active turn with target-aware settlement
calls promptAsync and reuses active product turn
-
approval/input
native JSON-RPC requests mapped to canonical request/input events
SDK-side deferred interactions mapped to canonical request/input events
native plans plus multi-agent signals become plan and task.* events
TodoWrite, coordinator, and member observations become plan and task.* events
Cursor plan/todo extensions become plan events; no task.* emission branch found
ACP plan observations become plan events; no task.* emission branch found
native /plan; subagent activity is grouped into batches
plan mode selects a native agent and task-like tools become item activity; no plan or task.* emission branch found
+
commands and skills discovery
snapshot requests native skills and adds a feedback slash command
snapshot combines initialization commands with discovered filesystem skills
snapshot exposes models/probe state
snapshot includes provider skills and commands where discovered
discovers user skills from the Gemini home
provider inventory exposes skills; no slash commands found
+
live context telemetry
emits canonical token-usage snapshots
emits canonical token-usage snapshots when normalization succeeds
provider-specific support
provider-specific support
reports account limit windows through provider status
provider-specific support
+
historical Usage source
Codex JSONL session transcripts are scanned
Claude JSONL project transcripts are scanned
not scanned
not scanned
subscription limits are account-reported rather than transcript-priced history
not scanned
+
rollbackThread behavior
native app-server rollback mapping
adapter-local turn snapshot truncation plus resume-cursor refresh
adapter-only local snapshot truncation
explicitly unsupported
explicitly unavailable
native session.revert mapping
+
in-session model switch
declared SPI capability
declared SPI capability
declared SPI capability
declared SPI capability
account catalog and ACP capability decide
declared SPI capability
+
failure projection
typed process/protocol/request failures plus runtime warning/error events
typed SDK/request failures plus terminal result classification
typed ACP failures plus provider-specific callback and cancel handling
typed ACP failures plus late-event suppression around interruption
managed runtime, authentication, account, and ACP failures stay distinct
typed SDK/HTTP failures; when probing a recognized cursor, only confirmed not-found permits fresh-session replacement
-An absence cell means no implementation branch was found at this pinned revision;
-it does not claim the upstream product can never expose that feature. Chapters 16,
-17, and 20 provide the longer Codex, Claude, and usage trails. The matrix keeps
+An absence cell means no implementation branch was found;
+it does not claim the upstream product can never expose that feature. Chapters 31,
+32, 33A, and 35 provide the longer Codex, Claude, Antigravity, and usage trails. The matrix keeps
provider discovery (skills/commands), live adapter normalization (plans/tasks and
context telemetry), and the independent transcript scanner in separate rows so one
surface cannot masquerade as another.
diff --git a/src/content/book/20-domain-vocabulary.mdx b/src/content/book/20-domain-vocabulary.mdx
index 2864676..b8be368 100644
--- a/src/content/book/20-domain-vocabulary.mdx
+++ b/src/content/book/20-domain-vocabulary.mdx
@@ -1,10 +1,10 @@
---
slug: domain-vocabulary
-order: 20
-number: "2"
+order: 170
+number: "17"
kind: chapter
-part: Part I · Boundaries and vocabulary
-partOrder: 1
+part: Part II · Boundaries and vocabulary
+partOrder: 2
title: Environment, project, thread, turn, and session
shortTitle: Domain vocabulary
summary: The entities share a UI, but they have different identity, cardinality, ownership, and restart behavior.
@@ -17,7 +17,7 @@ objectives:
keywords: [environment, project, thread, turn, session, entity model]
sourceAreas: [packages/contracts/src/environment.ts, packages/contracts/src/orchestration.ts, packages/contracts/src/providerRuntime.ts]
visuals: [entity relationship table, lifecycle scenario lab]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
diff --git a/src/content/book/200-usage-accounting.mdx b/src/content/book/200-usage-accounting.mdx
index 4ec50bd..59ae440 100644
--- a/src/content/book/200-usage-accounting.mdx
+++ b/src/content/book/200-usage-accounting.mdx
@@ -1,24 +1,25 @@
---
slug: usage-accounting
-order: 200
-number: "20"
+order: 350
+number: "35"
kind: chapter
-part: Part IV · Five harnesses, one product model
-partOrder: 4
+part: Part V · Six providers, one product model
+partOrder: 5
title: Usage accounting without a false ledger
shortTitle: Usage accounting
-summary: "The live context meter and historical transcript usage view are deliberately different measurements: one projects the latest usable context snapshot for a thread, while the other scans provider-owned files into a deduplicated, priced historical estimate."
+summary: "Live thread context, historical transcript accounting, and provider-reported subscription limits answer different questions and keep separate evidence, merge, pricing, and refresh rules."
status: source-checked
gates: [sources, interaction]
objectives:
- Trace the live context-window snapshot from provider adapter to the web composer.
- Trace historical Claude and Codex transcript records through parsing, deduplication, bucketing, pricing, and environment merge.
+ - Explain Grok transcript accounting, custom prices, pooled subscription windows, hubs, and reset credits.
- Interpret coverage, source fingerprints, cache state, and cost provenance without claiming a billing settlement.
- Keep task and subagent accounting as a distinct later concern.
keywords: [usage, context window, transcripts, pricing, deduplication, cache, RPC, provenance, environments]
sourceAreas: [packages/contracts/src/providerRuntime.ts, packages/contracts/src/usage.ts, apps/server/src/provider/Layers, apps/server/src/orchestration/Layers, apps/server/src/usage, packages/shared/src/usageMerge.ts, apps/web/src/components/usage, apps/mobile/src/features/usage]
visuals: [two-lane usage pipeline, usage accounting lab, source-fingerprint merge]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -29,19 +30,22 @@ import SourceExcerpt from "../../components/SourceExcerpt.astro";
import SourceList from "../../components/SourceList.astro";
import UsageAccountingLab from "../../components/UsageAccountingLab.astro";
-“Usage” names two different questions in T3 Code.
+“Usage” names three different questions in T3 Code.
The composer asks: **how full is this thread's context window at the latest valid
-provider update?** The Usage screens ask: **what token-shaped records can this
-environment read from selected provider transcript directories over a historical
-time range?** They share words such as model, tokens, and session, but they do not
-share a source of truth, an update cadence, or a settlement guarantee.
-
-
+provider update?** The Usage history asks: **what token-shaped records can this
+environment read from provider transcript directories over a historical time
+range?** The Limits view asks: **how much provider-reported subscription capacity
+remains across the selected accounts and environments?** They share words such as
+model, tokens, account, and session, but they do not share a source of truth, an
+update cadence, or a settlement guarantee.
+
+
A current context snapshot is not added to the historical Usage total. Conversely,
a historical transcript scan cannot certify that the currently displayed context
meter is complete, current, or billed. The first is a live operational aid; the
- second is an evidence-limited accounting estimate.
+ second is an evidence-limited accounting estimate. A subscription-limit bar is a
+ provider-reported rolling window; it is neither of those token totals.
## The live lane projects a current context snapshot
@@ -55,7 +59,7 @@ identity.
-At this pinned revision, source inspection finds canonical token-usage emission in
+Source inspection finds canonical token-usage emission in
two adapters:
@@ -88,7 +92,7 @@ files.
-
+
The meter can be absent because no valid activity has reached it, because an
@@ -99,16 +103,17 @@ files.
metadata—not a cross-thread, cross-day, or cost total.
-## The historical lane scans files, not orchestration state
+## The historical lane scans three provider homes, not orchestration state
-The version-4 usage contract intentionally reads selected CLI homes: Claude JSONL
+The version-5 usage contract reads selected CLI homes: Claude JSONL
under a resolved Claude home (preferring `.claude/projects`, with a `projects`
-fallback) and Codex JSONL under the resolved Codex shared-home `sessions` tree. The
+fallback), Codex JSONL under the resolved Codex shared-home `sessions` tree, and
+Grok `updates.jsonl` files under its resolved sessions home. The
server exposes preaggregated buckets, never raw transcript records. Consequently it
can include provider turns made outside T3 Code, but it cannot account for a
-provider whose history is not in those two scanned layouts.
+provider whose history is not in those three scanned layouts.
-
+
@@ -123,7 +128,9 @@ Parser rules are provider-specific. Claude accepts assistant records with a usag
object and deduplicates repeated content-block accounting by message/request key.
Codex follows turn-context model state and `last_token_usage` deltas; it subtracts
cached tokens from the reported input count and applies a one-second fork-copy
-suppression heuristic. Codex records carry no global duplicate key: consecutive
+suppression heuristic. Grok reads completed-turn updates, can split model-level
+usage, converts provider cost ticks, and uses session, prompt, and model identity
+for deduplication when available. Codex records carry no global duplicate key: consecutive
delta suppression and fork-copy suppression are parser-local. That one-second
threshold is implementation behavior, not a portable provider promise.
@@ -172,11 +179,51 @@ one session repeatedly across day/model buckets.
passes answered summaries to the shared versioned merge.
+## Custom prices are environment settings
+
+Automatic model pricing is a convenience, not an authority. Web and desktop let a
+user set exact per-million input, output, cache-read, and cache-write rates for a
+model on one or several environments. Blank cache rates inherit the input rate;
+zero means free. Saving is fan-out work: each destination reports success, and a
+failed destination can be retried without rewriting the environments that already
+accepted the change. Closing the dialog does not create an offline write queue.
+
+The historical scan applies these overrides before automatic pricing. A client that
+selects several environments can therefore see a mixed value when their local price
+settings differ. This is an intentional consequence of environment ownership.
+
+## Subscription limits are provider and account state
+
+Provider snapshots can carry normalized rolling windows with stable ids, a kind,
+label, used percentage, optional reset time, and optional duration. Sparse updates
+merge by window id so one rate-limit event does not erase unrelated windows. An
+unavailable reason distinguishes an account that cannot report limits from a probe
+that failed while a prior good snapshot may still be useful.
+
+The Limits view pools equivalent accounts across selected environments and optional
+CLIProxyAPI hubs. It presents **remaining** capacity, keeps the same account segment
+in the same visual column across windows, and explains the next reset. Codex accounts
+may also report banked reset credits; redemption pins the request to the displayed
+credit id so a retry cannot silently consume a different credit.
+
+`/usage-limits` reads the same snapshot inside a thread. It does not run an agent or
+refresh provider state. API-key accounts and some proxy configurations may never
+report subscription windows, which is different from a temporary probe failure.
+
+ L[Latest thread context\noperational meter]
+ B[Claude · Codex · Grok\ntranscript files] --> H[Historical tokens and\nAPI-equivalent estimate]
+ C[Provider account probes\nand optional hubs] --> Q[Remaining subscription\nlimit windows]
+ P[Environment model-price overrides] --> H
+ R[Sparse rate-limit updates] --> Q
+ L ~~~ H
+ H ~~~ Q`} />
+
-
+ B{usedTokens > 0?}
@@ -185,7 +232,7 @@ one session repeatedly across day/model buckets.
D --> E[composer context meter]
end
subgraph H[Historical transcript accounting · selected files]
- F[Claude / Codex JSONL homes] --> G[parse + normalize]
+ F[Claude / Codex / Grok JSONL homes] --> G[parse + normalize]
G --> I[within-file and cross-file dedupe]
I --> J[time bounds + day/hour buckets]
J --> K[reported cost or rate-table estimate]
@@ -196,7 +243,7 @@ one session repeatedly across day/model buckets.
A ~~~ F`} />
-There is an important diagnostic limitation at this pinned revision. The contract
+There is an important diagnostic limitation. The contract
permits `ok`, `missing`, `partial`, and `failed` source states, but the service path
observed here emits `missing` when the directory is absent—or when the existence
check itself fails—and otherwise reports `ok`. Directory listing errors are swallowed
@@ -244,7 +291,7 @@ live `88,000 / 200,000` context snapshot remains deliberately outside that total
Runtime task/subagent work has its own lifecycle and optional usage-shaped data.
This chapter intentionally does not roll it into thread context telemetry or
- provider-transcript accounting. The planned Chapter 25 will define its identity,
+ provider-transcript accounting. Chapter 40 defines its identity,
fan-out, retries, and attribution rules before a task-level total is presented.
diff --git a/src/content/book/210-project-discovery.mdx b/src/content/book/210-project-discovery.mdx
index ad6073f..f9b7e81 100644
--- a/src/content/book/210-project-discovery.mdx
+++ b/src/content/book/210-project-discovery.mdx
@@ -1,13 +1,13 @@
---
slug: project-discovery
-order: 210
-number: "21"
+order: 360
+number: "36"
kind: chapter
-part: Part V · The work lifecycle
-partOrder: 5
-title: Project discovery and t3.json
+part: Part VI · The work lifecycle
+partOrder: 6
+title: Project discovery, onboarding import, and t3.json
shortTitle: Project discovery
-summary: "A T3 project is an environment-local durable record for one normalized workspace root; checked-in t3.json and Git-remote identity enrich its behavior and presentation without replacing that record."
+summary: "A T3 project is an environment-local durable record for one normalized workspace root; onboarding can import existing agent sessions, while checked-in t3.json and Git-remote identity enrich behavior and presentation without replacing that record."
status: source-checked
gates: [sources, interaction]
objectives:
@@ -18,7 +18,7 @@ objectives:
keywords: [projects, workspace root, discovery, t3.json, repository identity, environments, configuration, setup scripts, projection]
sourceAreas: [apps/server/src/workspace/WorkspacePaths.ts, apps/server/src/project, packages/contracts/src/t3ProjectFile.ts, packages/shared/src/threadEnvMode.ts, packages/client-runtime/src/state/projectGrouping.ts]
visuals: [filesystem discovery decision explainer, project identity projection]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -29,8 +29,8 @@ import ProjectDiscoveryLab from "../../components/ProjectDiscoveryLab.astro";
import SourceExcerpt from "../../components/SourceExcerpt.astro";
import SourceList from "../../components/SourceList.astro";
-“Project” is deliberately not a synonym for “Git repository.” At this pinned
-revision, it starts as an environment-local durable record with a normalized
+“Project” is deliberately not a synonym for “Git repository.” It starts as an
+environment-local durable record with a normalized
directory as its `workspaceRoot`. Git can later provide an identity for that
directory; clients can then choose to group equivalent identities across
environments. Neither upgrade makes paths, directories, and project records the
@@ -140,7 +140,7 @@ entries merely because a checkout contains `t3.json`.
-
+ L[best-effort file loader]
L --> I[deduplicated import suggestions]
@@ -174,7 +174,7 @@ not promise that a remote URL is permanently frozen into project history.
-
+ R{validated directory?}
R -->|yes| C[project.create]
@@ -244,6 +244,21 @@ coexist—but none automatically proves the next one.
establish such a recursive importer.
+## Importing native agent history
+
+The welcome flow can scan Codex and Claude homes for work the user already did,
+group candidates by repository identity, and import selected conversations into T3
+projects. Git repositories sort ahead of ordinary folders, and recent, repeated work
+can be preselected without importing every scratch session.
+
+The scanner reads provider-native metadata. The importer creates canonical T3
+messages and activities with a stable source identity so retries do not duplicate the
+same history. Imported history is durable and searchable; resumability remains a
+provider decision because display records alone cannot recreate a missing native
+session. The boundaries live in
+[AgentSessionScanner.ts](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/apps/server/src/project/AgentSessionScanner.ts) and
+[AgentSessionImporter.ts](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/apps/server/src/project/AgentSessionImporter.ts).
+
-
+ L[local request: no new worktree]
L --> R[stored thread path, else project root]
diff --git a/src/content/book/230-turn-lifecycle.mdx b/src/content/book/230-turn-lifecycle.mdx
index dba889e..c2c9755 100644
--- a/src/content/book/230-turn-lifecycle.mdx
+++ b/src/content/book/230-turn-lifecycle.mdx
@@ -1,10 +1,10 @@
---
slug: turn-lifecycle
-order: 230
-number: "23"
+order: 380
+number: "38"
kind: chapter
-part: Part V · The work lifecycle
-partOrder: 5
+part: Part VI · The work lifecycle
+partOrder: 6
title: Start, stream, steer, interrupt, settle
shortTitle: Turn lifecycle
summary: A T3 turn begins as a durably accepted command and later crosses hot reactor and provider-runtime boundaries; session state, output, checkpoints, and client liveness each have narrower guarantees.
@@ -18,7 +18,7 @@ objectives:
keywords: [thread, turn, lifecycle, receipt, reactor, provider runtime, buffering, interrupt, checkpoint, settlement, liveness]
sourceAreas: [packages/contracts/src/orchestration.ts, packages/contracts/src/providerRuntime.ts, apps/server/src/orchestration/decider.ts, apps/server/src/orchestration/Layers/ProviderCommandReactor.ts, apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts, apps/server/src/orchestration/Layers/CheckpointReactor.ts, apps/server/src/provider/Layers/ProviderService.ts, packages/client-runtime/src/state/threads.ts]
visuals: [turn lifecycle swimlane, illustrative-control state-machine lab]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -137,7 +137,7 @@ The shared client reducer makes the same distinction: a completed assistant
message does not settle its turn while that turn remains the session's active
running turn; leaving `running` is the turn-end signal for the client model.
-
+ E[(message + start intent + receipt)]
E -. hot domain event .-> R[command reactor]
@@ -217,7 +217,7 @@ provenance; it must not be presented as a new T3 turn, completion, checkpoint,
or a T3-owned summary artifact.
- At this pinned revision, the runtime vocabulary can represent context
+ The runtime vocabulary can represent context
compaction and ingestion can preserve its observation as activity. The lifecycle
folding inspected here does not establish a generic “compaction completed the
turn” rule. Any future product behavior that does so should be explicitly sourced
diff --git a/src/content/book/240-permissions-input.mdx b/src/content/book/240-permissions-input.mdx
index 59b5dd2..1a483dc 100644
--- a/src/content/book/240-permissions-input.mdx
+++ b/src/content/book/240-permissions-input.mdx
@@ -1,10 +1,10 @@
---
slug: permissions-and-input
-order: 240
-number: "24"
+order: 390
+number: "39"
kind: chapter
-part: Part V · The work lifecycle
-partOrder: 5
+part: Part VI · The work lifecycle
+partOrder: 6
title: Permission modes, approvals, and structured input
shortTitle: Permissions and input
summary: T3 Code persists a four-value runtime-mode choice on a thread, but each provider maps that choice into its own controls; live approval and structured-input requests travel through distinct canonical flows.
@@ -17,7 +17,7 @@ objectives:
keywords: [runtime mode, permission, approval, structured input, reactor, pending state, provider adapter, security]
sourceAreas: [packages/contracts/src/orchestration.ts, packages/contracts/src/provider.ts, apps/server/src/provider, apps/server/src/orchestration/Layers, apps/web/src/session-logic.ts, apps/mobile/src/state/use-selected-thread-requests.ts]
visuals: [permission mapping matrix, interactive request router]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -51,7 +51,7 @@ policy, not an independent per-turn override hidden in the start command.
| `auto` | `on-request`, `workspace-write`, `auto_review` reviewer | `auto` | prefers an implement-mode alias when offered; permission callbacks still wait | no ACP session-mode mapping; a raised permission callback waits for an explicit response | broad operations ask; `question` is allowed |
| `full-access` | `never`, `danger-full-access`, user reviewer | `bypassPermissions` plus `allowDangerouslySkipPermissions: true` | prefers an implement-mode alias and auto-selects an offered allow option; otherwise waits on the callback | auto-selects an offered allow-always or allow-once option; otherwise waits on the callback | allows all permission rules |
-The table records executed mappings at this pinned revision. It does **not** turn
+The table records the executed mappings. It does **not** turn
the blank Claude map entry, Cursor mode aliases, Grok callback policy, or OpenCode's
shared non-full-access ruleset into claims of equivalent safety. Codex, for example,
also selects a native sandbox and reviewer for every mode. Claude intercepts
@@ -96,7 +96,8 @@ map.
- OpenCode maps `permission.asked` and `question.asked` separately, then calls
`permission.reply` or `question.reply`.
-All five adapters implement both response operations in the current source. That
+All six adapters implement the shared response boundary, with provider-specific
+support for originating each request shape. That
does not promise every provider originates both request kinds in every configuration.
The adapter capability surfaces are the positive evidence here; they are not a
guarantee that a native runtime will open a given request type during every session.
@@ -141,7 +142,7 @@ runtime ingestion and become durable activities.
Acceptance of the client command is not a synchronous certificate that a provider
completed the action, and the hot provider bridge is not a replayable outbox.
-
+ I[runtime ingestion]
I --> A[(request activity)]
@@ -170,7 +171,7 @@ addressed to a thread; each client chooses its controls.
| Person operating the client | the authorization decision | that a broad mode replaces reviewing a specific request |
Permission capability metadata could make these differences easier to negotiate in
-a UI, but none exists at this pinned revision. That is a **future design direction**,
+a UI, but no central inbox is implemented. That is a **future design direction**,
not current behavior.
-Codex and Claude have concrete task normalization paths in the pinned source.
+Codex and Claude have concrete task normalization paths.
Codex turns collaboration-agent notifications into task lifecycle/progress events.
Claude maps SDK task, workflow, and member progress messages into task events,
including typed usage when present. This audit does not establish equivalent
task-rollup coverage for Cursor, Grok, or OpenCode; absence here is an evidence
boundary, not a claim they can never support it.
-
+ A[provider adapter]
A -. canonical task event .-> I[runtime ingestion]
@@ -137,11 +137,11 @@ For Codex and Claude task data, the normalizer can roll up per-task `totalTokens
input/cache/output/reasoning fields, `toolUses`, and `durationMs` when typed usage
supplies them. These are task-local, provider-observed rollups. They are not invoice
records. **Inference from the separate ingestion paths:** they do not feed either
-Chapter 20 lane; neither the live thread-context meter nor the transcript-scan
+Chapter 35 lane; neither the live thread-context meter nor the transcript-scan
historical usage total consumes this task rollup.
-
- Chapter 20’s live lane selects one context-window snapshot for a thread; its
+
+ Chapter 35’s live lane selects one context-window snapshot for a thread; its
historical lane scans selected Codex and Claude transcript homes. Task usage is
activity payload for an Agents/work-log projection. No common accumulator joins
those three measurements in the pinned implementation.
@@ -151,7 +151,7 @@ historical usage total consumes this task rollup.
The inspected task path terminates in activity payloads and the Agents fold. The
live context path admits thread.token-usage.updated, while historical
accounting reads provider transcript sources. No inspected accumulator joins the
- task rollup into either Chapter 20 total; that negative conclusion is bounded to
+ task rollup into either Chapter 35 total; that negative conclusion is bounded to
these concrete paths.
diff --git a/src/content/book/260-context-memory.mdx b/src/content/book/260-context-memory.mdx
index 82fc46a..436277b 100644
--- a/src/content/book/260-context-memory.mdx
+++ b/src/content/book/260-context-memory.mdx
@@ -1,10 +1,10 @@
---
slug: context-compaction-memory
-order: 260
-number: "26"
+order: 410
+number: "41"
kind: chapter
-part: Part V · The work lifecycle
-partOrder: 5
+part: Part VI · The work lifecycle
+partOrder: 6
title: Context is provider-owned; history is T3-owned
shortTitle: Context and memory
summary: "T3 Code retains a product-visible thread history and an opaque provider continuation cursor, while each provider owns the prompt context it may resume or compact; the pinned system has no universal T3 long-term-memory subsystem."
@@ -18,7 +18,7 @@ objectives:
keywords: [context, compaction, memory, resume cursor, session recovery, thread history, telemetry, restart]
sourceAreas: [packages/contracts/src/provider.ts, packages/contracts/src/providerRuntime.ts, apps/server/src/persistence/ProviderSessionRuntime.ts, apps/server/src/provider/Layers, apps/server/src/orchestration/Layers, packages/client-runtime/src/state]
visuals: [context ownership map, restart ledger]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -107,7 +107,7 @@ These are adapter-specific policies—not an inter-provider migration protocol.
Codex thread id is not meaningful to Claude; an OpenCode session id is not an
executable representation of a Codex prompt.
-
+
For the separate historical question—tokens/cost-shaped records from provider
-transcript files—read [Chapter 20, “Usage accounting without a false ledger”](../usage-accounting/).
+transcript files—read [Chapter 35, “Usage accounting without a false ledger”](../usage-accounting/).
That scan is neither the source of the live context meter nor a T3 memory layer.
## 5. “Long-term memory” is absent as a universal product subsystem
@@ -223,7 +223,7 @@ event-subscription `afterSequence` from the cached shell sequence. That helps a
screen catch up; it does not act as provider context or server authority. Mobile
additionally owns environment-scoped local drafts and a persisted command outbox.
Those are client resilience/delivery mechanisms and receive their detailed
-treatment in Chapter 33 rather than being rebranded as memory here.
+treatment in Chapter 48 rather than being rebranded as memory here.
The distinction is particularly important after a disconnected mobile action:
delivery retry can re-attempt a client command, while provider session recovery
@@ -231,7 +231,7 @@ still depends on the server's binding and the provider's ability to use its curs
Neither mechanism means a client has captured a complete native model context.
- Chapter 33 will cover client caches, optimistic state, drafts, offline queues,
+ Chapter 48 covers client caches, optimistic state, drafts, offline queues,
and reconnect reconciliation by surface. This chapter only places them outside
the provider-context boundary so a reader does not mistake local UI state for
T3-owned long-term memory.
@@ -254,7 +254,7 @@ motion; keyboard tab navigation and a complete static/print ledger are included.
3. Represent compaction as provider-originated provenance unless the product owns
the summarization algorithm and its exact replay/retention semantics.
4. Name context telemetry, task usage, and transcript accounting as distinct data
- products. Chapter 20's historical ledger must not silently become a memory
+ products. Chapter 35's historical ledger must not silently become a memory
system.
5. If a universal memory feature is proposed, design its user control, source
provenance, deletion/retention, isolation, provider injection, and restart
diff --git a/src/content/book/270-checkpoints-revert.mdx b/src/content/book/270-checkpoints-revert.mdx
index fcde684..0f0cb43 100644
--- a/src/content/book/270-checkpoints-revert.mdx
+++ b/src/content/book/270-checkpoints-revert.mdx
@@ -1,10 +1,10 @@
---
slug: checkpoints-revert
-order: 270
-number: "27"
+order: 420
+number: "42"
kind: chapter
-part: Part V · The work lifecycle
-partOrder: 5
+part: Part VI · The work lifecycle
+partOrder: 6
title: Hidden-ref checkpoints, diffs, and revert
shortTitle: Checkpoints and revert
summary: Each completed turn can leave a Git tree snapshot under a hidden ref. Review reads those snapshots; revert restores workspace content first, then attempts provider-history rollback before it can complete the durable history rewrite.
@@ -18,7 +18,7 @@ objectives:
keywords: [checkpoint, git, hidden ref, diff, restore, revert, rollback, worktree, projection]
sourceAreas: [apps/server/src/checkpointing, apps/server/src/orchestration/Layers/CheckpointReactor.ts, apps/server/src/vcs/GitVcsDriver.ts, apps/server/src/provider/Layers, apps/web/src/components/DiffPanel.tsx]
visuals: [checkpoint timeline, checkpoint graph lab, revert saga]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -99,7 +99,7 @@ side-by-side review modes, but they answer different questions.
| Working tree | `HEAD` → current tracked worktree, plus patches for untracked files | live filesystem | yes |
| Branch changes | merge-base(selected base, `HEAD`) → `HEAD` via `git diff ...HEAD` | live repository refs | yes |
-
+ Z[hidden baseline ref · turn 0]
Z --> P[provider changes workspace]
@@ -161,7 +161,7 @@ the implementation is not uniform. Codex delegates to its live app-server runtim
Claude and Cursor truncate their adapter-maintained turn arrays (Claude also updates
its resume cursor). OpenCode reads native session messages, finds the earlier
assistant-message boundary, then calls `session.revert`. Grok deliberately returns
-an unsupported provider-side rollback error at this pinned revision.
+an unsupported provider-side rollback error.
That table is a capability map for this implementation, not a promise that the
upstream provider has erased files, billed tokens, cached context, tool side effects,
@@ -179,7 +179,7 @@ general remote-history deletion guarantee.
This chapter stops at server-side completion and derived projection pruning. How
web and mobile invalidate, race, refetch, and reconcile a reverted snapshot is a
- client history-epoch concern deferred to Chapter 29.
+ client history-epoch concern deferred to Chapter 44.
Do not infer that a fresh server event alone settles every local cache race.
diff --git a/src/content/book/280-workbench-services.mdx b/src/content/book/280-workbench-services.mdx
index f7d0c64..0797f6d 100644
--- a/src/content/book/280-workbench-services.mdx
+++ b/src/content/book/280-workbench-services.mdx
@@ -1,11 +1,11 @@
---
slug: workbench-services
-order: 280
-number: "28"
+order: 430
+number: "43"
kind: chapter
-part: Part V · The work lifecycle
-partOrder: 5
-title: Terminals, files, previews, MCP, VCS, and pull requests
+part: Part VI · The work lifecycle
+partOrder: 6
+title: Terminals, files, previews, MCP, VCS, and review graphs
shortTitle: Workbench services
summary: "T3 Code's chat surrounds itself with server-owned workbench services. Their transports differ deliberately: terminal and preview state stream, assets use expiring signed HTTP paths, pull-request diffs use authenticated HTTP slices, and desktop owns the only in-app browser host."
status: source-checked
@@ -18,7 +18,7 @@ objectives:
keywords: [terminal, PTY, assets, signed URL, preview, browser automation, MCP, VCS, worktree, pull request, authorization, streaming]
sourceAreas: [apps/server/src/terminal, apps/server/src/assets, apps/server/src/preview, apps/server/src/mcp, apps/server/src/vcs, apps/server/src/pullRequest, packages/contracts/src]
visuals: [interactive workbench capability matrix, service data paths, surface parity ledger]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -61,7 +61,7 @@ result through surface-specific code.
| VCS / worktrees | server driver and filesystem | RPC snapshots/commands | “A client branch selector creates a checkout locally.” |
| Pull requests | server host-provider service | RPC controls; HTTP diff slices | “A rendered action proves the user may write.” |
-
+|authenticated RPC| S[Environment server services]
S -->|snapshot + live events| T[Server PTY]
@@ -187,14 +187,15 @@ desktop host is connected.
T3 can attach its own `t3-code` MCP server to a provider session when the agent
browser-access setting permits it. This is not the same as discovering or managing
-every external MCP server configured by Codex, Claude, Cursor, Grok, or OpenCode.
+every external MCP server configured by Codex, Claude, Cursor, Grok, Antigravity,
+or OpenCode.
It is a narrowly scoped T3 endpoint for preview operations.
At provider-session preparation, the server either revokes/clears prior MCP state
when access is disabled or issues a fresh random bearer credential. Its scope is
bound to the environment, thread, provider instance, and a registry-generated MCP
-session id—the latter is not an adapter-native Codex, Claude, Cursor, Grok, or
-OpenCode session identity. The registry stores a hash, not the raw token, and only
+session id—the latter is not an adapter-native Codex, Claude, Cursor, Grok,
+Antigravity, or OpenCode session identity. The registry stores a hash, not the raw token, and only
advertises the `preview` capability. The `/mcp` route sits outside ordinary
environment auth, so it requires that provider-scoped bearer credential. Registry
liveness is refreshed by both MCP traffic and active provider turns; stop/revoke
@@ -203,7 +204,8 @@ liveness window.
-All five adapter paths can consume the T3-owned MCP configuration, but their native
+The six adapter paths can consume the T3-owned MCP configuration according to their
+declared support, but their native
injection mechanisms differ: Codex uses app-server arguments plus a bearer-token
environment variable; Claude supplies an HTTP MCP server; Cursor and Grok pass ACP
MCP server definitions; OpenCode registers the remote server only when T3 owns the
@@ -246,9 +248,9 @@ access merely by rendering a branch, diff, or worktree picker.
Two earlier boundaries matter here:
-- [Chapter 22](../worktree-topology/) traces the start-turn worktree
+- [Chapter 37](../worktree-topology/) traces the start-turn worktree
saga, including its server filesystem effects and failure seam.
-- [Chapter 27](../checkpoints-revert/) traces hidden checkpoint refs,
+- [Chapter 42](../checkpoints-revert/) traces hidden checkpoint refs,
comparison modes, and the destructive restore/revert path.
The workbench is where those results become visible: a terminal's cwd can be the
@@ -296,6 +298,21 @@ future mobile release.
route selects only environments that advertised pull-request capability.
+## 8. A thread can own a review graph
+
+Source control and review state no longer collapse to one pull-request link. A thread
+can link several reviews, including another repository on the same host. The server
+refreshes open links and periodically revisits closed ones so reopen state can return;
+terminal merged state stays terminal. GitHub stacks add layer discovery, navigation,
+sync, guarded rebase, and merge operations that verify expected heads before changing
+remote state.
+
+This graph remains separate from Git checkpoints. A checkpoint identifies workspace
+state for diff and restore. A linked review identifies hosted collaboration state.
+Creating a pull request may connect both workflows, but no transaction spans the Git
+working tree and the hosting provider. The user-facing rules are documented in
+[source-control.md](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/docs/user/source-control.md).
+
## What a surface can honestly claim
| Surface | Strongly evidenced workbench roles | Important non-equivalence |
diff --git a/src/content/book/285-device-host-architecture.mdx b/src/content/book/285-device-host-architecture.mdx
new file mode 100644
index 0000000..ef94578
--- /dev/null
+++ b/src/content/book/285-device-host-architecture.mdx
@@ -0,0 +1,152 @@
+---
+slug: device-host-architecture
+order: 435
+number: "43A"
+kind: chapter
+part: Part VI · The work lifecycle
+partOrder: 6
+title: Device hosts, targets, sessions, and agent control
+shortTitle: Device architecture
+summary: The runtime architecture behind local and SSH simulator hosts, host-scoped targets, concurrent thread sessions, proxied video, user controls, and optional agent tools.
+status: source-checked
+gates: [sources, links, interaction, editorial]
+objectives:
+ - Distinguish a device host, target, hub process, and thread session.
+ - Trace discovery, video, control, and agent-tool traffic through the server.
+ - Reason about concurrency, disconnects, and security boundaries.
+keywords: [device host, simulator, emulator, SSH, video proxy, MCP, agent-device]
+sourceAreas: [packages/contracts/src/device.ts, apps/server/src/device, apps/server/src/mcp/toolkits/device]
+visuals: [host-scoped device topology, recovery state machine]
+updatedAt: "2026-09-11"
+---
+
+import Callout from "../../components/Callout.astro";
+import Mermaid from "../../components/Mermaid.astro";
+
+The device system is a peer to provider orchestration, not a special kind of chat
+message. It discovers simulator targets, owns helper processes, proxies video and
+controls, associates open sessions with threads, and optionally exposes the same
+targets to an agent through a managed tool surface.
+
+## The identity ladder
+
+ LH[Local device host]
+ E --> SH[SSH device host]
+ LH --> H1[Device hub process]
+ SH --> H2[Remote hub process]
+ H1 --> I[iOS target]
+ H1 --> A[Android target]
+ H2 --> RI[Remote iOS target]
+ H2 --> RA[Remote Android target]
+ I --> S1[Thread device session]
+ A --> S2[Thread device session]
+ RI --> S3[Thread device session]
+ U[Web or desktop panel] -->|open · input · tools| E
+ G[Agent MCP / agent-device] -->|authorized commands| E
+ E -->|proxied video and state| U`} />
+
+A **device host** names the machine and connection method that can run platform
+tools. A **target** is one simulator or emulator discovered on that host. A
+**session** is T3’s thread-associated observation/control relationship with that
+target. Target IDs are meaningful only with their host; concurrent sessions must
+therefore route with both identities rather than assuming one global simulator.
+
+## Discovery and host ownership
+
+`LocalDeviceHost` launches helpers on the environment machine. `SshDeviceHost`
+resolves SSH configuration, checks the remote toolchain, installs pinned helper
+packages, owns remote processes, and reports stop or transport failures without
+silently losing ownership. The host abstraction lets DeviceService discover targets
+and manage sessions without moving SSH complexity into clients.
+
+The current `device.ts` contract still contains an outdated comment suggesting SSH
+hosts are future work. Executable `SshDeviceHost` code, settings schemas, tests, and
+the shipped user guide establish current behavior. The executable service and user
+contract are authoritative for the host model described here.
+
+The streaming hub and the agent driver have separate consent and lifetime. T3
+installs pinned `expo-device-hub` only after device viewing is enabled, while
+`agent-device` remains absent and stopped until agent access is granted. The hub is
+a supervised child because its iOS path loads private native frameworks; a helper
+crash must remain outside the environment server process. SSH hosts forward both
+helper endpoints to server loopback.
+
+## One server mediates three traffic classes
+
+1. **Inventory and lifecycle** requests list hosts and targets, start a stopped
+ target, open or close a session, and select its thread association.
+2. **Observation and control** streams carry frames, screen size, focus, taps,
+ swipes, keys, platform buttons, logs, and tool state.
+3. **Agent operations** arrive through the device MCP toolkit or managed
+ `agent-device` command and pass the server’s agent-access policy before reaching
+ a host.
+
+Only the visible client tab requests live video, which reduces background work while
+the simulator itself keeps running. Remote video travels through the environment
+server. Browsers require HTTPS or localhost for WebCodecs; plain HTTP falls back to
+an iOS MJPEG stream and cannot display Android video.
+
+The two platforms do not share a wire format. iOS sends AVCC envelopes over HTTP
+and accepts input on a binary WebSocket. Android multiplexes SEMU-framed H.264 and
+JSON gestures on one WebSocket. The viewer probes decoder support because the iOS
+encoder's H.264 High 5.1 output is not accepted by every hardware decoder.
+
+## Concurrency and recovery
+
+ HostConfigured
+ HostConfigured --> Available: test and discover succeed
+ HostConfigured --> Unavailable: SSH or toolchain fails
+ Available --> SessionOpen: user or agent opens target
+ SessionOpen --> Streaming: visible client subscribes
+ Streaming --> SessionOpen: tab hidden
+ SessionOpen --> Recovering: host connection drops
+ Recovering --> SessionOpen: same host and target return
+ Recovering --> Unavailable: identity or helper cannot recover
+ SessionOpen --> Available: close observation session
+ Available --> [*]: remove host configuration`} />
+
+Several targets and thread sessions can coexist. A host disconnect does not transfer
+ownership to another machine with a similar simulator name. Recovery must re-establish
+the configured host, helper, and target identity. Removing a host closes its T3
+sessions and attempts to stop reachable helpers, but it does not power off the
+underlying simulators.
+
+## Security and product boundaries
+
+The helper hub is never a public environment endpoint. Its upstream implementations
+contain unauthenticated execution or action routes, so they bind to loopback behind
+`DeviceHubProxy`. The proxy authenticates each request, allowlists only required
+stream, configuration, screenshot, and read routes, strips short-lived WebSocket
+tickets before forwarding, and prevents compression from buffering an endless
+MJPEG body. Device settings bypass that hub: typed `device.action` RPC handlers
+execute specific platform commands through the selected `DeviceHost`.
+
+Device settings are environment-scoped because SSH keys, aliases, platform tools,
+and simulator processes live on particular machines. Agent access is an explicit
+integration setting and affects newly started provider sessions; opening the user
+panel does not automatically grant agent tools. The simulator’s app network is also
+outside T3’s control: a remote simulator cannot reach a development server bound only
+to the environment’s loopback address.
+
+Provider process environments are fixed when their sessions spawn. Enabling agent
+device access starts the helper for eligible sessions, but an already running agent
+must restart before the managed CLI and its environment become available. Detailed
+driving instructions arrive from `device_open`, keeping them aligned with the pinned
+CLI without loading them into every conversation.
+
+
+ “No device” can mean the host is unreachable, the platform toolchain cannot list
+ targets, or the selected target exists but its video transport is unavailable.
+ Diagnose in that order: host, inventory, then session/stream. Recreating a thread
+ cannot repair an SSH key or an Android SDK installation.
+
+
+### Current source trail
+
+- [Device contract](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/packages/contracts/src/device.ts)
+- [Device service](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/apps/server/src/device/DeviceService.ts)
+- [SSH host implementation](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/apps/server/src/device/SshDeviceHost.ts)
+- [Agent device toolkit](https://github.com/pingdotgg/t3code/tree/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/apps/server/src/mcp/toolkits/device)
diff --git a/src/content/book/290-shared-client-runtime.mdx b/src/content/book/290-shared-client-runtime.mdx
index 717e907..0a39713 100644
--- a/src/content/book/290-shared-client-runtime.mdx
+++ b/src/content/book/290-shared-client-runtime.mdx
@@ -1,10 +1,10 @@
---
slug: shared-client-runtime
-order: 290
-number: "29"
+order: 440
+number: "44"
kind: chapter
-part: "Part VI · Client architectures: shared semantics, platform edges"
-partOrder: 6
+part: "Part VII · Client architectures: shared semantics, platform edges"
+partOrder: 7
title: "Shared runtime: connections, state, and convergence"
shortTitle: Shared client runtime
summary: "packages/client-runtime makes web and mobile agree about environment selection, one-attempt RPC sessions, reconnect supervision, and snapshot-plus-cursor convergence. Its most consequential work is rejecting stale history rather than merely rendering new data."
@@ -18,7 +18,7 @@ objectives:
keywords: [client-runtime, environment, websocket, RPC, Effect Atom, snapshot, cursor, reconnect, retry, pagination, revert, cache]
sourceAreas: [packages/client-runtime/src/connection, packages/client-runtime/src/rpc, packages/client-runtime/src/state, packages/contracts/src/orchestration.ts, apps/server/src/ws.ts]
visuals: [shared-runtime convergence map, client convergence lab]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -104,7 +104,7 @@ The seemingly strict “no retry” setting is a division of responsibility. The
supervisor owns intent (`connect`/`disconnect`), network status, session generation,
last failure, and the visible phases `available`, `offline`, `connecting`,
`backoff`, `connected`, and `blocked`. It reports preparation, opening, and
-synchronization separately. Transient failures retry on the pinned 3/4/8/16-second
+synchronization separately. Transient failures retry on a 3/4/8/16-second
ladder; blocked errors wait for an external signal rather than spinning. A stable
connection for at least 30 seconds resets retry state. A manual retry resets it;
a foreground probe can replace a stale mobile lease and make the immediate first
@@ -165,7 +165,7 @@ emits the buffered tail. A completion marker, when the server advertises support
means the buffered work before that marker has been delivered; it is not a claim
that future domain events have stopped.
-
+ R[Resolver]
R --> P[Prepared connection]
@@ -265,6 +265,24 @@ lets web and mobile differ at the platform edge while sharing the same answer to
the expensive correctness questions: what may be cached, what may be resumed, and
what must be thrown away.
+## Shared settings and environment selection
+
+Multi-environment clients reconcile settings that should follow the user separately
+from settings that name machine-local paths, credentials, hosts, or binaries. Shared
+patches carry version information and expose mismatches rather than overwriting an
+environment that cannot interpret them. Project defaults can therefore converge while
+worktree roots and provider executables remain local.
+
+When several connected environments can start the same project, the runtime may use
+weighted load balancing for a new thread. That decision selects an authority before
+work begins; it does not merge repositories or provider sessions after the fact.
+
+Attachments, media references, terminal output, device state, linked pull requests,
+pending requests, and usage limits also live in shared runtime modules so web and
+mobile apply the same identity and merge rules. See
+[sharedSettings.ts](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/packages/client-runtime/src/state/sharedSettings.ts) and
+[load-balancing.ts](https://github.com/pingdotgg/t3code/blob/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/packages/client-runtime/src/load-balancing.ts).
+
+ S[apps/server]
C --> R[packages/client-runtime]
diff --git a/src/content/book/300-web-runtime.mdx b/src/content/book/300-web-runtime.mdx
index 9a5d8b6..ec124e9 100644
--- a/src/content/book/300-web-runtime.mdx
+++ b/src/content/book/300-web-runtime.mdx
@@ -1,10 +1,10 @@
---
slug: web-runtime
-order: 300
-number: "30"
+order: 450
+number: "45"
kind: chapter
-part: "Part VI · Client architectures: shared semantics, platform edges"
-partOrder: 6
+part: "Part VII · Client architectures: shared semantics, platform edges"
+partOrder: 7
title: One React renderer, three runtime edges
shortTitle: Web runtime
summary: "The web client keeps one route tree and environment-oriented state model across hosted, locally served, and Electron renderer deployments. Platform differences enter at history, authentication, native-host, and transport boundaries—not in a forked product model."
@@ -18,7 +18,7 @@ objectives:
keywords: [web, Electron, history, router, environment, atoms, virtualization, tracing, terminal, performance]
sourceAreas: [apps/web/src/main.tsx, apps/web/src/AppRoot.tsx, apps/web/src/router.ts, apps/web/src/connection, apps/web/src/components/chat, apps/web/src/components/ThreadTerminalDrawer.tsx]
visuals: [web runtime architecture and hot path]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -118,7 +118,7 @@ reconnecting, and a client can hold several environment presentations at once.
The route tells the UI *which* scoped thread to request; the registry and
environment atoms answer *through which prepared connection* it can be reached.
-
+ BH[browser history]
E[Electron file shell] --> HH[hash history]
@@ -183,7 +183,7 @@ addressed by environment, thread, terminal id, cwd, optional worktree, and runti
environment. User input becomes a typed write command; resize becomes a typed
resize command; the renderer hydrates the terminal surface from the attached
session's buffered text and status. The client owns the screen component and local
-focus/selection behavior. The environment server owns the PTY, as Chapter 28
+focus/selection behavior. The environment server owns the PTY, as Chapter 43
establishes.
diff --git a/src/content/book/310-web-product-surfaces.mdx b/src/content/book/310-web-product-surfaces.mdx
index a9bda49..466fa90 100644
--- a/src/content/book/310-web-product-surfaces.mdx
+++ b/src/content/book/310-web-product-surfaces.mdx
@@ -1,10 +1,10 @@
---
slug: web-product-surfaces
-order: 310
-number: "31"
+order: 460
+number: "46"
kind: chapter
-part: "Part VI · Client architectures: shared semantics, platform edges"
-partOrder: 6
+part: "Part VII · Client architectures: shared semantics, platform edges"
+partOrder: 7
title: One thread, many deliberate projections
shortTitle: Web product surfaces
summary: "The composer, timeline, Agents panel, review panel, and sidebar do not own competing thread records. They select and project one canonical environment-scoped thread through different interaction contracts, including optimistic local affordances that must yield to canonical state."
@@ -18,7 +18,7 @@ objectives:
keywords: [composer, attachment, command, skill, optimistic UI, Agents, work log, review, sidebar, pinning, projection]
sourceAreas: [apps/web/src/components/chat, apps/web/src/components/AgentsPanel.tsx, apps/web/src/components/DiffPanel.tsx, apps/web/src/components/Sidebar.tsx, packages/client-runtime/src/state]
visuals: [interactive thread projection lab]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -58,7 +58,7 @@ model and modes on the thread. The server's normalizer then owns timestamp,
workspace, and attachment normalization before dispatch. A successful dispatch
result names the accepted command/sequence boundary; it is stronger than a local
button state, but later provider work still crosses the post-commit reactor seam
-described in Chapters 10–12 and 23.
+described in Chapters 25–27 and 38.
The web persists chosen mode/model before sending a turn; normalization and
@@ -173,7 +173,7 @@ the displayed pin, task, review, and local-view fields to see why a quiet timeli
and a detailed Agents panel can honestly look different without holding different
canonical threads.
-
+
diff --git a/src/content/book/320-desktop-electron.mdx b/src/content/book/320-desktop-electron.mdx
index d40bc15..4048968 100644
--- a/src/content/book/320-desktop-electron.mdx
+++ b/src/content/book/320-desktop-electron.mdx
@@ -1,10 +1,10 @@
---
slug: desktop-electron
-order: 320
-number: "32"
+order: 470
+number: "47"
kind: chapter
-part: "Part VI · Client architectures: shared semantics, platform edges"
-partOrder: 6
+part: "Part VII · Client architectures: shared semantics, platform edges"
+partOrder: 7
title: "Electron desktop: one renderer, explicit native authority"
shortTitle: Electron desktop
summary: "The desktop reuses the web renderer but not browser authority: Electron main assembles effects, supervises local backend children, exposes a narrow preload bridge, and separately brokers WSL, SSH, previews, menus, updates, telemetry, and shutdown."
@@ -18,7 +18,7 @@ objectives:
keywords: [electron, desktop, preload, backend pool, WSL, SSH, telemetry, preview, shutdown]
sourceAreas: [apps/desktop/src/main.ts, apps/desktop/src/app, apps/desktop/src/backend, apps/desktop/src/wsl, apps/desktop/src/ssh, apps/desktop/src/preload.ts, apps/desktop/src/preview]
visuals: [desktop process topology, interactive boot readiness shutdown lab]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -94,7 +94,7 @@ so a slow `wsl.exe` cold start does not block the primary readiness path.
-
+|curated preload IPC| M[Electron main]
M -->|protocol + window + menu + updates| R
diff --git a/src/content/book/330-mobile-client.mdx b/src/content/book/330-mobile-client.mdx
index f219337..770a7e9 100644
--- a/src/content/book/330-mobile-client.mdx
+++ b/src/content/book/330-mobile-client.mdx
@@ -1,13 +1,13 @@
---
slug: mobile-client-continuity
-order: 330
-number: "33"
+order: 480
+number: "48"
kind: chapter
-part: "Part VI · Client architectures: shared semantics, platform edges"
-partOrder: 6
-title: "Mobile: persistence, outbox, sharing, and native systems"
+part: "Part VII · Client architectures: shared semantics, platform edges"
+partOrder: 7
+title: "Mobile: adaptive workspaces, persistence, and native systems"
shortTitle: Mobile continuity
-summary: "The Expo client reuses T3 Code's connection and projection semantics but owns a deliberately mobile durability layer: cached snapshots in SQLite, credentials in secure storage, drafts and commands in atomic files, a transactional share inbox, native rendering bridges, and an OTA restart gate that yields to unsaved work."
+summary: "The Expo client reuses T3 Code's connection and projection semantics while adding adaptive navigation, native review and terminal surfaces, voice input, cached snapshots in SQLite, secure credentials, durable drafts and commands, transactional sharing, notifications, and a guarded OTA restart path."
status: source-checked
gates: [sources, interaction]
objectives:
@@ -18,7 +18,7 @@ objectives:
keywords: [mobile, Expo, React Native, connection runtime, SQLite, SecureStore, drafts, outbox, sharing, native terminal, native diff, Live Activity, OTA]
sourceAreas: [apps/mobile/app.config.ts, apps/mobile/src/App.tsx, apps/mobile/src/Stack.tsx, apps/mobile/src/connection, apps/mobile/src/persistence, apps/mobile/src/state, apps/mobile/src/features/sharing, apps/mobile/src/features/updates, apps/mobile/modules]
visuals: [mobile ownership graph, offline and OTA continuity simulator, native capability matrix]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -60,7 +60,7 @@ and share-extension lifecycle URLs: the latter is deliberately ignored because t
-The connection runtime is not a mobile rewrite of Chapter 29. It merges the shared
+The connection runtime is not a mobile rewrite of Chapter 44. It merges the shared
`Connection.layer` and shared shell/thread snapshot loaders with mobile platform
services:
@@ -78,10 +78,10 @@ services:
The platform supplies no SSH gateway. Its `SshEnvironmentGateway` operations fail
with an explicit “desktop only” blocked error. Mobile can connect through supported
direct/bearer or relay targets, but it does not provision a remote CLI over SSH and
-does not spawn a local provider. Chapter 34 returns to the access transports;
-Chapter 35 follows relay authentication and tunneling.
+does not spawn a local provider. Chapter 49 returns to the access transports;
+Chapter 50 follows relay authentication and tunneling.
-
+
-## 8. The design lesson is selective durability
+## 8. Adaptive navigation and native work surfaces
+
+The phone layout prioritizes one route at a time; the tablet layout can keep a thread
+beside files, review, terminal, or other detail surfaces. Those panes are navigation
+state, not duplicated thread authority. Native diff highlighting, file-tree search,
+image/video/PDF/web previews, and the Ghostty-backed terminal let mobile inspect the
+same work with platform-specific rendering.
+
+New-task drafts can coexist per project and remain local until submitted. Attachments
+have durable local copies and join the outbox only after their upload prerequisites
+are satisfied. iOS voice input performs on-device transcription before the text enters
+the composer under the revision guard above. Android ongoing notifications and iOS Live Activities expose work state,
+while opening the app still reconciles the authoritative environment snapshot.
+
+Appearance follows platform capabilities: Android can use Material You and wallpaper
+colors, while both platforms share semantic theme choices and readable terminal
+palettes. These native features are organized under the current
+[mobile feature tree](https://github.com/pingdotgg/t3code/tree/859304b7808ab9a4be87b1bddcd07c6485bf9c4f/apps/mobile/src/features).
+
+## 9. The design lesson is selective durability
T3 Code does not place every mobile value in one “offline database.” It gives each
kind of state the smallest recovery contract it needs:
diff --git a/src/content/book/340-access-transports.mdx b/src/content/book/340-access-transports.mdx
index 0cca9e2..6d328ca 100644
--- a/src/content/book/340-access-transports.mdx
+++ b/src/content/book/340-access-transports.mdx
@@ -1,10 +1,10 @@
---
slug: access-transports
-order: 340
-number: "34"
+order: 490
+number: "49"
kind: chapter
-part: "Part VII · Reach and ship"
-partOrder: 7
+part: "Part VIII · Reach and ship"
+partOrder: 8
title: "Reachability is a route; authority is a separate proof"
shortTitle: Access transports
summary: "A T3 Code environment can be host-local, paired through an endpoint, provisioned through a Tailnet, or reached through the desktop SSH gateway. These paths differ in how they launch and expose a server, but every usable route still has to establish an endpoint, enroll a client, and preserve the server's authority boundary."
@@ -18,7 +18,7 @@ objectives:
keywords: [remote access, primary, bearer, pairing, Tailscale, Tailnet, SSH, endpoint, exposure, trust boundary]
sourceAreas: [apps/server/src/auth, packages/client-runtime/src/connection, apps/desktop/src/backend, apps/desktop/src/ssh, packages/tailscale/src, packages/ssh/src]
visuals: [access transport route map, interactive access transport lab]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import AccessTransportLab from "../../components/AccessTransportLab.astro";
@@ -40,8 +40,8 @@ arrow in the picture. This chapter uses two narrower terms:
Neither word is authorization. A route merely lets a client reach an environment
that can evaluate its credential and scopes. The durable server, filesystem,
provider processes, and work state stay on the environment side of that boundary.
-For credential exchange, ticketing, and per-method scopes, see [Chapter 8](../auth-pairing/); for the shared resolver, supervisor, and RPC
-session after a route is prepared, see [Chapter 29](../shared-client-runtime/).
+For credential exchange, ticketing, and per-method scopes, see [Chapter 23](../auth-pairing/); for the shared resolver, supervisor, and RPC
+session after a route is prepared, see [Chapter 44](../shared-client-runtime/).
Tailscale can make one or more endpoints available—a Tailnet IP or a MagicDNS
@@ -59,6 +59,13 @@ id and obtain the associated profile through the catalog; Relay has its own
managed-bootstrap path. This is a model of *how a client prepares a connection*,
not a taxonomy of every network that may carry the bytes.
+The environment identity remains stable across route changes. Its initialization
+publishes a complete identifier atomically and retains a recovery candidate when it
+repairs an empty identity file, so concurrent initializers converge on the same
+winner. Advertised endpoints are only reachability hints: the connecting device
+must prove one works, and endpoint selection must not substitute host loopback when
+the requested shareable route is unavailable.
+
That distinction resolves a common false equivalence. A desktop app launching its
own host-local backend has a launch path, but a paired phone or browser never needs
to replay that launch. It needs an advertised endpoint and an enrollment credential.
@@ -73,7 +80,7 @@ itself.
advertises endpoints rather than representing a client target.
-
+|launch| E[Environment server\nfiles · providers · durable state]
P -->|loopback HTTP / WS| E
@@ -99,7 +106,7 @@ The important restraint is what this does **not** imply. A broad bind is a large
set of machines able to attempt a connection; it is not a grant of orchestration,
terminal, or review authority. Likewise, a loopback bind is a route constraint,
not a substitute for the desktop main/preload boundary described in
-[Chapter 32](../desktop-electron/). Bind deliberately, then make the client prove
+[Chapter 47](../desktop-electron/). Bind deliberately, then make the client prove
its entitlement at the environment.
@@ -128,9 +135,16 @@ random URL plus a token pasted into unrelated settings. Later edits refuse to
continue if the saved target, profile, or credential no longer forms that bearer
shape.
+The hosted web app remains a direct client, with its connection catalog in browser
+storage. A hosted pairing URL puts the environment address in its query and the
+pairing secret in its fragment, exchanges that secret with the environment, then
+removes it from browser history. The hosted origin never receives the fragment.
+Serving the UI over HTTPS also cannot make a plain-HTTP LAN environment reachable
+from that browser context.
+
This chapter stops at the trust-boundary consequence. It does not restate the token
exchange, browser-session, DPoP, WebSocket-ticket, or RPC-scope machinery from
-Chapter 8. The operational point here is simpler: **an endpoint makes enrollment
+Chapter 23. The operational point here is simpler: **an endpoint makes enrollment
possible; enrollment makes a saved access route usable; neither transfers
environment ownership to the client.**
@@ -161,7 +175,7 @@ discovery an invisible background prerequisite for ordinary local use.
Once a user selects a reachable Tailnet endpoint and pairs, the client has not
become a “Tailscale connection.” It has a Bearer target whose profile points at a
Tailnet address. That is why the resolver, retry policy, cache ownership, and
-session readiness remain the shared-runtime concerns of Chapter 29, regardless of
+session readiness remain the shared-runtime concerns of Chapter 44, regardless of
whether the bytes cross Wi-Fi, a Tailnet, or another HTTPS route.
@@ -189,9 +203,14 @@ refreshes the SSH bootstrap path before remote authorization continues.
The consequence is deliberately asymmetric: the desktop owns the SSH process and
tunnel lifetime; the renderer sees a ready environment route; the remote machine
still owns the server process, projects, files, git, terminals, and provider
-sessions. That complements Chapter 32's process map rather than turning SSH into
+sessions. That complements Chapter 47's process map rather than turning SSH into
another desktop-local backend pool member.
+Cleanup follows process ownership. Disconnecting stops a remote server only when
+the SSH launcher created and owns it; a server discovered already running survives
+the client tunnel. Reconnection restores the forward before the shared runtime opens
+its HTTP/WebSocket session.
+
The desktop service delegates to an SSH environment manager. The manager reserves
a local port, forwards it to remote loopback, waits for HTTP readiness, and
@@ -218,7 +237,7 @@ The resulting checklist is short:
4. Does the saved target describe the route honestly—Primary, Bearer, Relay, or
SSH—without mistaking Tailscale or an SSH forward for a new authority model?
-If all four answers are sound, Chapter 29 can supervise a normal prepared
+If all four answers are sound, Chapter 44 can supervise a normal prepared
connection. If any answer is missing, a live socket would only conceal a
reachability or trust-boundary defect until the next device, network, or restart.
diff --git a/src/content/book/350-t3-connect.mdx b/src/content/book/350-t3-connect.mdx
index 27be0df..ea1c01f 100644
--- a/src/content/book/350-t3-connect.mdx
+++ b/src/content/book/350-t3-connect.mdx
@@ -1,10 +1,10 @@
---
slug: t3-connect
-order: 350
-number: "35"
+order: 500
+number: "50"
kind: chapter
-part: "Part VII · Reach and ship"
-partOrder: 7
+part: "Part VIII · Reach and ship"
+partOrder: 8
title: "T3 Connect: OAuth, DPoP, relay, and tunnel"
shortTitle: T3 Connect
summary: "T3 Connect uses a Clerk account credential and a device-held DPoP key to authorize relay control-plane operations, links a local environment through a signed proof, provisions a Cloudflare tunnel, then gives the client a direct DPoP-bound connection to that environment. The relay authorizes, provisions, and brokers setup; normal T3 traffic does not transit it."
@@ -18,7 +18,7 @@ objectives:
keywords: [T3 Connect, Clerk, OAuth, PKCE, DPoP, relay, Cloudflare Tunnel, cloudflared, environment registration, WebSocket]
sourceAreas: [docs/internals/t3-connect.md, packages/shared/src/connectAuth.ts, apps/server/src/cloud/CliTokenManager.ts, apps/web/src/cloud/dpop.ts, packages/client-runtime/src/relay/managedRelay.ts, packages/client-runtime/src/authorization/service.ts, infra/relay/src/environments]
visuals: [credential ladder, relay control-plane and direct data-plane map]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -103,7 +103,7 @@ managed connector. `--publish-only` deliberately takes a different path: it link
activity publishing but asks for no managed tunnel, so a client must reach the
environment out of band.
-
+
@@ -115,13 +115,18 @@ HTTP origin, creates a proxied CNAME to `*.cfargotunnel.com`, obtains a connecto
token, and marks the allocation ready. The environment runtime launches the managed
client as `tunnel run` with that token and supervises it.
+Managed exposure accepts only a validated loopback HTTP origin. Link proof checks
+reject forwarded authority headers, allocation lookup uses relay-owned records, and
+health and mint requests do not follow redirects. Those constraints prevent endpoint
+setup from becoming arbitrary relay egress or exposing another host-local service.
+
That is an endpoint-exposure path: client traffic can travel through the managed
Cloudflare tunnel to the environment. It is not a relay data hop. The relay’s own
README says that normal API and WebSocket traffic goes directly between client and
selected environment after connection; the client runtime independently constructs
the environment’s token and WebSocket-ticket requests from the endpoint URL.
-
+
-## 6. Evidence boundary: what this pinned source does and does not establish
+## 6. Links, allocations, and connectors have different lifetimes
+
+Cloud authorization, desired exposure, an allocation, and a running connector do
+not begin or end together. Linking may record intent while the environment is down;
+startup reconciles that intent. A normal CLI-managed shutdown releases its active
+tunnel while retaining the hostname reservation and allocation record, so the
+environment appears offline rather than unauthorized.
+
+Two handoffs retain the tunnel: a client-installed link depends on its stored
+connector token, and an update starts a replacement environment immediately.
+Allocation cleanup claims a generation before deleting external resources so a
+delayed finalizer cannot remove a tunnel reused by a restart. Unlink commits
+authorization revocation before external teardown and retains enough state to retry
+a failed cleanup.
+
+## 7. Evidence boundary: what the implementation does and does not establish
+
+DPoP constrains credential replay, but it does not remove the relay trust
+assumption. The relay holds the signing authority for environment mint requests; a
+compromised relay signing key remains a privileged failure boundary.
The relay README specifies the intended direct post-connection API/WebSocket path,
diff --git a/src/content/book/360-reconnect-environments.mdx b/src/content/book/360-reconnect-environments.mdx
index 6129ea9..1246db8 100644
--- a/src/content/book/360-reconnect-environments.mdx
+++ b/src/content/book/360-reconnect-environments.mdx
@@ -1,10 +1,10 @@
---
slug: reconnect-environments
-order: 360
-number: "36"
+order: 510
+number: "51"
kind: chapter
-part: "Part VII · Reach and ship"
-partOrder: 7
+part: "Part VIII · Reach and ship"
+partOrder: 8
title: "Reconnect, environments, notifications, and version skew"
shortTitle: Reachability recovery
summary: "T3 Code recovers reachability one environment at a time: a registry leases a single supervisor and RPC session per environment, projections reconcile independently after a new generation, background work follows declared demand, notifications wake attention rather than synchronize state, and capability plus exact-version recovery makes skew explicit."
@@ -18,7 +18,7 @@ objectives:
keywords: [reconnect, environment, generation, lease, supervisor, cache, background, APNs, notifications, awareness relay, version skew, self-update]
sourceAreas: [packages/client-runtime/src/connection, packages/client-runtime/src/state, apps/mobile/src/connection, apps/mobile/src/features/agent-awareness, infra/relay/src/agentActivity, packages/contracts/src/environment.ts, apps/web/src/versionSkew.ts, apps/server/src/cloud]
visuals: [environment recovery boundary, reachability and notification recovery lab]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -80,10 +80,10 @@ and do not use an environment A session to repair environment B cache.
This constraint is useful even when a user has one desktop server exposed through
direct LAN, relay, and SSH-assisted routes: access and launch can differ while the
-saved environment identity decides which runtime scope owns recovery. [Chapter 34](../access-transports/)
+saved environment identity decides which runtime scope owns recovery. [Chapter 49](../access-transports/)
separates access from authority; this chapter follows the recovery consequence.
-
+ A[Environment A scope]
C --> B[Environment B scope]
@@ -166,8 +166,8 @@ The safe recovery order is therefore:
No step says “replay every command because the connection returned.” Commands
resolve their current environment runtime at execution time. Durable command and
-outbox semantics belong to [Chapter 24](../permissions-and-input/) and
-[Chapter 33](../mobile-client-continuity/); reconnect supplies reachability, not
+outbox semantics belong to [Chapter 39](../permissions-and-input/) and
+[Chapter 48](../mobile-client-continuity/); reconnect supplies reachability, not
permission to duplicate intent.
## 4. Background work has demand and policy, not a hidden always-on connection
@@ -266,7 +266,19 @@ Do not make the transport layer a process manager merely to disguise that restar
substitute for re-synchronizing after a server restart.
-## 7. The compact rule set
+## 7. Host-scoped and queued recovery
+
+Device sessions add a nested recovery problem: the client must reconnect to the T3
+environment, then DeviceService must reconnect to the configured local or SSH host,
+then the target and session identities must still match. A simulator with the same
+display name on another host is not a valid substitute.
+
+Mobile drafts, pending thread creation, attachment uploads, and notification launches
+can also outlive one connection attempt. Their local records wait for the environment
+and then reconcile against server evidence. Shared-setting mismatch is handled in a
+separate versioned channel so reconnect does not silently copy machine-local config.
+
+## 8. The compact rule set
Keep these rules together when extending any client surface:
diff --git a/src/content/book/370-distribution-artifacts.mdx b/src/content/book/370-distribution-artifacts.mdx
index 4d9f9fd..14f95df 100644
--- a/src/content/book/370-distribution-artifacts.mdx
+++ b/src/content/book/370-distribution-artifacts.mdx
@@ -1,10 +1,10 @@
---
slug: distribution-artifacts
-order: 370
-number: "37"
+order: 520
+number: "52"
kind: chapter
-part: "Part VII · Reach and ship"
-partOrder: 7
+part: "Part VIII · Reach and ship"
+partOrder: 8
title: "Distribution: artifacts, channels, and what actually ships"
shortTitle: Distribution artifacts
summary: "T3 Code distributes several deliberately different products: an npm CLI that contains a bundled web client, platform-specific Electron installers built from a staged closure, a release-controlled hosted web channel, store binaries plus fingerprint-gated mobile OTAs, and checksum-pinned AUR packages derived from the published Linux AppImage. The release matrix—not every target the builder knows—defines what is actually shipped."
@@ -19,7 +19,7 @@ objectives:
keywords: [distribution, npm, CLI, Electron, DMG, AppImage, NSIS, GitHub Releases, Vercel, Expo, EAS, fingerprint, AUR, stable, nightly]
sourceAreas: [apps/server/package.json, apps/server/scripts/cli.ts, scripts/build-desktop-artifact.ts, .github/workflows/release.yml, .github/workflows/mobile-eas-production.yml, apps/web/vercel.ts, apps/marketing/src, packaging/aur]
visuals: [distribution artifact map, interactive artifact factory]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import ArtifactFactoryLab from "../../components/ArtifactFactoryLab.astro";
@@ -63,7 +63,7 @@ GitHub Release. A successful GitHub Release then unlocks the AUR handoff and hos
web deploy. This is dependency ordering, not an assertion that all downstream
consumer updates happen simultaneously.
-
+ WEB[Web build]
REF --> SERVER[Server / CLI bundle]
diff --git a/src/content/book/380-release-updates-observability.mdx b/src/content/book/380-release-updates-observability.mdx
index 76defad..2caf4c4 100644
--- a/src/content/book/380-release-updates-observability.mdx
+++ b/src/content/book/380-release-updates-observability.mdx
@@ -1,10 +1,10 @@
---
slug: release-updates-observability
-order: 380
-number: "38"
+order: 530
+number: "53"
kind: chapter
-part: "Part VII · Reach and ship"
-partOrder: 7
+part: "Part VIII · Reach and ship"
+partOrder: 8
title: "Release, update, and observability: three safety boundaries"
shortTitle: Release operations
summary: "T3 Code's release graph publishes an exact CLI runtime before clients can require it. Desktop, service, and mobile each cross an update boundary differently, while analytics and diagnostics distinguish opt-out product telemetry from local traces, optional OTLP export, authenticated browser ingestion, and demand-driven native resource history."
@@ -18,7 +18,7 @@ objectives:
keywords: [release, nightly, npm, GitHub Releases, exact version, electron-updater, service launcher, SQLite snapshot, Expo Updates, fingerprint, PostHog, OTLP, resource telemetry, privacy]
sourceAreas: [.github/workflows/release.yml, docs/operations/release.md, docs/internals/server-updates.md, apps/desktop/src/updates, apps/server/src/cloud, apps/server/src/telemetry, apps/server/src/observability, apps/server/src/resourceTelemetry, apps/mobile/src/features/updates]
visuals: [release dependency graph, updater boundary comparison, release operations lab]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -65,7 +65,7 @@ operations guide therefore requires `publish_cli` before `release`, and `release
before the hosted web deployment. This prevents a newly visible client from issuing
an update request for a package version that cannot yet be fetched.
-
+ C
W --> C
C -->|request exact V| S
- N -->|"t3@V must already exist"| S
+ N -->|t3@V must already exist| S
R -. nightly selects prerelease\nnightly updater metadata .-> G`} />
@@ -114,6 +114,12 @@ and Windows instances—with a grace budget, destroys windows, then yields contr
the updater. That avoids relying on an application shutdown cascade after the OS
has begun quitting it.
+Updating a desktop-managed remote backend uses a separate prepare/commit token.
+Preparation returns while the connection is alive; the client commits only after it
+has received that token, then verifies the prepared version after reconnecting. If
+installation fails, desktop restarts the stopped backends and retains the failure
+for that same token.
+
### 2. Boot-service server: stage, preflight, trial, then have the launcher commit
@@ -153,6 +159,13 @@ old blocks a target that needs this safety path. After a commit, ordinary servic
manager restart policy applies; there is no promise of a second automatic rollback
for every later runtime failure.
+An accepted update remains pending from the client's perspective. After reconnect,
+the client correlates the launcher's update ID with the ready environment, then
+checks both outcome and target version; reconnect alone cannot distinguish commit
+from rollback. Servers without update-ID support retain version-only correlation.
+Foreground CLI processes do not self-update. Chapter 28 owns the restore-marker and
+filesystem-sync details of the launcher's recovery journal.
+
### 3. Mobile: OTA eligibility is native compatibility plus a safe teardown moment
Mobile's Expo Updates configuration uses a fingerprint runtime version. Inference:
@@ -176,7 +189,7 @@ update application is a separate immediate path.
decision boundary when one is downloaded.
-
+ DA[Update available]
@@ -207,6 +220,12 @@ are sent in batches only when delivery is enabled; the payload explicitly disabl
PostHog person profiles. The service supplies platform, architecture, client type,
and T3 Code version alongside the event properties.
+Client attribution comes from the WebSocket that produced the event. `clientType`
+describes how the server is hosted; `surface` describes the connected web, desktop,
+or mobile client. Missing metadata from an earlier client remains unknown. A
+server-global “current client” would misattribute simultaneous surfaces, especially
+when a desktop-hosted environment serves a phone or remote browser.
+
@@ -218,6 +237,13 @@ returning it. That reduces direct identifier exposure to the analytics service;
does **not** mean all event properties are automatically anonymous, so the payload
schema remains an operational privacy boundary.
+Active-use reporting should use `client.turn.requested`; `client.connected` counts
+reconnections and is therefore sensitive to network behavior. Provider send and
+completion totals need not match, and cost comparisons require complete usage with
+no observed subagents or mixed-model routing plus matching model, effort,
+interaction mode, and terminal status. Partial counts remain useful observations,
+but they cannot establish a complete turn total.
+
Tracing has a different default. The server creates a bounded local file trace sink
@@ -239,13 +265,21 @@ deliberately independent delivery lanes.
Finally, native resource telemetry is diagnostics-oriented rather than an event
-archive. Its native sidecar keeps a one-hour **in-memory**, bounded ring. Periodic
-streaming is off until a diagnostics subscription is retained; explicit refresh
-still works. The model samples counters and process trees, so processes that begin
-and end between samples may not be seen. It is explicitly not syscall, eBPF, ETW,
-or endpoint-security tracing.
-
-
+archive. A standalone Rust child owns a bounded in-memory history; collector failure
+does not stop the server, and there is no recurring shell-probe fallback. Age,
+snapshot count, process rows, and retained bytes are independent limits, so a large
+process tree shortens the available history. Periodic streaming is off until a
+diagnostics subscription is retained; explicit refresh still works.
+
+The model samples counters and process trees, so processes that begin and end
+between samples may not be seen. PID identity includes process start time, and
+snapshot sequence numbers reset with the monitor generation. Historical replay
+must not be overwritten with current Electron metrics. Windows packages do not
+currently provide the Linux monitor needed inside a WSL backend, although the
+inherited Electron power feed remains available. These are sampled diagnostics,
+not syscall, eBPF, ETW, or endpoint-security tracing.
+
+
This is an inference from the independently configured paths: product analytics
diff --git a/src/content/book/390-six-complete-traces.mdx b/src/content/book/390-six-complete-traces.mdx
deleted file mode 100644
index 3f3fc37..0000000
--- a/src/content/book/390-six-complete-traces.mdx
+++ /dev/null
@@ -1,355 +0,0 @@
----
-slug: six-complete-traces
-order: 390
-number: "39"
-kind: chapter
-part: "Part VIII · Synthesis"
-partOrder: 8
-title: "Six complete traces: ownership, convergence, and failure boundaries"
-shortTitle: Six complete traces
-summary: "Six source-grounded paths connect the book's modules end to end: a local turn, a T3 Connect mobile turn, an approval, an offline outbox drain, a checkpoint diff and revert, and an exact-version service update. Each trace names the owner of every handoff and the point where the observed implementation stops promising convergence."
-status: source-checked
-gates: [sources, interaction, links]
-objectives:
- - Trace six representative operations across client, relay, domain, side-effect, and projection boundaries.
- - Distinguish a durable fact from a best-effort handoff, a cached intention, and a completed external effect.
- - Reuse the owning chapters without flattening their separate authorization, recovery, and update protocols into one story.
- - Identify the exact failure boundary for each trace before treating a local design choice as a general guarantee.
-keywords: [synthesis, trace, orchestration, T3 Connect, mobile outbox, approval, checkpoint, revert, exact-version update, convergence]
-sourceAreas: [apps/server/src/orchestration, apps/server/src/provider, packages/client-runtime/src, apps/mobile/src/state, infra/relay/src/environments, apps/server/src/checkpointing, apps/server/src/vcs, apps/server/src/cloud, apps/server/src/serviceLauncher.ts, .github/workflows/release.yml, docs/operations/release.md]
-visuals: [synchronized trace swimlanes, six-trace stepper]
-updatedAt: 2026-08-24
----
-
-import Callout from "../../components/Callout.astro";
-import EvidenceClaim from "../../components/EvidenceClaim.astro";
-import Figure from "../../components/Figure.astro";
-import Mermaid from "../../components/Mermaid.astro";
-import SourceExcerpt from "../../components/SourceExcerpt.astro";
-import SourceList from "../../components/SourceList.astro";
-import SynchronizedTraceLab from "../../components/SynchronizedTraceLab.astro";
-
-This chapter is a synthesis, not a new seventh protocol. It puts already-audited
-pieces on one time axis so that the ownership changes are visible: a device can
-record intent, a relay can authorize connection setup, an environment can commit a
-fact, and a provider, Git driver, or stable launcher can perform a later effect.
-Those verbs are deliberately not interchangeable.
-
-The six traces are chosen because they exercise different seams. They do **not**
-combine into a global exactly-once guarantee. In particular, a server command may
-commit before a hot reactor observes it; a phone file and a server database have no
-shared transaction; a checkpoint revert can mutate files before provider rollback;
-and a prepared service runtime is not committed until its independent launcher says
-so.
-
-
- Read a trace straight through once, then use its linked prerequisite chapter for
- the local state machine. The swimlanes deliberately collapse detail; each arrow
- means an observed handoff, not an assertion that all arrows are durable, ordered,
- or retryable in the same way.
-
-
-## The common reading key: trigger, owner, durable fact, convergence boundary
-
-Every trace below has four questions:
-
-1. **What triggered work?** A user action, provider callback, queued file, or
- release workflow begins the path.
-2. **Which owner may act next?** An owner can pass an intent or fact onward, but
- does not automatically own the recipient's state machine.
-3. **What became durable, where?** A committed orchestration event, mobile outbox
- file, hidden Git ref, or launcher state has a scope. It is not universal proof.
-4. **What converges—or stops?** Snapshots and subscriptions converge client views;
- some other paths terminate at an honest failure activity, retry policy, or manual
- recovery boundary.
-
-
- >E: authorized turn command
- E->>D: commit event + projection + receipt
- E-->>W: hot provider intent
- W-->>E: runtime facts
- E->>D: commit projected result
- E-->>C: snapshot / resumed events
- end
- rect rgb(247, 242, 255)
- Note over C,W: 2 · relay-connected mobile turn
- C->>R: DPoP-bound connect authorization
- R->>E: short-lived bootstrap mint request
- E-->>R: proof-bound bootstrap credential
- R-->>C: endpoint + bootstrap credential
- C->>E: direct bootstrap exchange + WebSocket ticket
- C->>E: mobile turn through direct session
- E-->>C: environment snapshot / stream
- end
- rect rgb(255, 248, 234)
- Note over C,W: 3 · approval round-trip
- W-->>E: native approval request
- E->>D: project pending activity
- E-->>C: synchronized pending request
- C->>E: response command
- E->>D: response-requested event
- E-->>W: hot provider response
- W-->>E: native resolution or stale-request failure
- E->>D: later resolution / failure activity
- end
- rect rgb(239, 251, 241)
- Note over C,W: 4 · offline mobile outbox drain
- C->>D: atomic queued intent confirmation
- C->>E: after connection + live-shell evidence
- E->>D: accepted command receipt
- E-->>C: accepted command result
- C->>D: remove delivered local item
- E-->>C: later snapshot / stream reconciliation
- end
- rect rgb(255, 241, 241)
- Note over C,W: 5 · checkpoint diff / revert
- E-->>W: completion triggers capture
- W->>D: hidden Git ref + patch result
- E->>D: checkpoint metadata
- C->>E: revert request
- E->>D: durable revert request acceptance
- E-->>W: ordered restore + provider rollback
- W-->>E: restore / rollback outcomes
- E->>D: durable completion only after effects
- end
- rect rgb(241, 246, 250)
- Note over A,W: 6 · stable exact-version update
- A->>D: publish exact t3@V
- A->>C: expose compatible client artifact
- C->>E: request server target V
- E->>W: preflight then launcher handoff
- W->>D: snapshot, trial, commit or rollback
- W-->>E: candidate ready / rollback outcome
- E-->>C: reconnect / recovery signal
- end`} />
-
-
-## Trace 1 — local first turn: commit intent before provider work
-
-An existing-thread turn begins in a local, web, desktop, or mobile renderer. The
-client sends the typed command through an authenticated RPC method; the server
-normalizes the external input, serializes a decision through its command queue, and
-commits the emitted event, read-model work, and accepted receipt in one SQLite
-transaction. That transaction is the durable acceptance boundary.
-
-Only after that commit does `ProviderCommandReactor` observe the committed intent
-and ask `ProviderService` to establish or continue the provider session and send the
-turn. The provider adapter maps native notifications to the canonical runtime union.
-Runtime ingestion turns those facts back into internal commands, whose resulting
-projections flow to a client through an HTTP snapshot and resumable subscription.
-The detailed command-to-checkpoint path belongs to [Chapter 4](../request-trace/),
-with the lifecycle guards expanded in [Chapter 23](../turn-lifecycle/).
-
-
-
-The decisive limitation is after the commit: the reactor consumes a hot stream, not
-a durable outbox. A crash in the narrow window after the transaction but before the
-provider reactor handles the event does not automatically replay a missing send on
-restart. Retrying the same command finds the accepted receipt and does not create a
-new event. This is intentionally safer than duplicating the durable fact, but it is
-not a proof that every accepted turn reached a harness.
-
-
- The observed ordering gives one atomic environment-side acceptance point and a
- later, hot side-effect consumer. Client convergence reads committed projections;
- it cannot retroactively make an unobserved provider handoff durable.
-
-
-## Trace 2 — relay-connected mobile turn: launch through the relay, work directly with the environment
-
-A relay-connected phone first holds account authority and a device DPoP key. The
-relay authorizes discovery or connection setup and asks the selected environment to
-mint a short-lived bootstrap credential bound to that proof key, then returns the
-endpoint and bootstrap material to the phone. The phone exchanges that bootstrap
-**directly with the environment**, persists the environment-bound access material,
-gets a direct WebSocket ticket, and then runs the same shared connection, snapshot,
-and command path as another client.
-
-The tunnel can expose the local environment, but the hosted relay does not carry
-normal T3 API or WebSocket traffic after launch. Thus the mobile turn begins only
-after the environment session is established; neither a successful Clerk session
-nor a successful relay call is a thread update. [Chapter 35](../t3-connect/) owns
-the credential ladder and tunnel setup; [Chapter 29](../shared-client-runtime/) and
-[Chapter 33](../mobile-client-continuity/) own the client session and remote-native
-continuity edges.
-
-
-
-
-
-
- The relay is explicitly outside normal post-launch traffic. The safe next step is
- environment-scoped session establishment followed by normal snapshot and stream
- reconciliation, not treating a control-plane response as authoritative thread
- state.
-
-
-## Trace 3 — approval round-trip: persist a request and a response around a native callback
-
-A provider can request approval or structured user input while processing a turn.
-The adapter normalizes that native request; runtime ingestion flushes buffered
-assistant content before the interaction pause, records canonical pending activity,
-and projection storage exposes it to a selected web or mobile thread. The client
-derives a response UI from the synchronized pending request—not from an untrusted
-notification payload or a local approximation of provider state.
-
-When the person answers, the client sends a typed response intent. The decider
-creates a durable response-requested event; the provider command reactor later
-routes it to the exact bound session, and the adapter uses the provider-native reply
-mechanism. A subsequent provider event and projection update are what settle the
-visible pending state. The canonical and provider-specific mapping is in
-[Chapter 24](../permissions-and-input/).
-
-
- This trace has two durable request sides—provider request projection and user
- response intent—but the actual provider callback is a later reactor action. Do not
- infer universal approval semantics from a T3 runtime-mode label; adapters map
- their native controls differently.
-
-
-## Trace 4 — offline mobile task drain: durable phone intent waits for remote evidence
-
-While offline, the phone first exposes a queued row optimistically, then serializes
-an atomic file write. Before delivery, it confirms that the durable record still
-exists behind pending mutations. That prevents an item whose write failed from
-escaping merely because it was briefly visible in the UI.
-
-After reachability returns, the drain does not send every record at once. It handles
-one message globally and the first queued message per thread. For a creation, it
-waits for a **live shell**: a shell that already contains the stable thread id means
-the local cleanup is stale and the item is removed; only a live shell that lacks it
-may send. Existing-thread items likewise wait for enough shell evidence before a
-missing thread is discarded. Settings reconciliation can precede the final turn
-command; the environment then applies its normal receipt and invariant rules.
-
-Once the start-turn command returns its selected success result, the drain removes
-its local file; it does not wait for a later shell/detail projection to make that
-cleanup decision. Snapshot and stream state reconcile afterward and remain useful
-evidence on later drain passes. That joins no transaction across phone storage and
-server SQLite. [Chapter 33](../mobile-client-continuity/) is the full mobile
-state-machine account, while [Chapter 10](../events-receipts/) explains the
-environment receipt boundary.
-
-
-
-
-
-
- Stable identities, serialized confirmation, live-shell evidence, and environment
- receipts make retry safer. A crash or network loss between the atomic phone file
- and the remote command still leaves a cross-store ambiguity that the drain handles
- with evidence and policy rather than an exactly-once claim.
-
-
-## Trace 5 — checkpoint diff and revert: Git content first, then a conditional history rewrite
-
-For an eligible completed turn, the checkpoint reactor can capture the workspace
-through a temporary Git index into a hidden, thread-scoped ref. It derives the patch
-against the preceding checkpoint and dispatches a `thread.turn.diff.complete`
-command only after that capture/diff work. The engine then makes the checkpoint
-summary visible in the durable thread projection. A review screen can compare hidden
-turn boundaries; live working-tree and branch modes are separate Git queries.
-
-Revert begins with a durable request event, but it is an ordered saga rather than
-one transaction. It checks the thread, binding, Git workspace, turn count, and
-target; restores content and index, refreshes the workspace, asks the bound provider
-to roll back later turns, attempts ref pruning, returns those outcomes to the
-checkpoint reactor, and only then has the orchestration engine dispatch durable
-completion. If provider rollback or a later step fails after Git restore, files may
-already match the target while provider history and projected thread history do not.
-That partial state is an implementation-path inference, not a promise of automatic
-repair. See [Chapter 27](../checkpoints-revert/) for the full preconditions and
-provider matrix.
-
-
- The ordered calls show filesystem replacement before provider rollback and before
- durable completion. A failure later in that sequence records failure rather than
- compensating every changed boundary; a completed projection is therefore not
- warranted until the completion path runs.
-
-
-## Trace 6 — stable release and exact-version update: publish, prepare, trial, commit or roll back
-
-The release workflow first resolves a stable version and publishes the exact
-`t3@V` CLI/runtime package. Only then can the GitHub release make clients discoverable
-and a hosted deployment follow. A connected client that asks an eligible server to
-update targets that exact version, not whichever package currently owns an npm
-dist-tag.
-
-The active server rejects non-exact or concurrent targets, stages the immutable
-runtime, preflights it, and hands prepared target information to the stable service
-launcher. The launcher owns the migration/trial boundary: it records pending state,
-captures the SQLite triplet, stops the old child, starts the new candidate, and
-commits only after the candidate reports prepared. A failed or timed-out trial can
-restore the snapshot and select the old runtime; after durable commit, later
-failures are governed by ordinary restart policy instead. [Chapter
-38](../release-updates-observability/) separates this boot-service updater from the
-desktop and mobile state machines.
-
-
-
-
-
-
- Publication is a release graph invariant, preflight is an active-server check,
- and trial/rollback/commit belong to the independent launcher. Conflating these
- three boundaries would make a package publish look like a successful machine
- update, which the source does not support.
-
-
-
-
-## What these traces establish—and what they refuse to claim
-
-The repeatable pattern is not “make every operation a distributed transaction.” It
-is more disciplined: give each durable store a narrow contract, serialize the owner
-that must make a decision, pass effects through explicit handoff points, and show
-the reader or operator what evidence establishes convergence. Inference across
-modules is useful only when it keeps the seams visible.
-
-For example, a relay-connected mobile turn legitimately combines credential launch,
-environment supervision, and an ordinary turn. It does **not** imply that the relay
-stores the thread. Likewise, an outbox retry and a command receipt together reduce
-duplicate work, but they cannot promise that every provider-side effect occurred
-once. These distinctions are the basis for the decision review that follows.
-
-
diff --git a/src/content/book/40-runtime-topologies.mdx b/src/content/book/40-runtime-topologies.mdx
index b6dba6f..cf91db1 100644
--- a/src/content/book/40-runtime-topologies.mdx
+++ b/src/content/book/40-runtime-topologies.mdx
@@ -1,10 +1,10 @@
---
slug: runtime-topologies
-order: 40
-number: "4"
+order: 190
+number: "19"
kind: chapter
-part: Part I · Boundaries and vocabulary
-partOrder: 1
+part: Part II · Boundaries and vocabulary
+partOrder: 2
title: Runtime topologies and technology placement
shortTitle: Runtime topologies
summary: The same contracts appear in several process graphs; local CLI, hosted web, Electron, and mobile move ownership without moving repository execution off the environment server.
@@ -17,7 +17,7 @@ objectives:
keywords: [topology, Effect, SQLite, React, Electron, Expo, Astro]
sourceAreas: [apps/server, apps/web, apps/desktop, apps/mobile, apps/marketing]
visuals: [topology switcher, technology placement matrix]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
diff --git a/src/content/book/400-decisions-limitations-roadmap.mdx b/src/content/book/400-decisions-limitations-roadmap.mdx
deleted file mode 100644
index c3e0ba1..0000000
--- a/src/content/book/400-decisions-limitations-roadmap.mdx
+++ /dev/null
@@ -1,413 +0,0 @@
----
-slug: decisions-limitations-roadmap
-order: 400
-number: "40"
-kind: chapter
-part: "Part VIII · Synthesis"
-partOrder: 8
-title: "Decisions, trade-offs, limitations, and an honest roadmap"
-shortTitle: Decision ledger
-summary: "T3 Code's architecture is a set of bounded choices: server authority, transactional events, hot reactors, cursored projections, adapters, scoped reconnect, durable mobile intent, exact-version updates, and demand-driven background work each make one failure mode tractable while deliberately leaving another visible."
-status: source-checked
-gates: [sources, interaction]
-objectives:
- - Read the major architectural choices as pressure, choice, benefit, cost, alternative, and reversal trigger rather than as universal patterns.
- - Separate shipped behavior, documented intent, source-bounded inference, latent capability, and explicit future work.
- - Identify the persistence and delivery seams, including the conditions under which each choice should be reconsidered.
- - Leave a precise inventory of platform asymmetries and repository discrepancies without inventing roadmap commitments.
-keywords: [architecture, trade-off, server authority, event sourcing, reactor, projection, provider adapter, reconnect, outbox, update, retention, roadmap]
-sourceAreas: [apps/server/src/orchestration, apps/server/src/provider, apps/server/src/auth, packages/client-runtime/src/connection, apps/mobile/src/state, apps/mobile/src/connection, docs/internals/remote.md, docs/operations/release.md]
-visuals: [decision ledger, trade-off path, limitation taxonomy]
-updatedAt: 2026-08-24
----
-
-import Callout from "../../components/Callout.astro";
-import DecisionLedgerLab from "../../components/DecisionLedgerLab.astro";
-import EvidenceClaim from "../../components/EvidenceClaim.astro";
-import Figure from "../../components/Figure.astro";
-import Mermaid from "../../components/Mermaid.astro";
-import SourceExcerpt from "../../components/SourceExcerpt.astro";
-import SourceList from "../../components/SourceList.astro";
-
-This is a ledger, not a claim that T3 Code found the one right architecture. At
-the locked revision, its choices consistently put one environment server in charge
-of product authority, preserve accepted intent in SQLite, and make provider-native
-execution, filesystem work, and client presentation explicitly separate. That
-produces a comprehensible control surface across many harnesses. It also produces
-real seams: a committed event can miss a hot reactor, an external harness can cross
-an ambiguous crash boundary, and not every client or retained artifact has equal
-capabilities.
-
-Use the six columns throughout this chapter precisely:
-
-| Lens | Question it answers |
-| --- | --- |
-| Pressure | What failure or product constraint is being controlled? |
-| Choice | What is actually implemented at the pinned revision? |
-| Benefit | Which guarantee becomes easier to state or test? |
-| Cost | What complexity, boundary, or weaker guarantee remains? |
-| Alternative | What a different design could optimize instead—not a promise about T3. |
-| Reversal trigger | The product pressure that would justify revisiting this choice. |
-
-
- **Shipped** means executable behavior at the lock. **Documented** means an upstream
- statement of intent or operations rule. **Inference** is this book's explicitly
- bounded conclusion from cited paths. **Future** is only an upstream item named as
- unbuilt. A latent builder target or compatibility bridge is neither a shipped
- surface nor a future commitment.
-
-
-## 1. Authority and durable intent: make the environment server the product boundary
-
-### Server authority
-
-The pressure is remote control without pretending that a browser, desktop shell, or
-phone owns a provider process, Git worktree, terminal, or filesystem. T3 puts those
-operations behind the environment server. Clients authenticate, use typed RPC, and
-hold projections and presentation state; a provider still owns its native reasoning
-and context engine. This makes one environment the place where authorization,
-orchestration, workspace effects, and product history meet.
-
-
- Server composition acquires authentication, orchestration, provider, VCS, terminal,
- filesystem, and remote-endpoint services in one owned runtime. The adapter boundary
- keeps provider-native session behavior outside the product's durable domain core.
-
-
-The benefit is a clear remote model: adding another device adds another client of an
-environment rather than another competing owner of a workspace. The cost is that
-availability, upgrades, and recovery concentrate around that server; clients must
-reconnect and reconcile instead of making local state authoritative. A peer-to-peer
-or client-owned model could improve disconnected autonomy, but would need a conflict,
-credential, and workspace-execution story that this implementation deliberately does
-not carry. Revisit the choice if concurrent offline editing or multi-writer workspace
-authority becomes a primary product requirement.
-
-### Transactional event core
-
-The pressure is accepting a user command exactly enough to answer a retry without
-claiming provider completion. The choice is a serialized engine that decides a
-command, appends its event batch, applies projections, and records the command receipt
-inside one SQLite transaction. The benefit is a sharp acceptance boundary: retrying
-the same command id can recover the stored result, and a failed transaction leaves no
-accepted receipt. The cost is that normalization-time files, provider calls, and
-later reactor work are outside that transaction.
-
-
-
-An append-only log is not free: commands and deciders must retain invariants, read
-models must be maintained, and a receipt is not an end-to-end idempotence proof for a
-multi-step bootstrap saga. A direct CRUD model could lower local complexity when there
-is no need to replay or compose state. Revisit the event core when the product no
-longer benefits from immutable command history, independently shaped projections, or
-receipt-based retry semantics.
-
-
- S[Environment server\nauthority]
- S --> T[(Event + projection + receipt\nSQL transaction)]
- T -. committed event .-> R[Hot reactor]
- R --> A[Provider adapter]
- A --> P[Native harness / process]
- T --> Q[Projection cursors\nrebuild read models]
- C --> O[Mobile durable\nintent outbox]
- S --> U[Exact-version\nstage + preflight]
- C -. retained demand .-> B[Scoped background work]
- R -. no durable delivery record .-> X[Crash / replay seam]
- A -. native state remains external .-> X
- P -. result returns hot .-> R`} />
-
-
-## 2. Delivery and read state: choose explicit eventual boundaries
-
-### Hot, best-effort post-commit reactors
-
-The pressure is to avoid calling a harness while a domain transaction is still open.
-T3 publishes only after commit, then runs provider, runtime-ingestion, checkpoint,
-deletion, and awareness consumers as hot scoped workers. The benefit is simple:
-rollback cannot have caused a provider turn, and one reactor failure is handled without
-rolling back accepted domain history. The cost is the **reactor crash window**. A
-process can die after the receipt/event commit and before a reactor observes it; the
-source contains no durable outbox row, per-reactor delivery cursor, or startup replay
-of pending hot work.
-
-
- The provider command reactor consumes current hot events and records duplicate
- suppression in process memory before forking its send. Its source explicitly says
- pending work is not replayed on a later subscription.
-
-
-That is a reasonable trade where an external operation can be ambiguous to repeat:
-a durable outbox still needs idempotency keys, attempt records, and a policy for a
-harness that accepted work just before a crash. It would be the alternative when the
-product requires guaranteed post-commit execution. The reversal trigger is explicit:
-if “accepted turn” must eventually imply “provider send attempted” across server
-crashes, add a durable delivery protocol rather than describing the current reactor as
-exactly once.
-
-### Snapshot plus cursor
-
-The pressure is a fast UI that can restart, replay, and subscribe without claiming
-that one monolithic snapshot is globally current. Each projector has a durable cursor;
-normal command acceptance advances its projector SQL and cursor together. A composed
-snapshot uses the minimum cursor among its required projectors, while live clients
-attach before their replay/snapshot read and use global event sequence for gap repair.
-
-
- Projectors bootstrap independently from their own cursors. The snapshot helper
- deliberately returns the minimum required projection sequence, not the event-log
- head; subscription setup attaches live input before deciding replay or snapshot.
-
-
-The benefit is independently shaped and rebuildable read state. The cost is more
-than one watermark, a bounded bootstrap path, ordering-sensitive projectors, and
-careful client race guards. A single authoritative document per thread could simplify
-some reads but makes fan-out and independently evolved views harder. Revisit cursor
-architecture if projection lag, cross-projector joins, or operational replay needs
-outgrow the current SQLite/replay ceiling.
-
-## 3. Harness and client continuity: normalize the boundary, not the world
-
-### Provider adapters
-
-The pressure is five harnesses with different session, approval, stream, context,
-and process semantics. T3 chooses a narrow adapter lifecycle and canonical runtime
-event grammar; `ProviderService` owns routing, bindings, correlation, credentials,
-and cross-provider policy. The benefit is one product domain that can preserve native
-provenance without forcing all harnesses into a fictional universal feature set.
-
-The cost is an adapter matrix, capability gaps, and no repository-wide proof that all
-providers have semantic parity. A generic “agent protocol only” design could reduce
-some integrations but would either lose native features or push product policy into
-each provider driver. Revisit this boundary when the normalized contract can no
-longer represent an important native lifecycle without pervasive escape hatches.
-
-
- The adapter exposes provider lifecycle and canonical event operations. The service
- resolves persisted bindings, adopts/resumes sessions, correlates instance events,
- and supplies product-level policy around the concrete adapter.
-
-
-### One reconnect owner per environment
-
-The pressure is multiple pages, caches, notifications, and devices observing one
-remote environment without creating retry storms or merging unrelated authorities.
-The choice is one environment registry entry with one supervisor generation and at
-most one active RPC lease; shell and thread synchronizers retain separate cache and
-cursor responsibilities. The benefit is one place to own transport lifecycle while
-each projection remains honest about its own authoritative refresh.
-
-The cost is a sophisticated supervisor, generations, leases, and surface-specific
-resynchronization. A global connection manager is attractive but would blur separate
-environment authority and corrupt cache ownership. Revisit this model if the product
-adds genuine cross-environment aggregation or a shared write model—not merely a UI
-that displays several environment summaries.
-
-
- The runtime registry replaces an environment-scoped lease, and each new generation
- leads the shell back through an authoritative refresh rather than elevating cache
- continuity into authority.
-
-
-### Durable mobile intent outbox
-
-The pressure is a phone losing foreground time or connectivity after the user has
-pressed send. Mobile uses an optimistic enqueue with durable persistence, serializes
-its manager, and asks the user for a delivery decision when a queued turn collides
-with a changed thread state. The benefit is preserving user intent locally before it
-can be delivered to an environment. The cost is another state machine: existence
-guards, capped backoff, confirmations, and explicit replay semantics instead of an
-assumption that a compose action immediately became a server turn.
-
-An always-online client could omit this machinery, but it would trade away the
-recovery behavior that matters on a mobile lifecycle. Revisit the outbox when mobile
-intent becomes multi-device collaborative work requiring server-issued identities or
-when all clients need an equivalent durable intent queue.
-
-
-
-### Exact-version updates
-
-The pressure is a newly visible client asking a connected server to run an incompatible
-runtime. T3 publishes the exact CLI package before a release exposes the clients that
-can request it; a boot-service server rejects non-exact targets, stages and preflights
-that runtime, then hands activation to a stable launcher. The benefit is a precise
-compatibility target and a reversible SQLite-bound trial. The cost is release ordering,
-launcher protocol compatibility, and platform-specific update machinery.
-
-A floating channel update can reduce operations friction but makes an update request
-less reproducible. Revisit the invariant if a compatibility protocol—not matching
-versions—becomes sufficient to prove safe server/client combinations.
-
-
- The operations guide names the npm-before-clients invariant; the self-update path
- accepts only an exact target and validates its staged runtime before launcher handoff.
-
-
-### Scope-driven background work
-
-The pressure is staying useful while mobile is backgrounded without keeping every
-environment permanently active. Mobile background activity reports retained demand
-through reference-counted environment scopes. The benefit is a bounded reason for
-work to continue: a caller declares interest and releases it. The cost is that
-subscription ownership and lifecycle cleanup must be correct; background liveness is
-not a durable scheduler, and platform APIs constrain what actually runs.
-
-An always-on global worker would simplify call sites but waste resources and make
-ownership leaks more damaging. Revisit scopes when the product needs a durable
-background-job contract with OS-managed scheduling and completion receipts.
-
-
- Mobile background work is reported per environment and reference-counted by retained
- scopes; the platform layer owns connection cleanup rather than making a background
- indicator evidence of durable execution.
-
-
-
-
-## 4. Limitations are part of the architecture contract
-
-The ledger above describes choices. This section records the places where their edges
-must stay visible in a design review.
-
-### Shipped asymmetries and discrepancies
-
-| Classification | What the pinned source establishes | Consequence for a reader or successor |
-| --- | --- | --- |
-| Shipped platform asymmetry | Desktop, boot-service server, and Expo mobile update through three different state machines; mobile's OTA is fingerprint-gated and its safe reload waits for persistence and lifecycle conditions. | “Update” cannot be one shared abstraction without losing its owner and rollback boundary. |
-| Latent artifact | Root build scripts support more target names than the inspected release matrix actually publishes; Windows ARM64 is present as a latent/commented target rather than a distributed artifact at this lock. | Builder support is not evidence that a user can download a release. |
-| Transition / compatibility path | The web hides OpenCode's `plan` agent when legacy plan mode is off and heals old stored selections after settings hydrate; mobile retains a device-local legacy plan-mode preference. | The plan UI is transitional compatibility code, not proof of a new universal planning model. |
-| Shipped model boundary | Provider resume state is an opaque binding; thread plans, checkpoints, drafts, and native harness history remain distinct records. | There is no universal memory layer or provider-independent continuation guarantee. |
-
-
- The sources persist different identities and lifecycle shapes for bindings, domain
- plans, checkpoints, and mobile intent, while plan progress is explicitly in memory.
- Calling their collection “universal memory” would overstate what can be restored or
- resumed across a provider boundary.
-
-
-
- The web hydration pass repairs stale saved selections, the web capability filter
- removes the OpenCode plan option while legacy mode is off, and mobile independently
- keeps a device-local legacy preference. These are distinct compatibility paths.
-
-
-### Retention and cleanup are selected operations, not one erase button
-
-Tombstoning a project or thread changes its projected visibility; it does not erase
-the append-only event history or command receipts. Thread revert removes selected
-derived messages, plans, activities, turns, attachment files, and later checkpoint
-refs, but retains event history and records the revert itself. The thread-deletion
-reactor performs best-effort provider and terminal cleanup; the web separately offers
-an orphan-worktree removal path. Provider binding deletion exists as a repository
-operation, yet no caller appeared in the inspected production sources. Hidden checkpoint
-refs likewise do not gain a repository-wide lifecycle reconciler simply because a
-thread is tombstoned.
-
-
- This conclusion is scoped to the inspected production paths: they distinguish
- tombstones, selected revert pruning, hot deletion cleanup, and optional web worktree
- cleanup. It is not a promise that future retention behavior will remain unchanged.
-
-
-Attachment cleanup has the opposite shape: normalizers write image bytes before
-command dispatch, while projectors perform later filesystem deletion after their SQL
-and cursor step. That reduces database/file coupling but makes cross-store atomicity
-unavailable. A rejected or retried command can leave an early file; a failed cleanup
-is logged, and a crash after cursor advancement can prevent that event from selecting
-the same cleanup again. This is **shipped behavior**, not a future garbage collection
-protocol.
-
-
- File creation occurs before domain dispatch. The projector's SQL/cursor work occurs
- before best-effort filesystem cleanup, and bootstrap resumes from durable cursors.
-
-
-DPoP replay defense records a replay marker under a hashed proof-derived key through
-exclusive secret creation.
-The source path establishes rejection of a duplicate marker. **Inference:** the
-inspected source does not show a corresponding marker-expiry or retention sweep, so
-this book cannot claim a bounded replay-marker store merely because proof timestamps
-are recorded. That is a retention inference, not a security weakness claim.
-
-
- The code writes a durable marker keyed by proof material and maps an existing marker
- to replay rejection. This audit did not locate a deletion or expiry path for those
- markers at the pinned revision.
-
-
-### The only roadmap claims here are explicit upstream future work
-
-The internal remote document labels three items **unbuilt**: additional third-party
-tunnel endpoint providers, a **relay-hosted OAuth callback broker**, and richer
-multi-environment UI beyond the current connections list. They are future work, not
-dates, milestones, or a promise that their current design will ship. The pinned code
-and connect documentation do implement a hosted static `/connect/callback` handoff
-page. That is not evidence of a relay-hosted backend broker: only the broad claim
-that there is *no callback path* is stale, while the literal broker item remains
-future work.
-
-
- The source explicitly calls the three remote items unbuilt. Separately, the hosted
- callback handoff is executable; it does not establish the future relay broker. The
- source provides no release date, priority, or implementation guarantee for the
- broker or either other item.
-
-
-## 5. A decision review is more useful than a pattern checklist
-
-When evaluating T3 Code's choices, the useful question is not “should every system
-copy this?” It is: **which pressure does this choice address, which boundary is
-durable, and which cost does it impose?** T3's strongest recurring lesson is truthful separation:
-accepted intent is not provider completion; a projection is not a universal snapshot;
-a remote notification is not authority; a bounded local record is not a retention
-policy; and a compatibility branch is not a roadmap.
-
-
diff --git a/src/content/book/50-cli-bootstrap.mdx b/src/content/book/50-cli-bootstrap.mdx
index 2adfad4..9c6a4d2 100644
--- a/src/content/book/50-cli-bootstrap.mdx
+++ b/src/content/book/50-cli-bootstrap.mdx
@@ -1,10 +1,10 @@
---
slug: cli-bootstrap
-order: 50
-number: "5"
+order: 200
+number: "20"
kind: chapter
-part: Part II · Boot and connect
-partOrder: 2
+part: Part III · Boot and connect
+partOrder: 3
title: The `npx t3` bootstrap path
shortTitle: CLI bootstrap
summary: The published package resolves commands and configuration, locates its copied web client, and hands one readonly ServerConfig value to the layered runtime.
@@ -17,7 +17,7 @@ objectives:
keywords: [npx t3, CLI, ServerConfig, bootstrap, static assets, npm package]
sourceAreas: [apps/server/src/bin.ts, apps/server/src/cli, apps/server/scripts/cli.ts, apps/server/vite.config.ts]
visuals: [package exploder, interactive bootstrap stepper, configuration scenario resolver]
-updatedAt: 2026-08-24
+updatedAt: "2026-09-11"
---
import Callout from "../../components/Callout.astro";
@@ -31,7 +31,7 @@ import SourceList from "../../components/SourceList.astro";
`npx t3` looks like one command, but it crosses three distinct systems: npm
selects a published executable, the Effect CLI selects a command and resolves
-configuration, and the server runtime acquires the services described in Chapter 6.
+configuration, and the server runtime acquires the services described in Chapter 21.
Keeping those stages separate makes several otherwise surprising behaviors obvious.
## What npm actually installs
@@ -52,7 +52,7 @@ publishes only `dist`. That directory is deliberately more than one JavaScript f