diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..068a997 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,19 @@ +# Changelog + +All notable changes to `diffs-rs` are recorded here. The forked crates in +`crates/` keep their own changelogs. + +## 0.1.1 - unreleased + +- docs: new README, docs moved under docs/. + +## 0.1.0 - 2026-10-27 + +First release. + +- `diffs` viewer for Git patches (file or stdin), two files, or two Git commits. +- Split and unified layouts, wrapping, dark and light themes, and a changed-file sidebar. +- Syntax colors from complete old and new sources for file and commit comparisons, with + incremental context expansion. +- Literal search, source-line selection, save of original bytes, and clipboard copy on macOS. +- `diffs_rs::engine::Engine` for embedding the viewer in a Ratatui application. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..449e21f --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,43 @@ +# Contributing + +Bug reports and pull requests are welcome at +[plannotator/diffs-rs](https://github.com/plannotator/diffs-rs). + +## Build and test + +The tests need Rust 1.88 or newer, Git 2.50 or newer, Python 3.11 or newer, `shasum`, and a +Unix PTY. Many of them run the real `diffs` binary against files, pipes, keys, and signals. + +```sh +cargo fmt --check +cargo clippy --locked --all-targets -- -D warnings +cargo clippy --locked --all-targets --all-features -- -D warnings +cargo test --release --locked -- --test-threads=1 +``` + +CI runs the same commands on Linux and macOS, plus a `cargo check` with Rust 1.88. + +The embedded-host checks need the example binary: + +```sh +cargo build --release --locked --example embedded_viewer +NATIVE_DIFF_HOST_BINARY="$PWD/target/release/examples/embedded_viewer" \ + cargo test --release --locked --test process engine_host_contract -- --ignored --test-threads=1 +``` + +Build instrumented features (`--all-features`) in a separate target directory so they do not +replace the normal binary. + +## Repository layout + +- `src/`: the library (`diffs_rs`) and the `diffs` binary. +- `crates/`: forks of syntect, fancy-regex, and two-face. Record any change to a fork in its + `PATCHES.md`. +- `tests/`, `fixtures/`: unit, process, and rendering tests and their inputs. +- `tools/`: Python scripts for the large-patch measurements in + [docs/measurements](docs/measurements/README.md). They are not needed for normal development. +- `docs/`: user guides, design notes, and the measurement and development records. + +## Commits + +Use lowercase conventional commit subjects, for example `fix: keep the cursor on resize`. diff --git a/Cargo.lock b/Cargo.lock index 44493ca..5ce04f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -449,7 +449,7 @@ dependencies = [ [[package]] name = "diffs-rs" -version = "0.1.0" +version = "0.1.1" dependencies = [ "anyhow", "arboard", diff --git a/Cargo.toml b/Cargo.toml index b5a4439..70372f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "diffs-rs" -version = "0.1.0" +version = "0.1.1" edition = "2024" rust-version = "1.88" description = "Fast terminal diff viewer and embeddable Rust diff engine" @@ -9,8 +9,6 @@ repository = "https://github.com/plannotator/diffs-rs" readme = "README.md" keywords = ["diff", "patch", "terminal", "tui", "ratatui"] categories = ["command-line-utilities", "development-tools", "text-processing"] -# Publishing stays off until the forks in crates/ are published first and the -# repository is public. See RELEASE_READINESS.md for the publish order. # Ship only what the library and binary need to build, plus the docs a reader # of the crate needs. Tests, fixtures, tools, reports and the forked crates in # crates/ (published separately) stay out of this package. @@ -22,7 +20,8 @@ include = [ "/Cargo.toml", "/Cargo.lock", "/README.md", - "/EMBEDDING.md", + "/CHANGELOG.md", + "/docs/embedding.md", "/LICENSE", "/NOTICE.md", ] diff --git a/README.md b/README.md index 74fc9f5..fadc9df 100644 --- a/README.md +++ b/README.md @@ -1,441 +1,150 @@ # diffs-rs -A read-only Rust terminal diff viewer and embeddable diff engine. -The crate is `diffs-rs` (library `diffs_rs`) and the executable is `diffs`. -The project was previously called `native-diff`. That name remains in the viewer's title bar, in the `NATIVE_DIFF_*` diagnostic and test environment variables, and in historical reports and evidence paths. +[![crates.io](https://img.shields.io/crates/v/diffs-rs.svg)](https://crates.io/crates/diffs-rs) +[![docs.rs](https://img.shields.io/docsrs/diffs-rs)](https://docs.rs/diffs-rs) +[![CI](https://github.com/plannotator/diffs-rs/actions/workflows/ci.yml/badge.svg)](https://github.com/plannotator/diffs-rs/actions/workflows/ci.yml) +[![License](https://img.shields.io/crates/l/diffs-rs.svg)](LICENSE) -Status, 2026-10-03: local macOS arm64 candidate with one engine for standalone and embedded use. -The standalone includes literal search, source-line selection, exact-byte save, and explicit clipboard copy. -The [sidebar report](SIDEBAR_REPORT.md) records its checks and remaining qualification work. -The completed local-engine milestone passed correctness, isolated installation and final handoff review. Its sealed source and evidence are preserved. Production hardening is now active; physical-terminal acceptance remains pending. Deferred experiments remain archived outside the active build. -The accepted storage changes, required-byte highlighting optimization, and cached-view cancellation are included. -No special source snapshot or manual executable replacement is necessary. +A fast terminal diff viewer, and the Rust diff engine behind it that you can embed in a Ratatui +application. -The viewer opens large patches progressively and supports split/unified layouts, wrapping, syntax colors, and changed-word emphasis. -Source and rendering checks pass for the covered cases. All four final resource cohorts passed evidence inspection on preserved ordinary binaries. -Large-input memory, indexing, and complete-search costs remain support limitations. Native clipboard, physical-terminal acceptance, and the final package remain pending. -The final notice inventory covers all 194 locked packages. Its upstream licensing caveat remains explicit. -This is not the complete v0.1 viewer in the [spec](SPEC.md). +![diffs showing a split diff with the changed-file sidebar](https://raw.githubusercontent.com/plannotator/diffs-rs/main/assets/screenshot.webp) -The [current project state](CURRENT_STATE.md) records capabilities, evidence, deferred work, and next steps. -The [embedding guide](EMBEDDING.md) documents the engine, host-owned terminal lifecycle, and the forked dependencies. -The [pre-cleanup README](evidence/clean-baseline-v1/before/documents/README.md) preserves the earlier checkpoint narrative. - -## Run the viewer - -Build from the repository root: - -```sh -cargo build --release --locked -``` - -The output is `target/release/diffs`. -If all dependencies are cached locally, add `--offline`. -The current resource record (external record `native-diff-production-hardening/RESOURCE_RESULTS.md`, not in this repository) identifies the measured viewer and host, target misses, and interpretation limits. -The installation record (external record `native-diff-production-hardening/INSTALLATION_RESULTS.md`, not in this repository) identifies the separate normal and minimum-compiler builds. Different executable hashes do not inherit timings. - -The qualified build environment is macOS arm64 with Rust 1.96.0, the separately checked Rust 1.88.0 minimum, and Xcode command-line build tools. Other platforms remain unqualified. For an isolated source installation, use `cargo install --path . --locked --root /absolute/path/to/an/isolated/prefix`; add `--offline` only after locked dependencies have been acquired. This does not add the prefix to PATH. - -The build compiles the libgit2 source bundled with the published `libgit2-sys` crate. -If `LIBGIT2_NO_VENDOR` is set to a nonzero value, unset it before building. -The build rejects an override that would select a system library. - -The syntax engine needs patched Syntect and Fancy Regex. They are separate crates built from [`crates/`](crates/) in this repository: -`diffs-fancy-regex` (Fancy Regex 0.16.2), `diffs-syntect` (Syntect 5.3.0), and `diffs-two-face` (two-face 0.5.2, built against `diffs-syntect` and otherwise essentially unchanged). -Each keeps its upstream library name, so the source still uses `fancy_regex::`, `syntect::` and `two_face::`. -Each fork's README and patch notes list its changes. The forks exist only for diffs-rs; other projects should use the upstream crates. - -In an existing Ghostty window, open the sample patch: - -```sh -target/release/diffs patch fixtures/review.patch -``` - -The viewer uses the current terminal. It does not open windows or tabs, or change terminal preferences. -At 120 available diff columns or more, the default layout is split. Smaller diff panes use unified layout. -The sidebar uses 33 columns, including its divider. -The minimum usable size is 40 columns by 10 rows. - -If `NO_COLOR` is set, remove it for this invocation to inspect the colors: - -```sh -env -u NO_COLOR target/release/diffs patch fixtures/review.patch -``` - -Other supported invocations: - -```sh -target/release/diffs --layout unified --theme light patch fixtures/review.patch -git --no-pager diff --no-ext-diff --no-textconv --no-color | target/release/diffs patch - -git --no-pager log -p -3 --no-color | target/release/diffs patch - -git format-patch --stdout -3 | target/release/diffs patch - -target/release/diffs inspect fixtures/review.patch --summary -``` - -`patch` reads Git patch text, including `git show`, `git log -p`, `git format-patch`, and `--stat -p` output. -Commit headers, messages, diffstats, and mail signatures between file patches are skipped. Source offsets still address the original input. -Text without a `diff --git` file header, traditional `diff -u` output, and combined merge diffs (`diff --cc`) remain errors. - -`inspect` emits diagnostic JSON. It is not a formatted pager mode. -`inspect --canonical` emits a binary source stream for independent checks and refuses terminal stdout. -A nonzero exit invalidates that entire stream, including any earlier output. -The interactive viewer requires terminal stdout and a controlling terminal for keyboard input. - -## Local source inputs - -These commands require Git 2.50 or newer. Qualification currently covers Git 2.50.1 on macOS arm64. - -```sh -target/release/diffs files OLD NEW -target/release/diffs git --repo PATH --base REV --head REV -``` - -The file command captures two regular files before comparison. It compares content, not original permission bits. -The Git command pins two commits and compares their trees directly. It does not select a merge base or use working-tree changes. -Only SHA-1 repositories are supported. Neither command runs external diff helpers, text conversion, hooks, or network fetches. -The viewer does not change the repository, index, working files, or refs. - -Git sources load for visible files, with the reading cursor first. Completed captures remain stable for the review. -The source check compares every supplied line and every omitted range through EOF, including exact final-newline behavior. -If source preparation fails, the patch remains readable and the viewer exits nonzero when closed. -Binary entries and submodules remain metadata. A missing source is not an empty or deleted file. - -Both modes now color checked sources from their complete preceding contents, with separate old/new parser state and filename-based language selection. -Hidden comments, strings, and embedded-language boundaries contribute to the parser state. Patch boundaries do not reset it. -Pending or unavailable sources use plain syntax. Change backgrounds and valid inline emphasis remain available. -The footer distinguishes pending coloring, complete-context coloring, unsupported languages, oversized source lines, and parser failure. -Complete context does not prove universal grammar accuracy. -Checked unchanged gaps show their remaining line count and a `Show 20` action. -Click the gap row, or select it with Up/Down and press Enter. -Leading gaps reveal code nearest the first supplied section. Other gaps reveal the next source lines forward. -Each action reveals at most 20 source lines, regardless of wrapping. Exhausted gaps disappear. -Expansion persists through theme, layout, wrapping, sidebar, and width changes. -Original patch markers and addition/deletion totals remain unchanged. Alignment padding never expands. -Binary and metadata-only entries do not become full-file viewers. Collapse and whole-file expansion remain outside this version. -The original `patch` command never guesses a repository or loads full source. - -For a noninteractive source report, add `--check`: - -```sh -target/release/diffs files OLD NEW --check -target/release/diffs git --repo PATH --base REV --head REV --check -``` - -This mode checks all textual file entries, not only visible files. It emits JSON with pinned identities, source states, and byte/line counts. -Its disk figure covers retained source bodies and line indexes, not patch storage, temporary helper output, or total process memory. -The [local-source report](LOCAL_SOURCE_INPUT_REPORT.md) records the evidence and remaining limits. -The [coloring checkpoint](FULL_SOURCE_COLOR_REPORT.md) records the complete-context implementation and its checks. -The [expansion checkpoint](CONTEXT_EXPANSION_REPORT.md) records context mapping, controls, and qualification limits. - -## Reading controls - -| Input | Action | -| --- | --- | -| `j` / `k`, arrows up/down | Move one display row | -| Page Up / Page Down | Move one page | -| Mouse wheel | Scroll three display rows per reported wheel event | -| `g` / `G` | Select the first / last available source line | -| `[` / `]` | Move to the previous / next hunk header | -| `n` / `N` | Move to the next / previous file header | -| Enter or click on a ready context gap | Reveal up to 20 unchanged source lines | -| Arrows left/right | Scroll horizontally, with wrapping off | -| Tab | Change the active side | -| `u` | Change split / unified layout | -| `w` | Toggle wrapping | -| `l` | Toggle line numbers | -| `t` | Change dark / light theme | -| `f` | Show and focus Files | -| `/` | Open the literal diff-text search prompt | -| F3 / Shift-F3 | Find the next / previous match | -| `V` | Begin a line selection / fix its range | -| Shift-click | Extend and fix a range within the same file and side | -| `y` | Copy the selected range or current source line as plain text | -| Ctrl-S | Save the selected range or current source line to a new file | -| Escape | Cancel a reading action / clear the selection / return from help or Files | -| `?` | Toggle help | -| `q`, Ctrl-C | Quit / cancel | - -Horizontal scrolling stops at the right edge of the widest visible source line, -accounting for both panes and their gutters. Extra Right presses do not accumulate -an invisible offset. Moving to shorter content or widening the window reduces the -offset when needed. Wrapped views ignore Left and Right. - -The active line is a reading cursor. `V` starts a separate source-line selection. -Start/end movement uses supplied patch order and focuses the selected source side. It skips headers, metadata-only files, and newline markers. -Both commands select the first wrapped segment of the endpoint line. Empty and metadata-only patches leave the view unchanged. -While input loads, the endpoints use completed files only. -Resizing, wrapping, and layout changes retain the source, side, and position within the displayed text. -Mouse selection retains the clicked text position. Keyboard movement establishes a new position at the start of its displayed segment. -Unwrapping retains the horizontal offset when possible, or adjusts it to reveal the anchored text. -File jumps select the adjacent file, even from inside the current file. They include metadata-only files and stop at either boundary without wrapping. -During loading, file jumps use completed files only. A later file arrival does not repeat an earlier command. - -### Literal search - -The standalone searches supplied diff text and context expanded before submission. It includes off-screen files and source lines. -It excludes file paths, headers, gutters, hidden context, and unchanged files outside the review. -Search is case-sensitive. It matches original UTF-8 bytes without normalization, regular expressions, or multiline queries. -Tabs match source tabs, not their displayed spaces. Display escapes do not replace original source bytes for search. - -Enter submits the prompt. Escape dismisses it or cancels an active search. An empty submission retains the previous query. -Printable keys, including `q`, edit the prompt. Ctrl-C still exits the viewer with cleanup. -The prompt accepts at most 4,096 UTF-8 bytes. It rejects an oversized or multiline paste as one event. -This limit does not bound terminal-input memory: the terminal event library collects the complete paste before the prompt receives it. -Arrow keys, Home/End, Backspace/Delete, and Ctrl-U edit the query. Cursor movement preserves complete Unicode graphemes. - -F3 and Shift-F3 move between matches in logical unified order. Shared context appears once. Old and new replacement records remain distinct. -Each request wraps at most once. Repeated F3 input during an active request does not queue more scans. -Existing `n` and `N` always keep their file-navigation behavior. -The current match uses bold and underline without changing its syntax colors or addition/deletion backgrounds. - -Search requires complete patch indexing. Expansion or a source change invalidates its captured scope and displays a restart notice. -F3 restarts the retained query against the new scope. Layout, theme, wrapping, and width changes retain that scope. -Physical F3/Shift-F3 support still requires terminal qualification. The tested modifier sequence is `CSI 13;2~`. -The legacy `CSI 1;2R` sequence conflicts with cursor-position reports in the current terminal event parser. -The final reading-tool cohort passed response, cancellation-feedback, and quit targets. Complete largest-patch scans took 10.97–11.38 seconds. -These are terminal-output observations, not physical paint or instantaneous worker-stop measurements. Filesystem calls can block, and the largest case misses memory targets. - -### Source-line selection - -`V` starts a range at the current source line. Navigation extends that range until another `V` fixes it. -Shift-click extends and fixes a range from the reading cursor or existing anchor. -Escape clears the range after closing a prompt, canceling reading work, or returning from help or Files. - -Each range belongs to one file occurrence and one original side. -The footer shows its original line numbers. Underlining marks selected source without replacing syntax colors or change backgrounds. -Wrapping, layout, theme, width, and context expansion preserve the range. -Unified navigation across opposite-side rows retains the range until another source line on its side becomes the endpoint. -An explicit side change, another file, review replacement, or withdrawal of its checked source clears the range. - -Headers, context-gap controls, newline markers, absent replacement halves, and wrapped padding cannot be endpoints. -A range can span omitted patch-only context, but source export rejects unavailable lines before writing them. -Column selection and cross-file ranges are not supported. -Physical terminal selection behavior remains subject to final qualification. - -### Save original source - -Ctrl-S opens a path prompt for the selected range, or the current source line without a selection. -The request retains that original side and range. Later navigation does not change its contents. -Enter starts preparation. Escape dismisses the prompt or cancels preparation before publication. -The prompt retains the last submitted path. Ctrl-U clears it for a different destination. -Paths are literal UTF-8, relative to the launch directory or absolute. The viewer does not expand `~`, variables, or shell commands. -The prompt rejects multiline paths, NUL, and input longer than 4,096 UTF-8 bytes. It preserves spaces and tabs. - -Save preserves original bytes, including tabs, invalid UTF-8, line endings, and the final-newline state. -It does not export gutters, visual wrapping, alignment padding, or display escapes. -Checked full sources can supply omitted context. A patch-only range with unavailable lines fails without creating the destination. -The viewer never overwrites an existing file, directory, or symlink. An error retains the selection for another attempt. - -The worker prepares output in an owner-only directory beside the destination, then flushes and syncs the file. -The input loop checks the current request and source before publication. Canceled or superseded preparation removes its private output. -After publication, cancellation cannot undo the saved file. A cleanup error reports that the file was saved and identifies remaining staging. -New output files have owner-only permissions. The viewer does not copy source permissions or create missing parent directories. -Cancellation checks run between bounded copies. Filesystem calls can still block, and interrupted-machine durability is not guaranteed. -Finite save-resource and cleanup checks pass in the final resource record (external record `native-diff-production-hardening/RESOURCE_RESULTS.md`, not in this repository). Physical-terminal acceptance remains pending. - -### Copy original source - -`y` copies the selected range, or the current source line without a selection. -Copy retains the original side, tabs, Unicode, line endings, and final-newline state. -It excludes gutters, visual wrapping, alignment padding, and display escapes. -Unavailable source gaps fail instead of joining separate fragments. - -The macOS build accepts valid UTF-8 text up to 16 MiB. Larger ranges and invalid UTF-8 require Ctrl-S to save their original bytes. -The size limit bounds the text passed to the native API, which can allocate additional copies. It is not a total-memory guarantee. -The viewer publishes plain text without RTF or EPS content detection. It does not send terminal clipboard sequences. - -One reading worker prepares an anonymous private file before the input loop accepts delivery. -An owned helper receives that file directly, without terminal input or output. -The worker retains at most 4 KiB of diagnostic text and terminates a helper that exceeds its five-second deadline. -The viewer reaps an interrupted helper before another copy can start. - -Escape cancels preparation without changing the clipboard. Once delivery starts, interruption or failure cannot guarantee that the previous clipboard survives. -Opening search or a save prompt also cancels pending copy work and reports this uncertainty after delivery starts. -Errors retain the selection. Ctrl-S remains available when clipboard delivery fails. - -Clipboard support is optional and macOS-only. `--no-default-features` disables it without removing source selection or save. -Controlled-process checks cover source fidelity and helper lifecycle. Native clipboard round-trip, native helper memory, and physical-terminal acceptance remain pending. - -## Changed files - -The sidebar shows changed files under their exact patch directory hierarchy. -It does not scan the filesystem, combine directory levels, or reorder the patch. -Folders appear before files, with byte-sorted names. File activation uses the original patch entry. -File rows show status and textual additions/deletions. Folder rows show descendant file counts and totals. -Binary files show `B binary`, not textual zero counts. Repeated paths show occurrence suffixes. -The `*` marker identifies the current diff file. The `>` marker identifies the focused tree row. - -The sidebar appears automatically for two or more completed files. -It requires at least 97 terminal columns and ten rows. -Narrow windows hide the sidebar without discarding its expansion state. -The `--sidebar` and `--no-sidebar` flags override the initial file-count preference, but not the minimum width. -These flags conflict. Interactive visibility changes last only for the process. - -With Files focused: - -| Input | Action | -| --- | --- | -| Up/Down, `k`/`j` | Move the tree cursor without moving the diff | -| Page Up/Down, Home/End | Move by a page or to a visible-list boundary | -| Left/Right | Collapse or expand folders, or move to a parent or child | -| Enter | Open the selected file or toggle a folder | -| Space | Toggle the selected folder | -| Escape, Tab | Return focus to the diff | -| `f` | Hide Files and return to the diff | - -A click opens a file or toggles a folder. The wheel scrolls the pane under the pointer. -Newly completed files retain existing selection and expansion state. -The heading marks counts as partial during loading. Input failures leave completed files accessible and show an incomplete-result message. -The `g` / `G` bindings select source endpoints. The `n` / `N` bindings move between changed files. -The earlier `{` / `}` file bindings are removed. Numeric prefixes are outside the current scope. -A file picker is not implemented. Source-line selection, copy, and save use the diff cursor rather than the Files cursor. - -## Implementation - -One Cargo package contains one library and one executable. Ratatui draws the terminal cells. - -| Module | Responsibility | -| --- | --- | -| `ingest.rs` | Read file-patch units and check their hunk boundaries | -| `model.rs` | Parse file-patch units through libgit2 and apply the existing line-pairing rule | -| `model/rename_names.rs` | Quote rename and copy names that libgit2 would cut at whitespace, and map parser offsets back | -| `storage.rs` | Publish compact patch indexes and stable source identities | -| `source.rs` | Capture immutable source bodies, disk line indexes, and exact correspondence | -| `input` | Bind local comparisons, supervise Git, and prepare visible source pairs | -| `storage/bytes.rs` | Own private append-only byte stores, checked references, and shared cached pages | -| `source_spans.rs` | Store checked compact/wide source ranges and final-newline flags | -| `projection.rs` | Resolve both layouts and inverse lookups from shared source/change blocks | -| `view.rs` | Map immutable patch rows and incrementally exposed source ranges into each layout | -| `text.rs` | Display safe text and calculate grapheme columns | -| `geometry.rs` | Cache safe display text and sparse/wrapped boundaries within fixed payload and entry limits | -| `theme.rs` | Load the attributed palettes and compose terminal colors | -| `highlight.rs` | Produce syntax colors and inline spans on a worker thread, cache disposable styles | -| `app.rs` | Hold the reading position and apply navigation/settings changes | -| `render.rs` | Draw visible terminal cells through Ratatui | -| `main.rs` | Read inputs, drive Crossterm, handle signals, and restore the terminal | - -The input worker publishes complete files while later input loads. The event loop remains available for navigation and cancellation. -Exact source bytes and encoded patch source offsets use private disk-backed storage. -Source identities, newline flags, projection metadata, and other indexes retain resident costs. -The byte store can share one 32 MiB page-payload allowance with additional source stores. -Local source inputs, complete-context coloring, and context expansion use this storage foundation. Remote inputs remain separate work. -The [storage checkpoint](SOURCE_STORAGE_REPORT.md) records compatibility and cleanup checks against the preserved viewer. -One current file still uses temporary resident parser data during conversion. -After a later parse failure, earlier complete files remain readable with an incomplete status. Normal quit then returns 1. -The UI draws visible rows. A separate worker supplies syntax colors and inline emphasis after source content appears. -The status row distinguishes pending highlighting from completed styling or a plain-text fallback. -Visible styles stay protected while new colors arrive, so cache eviction cannot leave a completed request with missing visible colors. -The retained-style target is 32 MiB. If the visible styles alone exceed it, they remain available until the viewport changes; offscreen styles are evicted first. This is not a total-memory bound. - -Syntax uses Syntect and the Two Face grammars. Word differences use `similar`. -The local syntax backend skips a regex search only when the complete line lacks a provably required ASCII byte. -All other searches use the existing matcher. This preserves rule priority, captures, and side-specific parser state. -The [integration report](evidence/required-bytes-adoption-v1/REPORT.md) records correctness checks and the accepted cache-occupancy tradeoff. -Shared context keeps separate old/new syntax colors when the surrounding syntax states differ. Unified context uses the new-side colors. -Patch-only continuation resumes within the same hunk and theme generation. -Checked-source continuation follows each complete file side across patch boundaries. Hidden replay uses bounded sequential buffers and retains no offscreen style vectors. -Verified identical hidden ranges can share parsing when both sides use the same known grammar and have equal parser and scope state. -Each side keeps its own source position. Visible lines remain independently colored, and divergent states continue independently. -Bounded parser checkpoints also let backward requests and uncached revisits resume from compatible prior state. -During a complete-source file job, compatible checkpoints needed by that request stay protected from eviction. -If unprotected space is unavailable, parsing continues without another checkpoint. Protection ends with the job, including cancellation. -The limits remain 64 entries, 16 MiB in aggregate, and 256 KiB per entry. -The [retention decision](LOCAL_SOURCE_RETENTION_DECISION.md) records the saved parser work and accepted smaller-workload costs. -When a requested viewport needs no new styles, the application cancels obsolete coloring through the existing mailbox. -Queued styles must match both the theme epoch and source origin. Cancellation does not interrupt an individual regex instruction. -Cold requests replay the supplied hunk prefix in patch-only mode, or the complete source prefix in checked-source mode. -Offscreen replay advances syntax scopes without generating color spans. Both modes share the existing checkpoint budget. -Syntax coverage follows the bundled grammars. Universal grammar coverage and exact agreement with other viewers' replacement pairing are not established. -Very long lines use declared plain styling instead of syntax and word emphasis. -In patch-only mode, the affected side stays plain through that hunk. In checked-source mode, it stays plain through EOF, including later hunks. -A skipped source line cannot safely preserve parser state. The other side remains independent, and source text stays complete. -Uneven-replacement alignment uses a bounded search with positional pairing outside it. This fallback remains a presentation limitation. -Theme assets retain their Apache-2.0 license and attribution in [NOTICE.md](NOTICE.md). - -## Run the process checks - -The tests require Rust, Git 2.50 or later, Python 3.11 or later, `shasum`, and a Unix PTY. -They run the actual executable with real files, pipes, keys, and signals. -They do not launch a GUI terminal or capture the screen. +## Install ```sh -cargo test --release --locked -- --test-threads=1 -cargo clippy --locked --all-targets -- -D warnings -cargo fmt --check +cargo install diffs-rs --locked ``` -For optional diagnostic-feature checks, use a separate target directory: +This installs the `diffs` binary. Building needs Rust 1.88 or newer and a C compiler for the +bundled libgit2. -```sh -cargo test --release --locked --all-features --target-dir target/diagnostic-tests -- --test-threads=1 -``` - -This keeps the normal executable separate from instrumented builds. -The standard process suite passes 77 checks and excludes ten opt-in checks. Six host checks run separately with an explicit host executable. -The other four checks require pinned corpus or preserved-reference inputs. The corpus endpoint check requires the five downloaded patches: +## Usage ```sh -cargo test --release --locked --test process diffshub_corpus_opens_and_keeps_exact_end_anchors_in_both_layouts -- --ignored --exact --test-threads=1 +diffs patch changes.patch # a patch file +git diff --no-color | diffs patch - # a patch on stdin +git log -p -3 --no-color | diffs patch - # git show, log -p, and format-patch output work +diffs files old.rs new.rs # two files +diffs git --repo . --base main --head HEAD # two commits, compared tree to tree +diffs --layout unified --theme light patch changes.patch ``` -The old pre-storage visual comparison remains a historical check, not the current acceptance reference. - -To check the shared projection against the preserved pre-refactor model: - -```sh -cargo run --release --locked --example projection_equivalence -- --patterns fixtures/review.patch fixtures/position/review.patch +`--layout` is `auto`, `split`, or `unified`; `--theme` is `dark` or `light`. `--sidebar` and +`--no-sidebar` override the changed-file sidebar. `diffs files` and `diffs git` accept `--check` +to verify every source byte and print a JSON report instead of opening the viewer. Press `?` in +the viewer for all key bindings. + +`diffs` never changes the repository, index, or working tree, and makes no network requests. + +## Features + +- Split and unified layouts, wrapping, line numbers, and dark and light themes. +- Syntax colors for the bundled grammars, with changed-word emphasis. +- For `files` and `git`, colors are computed from the complete old and new sources, and unchanged + gaps can be expanded 20 lines at a time. +- A changed-file sidebar with the patch's directory tree and per-file and per-folder counts. +- Large patches open progressively; the first screen appears while the rest is still indexing. +- Literal search across the whole diff (`/`, F3). +- Source-line selection (`V`), saving the original bytes (Ctrl-S), and plain-text copy (`y`, macOS). +- Mouse support: wheel scrolling, clicking files, folders, and context gaps. + +## Performance + +On the Linux `v6.0...v7.0` patch (711 MB, 76,872 files, 421,819 hunks): + +| Measure | Result | +| --- | ---: | +| First text on screen | 11.8 ms | +| First syntax colors | 35.5 ms | +| Navigation, p95 of the slowest action type | 8.6 ms | +| Peak memory | 594 MiB | + +The first prototype used 2,590 MiB on the same patch and still failed to open it. Times are +medians of five fresh processes on an Apple M5 Max with a warm file cache, measured when the +correct output reached a 160 x 50 PTY, on pre-release builds. The +[measurements](docs/measurements/README.md) page has all five test patches, the method, and +the open memory goals. + +## Embedding + +```toml +[dependencies] +diffs-rs = { version = "0.1", default-features = false } +anyhow = "1" +ratatui = { version = "0.30.2", default-features = false, features = ["crossterm"] } ``` -Pass the pinned corpus paths to the same command for complete large-patch row, source, inverse-lookup, partner, metadata, and navigation-boundary comparisons. It holds only a bounded number of file-patch units. This regression reference supplements the independent source and terminal-cell checks; it does not replace them. - -To retain diagnostic terminal-cell previews, set a capture directory: - -```sh -diffs_capture=$(mktemp -d) -NATIVE_DIFF_CAPTURE_DIR="$diffs_capture" cargo test --release --locked -- --test-threads=1 +The host owns the terminal and the event loop. The engine loads and colors the review on +background threads and draws into any `Rect`: + +```rust +use std::{sync::mpsc, time::Duration}; + +use diffs_rs::engine::{Engine, Input, Options}; +use ratatui::crossterm::event::{self, Event, KeyCode}; + +fn main() -> anyhow::Result<()> { + let mut terminal = ratatui::init(); + // The engine sends a hint on this channel when background work is ready. + let (wake, woken) = mpsc::sync_channel(1); + let input = Input::Patch("changes.patch".into()); + let mut engine = Engine::open(input, Options::default(), wake)?; + + let result = (|| -> anyhow::Result<()> { + loop { + let _ = woken.try_recv(); + engine.poll()?; + if engine.needs_draw() { + let mut drawn = Ok(()); + terminal.draw(|frame| { + let area = frame.area(); + drawn = engine.draw(frame, area); + })?; + drawn?; + engine.after_draw(); + } + if event::poll(Duration::from_millis(16))? { + let event = event::read()?; + if matches!(&event, Event::Key(key) if key.code == KeyCode::Char('q')) { + return Ok(()); + } + engine.handle_event(event, true)?; + } + } + })(); + + // Joins the background workers and reports cleanup errors. + let closed = engine.close(); + ratatui::restore(); + result.and(closed) +} ``` -These SVG/ANSI previews come from actual PTY output. They are not Ghostty screenshots or proof of display timing. - -The [rendering contracts](tests/process/README.md) add independent expected rows, cell boundaries, changed spans, syntax roles, and metadata checks. -They also record the reproduced syntax-side and binary-label defects and the remaining correctness limits. - -## Run the five-patch checks - -The [five-patch plan](FIVE_PATCH_ACCEPTANCE.md) defines the independent interior checks and the frozen measurement boundary. -The corpus bodies and independent source references must already exist at their manifest paths. -The commands use the existing local Python environment with [measurement requirements](tools/measurement-requirements.txt). - -```sh -cargo build --release --locked --bin diffs --example sequential_style_reference -corpus_run=$(mktemp -d) -.measurement-venv/bin/python tools/corpus_acceptance.py target/release/diffs target/release/examples/sequential_style_reference "$corpus_run/rehearsal" --fixture pierre-0800fb -.measurement-venv/bin/python tools/corpus_measure.py "$corpus_run/rehearsal/trace.json.gz" "$corpus_run/freeze" --prepare-only -.measurement-venv/bin/python tools/corpus_measure.py "$corpus_run/rehearsal/trace.json.gz" "$corpus_run/results" --freeze "$corpus_run/freeze/freeze.json" -``` +`Input` also accepts an open stream, two files, or two Git commits. The +[embedding guide](docs/embedding.md) covers the host loop, focus, source coordinates, the reading +tools, and shutdown. [`examples/embedded_viewer.rs`](examples/embedded_viewer.rs) is a complete +host with its own pane beside the viewer. -The first Python command checks real PTY captures against independent source data and sequential syntax colors. -The freeze step challenges the checker with corrupted captures and binds the inputs, code, and executables by hash. -The final command runs five fresh-process timing repetitions. It rejects changed identities and existing output directories. -For a three-tour memory run, add `--memory` to the rehearsal command and use separate output directories. -Fixture IDs are `pierre-0800fb`, `ghostty-12291`, `node-59805`, `bun-30412`, and `linux-v6-v7`. -Run one measured workload at a time. Linux public-key setup can take several minutes per repetition. -These checks observe PTY cells, not Ghostty pixels. The [project overview](CURRENT_STATE.md) records results and remaining limits. +## Platform support -## Remaining work +Unix only: the viewer needs a PTY, `/dev/tty`, and Unix signals. macOS on Apple silicon is the +most tested platform. Linux runs the full test suite in CI. Windows is not supported. +`diffs files` and `diffs git` need Git 2.50 or newer. -The final five-patch, complete-source coloring, repeated-host, and reading-tool cohorts passed evidence inspection. -The memory, indexing, and complete-search limitations remain explicit in the resource record. -Native clipboard and physical-terminal acceptance, and local packaging remain open. -The [current project state](CURRENT_STATE.md) owns the ordered next steps and the preserved evidence. -The [shared position fixture](fixtures/position/README.md) and [terminal procedure](TERMINAL_PRESENTATION_CHECK.md) support the postponed visual check. +## Forked dependencies -PTY checks do not establish physical paint, frame pacing, or trackpad feel. -Ghostty is the intended physical-terminal target, but its acceptance remains incomplete. Other terminals and multiplexers remain unqualified, outside this local-candidate requirement. -The full [acceptance checklist](ACCEPTANCE.md) is not complete. +Syntax highlighting uses forks of three crates, published as +[`diffs-syntect`](crates/diffs-syntect/PATCHES.md) (syntect 5.3.0), +[`diffs-fancy-regex`](crates/diffs-fancy-regex/PATCHES.md) (fancy-regex 0.16.2), and +[`diffs-two-face`](crates/diffs-two-face/README.md) (two-face 0.5.2, rebuilt against +`diffs-syntect`). The patches share compiled regex engines between identical grammar patterns, +reuse search buffers within a line, and skip searches that cannot match because a required byte +is missing from the line. Matching results are unchanged. On the test traces this lowered live +heap from 275 MiB to 213 MiB and halved the time to color a deep, first-visited file, from +1,494 ms to 752 ms. The forks exist for diffs-rs; other projects should use the upstream crates. -## Boundaries +## License -The local candidate targets macOS arm64. Historical source and comparison identities remain in their evidence records. -The viewer performs no editing, staging, telemetry, network requests, or unsolicited clipboard writes. -No maintainer contact, publishing, global installation, or multi-candidate benchmark runs form part of this work. +Apache-2.0. See [LICENSE](LICENSE). The bundled theme and the forked crates keep their own +licenses, listed in [NOTICE.md](NOTICE.md). diff --git a/assets/screenshot.webp b/assets/screenshot.webp new file mode 100644 index 0000000..3a2d5c3 Binary files /dev/null and b/assets/screenshot.webp differ diff --git a/crates/diffs-fancy-regex/Cargo.toml b/crates/diffs-fancy-regex/Cargo.toml index 024be3d..723d715 100644 --- a/crates/diffs-fancy-regex/Cargo.toml +++ b/crates/diffs-fancy-regex/Cargo.toml @@ -23,7 +23,6 @@ include = [ "/AUTHORS", "/LICENSE", ] -# Not published yet. RELEASE_READINESS.md in diffs-rs gives the publish order. [package.metadata.diffs-rs.upstream] crate = "fancy-regex" diff --git a/crates/diffs-syntect/Cargo.toml b/crates/diffs-syntect/Cargo.toml index 8522f66..75bb71f 100644 --- a/crates/diffs-syntect/Cargo.toml +++ b/crates/diffs-syntect/Cargo.toml @@ -29,7 +29,6 @@ include = [ "/CHANGELOG.md", "/LICENSE.txt", ] -# Not published yet. RELEASE_READINESS.md in diffs-rs gives the publish order. [package.metadata.diffs-rs.upstream] crate = "syntect" diff --git a/crates/diffs-syntect/PATCHES.md b/crates/diffs-syntect/PATCHES.md index 253dc82..025dccd 100644 --- a/crates/diffs-syntect/PATCHES.md +++ b/crates/diffs-syntect/PATCHES.md @@ -38,7 +38,8 @@ The optional `regex-census` feature additionally exposes a borrowed snapshot in `src/parsing/regex_census.rs`. It inspects initialized static cells only, records owner identities, and does not load grammars, compile regexes, or clone owners. It is disabled in ordinary application builds. The application-level scope and -real-grammar controls are in `REGEX_CENSUS_PLAN.md` and `tests/regex_census.rs`. +real-grammar controls are in `docs/measurements/REGEX_CENSUS_PLAN.md` and `tests/regex_census.rs` +in the diffs-rs repository. The optional `owner-census` feature adds `src/parsing/owner_census.rs` for the Fancy Regex backend. It deduplicates initialized outer cells before visiting diff --git a/crates/diffs-two-face/Cargo.toml b/crates/diffs-two-face/Cargo.toml index d108f4a..65e94ca 100644 --- a/crates/diffs-two-face/Cargo.toml +++ b/crates/diffs-two-face/Cargo.toml @@ -28,7 +28,6 @@ include = [ "/LICENSE-APACHE", "/LICENSE-MIT", ] -# Not published yet. RELEASE_READINESS.md in diffs-rs gives the publish order. [package.metadata.diffs-rs.upstream] crate = "two-face" diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..f121974 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,30 @@ +# Documentation + +## Guides + +- [embedding.md](embedding.md): embed the diff engine in a Ratatui application. +- [release.md](release.md): publish the crates. +- [measurements/](measurements/README.md): large-patch timing and memory results, and how they + were measured. + +## Design + +[design/](design/) has the specifications the viewer was built against: + +- [SPEC.md](design/SPEC.md): product behavior, controls, and presentation. +- [LARGE_DIFFS.md](design/LARGE_DIFFS.md): the large-patch workload and its targets. +- [EXACT_SOURCE_CONTEXT_SPEC.md](design/EXACT_SOURCE_CONTEXT_SPEC.md): full-source coloring and + context expansion. +- [INPUT_SCENARIO_ANALYSIS.md](design/INPUT_SCENARIO_ANALYSIS.md): input sources, including + proposed GitHub pull request support. +- [SIDEBAR_SPEC.md](design/SIDEBAR_SPEC.md): the changed-file sidebar. +- [ACCEPTANCE.md](design/ACCEPTANCE.md): the acceptance checklist. + +Some of these describe features that are not implemented yet. + +## History + +[history/](history/README.md) keeps the dated plans, reports, and reviews from development +before the first release, including the full development log in +[CURRENT_STATE.md](history/CURRENT_STATE.md). They record what was measured or decided at +the time and are not current instructions. diff --git a/ACCEPTANCE.md b/docs/design/ACCEPTANCE.md similarity index 93% rename from ACCEPTANCE.md rename to docs/design/ACCEPTANCE.md index d7ab0d9..8a31506 100644 --- a/ACCEPTANCE.md +++ b/docs/design/ACCEPTANCE.md @@ -1,11 +1,11 @@ # Acceptance checklist Status: 31 real-process checks pass as of 2026-09-11. The five-patch interior/latency/memory batch is complete; no full milestone is complete. -The [rendering contracts](tests/process/README.md) define the new independent terminal checks and their limits. -The [large-diff progress report](docs/history/LARGE_DIFF_PROGRESS.md) records the current source checks and remaining acceptance work. -The [implementation report](docs/history/IMPLEMENTATION_STATUS.md) records the tested subset, limitations, and open visual acceptance. +The [rendering contracts](../../tests/process/README.md) define the new independent terminal checks and their limits. +The [large-diff progress report](../history/LARGE_DIFF_PROGRESS.md) records the current source checks and remaining acceptance work. +The [implementation report](../history/IMPLEMENTATION_STATUS.md) records the tested subset, limitations, and open visual acceptance. The [large-diff specification](LARGE_DIFFS.md) replaces provisional scale-fixture selection with the five exact cached DiffsHub inputs and defines the next batch. -The [five-patch results](docs/history/FIVE_PATCH_RESULTS.md) records its independent interior checks and current-build measurements. +The [five-patch results](../history/FIVE_PATCH_RESULTS.md) records its independent interior checks and current-build measurements. The [spec](SPEC.md) owns behavior and defaults. This file owns evidence and milestone completion. ## The evidence rules @@ -110,6 +110,6 @@ The original implementation passed ten development checks. Later work brought th All five large patches pass the complete supplied-source digest comparison. The new rendering contracts cover explicit small-screen expectations. The full milestone cells remain open because their requirements include additional evidence. The existing Pierre browser reference and user-supplied Ghostty screenshot do not establish complete visual acceptance. -Geometry-cache eviction and sparse Unicode boundaries now pass independent process checks. The [responsiveness batch](docs/history/RESPONSIVENESS.md) records the scope. -Deep old/new syntax, continued fallback, and hunk/theme isolation pass independent process checks. The [syntax replay batch](docs/history/SYNTAX_REPLAY.md) records the limits. -The five-patch batch now covers 205 independent interior PTY states per patch, five latency repetitions per patch, and three memory tours per patch. All interior oracles and corruption controls pass. Pierre has one styled distant-seek maximum above the strict 200 ms guard. Ghostty alone meets the current memory envelope; Pierre, Node, Bun, and Linux exceed their applicable RSS limits. Actual Ghostty pixel behavior, display timing, and full milestone acceptance remain open. See [FIVE_PATCH_RESULTS.md](docs/history/FIVE_PATCH_RESULTS.md). +Geometry-cache eviction and sparse Unicode boundaries now pass independent process checks. The [responsiveness batch](../history/RESPONSIVENESS.md) records the scope. +Deep old/new syntax, continued fallback, and hunk/theme isolation pass independent process checks. The [syntax replay batch](../history/SYNTAX_REPLAY.md) records the limits. +The five-patch batch now covers 205 independent interior PTY states per patch, five latency repetitions per patch, and three memory tours per patch. All interior oracles and corruption controls pass. Pierre has one styled distant-seek maximum above the strict 200 ms guard. Ghostty alone meets the current memory envelope; Pierre, Node, Bun, and Linux exceed their applicable RSS limits. Actual Ghostty pixel behavior, display timing, and full milestone acceptance remain open. See [FIVE_PATCH_RESULTS.md](../history/FIVE_PATCH_RESULTS.md). diff --git a/EXACT_SOURCE_CONTEXT_SPEC.md b/docs/design/EXACT_SOURCE_CONTEXT_SPEC.md similarity index 98% rename from EXACT_SOURCE_CONTEXT_SPEC.md rename to docs/design/EXACT_SOURCE_CONTEXT_SPEC.md index a4a13f8..d153901 100644 --- a/EXACT_SOURCE_CONTEXT_SPEC.md +++ b/docs/design/EXACT_SOURCE_CONTEXT_SPEC.md @@ -1,9 +1,9 @@ # Exact-source coloring and expandable context Date: 2026-09-22. -Status: feature specification, with [storage/reference groundwork](SOURCE_STORAGE_REPORT.md) and [local source inputs](LOCAL_SOURCE_INPUT_REPORT.md) implemented. -The [complete-context coloring checkpoint](FULL_SOURCE_COLOR_REPORT.md) implements the coloring stage. -The [context expansion checkpoint](CONTEXT_EXPANSION_REPORT.md) implements incremental local expansion. Integrated resource and physical-terminal qualification remain open. +Status: feature specification, with [storage/reference groundwork](../history/SOURCE_STORAGE_REPORT.md) and [local source inputs](../history/LOCAL_SOURCE_INPUT_REPORT.md) implemented. +The [complete-context coloring checkpoint](../history/FULL_SOURCE_COLOR_REPORT.md) implements the coloring stage. +The [context expansion checkpoint](../history/CONTEXT_EXPANSION_REPORT.md) implements incremental local expansion. Integrated resource and physical-terminal qualification remain open. This specification refines the input, syntax, and context proposals in [SPEC.md](SPEC.md). The [input scenario analysis](INPUT_SCENARIO_ANALYSIS.md) defines the broader source modes, GitHub requirements, and delivery priorities. @@ -59,7 +59,7 @@ The patch parser, line pairing, inline emphasis, and canonical patch export rema New context must not become fake additions, deletions, or extra original patch records. The implementation must not increase every stored patch record to hold optional full-file metadata. -The existing [sidebar report](SIDEBAR_REPORT.md) owns current correctness evidence. +The existing [sidebar report](../history/SIDEBAR_REPORT.md) owns current correctness evidence. Existing measurements do not describe this proposed feature or a future executable. ## 3. Inputs and exact version identity @@ -504,7 +504,7 @@ Public evidence cannot qualify private authentication or enterprise hosts. Recor Each stage preserves its ordinary executable and source identity before the next stage changes runtime behavior. Historical evidence and prepared measurement binaries stay unchanged. -The compatibility-only store/reference refactor is complete, as recorded in the [storage checkpoint](SOURCE_STORAGE_REPORT.md). +The compatibility-only store/reference refactor is complete, as recorded in the [storage checkpoint](../history/SOURCE_STORAGE_REPORT.md). The local-source checkpoint adds snapshots, disk indexes, local identities, exact correspondence, and both local commands. The expansion checkpoint preserves the typed identity mapping before it adds range expansion and terminal controls. Its concrete review type represents complete local comparisons only. Partial/unknown remote coverage states remain part of the remote adapter checkpoint. diff --git a/INPUT_SCENARIO_ANALYSIS.md b/docs/design/INPUT_SCENARIO_ANALYSIS.md similarity index 100% rename from INPUT_SCENARIO_ANALYSIS.md rename to docs/design/INPUT_SCENARIO_ANALYSIS.md diff --git a/LARGE_DIFFS.md b/docs/design/LARGE_DIFFS.md similarity index 98% rename from LARGE_DIFFS.md rename to docs/design/LARGE_DIFFS.md index 9365129..b8494ec 100644 --- a/LARGE_DIFFS.md +++ b/docs/design/LARGE_DIFFS.md @@ -1,6 +1,6 @@ # Large-diff foundation: implementation specification -Date: 2026-09-10. Status: implementation started, not performance-accepted. See the [progress report](docs/history/LARGE_DIFF_PROGRESS.md). +Date: 2026-09-10. Status: implementation started, not performance-accepted. See the [progress report](../history/LARGE_DIFF_PROGRESS.md). ## 1. Decision and scope @@ -16,7 +16,7 @@ DiffGrid remains untouched. No maintainer contact, publishing, global installati ## 2. Exact workload The pinned [DiffsHub route source](https://github.com/pierrecomputer/pierre/blob/0a7a733078f093577cd21ca65d2508806a22238a/apps/diffshub/app/api/diff/route.ts) contains five cached patch mappings. -All five downloaded bodies now have SHA-256 identities in [corpus.json](fixtures/diffshub/corpus.json). +All five downloaded bodies now have SHA-256 identities in [corpus.json](../../fixtures/diffshub/corpus.json). The CDN bytes define the workload. A current PR response or a newly generated Git diff cannot silently replace them. | Required input | Bytes | Physical lines | File records | Hunks | @@ -95,7 +95,7 @@ Steady RSS is the maximum during the settled portion of a third fixed memory tou Disk spool size, source/index allocations, cache payloads, and OS memory measurements remain separate fields. Kernel filesystem cache outside process RSS is not described as free memory or included in an allocator-only claim. After warm-up, retained state must plateau within its explicit budgets. A tour cannot retain another document-sized structure. -Each tour visits the fixed file quantiles and structural extremes defined in [scenario.json](fixtures/diffshub/scenario.json). +Each tour visits the fixed file quantiles and structural extremes defined in [scenario.json](../../fixtures/diffshub/scenario.json). It is not an exhaustive display of all 20 million lines. The separate full-content check covers every supplied source segment. Failure leaves a target unmet. It does not justify silently changing the corpus, excluding expensive files, or weakening visual settings. @@ -267,7 +267,7 @@ No dashboard or multi-candidate benchmark framework is required. Missing GUI acc | E | Release evidence and visual corrections | All five required cases meet targets, with actual Ghostty appearance/movement signoff recorded separately. | Step A includes pinned source digests, structural anchors, and an original parse/index diagnostic. -The [content-grid protocol](MEASUREMENT.md) adds a resolved input trace and a runner for the preserved interactive baseline. +The [content-grid protocol](../measurements/MEASUREMENT.md) adds a resolved input trace and a runner for the preserved interactive baseline. Its scope excludes style completion, normalized full-metadata coverage, long-line tours, and steady-memory acceptance. Those requirements remain pending. Step B now includes the private spool, progressive file publication, compact source records, and compressed display ranges. Full source checks and selected corpus terminal checks pass. A shared block index still needs implementation or an evidence-based design review. diff --git a/SIDEBAR_SPEC.md b/docs/design/SIDEBAR_SPEC.md similarity index 99% rename from SIDEBAR_SPEC.md rename to docs/design/SIDEBAR_SPEC.md index 35ff8f8..e786e35 100644 --- a/SIDEBAR_SPEC.md +++ b/docs/design/SIDEBAR_SPEC.md @@ -1,7 +1,7 @@ # Changed-file sidebar: implementation specification Date: 2026-09-22. -Status: implemented. The [implementation report](SIDEBAR_REPORT.md) records checks and limits. +Status: implemented. The [implementation report](../history/SIDEBAR_REPORT.md) records checks and limits. The user approved the feature boundary and the exact directory hierarchy. The controls and dimensions below define the first implementation. diff --git a/SPEC.md b/docs/design/SPEC.md similarity index 98% rename from SPEC.md rename to docs/design/SPEC.md index 3f694f5..3007bb2 100644 --- a/SPEC.md +++ b/docs/design/SPEC.md @@ -1,7 +1,7 @@ # Native diff viewer: product spec v0.1 Status: proposed behavior, not a description of an existing implementation. -Implementation progress is recorded separately in [IMPLEMENTATION_STATUS.md](docs/history/IMPLEMENTATION_STATUS.md). +Implementation progress is recorded separately in [IMPLEMENTATION_STATUS.md](../history/IMPLEMENTATION_STATUS.md). The [large-diff implementation specification](LARGE_DIFFS.md) now owns the next batch, exact scale corpus, and proposed performance targets. Date: 2026-09-10. Scope: a read-only Rust terminal viewer. The name and proposed defaults remain open to user review. @@ -101,7 +101,7 @@ Both layouts use the same source identities and inline-change spans. A layout sw - Syntax colors remain visible over change backgrounds. Whole changed lines do not become solid red or green text. - Inline emphasis covers changed spans, not the entire replacement line. - Inline comparison separates punctuation from words and preserves complete graphemes. Unchanged separators do not receive emphasis. -- Identifiers retain word-level emphasis. The [inline policy](docs/history/INLINE_HIGHLIGHTING.md) defines boundaries and covered checks. +- Identifiers retain word-level emphasis. The [inline policy](../history/INLINE_HIGHLIGHTING.md) defines boundaries and covered checks. - A small gutter marker identifies the active source line without covering its inline highlights. - No blinking decoration, scrolling animation, or automatic movement accompanies background highlighting. @@ -312,7 +312,7 @@ An input or allocation failure produces an explicit incomplete-result state. It - The small correctness corpus and generated single-hunk/long-line cases diagnose specific failures. They cannot replace a failing showcase. - A separate 1 GiB generated workload is outside the next batch. -The [corpus manifest](fixtures/diffshub/corpus.json) pins downloaded bytes and records structural inventory. +The [corpus manifest](../../fixtures/diffshub/corpus.json) pins downloaded bytes and records structural inventory. Full source-blob correspondence and viewer measurements remain pending. Live PR refs do not replace the pinned CDN bodies. Pierre's performance claims are not our results or pass thresholds. This product work makes no clean-room independence claim. diff --git a/EMBEDDING.md b/docs/embedding.md similarity index 78% rename from EMBEDDING.md rename to docs/embedding.md index 900f1e7..95611d5 100644 --- a/EMBEDDING.md +++ b/docs/embedding.md @@ -1,31 +1,28 @@ -# Embed the local diff engine +# Embedding the diff engine `diffs_rs::engine::Engine` owns one review, its view state, source storage, and background workers. -The standalone viewer and `examples/embedded_viewer.rs` use this same implementation. -This API is a local integration candidate, not a stable published crate API. -[CURRENT_STATE.md](CURRENT_STATE.md) separates the completed local-engine milestone from the current candidate. -The final four resource cohorts passed evidence inspection, with resource-target misses retained. Both isolated installations passed. -Native clipboard, physical-terminal acceptance, and the final package remain pending. The final notice inventory is complete, with its upstream licensing caveat retained. +The `diffs` binary and [`examples/embedded_viewer.rs`](../examples/embedded_viewer.rs) use this same implementation. +The API is pre-1.0 and can change between minor versions. ## Dependency setup -Use a path dependency on the source package. The host must use Ratatui 0.30. +The host must use Ratatui 0.30. ```toml [dependencies] -diffs-rs = { path = "../diffs-rs" } +diffs-rs = { version = "0.1", default-features = false } ratatui = { version = "0.30.2", default-features = false, features = ["crossterm"] } ``` -Adjust the path for the host's workspace. -The patched syntax engine comes from the forked crates `diffs-syntect`, `diffs-fancy-regex` and `diffs-two-face` in `crates/`. They are ordinary dependencies of `diffs-rs`, so the host needs no `[patch]` section. -Their library names stay `syntect`, `fancy_regex` and `two_face`. A host that also depends on upstream Syntect gets a second, separate copy whose types do not interoperate with the fork's. -The Git patch parser is the stock `libgit2-sys` crate. The build fails if `LIBGIT2_NO_VENDOR` asks it to link a system libgit2. -Do not substitute upstream Syntect, Fancy Regex or two-face, or a system libgit2, to make dependency resolution succeed. -Keep the host's generated lockfile and use `--locked` for subsequent builds. -Diagnostic crate features are not required for embedding. The default `dev-tty` feature makes Crossterm read keyboard input from `/dev/tty`, which the standalone viewer needs when a patch arrives on stdin. -Crossterm features are shared by the whole build, so a host that reads its own input should add `default-features = false` and enable `clipboard` only if it wants the native clipboard. +Crossterm features are shared by the whole build, so a host that reads its own input should use `default-features = false`. +Enable the `clipboard` feature only if the host wants the native macOS clipboard. +Diagnostic crate features are not required for embedding. + +The patched syntax engine comes from the forked crates `diffs-syntect`, `diffs-fancy-regex` and `diffs-two-face`. They are ordinary dependencies of `diffs-rs`, so the host needs no `[patch]` section. +Their library names stay `syntect`, `fancy_regex` and `two_face`. A host that also depends on upstream Syntect gets a second, separate copy whose types do not interoperate with the fork's. +Do not substitute upstream Syntect, Fancy Regex or two-face to make dependency resolution succeed. +The Git patch parser is the stock `libgit2-sys` crate with its bundled libgit2. The build fails if `LIBGIT2_NO_VENDOR` asks it to link a system libgit2. ## Ownership @@ -43,7 +40,7 @@ Caller-held duplicates must not read, seek, or change those flags concurrently. The patch reader temporarily enables nonblocking input and restores the original nonblocking bit when it finishes or closes. It supports cancellation while waiting for a FIFO writer, an idle stream, or an incomplete line. The safe descriptor-set implementation rejects descriptors at or above `FD_SETSIZE` before changing flags. -This is a Unix implementation. The currently tested system is macOS arm64; other platforms remain unqualified. +This is a Unix implementation. macOS arm64 is the most tested system; Linux runs in CI. ## Host loop @@ -120,9 +117,6 @@ The standalone owns its save prompt, private output, no-clobber publication, and The standalone also owns clipboard preparation, its helper process, and delivery acceptance. Its optional `clipboard` feature enables macOS plain-text publication. Engine-only consumers can disable default features to omit that dependency. The engine does not launch clipboard helpers or handle the standalone `y` key. -These APIs have functional evidence and finite final-build resource checks. -The resource record (external record `native-diff-production-hardening/RESOURCE_RESULTS.md`, not in this repository) retains response results, complete-scan costs, memory misses, and cancellation limits. -Native clipboard and physical-terminal acceptance remain separate pending requirements. ## Failure and shutdown @@ -148,21 +142,13 @@ Cancellation cannot interrupt one in-progress syntax-parser call or an operating No universal shutdown-latency bound is promised. The engine does not detach unfinished workers or leave old reviews running after a successful close. -Closing a review does not promise that process RSS returns to its opening value. In the prior three-cycle patch-host schedule, closed live heap was identical across cycles, but macOS allocator-held empty regions retained substantial resident memory. Closed RSS reached about 590 MiB. See the prior resource results (external record `native-diff-local-engine-milestone/RESOURCE_RESULTS.md`, not in this repository). - -A preceding three-cycle host qualification covered a 12,000-line file pair, a pinned 12-file Git review, and small-patch replacement. -Each ordinary and diagnostic process passed 96 stages. Closed live malloc heap was 1,116,528 bytes at all three diagnostic checkpoints, without retained regular file descriptors. -Ordinary first-close RSS medians rose from 33.516 to 34.188 MiB. -The historical full-source results (external record `native-diff-production-hardening/FULL_SOURCE_RESOURCES.md`, not in this repository) identify those earlier builds and diagnostic limits. - -The final ordinary host passed the same 96-stage schedule across three cycles. Maximum held RSS was 33.98 MiB, with a 42.00 MiB sampled process-group peak. -Closed RSS medians rose 0.41 MiB. Closed states retained no numeric regular-file descriptor, named private source, or owned child. -The final resource record (external record `native-diff-production-hardening/RESOURCE_RESULTS.md`, not in this repository) identifies the exact host and workload. -These finite observations do not establish indefinite stability, live-heap size, a largest-input capacity bound, or a total-memory guarantee. +Closing a review does not promise that process RSS returns to its opening value: the macOS allocator can keep freed regions resident. +After a large patch, closed RSS reached about 590 MiB even though live heap had returned to its earlier size. +On a three-cycle schedule of file-pair, Git, and small-patch reviews, the example host stayed under 34 MiB held RSS, and closed RSS rose 0.41 MiB across the cycles. ## Try the host example -From the package root: +From a clone of this repository: ```sh cargo run --release --locked --example embedded_viewer -- fixtures/review.patch fixtures/position/review.patch diff --git a/docs/history/BASELINE_REPORT.md b/docs/history/BASELINE_REPORT.md index fe07f83..0f8a87a 100644 --- a/docs/history/BASELINE_REPORT.md +++ b/docs/history/BASELINE_REPORT.md @@ -63,7 +63,7 @@ The smallest recorded navigation interval was 50.0035 ms. Only one measured comm The largest navigation validation duration was 10.83 ms. No overhead was subtracted from observations. The background RSS sampler remained bounded and reported no errors. -The [frozen contract](../../MEASUREMENT.md) describes the boundaries and reducers. +The [frozen contract](../measurements/MEASUREMENT.md) describes the boundaries and reducers. The read-only method review found five harness defects before retained trials. All five were corrected before the final freeze. The earlier, unrun freeze remains in `evidence/measurement-preflight/unrun-freeze-v1` for inspection. It is not the measurement freeze. diff --git a/CONTEXT_EXPANSION_REPORT.md b/docs/history/CONTEXT_EXPANSION_REPORT.md similarity index 100% rename from CONTEXT_EXPANSION_REPORT.md rename to docs/history/CONTEXT_EXPANSION_REPORT.md diff --git a/CURRENT_STATE.md b/docs/history/CURRENT_STATE.md similarity index 90% rename from CURRENT_STATE.md rename to docs/history/CURRENT_STATE.md index af6e789..d94a500 100644 --- a/CURRENT_STATE.md +++ b/docs/history/CURRENT_STATE.md @@ -2,7 +2,7 @@ Updated 2026-10-13. This page owns the current status and next steps. Historical plans describe their original checkpoints, not additional active tasks. -Dated plans and reports from finished experiments are in [docs/history](docs/history/README.md). +Dated plans and reports from finished experiments are in [docs/history](README.md). ## Standalone repository cleanup, 2026-10-13 @@ -128,7 +128,7 @@ The tree-cache proposal is closed without adoption; do not resume its old compar The decision (external record `native-diff-cache-decision/DECISION.md`, not in this repository) and durable evidence archive preserve the disposition. The isolated tree candidate was subsequently checked with Rust 1.88; the previous statement that the compiler was unavailable is historical. The integrated local engine has now also passed its own minimum-compiler installation and contracts. -The new `Engine` owns review orchestration and is shared by the standalone viewer and a bounded-pane host example. Hosts retain terminal modes, input and outer focus. Patch, local-source, coloring, key and signal workers now have owned shutdown. Input errors remain readable/recoverable; cleanup errors and worker panics are preserved. The patch reader uses safe readiness waits and restores stream flags, including cancellation of no-writer FIFOs and partial lines. Interactive stdin must be piped or redirected, not the keyboard TTY. [EMBEDDING.md](EMBEDDING.md) documents source coordinates, lifecycle, descriptor limits and the required downstream Cargo patches. +The new `Engine` owns review orchestration and is shared by the standalone viewer and a bounded-pane host example. Hosts retain terminal modes, input and outer focus. Patch, local-source, coloring, key and signal workers now have owned shutdown. Input errors remain readable/recoverable; cleanup errors and worker panics are preserved. The patch reader uses safe readiness waits and restores stream flags, including cancellation of no-writer FIFOs and partial lines. Interactive stdin must be piped or redirected, not the keyboard TTY. [EMBEDDING.md](../embedding.md) documents source coordinates, lifecycle, descriptor limits and the required downstream Cargo patches. The integrated ordinary suite passed 135 checks, including 61 process checks, with six opt-in checks excluded. Four real-worker/renderer engine checks cover bounded cells/styles, focus, both sides, wrapped padding, checked context, sidebar and source replacement. The two opt-in real PTY host checks passed separately, covering live-host close/reopen, failed-input recovery, resize, FIFO cancellation and terminal restoration. A separate Cargo root built and ran the engine with exact source endpoint assertions. Independent review prompted cleanup-error aggregation and poison-safe cancellation. The host calls `after_draw()` only after successful terminal output, preserving text-before-work order and delivery-event meaning. Strict all-target/all-feature application Clippy passed; the existing vendored lifetime warning remains. @@ -201,7 +201,7 @@ The table allocation stayed unchanged across the three end-of-tour snapshots. Th These component counts are not process RSS or a memory-saving result. The integration plan (temporary verification record `2026-09-27-cache-integration.IhX6h6/PLAN.md`, not retained) defines this checkpoint. -The [storage report](docs/history/STYLE_CACHE_STORAGE_REPORT.md#integration-and-bounded-owner-observations) records the completed checks and limitations. +The [storage report](STYLE_CACHE_STORAGE_REPORT.md#integration-and-bounded-owner-observations) records the completed checks and limitations. The accounting reports table allocation, retained vector capacity, FIFO capacity, and inline cache storage separately. The existing style charge, budget, eviction order, invalidation, and source/color behavior remain unchanged. @@ -287,7 +287,7 @@ The adoption decision (temporary verification record `2026-09-25-2141-memory.vsW Only the reviewed representation and test adaptations were integrated. Cache admission, budgets, weights and eviction remain unchanged. The normal build was restored after Cargo's test build replaced its executable, then checked directly. Both binaries and the failed identity-check log remain preserved. The memory measurements belong to the preserved candidate, not a new measurement of the integrated executable. -The [diagnostic invalidation accounting](docs/history/CACHE_ACTIVITY_ACCOUNTING.md) is qualified. +The [diagnostic invalidation accounting](CACHE_ACTIVITY_ACCOUNTING.md) is qualified. Activity schema 2 counts source-driven removals separately from budget eviction and reconciles retained entries, payload, and usable map capacity. Real source replacement, revocation, recovery, stale replies, unrelated-file survivors, theme reset, and owner release passed. The ordinary suite, compatible-baseline grids, and seven real-process census controls also passed; the normal executable is unchanged. @@ -300,7 +300,7 @@ Ordinary held RSS was about 29.42 and 33.45 MiB, unchanged between the final dee The file pair's opening already colored its deep patch sections; later jumps were cached. These bounded complete-source observations do not replace the large patch-only memory evidence or establish a long-term plateau. That observation did not include shared page occupancy, geometry, or live parser storage. No additional cache policy or representation change was selected. -The [retained-owner extension](docs/history/RETAINED_OWNER_ACCOUNTING.md) now measures those owners and current checkpoints in opt-in builds only. +The [retained-owner extension](RETAINED_OWNER_ACCOUNTING.md) now measures those owners and current checkpoints in opt-in builds only. It passed 124 ordinary checks, 43 targeted diagnostic checks, 96 compatible terminal grids, two canonical source streams, seven real-process census controls, and 11 malformed-record checks. Repeated observations preserve owner addresses, reference counts, cache contents, and terminal cells in the tested cases. The normal executable remains unchanged. The new bounded observation (temporary verification record `2026-09-26-retained-owners.6F99J4/REPORT.md`, not retained) is partial. @@ -319,13 +319,13 @@ The final Git snapshot retained 94,958 page-payload bytes, 55,177 geometry-paylo Those owner counts and the existing style/engine counts stayed unchanged on revisit. Diagnostic RSS rose by 655,360 bytes; that difference remains unattributed, not a demonstrated leak or an optimization result. Power was battery for this capture. The earlier ordinary process is a grid control, not a matched memory or timing comparison. -The [current allocation attribution](docs/history/CURRENT_ALLOCATION_ATTRIBUTION.md) is complete without a runtime change. +The [current allocation attribution](CURRENT_ALLOCATION_ATTRIBUTION.md) is complete without a runtime change. One current diagnostic Bun process passed 418 exact views, four owner snapshots, twelve native commands, 1,233 audited queries, and clean exit. Direct color-output and matched style-table/FIFO classes account for 77.23% of its first-to-third-tour native heap increase. The final style vectors retained 11.41 MiB of spare capacity, already included in their charge. This is not a process-memory saving. Pages stayed unchanged across tours. Geometry, checkpoints, and live parser state remained small in this workload. The grammar/outer-regex review did not justify a storage change or more instrumentation. -The [direct token collection prototype](docs/history/DIRECT_TOKEN_COLLECTION_REPORT.md) is implemented in an isolated copy, without token merging, boxed storage, or cache-policy changes. +The [direct token collection prototype](DIRECT_TOKEN_COLLECTION_REPORT.md) is implemented in an isolated copy, without token merging, boxed storage, or cache-policy changes. It passes 126 ordinary checks, 45 targeted diagnostic checks, 96 compatible terminal grids, and all 20,847,451 supplied source records. The preserved ordinary candidate separately passes all 61 enabled terminal-process checks. Exact token and syntax-state comparisons pass across 2,358 source-line advances. Recorded capacities are smaller for 2,142 visible lines, equal for 104, and larger for none. @@ -343,15 +343,15 @@ Navigation and focused coloring remained close in the observed pairs. Linux inde All five prototype sustained-process peaks were lower, including Linux at 800.56 versus 770.30 MiB. That does not establish a causal saving. Linux's third-tour settled maximum was 800.50 versus 663.56 MiB, but its final held sample was 634.70 versus 663.56 MiB. Bun's final held sample was also higher for the prototype, despite its lower process peak. Both roles contain substantial residency declines. Host-wide VM statistics do not attribute them to viewer allocation release or compression. Those decreases are not credited to the prototype. -The [qualification report](docs/history/DIRECT_TOKEN_COLLECTION_REPORT.md) preserves every patch, both directions of the memory observations, and the bounded follow-up scope. -The [bounded residency investigation](docs/history/DIRECT_TOKEN_COLLECTION_REPORT.md#completed-bounded-residency-investigation) is complete. +The [qualification report](DIRECT_TOKEN_COLLECTION_REPORT.md) preserves every patch, both directions of the memory observations, and the bounded follow-up scope. +The [bounded residency investigation](DIRECT_TOKEN_COLLECTION_REPORT.md#completed-bounded-residency-investigation) is complete. One small control and two Linux diagnostic processes passed 414 expected views, six owner snapshots, twelve native commands, twelve holds, and 2,531 audited RSS queries. The prototype's final native heap was 646.25 MiB versus 624.46 MiB, despite less vector slack. Its style-table capacity high-water mark was 458,752 versus 229,376. The larger table arose during insertion and eviction without a new entry-count peak. Other measured final page, geometry, parser/checkpoint, and engine owners matched. This supports a container-growth mechanism, not complete attribution of earlier ordinary RSS. Direct token collection is closed without adoption. All evidence remains preserved, and the normal executable remains unchanged. -The [whole style-cache accounting checkpoint](docs/history/STYLE_CACHE_STORAGE_REPORT.md) is complete in an isolated copy. +The [whole style-cache accounting checkpoint](STYLE_CACHE_STORAGE_REPORT.md) is complete in an isolated copy. It reports table allocation, retained vector capacity, FIFO capacity, and observed-build inline storage without overlap. The existing style charge and retention policy remain unchanged. This is accounting, not a memory reduction or a total-cache limit. The prototype passed 124 ordinary checks, 140 diagnostic checks, 96 preserved-viewer grids, and two canonical source streams. @@ -366,7 +366,7 @@ No measurement or diagnostic is currently active. See [Next work](#next-work) fo This section preserves prior results and build identities. Its measurements do not describe the current executable. -The [Git-completion notification](docs/history/LOCAL_SOURCE_GIT_WAKE_REPORT.md) is implemented independently of checkpoint retention. +The [Git-completion notification](LOCAL_SOURCE_GIT_WAKE_REPORT.md) is implemented independently of checkpoint retention. It uses the existing stderr reader to wake the child-status check, while preserving cancellation and the actual exit-status requirement. At that checkpoint, the normal suite passed 118 checks, with 18 diagnostic opening grids and 198 ordinary action grids. Git and Rust-source opening improved in every ordinary pair. Large-source opening and later actions remained mixed. @@ -381,12 +381,12 @@ Those observations remain accepted tradeoffs, not claims of a universal speedup Integrated local-source responsiveness and sustained-resource qualification remain separate from the patch-only corpus campaign. No further retention-policy experiment is selected. -The [sidebar-aware corpus qualification](docs/history/SIDEBAR_CORPUS_REPORT.md) prepared ten current-build workload packets across the five pinned patches. +The [sidebar-aware corpus qualification](SIDEBAR_CORPUS_REPORT.md) prepared ten current-build workload packets across the five pinned patches. All 1,765 selected workload views passed source and sequential-color checks, with 272 rejected corruption cases. The separate 15-view geometry trace and its 15-view frozen-matcher replay also passed. The normal executable and runtime source remain unchanged. These preparation results are separate from the measurements below. -The [current-build patch measurements](docs/history/SIDEBAR_MEASUREMENT_REPORT.md) are complete: 30 successful processes and 7,350 checked views. +The [current-build patch measurements](SIDEBAR_MEASUREMENT_REPORT.md) are complete: 30 successful processes and 7,350 checked views. All measured navigation categories, initial text/color goals, and normal exits passed. Linux completed-index receipt took a median 4.65 seconds and did not meet the 2-second goal. The final memory tours reached 174.1 MiB for Bun and 663.6 MiB for Linux. @@ -397,21 +397,21 @@ These are shared-workstation PTY observations, not physical-paint measurements o One preserved memory failure exposed a test-only sidebar reset omission. A qualified public-input reset corrected all five memory traces. No viewer code changed, and none of the 25 completed latency trials repeated. -The [current ownership investigation](docs/history/CURRENT_MEMORY_OWNERS_REPORT.md) is complete without a runtime change. +The [current ownership investigation](CURRENT_MEMORY_OWNERS_REPORT.md) is complete without a runtime change. Current document accounting totals 361.82 MiB for Linux and 9.36 MiB for Bun. One native Bun profile passed all 418 expected views and clean shutdown. Live allocations increased by 30.45 MiB between tours one and three. Direct color-token output and matched style-cache container classes account for 79.62% of that diagnostic increase. Those instrumented values do not partition the earlier ordinary RSS observations. -The [source-span representation census](docs/history/SOURCE_SPAN_CENSUS_REPORT.md) is complete without a production change. +The [source-span representation census](SOURCE_SPAN_CENSUS_REPORT.md) is complete without a production change. All 20,847,451 corpus records reconcile with preserved counts and storage extents. The conditional model saves 35.05 MiB of accounted storage on Linux after descriptor costs, but adds 75,238 allocations. These are modeled extents, not a heap, RSS, or performance improvement. Some small fixtures become larger. -The [isolated exact-length storage prototype](docs/history/SOURCE_SPAN_PROTOTYPE_REPORT.md) now passes correctness qualification without a production change. +The [isolated exact-length storage prototype](SOURCE_SPAN_PROTOTYPE_REPORT.md) now passes correctness qualification without a production change. Its source suite passed 122 checks. The preserved ordinary release matched 96 compatibility grids and all 1,770 corpus workload views. All 20,847,451 source records and 42,657,296 split/unified projection rows matched independent expectations. Actual retained storage matches the census model, including descriptor costs and small-file increases. -The [ordinary-build comparison](evidence/source-span-prototype-v1/COMPARISON_REPORT.md) is complete: 60 eligible processes and 14,700 exact terminal views passed the offline audit. +The [ordinary-build comparison](../../evidence/source-span-prototype-v1/COMPARISON_REPORT.md) is complete: 60 eligible processes and 14,700 exact terminal views passed the offline audit. All 62 attempts remain intact, including two power-ineligible attempts. The original 48 eligible processes did not repeat. The prototype remains unadopted. Linux settled RSS increased from 679.7 to 728.4 MiB in the third tour. Its memory-process peak increased from 704.2 to 748.2 MiB. Every candidate memory tour had higher RSS than the reference. @@ -423,38 +423,38 @@ The proposed follow-up separated live allocations and their owners from allocato The existing first Linux tour already contains the adverse difference. The Bun opening difference also remains unresolved. That experiment left the ordinary source and executable unchanged. -The changed-file sidebar is implemented against [its specification](SIDEBAR_SPEC.md). +The changed-file sidebar is implemented against [its specification](../design/SIDEBAR_SPEC.md). It retains the exact patch directory hierarchy, with folder expansion, counts, keyboard controls, and mouse controls. The [sidebar report](SIDEBAR_REPORT.md) preserves that feature's original build identity, checks, and limits. The patch-only performance campaign is complete. Historical executables and evidence remain unchanged. -The [exact-source coloring and expandable context](EXACT_SOURCE_CONTEXT_SPEC.md) feature is implemented for local inputs. +The [exact-source coloring and expandable context](../design/EXACT_SOURCE_CONTEXT_SPEC.md) feature is implemented for local inputs. Its specification covers stable source versions, source correspondence, memory limits, Rust structure, controls, and acceptance gates. -The [input scenario analysis](INPUT_SCENARIO_ANALYSIS.md) expands the proposed contract beyond local commits and files. +The [input scenario analysis](../design/INPUT_SCENARIO_ANALYSIS.md) expands the proposed contract beyond local commits and files. It names GitHub PR acquisition as the next adapter milestone, with explicit comparison identity, completeness, and per-side source availability. The [storage/reference groundwork](SOURCE_STORAGE_REPORT.md) is implemented and checked against the preserved sidebar executable. The [local source input checkpoint](LOCAL_SOURCE_INPUT_REPORT.md) implements captured two-file and fixed two-commit comparisons. The [complete-context coloring checkpoint](FULL_SOURCE_COLOR_REPORT.md) uses those checked sources for independent old/new syntax replay. The [context expansion checkpoint](CONTEXT_EXPANSION_REPORT.md) adds incremental `Show 20` actions for checked local sources. -The [source-readiness correction](docs/history/SOURCE_READINESS_REPORT.md) keeps the selected source visible as lazy source replies insert gap rows. -The [local-source hardening pass](docs/history/LOCAL_SOURCE_HARDENING_REPORT.md) reviews ownership and failure recovery without changing runtime code. +The [source-readiness correction](SOURCE_READINESS_REPORT.md) keeps the selected source visible as lazy source replies insert gap rows. +The [local-source hardening pass](LOCAL_SOURCE_HARDENING_REPORT.md) reviews ownership and failure recovery without changing runtime code. It adds input-worker shutdown checks and updates dependency maintenance notes. The prepared executable remains unchanged. -The [short local-source timing checkpoint](docs/history/LOCAL_SOURCE_TIMING_REPORT.md) passed ten AC-powered runs and all 110 expected views. +The [short local-source timing checkpoint](LOCAL_SOURCE_TIMING_REPORT.md) passed ten AC-powered runs and all 110 expected views. It measures two modest local-source workloads, not sustained scrolling or the five-patch memory campaign. -The [coloring investigation](docs/history/LOCAL_SOURCE_COLORING_REPORT.md) attributes the two-file delay mainly to hidden-source parsing. +The [coloring investigation](LOCAL_SOURCE_COLORING_REPORT.md) attributes the two-file delay mainly to hidden-source parsing. Its diagnostic and ordinary sampled processes passed all 33 final views. No runtime source changed. -The [saved-state reuse checkpoint](docs/history/LOCAL_SOURCE_REPLAY_REPORT.md) implements compatible checkpoint reuse across hidden gaps and theme changes. +The [saved-state reuse checkpoint](LOCAL_SOURCE_REPLAY_REPORT.md) implements compatible checkpoint reuse across hidden gaps and theme changes. Exact colors and source identities pass the new work-count and replacement checks. -The [completed ordinary comparison](docs/history/LOCAL_SOURCE_REPLAY_COMPARISON.md) retains all eighteen runs across the power interruption, with 198 exact views. +The [completed ordinary comparison](LOCAL_SOURCE_REPLAY_COMPARISON.md) retains all eighteen runs across the power interruption, with 198 exact views. It finds workload-dependent recoloring benefits and mixed navigation results. The large local-source case still repeats all hidden parsing after checkpoint eviction. -The [retention investigation](docs/history/LOCAL_SOURCE_RETENTION_REPORT.md) now reproduces how replay evicts states that the same request can reuse later. +The [retention investigation](LOCAL_SOURCE_RETENTION_REPORT.md) now reproduces how replay evicts states that the same request can reuse later. Its isolated diagnostic passed 27 measured worker requests, 520 old/new token lists, and 33 exact terminal views. That investigation did not change the normal implementation or executable. -The [original prototype](docs/history/LOCAL_SOURCE_RETENTION_PROTOTYPE.md) preserves the first experiment and its adverse observations. +The [original prototype](LOCAL_SOURCE_RETENTION_PROTOTYPE.md) preserves the first experiment and its adverse observations. The [adoption report](LOCAL_SOURCE_RETENTION_DECISION.md) adds matched attribution and the explicit tradeoff decision without increasing cache limits. Isolated expansion now has separate evidence. Cached layout and resize actions issue no coloring requests in the targeted diagnostic. That rules out direct checkpoint planning in those actions, not every indirect or host effect. -The [updated retention plan](docs/history/LOCAL_SOURCE_RETENTION_PLAN.md) closes the decision and identifies the next qualification work. +The [updated retention plan](LOCAL_SOURCE_RETENTION_PLAN.md) closes the decision and identifies the next qualification work. Remote acquisition remains unimplemented. Integrated resource and physical-terminal qualification remain open. ## Preserved retention build @@ -481,7 +481,7 @@ Git source preparation is lazy and cancellable. Source failure preserves the pat Both modes now use complete-source syntax after source checks pass. Pending or unavailable sources use plain syntax. Replay includes hidden prefixes and keeps each side's parser state across patch boundaries. Source origins, explicit side scopes, and theme epochs prevent incompatible checkpoint and style reuse. -The [readiness report](docs/history/SOURCE_READINESS_REPORT.md) records the current correction and qualification limits. +The [readiness report](SOURCE_READINESS_REPORT.md) records the current correction and qualification limits. The source-readiness executable and archive remain preserved under `evidence/source-readiness-v1/` as historical evidence. That checkpoint's final checks are `suite.log`, `diagnostic-suite.log`, `ordinary-pty.log`, and `compatibility.log`. The later test/documentation-only checkpoint is `evidence/local-source-hardening-v1/`, including its new `suite.log` and ownership report. @@ -524,11 +524,11 @@ cargo test --release --locked -- --test-threads=1 The preserved pre-sidebar executable is `evidence/sidebar-v1/baseline-native-diff`. Its checked SHA-256 is `6cf039592f9bc400ee9e90ea510eb4b2daa48ebc24ae1b75371d7d6cc16e2eb3`. -The [paired-emphasis report](evidence/inline-pair-v1/REPORT.md) records the preceding defect, correction, and qualification. -The [gap report](docs/history/ALIGNMENT_GAPS.md) records that change, checks, and incomplete physical captures. -The [inline report](docs/history/INLINE_HIGHLIGHTING.md) records the preceding inline-emphasis change. -The [cancellation report](evidence/cached-navigation-cancel-v1/REPORT.md) preserves the preceding source archive, executable, and rollback copies. -The [preceding integration report](evidence/required-bytes-adoption-v1/REPORT.md) remains intact. +The [paired-emphasis report](../../evidence/inline-pair-v1/REPORT.md) records the preceding defect, correction, and qualification. +The [gap report](ALIGNMENT_GAPS.md) records that change, checks, and incomplete physical captures. +The [inline report](INLINE_HIGHLIGHTING.md) records the preceding inline-emphasis change. +The [cancellation report](../../evidence/cached-navigation-cancel-v1/REPORT.md) preserves the preceding source archive, executable, and rollback copies. +The [preceding integration report](../../evidence/required-bytes-adoption-v1/REPORT.md) remains intact. Normal builds exclude diagnostic features. Optional diagnostic tests use a separate Cargo target directory. No special source snapshot or manual executable replacement is required. The pre-sidebar large-patch correctness recapture and measurement-build qualification are complete. @@ -548,7 +548,7 @@ No accepted performance capture is active or scheduled. Exact source bytes use a private disk spool. Compact indexes remain in memory. The renderer draws visible cells. A separate worker supplies styling. Geometry, source, and style caches have separate limits, not a total-memory guarantee. -The [README](README.md) owns build commands, controls, and implementation details. +The [README](../../README.md) owns build commands, controls, and implementation details. The new rejection check skips a syntax search only when a required ASCII byte is absent from the complete source line. Otherwise, the existing matcher runs unchanged. @@ -582,7 +582,7 @@ Post-cancellation revisits match sequential colors for divergent old/new state i The final ordinary executable passed all 12 focused rendering contracts through `NATIVE_DIFF_CONTRACT_BINARY`. The broader suites used their Cargo test-build executables. -The [preceding report](evidence/cached-navigation-cancel-v1/REPORT.md) records the earlier cancellation qualification and its environment-preflight correction. +The [preceding report](../../evidence/cached-navigation-cancel-v1/REPORT.md) records the earlier cancellation qualification and its environment-preflight correction. The earlier integration also passed ten complete sequential-color comparisons and independent checks of 20,847,451 source records. It matched 42,657,296 projection rows, 2,888 generated accepted cases, and 716 generated rejected cases. @@ -595,8 +595,8 @@ They do not prove every possible patch or grammar, ideal replacement pairing, ph ## Historical performance evidence and accepted tradeoff -The [ordinary comparison](evidence/required-bytes-comparison-v1/REPORT.md) measured the candidate source before integration. -The preserved source-readiness executable has [short local-source timing observations](docs/history/LOCAL_SOURCE_TIMING_REPORT.md). +The [ordinary comparison](../../evidence/required-bytes-comparison-v1/REPORT.md) measured the candidate source before integration. +The preserved source-readiness executable has [short local-source timing observations](LOCAL_SOURCE_TIMING_REPORT.md). Its two-file opening medians are 46.99 ms for expected text and 581.30 ms for complete cells. Its fixed-commit Git opening medians are 132.09 ms and 172.05 ms, respectively. Its theme changes in the two-file case take about 510 ms to reach complete cells. @@ -605,9 +605,9 @@ An ordinary stack sample also locates active work in parsing and regex matching. Those diagnostic values do not replace the accepted ordinary timings or establish an improvement. The series passed 110 final-grid checks, all cleanup checks, and 120 AC-power boundary checks. Its Page Up/Down actions move only the selection, so they do not establish scrolling performance. -The preserved sidebar executable has [five-patch timing and sustained-memory observations](docs/history/SIDEBAR_MEASUREMENT_REPORT.md). +The preserved sidebar executable has [five-patch timing and sustained-memory observations](SIDEBAR_MEASUREMENT_REPORT.md). That campaign does not extend the short local-source series into sustained complete-source qualification. -The [saved-state reuse comparison](docs/history/LOCAL_SOURCE_REPLAY_COMPARISON.md) completed all eighteen declared runs and 198 exact views. +The [saved-state reuse comparison](LOCAL_SOURCE_REPLAY_COMPARISON.md) completed all eighteen declared runs and 198 exact views. The interrupted attempt remains excluded and preserved. Eight resumed runs retain the original schedule, executables, inputs, and references. Offline replay and RSS checks pass. The series spans two shared-workstation sessions, with mixed opening and navigation observations. Real-source theme medians improve from approximately 53–55 ms to 21 ms, but no general timing improvement is accepted. @@ -616,7 +616,7 @@ Its 64-entry checkpoint limit triggers 212 evictions over the sequence. The Git All 33 new diagnostic views match. Short-workload peak RSS medians remain approximately 17–34 MiB, not results for the largest patch. The separate real-worker count check reduced repeated sparse parsing from 11,266 to 2,056 source lines while preserving exact tokens. The remaining evidence in this section applies to preserved pre-sidebar builds. -The [measurement-readiness checkpoint](docs/history/MEASUREMENT_READINESS.md) checked workload identities and an isolated build/install without accepting performance samples. +The [measurement-readiness checkpoint](MEASUREMENT_READINESS.md) checked workload identities and an isolated build/install without accepting performance samples. The 39 focused views now have reviewed expectations for the accepted gap and inline changes. The pre-sidebar executable passed those views and saved-output replay. Two matched ordinary comparison builds also passed all 39 views against their separate presentation answers. @@ -625,7 +625,7 @@ All 842 sampled paired sides pass independent checks, and all 724 expected views The corrected ordinary executable passed all 724 actual large-patch views against those reviewed expectations. The fresh ordinary measurement candidate also passed all 12 rendering contracts and 39 focused views. Its compiler, SDK, environment, Cargo configuration, and feature tree match the prepared reference. -The [historical comparison plan](evidence/inline-pair-v1/NEXT.md) scoped those preserved schedules. No capture of that paired comparison started. +The [historical comparison plan](../../evidence/inline-pair-v1/NEXT.md) scoped those preserved schedules. No capture of that paired comparison started. The current unpaired campaign does not complete that historical comparison. The earlier battery checkpoint retains its original evidence. The table describes preserved executables before the cached-view cancellation change. @@ -640,8 +640,8 @@ All three focused pairs favored the candidate for deep first-visit coloring. Small adverse timing observations remain in the report. The five-patch memory campaign passed all 4,324 views and 2,856 holds. These values do not establish physical paint time, universal improvement, or a repeated process-memory reduction. -The [ordinary allocator checkpoint](evidence/required-bytes-ordinary-owners-v1/REPORT.md) reproduced the moderate-patch memory increase. -The [endpoint census](evidence/required-bytes-endpoint-owners-v1/REPORT.md) then observed a comparable state without stack logging or intermediate inspection. +The [ordinary allocator checkpoint](../../evidence/required-bytes-ordinary-owners-v1/REPORT.md) reproduced the moderate-patch memory increase. +The [endpoint census](../../evidence/required-bytes-endpoint-owners-v1/REPORT.md) then observed a comparable state without stack logging or intermediate inspection. The candidate retained 24,537 styles versus 7,829, with 8.69 MiB more style payload and 8.22 MiB more total used heap. Both caches stayed below the unchanged 32 MiB payload budget, with no evictions in the observed cache instances. Static-pattern sets, compiled-pattern sets, and measured engine inventories matched. @@ -653,37 +653,37 @@ The development memory goals remain unchanged. The three largest inputs still ex ## Historical behavior and presentation work -The [cancellation review](evidence/highlight-cancellation-v1/REPORT.md) identified obsolete coloring at fully cached destinations. -The [completed change](evidence/cached-navigation-cancel-v1/REPORT.md) resolves that scheduling defect in the covered checks. +The [cancellation review](../../evidence/highlight-cancellation-v1/REPORT.md) identified obsolete coloring at fully cached destinations. +The [completed change](../../evidence/cached-navigation-cancel-v1/REPORT.md) resolves that scheduling defect in the covered checks. Its CPU, cache-occupancy, and process-memory effects remain unmeasured. Less offscreen work can also leave fewer styles available for a later revisit. -The [next checkpoint](evidence/cached-navigation-cancel-v1/NEXT.md) scopes an ordinary-build observation without another scheduling change. +The [next checkpoint](../../evidence/cached-navigation-cancel-v1/NEXT.md) scopes an ordinary-build observation without another scheduling change. -The user reported an inline-emphasis discrepancy in the visual gallery. The [inline change](docs/history/INLINE_HIGHLIGHTING.md) corrects the covered punctuation cases. -The [alignment-gap change](docs/history/ALIGNMENT_GAPS.md) makes empty alignment areas distinct from context rows in both themes. +The user reported an inline-emphasis discrepancy in the visual gallery. The [inline change](INLINE_HIGHLIGHTING.md) corrects the covered punctuation cases. +The [alignment-gap change](ALIGNMENT_GAPS.md) makes empty alignment areas distinct from context rows in both themes. Actual Ghostty light-theme captures show the complete multi-file view before and after the change. A dark capture has a framing discrepancy. The recorder lost window visibility before the wrapped captures. Those physical checks remain incomplete. The light multi-file gallery image uses the preceding alignment-gap executable. No physical gallery capture uses the latest paired-emphasis executable yet. At this checkpoint, physical comparison, rapid real-window resizing, and trackpad observations were incomplete. -The [prepared terminal check](TERMINAL_PRESENTATION_CHECK.md) remains postponed. +The [prepared terminal check](../measurements/TERMINAL_PRESENTATION_CHECK.md) remains postponed. No GUI automation or capture request is active. Very long lines retain complete source but use declared plain styling. Missing syntax context stays unknown. Uneven replacements retain the bounded alignment and positional fallback. At this historical checkpoint, literal search was implemented. Selection/copy, a file picker, and horizontal trackpad scrolling were unimplemented. -The [product spec](SPEC.md) describes intended behavior. The [release checklist](ACCEPTANCE.md) is not complete. +The [product spec](../design/SPEC.md) describes intended behavior. The [release checklist](../design/ACCEPTANCE.md) is not complete. ## Deferred work stays separate | Candidate | Decision and location | | --- | --- | -| Shared leading-syntax state | Deferred. The exact removed files are in [the saved experiment](evidence/clean-baseline-v1/before/deferred-source/). The [original report](docs/history/SHARED_SYNTAX_PREFIX_REPORT.md) and all measurements remain intact. | -| Borrowed loading records | Deferred. The [native diagnostic](evidence/borrowed-parser-residency-v1/REPORT.md) did not resolve the earlier ordinary-memory and exit observations. | -| Borrowed capture results | Closed without adoption. The [review](evidence/borrowed-capture-review-v1/REPORT.md) preserves the mixed timing benefit and adverse memory observations. | -| Unchanged regex save slots | Closed without adoption. The [comparison](evidence/redundant-save-comparison-v1/REPORT.md) preserves all three focused pairs and the mixed result. | -| Earlier cache representations and direct input buffer | Not adopted. The [saved-style report](docs/history/STYLE_STORAGE_REPORT.md), [boxed-value report](docs/history/STYLE_INDIRECTION_REPORT.md), and [input-buffer report](evidence/input-buffer-v1/REPORT.md) preserve their decisions. | -| Direct token collection | Closed without adoption. The [qualification and residency report](docs/history/DIRECT_TOKEN_COLLECTION_REPORT.md) records reduced vector slack, mixed ordinary memory, and a larger cache table with higher final live heap. | +| Shared leading-syntax state | Deferred. The exact removed files are in [the saved experiment](../../evidence/clean-baseline-v1/before/deferred-source/). The [original report](SHARED_SYNTAX_PREFIX_REPORT.md) and all measurements remain intact. | +| Borrowed loading records | Deferred. The [native diagnostic](../../evidence/borrowed-parser-residency-v1/REPORT.md) did not resolve the earlier ordinary-memory and exit observations. | +| Borrowed capture results | Closed without adoption. The [review](../../evidence/borrowed-capture-review-v1/REPORT.md) preserves the mixed timing benefit and adverse memory observations. | +| Unchanged regex save slots | Closed without adoption. The [comparison](../../evidence/redundant-save-comparison-v1/REPORT.md) preserves all three focused pairs and the mixed result. | +| Earlier cache representations and direct input buffer | Not adopted. The [saved-style report](STYLE_STORAGE_REPORT.md), [boxed-value report](STYLE_INDIRECTION_REPORT.md), and [input-buffer report](../../evidence/input-buffer-v1/REPORT.md) preserve their decisions. | +| Direct token collection | Closed without adoption. The [qualification and residency report](DIRECT_TOKEN_COLLECTION_REPORT.md) records reduced vector slack, mixed ordinary memory, and a larger cache table with higher final live heap. | The complete pre-cleanup working source, test support, documents, and executable remain in `evidence/clean-baseline-v1/before/`. The separate experiment copies are evidence, not active build inputs. diff --git a/docs/history/CURRENT_STATE_HISTORY.md b/docs/history/CURRENT_STATE_HISTORY.md index 22c22fb..64a1cc7 100644 --- a/docs/history/CURRENT_STATE_HISTORY.md +++ b/docs/history/CURRENT_STATE_HISTORY.md @@ -348,7 +348,7 @@ The syntax-delivery wake-up change and per-grammar compiled-pattern sharing are The representative allocation profile shows 11.8% fewer bytes in named regex-engine allocations. This is a general ownership change, not a grammar reduction or a patch-specific path. Current third-tour settled RSS maxima range from 111.4 MiB to 1,086.5 MiB. Four inputs still exceed the shared memory goals. One distant seek exceeds the final-coloring maximum, and the largest input exceeds the complete-index target. Small-workload paired responsiveness is roughly flat, with slower individual maxima retained. -Correctness remains scoped to the supplied source and checked views. Complete Pierre visual parity, actual Ghostty frame pacing, and a total-memory bound remain unproved. [The engineering plan](ENGINEERING_PLAN.md) owns the current next actions. No full milestone in [ACCEPTANCE.md](../../ACCEPTANCE.md) is complete. +Correctness remains scoped to the supplied source and checked views. Complete Pierre visual parity, actual Ghostty frame pacing, and a total-memory bound remain unproved. [The engineering plan](ENGINEERING_PLAN.md) owns the current next actions. No full milestone in [ACCEPTANCE.md](../design/ACCEPTANCE.md) is complete. ## Historical detail: 2026-09-11 storage checkpoint @@ -356,7 +356,7 @@ The sections below retain the earlier checkpoint and its measurements. They do n We have a working Rust terminal diff viewer with substantial correctness evidence and measured responsiveness improvements. We do not yet have a fully accepted release or complete Pierre visual parity. The storage refactor is implemented and passes full source/projection comparisons. Its five-patch measurements are complete: Linux memory is lower, but four memory limits still fail and a first-color regression remains open. Navigation limits pass on four patches; only Ghostty meets its memory envelope. -No full milestone in [ACCEPTANCE.md](../../ACCEPTANCE.md) is complete. +No full milestone in [ACCEPTANCE.md](../design/ACCEPTANCE.md) is complete. ## What we are building @@ -567,7 +567,7 @@ Cold/backward syntax remains relevant to the styled-seek investigation. Further When user-provided captures are available, actual Ghostty/Pierre comparison can proceed alongside the code-level checks. Search, watch mode, a file picker, editing, and additional controls stay outside the immediate priority list. -The [large-diff specification](../../LARGE_DIFFS.md) owns the existing acceptance targets. This overview does not weaken or replace them. +The [large-diff specification](../design/LARGE_DIFFS.md) owns the existing acceptance targets. This overview does not weaken or replace them. ## Storage-checkpoint evidence and documentation @@ -575,8 +575,8 @@ The storage checkpoint executable has SHA-256 `7a842a00acfb52d64ea9b7db1dccf980b The source directory is not a Git checkout. Current identity uses executable hashes and retained source archives rather than commit IDs. - [README.md](../../README.md): supported commands and current controls. -- [SPEC.md](../../SPEC.md): broader intended product behavior, including unimplemented features. -- [ACCEPTANCE.md](../../ACCEPTANCE.md): milestone requirements, not a list of completed features. +- [SPEC.md](../design/SPEC.md): broader intended product behavior, including unimplemented features. +- [ACCEPTANCE.md](../design/ACCEPTANCE.md): milestone requirements, not a list of completed features. - [LARGE_DIFF_PROGRESS.md](LARGE_DIFF_PROGRESS.md): chronological implementation and evidence history. - [RESPONSIVENESS.md](RESPONSIVENESS.md): geometry measurements on the preceding build. - [SYNTAX_REPLAY.md](SYNTAX_REPLAY.md): latest syntax measurements and limits. diff --git a/docs/history/ENGINEERING_PLAN.md b/docs/history/ENGINEERING_PLAN.md index 281ab9d..805f4a4 100644 --- a/docs/history/ENGINEERING_PLAN.md +++ b/docs/history/ENGINEERING_PLAN.md @@ -1,6 +1,6 @@ # General-purpose performance: audit and next actions -Historical plan and dated execution notes. Use the [current project state](../../CURRENT_STATE.md) +Historical plan and dated execution notes. Use the [current project state](CURRENT_STATE.md) for the active next steps and the [latest checkpoint](INNER_ENGINE_CHECKPOINT_REPORT.md) for current results. The original requirements and evidence below remain preserved. @@ -54,7 +54,7 @@ This review examined the current Rust input, storage, projection, geometry, rend ### Corrections completed in this review - `tools/corpus_measure.py` now uses one shared target object, includes it in new freezes and summaries, and rejects historical or altered policies before replay. Fixture names do not select limits. -- [The new measurement policy](../../MEASUREMENT_POLICY.md) applies the existing stricter development targets uniformly. It introduces no size crossover fitted to these patches. Targets are not supported-input limits and cannot justify degrading the display. A general scaling policy, if needed, must be justified separately before another candidate is evaluated. +- [The new measurement policy](../measurements/MEASUREMENT_POLICY.md) applies the existing stricter development targets uniformly. It introduces no size crossover fitted to these patches. Targets are not supported-input limits and cannot justify degrading the display. A general scaling policy, if needed, must be justified separately before another candidate is evaluated. - `tools/aggregate_five_patch_report.py` marks source and engineering checks unverified by that generator. It reports actual completion status, tolerates missing opening evidence, and does not describe failed corruption controls as rejected. It labels supplied historical observations accurately. - `tools/check_reporting.py` exercises the actual report CLI with copies of retained process evidence. Controls rename fixtures, retain a real seek failure, remove observations, omit an opening, and invalidate an oracle control. Original input hashes must remain unchanged. These are reporting tests, not fabricated performance runs. diff --git a/docs/history/FIRST_VISIT_HIGHLIGHTING_PLAN.md b/docs/history/FIRST_VISIT_HIGHLIGHTING_PLAN.md index e6b3831..1533ec8 100644 --- a/docs/history/FIRST_VISIT_HIGHLIGHTING_PLAN.md +++ b/docs/history/FIRST_VISIT_HIGHLIGHTING_PLAN.md @@ -20,7 +20,7 @@ An optimization must preserve source bytes, numbering, pairing, emphasis, readin This stage measures PTY receipt of correct text and colors separately. Those observations do not establish physical screen paint or smooth scrolling in Ghostty. -The [actual-terminal check](../../TERMINAL_PRESENTATION_CHECK.md) remains separate. +The [actual-terminal check](../measurements/TERMINAL_PRESENTATION_CHECK.md) remains separate. ## What we already know @@ -202,7 +202,7 @@ Faster colors cannot erase that result or justify unexplained new retained stora Any new owner needs a clear lifetime, accounting, release behavior, and measured tradeoff. No memory reduction or coloring speedup is claimed by this plan. -The [measurement policy](../../MEASUREMENT_POLICY.md) remains unchanged. +The [measurement policy](../measurements/MEASUREMENT_POLICY.md) remains unchanged. Wrong source, wrong colors, lost position, stale theme output, or failed cleanup blocks acceptance. Unexplained responsiveness or memory regressions require investigation before a keep decision. diff --git a/docs/history/FIVE_PATCH_RESULTS.md b/docs/history/FIVE_PATCH_RESULTS.md index 53fe20c..125bf9d 100644 --- a/docs/history/FIVE_PATCH_RESULTS.md +++ b/docs/history/FIVE_PATCH_RESULTS.md @@ -2,7 +2,7 @@ Run date: 2026-09-11 -This report records the completed batch defined in [FIVE_PATCH_ACCEPTANCE.md](../../FIVE_PATCH_ACCEPTANCE.md). +This report records the completed batch defined in [FIVE_PATCH_ACCEPTANCE.md](../measurements/FIVE_PATCH_ACCEPTANCE.md). It used the current release executable through a real PTY on the local M5 Max Mac. Files were warm and fixed. The baseline was 160×50, split, dark, truecolor, with line numbers and wrapping off. ## Independent interior presentation diff --git a/FULL_SOURCE_COLOR_REPORT.md b/docs/history/FULL_SOURCE_COLOR_REPORT.md similarity index 100% rename from FULL_SOURCE_COLOR_REPORT.md rename to docs/history/FULL_SOURCE_COLOR_REPORT.md diff --git a/docs/history/IMPLEMENTATION_STATUS.md b/docs/history/IMPLEMENTATION_STATUS.md index 6e57255..eb182a2 100644 --- a/docs/history/IMPLEMENTATION_STATUS.md +++ b/docs/history/IMPLEMENTATION_STATUS.md @@ -109,5 +109,5 @@ Its full independent before/after visual reference set still needs preparation f 2. Correct visual and source-anchor differences before adding controls. Add focused process regressions for observed failures. 3. Add full large-source reconstruction, then profile distant navigation and memory before choosing the smallest loading/checkpoint changes. -The full [acceptance checklist](../../ACCEPTANCE.md) remains the release gate. This report does not weaken it. +The full [acceptance checklist](../design/ACCEPTANCE.md) remains the release gate. This report does not weaken it. DiffGrid, its candidates, and its benchmark artifacts remain outside this implementation. diff --git a/docs/history/LARGE_DIFF_PROGRESS.md b/docs/history/LARGE_DIFF_PROGRESS.md index 9c9f7ad..0668324 100644 --- a/docs/history/LARGE_DIFF_PROGRESS.md +++ b/docs/history/LARGE_DIFF_PROGRESS.md @@ -240,7 +240,7 @@ Cold and backward syntax requests still replay from the start of the requested h A geometry miss scans a complete line once for that width. Next engine work addresses resumable syntax state and the complete responsiveness/memory trace, without changes to source semantics. -The [large-diff specification](../../LARGE_DIFFS.md) still owns the targets. Actual Ghostty inspection remains separate. +The [large-diff specification](../design/LARGE_DIFFS.md) still owns the targets. Actual Ghostty inspection remains separate. ## Reproduce the source check diff --git a/LOCAL_SOURCE_INPUT_REPORT.md b/docs/history/LOCAL_SOURCE_INPUT_REPORT.md similarity index 98% rename from LOCAL_SOURCE_INPUT_REPORT.md rename to docs/history/LOCAL_SOURCE_INPUT_REPORT.md index 348d9c8..3c2fc09 100644 --- a/LOCAL_SOURCE_INPUT_REPORT.md +++ b/docs/history/LOCAL_SOURCE_INPUT_REPORT.md @@ -41,7 +41,7 @@ The footer reports source failure, and normal quit returns a nonzero status afte Completed source preparation does not move the reader. Both new modes still use patch-context coloring. Their footer states this limitation even after source checks pass. -This staged policy is recorded in [the implementation plan](docs/history/LOCAL_SOURCE_INPUT_PLAN.md). +This staged policy is recorded in [the implementation plan](LOCAL_SOURCE_INPUT_PLAN.md). Full-prefix syntax, new syntax cache identities, and expandable context remain the next feature stages. ## Ownership and resources diff --git a/LOCAL_SOURCE_RETENTION_DECISION.md b/docs/history/LOCAL_SOURCE_RETENTION_DECISION.md similarity index 100% rename from LOCAL_SOURCE_RETENTION_DECISION.md rename to docs/history/LOCAL_SOURCE_RETENTION_DECISION.md diff --git a/docs/history/LOCAL_SOURCE_RETENTION_PLAN.md b/docs/history/LOCAL_SOURCE_RETENTION_PLAN.md index a4a6c3c..7ab9a7a 100644 --- a/docs/history/LOCAL_SOURCE_RETENTION_PLAN.md +++ b/docs/history/LOCAL_SOURCE_RETENTION_PLAN.md @@ -6,7 +6,7 @@ Findings: [the retention investigation](LOCAL_SOURCE_RETENTION_REPORT.md). Implementation and measurements: [the prototype report](LOCAL_SOURCE_RETENTION_PROTOTYPE.md). Opening attribution: [the diagnostic report](LOCAL_SOURCE_OPENING_REPORT.md). Git completion: [the independent notification report](LOCAL_SOURCE_GIT_WAKE_REPORT.md). -Decision: [the retention adoption report](../../LOCAL_SOURCE_RETENTION_DECISION.md). +Decision: [the retention adoption report](LOCAL_SOURCE_RETENTION_DECISION.md). ## Completed decision diff --git a/docs/history/LOCAL_SOURCE_RETENTION_PROTOTYPE.md b/docs/history/LOCAL_SOURCE_RETENTION_PROTOTYPE.md index 3ea84c5..a78582e 100644 --- a/docs/history/LOCAL_SOURCE_RETENTION_PROTOTYPE.md +++ b/docs/history/LOCAL_SOURCE_RETENTION_PROTOTYPE.md @@ -2,7 +2,7 @@ Date: 2026-09-23. Status: prototype complete, not adopted. The known baseline is restored. -This page preserves the original prototype checkpoint. The later [retention decision](../../LOCAL_SOURCE_RETENTION_DECISION.md) records adoption and current qualification. +This page preserves the original prototype checkpoint. The later [retention decision](LOCAL_SOURCE_RETENTION_DECISION.md) records adoption and current qualification. ## Decision diff --git a/docs/history/MEASUREMENT_READINESS.md b/docs/history/MEASUREMENT_READINESS.md index f352494..310236a 100644 --- a/docs/history/MEASUREMENT_READINESS.md +++ b/docs/history/MEASUREMENT_READINESS.md @@ -152,7 +152,7 @@ Another 29 emphasized source lines lack a visible peer in the inspected captures These counts identify the remaining review work. Multiple valid alignments do not establish a viewer defect. No large-patch expectations were silently regenerated or accepted from current output alone. -The [release-readiness checkpoint](../../RELEASE_READINESS.md) records the minimum-compiler and dependency checks. +The [release-readiness checkpoint](RELEASE_READINESS.md) records the minimum-compiler and dependency checks. All 2,065 active build inputs and the normal executable remain unchanged. The battery-powered captures retain raw diagnostic fields, but none counts as accepted performance evidence. @@ -168,4 +168,4 @@ The follow-up evidence is in: `native-diff-battery-readiness/` (external record, not in this repository) It contains the reviewed focused packet, raw captures, matched builds, minimum-compiler checks, and offline large-patch inventories. -The [current project state](../../CURRENT_STATE.md) owns the overall status. +The [current project state](CURRENT_STATE.md) owns the overall status. diff --git a/docs/history/MEMORY_PLAN.md b/docs/history/MEMORY_PLAN.md index 75129a2..e59291e 100644 --- a/docs/history/MEMORY_PLAN.md +++ b/docs/history/MEMORY_PLAN.md @@ -4,7 +4,7 @@ Date: 2026-09-11. Status: storage stages implemented and checkpoint measurements Reduce memory while preserving the exact source, settled terminal cells, and reading destinations of the current viewer. Correctness is a requirement for accepting each change. Performance goals apply after that requirement passes. -This plan defines the next work in the existing Rust package. [LARGE_DIFFS.md](../../LARGE_DIFFS.md) owns performance targets; [FIVE_PATCH_ACCEPTANCE.md](../../FIVE_PATCH_ACCEPTANCE.md) owns the current measured workload. This plan adds representation invariants and migration checks. It does not implement the unbuilt features proposed in [SPEC.md](../../SPEC.md). +This plan defines the next work in the existing Rust package. [LARGE_DIFFS.md](../design/LARGE_DIFFS.md) owns performance targets; [FIVE_PATCH_ACCEPTANCE.md](../measurements/FIVE_PATCH_ACCEPTANCE.md) owns the current measured workload. This plan adds representation invariants and migration checks. It does not implement the unbuilt features proposed in [SPEC.md](../design/SPEC.md). ## 1. Starting evidence and decisions diff --git a/docs/history/NEXT_PERFORMANCE_STAGE.md b/docs/history/NEXT_PERFORMANCE_STAGE.md index 84340fa..f3ca327 100644 --- a/docs/history/NEXT_PERFORMANCE_STAGE.md +++ b/docs/history/NEXT_PERFORMANCE_STAGE.md @@ -1,6 +1,6 @@ # Next stage: memory ownership, coloring, and terminal presentation -Historical stage specification and execution notes. Use the [current project state](../../CURRENT_STATE.md) +Historical stage specification and execution notes. Use the [current project state](CURRENT_STATE.md) for the active next steps and the [latest checkpoint](INNER_ENGINE_CHECKPOINT_REPORT.md) for current results. The original scope and acceptance gates below remain preserved. @@ -100,7 +100,7 @@ Storage totals come from `evidence/index-v1/candidate-final/index.json`. Sum the Opening allocation snapshots are not third-tour heap snapshots. Allocator call-site labels can combine inlined owners. RSS, live heap, physical footprint, and compressed memory are different, partly overlapping quantities. Do not subtract observations from different phases or add these quantities together as though they were disjoint. -The shared targets in [MEASUREMENT_POLICY.md](../../MEASUREMENT_POLICY.md) remain unchanged. Missing them must not alter supported input, source content, styling thresholds, or the reported result. +The shared targets in [MEASUREMENT_POLICY.md](../measurements/MEASUREMENT_POLICY.md) remain unchanged. Missing them must not alter supported input, source content, styling thresholds, or the reported result. ## Invariants and scope limits @@ -216,7 +216,7 @@ Initial experiment policy: consider a checkpoint every 256 supplied records; ret Preflight the clone cost, evict before admission, and verify actual owned bytes after cloning. Account for the transient clone separately from retained-cache limits. Check cancellation before and after snapshot/restore work. If safe size accounting or acceptable clone responsiveness requires a broad parser rewrite, defer checkpoints. -The proposed 16 MiB fits the unallocated portion of the 64 MiB disposable display/highlight plan in [SPEC.md](../../SPEC.md): current geometry and style payload budgets are 16 and 32 MiB. The separate source-page payload budget is 32 MiB. This is not free process memory or a total-memory guarantee; allocator overhead, active state, temporary clones, and grammar storage remain additional costs. Do not lower existing cache budgets to conceal the addition. +The proposed 16 MiB fits the unallocated portion of the 64 MiB disposable display/highlight plan in [SPEC.md](../design/SPEC.md): current geometry and style payload budgets are 16 and 32 MiB. The separate source-page payload budget is 32 MiB. This is not free process memory or a total-memory guarantee; allocator overhead, active state, temporary clones, and grammar storage remain additional costs. Do not lower existing cache budgets to conceal the addition. ### Required proof @@ -238,7 +238,7 @@ The handoff is one short manual checklist and exact launch commands, not another The user supplies screenshots and, for motion, a recording through their existing tools. No accessibility/computer-use control, new permission loop, new tabs, or global configuration changes are assumed. Keep diagnostic logs outside the visible diff. Stills prove appearance only; a clip without synchronized input timestamps and known capture behavior is qualitative motion evidence, not a millisecond latency result. -**Done:** a compact case/result table linked to actual paired images and the interaction clip, with defects and unverified cases explicit. Missing captures leave visual acceptance open even if process tests pass. Use [ACCEPTANCE.md](../../ACCEPTANCE.md) rather than inventing a parallel visual acceptance system. +**Done:** a compact case/result table linked to actual paired images and the interaction clip, with defects and unverified cases explicit. Missing captures leave visual acceptance open even if process tests pass. Use [ACCEPTANCE.md](../design/ACCEPTANCE.md) rather than inventing a parallel visual acceptance system. ## Verification and stopping rules diff --git a/docs/history/README.md b/docs/history/README.md index 78d429f..2160527 100644 --- a/docs/history/README.md +++ b/docs/history/README.md @@ -4,8 +4,8 @@ These files are dated plans, reports, censuses, and reviews from the experiments the current viewer. They record what was measured or decided at the time and are kept for provenance. They are not current status, instructions, or open tasks. -For the current state, start with the [README](../../README.md) and -[CURRENT_STATE.md](../../CURRENT_STATE.md). +For an overview, start with the [README](../../README.md). +[CURRENT_STATE.md](CURRENT_STATE.md) is the development log up to the first release. Some records cite evidence outside this repository: diff --git a/docs/history/REGEX_CENSUS_REPORT.md b/docs/history/REGEX_CENSUS_REPORT.md index 0a0e9b5..1e7f221 100644 --- a/docs/history/REGEX_CENSUS_REPORT.md +++ b/docs/history/REGEX_CENSUS_REPORT.md @@ -105,7 +105,7 @@ memory goals, and physical terminal-paint verification remain open. ## Evidence -- [Declared scope](../../REGEX_CENSUS_PLAN.md) +- [Declared scope](../measurements/REGEX_CENSUS_PLAN.md) - [Raw census](../../evidence/regex-census-v1/three-tour/census.json) - [Process and reduced results](../../evidence/regex-census-v1/three-tour/report.json) - [Run bindings](../../evidence/regex-census-v1/three-tour/declaration.json) diff --git a/RELEASE_READINESS.md b/docs/history/RELEASE_READINESS.md similarity index 92% rename from RELEASE_READINESS.md rename to docs/history/RELEASE_READINESS.md index f1a5ada..3b2d467 100644 --- a/RELEASE_READINESS.md +++ b/docs/history/RELEASE_READINESS.md @@ -37,7 +37,7 @@ Each step verifies the package against the crates already published by the previ ## Current local candidate The local candidate qualifies macOS arm64, not other platforms or a stable published library API. -The standalone viewer and host example share one engine. Hosts retain terminal ownership, as described in [EMBEDDING.md](EMBEDDING.md). +The standalone viewer and host example share one engine. Hosts retain terminal ownership, as described in [EMBEDDING.md](../embedding.md). - Both isolated installations, with Rust 1.96.0 and minimum Rust 1.88.0, passed 74 viewer checks and six host checks. Each viewer suite excluded ten opt-in cases. The separate host command selected six of those cases. @@ -106,8 +106,8 @@ The inventory records each changed and added file separately. | Vendored crate | Existing maintenance record | Remaining work | | --- | --- | --- | -| Syntect 5.3.0 | [Patch note](crates/diffs-syntect/PATCHES.md), source provenance, standalone checks | Summary updated 2026-09-22 for required-byte rejection, retained-heap APIs, and affected files. Keep the documented checks during updates. | -| Fancy Regex 0.16.2 | [Patch note](crates/diffs-fancy-regex/PATCHES.md), source provenance, standalone checks | Summary updated 2026-09-22 for required-byte metadata, public error behavior, and affected files. Keep the documented checks during updates. | +| Syntect 5.3.0 | [Patch note](../../crates/diffs-syntect/PATCHES.md), source provenance, standalone checks | Summary updated 2026-09-22 for required-byte rejection, retained-heap APIs, and affected files. Keep the documented checks during updates. | +| Fancy Regex 0.16.2 | [Patch note](../../crates/diffs-fancy-regex/PATCHES.md), source provenance, standalone checks | Summary updated 2026-09-22 for required-byte metadata, public error behavior, and affected files. Keep the documented checks during updates. | | libgit2-sys 0.18.8+1.9.7 | Parser correction, unchanged notices | Removed 2026-10-27. The stock crate is used; `src/model/rename_names.rs` quotes rename and copy names before parsing. Retain the parser regression checks during updates. | The bundled grammar package supplies notices in addition to its crate license. @@ -115,7 +115,7 @@ The local export contains 66 syntax notice entries from the pinned package's pub The export does not select the package's unused theme notices. Distribution preparation still needs the runtime dependency notices, bundled-component notices, and existing theme attribution. No dependency, vendored source, or notice changed during this inventory. -The later [local-source hardening pass](docs/history/LOCAL_SOURCE_HARDENING_REPORT.md) updated the two patch notes without changing runtime source or notices. +The later [local-source hardening pass](LOCAL_SOURCE_HARDENING_REPORT.md) updated the two patch notes without changing runtime source or notices. ## Historical release gates diff --git a/docs/history/SIDEBAR_CORPUS_REPORT.md b/docs/history/SIDEBAR_CORPUS_REPORT.md index 49bdef7..d381b1d 100644 --- a/docs/history/SIDEBAR_CORPUS_REPORT.md +++ b/docs/history/SIDEBAR_CORPUS_REPORT.md @@ -13,7 +13,7 @@ The normal executable, Rust source, dependencies, cache limits, and diff algorit The executable SHA-256 remains `1ab24c0c70c45a5b480b83e111fa909d33ed56f4f4af9510b30dad72558f2e4e`. This checkpoint establishes correctness for the declared views. It establishes no speedup or memory reduction. -Scope: [the frozen plan](../../SIDEBAR_CORPUS_PLAN.md). +Scope: [the frozen plan](../measurements/SIDEBAR_CORPUS_PLAN.md). Evidence index: [the machine-readable manifest](../../evidence/sidebar-corpus-v1/manifest.json). ## Checker changes diff --git a/SIDEBAR_REPORT.md b/docs/history/SIDEBAR_REPORT.md similarity index 97% rename from SIDEBAR_REPORT.md rename to docs/history/SIDEBAR_REPORT.md index f33dc64..b3a7506 100644 --- a/SIDEBAR_REPORT.md +++ b/docs/history/SIDEBAR_REPORT.md @@ -2,7 +2,7 @@ Date: 2026-09-22. -The sidebar is implemented against [the agreed specification](SIDEBAR_SPEC.md). +The sidebar is implemented against [the agreed specification](../design/SIDEBAR_SPEC.md). It belongs to the existing application. It does not introduce an integration layer or another terminal owner. ## Delivered behavior @@ -125,7 +125,7 @@ In an existing terminal window, run: Press `f` to focus Files. Use arrows to navigate. Press Enter to open a file. Press Escape to return to the diff. With Files focused, press `f` to hide it. -The [README](README.md#changed-files) lists all controls and width requirements. +The [README](../../README.md#changed-files) lists all controls and width requirements. ## Remaining qualification diff --git a/SOURCE_STORAGE_REPORT.md b/docs/history/SOURCE_STORAGE_REPORT.md similarity index 99% rename from SOURCE_STORAGE_REPORT.md rename to docs/history/SOURCE_STORAGE_REPORT.md index 9482b73..7da87cb 100644 --- a/SOURCE_STORAGE_REPORT.md +++ b/docs/history/SOURCE_STORAGE_REPORT.md @@ -8,7 +8,7 @@ The current viewer still accepts patches only. No new input command, context exp ## Scope and starting point This checkpoint covers the three requested steps: establish the baseline, refactor shared storage, and check compatibility. -It does not complete the entire first stage of [the exact-source feature](EXACT_SOURCE_CONTEXT_SPEC.md). +It does not complete the entire first stage of [the exact-source feature](../design/EXACT_SOURCE_CONTEXT_SPEC.md). Complete-source snapshots, disk line indexes, comparison identity, and patch-to-source correspondence remain separate work. The starting source passed 81 enabled checks, including 52 process checks. diff --git a/docs/history/STYLE_CACHE_STORAGE_REPORT.md b/docs/history/STYLE_CACHE_STORAGE_REPORT.md index 761063d..cf47a35 100644 --- a/docs/history/STYLE_CACHE_STORAGE_REPORT.md +++ b/docs/history/STYLE_CACHE_STORAGE_REPORT.md @@ -1,7 +1,7 @@ # Whole style-cache accounting Current status: qualified and integrated on 2026-09-27. -The [current state](../../CURRENT_STATE.md#current-checkpoint) identifies the normal executable and its completed integration checks. +The [current state](CURRENT_STATE.md#current-checkpoint) identifies the normal executable and its completed integration checks. The preserved candidate completed its ordinary comparison and Rust 1.88 checks before integration. Those measurements do not describe a new comparison of the integrated executable. diff --git a/docs/history/STYLE_INDIRECTION_REPORT.md b/docs/history/STYLE_INDIRECTION_REPORT.md index a9917aa..ea0d5e3 100644 --- a/docs/history/STYLE_INDIRECTION_REPORT.md +++ b/docs/history/STYLE_INDIRECTION_REPORT.md @@ -157,7 +157,7 @@ drivers must not restart after a reconnect. ## Next work -1. Follow the [small actual-terminal procedure](../../TERMINAL_PRESENTATION_CHECK.md) +1. Follow the [small actual-terminal procedure](../measurements/TERMINAL_PRESENTATION_CHECK.md) using one user-opened Ghostty window and the retained same-content Pierre reference. No actual Ghostty capture occurred in this experiment. 2. Follow the [metadata plan](DOCUMENT_METADATA_PLAN.md): count retained lengths, diff --git a/FIVE_PATCH_ACCEPTANCE.md b/docs/measurements/FIVE_PATCH_ACCEPTANCE.md similarity index 96% rename from FIVE_PATCH_ACCEPTANCE.md rename to docs/measurements/FIVE_PATCH_ACCEPTANCE.md index 3b5e5c4..57c2787 100644 --- a/FIVE_PATCH_ACCEPTANCE.md +++ b/docs/measurements/FIVE_PATCH_ACCEPTANCE.md @@ -80,7 +80,7 @@ Short-lived temporary allocations, source indexes, and opaque parser state remai ## Targets and limits -The targets in [LARGE_DIFFS.md](LARGE_DIFFS.md) remain authoritative. +The targets in [LARGE_DIFFS.md](../design/LARGE_DIFFS.md) remain authoritative. Navigation targets are p95 at most 50 ms and no response above 200 ms. First content targets 500 ms. Initial styling targets one second. Cold styling targets two seconds. Retained styling revisits target 100 ms. Quit and cancellation target 250 ms. @@ -96,4 +96,4 @@ Detailed run outputs use a temporary evidence directory. The final report separa The independent interior rehearsal passed for all five patches: 205 unchanged screens per patch, including source, layout, wrapping, resize, navigation, and sequential syntax checks. The deliberately corrupted captures were rejected. Five fresh-process latency repetitions completed for every patch. Pierre has one 251.8 ms styled distant-seek maximum above the 200 ms guard; the other latency guards pass. Three-tour memory runs completed for every patch. Ghostty meets its smaller-patch RSS envelope; Pierre, Node, Bun, and Linux do not. -The authoritative per-patch values and raw evidence paths are in [FIVE_PATCH_RESULTS.md](docs/history/FIVE_PATCH_RESULTS.md). The batch is therefore complete as measurement work, but it is not a full release acceptance: the recorded memory failures, the Pierre outlier, and actual Ghostty pixel/paint evidence remain open. +The authoritative per-patch values and raw evidence paths are in [FIVE_PATCH_RESULTS.md](../history/FIVE_PATCH_RESULTS.md). The batch is therefore complete as measurement work, but it is not a full release acceptance: the recorded memory failures, the Pierre outlier, and actual Ghostty pixel/paint evidence remain open. diff --git a/MEASUREMENT.md b/docs/measurements/MEASUREMENT.md similarity index 100% rename from MEASUREMENT.md rename to docs/measurements/MEASUREMENT.md diff --git a/MEASUREMENT_POLICY.md b/docs/measurements/MEASUREMENT_POLICY.md similarity index 100% rename from MEASUREMENT_POLICY.md rename to docs/measurements/MEASUREMENT_POLICY.md diff --git a/docs/measurements/README.md b/docs/measurements/README.md new file mode 100644 index 0000000..16eb160 --- /dev/null +++ b/docs/measurements/README.md @@ -0,0 +1,79 @@ +# Measurements + +This page summarizes the large-patch measurements. The linked reports have the full data, +method, and limits. + +## Workload + +Five patches pinned by SHA-256 in [corpus.json](../../fixtures/diffshub/corpus.json). They are +the cached inputs of Pierre's DiffsHub. The patch bodies are not in this repository. + +| Patch | Size | Files | Hunks | +| --- | ---: | ---: | ---: | +| Pierre commit `0800fb` | 0.6 MB | 73 | 109 | +| Ghostty PR 12291 | 4.2 MB | 25 | 130 | +| Node PR 59805 | 21.5 MB | 3,420 | 19,198 | +| Bun PR 30412 | 43.3 MB | 2,188 | 2,129 | +| Linux `v6.0...v7.0` | 710.9 MB | 76,872 | 421,819 | + +Source: [LARGE_DIFFS.md](../design/LARGE_DIFFS.md). + +## Conditions + +- Apple M5 Max, 48 GiB RAM, macOS 26.3, Rust 1.96.0, release build. +- The viewer runs in a real PTY at 160 x 50, split layout, dark theme. A harness parses the + terminal output and compares every checked screen with independently computed cells. +- Warm file cache. Each patch gets five fresh processes for timing and one process that browses + the same route three times for memory. +- Times are the moment the correct output reaches the PTY. They do not include terminal paint. + +These numbers come from pre-release builds (September and October 2026). Release builds have +not been timed again. + +## Results + +Opening and navigation, medians in milliseconds, from the +[2026-09-23 campaign](../history/SIDEBAR_MEASUREMENT_REPORT.md): + +| Patch | First text | First colors | Full index | Worst navigation p95 | +| --- | ---: | ---: | ---: | ---: | +| Pierre | 10.3 | 44.3 | 50.1 | 43.3 | +| Ghostty | 8.2 | 38.2 | 44.1 | 21.7 | +| Node | 8.5 | 33.1 | 144.1 | 14.5 | +| Bun | 8.5 | 34.4 | 200.6 | 19.9 | +| Linux | 11.8 | 35.5 | 4,650.5 | 8.6 | + +"Full index" is when the whole patch has been indexed in the background. The first screen is +usable long before that. + +Memory on the Linux patch, from the final 2026-10-03 cohort recorded in +[CURRENT_STATE.md](../history/CURRENT_STATE.md#current-integrated-candidate): 594 MiB peak RSS +and 543 MiB settled. The original prototype reached 2,590 MiB on the same patch before its +parser rejected it ([baseline report](../history/BASELINE_REPORT.md)). + +The memory goals (128 MiB settled, 192 MiB peak) are still missed by Node, Bun, and Linux. + +## Forked dependencies + +Measured changes from the patches in `crates/`: + +- Sharing compiled regex engines between identical patterns across grammars lowered live heap on + a syntax-heavy trace from 275 MiB to 213 MiB + ([report](../history/CROSS_GRAMMAR_REPORT.md)). +- Sharing identical patterns within one grammar lowered live heap by 11.4% + ([report](../history/REGEX_MEMORY.md)). +- Skipping regex searches whose required bytes are absent from the line cut the median time to + color a deep, first-visited file from 1,494 ms to 752 ms + ([summary](../history/CURRENT_STATE.md#historical-performance-evidence-and-accepted-tradeoff)). + +## Method documents + +- [MEASUREMENT.md](MEASUREMENT.md): the content-grid timing protocol. +- [MEASUREMENT_POLICY.md](MEASUREMENT_POLICY.md): targets and how results are reported. +- [FIVE_PATCH_ACCEPTANCE.md](FIVE_PATCH_ACCEPTANCE.md): the five-patch correctness and timing plan. +- [SIDEBAR_CORPUS_PLAN.md](SIDEBAR_CORPUS_PLAN.md): the corpus plan with the sidebar enabled. +- [REGEX_CENSUS_PLAN.md](REGEX_CENSUS_PLAN.md): the regex ownership census. +- [TERMINAL_PRESENTATION_CHECK.md](TERMINAL_PRESENTATION_CHECK.md): the manual terminal check. + +The scripts are in [`tools/`](../../tools/). They read the patch bodies and outputs from an +ignored `evidence/` directory. diff --git a/REGEX_CENSUS_PLAN.md b/docs/measurements/REGEX_CENSUS_PLAN.md similarity index 100% rename from REGEX_CENSUS_PLAN.md rename to docs/measurements/REGEX_CENSUS_PLAN.md diff --git a/SIDEBAR_CORPUS_PLAN.md b/docs/measurements/SIDEBAR_CORPUS_PLAN.md similarity index 100% rename from SIDEBAR_CORPUS_PLAN.md rename to docs/measurements/SIDEBAR_CORPUS_PLAN.md diff --git a/TERMINAL_PRESENTATION_CHECK.md b/docs/measurements/TERMINAL_PRESENTATION_CHECK.md similarity index 98% rename from TERMINAL_PRESENTATION_CHECK.md rename to docs/measurements/TERMINAL_PRESENTATION_CHECK.md index cf2de29..80e5b99 100644 --- a/TERMINAL_PRESENTATION_CHECK.md +++ b/docs/measurements/TERMINAL_PRESENTATION_CHECK.md @@ -25,7 +25,7 @@ screenshot and was not copied into the preserved reference directory. The kept normal executable hashes to `1b58a20778dc5ca0eedcaec0b3d7710cc19c8cc9151d58b3180e309fe6d73000`. It contains the kept line-local search-buffer change and shared replacement boundary, not the deferred shared-prefix candidate. -The [baseline report](evidence/clean-baseline-v1/REPORT.md) records its checks and rollback copy. +The [baseline report](../../evidence/clean-baseline-v1/REPORT.md) records its checks and rollback copy. The root working source now matches the accepted implementation. A normal build no longer includes the deferred experiment. Use the installed executable and record its hash at capture time. diff --git a/docs/release.md b/docs/release.md new file mode 100644 index 0000000..33ab8c0 --- /dev/null +++ b/docs/release.md @@ -0,0 +1,41 @@ +# Releasing + +The workspace publishes four crates to crates.io: + +| Package | Source | Notes | +| --- | --- | --- | +| `diffs-fancy-regex` | `crates/diffs-fancy-regex/` | Fork of fancy-regex 0.16.2 | +| `diffs-syntect` | `crates/diffs-syntect/` | Fork of syntect 5.3.0, depends on `diffs-fancy-regex` | +| `diffs-two-face` | `crates/diffs-two-face/` | Fork of two-face 0.5.2, depends on `diffs-syntect` | +| `diffs-rs` | repository root | Depends on all three forks | + +Fork versions are independent of upstream versions. crates.io ignores build metadata when it +compares versions, so a fork cannot carry the upstream version plus a suffix. Each fork records +its upstream base in its description, README, and `[package.metadata.diffs-rs.upstream]`. + +`diffs-rs` depends on each fork with a `package =` rename and both `path` and `version`. +Local builds use the workspace sources; the published package uses the registry versions. +A `diffs-rs` release that does not change a fork does not republish it. + +## Steps + +1. Update the version in `Cargo.toml` (and the forks' manifests if they changed), then run + `cargo update -p diffs-rs` so `Cargo.lock` matches. +2. Add an entry to `CHANGELOG.md`. +3. Run the checks listed in [CONTRIBUTING.md](../CONTRIBUTING.md) and + `cargo package --workspace --locked`. +4. Merge to `main`, then publish in dependency order, skipping crates whose version is already + on crates.io: + + ```sh + cargo publish --locked -p diffs-fancy-regex + cargo publish --locked -p diffs-syntect + cargo publish --locked -p diffs-two-face + cargo publish --locked -p diffs-rs + ``` + +5. Tag the published commit with an annotated tag, for example + `git tag -a v0.1.1 -m "diffs-rs 0.1.1"`, and push it. + +The record of the 0.1.0 release preparation and earlier local qualification is in +[history/RELEASE_READINESS.md](history/RELEASE_READINESS.md). diff --git a/src/lib.rs b/src/lib.rs index 8042d4d..c4405e1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,56 @@ +//! A terminal diff viewer engine for Ratatui applications. +//! +//! This crate provides the `diffs` command-line viewer and the [`engine::Engine`] it is built +//! on. An `Engine` opens one review (a Git patch, two files, or two Git commits), loads and +//! colors it on background threads, and draws into any [`ratatui::layout::Rect`]. The host keeps +//! ownership of the terminal, input, and layout. +//! +//! ```no_run +//! use std::{sync::mpsc, time::Duration}; +//! +//! use diffs_rs::engine::{Engine, Input, Options}; +//! use ratatui::crossterm::event::{self, Event, KeyCode}; +//! +//! fn main() -> anyhow::Result<()> { +//! let mut terminal = ratatui::init(); +//! // The engine sends a hint on this channel when background work is ready. +//! let (wake, woken) = mpsc::sync_channel(1); +//! let input = Input::Patch("changes.patch".into()); +//! let mut engine = Engine::open(input, Options::default(), wake)?; +//! +//! let result = (|| -> anyhow::Result<()> { +//! loop { +//! let _ = woken.try_recv(); +//! engine.poll()?; +//! if engine.needs_draw() { +//! let mut drawn = Ok(()); +//! terminal.draw(|frame| { +//! let area = frame.area(); +//! drawn = engine.draw(frame, area); +//! })?; +//! drawn?; +//! engine.after_draw(); +//! } +//! if event::poll(Duration::from_millis(16))? { +//! let event = event::read()?; +//! if matches!(&event, Event::Key(key) if key.code == KeyCode::Char('q')) { +//! return Ok(()); +//! } +//! engine.handle_event(event, true)?; +//! } +//! } +//! })(); +//! +//! // Joins the background workers and reports cleanup errors. +//! let closed = engine.close(); +//! ratatui::restore(); +//! result.and(closed) +//! } +//! ``` +//! +//! The [embedding guide](https://github.com/plannotator/diffs-rs/blob/main/docs/embedding.md) +//! covers the host loop, focus, source coordinates, reading tools, and shutdown. + pub mod app; mod cleanup; pub mod engine; diff --git a/src/main.rs b/src/main.rs index 98a7706..3b8b132 100644 --- a/src/main.rs +++ b/src/main.rs @@ -42,11 +42,7 @@ mod terminal_input; use terminal_input::TerminalInput; #[derive(Parser)] -#[command( - name = "diffs", - version, - about = "Read-only native terminal diff viewer · visual prototype" -)] +#[command(name = "diffs", version, about = "Fast terminal diff viewer")] struct Cli { #[arg(long, value_enum, default_value = "auto", global = true)] layout: Layout, diff --git a/tests/process/README.md b/tests/process/README.md index 59d485e..df13d11 100644 --- a/tests/process/README.md +++ b/tests/process/README.md @@ -149,7 +149,7 @@ cargo test --release --locked --test process storage_contract -- --ignored --noc ``` Preserved-build agreement supplements the independent source and cell expectations. It does not prove physical terminal presentation or performance. -The [storage report](../../SOURCE_STORAGE_REPORT.md) records the accepted reference and current executable. +The [storage report](../../docs/history/SOURCE_STORAGE_REPORT.md) records the accepted reference and current executable. `horizontal_contract.rs` adds two real-process checks for horizontal bounds. The expected widths count ASCII, tabs, CJK, and combining accents independently. diff --git a/tools/aggregate_five_patch_report.py b/tools/aggregate_five_patch_report.py index 850806e..9d2f205 100644 --- a/tools/aggregate_five_patch_report.py +++ b/tools/aggregate_five_patch_report.py @@ -131,7 +131,7 @@ def main(): "No engineering-check evidence was supplied to this generator."), item("ghostty-pixels", "Actual Ghostty pixel and gesture acceptance", "skipped", "Not measured here. PTY cell captures do not establish Ghostty paint timing, pixel parity, or trackpad feel; no GUI automation was used.", - "/Users/ramos/oss/native-diff/CURRENT_STATE.md", "mixed"), + "docs/history/CURRENT_STATE.md", "mixed"), ]) report["items"] = items (run / "aggregate.json").write_text(json.dumps({"schema_version": 1, "run_dir": str(run), "patches": patches}, indent=2) + "\n") diff --git a/tools/corpus_measure.py b/tools/corpus_measure.py index db421d0..d463cca 100644 --- a/tools/corpus_measure.py +++ b/tools/corpus_measure.py @@ -38,8 +38,9 @@ def bindings(binary, reference): paths = [binary, reference, Path(sys.executable), Path(PROTOCOL["command"]), ROOT / "Cargo.toml", ROOT / "Cargo.lock"] - paths += [ROOT / name for name in ["FIVE_PATCH_ACCEPTANCE.md", "LARGE_DIFFS.md", "MEASUREMENT_POLICY.md", - "SIDEBAR_SPEC.md", "SIDEBAR_CORPUS_PLAN.md", + paths += [ROOT / name for name in ["docs/measurements/FIVE_PATCH_ACCEPTANCE.md", "docs/design/LARGE_DIFFS.md", + "docs/measurements/MEASUREMENT_POLICY.md", "docs/design/SIDEBAR_SPEC.md", + "docs/measurements/SIDEBAR_CORPUS_PLAN.md", "fixtures/diffshub/scenario.json", "fixtures/diffshub/corpus.json"]] paths += sorted((ROOT / "src").rglob("*.rs")) paths += sorted((ROOT / "assets").rglob("*.json")) diff --git a/tools/freeze_trace.py b/tools/freeze_trace.py index 5d2457e..266debe 100644 --- a/tools/freeze_trace.py +++ b/tools/freeze_trace.py @@ -119,7 +119,8 @@ def main(): corpus = json.loads((ROOT / "fixtures/diffshub/corpus.json").read_text()) hashes = {p: digest(ROOT / p) for p in TOOLS + [BASELINE, "fixtures/diffshub/corpus.json", "fixtures/diffshub/scenario.json", "fixtures/diffshub/reference.json", - "MEASUREMENT.md", "SPEC.md", "LARGE_DIFFS.md"]} + "docs/measurements/MEASUREMENT.md", "docs/design/SPEC.md", + "docs/design/LARGE_DIFFS.md"]} hashes.update({str(p.relative_to(ROOT)): digest(p) for p in sorted((ROOT / "src").glob("*.rs"))}) fixtures = [] for fixture in corpus["fixtures"]: diff --git a/tools/regex_census.py b/tools/regex_census.py index 6cc268a..9644111 100644 --- a/tools/regex_census.py +++ b/tools/regex_census.py @@ -149,7 +149,7 @@ def main(): fixture = ROOT / trace["fixture"]["local_path"] assert digest(fixture) == trace["fixture"]["sha256"] hashes = bindings(args.binary, args.reference) - for path in [args.trace, fixture, Path(__file__), ROOT / "REGEX_CENSUS_PLAN.md"]: + for path in [args.trace, fixture, Path(__file__), ROOT / "docs/measurements/REGEX_CENSUS_PLAN.md"]: hashes[str(path.resolve())] = digest(path) if args.check_control: hashes[str(args.check_control.resolve())] = digest(args.check_control)