Configuration and Effective Policy
OptiFlow resolves configuration once, before any domain command runs. The resolver captures the initial working directory and recognized environment, selects files, reads each selected file into one stable in-memory snapshot, merges typed leaves, validates the result, materializes every default, and calculates two semantic identities.
Configuration is always read-only. Invalid configuration prevents scanning, probing, reporting, planning, and state creation.
Configuration document
The first public TOML contract is optiflow.config.v1. Every file must declare
the schema:
schema = "optiflow.config.v1"
[output]
format = "json"
[state]
directory = "./.optiflow-state"
[scan]
follow_symlinks = false
include_hidden = false
cross_filesystems = false
probe_media = true
The checked-in structural contract is
schemas/config-v1.schema.json. Missing or
unknown schemas, unknown sections or keys, duplicate keys, invalid scalar
types, and empty state paths are errors. OptiFlow does not preserve unknown
keys in an extension map.
Source selection and precedence
Automatic resolution uses this complete order:
compiled defaults
< user configuration
< nearest project configuration
< recognized environment variables
< explicit CLI arguments
The optional user file is:
- Linux:
$XDG_CONFIG_HOME/optiflow/optiflow.toml, or~/.config/optiflow/optiflow.tomlwhenXDG_CONFIG_HOMEis unset. - macOS:
~/Library/Application Support/optiflow/optiflow.toml.
Project discovery starts at the initial working directory, walks its ancestors,
and selects only the nearest optiflow.toml. Scan input roots are never used as
independent discovery anchors.
--config <FILE> selects exactly one file and suppresses automatic user and
project discovery. OPTIFLOW_CONFIG does the same when --config is absent;
the CLI selector wins when both exist. --no-config suppresses all file
loading, including OPTIFLOW_CONFIG, but recognized setting environment
variables and CLI overrides still apply. --config and --no-config together
return invalid_input.
Missing automatic files are normal. A discovered file that exists but is invalid, unreadable, not regular, or a symbolic link blocks execution. A missing explicitly selected file is also invalid input.
Supported settings
| Setting | Type and values | Default | File | Environment | CLI | Category | Evidence fingerprint |
|---|---|---|---|---|---|---|---|
output.format |
human, json |
human |
Yes | OPTIFLOW_OUTPUT_FORMAT |
--output-format, --json |
Presentation | No |
state.directory |
non-empty native path | platform state directory | Yes | OPTIFLOW_STATE_DIRECTORY |
--state-directory |
Operational | No |
scan.follow_symlinks |
boolean | false |
Yes | OPTIFLOW_FOLLOW_SYMLINKS |
--follow-symlinks, --no-follow-symlinks |
Evidence | Yes |
scan.include_hidden |
boolean | false |
Yes | OPTIFLOW_INCLUDE_HIDDEN |
--include-hidden, --exclude-hidden |
Evidence | Yes |
scan.cross_filesystems |
boolean | false |
Yes | OPTIFLOW_CROSS_FILESYSTEMS |
--cross-filesystems, --stay-on-filesystem |
Evidence | Yes |
scan.probe_media |
boolean | true |
Yes | OPTIFLOW_PROBE_MEDIA |
--probe, --no-probe |
Evidence | Yes |
Environment booleans accept exactly true or false, lower case. Output format
accepts exactly human or json. An empty recognized environment value is not
treated as absent. Unknown OPTIFLOW_ variables do not automatically become
configuration keys.
Positional scan roots remain CLI-only. Worker counts, color preferences, progress toggles, arbitrary executable paths or argument arrays, retry bounds, exit codes, diagnostic wording, and mutation authorization are not public configuration keys in v1.
Path rules
- File-relative paths resolve from the declaring configuration file's directory.
- CLI-relative paths resolve from the captured initial working directory.
- Environment-relative paths resolve from the captured initial working directory.
- Compiled defaults use the platform-directory abstraction.
Paths are not canonicalized as proof of identity. OptiFlow performs no ~
expansion, variable interpolation, command substitution, wildcard expansion,
or shell execution. Native paths remain lossless in structured source records;
terminal display escapes control characters.
Inspection commands
All inspection commands use the same resolver as scan, report, and plan:
optiflow config validate
optiflow config show
optiflow config explain output.format
optiflow config explain scan.include_hidden
optiflow --config "./optiflow.toml" config validate
optiflow --no-config config show
validate checks selected sources and the generated effective policy without
creating state. show emits the complete policy, source records, provenance,
shadowed values, and fingerprints. explain accepts a documented file-style
path or canonical policy path and reports the winning value, lower-precedence
values, ownership category, evidence impact, locked status, constraints,
environment name, and CLI arguments. Unknown paths return invalid_input.
Human results use stdout and escaped diagnostics use stderr. JSON results use
one optiflow.command-result.v1 document and preserve the actual exit status.
Effective policy and fingerprints
Configuration documents contain partial declarations. Runtime code receives a
fully populated optiflow.effective-policy.v1 object validated by
schemas/effective-policy-v1.schema.json.
It separates:
- evidence policy: eligibility, traversal, probing, exact grouping, stability, exclusions, and the bounded observation-attempt contract;
- operational policy: the concrete state directory;
- presentation policy: the concrete output format;
- locked safety invariants;
- per-leaf provenance;
- semantic fingerprints.
The blake3-256 effective-configuration digest covers normalized evidence,
operational, presentation, and safety values. The separate evidence-policy
fingerprint covers evidence values and evidence-relevant locked invariants.
Neither includes provenance, shadow traces, diagnostics, timestamps, process
identifiers, unrelated environment state, or secrets. Presentation changes can
change the full digest but cannot change the evidence fingerprint. Equal policy
values reached through different sources have equal fingerprints.
Canonicalization uses the deterministic serialized field order of the typed identity structures and the lossless tagged native-path representation. A generated or loaded policy whose declared digests do not match its normalized contents fails integrity validation. Fingerprints are provenance identifiers, never mutation authorization.
Locked safety invariants
The effective policy explicitly records that:
- source mutation is disabled;
- apply behavior is disabled;
- shell execution is disabled;
- generated artifacts must be schema-validated;
- artifact commits must remain atomic;
- exact grouping requires current stable evidence.
These values cannot be set in TOML, environment variables, or CLI arguments.
[safety] and [safety_invariants] attempts fail with
configuration_locked_invariant. Existing explicit traversal flags remain
evidence policy; their final values are recorded and fingerprinted.
Historical policy
Every new scan publishes effective-policy.json, run.json, and report.json
as one marker-sealed set in the run artifact directory. The existing v3 run
field artifact_directory remains the immutable location reference. Historical
v1-v4 contracts and database migrations remain unchanged. Run and plan v5 and
historical report v5 use artifact-set identity bindings. Report v6 retains that
binding while adding the required media-profile evidence collection.
Report and plan commands validate and expose the source policy artifact. A
different current evidence policy produces the informational
source_policy_differs diagnostic without overwriting historical evidence.
Older runs without the sidecar remain reviewable and report
historical_policy_unknown; OptiFlow never reconstructs missing historical
policy from current defaults. Future current-evidence or apply operations must
revalidate independently.
Compatibility and security
- Unknown configuration schema identifiers and unknown keys fail closed.
- Existing keys and enum values do not silently change meaning.
- User files are never rewritten or automatically migrated.
- Artifact, effective-policy, configuration, and binary versions are distinct.
- A future configuration schema transition or
config migratecommand is explicit work, not an implicit rewrite. - Files are captured into memory with before/after identity, length, and modification checks and at most two bounded read attempts.
- Configuration never executes a shell, expands commands or globs, stores raw environment snapshots, persists secrets, enables mutation, or bypasses validation and atomic commit.