Skip to content

feat: per-file preview limits and viewer load more - #125

Merged
flexdinesh merged 1 commit into
mainfrom
preview-limits
Oct 27, 2026
Merged

flexdinesh merged 1 commit into
mainfrom
preview-limits

Conversation

@flexdinesh

Copy link
Copy Markdown
Owner
  • Behavior owner and resulting change: collector owns the preview policy (new internal/collector/previews.go). The fixed 16 MiB raw budget, split 1/N across scopes (~3.2 MiB for a branch's Combined view), is replaced by:

    • per-file limits: patch 1 MiB, full contents 1 MiB per side;
    • a 1000-file-per-scope limit;
    • a total measured on encoded JSON (MaxRequestBytes minus the encoded request skeleton minus 1 MiB headroom), so </> HTML escaping can't push a request past 64 MiB.

    Patches for every scope are captured before any full contents, so full-file views degrade before files lose their patch. Each pass shares the remaining budget between scopes in rounds, in file order, skipping files that don't fit. No scope can consume another's share, and a share a scope doesn't need goes to the others. Piped patches use the same preview limits; piped input validation stays at 2 MiB per file and 16 MiB total. In the viewer (use-diff.ts, DiffWorkspace.tsx), previews load in file-tree order 16 MiB at a time, and a "Load more" notice action continues the next window, replacing the old hard "Preview budget exceeded" stop.

  • Contracts/invariants affected; local/remote implications: no wire or schema change. Both compositions use the same collector policy. Content identity stays independent of preview truncation. Unchanged checkouts keep reusing their earlier, more truncated snapshot until the content changes or the snapshot expires.

  • Validation results; remaining risks:

    • mise run check passes after rebasing on main.
    • New collector tests cover: allocation shares and redistribution, every comparison keeping its patches with unused shares redistributed, patches before contents, per-file and file-count limits, encoded-byte accounting, oversize piped patches.
    • A mutation that drops redistribution fails the tests.
    • Manual: a local server on a synthetic 100-file branch stored all 100 patches and full contents in both scopes (~27 MiB each); the old split stored about 23 per scope.
    • Risks:
      • snapshots can store up to ~3.5x more data;
      • files that don't fit their share may be read from Git again in later rounds;
      • in the viewer, a preview near the window cut can show briefly, then switch to "Not loaded".
  • Intentional architecture/design changes and rationale: docs/system.md describes the new policy. A total cap stays because an observation is one ingestion request and one transaction.

  • UI evidence: neutral Notice with an outline-muted small Button, following the "View latest" pattern; covered by the Playwright test "previews load in file order 16 MiB at a time". Pierre geometry is preserved by reusing one status item per file and message.

…d more

Replace the fixed 16 MiB raw budget split equally across scopes with
per-file (1 MiB patch, 1 MiB contents per side) and 1000-file limits,
plus a total measured on encoded JSON to fit the 64 MiB request limit.
Capture all patches before full contents; share the remaining budget
between scopes in rounds so unused shares move to scopes that need them.
Viewer loads previews in file order 16 MiB at a time with Load more.
@flexdinesh
flexdinesh merged commit 122ae80 into main Oct 27, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant