# Configuration contract [`PRODUCT.md`](PRODUCT.md) incorporates this document as normative version 1 behavior. ## Location and precedence The default file is `termux-janitor/config.json` below the XDG configuration directory. A nonempty absolute `XDG_CONFIG_HOME` selects that directory; an empty or relative value is ignored and falls back to `$HOME/.config`. State and logs use the same rule for `XDG_STATE_HOME`, falling back to `$HOME/.local/state`. Missing `HOME` when a fallback is required is a startup error. An explicit `--config PATH` replaces default discovery. A missing, inaccessible, non-regular, or oversized explicit file is a startup error. A missing default file means compiled defaults. Precedence is CLI, supported environment policy, configuration, then compiled defaults. `--no-color` overrides all configuration; otherwise nonempty `NO_COLOR` disables color. ## Encoding and grammar Version 1 configuration is one strict UTF-8 JSON object no larger than 1 MiB. The required top-level key is `schema_version` with integer value `1`. JSON comments, trailing commas, duplicate object keys, unknown keys, invalid UTF-8, non-integer numbers, and non-finite numbers are startup errors. An empty array is valid; an empty string is valid only where stated. Path strings are UTF-8 configuration input, not filesystem identity. Relative configured paths resolve against the directory containing the selected configuration file. Resolved paths are made absolute lexically by removing `.` and processing `..` without crossing the filesystem root. Symlinks are not generally resolved during lexical normalization. The shared-storage entry-point exception remains defined by `PRODUCT.md` section 4.1. Opened roots are deduplicated only by trusted runtime identity. ## Schema ```json { "schema_version": 1, "scan_roots": [], "workspace_roots": [], "document_roots": [], "exclusions": [], "manual_only_rules": [], "thresholds": { "large_file_bytes": 0, "large_directory_bytes": 0, "old_seconds": 0, "stale_temporary_seconds": 0, "stale_trash_seconds": 0, "old_rotated_log_seconds": 0 }, "adapters": {}, "network": { "offline": false, "disabled_adapters": [] }, "display": { "color": true, "ascii": false } } ``` Omitted optional keys use compiled defaults. Threshold values in the schema example are placeholders; canonical defaults are stated once in `spec/model/thresholds.zon` and projected in [PRODUCT ยง6.1](PRODUCT.md#61-default-thresholds). An explicitly empty root array disables that root class and remains visible in the scope summary. Strings in root and exclusion arrays must be nonempty. A manual-only rule contains exactly one of `root`, `glob`, or `suffix`, plus an optional nonempty `reason`. Adapter object keys are compiled adapter identifiers and values are booleans. Unknown adapter identifiers are errors rather than silently ignored misspellings. Thresholds are unsigned 64-bit integers in the units named by each key. Zero is valid and means the threshold matches every known nonnegative value. Overflow, negative values, fractions, and values exceeding signed 63-bit seconds are errors. The large-directory threshold must be at least the large-file threshold. Safety capacities in [`LIMITS.md`](LIMITS.md) are compile-time constants and are not configurable. Configuration cannot make a default manual-only class eligible for recommendation or bulk selection. ## Exclusions Exclusion strings are absolute or configuration-relative lexical path prefixes. A prefix matches only a complete path-component boundary. The root itself remains represented in the scope summary even when all descendants are excluded. Exclusions apply after root initialization and before descendant admission. They never convert excluded objects into package or direct filesystem actions through another alias. ## Errors and diagnostics These are safety-relevant startup errors: - invalid syntax, encoding, schema version, type, range, relationship, or duplicate key; - unknown top-level, nested, adapter, or rule key; - path, root, exclusion, or rule capacity exhaustion; - an explicit configuration file that is missing, inaccessible, non-regular, or oversized; - inability to establish required XDG or explicit path bases; - a configuration value that attempts to weaken mandatory manual-only or mutation rules. Diagnostics identify the file, bounded JSON path, and reason without echoing unrelated content. No scan, terminal initialization, adapter process, network request, or run-log creation occurs after a configuration startup error.