projmux 0.15.3 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,9 +2,10 @@
2
2
 
3
3
  The machine-readable ledger is retained as historical liveness evidence only.
4
4
  It is **not** capability authority for `durable-zero-turn-resume` or
5
- `remote-new-session`; those predicates require the exact executable tuple and
6
- the Phase-1 conformance record described in
7
- [`codex-native-required-migration.md`](codex-native-required-migration.md).
5
+ `remote-new-session`. The private generation pool that once owned that
6
+ conformance record has been removed; see
7
+ [`codex-native-required-migration.md`](codex-native-required-migration.md) for
8
+ the payload-free create behavior that remains.
8
9
  The legacy [`codex-installed-capabilities.json`](codex-installed-capabilities.json)
9
10
  schema separates method evidence from the semantic result:
10
11
 
@@ -42,8 +43,8 @@ observation. It must not be cited as payload-free support.
42
43
  The observation historically extended the earlier `pre-turn-attach` owner.
43
44
  That hosted evidence remains run `33560743314`,
44
45
  aggregate artifact `9821171919`, where the same tuple's direct pre-turn
45
- qualification was `pass`. Neither pass is an input to the new exact
46
- payload-free capability authority.
46
+ qualification was `pass`. Neither pass is capability authority for the
47
+ payload-free predicates above.
47
48
 
48
49
  Scheduled and manual `Installed Codex Qualification` artifacts use
49
50
  qualification schema v2 and embed this schema-versioned capability ledger.
@@ -59,11 +60,5 @@ records `github-actions:33566050834:1`.
59
60
  - `TestInstalledIsolatedPreTurnBootstrapSmoke` — historical owner for
60
61
  turn-free start/read/loaded observation and live-Pane liveness; not a
61
62
  payload-free support verdict.
62
- - `TestInstalledExactPayloadFreeCapabilityMatrix` — exact private owner for
63
- zero-turn start/read/stored-resume plus content-free remote-new liveness. It
64
- sends no input or turn, so remote-new remains unknown.
65
63
  - `TestInstalledCensusDeletionReceiptHasOneOwnerPerPrimitive` — topology and
66
64
  protocol ownership plus the Phase 2 merge receipt.
67
-
68
- The maintained repository-wide list in `docs/agent-workflow.md` records the
69
- current Phase-1 authority separately.
@@ -21,61 +21,7 @@ provider response is stored to produce that signal.
21
21
  The Phase-7 zero-turn durable-readiness failure is retained only as historical
22
22
  negative safety evidence. A typed Failed Agent with no Pane is not functional
23
23
  create success. Prompted native create, app-server picker resume, existing
24
- Agent resume, and generation-pinned routes keep their native contracts.
25
-
26
- ## Exact payload-free capability authority (Phase 1)
27
-
28
- Payload-free qualification is now owned by
29
- `internal/integrations/agents/codexgeneration`. A record is valid for exactly
30
- one tuple: RoleTUI binary SHA-256 and size, RoleAppServer binary SHA-256 and
31
- size, app-server version, protocol transport/schema, private socket locator and
32
- bound-runtime digests, state-domain identity/path digest, and platform/arch.
33
- Changing any one axis is a cache miss. A missing, corrupt, trailing, future
34
- schema, stopped, or rebound tuple projects `unknown` and the Phase-0
35
- `plain-fallback`; no semver family, changelog, or successful `thread/read` is an
36
- authority substitute.
37
-
38
- The record reduces two independent executable predicates:
39
-
40
- - `durable-zero-turn-resume` requires the same hashed exact thread to pass
41
- zero-turn start, independent read, and stored resume. Read visibility alone
42
- cannot promote it. Exact 0.153.0 private evidence is read-visible but stored
43
- resume is `unsupported/no-rollout-found`.
44
- - `remote-new-session` requires more than a living TUI. The remote-new thread
45
- and the exact first real input's thread must match, the turn identity must be
46
- present, and the content-free turn cardinality must be exactly one. An
47
- unrelated first-turn event or liveness-only observation stays `unknown`.
48
-
49
- Evidence stores timestamps, digests, closed outcomes, cardinality, and boolean
50
- identity facts only. It has no field for prompts, provider output, turns,
51
- transcripts, socket paths, or state paths. Doctor JSON/text and the create
52
- planner consume the same immutable record projection. Phase 1 intentionally
53
- maps every verdict—including a supported private observation—to
54
- `plain-fallback`; the remote-new production launch belongs to Phase 2.
55
-
56
- The private installed matrix is opt-in and starts/stops only exact root-owned
57
- app-server and tmux fixtures:
58
-
59
- ```sh
60
- smoke_root="$(mktemp -d /tmp/projmux-payload-free-XXXXXX)"
61
- env -u TMUX -u TMUX_PANE \
62
- PROJMUX_CODEX_PAYLOAD_FREE_SMOKE_ROOT="$smoke_root" \
63
- PROJMUX_CODEX_PAYLOAD_FREE_SOURCE_HOME=/absolute/private/copied-source-home \
64
- PROJMUX_CODEX_PAYLOAD_FREE_0152_0=/absolute/0.152.0/bin/codex \
65
- PROJMUX_CODEX_PAYLOAD_FREE_0152_1=/absolute/0.152.1/bin/codex \
66
- PROJMUX_CODEX_PAYLOAD_FREE_0153_0=/absolute/0.153.0/bin/codex \
67
- go test ./internal/testutil/codexinstalled \
68
- -run '^TestInstalledExactPayloadFreeCapabilityMatrix$' -count=1 -v
69
- ```
70
-
71
- An unset binary row is logged `unavailable`; the fixture never synthesizes a
72
- tuple. The installed probe sends no input, prompt, or turn. It may record
73
- content-free TUI liveness/loaded state, but remote-new remains `unknown`
74
- without a separately supplied exact first-real-input thread/turn observation.
75
- Use the documented short smoke-root shape: an overlong private tmux socket path
76
- is rejected before any lifecycle operation and cannot masquerade as liveness.
77
- After fixture cleanup the socket has no current route identity, so transient
78
- private evidence cannot be reused by another route.
24
+ Agent resume, and stored-endpoint routes keep their native contracts.
79
25
 
