batch: Preserve exact state across layered replay - #458
Merged
Conversation
The discard replacement workflow saves selected replacement text in a batch and reverses that selection from the live worktree. Users lose transformed wording when a selected addition extends beyond the deleted side of a mixed replacement. The rollback treats that wording as an independent insertion even though it belongs to the replacement already in progress. This commit begins preserving transformed additions by recognizing a selected addition in a mixed replacement run and excluding its rewritten row from the live-worktree rollback. The next commit will exercise the retained wording before later commits preserve its selectable identity and exact selection scope.
The discard replacement workflow retains transformed additions that extend mixed replacement runs in the live worktree. The functional suite does not demonstrate the multiline Markdown shape that exposed the rollback failure. A regression could therefore remove neighboring replacement content without detection. This commit continues validating transformed additions with a selected sentence beyond the deleted side of a replacement and verifies that the surrounding list remains live. Subsequent commits will preserve selected wording when it matches deleted baseline text and when it occupies part of a larger added side.
The discard replacement workflow retains transformed trailing additions by mapping their rewritten diff rows into saved batch ownership. Git can align transformed wording with a deleted baseline line and render the new occurrence as unchanged context. Users then cannot save the replacement because the rewritten occurrence has no selectable addition row. This commit continues preserving transformed additions by masking the rewritten span while Git constructs the diff and restoring its exact bytes on the resulting addition rows. Subsequent commits will exercise that alignment case before preserving exact added-line scope within larger replacements.
The discard replacement workflow retains transformed trailing additions even when Git could align their wording with deleted baseline content. The functional suite does not lock down that alignment case across batch creation and later application. A regression could make the transformed occurrence unselectable or alter the saved alternative during replay. This commit continues regression validation by reproducing the baseline-text collision and asserting the live file, saved batch, and replayed result. The next code commit will preserve selected added lines that occupy only part of a larger replacement run.
The discard replacement workflow retains transformed trailing additions and keeps their rewritten rows selectable when the wording matches baseline text. Users who transform selected added lines inside a larger replacement can still lose neighboring working text because the fallback widens those lines to the entire replacement. This commit addresses that by keeping a non-empty selection bound to its resolved worktree coordinates when unselected added lines remain in the same replacement. The existing snapshot-bound buffer builder now performs that rewrite, so its dead-code exception is no longer needed. The final commit will exercise the full document shape, line-count changes, the complete-added-side boundary, and saved-batch replay.
The discard replacement workflow keeps a non-empty selection of added lines bound to its worktree coordinates when other added lines remain in the same replacement. Selecting every added line retains the whole-replacement behavior. The functional suite lacks the full document shape that exposed selection widening. It also does not pin line-count changes or the complete added side across later batch application. This commit completes regression validation by reproducing the 31-line replacement, exercising selections that grow or shrink, and asserting the complete-added-side behavior through batch creation and replay. Discarding transformed added lines now preserves their intended scope across ordinary wording, baseline matches, and partial added-side selections.
Line matching owns two mapped vectors that record source-to-target and target-to-source correspondences. The replacement-origin fix needs the matcher result in its reciprocal orientation, but copying those potentially large vectors would violate the bounded-memory design. This commit begins correcting stale replacement origins by allowing a mapping to transfer its vectors into a reversed owner. Subsequent commits will add snapshot-bound projections before applying them to discard workflows.
Line mappings can transfer their mapped vectors into the reciprocal orientation without allocating duplicate storage. The new ownership rule must close the original mapping so two objects cannot claim the same mapped resources. This commit records the reciprocal lookup results and the closed state of the original owner. Later tests will exercise the snapshot-bound projections that consume the reversed mapping.
Coordinate transforms distinguish snapshot roles even when two snapshots contain identical bytes. Replacement origins need to move between such roles without reconstructing provenance from line matching. This commit continues the stale-origin fix by adding an exact projection that verifies identical snapshot content before rebinding a span. Subsequent commits will add structural projection for evolved sources and recorded lineage for rewritten worktrees.
Identical snapshots can now rebind coordinates across semantic roles through an exact span projection. The projection must preserve the full span geometry without relying on structural matching. This commit records the role-rebinding behavior for a snapshot with identical content identity and extent. The next code commit will provide conservative span projection when the batch source has evolved.
Structural alignments expose line correspondences as evidence without treating them as recorded provenance. A replacement origin may still be moved safely when every line in its source span maps reciprocally into one contiguous target span. This commit adds that conservative span projection while rejecting empty, fragmented, unmapped, or stale-snapshot requests. Subsequent commits will expose the typed replacement-origin contract that consumes the projection.
Structural alignments can now project a requested span only when its mapped lines form one exact target range. The boundary needs tests for successful relocation, fragmented matches, unrelated global ambiguity, and stale snapshot evidence. This commit records the accepted contiguous cases and the conservative rejection cases. The next code commit will bind recorded rewritten-worktree lineage to an exact transform.
Recorded batch-source lineage has typed exact transforms for original source coordinates and observed worktree coordinates. The transformed discard workflow produces another coordinate role after applying its explicit edit, so ordinary worktree typing cannot describe that source snapshot. This commit adds a dedicated rewritten-worktree lineage variant with runtime role validation. Subsequent commits will use the available transforms through a typed replacement-origin interface.
Replacement-origin inputs describe where semantic replacement runs came from, but they do not describe the current batch-source snapshot that will store them. Passing untyped line-number callbacks would permit the coordinate-space mix-up that caused stale replacement spans. This commit defines a generic snapshot-bound projection protocol whose target is always batch-source space. Later commits will bind replacement metadata through that protocol before discard workflows adopt it.
Replacement-unit origins persist produced-side geometry as line numbers in the current batch source. Callers that translate a typed source span still have to unpack it manually, which could discard the proof of its coordinate role at the assignment boundary. This commit adds a model operation that accepts only a batch-source snapshot span before updating the stored geometry. Subsequent commits will route live hunk origins through the typed projection contract.
Live hunk replacement translation derives origin geometry from the replacement stream that is currently displayed. After a batch source evolves, those displayed line numbers can name a different range or extend beyond the source snapshot. This commit projects each complete semantic origin span into batch-source coordinates and omits origin evidence when the mapping is not exact. Subsequent commits will expose that behavior through the selection translator before each discard workflow supplies its source projection.
Live hunk translation can now bind semantic replacement origins to a contiguous batch-source span. The behavior needs to distinguish an exact relocated range from content that appears only in fragmented source positions. This commit records the rebound coordinates for the exact case and omitted provenance for the fragmented case. The next code commit will carry the projection through the higher-level hunk selection translator.
The low-level replacement translator accepts a snapshot-bound origin projection, while the general hunk selection entry point still exposes only replacement content. Discard workflows enter through the general translator, so they cannot yet preserve the typed coordinate evidence. This commit threads the generic projection through that entry point without changing callers that omit it. Subsequent commits will construct the projection for ordinary stale-source discard selections.
Batch ownership updates can carry a typed origin projection through hunk translation, but the update acquisition layer does not construct one from live source content. Ordinary discard selections may use either unchanged source bytes or a source advanced by prior batch operations. This commit prepares an exact same-content projection or a reciprocal structural alignment when a caller supplies the live replacement target. The next code commit will make the ordinary line discard path supply that target.
Line-based batch updates prepare replacement runs from the current working content and can now construct a batch-source projection for their origins. The discard path does not supply that content to ownership acquisition, so cached sources can still persist origin coordinates from the wrong snapshot. This commit enables projection for ordinary line discard by passing the live working-source buffer into ownership acquisition. Subsequent commits will record the cached-source reproducer before applying the same invariant to transformed discard selections.
Ordinary line discard now projects replacement origins from the live working snapshot into the current batch source. A prior deletion peel can enlarge the working file after the later batch source was cached, which previously left the next replacement with out-of-range origin geometry. This commit reproduces that sequence and verifies both the stored source bounds and the resulting batch content. The remaining commits will apply the same coordinate invariant to the transformed replacement discard workflow.
Ordinary line discard now stores replacement origins in current batch-source coordinates, while transformed replacement discard still records rewritten display coordinates directly. Separate peels can evolve the source around those replacements, so the transformed path can restore an unrelated baseline span even when its numeric range remains in bounds. This commit composes the recorded edit with exact rewritten lineage for normal replacements and expanded semantic parents before binding their origins. The final commit will preserve the fuller multi-peel reproducer that closes the stale replacement-origin fix.
Both ordinary and transformed discard workflows now bind replacement origins to the batch-source snapshot that persists them. The fuller failure requires three separate peels from an evolving Markdown replacement, where stale numeric geometry previously restored an earlier baseline block. This commit reproduces that sequence and verifies that the final batch retains each intended replacement in file order. The series now prevents replacement-origin coordinate mix-ups through snapshot-typed projections across both discard workflows.
Line comparison streams semantic change runs as range-backed records. Each record classifies an unmatched gap and retains its source and target ranges with the preceding target line. Saved and live replacements can be layered across snapshots where the same numeric positions identify different content. The program cannot replay those layers exactly unless comparison preserves positional evidence for both sides of every changed section. This commit begins making layered replacement replay exact by adding the preceding source line to every streamed range record beside its existing target anchor. The next commit will exercise streamed range anchors directly. Subsequent commits will add exact-sequence groundwork, then carry that evidence through replacement ownership into saved and live replay.
Line comparison streams semantic changes as range records that retain the source and target positions immediately before each changed section. The project does not directly verify that the newly retained source position survives streaming across replacements, deletions, and additions. Exact layered replay could lose needed positional evidence without a comparison test detecting the regression. This commit exercises the source anchor, meaning the source position before a change, on streamed replacement, deletion, and addition range records. Subsequent commits will add exact-sequence groundwork, then propagate the anchor evidence through replacement ownership into saved and live replay.
Line comparison streams semantic change ranges with the source and target positions immediately before each changed section. Direct range tests exercise those anchors across replacements, deletions, and additions. The project lacks a bounded search for every byte-for-byte occurrence of a line sequence, including overlapping occurrences, without retaining temporary match state in Python containers. Replacement ownership needs that capability to locate corresponding content across layered snapshots. This commit adds a linear-time iterator for exact sequence occurrences within optional source bounds. It stores prefix-match lengths in a matcher workspace and releases that scratch resource when iteration finishes or callers stop early. Next commits will add reciprocal mapping exclusions and structural occurrence matching before replacement ownership consumes the search.
Line comparison provides reciprocal mappings between batch-source and working-tree lines, and exact-sequence search keeps its match workspace outside the Python heap. The project lacks a way to retain those relationships while omitting selected source lines and target spans without growing Python heap use. Structural occurrence matching needs that filtered evidence before it can normalize repeated content for replacement ownership. This commit adds a mapping copy operation that walks the target side once, skips pairs covered by either exclusion, and rebuilds both directions in mapped storage. It validates target spans, preserves uncertainty about unmapped equal lines, and closes allocated storage after failures. The preceding commit established exact-sequence search with scratch storage outside the Python heap. Filtering reciprocal mappings under the same constraint advances that groundwork; the next commit can normalize structural occurrences before replacement ownership uses them.
Line comparison can copy reciprocal mappings while excluding selected batch-source line ranges and working-tree target spans. The copy retains both mapping directions in mapped storage and marks excluded pairs as potentially equal but unmapped. The project does not directly verify that exclusions clear each reciprocal entry or that a large target span stays represented by fixed boundary offsets. A regression could leave one direction stale or return line-scale temporary storage to Python heap memory. This commit exercises source-range and target-span exclusions, checks both directions and the uncertainty flag, and bounds Python heap growth as the excluded span expands. The preceding commit introduced the filtered mapping copy. The next commit will normalize structural occurrences before replacement ownership consumes the retained positional evidence.
Line comparison can retain mappings in both directions outside excluded source and target regions. Its mapped-storage occurrence index groups exact or line-ending-normalized byte payloads. Structural occurrence matching must recognize lines after nesting shifts them to another indentation level. Payload identity preserves leading spaces and tabs, while applying byte indentation rules to caller-defined non-byte payloads would give that mode no valid meaning. This commit continues preparing structural occurrence matching by adding an indentation-insensitive occurrence index mode. Normalized payloads lose their final line terminator before leading spaces and tabs are stripped, and the mode rejects non-byte payloads rather than applying byte indentation rules. The next commit will exercise indentation-insensitive occurrences before later work searches for occurrences bounded by adjacent lines.
Line comparison has an occurrence index that groups repeated line payloads after normalizing their final line endings. Callers can also request that leading spaces and tabs be ignored for byte payloads. The project does not directly verify that the optional mode normalizes both indexed lines and lookup values. A regression could match content at its original indentation while losing it when the same structural line moves into another block. This commit exercises indentation-insensitive occurrence counts with tabs, spaces, and differing line endings on both sides of a lookup. The checks show that normalized structural payloads remain identical across indentation shifts. The next commit will search for structural occurrences bounded by adjacent lines.
Functional discard coverage applies one transformed paragraph replacement at a time. It does not demonstrate sequential replacements whose headings and shared prose evolve between batch operations. This commit records and discards two Markdown replacements while checking each retained section and boundary. Replacement discard now has end-to-end coverage for sequential document rewrites.
Functional apply coverage replays line-oriented edits across batch layers. It does not combine independent word-level insertions around a paragraph rewritten by another layer. This commit applies layered paragraph replacements and verifies compatible words from each layer survive once. Applied-text replay now has end-to-end coverage for layered paragraph composition.
Functional apply coverage composes transformed text before ownership is recorded. It does not replay a later paragraph transformation after an earlier batch has already established ownership. This commit records ownership first, applies a transformed paragraph, and verifies baseline words and both compatible insertions. Applied-text replay now has end-to-end coverage after ownership capture.
Whole-file discard planning replays ownership and applied overlays against the current worktree. When the selected batch is the trailing application, that reconstruction can guess through a transformed file even though its exact predecessor was recorded. This commit loads the saved predecessor for unscoped trailing-batch discard before falling back to structural reversal. Discarding a trailing whole-file batch now restores its exact prior content.
Functional apply coverage replays a whole tracked file without earlier batch removals. It does not verify that surviving baseline deletions remain absent after a prior batch peels independent content. This commit adds that sequence and asserts the exact whole-file result. Whole-file replay now has end-to-end coverage after an independent peel.
Functional replacement coverage extends a whole-file transform before independent batch content is removed. It does not repeat the extension after that separate content has already been peeled from the live file. This commit updates the scenario to verify the extended transform keeps the peeled content absent. Whole-file replacement now has end-to-end coverage after an independent peel.
Presence-context tests cover a direct recorded alternative. They do not distinguish exact claim elision from wrong duplicate coordinates or ambiguous enclosing target spans. This commit adds accepted and rejected mappings for those alternative placements. Presence context now has direct coverage for exact and unique live alternatives.
Structural validation tests cover complete replacement mappings. They do not stress split claimed ranges, a claimed line matching its old side, or unrelated source matches inside the replacement old span. This commit adds cases that require replacement ownership to rebuild and remove content only within its verified boundary. Replacement validation now has direct coverage for fragmented and duplicate text.
Merge tests cover one source alternative positioned by distinct surrounding content. They do not stress leading separators, duplicate old-side text outside the selected span, or several unambiguous predecessor occurrences. This commit adds replay cases that require source-scoped alternative placement and exact separator restoration. Structural merge now has direct coverage for duplicate and repeated alternatives.
Functional discard coverage uses focused synthetic transformations and a smaller set of realistic source movements. It does not cover the broader combinations of predecessor restoration, adjacent deletion geometry, duplicate anchors, whole-file expansion, and retained suffix placement. This commit adds a regression corpus for those transformed replacement workflows and updates the shared scenarios to assert exact replay boundaries. Discard and apply replay now have broad end-to-end coverage for composed real-world transformations.
Functional inclusion coverage places tracked insertions after distinct context. It does not isolate an insertion whose boundary follows a closing fence shared by neighboring transformed content. This commit includes that insertion and verifies its exact position and surrounding text. Tracked insertion replay now has end-to-end coverage for shared closing boundaries.
Live-change workers import the applied overlay view through a data-layer compatibility module. The view now belongs to the batch layer, so retaining the indirect import obscures ownership and keeps an unnecessary dependency edge. This commit imports the batch overlay view directly while normalizing the worker module layout. Live status counting now follows the current batch-layer boundary.
Recent implementation work leaves touched modules with older wrapping, dense expressions, and authority-oriented module descriptions. The mixed presentation makes the edited paths inconsistent even though their behavior is already covered by separate commits. This commit applies the current local normalization to source and benchmark modules without changing their runtime decisions. The touched implementation paths now use consistent prose and layout.
The expanded regression suite leaves several touched test modules using older wrapping and spacing. Those presentation-only differences obscure the behavioral assertions committed in the preceding validation changes. This commit normalizes imports, expressions, and blank-line layout without changing test intent. The touched tests now follow one consistent source layout.
The Arabic message catalog predates the latest include diagnostics and replacement-batching status text. Leaving it unchanged would omit the new source messages and retain obsolete reference ordering after the implementation series. This commit merges the current message inventory and supplies the updated Arabic translations. The Arabic catalog now matches the translatable application surface.
The Czech message catalog predates the latest include diagnostics and replacement-batching status text. Leaving it unchanged would omit the new source messages and retain obsolete reference ordering after the implementation series. This commit merges the current message inventory and supplies the updated Czech translations. The Czech catalog now matches the translatable application surface.
The German message catalog predates the latest include diagnostics and replacement-batching status text. Leaving it unchanged would omit the new source messages and retain obsolete reference ordering after the implementation series. This commit merges the current message inventory and supplies the updated German translations. The German catalog now matches the translatable application surface.
The Spanish message catalog predates the latest include diagnostics and replacement-batching status text. Leaving it unchanged would omit the new source messages and retain obsolete reference ordering after the implementation series. This commit merges the current message inventory and supplies the updated Spanish translations. The Spanish catalog now matches the translatable application surface.
The French message catalog predates the latest include diagnostics and replacement-batching status text. Leaving it unchanged would omit the new source messages and retain obsolete reference ordering after the implementation series. This commit merges the current message inventory and supplies the updated French translations. The French catalog now matches the translatable application surface.
The Japanese message catalog predates the latest include diagnostics and replacement-batching status text. Leaving it unchanged would omit the new source messages and retain obsolete reference ordering after the implementation series. This commit merges the current message inventory and supplies the updated Japanese translations. The Japanese catalog now matches the translatable application surface.
The Korean message catalog predates the latest include diagnostics and replacement-batching status text. Leaving it unchanged would omit the new source messages and retain obsolete reference ordering after the implementation series. This commit merges the current message inventory and supplies the updated Korean translations. The Korean catalog now matches the translatable application surface.
The Dutch message catalog predates the latest include diagnostics and replacement-batching status text. Leaving it unchanged would omit the new source messages and retain obsolete reference ordering after the implementation series. This commit merges the current message inventory and supplies the updated Dutch translations. The Dutch catalog now matches the translatable application surface.
The Polish message catalog predates the latest include diagnostics and replacement-batching status text. Leaving it unchanged would omit the new source messages and retain obsolete reference ordering after the implementation series. This commit merges the current message inventory and supplies the updated Polish translations. The Polish catalog now matches the translatable application surface.
The Brazilian Portuguese message catalog predates the latest include diagnostics and replacement-batching status text. Leaving it unchanged would omit the new source messages and retain obsolete reference ordering after the implementation series. This commit merges the current message inventory and supplies the updated Brazilian Portuguese translations. The Brazilian Portuguese catalog now matches the translatable application surface.
The Russian message catalog predates the latest include diagnostics and replacement-batching status text. Leaving it unchanged would omit the new source messages and retain obsolete reference ordering after the implementation series. This commit merges the current message inventory and supplies the updated Russian translations. The Russian catalog now matches the translatable application surface.
The Turkish message catalog predates the latest include diagnostics and replacement-batching status text. Leaving it unchanged would omit the new source messages and retain obsolete reference ordering after the implementation series. This commit merges the current message inventory and supplies the updated Turkish translations. The Turkish catalog now matches the translatable application surface.
The Ukrainian message catalog predates the latest include diagnostics and replacement-batching status text. Leaving it unchanged would omit the new source messages and retain obsolete reference ordering after the implementation series. This commit merges the current message inventory and supplies the updated Ukrainian translations. The Ukrainian catalog now matches the translatable application surface.
The Simplified Chinese message catalog predates the latest include diagnostics and replacement-batching status text. Leaving it unchanged would omit the new source messages and retain obsolete reference ordering after the implementation series. This commit merges the current message inventory and supplies the updated Simplified Chinese translations. The Simplified Chinese catalog now matches the translatable application surface.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Saved batches can preserve line-level additions, deletions, and replacements,
then replay that ownership while the index and worktree continue to evolve.
The existing merge paths use recorded source ranges, target ranges, and nearby
content to recover those changes.
Repeated text, nested replacements, whole-file transforms, and applied batch
layers can make several locations look equally plausible. Coordinate evidence
may also become stale after a peel, sift, review, or same-file rewrite. Those
ambiguities can widen a selection, restore unrelated baseline text, duplicate
content, reject a valid operation, or display IDs that no longer identify the
reviewed lines.
This pull request carries exact source and target identity through comparison,
ownership, source advancement, merge, discard, and review workflows. It adds
reciprocal line projections and bounded occurrence indexes, persists complete
file-pair and replacement alternatives, records exact preimages and separator
provenance for applied overlays, and retains exact page membership for file
reviews. Replay now resolves alternatives from their recorded geometry and
verified context instead of borrowing authority from similar surrounding
content.
The regression corpus exercises nested and repeated alternatives, transformed
added files, tracked and untracked whole-file replacements, layered Markdown
rewrites, sifting, reset, sequential undo, and insertions or deletions crossing
evolved source context. Supporting workflow changes keep rich prompt status in
a nonblocking validated cache, apply ordered file-pattern exclusions, preserve
explicit replacement and executable-file behavior, and scope rewrite
publication checks to the movable range. Documentation, checker policy, source
layout, and all maintained translation catalogs match the resulting command
surface.
This pull request supersedes #457. Its transformed-addition fixes are preserved
at the start of the series and extended with exact replacement-origin
projection through the later replay pipeline.
Validation:
uv run pytest -n autouv run ruff check src tests scriptsuv run python scripts/check_translations.pyuv run python scripts/check_dead_code.pyuv run python scripts/check_type_hygiene.pyuv run mypy