xff v0.3.7

xff - Configuration System Design

Detailed spec for the layered config system. Refines design.md
§"Security & safety (review #2)" and §"Flag / toggle conventions"; where the
two differ, this document is authoritative for config specifically.
Status: Draft · 2026-06-21 · Org: MBO Works

SUPERSEDED IN PART - the project layer was dropped (Option B, 2026-07-06).
xff has no auto-discovered project config: no per-directory .xffrc, no ancestor
cascade, no subtree scoping, and no --project-config flag. Config comes from three
tiers only
: system (/etc/xff.ini, root-owned), user
(~/.config/xff/config), and an explicit --xffrc=FILE (naming the file is the
consent to load it). Per-directory ignore rules (.gitignore / .xffignore) are an
ignore concern, not config, and are unaffected. Every mention below of the "project"
layer, the .xffrc cascade, or --project-config is historical - read it as removed.
The --xffrc arming restriction (a named file cannot self-arm -exec/-delete;
--allow-exec arms from the CLI/user/system tiers only) is the remaining live rule; see
TODO.md "Config: drop the project .xffrc layer".

Purpose

A find-compatible tool that can run -exec/-capture is, by construction, a
code-execution engine. A config system for it must make the common case
convenient without ever letting an untrusted, repo-local file silently run
commands. The design goal, in the user's words: "by default there is no
security issue."

The system has four layers with a strict trust order, and a single
root-owned policy that decides how much each lower (less-trusted) layer may
do. The policy is the keystone: absence of an admin policy yields the safe
default, never an unsafe one.

The four layers

Lowest → highest precedence; each overrides values set by an earlier one, and
the CLI always wins (typing a flag is explicit consent).

# Layer Owner / trust Format
1 built-in the binary (none)
2 system root - the trust anchor INI (structured policy)
3 user the user - trusted as-is .xffrc grammar
4 project repo - untrusted .xffrc grammar
5 CLI explicit user consent flags

(Locations are detailed under Discovery below.)

Discovery & loading

Formats

System policy - /etc/xff.ini (structured)

INI: a [defaults] section of plain flag lines, and a [policy] section of
per-layer, per-flag allow/deny lists. Structured because a policy wants
typed validation and must be unambiguous.

[defaults]
--color = auto

[policy]
# Per-flag overrides on top of the built-in safety classification.
# Built-in default already denies @sensitive/@destructive at the project layer.
project.allow = --sort, --color, --format       # redundant with built-ins; explicit is fine
project.deny  = --threads                        # tighten: forbid even a "safe" flag
user.allow    = @sensitive                       # user may arm -exec/-capture from ~/.config

.xffrc (user & project) - bazel-rc grammar

Line-oriented flag bundles ("what you can type, you can save", design.md
§125), each optionally prefixed by a two-axis selector base:config::

# <base>:<config>:  <flags…>     base ∈ {common, <named-config>, ∅(=common)}
common:        --color=auto                 # every run, always (your defaults)
myproj:        --feature=long-paths         # only when --config=myproj is active
xff:myproj:    --feature=trace --threads=1  # only when the xff style AND --config=myproj

Capability policy (per-flag, safe-by-default)

The user-chosen model is per-flag allow/deny, anchored to the registry's
built-in safety classification so the safe default needs no admin file:

Class Project User System
safe allow allow allow
sensitive deny allow allow
destructive deny allow allow

safe = output / traversal / matching (--color, --sort, -name); sensitive = the exec family (-exec, -execdir, -ok, -okdir, -capture, -capturedir); destructive = -delete and future built-in mutators.

Enforcement & self-documentation

CLI selectors

Worked examples

# Hostile repo → a per-directory .xffrc is OFF by default: nothing from ./.xffrc applies.
cd ./untrusted && xff .
#   ./.xffrc present → ignored; "a per-directory .xffrc was found but ignored" on stderr
#   (silence with --project-config=off)

# Opt in to a per-directory .xffrc. Even then it is safe-subset only: sensitive/destructive
# lines and style selectors are never honored from a project file (those need user/system config).
cd ./trusted && xff --project-config=on .
#   ./.xffrc: common: --color=never     → applied (safe)
#   ./.xffrc: common: -exec rm {} ;      → dropped + warned (sensitive, project-denied)

# Personal exec recipe from your own (user) config → trusted, applied with no opt-in.
#   ~/.config/xff/config: xff:thumbs: -capture:W=… convert {} … ;
xff --config=thumbs ~/Pictures            # armed: user layer allows @sensitive

# CI host loosens the project layer for a vetted pipeline (opt-in + policy allow).
#   /etc/xff.ini: [policy] project.allow = -capture
cd $CI_WORKSPACE && xff --project-config=on .   # repo .xffrc -capture now armed

# Strict drop-in via name.
ln -s xff find && ./find . -println        # → error: -println unknown (find style)

Implementation roadmap (small PRs)

Open questions

Prior art