| 0019 |
v0.1.12 chose tree-sitter-language-pack over direct tree-sitter deps to keep binary small. |
0019 |
0019 |
| 0020 |
G114 WAL sidecar path is .atomwrite.journal.<basename>.atomwrite.journal.json. |
0020 |
0020 |
| 0021 |
v0.1.12 query and outline accept only kind names, not tree-sitter S-expressions. |
0021 |
0021 |
| 0022 |
G72 tree-sitter REAL syntax check replaces (not adds to) the bracket heuristic. |
0022 |
0022 |
| 0023 |
G114 recovery is consultative (no auto-replay, no auto-delete). |
0023 |
0023 |
| 0024 |
get/del TOML dotted path navigation is manual Table descent, not toml_edit::Table::get. |
0024 |
0024 |
| 0025 |
query --positions is valid in --query/--tree, silently ignored in --kinds. |
0025 |
0025 |
| 0026 |
Multi-pair --old/--new gains fuzzy parity, per-pair pair_results, failed_pair_index on error, and opt-in --partial. |
0026 |
0026 |
| 0027 |
write resolves the target via validate_path before append/prepend, line-ending auto-detection, and --expect-checksum (fixes CWE-367 double path identity; checksum drift exits 82 with a divergent CWD). |
0027 |
0027 |
| 0028 |
Five-layer autonomous WAL cleanup: L1 --wal-policy prevention, L2 Drop guard, L3 --no-auto-heal startup heal, L4 heuristics (TTL/LRU/rate/sentinel/archive), L5 wal-stats. |
0028 |
0028 |
| 0029 |
L3 explicit cross-validation of --append/--expect-checksum/--allow-empty-stdin via tracing::info and --no-checksum-when-empty opt-out. |
0029 |
0029 |
| 0030 |
replace pre-validates root paths against the jail, G120 L3 end-to-end test, G117 edge cases (Unicode, CRLF, multi-pair same --old). |
0030 |
0030 |
| 0031 |
search and replace resolve root paths against the workspace through a shared helper (CWE-367). |
0031 |
0031 |
| 0032 |
query accepts tree-sitter S-expressions through Query::new (the v0.1.12 docs promised it but the code never implemented it). |
0032 |
0032 |
| 0033 |
7 exit-code drifts between the published docs and the binary (STATE_DRIFT, SYNTAX_ERROR_DETECTED, ORPHAN_JOURNAL, BROKEN_PIPE, binary read, ARGUMENT_PARSE_ERROR, missing --workspace). |
0033 |
0033 |
| 0034 |
clap --help nunca declarado antes da implementação (5 dos 11 GAP-2026 tinham esse anti-pattern; motivação para help-driven testing). |
0034 |
0034 |
| 0035 |
Seis camadas de defesa em profundidade (--require-backup, --confirm, --preview/--yes, --auto-rotate, --risk-threshold) + risk_assessment no envelope, motivadas pelo incident c24-framework34.html de 2026-06-15. |
0035 |
0035 |
| 0036 |
Single-pair com zero matches retorna NO_MATCHES (exit 1); multi-pair aplica matched e relata unmatched em pair_results (exit 0). |
0036 |
0036 |
| 0037 |
Rename GlobalArgs.lang flag --lang para --locale; env var ATOMWRITE_LANG e campo args.global.lang preservados; namespace --lang liberado para subcomandos (histórico, pré-0.1.35, superado). |
0037 |
0037 |
| 0038 |
keep_backup default false + helper delete_backup_quietly; paridade de --backup em 4/4 subcomandos (write, edit, replace, rollback) e --keep-backup em 6/6 (write, edit, replace, rollback, apply, batch). |
0038 |
0038 |
| 0039 |
Sub-comando para N pares em 1 invocação; re-captura checksum opcional. |
0039 |
0039 |
| 0040 |
Cleanup manual para legados v0.1.20; flags --max-age-secs e --max-count. |
0040 |
0040 |
| 0041 |
allow_hyphen_values for 12 CLI text-accepting fields across 8 structs, since the three positionals require --; prevents exit 2 cascade in agent pipelines. |
0041 |
0041 |
| 0042 |
Backup default true in 9 content-mutating structs; --no-backup and ATOMWRITE_BACKUP=0 for opt-out (historical, pre-0.1.35, superseded). |
0042 |
0042 |
| 0043 |
Blocking shrink guard (exit 65) when --expect-checksum is active and stdin shrinks >50%; --allow-shrink for override. |
0043 |
0043 |
| 0044 |
--old-file/--new-file to bypass ARG_MAX; cross-mixing validation and trailing newline stripping. |
0044 |
0044 |
| 0045 |
ARGUMENT_PARSE_ERROR (exit 2) gains context-aware suggestion field pointing to --old-file/--new-file when error involves hyphen values. |
0045 |
0045 |
| 0046 |
diff now resolves file_a and file_b against workspace via validate_path (was the only command violating ADR-0027 convention). |
0046 |
0046 |
| 0047 |
scope read-only mode now correctly reports files_matched via Node::find_all; files_modified=None when no action configured. |
0047 |
0047 |
| 0048 |
Single BackupOpts struct flattened via #[command(flatten)] into 15 mutating subcommands; single resolve_backup() with precedence ATOMWRITE_BACKUP env > CLI flags > .atomwrite.toml [defaults] > built-in default (historical, pre-0.1.35, superseded). |
0048 |
0048 |
| 0049 |
load_config called once in lib.rs::run(); DefaultsSection propagated to every mutating handler, closing GAP-CONFIG-DEFAULTS-DEAD. |
0049 |
0049 |
| 0050 |
main.rs computes stdin.is_terminal() once and propagates stdin_is_tty down to cmd_edit; stdin-consuming edit modes fail fast with exit 65 instead of blocking indefinitely. |
0050 |
0050 |
| 0051 |
v0.1.29: fecha P0–P3 e residuais: fuzzy compartilhado, best_candidate, features core/slim, recipe real, durability, renameat2, agent-surface, foundation P3, schemas e documentação EN/PT alinhados à 0.1.29. |
0051 |
0051 |
| 0052 |
v0.1.30: fecha residual P17–P24: match_count, indent_adjusted, fuzzy off rejeitado, backup reflink_or_copy, recipe bak skip, sparse outline AST real, semantic-merge line-based, schema e docs. |
0052 |
0052 |
| 0053 |
Documented Clap audit exceptions (v0.1.32): BackupOpts.backup: Option<bool> tri-state; prescan_json_schema via std::env::args before Clap. |
0053 |
0053 |
| 0054 |
v0.1.34: one-pass fuzzy; embeds force 1; timeout default 120 / exit 124; cancel mid-cascade; caps; no telemetry; docs-complete of 0.1.33. Amended by 0065 and 0073. |
0054 |
0054 |
| 0055 |
v0.1.36: closes/mitigates GAP-2026-019…033: content-source jail + scratch init, error ok:false + match_count, fuzzy honesty (null similarity / dual-gate / soft-floor), agent-native --select/--filter/--limit, extract --field, CANONICAL_SUBCOMMAND_COUNT=46, ADR surface. Amended by 0061, 0065 and 0072. |
0055 |
0055 |
| 0056 |
Removes release_max_level_info so -vv/-vvv stay JSON-only with DEBUG/TRACE in release; measured median +1.60 % (inside noise), binary +17 216 bytes. |
0056 |
0056 |
| 0057 |
Documents third-party environment reads (sys-locale, directories, ureq proxy), keeps tree-sitter-language-pack download (measured: outline/query fail without it), MSRV 1.89, rust-i18n 4.2, serde-saphyr, notify 8. |
0057 |
0057 |
| 0058 |
v0.1.37: the 47th subcommand config path|list|get|set|unset over 37 typed keys, mandatory --scope, comment-preserving atomic write, answered before the config load. |
0058 |
0058 |
| 0059 |
v0.1.37: one src/retry.rs with full jitter, two stop conditions, 15 ms cancel slices and a budget cut to the global deadline. |
0059 |
0059 |
| 0060 |
v0.1.37: one 8 MiB byte budget shared by every search worker (search.max_inflight_bytes, 4 MiB to 1 GiB); default -j memory 142.6 MB to 45.3 MB. |
0060 |
0060 |
| 0061 |
v0.1.37: NdjsonWriter::publish_failure and VerdictPublished, so a failed run ends in exactly one terminal event; files_failed and errors[]. |
0061 |
0061 |
| 0062 |
v0.1.37: WAL H3 rate limit applies at journal creation only, startup_wal_heal limited to the argv directories with a 100 ms budget, cancelled runs leave no journal. |
0062 |
0062 |
| 0063 |
v0.1.37: SIGPIPE has a cooperative handler with exit 141, a DELIBERATE DEVIATION from the literal SIG_DFL owner rule (measured: 7 to 11 locks and 3 to 7 journals left with SIG_DFL). |
0063 |
0063 |
| 0064 |
v0.1.37: automatic threads min(CPUs, 16, RAM cap), walker capped at 12, explicit -j N honoured, rayon pool built on demand. |
0064 |
0064 |
| 0065 |
v0.1.37: fuzzy.max_content_bytes ceiling (256 MiB), escape_normalized cut at 32 MiB, CancelPoll in every fuzzy loop, dual-gate ties only. |
0065 |
0065 |
| 0066 |
v0.1.37: DoctorChecksFailed, doctor --strict exits 1 with DOCTOR_CHECKS_FAILED and the report as the single terminal line. |
0066 |
0066 |
| 0067 |
v0.1.37: closed terminal schemas, diff as a oneOf of four branches, 55 names served by --print-schema. |
0067 |
0067 |
| 0068 |
v0.1.37: common::hermetic for tests plus two source guards (hardcode; let _ = and panics) with empty allowance lists. |
0068 |
0068 |
| 0069 |
v0.1.37: constants.rs split into three include! parts and large modules split into .inc.rs files, public paths unchanged. |
0069 |
0069 |
| 0070 |
v0.1.37: watch is an opt-in feature; the default binary answers exit 78 with a rebuild hint and agent-surface reports available: false. |
0070 |
0070 |
| 0071 |
v0.1.37: extract-artifact returns bounded signal from PDF, OOXML and image headers, never raw bytes; limits are extract.* config keys. |
0071 |
0071 |
| 0072 |
v0.1.37: agent-native surface with global stream shaping flags, --print-schema answered before clap, --non-interactive and --confirm-side-effect. |
0072 |
0072 |
| 0073 |
v0.1.37: one terminal cancel point in the dispatch, deadline_exceeded always serialized, exits 129, 130, 143 and 124. Amends 0054. |
0073 |
0073 |
| 0074 |
v0.1.37: read-modify-write verbs take the advisory lock before they read (acquire_for_update), atomic_write_based fails with STATE_DRIFT (exit 82) on a stale base, and apply is strict (MATCH_FAILED, nothing written). |
0074 |
0074 |
| 0075 |
v0.1.37: tree-sitter-language-pack 1.22.1, ast-grep 0.51 and tree-sitter 0.27 in one move, which takes zstd from 0.13.3 to 0.14.3 and clears 4 vulnerabilities and 10 unsound warnings; rust-version rises to 1.90. Amends 0019 on the pack and 0057 on the MSRV. |
0075 |
0075 |
| 0076 |
v0.1.37: read takes several operands and expands one level of *, ? or [ itself, so --format raw concatenates like cat; the byte channel never carries an error envelope; --sort summaries stop claiming walker_stopped_early. |
0076 |
0076 |
| 0077 |
v0.1.37: a match is a file that answered (scope), a failure counts once per distinct path (transform --rules), a broken ignore file is a reported failure, case joins the answer-keeping family, the five read verbs carry the target stamp, and files_skipped/files_visited/total_matches descriptions match their producers. |
0077 |
0077 |
| 0078 |
v0.1.37: one schema per verb describing the whole stream, the error envelope as a branch of every union, child tags declared, and the served list down from 59 to 55 names backed by 54 files. Supersedes the name list of 0067. |
0078 |
0078 |
| 0079 |
v0.1.38: the exclusive lock is taken on the target inode with try_lock, the sidecar becomes best-effort compatibility, the swap revalidates the inode with same_file and fails STATE_DRIFT (exit 82), a read-only directory selects the in-place strategy, and apply/set/del/edit pass the base digest. Supersedes the sidecar requirement of 0031. |
0079 |
0079 |
| 0080 |
v0.1.38: sparse outline stops dropping the atomwrite journal by name, so the dotfile rule is the only exclusion and --hidden counts it; files_scanned becomes 3 on a folder the other verbs already counted as 3. Amends the walk policy of 0077. |
0080 |
0080 |
| 0081 |
v0.1.38: write publishes write_strategy, apply publishes write_strategy and backup_skipped, and a lock that cannot be taken names the target instead of the .atomwrite.lock sidecar. Amends 0078. |
0081 |
0081 |
| 0082 |
v0.1.38: sparse list honors --hidden, both sparse listing verbs drop a timestamped backup copy, and files_scanned says when a dotfile counts. Amends 0077 and refines the measurement of 0080. |
0082 |
0082 |
| 0083 |
v0.1.38: hash, copy -r and semantic-search hide dotfiles by default, WholeTree becomes CopyTree, sparse list and sparse outline take --all, and a path named in the invocation still wins. Amends 0082 and completes 0077. |
0083 |
0083 |
| 0084 |
v0.1.38: the seven mutating verbs publish write_strategy and backup_skipped, delete and the read actions of config report the mechanism honestly, and batch publishes the verdict per operation. Extends 0081. |
0084 |
0084 |
| 0085 |
v0.1.38: the nine verbs that rewrite content publish the same verdict, a preview publishes none, del on an absent key omits the field, and batch delete refuses to copy a copy. Extends 0084. |
0085 |
0085 |
| 0086 |
v0.1.38: apply publishes backup_path, a failed run that restored files publishes one rollback record, a failed restoration exits as TRANSACTION_ROLLBACK_FAILED, the schema of the verb becomes a union of plan, applied and rollback, and every optional verdict field declares a plain string. Extends 0081 and 0085. |
0086 |
0086 |
| 0087 |
v0.1.38: the snapshot of batch --transaction is removed when the run ends unless --keep-backup keeps it, --no-backup wins over it, and the rollback record of apply and of batch names every reverted path in target_resolved. Extends 0086. |
0087 |
0087 |
| 0088 |
v0.1.38: the commit keeps the snapshot of a target the transaction deleted, a failed reversal publishes failed_paths and backups_preserved, apply stamps stdin when the patch names its own file, and the rollback record publishes target_resolved always as an array. Extends 0087. |
0088 |
0088 |
| 0089 |
v0.1.38: target_resolved is always an array and the schema declares one shape, batch publishes warnings and backup_path on each operation and backups_preserved on the summary, move and copy keep the snapshot of the destination they overwrite, and a failed apply publishes the copies its rollback left. Amends 0088, amended by 0090. |
0089 |
0089 |
| 0090 |
v0.1.38: a transactional delete or move reports the snapshot the transaction already made instead of writing a second copy, and a failed apply carries the copy it created on the error and publishes it in backups_preserved. Amends 0089. |
0090 |
0090 |
| 0091 |
v0.1.38: a transactional write, replace, edit or copy reuses the snapshot the transaction already made, --keep-backup leaves one copy instead of two, the commit names a rewrite it preserves, and the source of move and copy is no longer snapshotted. Amends 0088 and 0090. |
0091 |
0091 |
| 0092 |
v0.1.38: delete creates a copy only when the call asks, --keep-backup only preserves one that exists, and the batch delete follows the same rule. Clarifies 0038, amended by 0093. |
0092 |
0092 |
| 0093 |
v0.1.38: [defaults].backup becomes Option<bool>, so an absent key keeps each verb's default while a written true reaches delete and the batch; --no-backup still wins and config get still omits value while the key is not written. Amends 0092. |
0093 |
0093 |
| 0094 |
v0.1.38: delete --recursive owns the whole named tree, removes hidden, ignored, linked, fifo, socket and device entries, refuses a backup inside the tree, and reports a surviving directory with the measured I/O error instead of a synthetic exit 65. Amends 0083, 0092 and 0093. |
0094 |
0094 |
| 0095 |
v0.1.38: search renders submatch text from the matched bytes with from_utf8_lossy instead of slicing &str at a matcher offset, so a zero-width or byte-oriented match inside a multi-byte character no longer aborts the run. |
0095 |
0095 |