---
name: assemble-onto-the-repair-tip-not-a-sibling
description: "BINDING assembly rule: a fix branch off main is a SIBLING of your candidate, not a descendant — assert ancestry before push, and assert picked content by BLOB because a rebase mints new shas"
metadata: 
  node_type: memory
  type: feedback
  originSessionId: f5d0d603-387b-4bcf-bcbe-273b1452dc5c
  modified: 2026-07-30T00:57:01.627Z
---

**BINDING on me as ASSEMBLER, learned 2026-07-30 (milestone A r3). deployah caught it; it was mine to make.**

When a peer hands you a "final batch tip" carrying a fix, **it is very likely a SIBLING of your candidate, not a descendant of it** — because peers branch off `main`, and your candidate also branched off `main`. Milestone A: my candidate `ce4386e` (6 repair commits) and hertz's `aa487b9` (3 doctrine/fix commits) shared exactly one ancestor — `af65ac0`, main itself.

**Why:** pushing at his tip would have shipped a tree **missing all six repair commits**, including the very change that produced that night's first-ever cross-machine seam evidence — and **every gate would have gone green**, because the tree was internally consistent. It would have tested none of the repairs it purported to validate. This is the wrong-subject-tree class: every other check verifies *what* the run measured; nothing verifies *which tree* it measured.

**How to apply — assert BEFORE any push, never infer from one link of parentage:**

```
git merge-base --is-ancestor <your-candidate> <proposed-tip>   # MUST be 0
git merge-base <your-candidate> <proposed-tip>                 # if this == main, they are SIBLINGS
```

Verifying `fix^ == doctrine` proves ONE link. deployah's error was inferring a chain back to the candidate from that one link and asserting "nothing is missing" without testing it — the same class as reading a condition off a stale checkout ([[name-the-file-and-sha-a-condition-came-from]]).

**Assemble by cherry-picking `main..<their tip>` ONTO your candidate** (ff-shaped, no merge commit — [[ff-only-absorbs-one-sibling-lane]]).

⭐⭐ **Then assert the picked content by BLOB, not by ancestry — a rebase/cherry-pick MINTS A NEW SHA**, so `is-ancestor <their-fix-sha> <tip>` **FAILS on a correct tree** and proves nothing on any tree. Byte equality is the honest form:

```
git rev-parse <tip>:<load-bearing-file>   ==   git rev-parse <their-fix-sha>:<same-file>
```

doyle had written the ancestry form into his own pre-push list and replaced it with this one.

⭐ **If their commit's parent already IS your tip, FAST-FORWARD — do not cherry-pick.** An ff preserves their authorship sha AND bytes; a cherry-pick mints a new sha for byte-identical content and discards their hash for nothing. ("Cherry-pick it onto my branch" from a peer usually means "don't use my branch as the push lane" — an ff satisfies that, since the lane is your branch either way.)

⭐⭐ **Prove a merge resolution with a FALSIFIABLE NUMBER, not by reading the file back.** The one conflict was `traceable-reqs.toml`, both lines APPENDING a `[[requirements]]` block ⇒ union. Proof it worked: their line measures **630** requirements, the reconciled tree **631** — 630 plus exactly the registration their line lacked. **Taking either side would have left 630 and looked perfectly healthy.** A count that can trip catches a merge error that prose cannot. Get the REAL exit code, not a pipeline's (`cmd > f; RC=$?` — `cmd | tail; echo $?` reports `tail`).

⭐ **Re-run the full invariant set at the FINAL tip, and treat "a docs commit cannot move them" as a PREDICTION you might be wrong about** — naming which ones *could* legitimately move (load-bearing blobs, the lockfile) is what makes the re-run evidence instead of ceremony.

Related: [[resolve-wrapper-conflict-toward-shared-body]], [[release-standard-bump-in-pr]] (the DATE LEG runs at assembly), [[milestone-a-golden-landed]], [[verdict-from-exit-not-from-silence]].