80
26
  ## Native-required prompted create (0.14.0)
81
27
 
@@ -254,10 +200,6 @@ go test ./internal/integrations/agents/codexappserver/ -run TestStartDefaultThre
254
200
  | Both `--interactive-only` spellings are equivalent, and non-Codex providers refuse it at zero transactions | `TestInteractiveOnlyIsTheOnlyPlainCodexLaneAndBothSpellingsAreEquivalent` |
255
201
  | Payload cardinality × `--interactive-only` × readiness stays a closed pre-provider decision table | `TestCodexCreatePayloadCardinalityInteractiveOnlyAndReadinessOutcomeTable` |
256
202
  | Canonical and shortcut payload-free create are byte/argv-equivalent to the explicit plain lane and touch no provider route | `TestPayloadFreeCodexCreateUsesSafePlainFallbackAndInteractiveOnlyEquivalentLane` |
257
- | Exact tuple keys, immutable cache fixed points, and one-axis drift/corrupt/future/trailing fail closed | `TestCapabilityCacheInvalidatesEveryExactTupleAxis`, `TestCapabilityCacheCorruptFutureAndTrailingRecordsResolveUnknown` |
258
- | Read visibility and stored resume reduce independently; remote-new requires the exact first real thread/turn | `TestExactPayloadFreeCapabilitySeparatesReadVisibleFromStoredResumable`, `TestRemoteNewCapabilityRequiresExactFirstRealInputThreadAndTurn` |
259
- | Doctor and create plan consume byte-semantic identical capability projections while Phase 1 stays plain | `TestCodexPayloadFreeDoctorAndCreatePlannerShareExactRecordProjection`, `TestCodexPayloadFreeUnknownCapabilityCannotBypassPhaseZeroFallback` |
260
- | Available exact installed binaries are qualified independently in creator-live/closed private rows | `TestInstalledExactPayloadFreeCapabilityMatrix` |
261
203
  | Saved-default, provider-picker, and direct-provider AI intents produce one managed plain lane without native mutation | `TestEmptyPromptCodexSplitProducersKeepOnePlainCLILane` |
262
204
  | A failed plain launch rolls Registry and tmux back and never tries a provider lane | `TestPayloadFreeCodexPlainLaunchFailureRollsBackWithoutProviderMutation` |
263
205
  | The installed outcome requires a Running plain Agent/Pane, no session ref, zero provider-thread delta, diagnostic signals, isolated socket cleanup, and ambient mutation zero | `TestInstalledPayloadFreePlainFallbackOutcomeSmoke` |
@@ -38,13 +38,15 @@ those folders exist:
38
38
 
39
39
  It does not assume a canonical repo root.
40
40
 
41
- Use Settings > Project Picker for the normal interactive flow:
41
+ Use `Settings > Global > Projects` for the normal interactive flow:
42
42
 
43
- - `Project Root` sets, changes, or clears the saved primary root.
44
- - `+ Add Workdir...` appends one directory to the saved workdirs list.
45
- - `Workdirs` reviews and removes saved workdirs.
43
+ - `Primary discovery root` sets, changes, or clears the saved primary root.
44
+ - `Additional discovery roots > Add path` appends one directory to the saved
45
+ workdirs list.
46
+ - `Additional discovery roots` reviews saved workdirs; each root's
47
+ `Remove discovery root` removes it.
46
48
 
47
- `Add Workdir > Type path manually...` skips the filesystem scan and is useful
49
+ `Add path > Type path manually...` skips the filesystem scan and is useful
48
50
  for large mounts, WSL paths, NFS paths, or temporary project roots.
49
51
 
50
52
  The saved workdir file is:
