From 2c7772068ade3992130b057404796c4db2bd80ad Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 20 Oct 2026 02:47:30 +0000 Subject: [PATCH] research: record the compensated-shear hypothesis for the R439 K footprint The three helper-star words and the pinned pair control keep E equal to K because their D sections are compensated restored shears of the parent bracket. The synthetic restored edge omits that support update. Co-authored-by: unpaidmoon --- .../README.md | 147 +++++++++ .../SOURCES.json | 42 +++ .../TASK.json | 67 ++++ .../VERIFY.json | 25 ++ .../verify.py | 302 ++++++++++++++++++ 5 files changed, 583 insertions(+) create mode 100644 research/r439-shear-compensation-hypothesis/README.md create mode 100644 research/r439-shear-compensation-hypothesis/SOURCES.json create mode 100644 research/r439-shear-compensation-hypothesis/TASK.json create mode 100644 research/r439-shear-compensation-hypothesis/VERIFY.json create mode 100644 research/r439-shear-compensation-hypothesis/verify.py diff --git a/research/r439-shear-compensation-hypothesis/README.md b/research/r439-shear-compensation-hypothesis/README.md new file mode 100644 index 0000000000..e82dde8eef --- /dev/null +++ b/research/r439-shear-compensation-hypothesis/README.md @@ -0,0 +1,147 @@ +# Compensated restored shears keep the R439 helper footprint + +**Partial certificate. No new kappa.** Selected κ stays +0.001672660197076918. This does not adopt a weakened `K_equals_D` contract +and does not change a paid profile. + +## Question + +The K-defect tally on the three retained helper-star words shows that the +helper mask `E` actually written by `D`, starting from identity columns, +equals the forward footprint `K` left by `(A, scatter, B)`. A three-gate +restored edge `h0 ^= h1`, `y ^= h0`, `h0 ^= h1` restores its helpers and +still has `E` different from the column it names. The released question is +which extra hypothesis the three words satisfy and that edge violates, tested +on one other pinned helper-mixing word. The hypothesis is not allowed to be +only "this `D` was built to match `K`". + +Card `bit-helper-contract`, scope refined to that hypothesis. + +## Hypothesis + +Let the parent word be `research/r439-target-compensation/candidate.json.gz`. +Its `D` is three blocks: 306 target-to-target gates, 111 helper reads (one +per target), and 306 target-to-target gates. Neither transport block writes +a helper, and neither reads anything but targets. + +A **compensated restored shear** of that parent is a word whose `D` is + +```text +S + P + M + Q + reverse(S) +``` + +where `P` and `Q` are the parent's transport blocks, `S` is a list of gates +`h_a ^= h_b`, and `M` is the parent's middle support after the updates +`columns[b] ^= columns[a]` in that edge order. Bit `i` of `columns[j]` means +target `i` names helper `j`. + +The three tally words and the pinned degree-1 pair control +`research/r439-bsection-stars-seed01/pair_control.json.gz` all have this +shape. Their edge counts are 221, 221, 236 and 188. The synthetic edge is +the shear `h0 ^= h1` with a middle that still names only `h0`. + +## One-edge identity + +Suppose each helper `j` currently holds a value `V_j` in an abelian 2-group, +and target `i` is about to receive the sum of `V_j` over `j` in its support +`S_i`. After the gate `h_a ^= h_b`, the new value of `h_a` is `V_a + V_b` and +`h_b` is unchanged. Replace the support by toggling membership of `b` on +exactly the targets that already name `a`. + +- If target `i` does not name `a`, its support and its sum are unchanged. +- If it names `a` and already names `b`, the new sum replaces `V_a + V_b` + by `V_a + V_b` from the dirty `h_a` alone. The named `b` is dropped. +- If it names `a` and does not name `b`, the new sum is + `(V_a + V_b) + V_b = V_a`. The extra `V_b` is cancelled by naming `b`. + +So one compensated edge preserves every target sum. The leading transport +block only mixes targets, and targets start with no helper columns, so it +does not change the helper footprint. The trailing block is the same map for +the parent and the sheared word, so the final executed mask `E` is the +parent's `E`. Reversing `S` restores every helper because `P`, `M` and `Q` +do not write helpers and each shear is an involution. + +The parent's own execution has `E = K`. A descendant with the same forward +helper footprint therefore also has `E = K`. The star word keeps `A`, +`scatter` and `B` byte for byte. The composition, the later candidate and +the pair control change `B` and `C`; their forward helper masks were checked +equal to the parent's, not deduced from the text of those edits. + +The identity does not use the gain order or the degree bound of the star +search. The verifier also runs five compensated edges that are not in those +searches, and the same five edges without the support update. Compensation +keeps `E`. Dropping it changes `E`. + +## What was checked + +| object | edges | shape | `E = K =` parent `K` | +|---|---:|---|---| +| parent target-compensation | 0 | bare bracket | yes | +| helper-stars-seed19 candidate | 221 | compensated | yes | +| bsection composition | 221 | compensated | yes | +| bsection candidate | 236 | compensated | yes | +| bsection pair control | 188 | compensated | yes | +| five-edge probe, support updated | 5 | compensated | `E` unchanged | +| same probe, support not updated | 5 | not the hypothesis | `E` changes | +| synthetic `h0 ^= h1` then read `h0` | 1 | not the hypothesis | delivers `h0+h1`, not `h0` | + +The pair control is the other pinned helper-mixing word. It is not one of +the three tally words. It satisfies the hypothesis, so the agreement is the +shear identity rather than a property of those three greedy outputs alone. + +## What is not established + +`E = K` is not claimed for an arbitrary restored helper program. The +synthetic edge is the counterexample to that reading. Changed `B` and `C` +sections are checked only for the three words that carry them. The 612 +target-to-target reads inside `D` remain an open H2 read-kind clause. No +supplier, native schedule, all-size transfer, or selected-frontier change is +claimed. + +## Reproduce + +From the repository root, CPython 3.12: + +```sh +python3 -B research/r439-shear-compensation-hypothesis/verify.py +python3 -I -O -Werror -B research/r439-shear-compensation-hypothesis/verify.py +python3 scripts/research_package.py --package research/r439-shear-compensation-hypothesis +``` + +Expected first line: + +```text +PASS_R439_SHEAR_COMPENSATION words=4 edges=221/221/236/188 parent_E_equals_K=1 descendants_E_equals_K=4 shape=4 one_edge_steps=871 compensated_probe=1 uncompensated_probe=1 synthetic_rejects=1 no_new_kappa +``` + +The verifier exits nonzero if a pin drifts, a descendant is not the +compensated shape, `E` or `K` moves, the one-edge identity fails, the +compensated probe moves `E`, or the uncompensated probe or synthetic edge +fails to separate. Runtime is a few seconds. + +## Open next questions + +1. Does every later phase-B rewrite with this same `D` bracket preserve `K`, + or only the three checked variants? The shear lemma fixes `E`. Those + variants were executed; their `B` and `C` edits were not identified. + First step: compare one other pinned B-section word's forward helper mask + with the parent. Blocked by the absence of a structural account of those + edits. +2. Which H2 clause still fails once `E` is read as delivered columns? The + read-kind clause on the 612 target-to-target gates is the obvious + candidate and is not settled here. First step: name the first failing + read of `H2_D_frame0_targets_from_helpers` on the star word. Blocked + because this package does not rerun that checker and does not propose a + replacement predicate. + +## Credit + +The parent bracket is the target-compensation word. The shear assembly and +the star and pair-control words are the helper-star builder (PR #967) and +the phase-B package `research/r439-bsection-stars-seed01`. PR #3533 isolates +one restored helper edge whose literal mask misses the delivered column. +PR #4092 (Nick Petalas) counts the defect by sector. The tally that left +this question open is PR #4115. + +Prepared by unpaidmoon with substantial AI assistance (Cursor Grok). +Apache-2.0. Predecessor packages keep their own notices. diff --git a/research/r439-shear-compensation-hypothesis/SOURCES.json b/research/r439-shear-compensation-hypothesis/SOURCES.json new file mode 100644 index 0000000000..2a40c14835 --- /dev/null +++ b/research/r439-shear-compensation-hypothesis/SOURCES.json @@ -0,0 +1,42 @@ +{ + "schema_version": 1, + "base_commit": "bb4bccbf42844d2801487450727c2f63e10d1d0f", + "files": [ + { + "path": "docs/research/agent-task-catalog.json", + "usage": "provenance", + "git_blob": "67f085acd86acd7d4e03922d9cf4b26bca66fed5", + "sha256": "47b42433f5a85809a3aadd29c2c339da2c6ed728e4f7762df6b88bccb7874cf0" + }, + { + "path": "research/r439-target-compensation/candidate.json.gz", + "usage": "input", + "git_blob": "7f1f188f516ca4661f419dc72114751abf3cc920", + "sha256": "ac30266144f8772ec8cd629153993aa9eb692fe745a9f95015a1b7fa88977a2e" + }, + { + "path": "research/r439-helper-stars-seed19/candidate.json.gz", + "usage": "input", + "git_blob": "8b0210d8b8e9524182e5f54f9bf93c28f4719735", + "sha256": "d8b08885e8ce9868200b2645189d15ed18a27fc2742e54990b3257a0ca4df6b8" + }, + { + "path": "research/r439-bsection-stars-seed01/composition.json.gz", + "usage": "input", + "git_blob": "d95fc2bf795fd9ef8d8bae9d70693c5e64948cec", + "sha256": "0203fea9fa442ca206fe683aa5b6860adac680d63b9fb8be6bd42b39aa7b5cce" + }, + { + "path": "research/r439-bsection-stars-seed01/candidate.json.gz", + "usage": "input", + "git_blob": "9a17b4920334878d6c949191f6931bd97126fe3c", + "sha256": "b452d2c2b0b2a546d1105b1da9769aa78e5c54d6f00e97b30c77e3f54ce445ee" + }, + { + "path": "research/r439-bsection-stars-seed01/pair_control.json.gz", + "usage": "input", + "git_blob": "16972bc96de0c81321eb2feef70766c403017016", + "sha256": "628ebfebe215e153338e88e2e324040d139a111eebfb090929697c7a0b6f3f59" + } + ] +} diff --git a/research/r439-shear-compensation-hypothesis/TASK.json b/research/r439-shear-compensation-hypothesis/TASK.json new file mode 100644 index 0000000000..92812928e8 --- /dev/null +++ b/research/r439-shear-compensation-hypothesis/TASK.json @@ -0,0 +1,67 @@ +{ + "schema_version": 1, + "task_id": "bit-helper-contract", + "priority_revision": 6, + "base_commit": "bb4bccbf42844d2801487450727c2f63e10d1d0f", + "original_card": { + "id": "bit-helper-contract", + "question": "Can one precisely specified helper-mixing word satisfy a replacement for the inherited H2/K interface?", + "starting_points": [ + "docs/research/research-family-status.md", + "research/r439-bsection-stars-seed01/README.md", + "research/r439-copy-path-sharing-barrier/README.md" + ], + "methods": [ + "Derive a replacement interface lemma and price its implementation.", + "Seek an exact dirty-input or chronological-cut counterexample to the proposed replacement." + ], + "acceptance_gate": "A full boundary contract and paid profile; unchanged scalar counts alone are insufficient. A scoped local result may be retained without a complete supplier. Expanding it into further construction rounds requires the family-level budget and obligation gate in research-family-status.md; an optimistic passing relaxation alone is not acceptance.", + "first_step": { + "command": [ + "python3", + "-B", + "research/r439-bsection-stars-seed01/verify.py" + ], + "expected": "PASS_R439_BSECTION_STARS", + "inspect": "Compare the two false H2/K flags with the unchanged paid profile in its README.", + "scope": "Positive control / source-bound orientation only; this is not a new construction or full cold replay." + }, + "first_experiment": "Write one replacement H2/K implication for a single helper-star operation, then try to falsify it on dirty inputs.", + "bottleneck_link": "A legitimate replacement could admit a cheaper bit circuit; scalar savings alone do not alter the selected moment.", + "allowed_variations": [ + "Choose one helper-star or quartet instance; narrow to one boundary implication." + ], + "scope_change_triggers": [ + "Changing only source count or scalar addition count without an interface argument." + ], + "overlap_terms": [ + "H2_D_frame0_targets_from_helpers", + "K_equals_D", + "helper-star" + ] + }, + "scope_status": "refined", + "actual_scope": "Which extra shape makes the executed helper mask E equal the forward footprint K on the three retained R439 helper-star words, while the synthetic restored edge fails that shape, and does the pinned degree-1 pair control satisfy it?", + "scope_change_reason": "The card asks for a replacement H2/K contract and a paid profile. This package does not adopt one. It answers the released next question of the K-defect tally: name a hypothesis the three legal words satisfy and the synthetic edge violates, then test one other pinned helper-mixing word. Stop if the hypothesis is only that D was built to match K.", + "bottleneck_link": "A legitimate H2/K replacement could admit a cheaper bit circuit. Scalar agreement of two masks does not. The compensated-shear shape says when that agreement is forced, and the synthetic edge shows it is not free.", + "budget_minutes": 60, + "stop_rule": "Stop once the compensated-shear shape is checked on the parent, the three tally words and the pair control, the one-edge identity is recorded, and the uncompensated probe and synthetic edge are shown to miss E. Do not adopt K_equals_D, price a new profile, or search another star forest.", + "outcome": "partial", + "evidence": "verify.py checks the parent bracket, four descendant shapes, equality of E and K with the parent footprint, the one-edge identity on all 866 real edges plus five probe edges, one compensated probe, one uncompensated probe, and the three-gate synthetic edge.", + "author": "unpaidmoon", + "ai_assistance": "Substantial Cursor Grok assistance in the shape check, the verifier and the write-up. No proof assistant was used.", + "open_questions": [ + { + "question": "Does every phase-B rewrite that keeps this D bracket preserve the forward helper footprint K, or only the three checked B/C variants?", + "why_it_matters": "The shear lemma fixes E. E equals K on those variants only because their changed B and C sections were checked to leave K unchanged.", + "first_step": "Take one other pinned B-section word with the same 306+111+306 transport blocks and compare its forward helper mask with the parent.", + "blocked_by": "No structural account of those B and C edits is claimed here, so a new word needs its own execution." + }, + { + "question": "After E is read as delivered columns, which H2 clause still fails on these words?", + "why_it_matters": "Mask agreement does not repair the 612 target-to-target reads inside D. Adopting a contract still needs that clause.", + "first_step": "Evaluate H2_D_frame0_targets_from_helpers on the star word and name the first failing read.", + "blocked_by": "This package does not rerun the owner interface checker and does not propose a replacement predicate." + } + ] +} diff --git a/research/r439-shear-compensation-hypothesis/VERIFY.json b/research/r439-shear-compensation-hypothesis/VERIFY.json new file mode 100644 index 0000000000..55f6c6792f --- /dev/null +++ b/research/r439-shear-compensation-hypothesis/VERIFY.json @@ -0,0 +1,25 @@ +{ + "schema_version": 1, + "status": "ready", + "python": "3.12", + "requirements": [], + "inputs": [ + "research/r439-target-compensation/candidate.json.gz", + "research/r439-helper-stars-seed19/candidate.json.gz", + "research/r439-bsection-stars-seed01/composition.json.gz", + "research/r439-bsection-stars-seed01/candidate.json.gz", + "research/r439-bsection-stars-seed01/pair_control.json.gz" + ], + "commands": [ + { + "argv": ["{python}", "-B", "{package}/verify.py"], + "timeout_seconds": 60, + "checks": "Parent E equals K, four compensated-shear descendants keep that footprint, the one-edge identity holds on their edges, and an uncompensated probe and the synthetic edge do not." + }, + { + "argv": ["{python}", "-I", "-O", "-Werror", "-B", "{package}/verify.py"], + "timeout_seconds": 60, + "checks": "The same certificate under isolated imports, optimized bytecode and warnings as errors." + } + ] +} diff --git a/research/r439-shear-compensation-hypothesis/verify.py b/research/r439-shear-compensation-hypothesis/verify.py new file mode 100644 index 0000000000..c09ac7d59c --- /dev/null +++ b/research/r439-shear-compensation-hypothesis/verify.py @@ -0,0 +1,302 @@ +#!/usr/bin/env python3 +"""Compensated restored shears preserve the R439 helper footprint. + +The three words in the K-defect tally, and the pinned degree-1 pair control, +are the same parent D bracket with a helper-only prefix S and its reverse. +Each gate of S is h_a ^= h_b, and the middle support is the parent support +after columns[b] ^= columns[a]. That shape forces the executed helper mask E +to equal the parent's E. The synthetic restored edge applies the shear and +does not update the support, so its executed mask is not the named column. + +This is a finite certificate plus the one-edge identity in README.md. It does +not adopt an H2/K contract and does not change a paid profile or kappa. +""" +import gzip +import hashlib +import json +import os + +HERE = os.path.dirname(os.path.abspath(__file__)) +ROOT = os.path.abspath(os.path.join(HERE, "..", "..")) +PARENT = "research/r439-target-compensation/candidate.json.gz" +WORDS = ( + ("star", "research/r439-helper-stars-seed19/candidate.json.gz", 221), + ("composition", "research/r439-bsection-stars-seed01/composition.json.gz", 221), + ("candidate", "research/r439-bsection-stars-seed01/candidate.json.gz", 236), + ("pair_control", "research/r439-bsection-stars-seed01/pair_control.json.gz", 188), +) +BLOCKS = (306, 111, 306) + + +def fail(message): + raise SystemExit("FAIL_R439_SHEAR_COMPENSATION " + message) + + +def sha256(path): + digest = hashlib.sha256() + with open(path, "rb") as handle: + for chunk in iter(lambda: handle.read(1 << 20), b""): + digest.update(chunk) + return digest.hexdigest() + + +def pin_inputs(): + with open(os.path.join(HERE, "SOURCES.json"), encoding="utf-8") as handle: + rows = json.load(handle)["files"] + for row in rows: + if row["usage"] != "input": + continue + path = os.path.join(ROOT, row["path"]) + if sha256(path) != row["sha256"]: + fail("sha256 mismatch for " + row["path"]) + + +def load_word(relative): + with gzip.open(os.path.join(ROOT, relative), "rt", encoding="utf-8") as handle: + word = json.load(handle) + if word.get("v") != 111 or word.get("R") != 439 or "D" not in word: + fail("unexpected word shape: " + relative) + return word + + +def helper_mask(word): + return ((1 << word["R"]) - 1) << (2 * word["v"]) + + +def xor_sources(values, sources): + acc = 0 + for src in sources: + acc ^= values[src] + return acc + + +def execute(word, gates): + """Helper-column masks xored into targets, and whether helpers return.""" + width, helpers = word["v"], word["R"] + columns = 2 * width + helpers + mask = helper_mask(word) + values = [1 << reg for reg in range(columns)] + delivered = [0] * width + for _frame, dest, sources in gates: + acc = xor_sources(values, sources) + if width <= dest < 2 * width: + delivered[dest - width] ^= acc & mask + values[dest] ^= acc + restored = all(values[reg] == (1 << reg) for reg in range(2 * width, columns)) + return delivered, restored + + +def forward_k(word): + """Helper columns on targets after A, scatter and B, frames off.""" + width = word["v"] + mask = helper_mask(word) + columns = 2 * width + word["R"] + values = [1 << reg for reg in range(columns)] + for name in ("A", "scatter", "B"): + if name == "scatter": + copies = [values[reg] for reg in word["ret"]] + for target, row in enumerate(word["scatter"]): + values[width + target] ^= xor_sources(copies, row) + else: + for _frame, dest, sources in word[name]: + values[dest] ^= xor_sources(values, sources) + return [values[width + target] & mask for target in range(width)] + + +def split_d(word): + width = word["v"] + gates = word["D"] + prefix = 0 + while prefix < len(gates) and gates[prefix][1] >= 2 * width: + prefix += 1 + left, middle, right = BLOCKS + body = gates[prefix:prefix + left + middle + right] + if len(body) != left + middle + right or len(gates) != prefix + len(body) + prefix: + fail("D is not prefix + 306 + 111 + 306 + reverse-prefix") + return (gates[:prefix], body[:left], body[left:left + middle], + body[left + middle:], gates[-prefix:] if prefix else []) + + +def writes_targets_only(gates, width): + return all(width <= dest < 2 * width and all(width <= src < 2 * width for src in sources) + for _frame, dest, sources in gates) + + +def columns_from_middle(middle, width): + columns = [0] * 439 + for index, (_frame, dest, sources) in enumerate(middle): + if dest != width + index: + fail("middle target %d is not in order" % index) + for src in sources: + if src < 2 * width: + fail("middle gate names a non-helper") + columns[src - 2 * width] ^= 1 << index + return columns + + +def shear_columns(columns, edges): + updated = list(columns) + for center, leaf in edges: + updated[leaf] ^= updated[center] + return updated + + +def edges_of(prefix, width): + edges = [] + for _frame, dest, sources in prefix: + if len(sources) != 1 or dest < 2 * width or sources[0] < 2 * width: + fail("helper prefix is not a single helper-to-helper gate") + edges.append((dest - 2 * width, sources[0] - 2 * width)) + return edges + + +def middle_from_columns(columns, width): + gates = [] + for target in range(width): + sources = [2 * width + helper for helper, col in enumerate(columns) if col >> target & 1] + gates.append([0, width + target, sources]) + return gates + + +def source_sets(middle): + return [tuple(sorted(sources)) for _frame, _dest, sources in middle] + + +def one_edge_preserves(columns, values, center, leaf): + """The README case split, evaluated on arbitrary helper-supported values.""" + width_bits = max((col.bit_length() for col in columns), default=0) + before = [0] * width_bits + for helper, col in enumerate(columns): + bit = 0 + row = col + while row: + if row & 1: + before[bit] ^= values[helper] + row >>= 1 + bit += 1 + values[center] ^= values[leaf] + columns[leaf] ^= columns[center] + after = [0] * width_bits + for helper, col in enumerate(columns): + bit = 0 + row = col + while row: + if row & 1: + after[bit] ^= values[helper] + row >>= 1 + bit += 1 + return before == after + + +def probe_edges(columns): + """Five shears whose centers actually carry support. Deterministic.""" + carriers = [helper for helper, col in enumerate(columns) if col] + if len(carriers) < 5: + fail("parent middle has fewer than five occupied helpers") + edges = [] + for step, center in enumerate(carriers[:5]): + leaf = (center + 1 + step) % len(columns) + if leaf == center: + leaf = (leaf + 1) % len(columns) + edges.append((center, leaf)) + return edges + + +def assemble(parent_parts, edges, columns, compensated): + prefix_gates, transport_before, _middle, transport_after = parent_parts + updated = shear_columns(columns, edges) if compensated else list(columns) + width = 111 + shears = [[0, 2 * width + center, [2 * width + leaf]] for center, leaf in edges] + middle = middle_from_columns(updated, width) + return shears + transport_before + middle + transport_after + shears[::-1] + + +def main(): + pin_inputs() + parent = load_word(PARENT) + width = parent["v"] + prefix, before, middle, after, suffix = split_d(parent) + if prefix or suffix: + fail("parent D is not the bare 306+111+306 bracket") + if not writes_targets_only(before, width) or not writes_targets_only(after, width): + fail("parent transport blocks are not target-to-target") + base_columns = columns_from_middle(middle, width) + if source_sets(middle_from_columns(base_columns, width)) != source_sets(middle): + fail("parent middle is not the column support it defines") + parent_e, parent_restored = execute(parent, parent["D"]) + parent_k = forward_k(parent) + if not parent_restored or parent_e != parent_k: + fail("parent executed footprint is not its forward K") + if execute(parent, middle + after)[0] != parent_e: + fail("parent leading transport changes the helper footprint") + + # The one-edge identity on the parent's real supports, five times. + probe = probe_edges(base_columns) + running_columns = list(base_columns) + running_values = [1 << (2 * width + helper) for helper in range(parent["R"])] + for center, leaf in probe: + if not one_edge_preserves(running_columns, running_values, center, leaf): + fail("one-edge identity failed on the probe") + parts = (prefix, before, middle, after) + compensated = assemble(parts, probe, base_columns, True) + bare = assemble(parts, probe, base_columns, False) + if execute(parent, compensated)[0] != parent_e: + fail("compensated probe changed E") + if execute(parent, bare)[0] == parent_e: + fail("uncompensated probe did not change E") + if not execute(parent, compensated)[1]: + fail("compensated probe did not restore helpers") + + edge_counts = [] + for name, relative, expect in WORDS: + word = load_word(relative) + word_prefix, word_before, word_middle, word_after, word_suffix = split_d(word) + if len(word_prefix) != expect: + fail(name + " prefix length is not " + str(expect)) + if word_suffix != word_prefix[::-1]: + fail(name + " suffix is not the reversed helper prefix") + if word_before != before or word_after != after: + fail(name + " transport blocks are not the parent's") + edges = edges_of(word_prefix, width) + expected = shear_columns(base_columns, edges) + if columns_from_middle(word_middle, width) != expected: + fail(name + " middle is not the compensated parent support") + if source_sets(middle_from_columns(expected, width)) != source_sets(word_middle): + fail(name + " middle names a source twice or out of helper order") + # Replay every real edge through the same identity, not only the total. + columns = list(base_columns) + values = [1 << (2 * width + helper) for helper in range(word["R"])] + for center, leaf in edges: + if not one_edge_preserves(columns, values, center, leaf): + fail(name + " rejected the one-edge identity") + delivered, restored = execute(word, word["D"]) + footprint = forward_k(word) + if not restored or delivered != parent_e or footprint != parent_k: + fail(name + " does not keep E = K = parent K") + edge_counts.append(str(len(edges))) + + synthetic = { + "v": 1, + "R": 2, + "D": [[0, 2, [3]], [0, 1, [2]], [0, 2, [3]]], + "A": [], + "B": [], + "scatter": [[]], + "ret": [2], + } + # h0 ^= h1 dirties h0. The read still names only h0, so the leaf support + # was not toggled. Delivery is e0 XOR e1, not the named column e0. + syn_e, syn_restored = execute(synthetic, synthetic["D"]) + named = 1 << 2 + if not syn_restored or syn_e != [named ^ (1 << 3)] or syn_e == [named]: + fail("synthetic uncompensated edge did not separate delivery from the name") + + print( + "PASS_R439_SHEAR_COMPENSATION words=4 edges=%s parent_E_equals_K=1 " + "descendants_E_equals_K=4 shape=4 one_edge_steps=%d compensated_probe=1 " + "uncompensated_probe=1 synthetic_rejects=1 no_new_kappa" + % ("/".join(edge_counts), sum(int(item) for item in edge_counts) + len(probe))) + + +if __name__ == "__main__": + main()