Expand description
Verifying the WORKING TREE — the check an agent actually wants.
weave check used to compare HEAD against MERGE_HEAD: two commits,
not the working-tree resolution someone had just written. That misses the
dominant real defect in these merges, which is not a mis-resolved
marker — it is silent breakage in the unconflicted region that no marker
points at, findable only by reading the whole file by hand. That reading
is the cost this module exists to remove.
So the subject is the file on disk, and the questions are the four an agent asks after editing:
- markers — did I finish? (including weave’s own teach line)
- loss — did I drop a line BOTH sides kept? Unanimity is the one thing a resolution may never overrule: neither developer asked for it to go.
- duplicates — did the merge state something more times than either
side did? Same ruler as
weave_core::frame, applied to the whole file instead of the frame. - dangling — is anything still called that nothing defines any more? Binding evidence, repo-wide, the same functions the per-file pass uses.
Every verdict is stated as a sentence, never as an empty array. A
reader who gets back a bare [] reasonably takes it for approval; a
channel whose “nothing found” and “nothing looked at” render identically
has a failure mode where silence is indistinguishable from a clean bill of
health.
§Why the bounds below are the ones they are
A verifier that replaces a manual pass is only worth its calls if its findings are evidence. Every rule here is therefore stated as a necessary condition on a correct resolution — one the developer’s own committed resolution satisfies — and the three ways that can be got wrong are all ways this file once got them wrong:
- The unanimity floor is base-relative and additive.
min(ours, theirs)is what a merge must keep only if the two sides always delete the same copies of a repeated line, which on real code they never do. The bound ismin(n, ours) + min(n, theirs) − nover base’sncopies, floored at zero — the predicate [weave_core::container] enforces inside the merge. Two owners of one rule is one owner too many, so this states it the same way rather than a second way. - The duplication ceiling is additive too. Two sides that each add a
copy of the same line license a resolution that has one more copy than
either side does;
max(base, ours, theirs)calls every such union a duplicate. The ceiling is the oneweave_core::frame::frame_duplicatesalready uses. - Multiplicity is only evidence for a line that has an identity.
framesays this for structural punctuation. It is equally true of a continuation fragment —anyInt(),,await fire_event(— which is not a statement but a slice of one, and repeats wherever the same call shape is written. A fragment counts only when it is part of a run of over-budget lines, which is what a doubled edit actually looks like.
and one that is about names rather than lines:
- A declaration and its impl blocks are ONE nameable thing. Rust’s
struct Xplusimpl Xis notXdefined twice; neither is a namespace reopened, an interface merged, twotest('…')calls sharing a title, or two overloads sharing a name. Identity is (kind, name, signature) with the kinds that attach to a declaration excluded — not the bare name.
Structs§
- Advisory
- One advisory about one file — a fact weave surfaces without deciding it. It
is NOT a finding: it never makes a verdict
FOUND, never counts in the tally, and never changes the exit code. It rides beside the verdict as something a reviewer may want to glance at, not something they must fix. - Finding
- One finding about one file, already in the words the reader gets.
- Report
- Everything one run of the working-tree check looked at and concluded.
- Verdict
- One file’s verdict. An empty
findingsis the OK verdict and prints as a sentence.advisoriesare separate: a file may be OK and still carry them.
Functions§
- check
- Verify a whole working tree against the three merge stages.