Skip to content

Latest commit

 

History

History
723 lines (596 loc) · 51.1 KB

TESTING.md

File metadata and controls

723 lines (596 loc) · 51.1 KB

atomwrite Testing Guide

Leia em Português

Objectives

  • Spend fewer tokens: one NDJSON object per call replaces the shell pipeline, and commands --brief answers in 5 020 bytes where the full tree costs 67 492
  • Lower the financial cost, because the bill follows the tokens and the round trips, and one call replaces the several shell calls a file task needs
  • Reduce errors with an atomic write and a BLAKE3 checksum on every response, so a stale or partial result is caught instead of assumed
  • Reduce hallucinations with a type discriminator, a closed schema per verb and an exit code that names the failure
  • Reduce the time spent on each task, because the read, the search and the write run in one process instead of a chain of shell tools
  • Reduce latency with local execution and no network on the file path, measured at medians of 5.6 ms on read and 6.7 ms on write for small files
  • Multiply the speed of operations with batch, edit-loop, replace, case, transform and codemod settling many files in one call
  • Cut the lead time between the request and the verified result, because the response already carries the checksum, the target_resolved and the next step
  • Make the agent faster, more effective and more assertive, since the exit code, the code and the suggestion say what to do next without a retry guess

Current Release Line: v0.1.38

  • The full suite exited 0 on 2026-11-04 with cargo test --no-fail-fast, and the run printed 134 test result: ok blocks
  • The failure envelope schema requires ok, code and exit, so a suite that asserted error: true reads .ok == false plus .code instead
  • No test was added for the 0.1.38 fixes and the existing suites were updated in place, because a real run on the installed binary is the proof and a new mock is not
  • The 0.1.38 binary was executed on 2026-11-04 and answered agent-surface with 47 tools, 42 exit codes and 34 distinct numbers, and config list with 43 keys
  • The 47 examples of the smoke test below were run against the 0.1.38 binary on 2026-11-04, and 46 exited 0 while watch exited 78

