Skip to content

IO format - #385

Merged
Byron merged 7 commits into
mainfrom
io-format
Aug 30, 2026
Merged

IO format#385
Byron merged 7 commits into
mainfrom
io-format

Conversation

@Byron

@Byron Byron commented Aug 29, 2026

Copy link
Copy Markdown
Owner

Fixes #137.

Tasks

  • validate
  • quick review

@Byron
Byron force-pushed the io-format branch 3 times, most recently from ab6c7fa to e2340f1 Compare August 30, 2026 07:37
Byron and others added 3 commits August 30, 2026 15:10
<!-- agent -->
## Snapshot format

- Add a deterministic version-1 `DUASNAP\0` codec for depth-first traversal
  forests while preserving input-root order and native Unix and Windows path
  representations.
- Encode parent distances, node flags, names, `u128` sizes, nanosecond
  modification times, and optional entry counts using canonical ULEB128 fields.
- Validate path components, tree structure, record limits, integer encodings,
  timestamps, node counts, checksums, truncation, and trailing data.
- Protect decoded snapshot data with SHA-256 and preserve deterministic child
  ordering.
- Support raw snapshots and streaming zlib compression through the existing
  `gix::zlib` dependency. Export at level 2 by default, accept levels 1–9, and
  use level 0 for raw output.
- Verify seekable snapshots once and rewind them for bounded-memory replay
  without materializing the full tree.

## CLI integration

- Add `dua interactive --export` to atomically persist a completed traversal
  through a neighboring temporary file before replacing the destination.
- Add `dua interactive --import` to load a snapshot into the terminal UI
  without traversing the filesystem.
- Add `dua aggregate --import` with flat, tree, depth-limited, sorted, total,
  and folded-stack output modes.
- Reject traversal-only paths and options when importing and print snapshot
  provenance to standard error.
- Preserve stored root ordering, sizes, entry counts, modification times, and
  metadata IO errors.

## Replay rendering

- Add completed-traversal and replay renderers for aggregate, tree, and
  folded-stack output.
- Keep only roots, displayed levels, or the current stack path in memory as
  required by each output mode.
- Use checked arithmetic for aggregate and exclusive-size calculations and
  report malformed snapshot totals instead of silently saturating.
- Handle the full `u128` snapshot size range and sanitize control characters
  when writing terminal output.

## Interactive safety

- Treat imported snapshots as read-only while retaining navigation, sorting,
  searching, marking, and display controls.
- Disable entry existence checks, filesystem refreshes, upward scans,
  gitignore discovery, permanent deletion, and trash operations.
- Show snapshot load statistics and replace destructive mark prompts and
  styling with an explicit read-only safety notice.
- Expose completed traversal roots in original input order for deterministic
  export.

Assisted-by: GPT 5.6
Co-authored-by: GPT 5.6 <codex@openai.com>
<!-- agent -->
## Command-line interface

- Add `dua diff OLD NEW` to compare an earlier traversal snapshot with a later
  one.
- Support byte-format selection either globally or after the subcommand, with
  the configured format as the fallback.
- Add `--directories-only` for aggregate directory changes, `--prefix PATH`
  for a component-aware subtree filter, and `--depth DEPTH` for limiting the
  displayed tree.
- Treat the selected root or prefix as the first displayed depth level while
  leaving summary calculations unbounded.
- Reject traversal-only options and input paths because diffing never walks
  the live filesystem.
- Fully validate both snapshots before writing output so a malformed input
  cannot leave a partial report.

## Streaming comparison

- Refactor snapshot decoding into a resumable decoder and entry iterator that
  can replay a verified, seekable snapshot without materializing its tree.
- Rewind each snapshot for every pass and verify its digest again at the end
  of replay, detecting files changed after initial validation.
- Expose native encoded names and duplicate-sibling ordinals from decoded
  entries to build deterministic comparison keys on Unix and Windows.
- Enforce canonical sibling ordering during decoding and distinguish repeated
  sibling names without changing the snapshot format.
- Merge the two canonical depth-first streams in lock-step, retaining only
  cursor state, ancestor paths and keys, and bounded summary entries.
- Pair roots in stored order and deliberately avoid cross-root matching or
  rename detection.
- Collapse an entirely added or removed directory to one change and skip its
  descendants, keeping large subtree changes concise.

## Diff output

- Report additions, removals, and signed size deltas with `+`, `-`, and `~`
  markers in a compact tree with shared directory context.
- Precede the tree with up to five largest additions and removals while still
  reporting the total number of changes in each category.
- Compare file sizes in the default mode and aggregate directory sizes in
  directory-only mode, including file-to-directory type changes.
- Preserve full `u128` size deltas and use the selected human-readable byte
  format.
- Mark depth-collapsed branches with an ellipsis without hiding their entries
  from the largest-change summary.
- Render terminal additions in green, removals in red, modifications in
  yellow, and directory context in cyan while keeping redirected output free
  of escape sequences.
- Use native path separators, sanitize control characters that could split
  output lines, and emit no output for identical snapshots or unmatched
  prefixes.

Assisted-by: GPT 5.6
Co-authored-by: GPT 5.6 <codex@openai.com>
<!-- agent -->
Keyboard shortcuts are configurable, but `--once` could only synthesize plain
character events. That made named and modified bindings impossible to reproduce
in one-shot debugging runs.

- Reuse the configuration keybinding parser for `--once`.
- Convert parsed bindings into terminal events.
- Preserve compact character sequences such as `--once=jko`.

Assisted-by: GPT 5.6
Co-authored-by: GPT 5.6 <codex@openai.com>
@Byron
Byron marked this pull request as ready for review August 30, 2026 14:03
Byron and others added 2 commits August 30, 2026 17:32
Admittedly, this one I waved through, but looked at the new storage for
a more tightly packed tree closely.
The parts with DirectoryId I just skipped over, as they are the most invasive
overall and touch a log of places.
Fine with me, everything seems to work, and this is beyond the time I can spend
on reviewing, while the value proposition is too high to skip it.

<!-- agent -->
## Traversal storage

- Replace `petgraph` with a 64-byte arena-backed tree and compact stable indices.
- Store native filenames in one append-only arena and reuse deleted node slots.
- Route parents through dense directory IDs and keep glob matches outside the filesystem topology.

## Snapshot replay

- Lend names from reusable record buffers and reuse sibling-order buffers by depth.
- Copy names only for retained entries and sort snapshots directly from arena bytes.
- Preserve the V1 encoding, validation, and platform-native path handling.

Assisted-by: GPT 5.6
Co-authored-by: GPT 5.6 <codex@openai.com>
Not reviewed at all, only functional tests.

<!-- agent -->
Depth-limited snapshot diffs now reveal the churn hidden beneath each collapsed directory.

- Accumulate gross additions and removals while preserving bounded streaming memory.
- Keep directory-only output and largest-change summaries unchanged.
- Cover mixed changes, overflow, root boundaries, context ordering, and terminal colors.

Assisted-by: GPT 5.6
Co-authored-by: GPT 5.6 <codex@openai.com>
@Byron
Byron merged commit 3343158 into main Aug 30, 2026
13 of 14 checks passed
@Byron
Byron deleted the io-format branch August 30, 2026 15:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Save and load?

1 participant