Skip to content

feat(git): keep a commit window per author when their files cannot overlap - #467

Open
sunib wants to merge 2 commits into
fix/withheld-apply-carryfrom
feat/concurrent-windows-stage2
Open

sunib wants to merge 2 commits into
fix/withheld-apply-carryfrom
feat/concurrent-windows-stage2

Conversation

@sunib

@sunib sunib commented Oct 28, 2026

Copy link
Copy Markdown
Contributor

Stage 2 of concurrent-author-windows.md: a branch worker keeps a commit window per author of a GitTarget, side by side, while their writes are proven to change different files. Two people editing different objects in their own files get one commit each, instead of the second write closing the first person's window (identity_change) and splitting their change. Stacked on #466.

What stays serial

A window's footprint is the set of Git files its writes may change (internal/git/footprint.go). Two windows sit side by side only while their footprints are proven disjoint; anything not proven is unknown, and unknown overlaps everything. A write is proven only when, on the checkout its commit is planned on:

  • the GitTarget has no placement.default, no useKustomize, and no placement.byType template for the kind (a template can bundle objects into one file);
  • the folder reads nothing outside spec.path, feeds no configMapGenerator, and holds no kustomization the writer does not model;
  • no kustomization governs the object's file (none in its directory or above, none naming it in resources: or patches:); a create that placement routes into a kustomize root is unknown;
  • the object's document is alone in its file, or it has none and the built-in path is free;
  • the folder's bootstrap files are committed (a write that committed nothing leaves them staged, and the next commit adds them), and the checkout holds every decided write;
  • the write is a whole object of a type that is not encrypted.

Admission (window_admission.go): an unknown footprint, a write of another GitTarget, or a worker that fell back closes every other window first (identity_change, as today). A proven write that overlaps another window's footprint closes that window first (path_conflict, a new close_reason), so its older write commits before the newer one. Same object means same document in any one tree, so two windows never hold one object.

Proof per revision

A proof is made against a revision: the count of the worker's resets and own commits, plus the GitTarget's generation. Before a write is admitted beside others, every open window whose proof is of another revision is proven again from all its writes (FootprintReproved); windows whose new proofs overlap close first, oldest first, with path_conflict. A window is proven only once it has company: a lone window stays "unproven", costs no scan, and its commit is not checked. Once proven, its footprint covers every write it collects.

Check before the commit

A window that was ever open beside another carries its footprint onto its decided write. Right before the write's first commit, once the checkout holds every write before it, the footprint is proven again on that exact tree (proveBeforeCommit): the windows its admission closed commit first and can move what it changes (a delete committed first turns its update into a create). Then every path the commit would change, read from the index against HEAD (not writeBatch.touched), must be inside it. A violation is a footprint bug and is refused, not committed: the batch's worktree is undone, the write fails as terminal and its save fails with the paths in the message, the worker logs SingleWindowFallback and holds one window at a time for the rest of its life, and a resync of the GitTarget is asked for. A proof of another tree (after a reset, or a GitTarget change) says nothing about this one, so that commit is not checked. Replays are never checked: their order is already fixed.

Other changes

  • commitWindows is an ordered list (open order = seq) and is no longer embedded in the loop; tests read it through only() / bytes() (and fake one with setOnly).
  • finalizeWindow arms the commit timer for the earliest deadline of the windows left open instead of stopping it; commitTimerAt stays accurate.
  • attachWaitingCommitRequests skips a window an earlier attach in the same pass closed (with several windows that leaked a request onto a closed window and its charge).
  • A save waiting while another author's window is open records a mismatch only when no window of its own author is open.
  • "Opening commit window", "Finalizing open commit window" and "Open commit window finalized" carry window (the seq, reset per worker, never a metric label), branch, and decision (WindowOpened, WindowClosed); joins log WriteJoinedWindow at V(1). These are diagnostic names, not a journal.
  • Interactions kept: saves commit on their own timers from the attach; pendingCarriesCommitRequest pushes at once; the holdPushes / cooldownHoldsSaves seam; a flush, a resync, buffer pressure and shutdown close every window, oldest first; the push-notice close skips windows carrying a save; the byte budget is shared; the withheld-field restore runs per object before admission.

No flag: stage 3 before the release

By decision there is no startup flag; stage 2 is on once merged. So stage 3 (the failure boundaries against the reference model, with several windows open) must land before the next release; docs/TODO.md "Before the next release" says so.

Reference model