What's New in v0.1.37

  • Full CLI surface under test policy: 47 subcommands (CANONICAL_SUBCOMMAND_COUNT): agent-surface, apply, backup, batch, calc, case, codemod, commands, completions, config, copy, count, del, delete, diff, doctor, edit, edit-loop, extract, extract-artifact, get, hash, list, locale, move, outline, prune-backups, query, read, recipe, regex, replace, rollback, scope, scratch, search, semantic-merge, semantic-search, set, sparse, stat, transform, verify, wal-heal, wal-stats, watch, write
  • Documentation suites: cargo test --test docs_coverage --test docs_consistency --test docs_exit_codes --test docs_schemas_sync
  • docs_coverage demands every subcommand and every local flag in each primary doc, and docs_consistency checks every quoted total against the real binary and proves its own reader rejects a stale count
  • docs_exit_codes compares the README exit tables with agent-surface, and docs_schemas_sync keeps the schema files and the published names in step
  • config verb: cargo test --test cli_v0137_config_verb (set/get/unset round trip, scope required, invalid values write nothing, layering key by key, atomic 0600 write)
  • Terminal event and failure report: cargo test --test cli_v0137_terminal_event --test cli_v0137_terminal_pipe --test cli_v0137_terminal_schema (one terminal event, MATCH_FAILED for a missing pair, files_failed and errors[], exit 141 with a closed reader, the six summary schemas)
  • Retry, cancel and limits: cargo test --test cli_v0137_retry_deadline --test cli_v0137_retry_guards --test cli_v0137_cancel --test cli_v0137_search_rss --test cli_v0137_wal_startup_heal
  • Source guards (they fail the build): cargo test --test cli_v0137_hardcode_guard --test cli_v0137_let_underscore_guard
  • cli_v0137_hardcode_guard scans the production code under src/ (it skips constants* files, test files, #[cfg(test)] items and comments). It forbids duration literals in Duration::from_*, the .bak. infix, sidecar and probe names and time-unit numbers outside constants*, and it forbids env::var, env::var_os, env::vars and Command::new anywhere in production code. It also checks that the repository ships no .sh file and no remote-automation directory. The ALLOWED list of exceptions is empty
  • cli_v0137_let_underscore_guard forbids let _ = in production code, and forbids .unwrap(), .expect(, unreachable!(, panic!(, todo!( and unimplemented!( there. Both allowance lists are empty
  • Hermetic harness: every test that runs the binary goes through common::hermetic(...) in tests/common/mod.rs. The child gets an empty HOME, USERPROFILE, APPDATA, LOCALAPPDATA, XDG_CONFIG_HOME, XDG_DATA_HOME and XDG_STATE_HOME under the cargo target tmp directory, LANG and LC_ALL fixed to en_US.UTF-8, and LANGUAGE and LC_MESSAGES removed
  • XDG_CACHE_HOME stays on the real cache of the machine on purpose: the ast feature downloads the tree-sitter parsers there on first use, and an empty cache would send the outline, query and --syntax-check tests to the network
  • A test that needs its own config redirects HOME and XDG_* after it calls hermetic, because the later env call wins
  • Version and slim build: cargo test --test cli_v0137_version; cargo xtask check-features checks the core and core,watch feature sets
  • The supported test run uses the default features: cargo test --locked. Do not use cargo test --no-default-features --features core as a gate (see Local test profiles)
  • Local DoD (local gates only, no remote automation): cargo test --lib --tests, cargo clippy --all-targets -- -D warnings
  • Pin docs/agents to ^0.1.38

Smoke Test of the 47 Subcommands

  • One example per subcommand, each run against atomwrite 0.1.38 (the command, its one-line summary and the example)

  • Setup: WS is the absolute path of an empty workspace that holds src/a.rs (an unwrap() and a comment), src/b.rs (the word beta once), src/c.rs (with user_id), src/tmp.rs, config.toml (a [package] table with name and a [features] table with x), notes.txt, tmp.txt, base.txt, ours.txt, theirs.txt, img.png and rules.yaml (a YAML list with id, language, pattern and rewrite)

  • HASH_A is the checksum that hash src/a.rs prints

  • Run them with HOME and the XDG_* variables pointing inside the workspace, as common::hermetic does for the test suite, so that no real config, locale preference or completion file is touched

  • The examples run in the order below: rollback needs the backup before it and edit-loop needs the edit before it

  • Result: 46 of the 47 exit 0, and watch exits 78 because the default build has no watch feature. A build with --features watch was not run

  • read — Read a file with checksum, size and lines, optionally only head/tail/range. Example: atomwrite --workspace "$WS" read --head 2 src/a.rs

  • write — Create or overwrite a file atomically from stdin. Example: printf 'x\n' | atomwrite --workspace "$WS" write notes/new.txt

  • edit — Edit a file by exact or fuzzy text match, line number or marker. Example: atomwrite --workspace "$WS" edit src/b.rs --old beta --new gamma

  • delete — Delete files or trees with backup, or only print the plan. Example: atomwrite --workspace "$WS" delete --plan tmp.txt

  • copy — Copy a file or tree with checksum verification. Example: atomwrite --workspace "$WS" copy src/a.rs src/a_copy.rs

  • move — Move or rename a file atomically. Example: atomwrite --workspace "$WS" move src/tmp.rs src/tmp2.rs

  • apply — Apply a patch (unified diff, SEARCH/REPLACE, full file) from stdin. Example: printf 'new body\n' | atomwrite --workspace "$WS" apply --format full notes.txt

  • search — Search file contents in parallel with the ripgrep engine. Example: atomwrite --workspace "$WS" search alpha src/

  • replace — Replace text across files with atomic writes and fuzzy matching. Example: atomwrite --workspace "$WS" replace --dry-run alpha omega src/

  • transform — Rewrite code by AST pattern (ast-grep). Example: atomwrite --workspace "$WS" transform --dry-run -p '$E.unwrap()' -r '$E?' -l rust src/

  • hash — Print the BLAKE3 checksum of files. Example: atomwrite --workspace "$WS" hash src/a.rs

  • count — Count lines and files by extension or by size. Example: atomwrite --workspace "$WS" count --by-extension src/

  • diff — Compare two files (unified, stat or changes). Example: atomwrite --workspace "$WS" diff src/a.rs src/b.rs --unified

  • list — List a directory tree with metadata. Example: atomwrite --workspace "$WS" list --long --depth 1 src/

  • extract — Pick fields from NDJSON read on stdin. Example: printf '{"a":1}\n' | atomwrite --workspace "$WS" extract --field a

  • extract-artifact — Bounded signal from PDF, OOXML and image headers (never raw bytes). Example: atomwrite --workspace "$WS" extract-artifact img.png

  • scope — Grammatical scoping: act on comments, strings, functions and other code categories. Example: atomwrite --workspace "$WS" scope src/ --language rust --query comments --delete --dry-run

  • regex — Generate a regex from example strings. Example: atomwrite --workspace "$WS" regex abc-12 xyz-99 id-7 --digits

  • calc — Math and unit conversion. Example: atomwrite --workspace "$WS" calc "2 hours to seconds"

  • completions — Print or install shell completions (bash, zsh, fish, elvish, powershell). Example: atomwrite --workspace "$WS" completions bash

  • backup — Create timestamped backups with BLAKE3 checksums. Example: atomwrite --workspace "$WS" backup src/a.rs --retention 3

  • rollback — Restore a file from a previous backup. Example: atomwrite --workspace "$WS" rollback src/a.rs --latest --verify

  • batch — Run NDJSON operations from stdin, optionally as one transaction. Example: printf '{"op":"write","target":"batch.txt","content":"x"}\n' | atomwrite --workspace "$WS" batch --transaction

  • edit-loop — Apply N old/new pairs in one write, all or nothing. Example: printf '[{"old":"gamma","new":"delta"}]\n' | atomwrite --workspace "$WS" edit-loop src/b.rs

  • prune-backups — Remove old .bak files by age or count. Example: atomwrite --workspace "$WS" prune-backups --max-age-secs 86400 --dry-run --recursive .

  • wal-stats — Show the state of WAL journals (read only). Example: atomwrite --workspace "$WS" wal-stats

  • wal-heal — Remove orphan terminal WAL journals older than a threshold. Example: atomwrite --workspace "$WS" wal-heal --threshold-secs 3600 .

  • verify — Check a file against an expected BLAKE3 hash (exit 0 match, 81 mismatch). Example: atomwrite --workspace "$WS" verify src/a.rs HASH_A

  • set — Write a value at a dotted path in a TOML or JSON file. Example: atomwrite --workspace "$WS" set config.toml package.name demo2

  • get — Read a value at a dotted path in a TOML or JSON file. Example: atomwrite --workspace "$WS" get config.toml package.name

  • del — Remove a key from a TOML or JSON file. Example: atomwrite --workspace "$WS" del config.toml features.x

  • case — Rename identifiers across files between case styles. Example: atomwrite --workspace "$WS" case --subvert user_id UserId --to pascal --dry-run src/c.rs

  • query — Walk the tree-sitter AST and emit nodes. Example: atomwrite --workspace "$WS" query --kinds src/a.rs

  • outline — Emit the high-level structure of a source file. Example: atomwrite --workspace "$WS" outline src/a.rs

  • semantic-merge — Line-based three-way merge with conflict markers (not AST). Example: atomwrite --workspace "$WS" semantic-merge --base base.txt --ours ours.txt --theirs theirs.txt --output merged.txt --fail-on-conflict

  • sparse — Budgeted list, read and outline for large trees. Example: atomwrite --workspace "$WS" sparse list src/ --max-files 10 --max-bytes 1048576

  • recipe — List and run built-in multi-step recipes. Example: atomwrite --workspace "$WS" recipe run --name search-replace-verify --pattern alpha --replacement omega --path src --dry-run

  • stat — Metadata only, alias of read --stat. Example: atomwrite --workspace "$WS" stat src/a.rs

  • agent-surface — Tool manifest for agents (the SSOT of subcommands). Example: atomwrite --workspace "$WS" agent-surface --format json

  • watch — Stream filesystem events with debounce; ends with watch_summary (needs a build with --features watch, the default build exits 78). Example: atomwrite --workspace "$WS" watch src/ --max-events 1 --idle-exit-ms 500

  • codemod — Apply a YAML list of AST rewrite rules across a tree. Example: atomwrite --workspace "$WS" codemod --rules rules.yaml --dry-run src/

  • semantic-search — Offline Jaccard ranking of files by query. Example: atomwrite --workspace "$WS" semantic-search "unwrap value" src/ --k 5 --min-score 0.01

  • doctor — Host readiness diagnostics. Example: atomwrite --workspace "$WS" doctor

  • scratch — Create the staging dir .atomwrite/scratch inside the workspace jail. Example: atomwrite --workspace "$WS" scratch init .atomwrite/scratch

  • locale — Show, set or clear the UI locale. Example: atomwrite --workspace "$WS" locale

  • commands — Print the full command tree as JSON. Example: atomwrite --workspace "$WS" commands --include-globals

  • config — Read and write persistent tuning keys (43 keys, scopes global and workspace). Example: atomwrite --workspace "$WS" config get fuzzy.threshold

What's New in v0.1.36

  • Historical (v0.1.36): residual agent-contract CAPA, always-emit errors under --filter; extract --field; CANONICAL_SUBCOMMAND_COUNT was 46
  • Historical (v0.1.36): full CLI surface under test policy was 46 subcommands (CANONICAL_SUBCOMMAND_COUNT): agent-surface, apply, backup, batch, calc, case, codemod, commands, completions, config, copy, count, del, delete, diff, doctor, edit, edit-loop, extract, get, hash, list, locale, move, outline, prune-backups, query, read, recipe, regex, replace, rollback, scope, scratch, search, semantic-merge, semantic-search, set, sparse, stat, transform, verify, wal-heal, wal-stats, watch, write
  • Suite tests/cli_v0136_gaps.rs covers GAP-019…033 contract points (workspace jail / scratch staging, error ok:false + match_count, fuzzy honesty with normalized strategies emitting similarity: null (never fake 1.0), dual-gate / soft-floor policy, shape flags, extract --field not --select, staging formulas)
  • Local SSOT gate: the gap inventory is a local unversioned note, so the current status of every gap lives in the ADR series and review keeps both aligned
  • Run: cargo test --test cli_v0136_gaps
  • Local DoD (local gates only): cargo test --lib --tests, cargo clippy --all-targets -- -D warnings
  • Historical pin ^0.1.36; ADR-0055

What's New in v0.1.35

  • Residual A-* closed: suite green without delete --yes; large overwrite default-deny (--ack-overwrite); watch always emits watch_summary; semantic-merge conflict markers default ON; monólitos include! splits
  • Local DoD (local gates only): cargo test --lib --tests, cargo clippy --all-targets -- -D warnings, cargo check --target x86_64-pc-windows-gnu, cargo install --path . --force
  • Contract suite: cargo test --test cli_e2e_v0135
  • See ADR-0055 for the A-* closeout matrix

What's New in v0.1.34

  • Suite tests/cli_v0133_oneshot_fuzzy.rs locks the one-shot fuzzy + timeout contract (code fix logged as 0.1.33; docs-complete publish 0.1.34)
  • Covers: expand-section hang when NEW embeds OLD finishes in under 2 seconds; embeds force single apply via apply_fuzzy_one_pass; hard ceiling 10_000 applies; global timeout default 120 / exit 124; cooperative cancel mid-cascade / exit 143
  • Explicit contract under test: apply_fuzzy_one_pass one-pass L→R (never re-scans inserted text); NEW embedding OLD must not hang
  • Run: cargo test --test cli_v0133_oneshot_fuzzy
  • Keep older suites listed below
  • See ADR-0054

What's New in v0.1.30

  • Suite tests/cli_v0130_agent_contract.rs covers residual contract: match_count, indent_adjusted, fuzzy modes, recipe bak skip, sparse outline kind, semantic-merge help line-based, replace-all uniqueness. Note (v0.1.35): --fuzzy off = exact-only (G-010), not rejected
  • Suite tests/cli_v0129_fuzzy_replace.rs covers the 0.1.29 surface: fuzzy replace, best_candidate, durability, recipe, sparse, semantic-merge, stat, agent-surface, semantic-search, platform.rename_method
  • replace --fuzzy auto|aggressive|off (off = exact-only, G-010; default auto) with optional --fuzzy-threshold and bulk --progress-every
  • Match-failure envelopes may include best_candidate (schema best-candidate.schema.json)
  • Cooperative cancel emits cancelled NDJSON events (schema cancelled-event.schema.json, exit 143)
  • Write NDJSON reports platform.rename_method (renameat2 or rename)
  • write --durability full|fast|auto trade-off for fsync cost
  • Historical (at v0.1.29): new subcommands: semantic-merge, sparse, recipe, stat, agent-surface, watch (feature), codemod, semantic-search — 41 subcommands total
  • Feature matrix: slim core (26,560,352 bytes = 25.33 MiB measured on 2026-11-04, above the local size-gate of 15 MiB) vs default AST (71,084,440 bytes = 67.79 MiB measured on 2026-11-04)
  • Local gates (manual; no remote automation): size-gate slim ≤15 MiB, whose measured slim build on 2026-11-04 is 25.33 MiB and above it; core-test; schema-diff on docs/schemas
  • Run the 0.1.30 contract suite: cargo test --test cli_v0130_agent_contract
  • Run the 0.1.29 suite: cargo test --test cli_v0129_fuzzy_replace

What's New in v0.1.28

  • 661 tests passing, 0 failures, 3 ignored (cross-compile gate)
  • BREAKING: delete now creates a backup by default (was opt-in) — pass --no-backup to disable
  • BREAKING: move/copy overwriting an existing destination now require --force OR an explicit --backup
  • GAP-CLI-SURFACE-DRIFT resolved: single BackupOpts struct flattened via #[command(flatten)] into 15 mutating subcommands, replacing 15 hand-declared divergent flag sets
  • GAP-CONFIG-DEFAULTS-DEAD resolved: .atomwrite.toml [defaults] backup/retention keys are now effective end-to-end via a single resolve_backup() call fed by load_config() in lib.rs::run()
  • New shared edit stdin-tty guard: 7 stdin-consuming modes fail fast with exit 65 INVALID_INPUT instead of blocking indefinitely when stdin is a terminal
  • New test files: cli_v0128_backup_matrix.rs (12 tests), cli_v0128_config_defaults.rs (6 tests), cli_v0128_edit_stdin_guard.rs (3 tests), cli_v0128_batch_backup.rs (6 tests)
  • 33 subcommands, 32 ADRs (0019-0050)

What's New in v0.1.27

  • 631+ tests passing, 0 failures, 3 ignored (cross-compile gate)
  • 10 bugs fixed: BUG-SEC-001 (CRITICAL symlink-dir escape), BUG-SCOPE-004 (CRITICAL scope --delete code destruction), BUG-GET, BUG-001, BUG-002, BUG-005, BUG-008, BUG-SCOPE-002, BUG-SCOPE-003, BUG-SCOPE-005
  • 3 known limitations documented: GAP-01 (test-fn), GAP-02 (doc-comment), GAP-03 (JS export)
  • tests/cli_get_del.rs updated: get missing key expects exit 65 INVALID_INPUT (was exit 4)
  • scope.rs unit test lookup_rust_queries_known updated for pub-variant patterns
  • scope.rs unit test lookup_go_queries_known updated for var-without-type pattern
  • 33 subcommands, 29 ADRs (0019-0047)

What's New in v0.1.25

  • 631 tests passing, 0 failures, 3 ignored (cross-compile gate)
  • 49 additional gaps resolved in 6 e2e audit rounds (GAP-071 through GAP-134)
  • Property-based fuzzy tests via proptest (5 properties in tests/proptest_fuzzy.rs)
  • ~505 e2e scenarios executed against real binary

What's New in v0.1.24

  • 621 tests passing, 0 failures, 3 ignored (cross-compile gate)
  • 52 gaps resolved (GAP-2026-019 through GAP-2026-070)
  • 20 anyhow::bail!() converted to typed AtomwriteError (inline unit tests added per command)
  • 3 new ADRs (0045-0047)

New Test Files (v0.1.24)

  • tests/cli_v0124_clap_suggestion.rs — 5 tests for GAP-019 (actionable clap error suggestions)
  • tests/cli_gap020_diff_workspace.rs — 3 tests for GAP-020 (diff resolve-first)
  • tests/cli_gap021_scope_readonly.rs — 4 tests for GAP-021 (scope read-only mode)

Bug Fixes Validated by Existing Test Suites

  • GAP-022 to GAP-070: fixes validated by existing integration tests in cli_*.rs files
  • Each bail! → AtomwriteError conversion includes inline #[cfg(test)] assertions
  • cargo test confirms 621 total: 609 (v0.1.23) + 5 (GAP-019) + 3 (GAP-020) + 4 (GAP-021)

What's New in v0.1.23

  • 609 tests passing (575 baseline v0.1.22 + 12 GAP-2026-015 + 7 GAP-2026-016 + 4 GAP-2026-017 + 8 GAP-2026-018 + 3 from [Unreleased] Windows)
  • 33 subcommands (32 from v0.1.22 + verify from v0.1.25)
  • 26 ADRs in docs/decisions/ (0019-0044)
  • GAP-2026-015 (allow_hyphen_values) closed; 12 CLI fields across 8 structs accept values starting with -, and the three positionals require -- since 0.1.37
  • GAP-2026-016 (backup-by-default) closed; backup enabled by default in 9 content-mutating structs
  • GAP-2026-017 (shrink guard) closed; writes shrinking >50% blocked when --expect-checksum active
  • GAP-2026-018 (--old-file/--new-file) closed; edit reads match/replacement from files, bypassing ARG_MAX
  • New tests: tests/cli_v0123_hyphen_values.rs (12), tests/cli_v0123_backup_default.rs (7), tests/cli_v0123_shrink_guard.rs (4), tests/cli_v0123_old_file.rs (8)

What's New in v0.1.22: Test Totals

  • 631+ tests passing (542 baseline v0.1.18 + 33 in v0.1.21-v0.1.22 + 46 in v0.1.23-v0.1.24 + 10 in v0.1.25)
  • 33 subcommands (30 baseline v0.1.18 + edit-loop + prune-backups from v0.1.22 + verify from v0.1.25)
  • 22 ADRs in docs/decisions/ (0019-0040)
  • 2 new NDJSON schemas: edit-loop-output.schema.json, prune-backups-output.schema.json

What's New in v0.1.21

  • GAP-2026-012 (--allow-sequential-drift flag) closed; sequential edits no longer require re-capturing checksum between iterations
  • GAP-2026-013 Front 4 (--backup exposed in edit and rollback) closed; parity with write and replace
  • GAP-2026-014 v2 (backup default-deletes after success) closed; --keep-backup opt-in escape hatch added
  • ADR-0038 created documenting the backup-default-deletes paradigm
  • New tests: tests/cli_v0121_sequential_drift.rs (4), tests/cli_v0121_backup_keep_flag.rs (3), tests/cli_v0121_edit_backup.rs (3), tests/cli_v0121_rollback_backup.rs (2), tests/cli_v0121_apply_keep.rs (2), tests/cli_v0121_batch_keep.rs (2), tests/proptest_v0121_backup_delete.rs (2 property tests)

What's New in v0.1.22

  • GAP-2026-012 Front 3 (edit-loop helper subcommand) closed; new edit-loop applies N pairs {old, new} in 1 invocation via NDJSON on stdin
  • GAP-2026-013 Front 2 (prune-backups subcommand) closed; new prune-backups provides manual cleanup of legacy .bak.YYYYMMDD_HHMMSS files
  • ADR-0039 created documenting the edit-loop design
  • ADR-0040 created documenting the prune-backups design
  • New tests: tests/cli_v0121_edit_loop.rs (4), tests/cli_v0121_prune_backups.rs (3)

What's New in v0.1.12 (historical)

This section summarizes the test-relevant changes in v0.1.12. The release added 96 new tests (was 320 baseline) for a total of 445 tests in 43 test suites. v0.1.15 raises the total to 542 tests (+2 unit tests in v0.1.14, +8 G117 tests in tests/cli_edit.rs, +6 G118 tests in tests/cli_write.rs).

New Test Files (10 Added in v0.1.11+v0.1.12)

  • tests/cli_v012_regressions.rs -- 11 tests for v0.1.2 through v0.1.4 regressions
  • tests/cli_v012_audit_regressions.rs -- 27 tests for the v0.1.12 G72/G114 audit
  • tests/cli_v012_batch4_regressions.rs -- 23 tests for the v0.1.12 final batch
  • tests/cli_v012_syntax_check.rs -- 5 tests for G72 tree-sitter validation
  • tests/cli_v012_wal.rs -- 8 tests for G114 WAL sidecar
  • tests/cli_v012_xattr_reflink.rs -- 3 tests for G39 xattr + G64 reflink
  • tests/cli_set.rs -- 6 tests for v14 Tier 3 set subcommand
  • tests/cli_get_del.rs -- 5 tests for v14 Tier 3 get/del subcommands
  • tests/cli_query.rs -- 5 tests for v14 Tier 3 query subcommand
  • tests/cli_outline.rs -- 5 tests for v14 Tier 3 outline subcommand
  • tests/cli_case.rs -- 3 tests for v14 Tier 3 case subcommand

New Tests in Existing Files

  • 12 tests in src/binary_detect.rs::tests (G41 content_inspector)
  • 16 tests in src/syntax_check.rs::tests (G72 tree-sitter)
  • 8 tests in src/wal.rs::tests (G114 WAL)
  • 3 tests in src/xattr_restore.rs::tests (G39 xattr)
  • 3 tests in src/lock.rs::tests (G54 advisory lock)
  • 3 tests in src/atomic.rs::tests (WriteStrategy: rename/inplace/copyback)

Test Suite Organization

  • Total: 43 test suites (was 34 in v0.1.10)
  • Unit tests in src/
  • Integration tests in tests/cli_*.rs
  • Property-based tests in tests/proptest_*.rs
  • Snapshot tests via insta
  • Signal tests (SIGINT, SIGTERM, SIGPIPE)

How to Run

# Run all tests
cargo test

# Run the v0.1.33/v0.1.34 one-shot fuzzy + timeout suite
cargo test --test cli_v0133_oneshot_fuzzy
# Run the v0.1.30 residual contract suite
cargo test --test cli_v0130_agent_contract
# Run the v0.1.29 suite (fuzzy replace + new surface)
cargo test --test cli_v0129_fuzzy_replace

# Run only the v0.1.12 regression suite
cargo test --test cli_v012_regressions
cargo test --test cli_v012_audit_regressions
cargo test --test cli_v012_batch4_regressions

# Supported run: the full suite with the default features
cargo test --locked

# Slim build: only prove that it compiles (xtask exists in a source checkout only)
cargo xtask check-features

# Run with output visible for debugging
cargo test --test cli_v012_syntax_check -- --nocapture

# Run the cross-compile gate
cargo test --test cross_compile_check -- --ignored

Coverage

  • Historical (at v0.1.12): 20.19% line coverage via cargo tarpaulin (935/4631 lines covered), measured at that release and not repeated since
  • It was low because tarpaulin only counts unit tests, not CLI integration tests
  • The integration test suite is the primary coverage metric (see Current Stats)

Dependencies Added

  • tree-sitter-language-pack = "1.8" -- 305 languages for query/outline/syntax-check at that version, and the tree now pins 1.22.1 with 372
  • All test dependencies are already in the dev-dependencies section

ADRs and Schemas

  • 29 ADRs in docs/decisions/ (0019-0047) explain the architectural decisions behind the v0.1.12 to v0.1.27 features
  • Historical (at v0.1.27): 29 JSON schemas in docs/schemas/; the current count is 54 (full index in docs/schemas/README.md)
  • See docs/decisions/README.md for the full list of ADRs

Why Categorized Tests

  • Each test category validates a different layer of the system
  • Unit tests verify pure logic in isolation
  • Integration tests verify CLI behavior end-to-end
  • Snapshot tests lock down JSON output structure
  • Property-based tests discover edge cases humans miss
  • Running all categories together gives confidence that atomwrite works correctly

Current Stats

  • Final run of v0.1.38 recorded in CHANGELOG.md: 131 test targets, 1486 tests passed, 0 failed and 9 ignored (the cross_compile_* tests)
  • Inventory measured with fd and rg on the source tree: 131 integration test files in tests/ (plus tests/common/mod.rs, doc_scan.rs and schema_check.rs), 994 #[test] functions in tests/ and 485 in src/ (DERIVED: 994 + 485 = 1479), plus 9 snapshot files, 4 proptest files and 2 fuzz targets
  • Measure it again with rg -c '#\[test\]' tests src and cargo test --lib --tests. A macro-generated test (proptest) is not counted by that rg, so the number of tests that run can differ from the number of #[test] attributes
  • Suites by theme: unit + integration + snapshot + property-based + signal + tracing + NDJSON + regression + cross-compile + concurrency
  • Historical (v0.1.11 and v0.1.12): 96 new tests were added then:
    • 11 tests in tests/cli_v012_regressions.rs (GAP 13, GAP 14, GAP 18 fixes)
    • 27 tests in tests/cli_v012_audit_regressions.rs (v0.1.12 G72/G114 audit)
    • 23 tests in tests/cli_v012_batch4_regressions.rs (v0.1.12 final batch)
    • 5 tests in tests/cli_v012_syntax_check.rs (G72 tree-sitter)
    • 8 tests in tests/cli_v012_wal.rs (G114 WAL sidecar)
    • 3 tests in tests/cli_v012_xattr_reflink.rs (G39 xattr + G64 reflink)
    • 6 tests in tests/cli_set.rs (v14 Tier 3)
    • 5 tests in tests/cli_get_del.rs (v14 Tier 3)
    • 5 tests in tests/cli_query.rs (v14 Tier 3)
    • 5 tests in tests/cli_outline.rs (v14 Tier 3)
    • 3 tests in tests/cli_case.rs (v14 Tier 3)
    • 3 mtime regression tests in src/atomic.rs::tests
    • 7 GAP 13 error-suggestion tests in src/error.rs::tests
    • 3 cross-compile gate tests in tests/cross_compile_check.rs (v0.1.4; there are 9 now)
    • 16 tests in src/syntax_check.rs::tests (G72 tree-sitter)
    • 8 tests in src/wal.rs::tests (G114 WAL)
  • 12 tests in src/binary_detect.rs::tests (G41 content_inspector)
  • 3 tests in src/xattr_restore.rs::tests (G39)
  • 3 tests in src/lock.rs::tests (G54 advisory lock)
  • 9 snapshot files in tests/snapshots/
  • 2 proptest regression files
  • 2 fuzz targets in fuzz/fuzz_targets/

Test Categories

Unit Tests (src/)

  • Located inside source files via #[cfg(test)] modules
  • Test pure functions without filesystem or CLI interaction
  • path_safety.rs -- 5 tests for path traversal prevention and workspace jail
  • checksum.rs -- BLAKE3 hashing correctness

Integration Tests (tests/cli_*.rs)

  • Located in tests/ directory
  • Each file tests one subcommand end-to-end via the compiled binary
  • Use assert_cmd to invoke atomwrite as a subprocess
  • Use tempfile crate for isolated filesystem fixtures
  • cli_write.rs -- 6 tests for atomic write operations
  • cli_read.rs -- 6 tests for read with metadata and checksums
  • cli_edit.rs -- 5 tests for surgical edit modes
  • cli_search.rs -- 6 tests for parallel search
  • cli_replace.rs -- 6 tests for bulk text replacement
  • cli_hash.rs -- 4 tests for BLAKE3 checksum operations
  • cli_delete.rs -- 4 tests for file deletion with backup
  • cli_count.rs -- 2 tests for line and file counting
  • cli_diff.rs -- 4 tests for file comparison
  • cli_move.rs -- 5 tests for atomic move and rename
  • cli_copy.rs -- 4 tests for copy with checksum verification
  • cli_list.rs -- 4 tests for project structure listing
  • cli_extract.rs -- 4 tests for NDJSON field extraction
  • cli_calc.rs -- 5 tests for math and unit conversion
  • cli_regex.rs -- 5 tests for regex generation from examples
  • cli_transform.rs -- 5 tests for AST search and rewrite
  • cli_scope.rs -- scope operations: find functions, delete comments, unknown language error, custom patterns
  • cli_backup.rs -- backup creation, dry-run, not-found error, multiple files
  • cli_rollback.rs -- restore from backup, dry-run, no-backup error, verify flag
  • cli_apply.rs -- full file replacement, SEARCH/REPLACE blocks, unified diff, dry-run
  • cli_batch.rs -- 13 tests for batch operation execution (write, replace, delete, move, copy, path alias, transaction rollback)

Snapshot Tests (insta)

  • Located in tests/snapshot_write.rs -- 9 tests
  • Use the insta crate for snapshot-based output verification
  • Lock down the exact JSON structure of each output type
  • Snapshot files stored in tests/snapshots/
  • Run cargo insta review to accept or reject snapshot changes
  • Available snapshots:
  • snapshot_write__write_output_structure.snap
  • snapshot_write__read_output_structure.snap
  • snapshot_write__edit_output_structure.snap
  • snapshot_write__search_match_structure.snap
  • snapshot_write__replace_result_structure.snap
  • snapshot_write__error_not_found_structure.snap
  • snapshot_write__batch_summary_structure.snap
  • snapshot_write__error_invalid_input_structure.snap
  • snapshot_write__error_workspace_jail_structure.snap

Regression Tests

  • tests/cli_v012_regressions.rs -- 11 tests for v0.1.2 through v0.1.4 regressions
  • jail_suggestion_mentions_workspace_flag -- updated in v0.1.4 (GAP 13): asserts the suggestion mentions --workspace when no workspace is provided
  • gap13_jail_suggestion_when_workspace_supplied_says_inside -- added in v0.1.4 (GAP 13): asserts the suggestion says "inside the workspace" when --workspace IS provided
  • Other regressions cover scope, batch path/source aliases, fuzzy edit, search files dedup, edit multi NDJSON, clap JSON errors, json-schema, validate path jail, dead flags, mtime

Cross-Compile Gate (v0.1.4)

  • tests/cross_compile_check.rs -- 9 tests (3 guarded Windows-only compilation in v0.1.4, 6 more cover Windows arm64, Linux musl and aarch64, Apple aarch64 and x64)
  • They were NOT validated for v0.1.37: the audit host lacks the foreign linkers (for example x86_64-w64-mingw32-gcc)
  • The 9 tests are cross_compile_windows_gnu_x64_succeeds, cross_compile_windows_gnu_i686_succeeds, cross_compile_windows_msvc_succeeds, cross_compile_windows_arm64_msvc_succeeds, cross_compile_linux_musl_x64_succeeds, cross_compile_linux_aarch64_gnu_succeeds, cross_compile_linux_aarch64_musl_succeeds, cross_compile_apple_aarch64_succeeds and cross_compile_apple_x64_succeeds
  • cross_compile_windows_gnu_x64_succeeds -- asserts cargo check --target x86_64-pc-windows-gnu succeeds and emits no E0433, E0308, or E0507
  • cross_compile_windows_gnu_i686_succeeds -- asserts the same for i686-pc-windows-gnu (32-bit Windows)
  • cross_compile_windows_msvc_succeeds -- asserts the same for x86_64-pc-windows-msvc (Microsoft Visual C++ toolchain)
  • All tests are #[ignore] by default to skip on hosts without the Windows targets installed
  • Run with cargo test --test cross_compile_check -- --ignored
  • Skips gracefully when the required linker (lib.exe for MSVC, i686-w64-mingw32-gcc for 32-bit) is missing
  • Required before any release that touches #[cfg(windows)] code (see docs/INSTALL.md and docs/CROSS_PLATFORM.md)

Property-Based Tests (proptest)

  • Located in tests/proptest_checksum.rs -- 2 tests
  • Located in tests/proptest_backup.rs -- 2 tests
  • Use the proptest crate to generate random inputs
  • Verify that BLAKE3 checksums are deterministic for any input
  • Verify that backup creation works for arbitrary file contents
  • Regression files stored alongside test files

Signal Tests

  • Located in tests/signal_test.rs -- 5 tests
  • sigpipe_handler_ends_the_run_with_exit_141 proves that a closed pipe ends the run with exit 141 (SIGPIPE has a cooperative handler, not SIG_DFL)
  • sigint_during_search_exits_130 and sigterm_during_search_exits_143 prove the exit codes of the signals
  • batch_interrupted_by_signal and shutdown_message_on_stderr prove the cleanup and the shutdown message
  • Verify graceful shutdown behavior on signal reception

NDJSON Validation Tests

  • Located in tests/ndjson_valid_test.rs -- 21 tests (counted with rg -c '#\[test\]')
  • 19 tests validate the NDJSON output of 19 of the 47 commands: search, hash, list, diff, write, read, edit, replace, count, backup, copy, move, delete, batch, calc, regex, rollback (not-found case), apply and extract
  • 2 jaq interop tests (search and read) verify piped JSON parsing, and skip when jaq is not in PATH

Concurrency Tests

  • Located in tests/cli_concurrency.rs
  • Test parallel file operations and race conditions

Max Filesize Tests

  • Located in tests/cli_max_filesize.rs
  • Test enforcement of file size limits

Tracing Tests

  • Located in tests/tracing_test.rs
  • Verify tracing/logging infrastructure behavior

Fuzzing Targets

  • Located in fuzz/fuzz_targets/batch_parse.rs -- batch NDJSON parser fuzzing
  • Located in fuzz/fuzz_targets/extract_json.rs -- extract JSON parser fuzzing
  • Require cargo +nightly fuzz run <target>
  • Run with --max_total_time=30 for quick validation

How to Run

Run All Tests

cargo test

Run a Specific Test File

cargo test --test cli_write
cargo test --test cli_search
cargo test --test snapshot_write
cargo test --test proptest_checksum

Run a Specific Test by Name

cargo test --test cli_write test_write_atomic
cargo test --test cli_edit test_edit_old_new

Run Only Unit Tests

cargo test --lib

Run Only Integration Tests

cargo test --tests

Run With Output Visible

cargo test -- --nocapture

Run Snapshot Review

cargo insta review

Update All Snapshots

cargo insta test
cargo insta review

Local test profiles

Fast (Development)

  • Run cargo test with default settings
  • Skip long-running property tests with PROPTEST_CASES=10
  • Suitable for pre-commit hooks
  • Total time: an old estimate of under 30 seconds, not measured for v0.1.37

Full (local pre-release v0.1.36+)

Required local release gate (local gates only):

cargo fmt --check
cargo clippy --all-targets -- -D warnings
cargo test --lib
cargo test --tests
cargo test --test cli_v0136_gaps

Slim (compile check only)

  • cargo test --no-default-features --features core compiles but is NOT green: 44 tests in 11 targets (cli_scope, cli_transform, cli_query, cli_outline, cli_concurrency, cli_e2e_v0135 and others) need the ast feature and carry no #[cfg(feature = "ast")] (gaps.md W19, CHANGELOG.md Notes)
  • Use cargo xtask check-features to prove that the slim build compiles: it runs cargo check --locked for the core and core,watch sets and stops at the first failure
  • Run the test suite with the default features

Full (local pre-release)

  • Run cargo test with all features
  • Run cargo clippy -- -D warnings for linting
  • Run cargo fmt -- --check for formatting
  • Run cargo insta test for snapshot verification
  • Run property tests with default case count
  • Suitable for pull request validation
  • Total time: an old estimate of under 2 minutes, not measured for v0.1.37

Release (Pre-Publish)

  • Run cargo test --release for optimized build testing
  • Run cargo test --test proptest_checksum with PROPTEST_CASES=1000
  • Run cargo test --test proptest_backup with PROPTEST_CASES=1000
  • Verify all snapshots are up to date with cargo insta test

Performance (local only)

Rules Rust eficiência + latência: measure before optimizing; never compare debug vs release; prefer tail percentiles (P50/P99/P999/P9999) over means.

# Criterion microbenches (hash + read/mmap). Profile inherits release (fat LTO, CGU=1).
# Each bench also prints `latency_hist … P50=…ns P99=…ns P999=…ns P9999=…ns` on stderr.
cargo bench --bench hash_benchmark
cargo bench --bench read_benchmark

# Optional size-optimized binary (same LTO/strip as release, opt-level = "z")
cargo build --profile min-size

# Host-CPU binary for local profiling only (do not publish):
RUSTFLAGS='-C target-cpu=native' cargo build --release

# Hot-path profile (install samply or cargo-flamegraph separately):
# samply record ./target/release/atomwrite search PATTERN --path .
# cargo flamegraph --bin atomwrite -- search PATTERN --path .

Latency budget notes (CLI one-shot, not HFT):

Path Dominated by Notes
hash multi-file BLAKE3 + FS Parallel digests (rayon), sorted NDJSON emit
hash/read large file mmap + page cache posix_fadvise(SEQUENTIAL) on Linux
stdout NDJSON serialization + flush Flush-per-line is intentional (agent TTFB)
PGO/BOLT / isolcpus / mlockall — N/A for short-lived multi-host CLI

Release knobs live in Cargo.toml ([profile.release], [profile.bench], [profile.min-size]) and the mold linker in .cargo/config.toml (Linux x86_64). No remote benchmark gates: the benchmarks run on the local machine only (project policy).

Logging and test harness knobs

  • Binary runtime logging is CLI + XDG only (v0.1.35): use -v/-vv/-vvv and -q/-qq; optional file tee under XDG state …/atomwrite/logs via directories::ProjectDirs (no product ATOMWRITE_* or RUST_LOG knobs in the binary).
  • Tracing entrypoint: init_tracing (local diagnostics only — no product telemetry).
  • The common::hermetic helper sets HOME, XDG_*, LANG and LC_ALL on the child process only, for the tests; it is not a product setting.
  • Cargo/test harness only (not product config): PROPTEST_CASES, INSTA_UPDATE, RUST_TEST_THREADS, CARGO_TARGET_DIR.
  • Do not document or rely on product environment variables for logging, locale, workspace, backup, or home override — removed in v0.1.35 (use CLI + XDG only).
  • doctor reads no environment variable: host detection uses file probes only, and this configures no product knob.

Troubleshooting

Snapshot Mismatch

  • Run cargo insta review to see the diff
  • Accept changes with cargo insta accept
  • Reject and fix with cargo insta reject
  • Snapshots live in tests/snapshots/

Proptest Regression

  • Check tests/*.proptest-regressions files for recorded failures
  • These files contain minimal reproducing inputs
  • Delete regression files to re-discover (not recommended)
  • Fix the root cause instead

Flaky Tests

  • Check for filesystem timing issues in integration tests
  • Use --test-threads 1 to serialize test execution
  • Verify /tmp has sufficient space for temporary files

Permission Errors

  • Integration tests create temporary directories
  • Verify write access to TMPDIR or /tmp
  • Some tests verify permission-denied behavior and need writable parent directories
  • Use tempfile::tempdir() for all filesystem fixtures

Test Hangs or Times Out

  • Check for infinite loops in the code under test
  • Use RUST_TEST_THREADS=1 to run sequentially
  • Check that no test writes to a path another test reads

Parser Download in Tests

  • The outline, query and --syntax-check tests need the tree-sitter parser bundle (23,031,807 bytes on Linux x86_64, which is 21,97 MiB) in the real XDG_CACHE_HOME; the first run downloads it, so run it once with network access or fill the cache beforehand
  • The tests never read the real HOME, config or locale preference: the common::hermetic helper isolates them, and only the cache is shared

A Test Depends on the Machine

  • If a test passes on one machine and fails on another, check that it builds its command through common::hermetic(...) and does not read a config of the developer
  • A test that sets its own config must redirect HOME and XDG_* after calling hermetic

Slim Tests Fail

  • cargo test --no-default-features --features core is expected to fail 44 tests in 11 targets that need the ast feature; run the suite with the default features instead (see Local test profiles)

Cross-Compile Gate Fails

  • Confirm the Windows target is installed: rustup target list --installed
  • Install missing targets: rustup target add x86_64-pc-windows-gnu i686-pc-windows-gnu x86_64-pc-windows-msvc
  • On Linux, install the required toolchain: mingw64-gcc (Fedora) or mingw-w64 (Ubuntu)
  • For 32-bit Windows: install mingw32-gcc separately
  • For MSVC: install Visual Studio 2019+ Build Tools with the C++ workload (lib.exe must be on PATH)
  • Re-run after fixing: cargo test --test cross_compile_check -- --ignored
  • The gate reports a missing linker with a clear stderr snippet like "lib.exe" or "i686-w64-mingw32-gcc"; match that string to the missing toolchain

v0.1.20 — What Is New

This release introduces a new safety layer called intention guards and renames the global --lang flag to --locale to disambiguate from the tree-sitter --lang selector used by scope and transform.

Intention Guards (5 OPT-IN flags)

  • --require-backup — require --backup: abort when it is missing and the target file exists (takes no value)
  • --confirm — legacy awareness flag on write (historical: interactive Y/N on large overwrite). Superseded in v0.1.35: large overwrite is one-shot default-deny via --ack-overwrite (no Y/N); delete --confirm is rejected (use --plan)
  • --auto-rotate — force an automatic rotation backup for recently modified files (age from [write].auto_rotate_max_age_secs, default 24 h; takes no value)
  • --risk-threshold <PERCENT> — size-delta threshold in percent for the risk warning (default 255 = off; for example --risk-threshold 50)
  • --locale <en|pt-BR> — renamed from --lang to disambiguate from the tree-sitter --lang

Other Additions

  • count --by-size — list the largest files in the tree with sizes and line counts
  • read --format raw|ndjson — select between byte-stream output and structured NDJSON envelope (an old --mode spelling never existed)
  • search --no-begin-end — disable the implicit ^ and $ anchor decoration in regex output
  • write --preserve-timestamps — keep the source file mtime when overwriting
  • scope --lang rust — explicit alias of scope --language; transform takes -l/--language only

Statistics

  • 542 tests passing in 47 integration suites, 0 failures
  • 11 GAP-2026 closed
  • 3 Windows cross-compile targets green
  • 19 ADRs in docs/decisions/ (0019-0037)

Migration --lang to --locale

# Discover all files using --lang
rg -l -- '--lang\b' .

# Bulk replace while preserving other matches
fd -e sh -e md -e toml -e yml -e yaml -e json -x sd -- '--lang\b' '--locale' {}

# Or via ruplacer (a dry run until you add --go)
ruplacer -- '--lang' '--locale' .

Every local flag, by command

  • This list names every local flag of each command, and the global flags stay in atomwrite --help.
  • agent-surface: --format
  • apply: --ack-overwrite, --all, --allow-shrink, --backup, --dry-run, --format, --keep-backup, --no-backup, --no-syntax-check, --retention, --show, --strict-atomic
  • backup: --dry-run, --output-dir, --retention
  • batch: --backup, --batch-size, --dry-run, --file, --input-schema, --keep-backup, --no-backup, --retention, --strict-atomic, --transaction
  • calc: --stdin
  • case: --backup, --dry-run, --exclude, --include, --keep-backup, --no-backup, --preserve-timestamps, --retention, --strict-atomic, --subvert, --to
  • codemod: --backup, --dry-run, --keep-backup, --no-backup, --retention, --rules, --strict-atomic
  • commands: --brief, --include-globals
  • completions: --install
  • config: no local flag of its own, only the global set
  • copy: --backup, --dry-run, --force, --keep-backup, --no-backup, --no-reflink, --preserve-xattr, --preserve, --recursive, --retention, --strict-atomic
  • count: --by-extension, --by-size, --exclude, --include, --top
  • del: --backup, --dry-run, --force-missing, --keep-backup, --no-backup, --preserve-timestamps, --retention, --strict-atomic
  • delete: --backup, --confirm, --dry-run, --exclude, --include, --keep-backup, --no-backup, --older-than, --plan, --recursive, --retention, --yes
  • diff: --algorithm, --context, --stat, --unified
  • doctor: --strict
  • edit: --after-line, --after-match, --allow-sequential-drift, --backup, --before-line, --before-match, --between, --delete-range, --dry-run, --expect-checksum, --fuzzy-threshold, --fuzzy, --keep-backup, --line-ending, --multi, --new-file, --new, --no-backup, --old-file, --old, --partial, --preserve-timestamps, --range, --replace-all, --retention, --strict-atomic, --wal-policy
  • edit-loop: --allow-sequential-drift, --backup, --keep-backup, --line-ending, --no-backup, --partial, --retention, --strict-atomic, --syntax-check
  • extract: --delimiter, --field, --stdin
  • extract-artifact: --max-sample-rows, --max-text-chars
  • get: no local flag of its own, only the global set
  • hash: --exclude, --recursive, --stdin, --verify
  • list: --all, --count-by-ext, --depth, --exclude, --format, --include, --long
  • locale: --clear, --set
  • move: --backup, --dry-run, --force, --keep-backup, --no-backup, --preserve-hardlinks, --retention
  • outline: --format, --kind, --language, --positions
  • prune-backups: --dry-run, --max-age-secs, --max-count, --recursive
  • query: --kinds, --language, --positions, --query, --tree
  • read: --all, --bytes, --context, --crop, --dpi, --enclosing, --force, --format, --grep, --head, --high-res, --line, --lines, --max-tokens, --no-comments, --number, --ocr, --page, --pages, --stat, --symbol, --tail, --verify-checksum
  • recipe: no local flag of its own, only the global set
  • regex: --case-insensitive, --digits, --no-anchors, --repetitions, --spaces, --stdin, --words
  • replace: --backup, --dry-run, --exclude, --expect-checksum, --fuzzy-threshold, --fuzzy, --include, --keep-backup, --literal, --max-replacements, --no-backup, --preserve-case, --preserve-timestamps, --preview, --progress-every, --regex, --retention, --strict-atomic, --word
  • rollback: --backup, --dry-run, --keep-backup, --latest, --no-backup, --retention, --strict-atomic, --timestamp, --verify
  • scope: --action, --backup, --delete, --dry-run, --exclude, --include, --keep-backup, --language, --no-backup, --pattern, --query, --replace-with, --retention, --strict-atomic
  • scratch: no local flag of its own, only the global set
  • search: --binary, --case-insensitive, --context, --count, --exclude, --files, --fixed, --format, --include-fifo, --include, --invert, --limit, --max-columns, --max-count, --max-filesize, --multiline, --no-begin-end, --offset, --pcre2, --regex, --smart-case, --sort, --target, --word
  • semantic-merge: --backup, --base, --dry-run, --expect-checksum, --fail-on-conflict, --keep-backup, --no-backup, --no-conflict-markers, --ours, --output, --retention, --strict-atomic, --theirs, --write-conflict-markers
  • semantic-search: --include-backups, --index-dir, --k, --min-score
  • set: --backup, --dry-run, --keep-backup, --no-backup, --preserve-timestamps, --retention, --strict-atomic
  • sparse: no local flag of its own, only the global set
  • stat: --all, --bytes, --context, --crop, --dpi, --enclosing, --force, --format, --grep, --head, --high-res, --line, --lines, --max-tokens, --no-comments, --number, --ocr, --page, --pages, --stat, --symbol, --tail, --verify-checksum
  • transform: --backup, --dry-run, --exclude, --include, --inline-rules, --keep-backup, --language, --no-backup, --pattern, --retention, --rewrite, --rules, --strict-atomic, --verify-parse
  • verify: no local flag of its own, only the global set
  • wal-heal: --dry-run, --max-duration-ms, --threshold-secs
  • wal-stats: --dry-run
  • watch: --checksum, --debounce-ms, --gitignore, --idle-exit-ms, --max-events
  • write: --ack-overwrite, --allow-empty-stdin, --allow-shrink, --append, --auto-rotate, --backup, --confirm, --dry-run, --durability, --expect-checksum, --keep-backup, --line-ending, --max-size, --no-backup, --no-checksum-when-empty, --prepend, --preserve-timestamps, --require-backup, --require-large-ack, --retention, --risk-threshold, --strict-atomic, --syntax-check, --wal-policy