| name | ctx-merge |
| description | Converges many scattered sources — dated research notes, subagent outputs, audit reports, revision cycles — into one living source of truth without silently dropping or distorting anything, routing each conclusion to exactly one home via a visible disposition ledger and surfacing conflicts as choices for a human. Use when merging or consolidating notes/reports into a ctx source of truth, integrating subagent research, synthesizing multiple audit reports, closing a decision cycle where alternatives existed, or rolling a corpus too large for one context through successive batches. Not for writing a single fresh doc from scratch — use ctx-spec. |
| license | MIT |
| metadata | {"author":"motiful","version":"1.4"} |
ctx-merge — Converge Without Losing or Distorting
Routing destinations (spec / decisions / scratch) follow the lifetime model in ../ctx.
Execution Procedure
converge(sources) → living_kb_update + conflict_choices
# STEP 0 — Scale check (before anything else)
if sources exceed one context, or constraint 2 (coverage split) is unexecutable at this scale:
run this ENTIRE procedure once per batch # see § Rolling batches
# batches share ONE carried-forward framing; each batch still runs STEP 1–7 in full
# STEP 1 — Extract (provenance starts here)
claims = []
for src in sources:
claims += extract_atomic(src) # each conclusion decontextualized, tagged {source, span}
# STEP 2 — Cluster + relate (map-reduce, NEVER a recursive prose merge — see § What "NEVER recursive" bans)
clusters = cluster_paraphrastic(claims) # dedupe equivalents
for c in clusters:
relate(c) # entail → keep one + merge provenance
# neutral/complementary → keep both
# contradiction → DO NOT reconcile → promote to a decision point
# STEP 3 — Ledger (make every disposition explicit; a drop is a recorded decision)
ledger = disposition_ledger(claims) # each: keep→spec/§ | keep→decisions/NNNN | superseded | drop+reason
assert every_source_claim_has_a_disposition(ledger) # GATE — no invisible absences
# STEP 4 — Assemble (information SUPERSET, only-more-never-less) + conflict register
draft = union(non_conflicting) + conflict_register # every line carries its source
# STEP 5 — Human adjudication (LLM induces, human judges)
choices = choice_cards(conflict_register) # choose A / B / keep both / UNSURE + comment
apply(human_clicks(choices)) # non-conflicting superset defaults to keep
# STEP 6 — Faithfulness audit (MANUAL discipline — there is no faithfulness_audit() tool)
# YOU MUST re-decompose the draft and check every claim back to a source, using a
# DIFFERENT agent/model than the merger (a model grading itself shares its blind spots).
# This is a step you perform, not a function you call. See "Faithfulness audit" below.
# STEP 7 — Verify the four constraints, then sink
# Walk the four-constraint checklist by hand (named target · coverage split · boundary ·
# destination); fail any → fix the gap, re-walk. Then sink:
sink(draft, ledger) # edit spec in place / append decisions per destination
apply("../ctx/references/consistency.md") # single-source · same-change · verify-canonical · gate — before committing
# STEP 8 — Self-verify, then hand back in VALUE terms (automatic, not on request)
landed = self_verify(batch) # (a) did the round follow its OWN declared procedure?
# (b) enumerate what is now IN the artifact — read it, not the ledger
handback = value_handback(landed) # what the SOT now asserts that it could not before
Skill("ctx-report", handback) # the format; this step owns WHAT goes in it
# The two halves are one step on purpose: you cannot state what a round was worth
# without first confirming what actually landed. See § The round-close self-check.
# A merge that ends at sink() is not finished. If the human has to ask "so what happened?",
# this step did not run — and no count of claims, losses, or agents answers that question.
The lines above are a procedure you execute by hand, not an API. The faithfulness audit and the four-constraint walk name disciplines you must carry out (below) — no such tool exists; do not treat them as callable.
The two failure modes (why naive merging fails)
- False negative = silent drop. A high-value conclusion gets dropped. Invisible — you can't see a missing thing by reading the output; it surfaces later at build time as "we keep making the same mistake." Empirically the harder class to catch (LLM recall ≪ precision; summarizers drop key items routinely).
- False positive = stain. Wrong or trivial content kept as if true. Visible, but only on careful read.
Human merging worked because of unspoken tacit judgment (Polanyi: "we know more than we can tell"). An agent can't replicate that, so you MUST replace it with an explicit harness — not a smarter prompt.
The merge pipeline (map-reduce, NEVER recursive)
- Extract atomic, decontextualized conclusions from each source, each tagged
{source, span}. Provenance starts at step 1.
- Cluster equivalent/paraphrastic conclusions (dedupe).
- Relate within a cluster: entailment → keep one + merge provenance; neutral/complementary → keep both; contradiction → do NOT reconcile — promote to a decision point.
- Assemble = union of non-conflicting conclusions (information SUPERSET, only-more-never-less) + a conflict register, every line carrying its source.
- Faithfulness audit (a discipline you perform, not a tool you call): re-decompose the output and check every claim back to a source — catches silent drops and inventions. You MUST run this with a different model/agent than the merger (a model auditing its own output shares its blind spots). There is no
faithfulness_audit() function; it is manual work: dispatch a fresh agent, hand it draft + sources, ask "which source-claims are missing, which draft-claims have no source?", act on what it finds.
Prompt rule: instruct the merging agent to emit atomic claims with source IDs and, on conflict, output both variants tagged CONFLICT — never silently pick one.
What "NEVER recursive" bans — and what it does not
It bans recursive prose compression: summarizing a summary, then merging that summary with the next source, so that whatever finally decides never sees the original wording. Every reduce step reads source-tagged atomic claims, never a previous step's prose.
It does NOT ban handing every mapper the same shared context — a carried-forward framing, a glossary, the current conclusion set. That is not compression, it is a common vocabulary, and the mappers still read their own sources verbatim. Reading this line as "each mapper must work blind" produces piles of mutually untranslatable fragments and pushes the translation onto a reduce step that never read the originals — which is the exact loss this skill exists to prevent, arrived at by way of obeying it.
Rolling batches (when the corpus exceeds one context)
Trigger. The sources do not fit one context, or constraint 2 (coverage split — state per source what is covered vs not) cannot actually be executed at this scale. Against 35 sources that constraint is unenforceable; against 3 it is natural. That is the tell.
Shape.
-
Order the sources newest-first. The newest carry the current vocabulary, and they become the lens the older ones are read through.
This ordering is a one-way contract, and it is the load-bearing invariant of the whole method: a backward batch may only RECOVER what was lost. It may never overturn a conclusion a later source already reached. The reason the newest are read first is that they are closest to the truth; reading an older source afterwards cannot make it closer. So an old source's material has exactly two legitimate fates — it fills a gap the later sources never addressed, or it is superseded. There is no third. A datum found in an older source does not reopen a reading that a later source demoted, even when the datum is genuine. One merge violated this at close-out: a lower-tier report carried an experimental figure showing a safety score falling, the orchestrator added it, and wrote alongside it that hardening lowers the very dimension it claims to raise — which was precisely the reading a later revision had demoted from a gate to a diagnosis, on the owner's own argument that gating by category is wrong. The number was real; the inference restored a retracted position. The test before adding anything from a backward batch: does the framing already answer this question? If yes, the only question left is whether the old source adds evidence for the answer that stands — never whether it revives the answer that fell.
And check it mechanically, because "the framing already answers this" is a lookup, not a memory. Nothing in the procedure makes a batch read the conclusions already landed before it writes. Add one step: for each entry a backward batch is about to write, take its load-bearing terms and the ctx-internal components it names — folders, decision IDs, lifecycle classes, shipped files — and look each up in whatever disposition lists the artifact already carries. On one merge the artifact held three such lists (a 25-file rewrite table, a 23-ADR A/B/C grading, an execution checklist), and no batch had ever queried them; the join was one script. A verdict already recorded in the artifact is not background — it is the incumbent, and the new entry has to answer to it.
A corollary about quoted blocks, learned by breaking it. A block labelled verbatim is a claim about what one passage of one source says, not about a topic. The same close-out appended a fourth data row to a block attributed to a specific revision — a row that revision never contained (measured afterwards: zero occurrences of either figure in it). The figures were accurate and came from the underlying paper; the block still became a forgery, because its label promises provenance rather than correctness. Never add a line to a verbatim block. If the extra material belongs, it goes in a new block with its own attribution.
The comparison object is claim ↔ framing, not claim ↔ claim. Each batch's agent holds the already-converged half and reads the old sources through it, translating yesterday's wording into today's on the spot. There is no "organize it all at the end" step, because organizing started at batch 0.
But that comparison runs on conclusions, and a claim can die at its premise while its conclusion still looks live. Tier rules and superseded-by-newer both ask does the framing say the opposite of this? Neither asks is the framing in the middle of demolishing the thing this stands on? On one merge a batch adopted an older source's admission test and anchored it to a line in the product's own README — while two entries already in the framing recorded a newer, higher-tier source proposing that that exact line be torn down, and a third concurring. Nothing contradicted the conclusion. The ground under it had been condemned. So before writing any entry that carries normative weight, take the anchor it rests on — the quoted README line, the ADR, the existing criterion it invokes — and search the framing for it. The test is not "has this been said before"; it is "is anything here retracting what I am about to stand on." A conclusion is no more alive than its premise, and the premise is the half nobody compares.
A related check on the same entry, and it is cheaper: does the source itself route this to the human? Reports that end in a decision list mark their own items — needs your call, already settled, no action, not a product action at all. That list is an enumerable block. A claim the source flagged as awaiting the human's judgement cannot be written as a chosen answer, and the tell that this went wrong is self-contradiction inside one unit: a normative prefix asserting the answer, beside an open-question field recording that nobody has approved it. One batch shipped three of those. Enumerate the source's decision list at extraction and carry each item's status onto whatever it becomes; an unapproved proposal is a quotation or an open question, never a rule.
And when the thing being adopted is a taxonomy, ask what criterion sits under it. A four-category scheme applied as an admission gate is a lookup table; it is useful as shorthand and it is not a criterion, because it cannot say why those are the categories. The same merge had already recorded a source retracting an earlier gate for precisely this reason — classifying by category and routing by category is the thing this round just abolished — and the next batch wrote a category gate into the framing anyway, describing "turning a judgement call into a lookup" as the improvement. Which is the more general lesson: a rule that has landed in the artifact does not thereby govern the next batch. Rules bind when they are an action someone runs at the start, not when they are a sentence someone could have read.
Verification burden scales with how much was written after a source, and that number is exactly computable. For an old source's conclusion to still hold, nothing published since can have overturned it — so the set that must be checked against is everything downstream of it, and reading newest-first means that set grows monotonically as the batch number rises. On one 35-document corpus it ran 5, 8, 11, 13, 15, 18, 21, 24 across the first eight batches and 26, 29, 32, 34 for the last four. The control case is sharp: the one batch whose sources were contemporaneous with the newest material had a downstream set of 2, and it was the cheapest and cleanest batch of the run — not because its sources were simple, but because almost nothing had had the chance to retract them. So the two failure modes need separate budgets: extraction loss scales with source volume, stale-premise risk scales with downstream mass, and staffing a batch off the first number alone leaves the second unfunded — hardest exactly on the last batches, which is where it is easiest to assume the work is winding down.
Three things make a rolling merge cheaper without removing a single check, and all three were found too late to pay off on the run that found them. Measured on one 13-batch merge: 97 hours wall-clock, 37 hours of actual activity, 47 agents.
-
Put the audit's verbatim requirement in the FIRST batch's spawn prompt, not the eighth. Every lost-content finding must carry the source's own words, quoted, alongside the row it came from and the destination it belongs in. That one sentence is what turns closing from generation into transcription, and transcription needs no agent. On that merge the first seven batches averaged 4.5 agents each and the last five averaged 2.4 — a 47% cut, from one line. It was written down at batch 8. Written at batch 0 it would have saved roughly fourteen agent-rounds.
-
Carry a gate-hygiene rule from batch 0, because the same defect recurs in a new costume every time. On that merge, a check that only sees what its pattern assumes fired at least eight times — bold-only markup, one arrow glyph out of four, case sensitivity, an HTML tag splitting a phrase, a regex eating BQ-024 as Q-024, a table indexed by term used to verify things that have no term, a write whose assertion checked its anchor but not its output, and an identity satisfied by both the right and the wrong answer. Not one was caught by a check; every one was caught by the next agent. The rule that stops all eight is three mechanical steps: enumerate the full set, subtract what was covered, report the complement with its denominator beside it. Cheap, and it retires whole rounds of rework.
-
Do not let the spawn prompt become a second copy of this document. On that merge the merge-agent prompt went 448 → 647 → 737 → 815 lines across four batches as each batch's lessons were pasted in, and every agent reads all of it before starting. Measured per section: 564 of those lines (69%) were batch-invariant — and every one of them was a rewritten restatement of rules already in this file, which was 357 lines at the time. The saving is not cutting the lessons; the lessons are load-bearing and none can go. The saving is deleting the duplicate: have the spawn prompt name the sections of this document the agent must read, then carry only what is genuinely specific to the batch (which sources, which same-tier pairs, which named obligations, which numbers). ⚠ And the stronger argument is correctness, not speed: a hand-made restatement drifts from what it restates. The agents were reading a paraphrase while the canonical rules were being maintained elsewhere — the single-source violation this whole procedure exists to prevent, committed against its own tooling, for thirteen batches.
And be honest about what the wall-clock number is measuring. On that merge 62% of the elapsed time was nobody working — the orchestrator waiting on the human. Reporting "it took three days" when it took 37 hours of activity invites cutting the checks, which is the one thing that cannot be cut: on the final batch alone the audit found six content losses and the third pass found two more plus eleven permanently mis-routed pointers, and after the final batch there is no later batch to catch them.
The framing is a SUPERSET per batch (STEP 4): a batch only adds. Removing something requires a conflict card — never an in-passing edit.
But "only add" does not mean earlier sentences stay true. A framing accumulates self-referential claims — "this is the only place X is used as a criterion", "X appears seven times", "nothing here covers Y" — and every later batch can falsify one by adding. The superset rule protects the content and says nothing about these, so they rot silently while the document is formally correct. Before finishing a batch, re-check every claim the framing makes about itself — counts, uniqueness, absence — and restate the ones your own additions broke, leaving a line saying what it used to assert. Do not delete them: they carry real information and merely need recomputing.
Two of those self-referential claims look identical and MUST NOT be updated the same way. A framing accumulates sentences of the form "scope: what we have read so far, sources 22 through N." Some are facts about the merge's own progress — bump them. Others are the boundary on a claim (earliest / only / most complete), and bumping one asserts that the claim was re-checked against the newly-read sources. On one batch, seven such sentences were stale and four of them could not honestly be advanced, because advancing them substitutes "we have read those sources" for "we looked for this claim in those sources" — an order of magnitude of evidence, one character apart in the file. Advance a claim's scope only where the same measurement was actually re-run on the new material; otherwise mark it as lagging and leave the number. The corollary is cheaper and easier to miss: content read in a batch does not update other places' statements about what has been read — one file still said a source was outside the reading range while the same batch's ledger built an argument on it. Sweep that phrasing as a class.
The structural defect, and its hedge. The framing evolved out of these same sources, so it inherits their blind spots; filtering old material through current conclusions is structured confirmation bias. That is the price of rolling, and it is real. The hedge is the mandatory unplaceable field (below), which asks the opposite question — what is in here that the framing has no place for?
The hedge has a characteristic signature, worth recognising because it looks like a defect in the framing and is not. Newest-first means the framing inherits the newest sources' agenda, including the topics they had stopped discussing. Read far enough back and you reach the rounds where those topics were live — and they arrive with nowhere to go, because the skeleton was built by writers who had moved on. On one merge this surfaced as four terms in the merge's own glossary having zero occurrences anywhere in the framing. Nothing was wrong with the framing; it was the bias becoming visible at the one moment it could be caught. Expect it when the batch order crosses the point where the corpus changed subject, and treat it as the field succeeding.
Audit every batch, not once at the end. An end-of-run audit has to re-read the whole corpus to answer "which source claim never arrived" — the same arithmetic that forced batching in the first place, merely postponed. Per batch, the audit reads only this batch's sources plus the framing delta, and STEP 6's "must be a different agent" is satisfied for free by opening a fresh one each batch. It asks exactly two questions, which are the two ways a rolling merge loses things:
-
Q1 — which conclusion in this batch's sources never reached the framing and has no disposition in the ledger? The classic silent drop.
-
Q1b — for each claim the ledger dispositions as keep → <destination>, go to that destination and read: is the content actually there? A ledger row asserting a landing is the one kind of absence an auditor will not go looking for — the row itself says the checking is done. Empirically the sharpest of the three: in the first batch that ran this procedure, four of eight losses were catchable only by this question, and every one of them sat behind a row reading keep. Verify per ledger row, not per destination. Several rows routinely name the same Question, and checking destinations makes that Question look landed as soon as any one of them arrives. One batch sent four rows to a single Question, one landed, and the destination sampled clean — three losses behind a green check.
Running the same check three times is running it once. One merger executed its landing read-back three times and reported 164/164; an auditor opened the destinations and found 26 rows absent. It had not been careless — it had used one method each time (take a distinctive string from the source, search the output for it), and that method can only surface what is in its probe set. Two entire classes had no probes, so all three passes were green. Worse, it had written this exact limitation into its own ledger before the third pass and then ran the third pass with the same candidate list; naming a failure mode feels like handling it. So the repeat MUST be non-isomorphic: enumerate from the ledger side — every keep row gets its destination opened — rather than from the source side. And match the granularity to the unit: one source block held two to seven independent questions, landing the first made the whole block read as landed, and two rows the auditor itself had passed turned out to be one-of-two and one-of-five.
There is one absence this question cannot see at all, and it is structural rather than careless: a ledger row whose destination is not a unit of the artifact's addressing scheme. The read-back enumerates the artifact's units — numbered Questions, sections, whatever the scheme is — so a row pointing at a sibling file, an appendix, a prose paragraph, or nothing is never in the candidate set. It is not reported missing; it is not reported at all. On one merge the class ran to dozens of rows and a cross-batch pass found four losses inside it. Add a gate that enumerates the complement: every non-drop row whose destination does not name a unit. Report the number even when the rows are legitimate — several are, and saying so is the point, because an unstated zero and an unlooked-at zero are again the same file.
Any question returning a finding → the batch is not done. Backfill, then re-audit.
Backfill discipline — the second pass has its own two failure modes. Both were observed on the first batch ever to run this procedure, in this order:
-
The fix injects what the sources never said. Round one dropped content; round two invented it. Filling a hole is generative work, and a merger that marks its inferences scrupulously in normal operation will state them flatly while patching. So the re-audit MUST ask "does the backfill contain anything with no source?" — not merely re-check the original findings — and the backfilling agent MUST be told to mark an inference as an inference. This is the worse direction: an invented claim leaves no trace that it was ever absent, while a dropped one at least still exists in the source.
One batch fabricated once per repair round, weakening each time: a fact (a claim about a source, refutable by one grep), then a reading (a reconciliation the source never proposed, in the same argumentative slot), then a count (a number where the source gave none, headed by the word "verbatim"). None was a knowledge error. All three filled the same kind of gap: a passage of reasoning that needed one more piece to read as finished, where supplying it was easier than leaving a hole. That makes it a property of the writing, not of the writer, so "be careful" does not address it. What does: three sentence shapes account for all of them — the reconciliation ("these don't actually conflict", "it's a division of labour"), the count ("N locations", "all four"), and the connective ("taken together", "therefore"). Reaching for any of them is the cue to go back to the source, because each one asserts something no single quoted line contains.
-
The loop has a fixed point, and you have to notice it. Each repair round costs an agent and carries a fresh chance to fabricate, so it is only worth spending while the findings are still about lost content. Once an audit's remaining findings are mechanical and precisely located — a wrong count, an unmarked inference, a pointer to the wrong row — apply them directly instead of dispatching another pass. The signal is an auditor writing some version of the evidence is broken, not the content, usually alongside an independent sample that came back clean. Two batches ran this way: the first looped to seven agents before closing by hand, the second closed by hand at four and delivered more. The generative step is what introduces stains, so removing it is not a shortcut — it is the fix.
Closing by hand removes the agent, not the generation — and nothing audits the orchestrator. The whole apparatus points outward: spawn prompts, a different model for the audit, three forbidden sentence shapes, an honest reach count. All of it constrains agents. The orchestrator writes too — every finding transcribed by hand arrives with a connective sentence explaining what it means, and that sentence is generation under a different name. On one merge every defect the owner later caught had been produced during a hand close-out, by the orchestrator, after an audit had certified the batch: a line added to a block labelled that its cited revision never contained, an inference reviving a reading a later revision had demoted, and two passages recorded that changed no decision. — state the reach count for your own additions, keep the anchor lookups, and treat any you write beside transcribed material as a claim needing the same grounding as the material.
The round-close self-check (STEP 8a) — verify your own round before you value it
Every batch and every round ends by checking its own work, before anything is handed back. Not the faithfulness audit — that is STEP 6, it runs on a different agent, and it asks did the content survive. This one is the merger's own, it asks two questions the audit does not, and its output is the input to the value handback.
- Did this round do what it said it would? A round declares checks — a landing read-back, a class sweep, a contradiction screen, a stop-signal self-check. For each one: did it run, and did it produce output somebody can re-run? A declared check with no transcribed output did not happen, however sincerely it was intended. The failure mode is specific and repeats: naming a limitation feels like handling it, so a round can write down exactly why its method is insufficient and then run that method again.
- What is actually in the artifact now? Enumerate it by reading the destination, not by reading the ledger. The ledger records intent; the artifact holds the result, and the whole reason STEP 6 exists is that those diverge. This enumeration is not a count — it is a list of the conclusions the artifact can now state.
Why the two halves are one step. You cannot say what a round was worth without knowing what landed, and a value claim built on the ledger's word inherits every gap the ledger has. Coupling them also makes the check self-interested: the merger now needs an accurate landing list for its own report, rather than producing one because a rule says to. A round that cannot enumerate what it deposited has not finished, no matter how clean its counts are.
It also makes the checking better-aimed, which is the second reason to do it. A generic audit asks "is anything missing?" against the whole surface. A round that has just written its own value statement knows exactly which conclusions it is claiming credit for — so it can verify those first, and hardest. The claims a round is proudest of are the ones whose loss would be least visible, because everyone assumes the headline landed.
The value handback (STEP 8b) — a merge is for the conclusions, not for the merging
The unit of value is a conclusion the SOT now carries that it did not carry before, stated in the product's own terms. Not a Question that was added, not a claim that was dispositioned, not a loss that was recovered — those are the machinery. The owner commissioned a merge to make the product know things; the artifacts are how, and nobody asked how.
The failure is stable and worth naming because it survives every other kind of quality. A batch closes, the merger reports agent counts, landing rates, losses found, checks that failed, rules earned — all accurate, all measured, all reproducible — and the owner reads it and says "I still don't see what improved." They are right, and accuracy cannot fix it, because the report answered a different question. The process is what the merger just spent its entire effort on, so it is what is loaded and vivid; the owner spent none of that effort and is asking what the thing they are building now knows.
So write each item as a statement the SOT can now make. The form is "ctx now answers <question>, and the answer is <answer>" — or, when a batch settles rather than adds, "<claim> is now closed, and the closing is <terminal state>." Two tests:
- Could the owner act on it? "We added Q-117" is not actionable; "there is no runnable benchmark for this category, so the evaluation has to be self-built, and here are its four measurement targets" is.
- Does it survive deleting the batch? If the sentence stops making sense once you remove the words batch, ledger, audit, and landing, it was about the machinery.
Order by what the product gained, not by what cost the most effort. A capability outranks a defect even when the defect took ten times the work — and a defect earns its place only when the owner asks or when it changes how the next batch runs.
Run it automatically at every batch close, and at every round close. Not when asked. Being asked "what happened?" is the defect this step exists to prevent — by the time the question is put, the owner has already read an artifact that failed to answer it. The report format, the term discipline, and the verdict list belong to ctx-report; this step owns only what goes in.
In a rolling merge, report the LEVEL, not just the count — because the count falls while the value rises. Sources ordered newest-first means the late batches read the earliest material, where the vocabulary and the rules had not been invented yet and what exists instead is the founding intent: what is this for, who is it for, what is its scope, how would we know it works. On one 22-source thread the per-batch yield of new Questions ran 25, 26, 9, 4, 5, 3, 4 — a curve that reads as exhaustion. It was not: the last batch's four were what is the scope of the thing, how does it prove it works, what are its claims anchored to, and how autonomous should it be — none of them a rule, all of them load-bearing on identity, and none answerable from any later source, because by then everyone had stopped asking. A falling count with a rising level is the expected shape of reading backwards; report both, or the owner reads diminishing returns into the most valuable batch.
Source reliability — declare it before merging
Rank the sources into explicit tiers before the first batch, and write the ranking down. Merge without a declared ranking and every source argues as an equal: a superseded note from months ago contradicts the latest conclusion, and the merge stops for an adjudication the ranking would have settled.
- A contradiction between tiers resolves toward the higher tier automatically, recorded as
superseded with the tier as its reason. It does not become a conflict card.
- A contradiction within a tier is a real conflict and escalates (STEP 5).
- The ranking is a claim about the sources, not about the truth. State it explicitly so a later reader can disagree with it explicitly.
Corollary, and it is easy to get backwards: leaving one revision thread is not what produces conflict cards — being in one tier is. A rolling plan that starts inside a single thread will predict, reasonably, that the first cross-thread batch is where disagreement finally surfaces. It is not, if that batch also crosses tiers: the tier rule then resolves every disagreement automatically and the register stays empty for a second, unrelated reason. One merge ran eight same-thread batches at zero cards, wrote "expect this to change when we cross threads", crossed threads into a lower tier — and got zero again. Work out where a same-tier collision can actually occur before predicting where the first card appears; on that merge it was two forks of one archived side-track, four batches further out than the note assumed. And an empty register still has to be earned per batch: enumerate the pairs that could have collided and say you checked them, or a structural zero and an unlooked-at zero are again indistinguishable.
Two same-tier sources are not one thread merely because the later one answers the earlier. The first batch to hold same-tier material will look for a way to avoid a stack of conflict cards, and "B declares itself the next round of A, names A throughout, and its section skeleton is A's feedback list" is a tempting one — every clause of it true. Test any such criterion by applying it to the whole corpus before you rely on it once. On that merge the same three facts held for A over its own predecessor, and for the next thread over B, so the criterion silently merged six rounds and twenty-two revisions into a single thread — dissolving the very tier table it was written inside, and it would have been reused four days later on three more same-tier sources. A justification that erases the distinction it is an exception to is not a justification.
And most of the time you do not need the ruling at all, because the disagreement is already adjudicated in the source. On that batch, all eight disputed pairs carried the owner's own decision, verbatim, inside the later report's own quoted-question blocks — scrap it, rewrite the whole thing, this part is simply wrong — and its summary table marked five rows "rejected by you this round." A conflict card exists to hand a choice to a human; where the human already made it, in the source, there is nothing to hand over. That reason is greppable, needs no theory of what a thread is, and cannot leak onto other tiers. So before reaching for either a card or a supersede, look for the decision.
When the count does come back zero, resist explaining it. That batch wrote itself a tidy mechanism — "sources that have already limited their own claims do not contest anything" — and sank it into two documents as a finding. It was a reconciliation with nothing behind it: what those sources hedged was their evidence strength, not their claims; the same batch's own ledger held two flat contradictions grown out of them; and the exception clause it derived named a set that was already empty. A zero is allowed to stand unexplained. The cost of furnishing it with a reason is specific and severe: the standing instruction for a repeated zero is to investigate it, and a plausible explanation is precisely what retires that instruction.
The disposition ledger (the move that makes drops visible)
Before/while merging, build a ledger: every source conclusion gets an explicit disposition, so a drop is a recorded decision, not an invisible absence.
| Conclusion (+ source) | Disposition | Destination |
|---|
| … | keep | → spec/X.md §… |
| … | keep | → decisions/NNNN |
| … | superseded by … | (chain note) |
| … | superseded-by-newer — same thread, higher revision wins | — (does NOT enter the conflict register) |
| … | copied-as-is | → destination, unchanged |
| … | drop + one-line reason | — |
Routing destinations, per the SOT model (../ctx/SKILL.md § the model): keep → spec/ (current truth) or decisions/ (a choice + why) — the SOT is generative, so what's kept lands in the generative core; drop → recorded in the ledger with a one-line reason — the ledger is replayable, so a re-merge honors a prior drop and a rejected concept cannot quietly return under a new label; unsure → an open question carried to the next round. Raw source material itself is not a merge destination — it already lives in scratch/ (the model's single home for ALL raw: notes, prompts, research dumps, comparisons). No log destination — "what happened" is git. The ledger is the artifact a human reviews; review judgments, not absences.
Never dispose of a whole section as superseded. Supersession is a claim about a claim, not about a region of text. A section usually contains several, and a later revision rarely overturns all of them — most often it revises two and relocates a third. Disposing of the region marks the survivors as handled, and the ledger then reports the section as processed, so no later batch comes back for them. A source that says of its own content "this did not disappear, it moved" is naming a destination: record the destination, or open the question of where it went. What is forbidden is superseded with no receiver — the one form of the disposition that cannot be checked, because there is nothing to compare against. This is how a batch lost two rules that its own source had explicitly declared surviving.
Supersession contaminates the keeps around it. When a batch holds two revisions of one thread, the sections the newer one overwrote are where landings fail — not because they were dispositioned superseded, but because everything near them reads as already handled. In one batch, eight of nine failed landings came from the older source, clustered in exactly the sections its successor had rewritten. So the risk of superseded is not only judging it wrong; it is the shadow it casts over the keep → rows beside it. Give those rows the closest reading of the batch, not the quickest.
superseded-by-newer. Within one revision thread, the higher-numbered revision wins automatically and the difference does not become a conflict card. Without this, a 22-revision thread manufactures hundreds of false conflicts and adjudication collapses under its own volume. It holds only within a thread — across threads, or between same-tier sources, a contradiction is still a contradiction and STEP 2 applies.
The disposition's real failure mode is not misapplying it — it is not reaching for it, and the tell is a sentence, not a number. On one batch the ledger recorded a claim from an old revision as a plain keep and annotated it "opposite in direction to what the framing does today, and no revision ever recorded this turn" — then escalated it to the human as a decision. Both halves are wrong: the higher revision had already won automatically, and the absence of a recorded turn is what this rule exists to permit — requiring each reversal to be minuted is exactly the hundreds of false conflicts it prevents. The batch was not ignorant of the rule; it had applied it correctly nine times in the same artifact, once fourteen lines above the escalation, in the same section. So "remember the rule" is not the fix. Make it mechanical: grep the ledger for the annotations that describe a contradiction — opposite / contradicts / reverses / no version recorded / conflicts with what we do now — and require every hit to carry a supersede disposition with a named receiver, or an explicit statement of why the two sources are not in one thread. A contradiction inside a thread is a disposition, never a finding, and never an escalation.
Declining to use the disposition does not remove its risk; it relocates it. That same batch had written itself a stricter-than-the-procedure rule — "this batch will not use superseded-by-newer at all; every overturn goes to keep with the original quoted" — and then encoded overturns three different ways (keep + quoted original, bare keep, and drop + receiver). Two whole-section supersedes ended up in drop, and one of them dropped the survivors: the later revision replaced the routing mechanism and said nothing about the phrases a user says out loud, which the older section also carried and which then existed nowhere. The prohibition on section-level supersession is attached to the supersede disposition; route the same act through drop and nothing enforces it.
It also assumes the revision numbers are unique and increase with time, and a thread written by hand often breaks both. On one merge, v11 named four distinct documents and v12 two, and the voided v12 was dated a day earlier than the v11 that replaced it — so "the higher number wins" would have picked the retracted draft. Nothing was mis-decided there, but only because the reverted files were no longer on disk to be read. Before relying on this disposition, list the thread's revisions with their dates and confirm the ordering is real. Where it is not, the tiebreaker is the date or the git history, and the numbering is just a label.
copied-as-is. Copying is a disposition and gets its own line. It is not "skipped": a skip is invisible, and an invisible skip reads exactly like "I looked at it and it was fine."
A drop reasoned as "already carried by X" is not a drop — it is a redirect, and it must be verified like a keep. It asserts something about a different row, and nothing in the procedure checks that assertion. The failure it produces is the nastiest kind, because every step of it is locally correct: a source states its headline conclusion five times — title, summary line, TLDR, diagram node, body — and four of them are honestly dispositioned drop (duplicate; the body row carries it). Then the body row does not land. Four correct drops erase the source's main finding, the ledger reads as fully accounted for, and no later batch returns for it. One batch's redirect pointers were checked afterwards and seven of them named the wrong receiving row — each time the content survived by accident, in some third row. So: whenever a disposition's justification points at another row, open that row. A redirect is a claim with a destination, which is the definition of a keep.
And the rule is about the shape of the justification, not about the word drop. A ledger will invent its own disposition names — one used externalize → <backlog entry> for material that belonged on a different axis than the merge artifact. Four such rows named the same backlog entry, and the backlog entry received none of it: the content existed in neither the framing nor the backlog, which is to say nowhere. It had passed every check because externalize was not keep and not drop, and both the landing read-back and the redirect sweep were scoped by disposition name. Any disposition whose justification names a destination is a keep for verification purposes, whatever it is called — open the destination and read. The ledger had also already displayed the gap: its own summary table listed those four rows in the source column while the what-was-added column described something else entirely. Nobody read the table across.
Define that set semantically, not by the string the ledger happens to use. One batch verified its redirects by grepping its own phrasing — "duplicate; carried by NN" — got 44 rows and 31 destinations, and reported them all clean. Re-derived from the rule as written (does this justification point at another row?) the same ledger yields 47 rows and 56 destinations: fourteen redirects, including five whose destination was itself a drop, had never been in the candidate set. The rule says "points at another row"; a literal-string filter answers a different question and cannot discover what it excluded. Its own accuracy report is the giveaway: the batch quoted a hit-rate percentage that was arithmetically incompatible with the denominator printed directly above it and compatible only with the larger, unwritten one.
The GATE proves the ledger is complete against itself, not against the source. every_source_claim_has_a_disposition can only range over claims that were extracted, so a batch that never reaches a section passes it cleanly — the missing rows are missing from the thing doing the checking. One batch passed with an eleven-item decision list carrying four rows and a thirteen-item source-notes section carrying one, and the arithmetic was self-consistent throughout. Close it by naming the source's structural blocks and accounting for each: the verdict list, the source notes, each appendix or ADR body, each figure, each summary block. Count blocks, not rows — row counts are computed from what you already saw.
Enumerate by position, not by markup class. Four batches ran this and each still lost about one claim, every one of them outside the classes anyone had listed: a section's thesis as opposed to the table inside it; a closing block that carried no class attribute; a row of a verdict table covered by one blanket drop (duplicate); and text marked merely small. Enumerating the pretty blocks is easy and feels like coverage, so it is what gets done. Walk the document top to bottom instead and account for every span between headings — the losses live in the plain prose the eye skates over, and in whatever a batch's own coverage declaration did not think to name.
An ellipsis inside a block you labelled verbatim is its own loss class, and it is drawn to the grounds. Quoting source text into the merge artifact is the safest thing the procedure does, so nobody audits inside the quotes. One batch counted what its own … had eaten: the audit named three, a class sweep found nineteen, a second sweep found thirty-one — two of them created by the repair round itself. They were not randomly placed. What an elision takes is the parenthetical, and the parenthetical is where the evidence lives: one ate the definition of the term its section was about, leaving a passage that says a concept exists without saying what it means; one ate the first-hand basis of a conclusion — the shipped file the principle was quoted from — leaving an argument that reads as the author's own induction; one ate a criterion and left the criterion's name. An elision lands on exactly the clause a summary would drop and a verification would need. Two mechanics make it tractable: count the editorial ellipsis separately from the one the human actually typed (mixing them tripled one batch's candidate list), and a block whose contents were shortened MUST be relabelled excerpt — the label is the only signal a later reader gets.
The same loss happens without any ellipsis to find it by, and that variant is invisible to the sweep above. A later batch lost seven passages; five were one shape — the first or last sentence of a quoted block, dropped at extraction time, with no mark left behind. What those sentences held: why the numbers must be discounted (the block kept the discount and lost the instruction), what the paper does not claim (leaving a methodological aside where a prohibition had been), what an experiment was measuring (leaving a result table the argument then cited as evidence for a point the table cannot support), the equation a paragraph goes on to paraphrase (leaving the paraphrase sourceless), and who commissioned the report (leaving a solicited investigation looking self-directed). An opening sentence sets up what the quote is for; a closing one says what to do with it — and both read as framing rather than content, which is exactly why they are what gets trimmed. The ellipsis rule cannot catch these because nothing was marked. So run a second, cheap sweep: for every quoted block, check its first and last sentence individually against the source.
That sweep has a second payoff, and it is the one that argues for running it even when you believe nothing was lost: a dropped closing sentence does not only remove content — it silently downgrades the source's own assertion into your inference. On the batch above, three passages in the merged artifact carried a hedge in the merger's voice — "this cross-reading is ours; treat it as inference" — and in all three the sentence establishing the connection was sitting in the source, in the very clause that had been trimmed. This leaves no gap to find. The elision sweep cannot see it (nothing was marked), and the landing read-back cannot see it (the row did land). Worse, the hedge makes the passage look careful, so no later pass revisits it. Whenever you are about to mark a connection as your own inference, check the quoted block it draws on for a first or last sentence you did not carry over. And the arithmetic that catches an under-run sweep is free: new fenced blocks equals the growth in fence count divided by two — one merge reported sweeping thirty-six blocks when the identity gave forty-three, and the seven it never opened were exactly where the closing sentences had gone.
One row, one claim. A row that joins two items — "the term plus the four-row comparison table" — will be verified on the first and the second dies in silence, because every check that follows looks for evidence the row landed and finds it. This survived a merger's self-check, a second self-check by a corrected method, and an auditor's first sampling pass; three independent checks all stopped at the conjunction's left half. Split at extraction, not at verification: by the time anyone is checking, the row already reads as one thing.
Count the ledger by machine, and record the command — adjacent to the number. The tally is the only visible evidence that every_source_claim_has_a_disposition held, so an asserted number is evidence of nothing. Two consecutive batches reported counts that were wrong — one whose total silently treated six unextracted claims as nonexistent, one that reported three mutually inconsistent numbers (rows, self-report, and the sum of its own categories). A number nobody can reproduce is worse than no number: it reads as verification.
"Count by machine" is not enough on its own, because the failure is one of order, not of method: a batch that had already written this very lesson into its own ledger then drafted a summary with the numbers filled in and ran the commands afterwards — twice, in the same batch. So make the order structural rather than remembered: every number in the ledger MUST be produced by a command block immediately above it, and a number with no adjacent command block is a defect regardless of whether it happens to be right.
The adjacent command is only half of it — the output has to be transcribed too, and the half that gets dropped is the half that was doing the work. A later batch printed the command and wrote its result as "see the table below". Run that command as written and it scans the whole document rather than the ledger's table rows, so it cannot produce the number it was standing next to; the number came from somewhere else and the command was decoration. The batch reported verifying 137 landings out of 137. Counting the table rows two non-isomorphic ways gives 146 keeps — nine rows were never in the candidate set, and the verification could not have found them because they were outside what it enumerated. A command with no transcribed output is not evidence, it is a citation to work nobody can check — and it reads as stronger evidence than a bare number, which is what makes it worse.
Two traps worth naming, both encountered live. A shell can eat your path silently: in zsh git show $c:path parses :path as a parameter modifier, so git receives only $c, prints a commit, and exits 0 — empty output, no error. Quote it ("${c}:path"). And an empty result is not a finding. The batch above turned that empty output into a stated fact about its own artifact ("the framing is not in git"), then used the fact to justify declining to give a number — a fabrication wearing the clothes of refusing to fabricate. When a command returns nothing, suspect the command first.
"Not found" has a third form, and it corrupts instead of merely misreporting: a lookup that returns a sentinel the next line treats as a valid value. An orchestrator splicing a note into one long line computed the end of the fragment with find(closer), the closer was a different character than assumed, find returned -1, -1 + 1 = 0, and old[:j] + note + old[0:] wrote the entire original line back onto the end of itself. No exception, no diff-time warning, a plausible-looking result — the line had simply doubled. The two earlier traps make a check return nothing; this one makes a write silently produce something wrong, which is worse because the audit trail now contains the corruption rather than a gap. So: after computing an index, assert it moved (assert k > j), and before writing a spliced line, assert the round trip — reversing the substitution must reproduce the original byte for byte. Both are one line each and they catch the whole family.
A negative existential is a different claim from a failed search, and one word separates them. "We found no receipt for any of these" is a measurement; "this class has no receipts" is a universal, and the second is what gets written. On one batch the ledger recorded a source's decision list as 16 of 16 awaiting the human, with no acknowledgement anywhere — and the refutation sat in a block the same ledger had transcribed two hundred lines earlier: the source's closing paragraph named four items the human had already affirmed, in prose, outside the numbered list the search had covered. The cost was not bookkeeping. The batch's one owner-approved invariant, self-labelled in the source as a direction decision, execute it, no more hedging, was handled as an unapproved proposal and never entered the artifact at all — the single largest loss of that batch, produced by a sentence that was true about where it looked. So before writing "this class has none", state the surface the search covered. If the surface is the numbered list and the class is decisions the human settled, the sentence is already false.
Note what these four have in common, because it is the actual lesson: the failure is never in the thing being measured, it is in the instrument, and a wrong instrument reports confidently. In one batch, 伪证 vs 证伪 (a two-character transposition) made two agents in succession conclude a passage was absent when it sat 106 lines away in the same section — and the second one dutifully wrote a duplicate copy of it, creating two sources of truth inside a document whose entire purpose is to have one. A regex matching 第 N 句 but not 第 N 问 produced "there is only one such pointer" when there were two. A <code> tag inside a quoted phrase made a grep for it return zero. A drop written as **drop** made a count of dispositions return zero out of thirty-six. Any assertion of the form "there are exactly N" or "there are none" MUST be measured twice with non-isomorphic patterns, and every hit MUST be opened to confirm which unit it belongs to. Counting the right thing and counting correctly are different claims; only the second one is cheap.
The same instinct is needed when two measurements disagree. A batch counted one field twice, got 108 and then 97, re-ran and got 97 again — and kept 97, filing the discrepancy as unexplainable. 108 was right: eleven entries used a variant separator the narrower pattern could not see. A disagreement between measurements is itself the finding, and reproducibility is not correctness — a wrong pattern reproduces its own error perfectly, which is exactly why it reads as verification. Resolve the difference before recording either number.
Resolve it with an identity, not with a third opinion. Two agents counted the same tag across three files and got 100 and 99; the instinct is to run a third pattern and take the majority. That is a vote, and a wrong pattern will happily join a majority. What settled it was an arithmetic identity — bare tags plus attributed tags must equal all tags — which held per file (39+3=42, 20+3=23, 40+3=43), located the discrepancy in one file, and explained the difference in full instead of out-voting it. Prefer a check whose failure is visible to a check whose agreement is reassuring.
One technique reliably solves the wrong half of this, and knowing which half is the point. A self-referential count goes stale because writing the sentence around it is itself an edit; the fix is to draft the whole passage with placeholders, take the measurement after the last edit, and substitute digits only — a pure digit swap adds no lines and cannot invalidate itself. It works, and it is worth using. But it fixes only staleness. It says nothing about whether the number counted the right thing. On one close-out that discipline was followed exactly and the figure was still wrong, because the measurement had been taken with a hand-rolled script instead of the command the document itself names as canonical — the two differed by precisely the number of files, since joining file contents on a newline leaves each trailing newline as an extra empty element. The identity (script − canonical == file count) settled it in one line. So pair the two: take the measurement with the canonical command, never a fresh script written for the occasion, and write it with placeholders. Drop either one and the number is wrong — only the failure mode changes.
unplaceable — a mandatory ledger field, not a disposition. Every batch ledger MUST answer: is there anything in these sources the current framing has no place for? An empty answer is acceptable only as an explicit sentence ("read through; nothing the framing cannot hold"). A silently empty list and a carefully-searched empty list read identically, and only one of them is true. Whatever lands here is the highest-value line in the ledger — it is precisely what the framing's blind spot would otherwise have filtered out.
Memory-defense routing. Every durable conclusion this merge produces routes to a git-tracked ctx SOT file (spec/ / decisions/) — never to an agent's volatile memory (~/.claude/projects/*/memory/, MEMORY.md, and equivalents). Memory is not shareable, not in git, not in any dependency chain: a conclusion sunk there dies at the next machine/instance switch — a silent drop by another route. Memory's only legitimate use is a local pointer for context recovery ("read spec/X.md to restore state"), never the home of the knowledge itself. If a system prompt nudges "save this to memory," sink it to the SOT and leave a pointer instead.
Human adjudication (LLM induces, human judges)
The LLM does induction/organization (cheap); the human supplies the value judgment (Agrawal/Gans/Goldfarb). So: agent merges into a superset + surfaces conflicts as pre-structured choice cards (choose A / choose B / keep both / unsure); human clicks. Non-conflicting superset content defaults to keep.
Before the gate, run the lookup — most escalations are not decisions, they are unanswered lookups. On one batch, every one of the four items escalated to the human died to a search the escalator had not run: one was already settled by a rule in this document (a same-thread contradiction, which superseded-by-newer decides automatically), one by the plan (a source reported as "never merged" was a scheduled input two batches out), one by a single shell command (a file whose existence was treated as unknown), and one by precedent (an earlier batch had ruled on the identical shape and written down why). Four for four. The pattern is not carelessness: an open question and an un-looked-up question are indistinguishable from the inside, and escalating feels like diligence. So before anything reaches the human, confirm none of these four answers it: (a) a rule in the procedure, (b) the plan or schedule, (c) a precedent from an earlier batch, (d) a command you could run right now. Only what survives all four is a decision. Everything else is work.
Running the four checks is not the same as answering them, and the next batch proved it: it ran all four, wrote its answers into a table, escalated four items — and three of them died to the very gate it had filled in. So the checklist alone is not the fix; each gate needs a form the wrong answer cannot satisfy.
- (b) must resolve a class to its members. A schedule row reading
B08 | companions ×3 does not answer "is X scheduled?" until you open what those three are — the membership lived in a different file. Looking up the member's name against a table written by class returns "not scheduled", and that false negative is indistinguishable from a true one. Any schedule hit that states a count instead of naming members requires a second hop.
- (c) includes what you yourself decided ten minutes ago. Two of the three had their precedent in a backlog entry this same batch had just written — one of them with the escalated item quoted verbatim inside it, un-defer trigger and all. An agent remembers other batches' precedents and forgets its own, because while writing one it is solving a problem, not setting a precedent. Put this batch's own dispositions in the candidate set.
- Ask whether the content is already in the artifact — that is a different question from whether a human is needed. One item asked whether a source's unrecorded choice among four candidates should be written down; all four candidates were already sitting in the destination, verbatim, under the prefix whose definition is considered and not chosen. The escalation was about scheduling a revisit, which is a backlog entry, not a decision.
A disagreement is a claim too, and nothing in the machinery gives it a premise gate. Every mechanism for handling a contradiction — tiers, threads, superseded-by-newer, the conflict register — classifies the sources: which tier, which thread, same layer or not. Not one of them asks whether the artifact already answers the question the two sources are arguing about. On one merge a same-tier pair was ruled three different ways in one day — auto-resolved by thread (the clause turned out to be scoped to a different thread), then escalated as the register's first card, then withdrawn by the owner because a higher-tier entry had settled the question outright, and had also rejected by name the whole family of answers both sources were proposing. Three rulings, all about classification, none about content. So before classifying any disagreement, take the question it is a disagreement about and look it up in the artifact. If the artifact answers it, the disagreement is moot: it is neither a card nor a same-tier supersede, it is superseded by the standing answer — and the sources are simply arguing downstream of a decision neither of them had seen.
Verifying an old claim means walking the topic FORWARD to where it was settled — not to the next report that mentions it. This is the same error as the two above wearing its most ordinary clothes, and it is the one that keeps recurring. The check feels complete the moment a later source is found discussing the claim, so that is where it stops. On one merge an orchestrator confirmed a three-way terminological distinction from revision N, wrote it into the artifact as the settled state, and reported two of the three terms as missing from the product. Revision N+1, published the next day, had deleted both of them outright — on the owner's own argument, recorded verbatim, with the reason (this failure mode has no purchase in our setting; the constraint it assumes does not exist here). Their absence from the product was not a gap; it was the decision. And the artifact already said so, in three separate places, none of which was consulted. ⇒ So: list the topic's successors in time order, print how many there are, and read each one for whether it moved — until a revision settles it or the thread ends. "I checked the next one" and "I followed it to the end" differ by one word, and the cost of the difference is a conclusion that points backwards. The tell is a report that treats an absence as a defect without first asking who removed it.
And this outlives the merge. The rule reads like a merge-time check because that is where it was earned, but its trigger is not "I am merging" — it is "a conclusion is in dispute and the evidence is a dated document". That condition recurs long after the last batch: someone questions a decision, someone cites a report to defend one, someone asks why is this not in the product. Every one of those is the same lookup: find the topic's documents, order them, walk to the end. State the trigger that way in whatever carries this rule forward, or it will be read as merge-only machinery and retired with the merge — while the failure it prevents is at its most likely precisely when nobody is merging and nobody is auditing.
And a source's own status tag expires — read it as a statement about that source's moment, not about today. Reports mark their own items awaiting your call, still open, nobody has approved this, and the status gate correctly forbids writing such an item as a rule. The error is to carry that tag forward as the artifact's status. Newest-first means the batch reading it is reading old material: whatever it says is unresolved may have been resolved by anything written since. On that same merge the escalation quoted a source's "awaiting your decision" verbatim and correct — from a report predating the deciding source by a week. The owner's reply was "I did decide this; you didn't read the reports properly." This is the exact mirror of the negative-existential rule above: we found no receipt is not this class has no receipts, and the source says undecided is not this is undecided. State which surface, and state which date.
Escalation is a disposition and takes the same four gates as any other. A keep gets verified, a superseded needs a named receiver, a drop needs a reason — and → the human gets none of that, because handing something to a person reads as the absence of a decision rather than one of its outcomes. It is not. Escalating a question the artifact already answers is not caution; it transfers the lookup you owed onto the person who commissioned the work. The tell that this happened is the owner answering with a pointer rather than a preference. And check the backlog's own oldest entries for this shape before writing a new one: on that merge the identical error had been made, caught, and written up months earlier as the first entry in the backlog file, verdict included — taking a settled matter back to the owner is the orchestrator's error, not the owner skipping a step — and nobody read it.
The deeper reading: all four gates ask "has someone already answered this?", and the failure is always looking in a place whose shape does not match the question — a class-shaped table queried by member, a precedent set that excludes the present, an artifact never consulted at all. A lookup that returns nothing is only evidence if you can say what it would have looked like had the answer been there.
Adjudication gate (confidence × blast-radius). Decide which dispositions you apply yourself vs. escalate by one rule: high-confidence + low-blast dispositions auto-apply; anything high-blast OR low-confidence escalates to the human as a choice card. A non-conflicting paraphrase-dedupe you're sure of = auto-apply. A contradiction, a supersede that flips a LOCKED decision, or a drop you're unsure about = escalate. (This is the merge-side instance of the same gate ctx-report uses for its verdict.)