window_model_test.go now models several windows with its own footprint rules, on a folder with three shapes: x, w, z alone in their files; k in a kustomize root, which also takes every object created anew; and s1, s2 in one shared file. After every step it compares the open windows (seq, author, objects, save, deadline, charge, footprint), the armed timers, saves, the byte charge and the close reasons (with window numbers). On every commit it compares the full changed-path set, every changed file whole (documents parsed with yaml.v3, the kustomization's resources:), write order per document, and asserts changed paths ⊆ footprint for a window that had company. It fails on any SingleWindowFallback.

  • CI seeds (6 × 40): pass, 25 steps end with several windows open.
  • Sweeps: 100 × 60 pass (383 concurrent steps); 300 × 80 pass (1444).
  • Mutation check (CI seeds, a 40 × 60 sweep, and the new unit tests):
    • never close a blocking window: caught by the model (CI seeds) and three unit tests;
    • skip the timer re-arm in finalizeWindow: caught by the 40 × 60 sweep (not the CI seeds) and by TestWindowAdmission_ClosingOneWindowArmsTheTimerForTheOthers;
    • skip reproving stale proofs: caught by the model (CI seeds);
    • skip the check before the commit: caught only by TestWindowAdmission_ACommitOutsideItsFootprintIsRefusedAndTheWorkerFallsBack (the model asserts ⊆ footprint itself, so it never sees a refusal);
    • skip proveBeforeCommit: not caught; the check then skips commits whose proof is stale, so it checks fewer commits but refuses none wrongly. An earlier version without it refused a correct commit in the sweep, which is why it exists.

Found on the way and left alone: a ConfigMap named y in a kustomize root is refused by the render oracle (kustomize reads a bare y as a boolean); the model has no object y for that reason.

Validation

task fmt, task generate, task manifests, task vet, task lint, task test pass; local e2e queued; result will be posted as a PR comment (CI runs the e2e legs too).

🤖 Generated with Claude Code

sunib and others added 2 commits October 28, 2026 19:47
…erlap

A branch worker held one commit window, so a second author's write closed
the first author's window (identity_change) and split their change. Stage 2
of docs/design/concurrent-author-windows.md keeps a window per author of a
GitTarget, side by side, while their footprints are proven disjoint.

- commitWindows holds an ordered list of windows (open order = seq); the
  loop no longer embeds it, and tests read it through only()/bytes().
- footprint.go proves the set of files a write may change against a
  revision (resets, own commits, GitTarget generation). An object alone in
  its file, ungoverned by any kustomization, with no placement template, in
  a bootstrapped folder, is proven; anything else is unknown and serial.
- window_admission.go: unknown footprints and other GitTargets close every
  other window (identity_change); an overlapping footprint closes the
  window that holds the file first (path_conflict). Before a write is
  admitted beside others, every open window is proven again
  (FootprintReproved).
- A window once open beside another is checked before its first commit:
  every staged path must be inside its footprint, proven again on the tree
  the commit is planned on. A violation undoes the worktree, fails the
  write and its save, falls back to one window for the worker's life
  (SingleWindowFallback) and asks a resync of the GitTarget.
- finalizeWindow arms the commit timer for the remaining windows instead
  of stopping it; attachWaitingCommitRequests skips a window an earlier
  attach closed.
- Log lines carry the window ID and branch; path_conflict is a new
  close_reason.
- The reference model grows to several windows, a kustomize root and a
  shared multi-document file, and checks footprints, every changed path
  and whole documents (yaml.v3) on every commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…age 3

configuration.md says which writes keep a window per author and which stay
serial, and that commits land in the order their windows close.
interpreting-metrics.md documents close_reason="path_conflict". The design
page records what stage 2 built. Stage 2 ships without a flag, so TODO.md
holds the next release for stage 3, the failure boundaries against the
reference model.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 59 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 1e3c471e-98b8-4a91-8055-23a697470261
Commits

Reviewing files that changed from the base of the PR and between ace401b and f5e5e26.

Files selected for processing: 49
  • docs/TODO.md
  • docs/configuration.md
  • docs/design/concurrent-author-windows.md
  • docs/interpreting-metrics.md
  • internal/git/applier_claim.go
  • internal/git/applier_claim_test.go
  • internal/git/applier_echoes_test.go
  • internal/git/apply_attempt_test.go
  • internal/git/apply_catchup_test.go
  • internal/git/apply_converge_test.go
  • internal/git/apply_ownership_test.go
  • internal/git/apply_window_carry_test.go
  • internal/git/apply_window_test.go
  • internal/git/branch_worker.go
  • internal/git/branch_worker_loop_test.go
  • internal/git/branch_worker_new_branch_test.go
  • internal/git/branch_worker_queue_depth_test.go
  • internal/git/branch_worker_split_test.go
  • internal/git/commit_executor.go
  • internal/git/commit_request_attach_loop.go
  • internal/git/commit_request_attach_test.go
  • internal/git/commit_request_empty_test.go
  • internal/git/commit_request_withdraw_test.go
  • internal/git/commit_window_clock_test.go
  • internal/git/commit_window_metrics_test.go
  • internal/git/commit_window_timers_test.go
  • internal/git/footprint.go
  • internal/git/intake.go
  • internal/git/intake_test.go
  • internal/git/open_window.go
  • internal/git/pending_writes_loop.go
  • internal/git/push_notification_test.go
  • internal/git/refresh.go
  • internal/git/render_fidelity_drops_test.go
  • internal/git/render_fidelity_gate_test.go
  • internal/git/render_fidelity_hold_test.go
  • internal/git/replay_failure_test.go
  • internal/git/replay_refusal_test.go
  • internal/git/resync_flush.go
  • internal/git/resync_push_test.go
  • internal/git/types.go
  • internal/git/window_admission.go
  • internal/git/window_admission_test.go
  • internal/git/window_model_test.go
  • internal/git/window_set.go
  • internal/git/window_set_test.go
  • internal/git/write_boundary_precondition_test.go
  • internal/git/write_gate_test.go
  • internal/telemetry/exporter.go
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sunib

sunib commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor Author

Local task test-e2e on f5e5e26 (the PR head): SUCCESS, 113 of 176 specs ran, 113 passed, 0 failed, 63 skipped (948s). No flakes, no reruns.

@codecov

codecov Bot commented Oct 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.91774% with 47 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/git/footprint.go 78.8% 46 Missing ⚠️
internal/git/window_admission.go 98.8% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

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