Verified an agy audit of every bare rm call (the trash-routing C1
shadow) by hand rather than trusting its report. Confirmed correct:
scrub.fish's custom_rm strategy and logs.fish's Ctrl-D delete both
deliberately want trash for a real, user-facing deletion.
Confirmed and fixed three cases where a function's own throwaway
scratch file was going to the user's trash instead of being wiped:
fc.fish's edited-command tmpfile, dng2avif.fish's intermediate PNM
(inconsistent with its own failure-path cleanup two lines up, which
already used -f), and _scrollback_prune_junk.fish's junk log files
(its sibling _prune_terminal_logs.fish already documents this exact
pitfall in its header).
Also went further than the report and classified every bypasses-shadow(rm)
caller found by grep that had never been audited at all:
config-settings.fish and edit.fish (own scratch cleanup, no destructive
data at stake) and key-crypt.fish (--remove deletes the user's real
input file after encryption, genuinely destructive, already documented
in its own header as 'not a secure wipe'). Corrected scrub.fish's tag,
which was missing uses-shadow(rm) for its deliberate trash-routing
branch alongside the bypass branch it already had tagged.
Added a note to the schema doc: rm's flag-based fallback lives inside
the shadow itself, so a bare rm -f/rm -rf call is not the caller
bypassing anything -- only an explicit command rm/builtin rm earns
the tag. This is why dng2avif.fish's fix needed no CLASSIFICATION
change: it already used rm -f, which was never actually the bug --
the missing -f on line 122 was.
Audits every function's interaction with the C1-shadowed commands
(uses-shadow/bypasses-shadow) and general hazards (destructive,
network, blocking-prompt) per the CLASSIFICATION schema.
Delegated the initial mechanical sweep to agy, then reviewed every
file by hand: fixed a systemic double-blank-comment-line formatting
bug from the delegate pass, and corrected several judgment errors
found on review -- three false blocking-prompt tags where a fish
'read' was consuming piped input rather than waiting on a terminal
(open-url.fish, sbver.fish, play-media.fish, now untagged entirely),
a blocking-prompt tag on mkrep.fish despite its documented --yes
escape hatch, an untagged read in jobrunner.fish's own baseless
blocking-prompt claim (removed, along with a destructive tag on
cleanup of its own mktemp output -- the schema explicitly excludes
that), the same own-output-cleanup false positive on
_zellij_dump_log.fish's destructive tag, an interactive fzf-gated
confirmation on logs.fish and replay.fish's piped read misread the
same way as the first three, and a uses-shadow(mkdir) on mkcd.fish
that actually belongs to the _fish_mkdir_p helper it delegates to,
not to mkcd itself.
__fish_palette's c_cmd/c_flag/c_arg/c_dim now read fish's own highlighter
variables (fish_color_command/option/param/autosuggestion) when set, and
c_head reads the pager's fish_pager_color_prefix, so --help text matches
whatever the user's actual theme renders at the prompt instead of a fixed
guess at it. Each role keeps its previous static value as a fallback
(e.g. a --no-config script, or the theme variable being unset or empty).
Routes __fish_help_header's title/section colors and config-help's,
gi's, and git-clean's own hand-rolled --help blocks through the palette
instead of their hardcoded set_color calls, which fixes the
--help-vs-actual-prompt color mismatch across most of the config's
functions in one place (__fish_help_header backs the majority of
user-facing --help output).
Also fixes role mismatches found along the way: several already-palette
functions (dockup, fish-deps, pkg, play-media, dng2avif) were coloring
their <placeholder>/[bracket] argument text with c_dim instead of c_arg,
and scrub's "Aggressive Targets:" heading was still a hardcoded
set_color call sitting next to an otherwise-converted help block.
44 duplicated declarations replaced by 8 calls. Output strings untouched.
fish-deps, upgrade and wake-lock have no --help path and are deliberately
NOT added to the harness case list -- upgrade and wake-lock have side
effects, and runtime coverage is not worth mutating state during tests.
They are covered by --structural, which proves mechanically that no
rendering line changed.
Add the established c_head/c_cmd/c_flag/c_dim/c_arg color scheme to
--help (or usage-on-error) output in play-media and 13 other functions
that lacked it or used an ad hoc scheme: bkg, detach, replay, p, y,
spark, wake-lock, open-url, repo-open, dng2avif, dockup, fish-deps
(__fish_deps_help), and scrub.
Also tweak the standard itself:
- c_cmd now uses plain `set_color --bold` instead of `--bold white`,
so the command name adapts to the terminal's foreground instead of
forcing white text that washes out on light-background themes.
Applied across all functions already using the pattern.
- jobrunner's reset variable renamed from c_rst to c_reset to match
the naming used everywhere else.
A missing trailing backslash after the Thumbs.db:encryptable pattern
terminated the `set -l aggressive_patterns` array early. The AI-tool
patterns (.gemini*, .claude*, .antigravity*, .remember*) were then
executed as a bogus command instead of being appended to the array,
so scrub -a never actually purged them, and every scrub invocation
printed a spurious "Unknown command" error.
RETURNS previously conflated fish's $status exit code with genuine
stdout/printed output, e.g. rm listing "0/1" as if they were print
values rather than exit codes. Rename RETURNS to EXIT STATUS across
all 83 documented functions, and reintroduce RETURNS as a distinct
label reserved for the 15 functions that actually print to stdout.
Update build-manual.py's ENTRY_HEADS to render Exit Status before
Returns, manualtools.py's SECTIONS constant, and AGENTS.md's label
order and label-usage guidance to match. Add two verify-manual.py
regression tests: EXIT STATUS bodies must never contain stray
stdout/printed language, and Returns: must always render after
Exit Status: when both are present. Regenerate docs/fish-config.md.
Word-level diff of every manual entry against its generated counterpart
surfaced 546 tokens present in the manual and absent from the header —
losses reconcile.py missed, because it compared description length and
these headers are longer overall thanks to ARGUMENTS/RETURNS.
Merged the substantive ones (546 -> 202 residual tokens, the remainder
being synonym drift). Notable real fixes:
- git-clean: -f/--force was missing from ARGUMENTS entirely
- pkg: per-package-manager query table
- qc: cli-role rationale, role paths, --role passthrough
- config-help: site URL, xdg-open, man page path, case-insensitivity
- agents-init: idempotency, .gitignore paths, upstream pull, wrapper callers
- smart_exit: exit-builtin wiring note, $SCROLLBACK_HISTORY_DIR
The manual's claim that claude/agy pass `agents-init --agents` is stale;
both pass `--quiet` (full setup). Header wins, manual dropped.
Records each documented function's manual category in its own header, so
Section 5 can later be generated from source instead of hand-maintained
alongside it. Values reproduce the current grouping in
docs/manual/05-functions/ exactly; no documentation changes meaning here.
Four functions are skipped because they have no header at all yet
(branch, fc, gitup, sudo-toggle); they get one in the merge that follows.
Replace all ad-hoc inline comments between license headers and function
declarations with consistent SYNOPSIS / DESCRIPTION / ARGUMENTS / RETURNS /
EXAMPLE blocks across all 99 project-owned functions/ files. No executable
logic, variable names, or exit codes were modified.
Completes Task #6 from AGENTS.md (Retroactive Function Documentation
Standardization).
Adds a robust `scrub` utility function to safely and recursively clean
up common OS metadata, development caches, editor artifacts, and slicer
cruft using `fd`.
Features:
- Hierarchical deletion fallback system: checks for a custom `rm`
function, falls back to `trashy` (trash put), then `trash-cli`,
and drops to standard `rm -rf` as a final measure.
- Safe `-d/--dry-run` modes to preview matched targets.
- An advanced `-a/--aggressive` mode for wiping heavy project caches
(node_modules), local logs, and custom AI runtime config histories.
- Full flag validation and colorized help menus.