feat(logging)!: make C5 session logging opt-in

Session logging is the one opinionated category that writes a persistent
record of terminal output to disk, and those logs can contain secrets.
Silent-by-default is the wrong posture for it, so C5 now defaults to off:
__fish_config_op_logging must be set to an explicit truthy value to enable
capture, and the master switch cannot enable it on its own.

Implemented as a single special case in __fish_config_op_enabled, so all
five capture components, the sentinel file, the paru/yay wrappers, the
Kitty watcher, and the config-settings TUI pick it up with no other code
changes. The existing startup sync in conf.d/logging-events.fish
reconciles the sentinel and removes the generated wrappers on the first
shell after upgrading.

BREAKING CHANGE: users relying on the previous default must now run
`set -U __fish_config_op_logging on`. Existing logs in ~/.terminal_history
are left untouched.
This commit is contained in:
2026-07-27 19:17:05 -04:00
parent d085d5c597
commit f2874bf890
9 changed files with 172 additions and 88 deletions
+36 -12
View File
@@ -62,12 +62,18 @@ Every opinionated piece of this config is active by default but can be
switched off through six category opt-out variables, each evaluated via
__fish_variable_check. Set a variable to any falsy value (0, false, no,
off, n) to disable its category; erase it or set a truthy value (1, true,
yes, on, y) to re-enable. Unset means enabled.
yes, on, y) to re-enable. Unset means enabled — except for C5 logging, which
is opt-in (see below).
An explicit per-category truthy value takes precedence over the master
switch: setting __fish_config_opinionated=0 disables all unset categories,
but a category with an explicit truthy value remains enabled regardless.
C5 (logging) is the one exception to "unset means enabled". Because it
writes terminal output to disk, it is opt-in: unset means disabled, and the
master switch cannot enable it. Only an explicit truthy value turns logging
on.
Variable Disables
────────────────────────────────────────
__fish_config_op_aliases Command shadows and flag injection:
@@ -92,10 +98,11 @@ but a category with an explicit truthy value remains enabled regardless.
WezTerm window abbreviations, done
notifications, spwin/tab/split,
hist, logs, upgrade, WakaTime
__fish_config_op_logging Logging & capture: scrollback
capture on exit, paru/yay AUR log
wrappers, Kitty watcher capture;
sentinel file coordinates
__fish_config_op_logging Logging & capture (OPT-IN — this one
is off unless explicitly enabled):
scrollback capture on exit, paru/yay
AUR log wrappers, Kitty watcher
capture; sentinel file coordinates
cross-process state
__fish_config_op_greeting Greeting & first-run UI: per-session
fish_greeting override (defines empty
@@ -109,10 +116,13 @@ Examples:
# Disable command shadows only (rm becomes plain rm again):
set -U __fish_config_op_aliases off
# Turn session logging on (opt-in; off until you do this):
set -U __fish_config_op_logging on
# Full minimal mode — disable all six categories at once:
set -U __fish_config_opinionated 0
# Re-enable everything:
# Re-enable everything (except C5 logging, which stays opt-in):
set -Ue __fish_config_opinionated
# Minimal mode but keep the greeting:
@@ -266,8 +276,16 @@ silently failing.
#### C5 — Logging and Capture
Five components capture shell output to disk. Disabling
__fish_config_op_logging skips all capture and removes the logging wrappers.
Five components capture shell output to disk. Unlike every other category,
C5 is opt-in: it stays off until __fish_config_op_logging is set to an
explicit truthy value, and a truthy master switch does not enable it. While
it is off, all capture is skipped and the logging wrappers are removed.
# Turn it on (persistently, in every shell):
set -U __fish_config_op_logging on
# Turn it back off:
set -U __fish_config_op_logging off # or: set -Ue __fish_config_op_logging
Component What it captures
───────────────────────────────────────────────────────────────────────────
@@ -324,8 +342,10 @@ The Kitty watcher is managed by the kitty-logging command: it symlinks the
watcher (fish-config-watcher.py) into the Kitty config directory and wires it
into kitty.conf via a managed block. Inside Kitty, a non-blocking
per-session reminder points first-time users at `kitty-logging install` until
they install or run `kitty-logging dismiss`. Install affects new Kitty windows
only; runtime disable is still handled by the .logging_disabled sentinel.
they install or run `kitty-logging dismiss`; the reminder is itself gated on
C5, so it stays silent until you enable logging. Install affects new Kitty
windows only; runtime disable is still handled by the .logging_disabled
sentinel.
Logging coordination via sentinel file
@@ -334,7 +354,11 @@ out-of-process components (the Kitty watcher and all running shells):
~/.config/fish/.logging_disabled
Disabling __fish_config_op_logging:
Because C5 is off by default, the sentinel is present on a fresh install —
the startup sync in conf.d/logging-events.fish reconciles it on every shell
start, so it appears without any action on your part.
Disabling __fish_config_op_logging (or leaving it unset):
1. Creates the sentinel immediately in every open shell.
2. Removes ~/.local/bin/paru and ~/.local/bin/yay logging wrappers;
bare /usr/bin/paru and /usr/bin/yay are used instead.
@@ -343,7 +367,7 @@ Disabling __fish_config_op_logging:
4. smart_exit stops saving scrollback logs.
5. Stops tmux pipe-pane capture in every open fish shell inside tmux.
Re-enabling __fish_config_op_logging:
Enabling __fish_config_op_logging:
1. Removes the sentinel in every open shell.
2. Regenerates paru/yay logging wrappers in ~/.local/bin/.
3. Kitty watcher resumes capture on the next session exit.