@@ -56,7 +58,7 @@ The saved workdir file is:
56
58
  It stores one absolute path per line. Lines beginning with `#` are comments.
57
59
  The file is read only when no env root list is set.
58
60
 
59
- Workdirs are a **scan source and nothing else**. Adding a root, and scanning one,
61
+ Saved workdirs are a **scan source and nothing else**. Adding a root, and scanning one,
60
62
  never registers a Registry Project: a discovered child is an unregistered
61
63
  candidate until `projmux create project --root <path>` or opening it once from the
62
64
  Projects sidebar registers that exact path. See
@@ -92,51 +94,11 @@ request with `projmux pin project migrate`; see
92
94
  [upgrading.md](upgrading.md#pins-are-typed-and-migrate-on-request) for the
93
95
  per-line outcomes and the ambiguity refusal.
94
96
 
95
- ## Legacy Project Layout Snapshots
97
+ ## Legacy Project Layout Files
96
98
 
97
- Older checkouts may already have named layout snapshots in the legacy storage
98
- directory:
99
-
100
- ```text
101
- <project>/.projmux/layouts/<name>.toml
102
- ```
103
-
104
- The project context comes from `PROJMUX_CWD` when set, otherwise projmux walks
105
- upward from the current directory to the nearest `.projmux` or `.git` marker.
106
- Files outside that project tree are not discovered. This storage is treated as
107
- legacy import data for explicit conversion and preview. Closed-Project startup
108
- does not expose legacy snapshot choices; current user-facing surfaces describe
109
- the restore unit as a snapshot, not as a separate layout or preset feature.
110
-
111
- The legacy schema is intentionally close to the session-state snapshot shape:
112
-
113
- ```toml
114
- schema_version = 1
115
- description = "Daily dev"
116
- mode = "inherit-autosave" # default; or "fresh-each-time"
117
- default_cwd = "${PROJMUX_CWD}"
118
-
119
- [[windows]]
120
- index = 0
121
- name = "main"
122
- layout = "..."
123
- active_pane_index = 0
124
-
125
- [[windows.panes]]
126
- index = 0
127
- cwd = "${PROJMUX_CWD}"
128
- command = "make watch"
129
- ```
130
-
131
- `command` records a startup recipe, matching the supported session-state replay
132
- recipe. Panes without `command` may use `recipe = "shell"`. Supported
133
- interpolation placeholders are limited to `${PROJMUX_CWD}` and
134
- `${PROJMUX_SESSION}`; other `${...}` values are rejected during load.
135
-
136
- Unknown fields and unknown sections are ignored so future schema additions do
137
- not break older files. The built-in parser only accepts quoted strings and
138
- integer values for the known fields above; it does not implement the full TOML
139
- language.
99
+ Older checkouts may still have named layout files under
100
+ `<project>/.projmux/layouts/*.toml`. projmux no longer reads, writes, trusts,
101
+ or deletes them; they have no effect and can be removed by hand.
140
102
 
141
103
  ## Keymap File
142
104
 
@@ -234,7 +196,7 @@ popup action with no built-in shortcut. Every configured alias renders the
234
196
  canonical client-scoped body
235
197
  `projmux internal tmux popup-toggle --client #{client_tty} resource-inspector`; pressing
236
198
  the same alias again closes only that client's popup. It remains available on
237
- Linux/tmux even when the Labs live-resource status segment is off.
199
+ Linux/tmux even when the `Status Bar > Resources` live-resource segment is off.
238
200
 
239
201
  The Settings writer is deterministic and rewrites the supported saved subset
240
202
  only. If the existing file has parse errors or unknown action IDs, Settings
@@ -465,30 +427,11 @@ in-flight process decision, then retries proxy initialization with a bounded
465
427
  backoff. Projmux never automatically stops, kills, restarts, adopts, or enables
466
428
  remote control on the shared app server.
467
429
 
468
- The default `Codex` row in the provider picker launches immediately through the
430
+ The `Codex` row in the provider picker launches immediately through the
469
431
  canonical create route. It does not start or probe the app-server, call
470
432
  `model/list`, or add `--model` or `model_reasoning_effort`; the Codex process
471
- therefore keeps its own configured defaults.
472
-
473
- The separate `Codex advanced launch` action uses the readiness path to read
474
- every page of the current app-server `model/list`. Its second picker shows only
475
- visible models and their advertised reasoning efforts. The display also carries
476
- the advertised default, supported input modalities, and whether personality is
477
- supported; the boolean personality capability is not expanded into invented
478
- personality choices. The selected model and effort are launch-only CLI
479
- overrides (`--model` and `--config model_reasoning_effort=...`); Projmux never
480
- writes a Codex configuration file. Each normalized catalog is tied to its live
481
- connection and negotiated-version epoch. Projmux retains that connection from
482
- picker render through pre-create validation and refreshes `model/list` before
483
- building argv, so a disconnect or removed option invalidates the selection. If
484
- advanced discovery fails, is empty, or comes from an older Codex, that action
485
- reports the exact unavailable reason and creates nothing; the separate default
486
- `Codex` row remains available.
487
-
488
- Picker chrome and semantic annotations such as default, unspecified modality,
489
- and personality support use the Projmux message catalog. Model display names,
490
- effort identifiers, and advertised modality tags remain exact provider data and
491
- are not translated.
433
+ therefore keeps its own configured defaults. The picker has no per-launch model
434
+ or effort row.
492
435
 
493
436
  `projmux agent review` starts `review/start` only for a Running Codex Agent whose
494
437
  Registry Agent, owned Pane, activation generation, stored thread, and live Pane
@@ -582,6 +525,19 @@ with `--cwd-from pane`, and as one client message for a split started from the
582
525
  UI. A split is never refused for this reason. `--cwd` on `create agent` still
583
526
  names the Agent working directory outright and ignores this setting.
584
527
 
528
+ ## Enabled AI Providers
529
+
530
+ Disabled providers are a central policy, stored in
531
+ `${XDG_CONFIG_HOME:-$HOME/.config}/projmux/ai-enabled-agents`, that the CLI
532
+ honors as well as the UI: `create agent`, `create window --provider`, and
533
+ `agent resume` refuse a disabled provider, and the refusal names the command
534
+ that re-enables it.
535
+ `projmux config providers` lists every provider as `<id> enabled` or
536
+ `<id> disabled`; `projmux config providers --enable <id>` and
537
+ `--disable <id>` change one through the same writer as
538
+ `Settings > Global > AI > Enabled providers`. A missing file means every
539
+ provider is enabled; disabling every provider persists as none enabled.
540
+
585
541
  ## AI Resume Picker
586
542
 
587
543
  The Agent resume picker lists the most recent
@@ -591,7 +547,7 @@ the defaults are 30 rows and depth 0 (the current directory only).
591
547
 
592
548
  Preferred interactive path:
593
549
 
594
- - `Settings > AI Settings > Resume picker`
550
+ - `Settings > Global > AI > Agent Resume Picker` (`Picker limit`, `Scan depth`)
595
551
 
596
552
  Config paths (global and project both honored):
597
553
 
@@ -649,17 +605,8 @@ existence/mtime. They do not open SQLite content and do not treat `.db-wal`,
649
605
  latest-session floor rather than complete history. Missing/malformed cache,
650
606
  workspace-less metadata, and stale mappings degrade to legacy `history.jsonl`
651
607
  without changing the shared exact/depth/sort/cap behavior.
652
- Live hook/session-state resume metadata is a separate high-confidence lane and
653
- is not a disk-picker candidate. When a disk picker selection creates a pane,
654
- its source is persisted so Session State preview and doctor can report medium
655
- confidence for DB-validated cache sources or low confidence for legacy history.
656
-
657
- Session State saves the exact bound Codex session/thread id before considering
658
- discovery. An existing bound session id or persisted resume id is replayed
659
- without an app-server read. Only a thread-only candidate is validated with
660
- `thread/read` and `includeTurns=false`; this validation is probe-only and never
661
- starts the shared daemon. Failure retains the persisted id or uses the current
662
- rollout fallback, and a read response can never substitute a different id.
608
+ Live hook resume metadata is a separate high-confidence lane and is not a
609
+ disk-picker candidate.
663
610
 
664
611
  ## Release channel
665
612
 
@@ -703,7 +650,7 @@ installed; that install stays put until its stable line ships.
703
650
 
704
651
  | Variable | Purpose |
705
652
  | --- | --- |
706
- | `PROJMUX_PROJDIR` | Explicit primary project root. Accepts an OS-native PATH-style multi-value: the first non-empty entry is the primary root and later entries are prepended to managed-root discovery. The primary value is memoized to `~/.config/projmux/projdir`. |
653
+ | `PROJMUX_PROJDIR` | Explicit primary project root. Accepts an OS-native PATH-style multi-value: the first non-empty entry is the primary root and later entries are prepended to managed-root discovery. The primary value is memoized to `~/.config/projmux/projdir`. The legacy `PROJDIR` and `RP` env vars are no longer honored. |
707
654
  | `PROJMUX_MANAGED_ROOTS` | Search-root override. Uses the OS-native path-list separator and takes priority over the saved workdirs file and default weak probes. |
708
655
  | `TMUX_SESSIONIZER_ROOTS` | Legacy alias still honored at runtime for managed roots. |
709
656
  | `PROJMUX_LOCALE` | UI locale override. `auto` resumes detection; `en-US` and `ko-KR` pin supported locales. Unsupported tags fall back to `en-US` and surface a Settings warning. |
@@ -715,12 +662,12 @@ installed; that install stays put until its stable line ships.
715
662
  | `PROJMUX_DESKTOP_NOTIFY_MODE` | OS desktop notification mode override. `off` / `none` / `notify` (case insensitive). When set, this takes priority over every other resolution rung. The in-app notify queue is not affected. The retired `raise` / `auto-raise` / `autoraise` literals are still accepted and read as `notify`. |
716
663
  | `PROJMUX_DESKTOP_NOTIFY` | Legacy on/off override kept for backward compatibility. `on` maps to `notify`, `off` maps to `none`. Honored only when `PROJMUX_DESKTOP_NOTIFY_MODE` is unset. |
717
664
  | `PROJMUX_WSL_TOAST_ICON_DIR` | Directory used when copying the WSL toast icon into a Windows-readable path. |
718
- | `PROJMUX_USAGE_STATE_DIR` | Override directory for AI usage snapshots. Defaults to `<state>/projmux/usage`. Point this at a synced directory to share authoritative usage across machines. |
665
+ | `PROJMUX_USAGE_STATE_DIR` | Override directory for AI usage snapshots. Defaults to `<state>/projmux/usage`. Point this at a synced directory to share authoritative usage across machines. The value is used as given, with no `~` expansion. |
719
666
  | `PROJMUX_USAGE_DEBUG` | When non-empty, prints adapter errors from the `projmux internal status usage` renderer to stderr. |
720
667
  | `PROJMUX_USAGE_LIMITS_PATH` | Deprecated. Read but ignored; limits now come from upstream APIs and local Codex rollout state. |
721
- | `PROJMUX_SESSIONSTATE_AUTOSAVE` | Session snapshot autosave override for the global fallback. Values such as `off`, `false`, or `0` disable autosave for projects that inherit the global setting; explicit project auto-save `on`/`off` still takes precedence. |
722
- | `PROJMUX_SESSIONSTATE_DEBUG` | When non-empty, quiet autosave surfaces suppressed session-state errors to stderr. |
723
- | `PROJMUX_FOCUS_DEBUG` | When non-empty, `projmux focus` prints one telemetry line to stderr. |
668
+ | `PROJMUX_SESSIONSTATE_AUTOSAVE` | Ignored. Project snapshots and their auto-save were removed. |
669
+ | `PROJMUX_SESSIONSTATE_DEBUG` | Ignored. It only gated stderr for the removed quiet autosave. |
670
+ | `PROJMUX_FOCUS_DEBUG` | When non-empty, `projmux focus` prints one telemetry line to stderr with the target, session, window, pane, socket, client, source, and kind. |
724
671
  | `PROJMUX_INSTALLER` | Installer source hint used by update flows. npm installs set this automatically; advanced release installs can set `github-release`. |
725
672
  | `PROJMUX_RELEASE_CHANNEL` | Release channel the update judgment is made against, orthogonal to `PROJMUX_INSTALLER`. Only an exact `rc` opts in; unset, empty, and unrecognised values all mean the default `stable` channel, which never sees a prerelease. An rc install is answered with whichever of the stable and rc lines is newer, so it returns to stable as soon as that line ships. Read only until `[update] release_channel` exists; see [Release channel](#release-channel). |
726
673
  | `PROJMUX_SHELL_UPDATE_CHECK_TIMEOUT_MS` | Timeout in milliseconds for the best-effort release check attempted by `projmux shell` when the update cache is missing or stale. Invalid, zero, or negative values use the default. |
@@ -771,7 +718,7 @@ export PROJMUX_PROJDIR="/main/repos:/srv/work/repos"
771
718
  On Linux and macOS the separator is `:`. On Windows-style paths the separator
772
719
  is `;`.
773
720
 
774
- ## tmux Project Root Option
721
+ ## tmux Primary Discovery Root Option
775
722
 
776
723
  The switch command also reads this tmux option:
777
724
 
@@ -833,7 +780,8 @@ seconds window. Resolution priority is:
833
780
  `${XDG_CONFIG_HOME:-$HOME/.config}/projmux/ai-notify-dedupe-seconds`
834
781
  3. default `120`
835
782
 
836
- Settings exposes this at `Settings > Notifications > AI notification dedupe`.
783
+ Settings exposes this at
784
+ `Settings > Global > Notifications > Desktop delivery > Dedupe window`.
837
785
  The value is stored as integer seconds and applies only to AI desktop
838
786
  notification dispatch. The tmux bell fallback keeps its fixed 5 second
839
787
  dedupe window.
@@ -918,7 +866,7 @@ Settings press through the new row writes `desktop-notify-mode`, mirrors the
918
866
  new value into `@projmux_desktop_notify_mode` when tmux is live, and leaves the
919
867
  legacy key unused. No eager rewrite of tmux state.
920
868
 
921
- Toggle from Settings > Notifications > `Desktop notifications`. The
869
+ Choose it from `Settings > Global > Notifications > Desktop delivery > Delivery mode`. The
922
870
  Settings info row labels the effective source as `env`, `env (legacy)`,
923
871
  `setting`, `setting (legacy)`, or `default` so users see which rung of
924
872
  the cascade pinned the value. `projmux config apply` regenerates the live tmux
@@ -964,28 +912,35 @@ ${PROJMUX_USAGE_STATE_DIR:-${XDG_STATE_HOME:-$HOME/.local/state}/projmux/usage}/
964
912
  See [Usage tracking](usage-tracking.md) for adapter behavior, throttling, and
965
913
  failure handling.
966
914
 
967
- ## Session State
968
-
969
- `projmux shell` autosaves session snapshots from the app tmux status tick. The
970
- autosave command is quiet and debounced per session, and stores snapshots under
971
- `${XDG_STATE_HOME:-$HOME/.local/state}/projmux/sessions`.
972
-
973
- Global auto-save defaults to `off` on a fresh install. Project auto-save is an
974
- override with `inherit`, `on`, and `off`; `inherit` follows the global value,
975
- while `on` and `off` take precedence. Auto-save only updates the latest
976
- snapshot. Named snapshots are manual and are never updated by auto-save.
977
-
978
- With no saved preference, Project open from the Alt-1 sidebar shows a native
979
- `Start project` step with exactly `Continue project` and `Recreate Project`.
980
- Settings > Projects > Project Sidebar > Closed Project startup reports this as
981
- `Continue project / Recreate Project - default`. A saved `on` keeps the same explicit
982
- choice and reports `Continue project / Recreate Project - on - saved`. A saved `off`
983
- reports `Continue project - off - saved` and skips the picker: a registered root
984
- continues, while an unregistered root follows the existing Fresh adjudication.
985
- Resolving or cancelling the missing-file default never creates the preference
986
- file or changes saved bytes or mtime. `Recreate Project` confirms first, then atomically replaces the old Project graph
915
+ ## Project Startup
916
+
917
+ The Registry (`registry.json`) is the only saved Project state; see
918
+ [session-restore.md](session-restore.md). projmux keeps no separate Project
919
+ snapshot store. Nothing reads the former
920
+ `${XDG_STATE_HOME:-$HOME/.local/state}/projmux/sessions/*.json` snapshot
921
+ files; they are removed by `config apply`. The app tmux status tick saves
922
+ nothing: generated status lines carry no auto-save job, and the hidden
923
+ `internal tmux autosave-session-state` route that older generated configs
924
+ still call is a silent no-op that writes nothing and records no diagnostics.
925
+ The `sessionstate-autosave` and `sessionstate-autosave-interval` files and the
926
+ per-Project `sessionstate-projects/<session>/autosave` files are removed by
927
+ `config apply`, together with the `sessions/` and `sessionstate-projects/`
928
+ directories once they are empty. Any other entry there is kept, and listed
929
+ by the apply that removes the files.
930
+ `PROJMUX_SESSIONSTATE_AUTOSAVE` is still ignored without a warning.
931
+
932
+ Opening a registered closed Project from the Alt-1 sidebar shows a native
933
+ `Start project` step with exactly `Continue project` and
934
+ `Clear layout and open`. A root that is not a registered Project skips that
935
+ step and opens fresh, which registers it. There is no setting that skips the
936
+ step for a registered Project.
937
+ An explicit `Continue project` on a root that is not a registered Project
938
+ refuses with zero writes and points to `Clear layout and open`.
939
+ `Clear layout and open` clears only the saved Window and Agent layout: the
940
+ folder, its files, `.projmux/config.toml`, and trust stay. It confirms first,
941
+ then atomically replaces the old Project graph
987
942
  with a new Project UID and a new canonical Window/shell UID pair. Exactly one
988
- same-root Project claimant remains. Snapshot bytes, the root directory,
943
+ same-root Project claimant remains. The root directory,
989
944
  Git/worktree data, and the trust decision remain unchanged. Esc returns to
990
945
  Projects with zero writes. After
991
946
  the startup mode is selected, project automation trust is evaluated if needed.
@@ -997,62 +952,17 @@ Deny/cancel refreshes the original sidebar query/selection context with a
997
952
  visible status message. Existing sessions switch directly without a startup
998
953
  picker.
999
954
 
1000
- Default `projmux shell` no longer opens a startup picker or replays session-state
1001
- snapshots before attach. It still derives the default app session identity and
1002
- startup directory from the current project context when available; otherwise it
1003
- uses the `home` target and home directory. Snapshot restore is an explicit CLI
1004
- operation that requires both the source session and the exact target Project;
1005
- it is not a Project-startup choice.
1006
-
1007
- Settings > Session State is global settings only: global auto-save, auto-save
1008
- interval, and storage/retention policy. Settings > Project > Session State
1009
- is override/effective-focused: project identity, project auto-save
1010
- `inherit`/`on`/`off`, effective auto-save value/source, and snapshot save
1011
- actions. Snapshot inspection lives under `Projects > Sessions > State`, whose
1012
- overview shows latest/named snapshot status and the window -> pane read model
1013
- without immediate mutation.
1014
-
1015
- The saved global toggles live under
1016
- `${XDG_CONFIG_HOME:-$HOME/.config}/projmux/sessionstate-autosave`,
1017
- `${XDG_CONFIG_HOME:-$HOME/.config}/projmux/sessionstate-autosave-interval`, and
1018
- `${XDG_CONFIG_HOME:-$HOME/.config}/projmux/sidebar-startup-picker`. Project
1019
- auto-save overrides live under
1020
- `${XDG_CONFIG_HOME:-$HOME/.config}/projmux/sessionstate-projects/<session>/autosave`.
1021
- The environment variables above override the global files.
1022
- `sidebar-startup-picker` accepts the existing `on` and `off` bytes; absence is a
1023
- read-only effective `on - default`, not a migration or an implicit write.
1024
-
1025
- Manual snapshot actions are available from the CLI:
955
+ Default `projmux shell` does not open a startup picker before attach. It
956
+ derives the default app session identity and startup directory from the
957
+ current project context when available; otherwise it uses the `home` target
958
+ and home directory.
1026
959
 
1027
- ```sh
1028
- projmux get snapshots
1029
- projmux create snapshot
1030
- projmux delete snapshot [--session <name>]
1031
- projmux restore snapshot --session <snapshot-session> [--project <ref> | -p <ref>] --dry-run
1032
- projmux restore snapshot --session <snapshot-session> [--project <ref> | -p <ref>] --yes [--client <tmux-client>]
1033
- ```
960
+ The retired closed-Project startup setting's file under
961
+ `${XDG_CONFIG_HOME:-$HOME/.config}/projmux/` is not read, and `config apply`
962
+ removes it; see [Upgrading](upgrading.md#closed-project-startup-setting-removed).
1034
963
 
1035
- `status` prints the source label (`autosave`, `layout(<name>)`, or `fresh`), the
1036
- effective auto-save state, and a compact snapshot preview for the
1037
- target session. Older snapshots without a source field display as `autosave`.
1038
- `save` captures the current tmux session immediately and intentionally bypasses
1039
- the autosave debounce and disabled-autosave gate; it still requires a current
1040
- tmux session. `delete` removes the target snapshot without an interactive
1041
- confirmation. Restore treats the snapshot as desired-state input for one exact
1042
- closed Project, never as a global Registry replacement or tmux replay.
1043
- `--dry-run` prints scoped projection counts with zero writes. `--yes` commits
1044
- that target subtree atomically, runs the ordinary materializer, and performs an
1045
- explicit client handoff last when `--client` is present. Restore never modifies
1046
- or deletes the source snapshot.
1047
-
1048
- Interactive `projmux quit` also offers `Save Project snapshots and quit`. It
1049
- recaptures the latest snapshot for every live Registry-bound Project on the
1050
- exact app server, regardless of the global or Project auto-save toggle, and
1051
- stops the server only after all captures succeed. A partial failure keeps the
1052
- server running and keeps each successful atomic snapshot for inspection or
1053
- retry. Control/Home, ephemeral, unmanaged, conflicted, and sibling-server
1054
- sessions are never promoted into Project snapshots. `Quit without saving`,
1055
- `quit --yes`, and `quit --force` perform no snapshot inventory or store I/O.
964
+ Interactive `projmux quit` offers only the quit row and `Cancel`. Neither it
965
+ nor `quit --yes` / `quit --force` saves Project state.
1056
966
 
1057
967
  ## Decoration Mode
1058
968
 
@@ -1081,9 +991,8 @@ independent global presentation preferences:
1081
991
 
1082
992
  - `Notifications HUD > Visible`
1083
993
  - `Agent Usage HUD > Visible`
1084
- - `Agent Usage HUD > Claude|Codex|Antigravity > Visible`
1085
- - each provider's supported HUD windows (`Claude`/`Codex`: `5h`, `Weekly`;
1086
- `Antigravity`: `Weekly`)
994
+ - `Agent Usage HUD > Claude|Codex > Visible`
995
+ - each provider's supported HUD windows (`5h`, `Weekly`)
1087
996
 
1088
997
  The saved values are `on` or `off` in these files:
1089
998
 
@@ -1092,12 +1001,10 @@ The saved values are `on` or `off` in these files:
1092
1001
  ~/.config/projmux/statusbar-visibility-agent-usage-hud
1093
1002
  ~/.config/projmux/statusbar-visibility-agent-usage-provider-claude
1094
1003
  ~/.config/projmux/statusbar-visibility-agent-usage-provider-codex
1095
- ~/.config/projmux/statusbar-visibility-agent-usage-provider-antigravity
1096
1004
  ~/.config/projmux/statusbar-visibility-agent-usage-window-claude-5h
1097
1005
  ~/.config/projmux/statusbar-visibility-agent-usage-window-claude-weekly
1098
1006
  ~/.config/projmux/statusbar-visibility-agent-usage-window-codex-5h
1099
1007
  ~/.config/projmux/statusbar-visibility-agent-usage-window-codex-weekly
1100
- ~/.config/projmux/statusbar-visibility-agent-usage-window-antigravity-weekly
1101
1008
  ```
1102
1009
 
1103
1010
  Missing, empty, and invalid values resolve to `on` except the Codex `5h`
@@ -1111,8 +1018,9 @@ Parent visibility gates only the effective projection. Turning the overall HUD
1111
1018
  or a provider off does not rewrite its provider/window leaf files; turning the
1112
1019
  parent back on restores the saved child selection. Provider rows follow the
1113
1020
  usage-supported provider catalog. Window rows come only from the explicit HUD
1114
- capability map, so opaque quota buckets never create settings and Antigravity
1115
- never gains a fabricated `5h` row.
1021
+ capability map, so opaque quota buckets never create settings. Antigravity has
1022
+ no usage source; `statusbar-visibility-agent-usage-*-antigravity*` files left by
1023
+ older releases are ignored and never deleted.
1116
1024
 
1117
1025
  Visibility does not enable or disable either producer. Hiding Notifications HUD
1118
1026
  does not change the persistent queue, desktop delivery, or Notification
@@ -1196,12 +1104,27 @@ The CPU delta cache is internal state at
1196
1104
  CPU reference samples older than 30 seconds are ignored and replaced on the
1197
1105
  next refresh.
1198
1106
 
1107
+ ## Setting Layers
1108
+
1109
+ Settings live in two layers:
1110
+
1111
+ | Layer | Where | What |
1112
+ | --- | --- | --- |
1113
+ | central | `config.toml` central keys (`[ui] locale`, `[update]`, `[startup]`, `[hooks.*]`, `[env]`, `[ai] split_cwd_from`), `ai-enabled-agents`, `live-resources`, `projdir`, `workdirs`, `pins`, `tags`, `project-hooks`, `desktop-notify-mode`, `ai-notify-dedupe-seconds`, `ai-hook-actions.json`, `ai-semantic-policies.json`, `ai-hooks.d/`, `hooks/`, `personas/` | product behavior every surface shares |
1114
+ | TUI | `statusbar-visibility-*`, `statusbar-decoration*`, `ai-badge-style`, `runtime-diagnostics-visibility`, `keymap.toml`, `tmux-ai-split-mode`, `config.toml` `[theme]`, `[ui] native_keys`, `[ai] resume_*` | how the terminal looks and launches |
1115
+
1116
+ TUI is the front layer: only the front entry points (`settings`, `shell`,
1117
+ `switch`, `config render|apply|edit` and the internal namespace) read it. Every
1118
+ other public route reads the central layer alone, except that a route opening a
1119
+ picker may read that picker's theme and keys to paint it.
1120
+
1121
+
1199
1122
  ## Rare Tunables
1200
1123
 
1201
1124
  These are intended for debugging or local policy, not routine setup:
1202
1125
 
1203
1126
  | Variable | Purpose |
1204
1127
  | --- | --- |
1205
- | `PROJMUX_TMUX_NOTIFY_DEDUPE_SECONDS` | Override the Settings/default collapse window for duplicate AI desktop notifications keyed on the pane-local AI notification key. |
1128
+ | `PROJMUX_TMUX_NOTIFY_DEDUPE_SECONDS` | Override the Settings/default collapse window for duplicate AI desktop notifications keyed on the pane-local AI notification key. The Settings value and default apply only when this env is unset or not a positive integer. |
1206
1129
  | `PROJMUX_CODEX_TITLE_WATCH_INTERVAL` | Title-watch loop pacing for Codex panes. |
1207
1130
  | `PROJMUX_CODEX_REPLY_SETTLE_LOOPS` | Reply-detection settle-loop pacing for Codex panes. |
@@ -110,7 +110,6 @@ Files:
110
110
  - `internal/app/*help*`
111
111
  - `docs/cli.md`
112
112
  - `docs/cli-guide.md`
113
- - `docs/agent-workflow.md`
114
113
 
115
114
  Classification:
116
115
 
@@ -122,6 +121,17 @@ Classification:
122
121
  | Command syntax | `projmux shell`, `make test`, `gh pr create` | `literal` | Preserve exactly. |
123
122
  | Version strings and release tags | `vX.Y.Z`, git SHA, installer source | `data` | Preserve source content. |
124
123
 
124
+ ### Install replacement failures
125
+
126
+ `internal/app/install_replacement*.go` adds the failure explanation, remaining
127
+ target heading, impact, and recovery under `install.replacement.*` catalog keys
128
+ with `en-US` and `ko-KR` entries (`translate`). The pre-existing summary and
129
+ successful/pending install output remain unchanged. Role/refusal tokens,
130
+ `pid`, `revision`, and `unknown` are `literal`; observed pids and revisions are
131
+ `data`, preserved only in the terminal diagnostic. `Codex` and `make install`
132
+ remain literal inside the translated guidance. No process identity is added to
133
+ the persisted outcome or residue ledger.
134
+
125
135
  ## Literal Preservation Rules
126
136
 
127
137
  Do not translate these families: