diff --git a/research/t74-borrow43-independent-check/README.md b/research/t74-borrow43-independent-check/README.md new file mode 100644 index 0000000000..90dcbe17c1 --- /dev/null +++ b/research/t74-borrow43-independent-check/README.md @@ -0,0 +1,141 @@ +# Independent check of record candidate PR #2269 (T74 borrow43) + +**Status: independent verification. The construction claims reproduce, so no counterexample was found. Evidence, +metadata and accounting defects are listed below. No new κ, no frontier change, and no endorsement of the claimed κ +beyond what is checked here.** + +PR #2269 (Jeremy Kothe, head `b479fc5567bc09ab9185bffe89b62594f36d74e5`, `research/gmx-t74-borrow43/`) claims the +conditional κ = 0.0016962471390584742…, which is +1.4% over the selected record. It adds 43 borrowed-helper +aliases, taken from Cinna Davis's anticipatory dirty borrowing (#2226), to the T74 pivot-566+554 local words. It then +re-fills the 666-call hosting and prices the result under the PR1673 capped phase-cell fusion outer. + +When this check started (2026-10-15 03:50 UTC), nothing committed checked the *new* 437-helper fill independently. +The package's `evidence/INDEPENDENT.json` describes a different, pre-borrowing 480-helper fill. + +This package rechecks the new construction with fresh standard-library code. It imports, executes and copies no code +from #2269, #2226 or #2260. A reviewer measured the longest shared token run against 19 PR scripts at 27 tokens. +Every input (40 blobs) is pinned by its git blob id and SHA-256 at the head commit. + +## What reproduces exactly + +| Check | Script | Result | +|---|---|---| +| **Words** (both `BORROW-WORD-43base/extra`) | `words_check.py` | Each of the 43 warps has an invertible G over GF(2), dim U = dim E and G·span U = span E. Each symplectic K_G maps L_U to L_E, so its Fourier rank is 0. All aliases are "high" (no anticipatory terms). Frame climbs are nested. An exact replay over ℚ⟨F₄₃⟩ with every live register arbitrary (dirty) gives Yᵢ ← Yᵢ + Xᵢ and restores the other 549 live registers and the 76 zero buffers; the dual orientation also replays. The recounted paid profiles are 43base `{1:2351,2:501,3:414,4:129,5:42,8:8}` and 43extra `{1:2339,2:509,3:418,4:125,5:42,8:8}`, with mass 5385, 437 helpers and widths `{4:36,5:9,7:36,8:116,9:240}`. | +| **Fill** (`OWNERS.json.gz`, 291,042 rows) | `fill_check.py` | There is exactly one role per (call, live helper) over 666 × 437, and none of the 43 removed helpers appears. Widths equal the word widths. 1,332 windows are rebuilt from the event stream and equal PLAN's, and every role is strictly inside its window. Families are correct, no role lands on the caller's active pair, and each family hosts at most one helper per call. On 149,184 bins slices are disjoint, within rank and prefix-filled. The recounted idle remainders `{1:23976,3:8673,5:813,7:150,48:24479}` equal CONSTRUCTION/SPEC. | +| **Price** | `price_check.py` | The global profile is composed from *our* recounts as 249·P_gauge44 + 417·P_extra + idle, and equals `PROFILE.json`. Mass is 4,816,512 = 73·66304 − 23680. The moment root is bracketed exactly to width 10⁻¹³⁰ with a fresh certified atanh/exp evaluator on a 2⁻⁸⁰⁰ grid. The claimed b lies inside the bracket and `complex_lower` + 10⁻⁹⁰ is rejected. κ = ⌊(1−2·10⁻¹⁰⁰)(b−10⁻¹⁰⁰)⌋₁₀⁻¹³⁶ − 10⁻¹¹² holds as arithmetic, and the strict-assembly κ is ≈ b/(1+b) = 0.0016933747…. | +| **Positive controls** | | The unborrowed canonical words reproduce the old profiles (`{5:82}`, masses 5590 and 5594) and equal the pinned 566 words under relabelling. The pre-borrowing T37 parent fill reproduces its SPEC, PLAN and PROFILE (159,840 roles). | + +Each script has targeted negative controls, 3 to 12 per script, including: +- dropping a warp or an inverse warp; +- perturbing a coefficient; +- charging a warp as a climb; +- duplicating a helper; +- overlapping slices; +- moving a role outside its window; +- tampering with idle; +- moving the moment root by ±10⁻⁸⁰. + +Each control is rejected by the check it targets. The gain attributable to borrowing is +Δb = 1.64922·10⁻⁵ over #2044's b = 0.0016797549561255445…. + +## Defects and open obligations found (none changes b as checked) + +1. **No admission receipt for the borrowed supplier.** Eight files are byte-identical to the pre-borrowing #2044 + package: `evidence/INDEPENDENT.json`, `evidence/ASSEMBLY.json`, `evidence/FULL-ADMISSION.json`, `PRICE.json`, + top-level `SPEC.json`, `evidence/ADMISSION-CONTROLS.json`, `evidence/GEOMETRY-CONTROLS.json` and + `evidence/OUTER-DISCOVERY.json`. `INDEPENDENT.json` pins an OWNERS file (`cdfdcdec…`) that is not in the tree. The + "fresh receipt" exists only as PR-body text. The top-level `PLAN.json` is the borrowed version, despite the README's + "unchanged" wording, so the top-level PLAN and SPEC disagree. `new/SPEC.json` and `new/PLAN.json` are the + consistent pair. +2. **Unpriced zero buffers.** + - Each call's cleanup uses 76 private zero buffers outside the 437-helper inventory. #2269's own emitter + (`new/code/borrow/bw_emit.py`) allocates all of them up front, giving a peak of 437 + 76 = **513 fields**, + against 480 unborrowed. Lazy allocation would give 481 forward and 485 in the dual orientation. + - `code/assemble.py` charges `physical = data + R + 8 + 2` with no buffer term. #2260 did charge its 75 buffers, + and #2226 PROOF §4 lists buffer allocation as an open pricing obligation. + - Charging the 76 as dedicated families leaves the stock bits (2644) and the row coefficient (≤ 19547 < 20161) + unchanged. + - Only a model that hosts the buffers inside idle children would move b, and that model was not evaluated. +3. **X2 not checked: disjoint pending axes across children sharing a physical family.** 37,408 of the 54,145 hosted + families carry slices of two or more children. The 7,300 actual 73-column charts are not checked either. An X2 + failure would force a repack and change the idle profile, and with it b. The package attests this only through its + own pipeline; `DATA-PHASES.json` is shipped only inside a vendored tarball. +4. **Metadata errors.** + - `CLAIM.json` has `"construction_improvement": false`, but the gain is a profile change. + - The status string is inherited. + - `gain_over_claimed_leader` (1.28346·10⁻⁵) is an outer-ledger gain set against the strict-assembly κ (gain + 9.962·10⁻⁶). + - The README's lineage section mislabels the new strict κ as the old package's. + - "8 width-4, 35 width-5" and "5590 → 5385" hold only for the gauge44 word. The extra word removes `{4:4, 5:39}` + and goes 5594 → 5385. Helpers 533 and 554 widen from 7 to 8. + - Stale numbers remain in the edited outer notes. The vacuous `or True` assertions found by #2286 persist; those + blobs are byte-identical to #2044's. + +## Not checked + +- **Outer stack.** κ = b depends on PR1673's capped phase-cell fusion outer, with PR1758 gauge-free interiors, PR1786 + fine-prime padding and the union schedule. All are open PRs. Only the arithmetic map b → κ is checked here. Their + written side conditions were inventoried at #2044's point in #2286; `outer/check_ledger.py` and `vendor/` are + byte-identical here, but the point moved (r₀ = 10⁻¹⁰⁰), so that inventory was not re-run. +- **Native level.** Not checked: the native lowering (`run_native_borrow.py`, warp recipes, both orientations, + wrappers, precision/tape, prefix bits, invoice, controller, the Lemma G label stage) and the exact Clifford lifts and + phases of K_G. Only K_G's binary-symplectic image, which fixes the Fourier rank, is checked. The whole borrowing gain + rests on the rank-zero K_G handoffs: charging the warps as plain frame changes would give local mass 5581 rather + than 5385. +- **Assembly.** The 47 strict inequalities and the 39-step bootstrap are not recomputed. +- **Cost conventions** are taken as the specification: cleanup at FULL is free, rank-zero warps are free, and the + COPY rule. The positive controls show these scripts agree with the package's convention; they do not validate it. +- **Inherited premises** of the T74/PR1319 lineage and the PR589 bit supplier. +- **Successor #2288** (exact frame refit of the borrowed gauge44 word) changes the gauge44 word, so the word checks + here do not carry over to it. +- **Successor #2281.** It reuses byte-identical words, OWNERS and PROFILE, so the word and fill checks carry over; its + 10⁻³⁰⁰⁰ endpoint is not certified here. + +## Reproduce + +The inputs are in the open PR, not on main. From a checkout of this repository, Python 3.10+ standard library and +`git`, in about 35 s: + +```sh +python3 -I -B research/t74-borrow43-independent-check/check_all.py --fetch +``` + +`--fetch` downloads `refs/pull/2269/head` only if commit `b479fc55` is absent; every input is still verified against +its pins. Alternatively, pass `--blob-dir DIR` for an exported copy (`git archive b479fc55 research/gmx-t74-borrow43`). + +Expected last line: + +```text +PASS_T74_BORROW43_INDEPENDENT_CHECK words=PASS fill=PASS price=PASS runner_controls=3 commit=b479fc5567bc mode=git +``` + +The receipts `*_check.receipt.json` and `check_all.receipt.json` are deterministic. `--out` regenerates them. + +## Open next questions + +1. **X2 and the 73-column charts for the 437-helper fill.** *Why it matters:* it is the one unchecked fill condition + that could change b. *First step:* extend `fill_check.py` with the T74 template's `port_restriction` and the + PR558/T74 `DATA-PHASES` pending axes. *Blocked by:* the phase data ships only inside a vendored tarball. +2. **Price the cleanup buffers.** *Why it matters:* the emitter's eager 513-field peak is unpriced. *First step:* a + `physical_stock_identity` with a buffer term, or a lazy-allocation emitter with an explicit 481/485 peak bound. + *Blocked by:* an author or maintainer decision on the buffer model. +3. **Fresh admission receipt.** *Why it matters:* the shipped evidence describes the pre-borrowing supplier. + *First step:* commit the `verify_release.py` receipt for `b479fc55`. *Blocked by:* the author. + +## Credit and provenance + +- **Checked work:** + - Jeremy Kothe (PR #2269, T74 lineage, previous records). + - Cinna Davis / 1337isnot1337 (PR #2226 anticipatory dirty borrowing, the alias rule and K_G handoffs). + - Dugongue (PR #2260, selective borrowing with buffer pricing). + - PR1319/PR1625/PR1297, mdumitrean and others (the T74 lineage). + - icekylinx (checker lineage). +- **Related:** Josie Elliston's seed67 owner auditor, an example rule set that was not reused. #2311 (same account, + a separate session) independently audits the different #2260/#2265 T8 selective-borrowing supplier. It is + complementary and shares no code with this package. +- **Base and assignment:** base `0fdd7d82de03e43c9e5a1000dfbcd380d1b687d2`, priority revision 4. Sprint track 75–84 + (independent verification), OS seed 76. No pinned coordination issue existed, so the claim was recorded locally. +- **AI assistance:** prepared for Sagar Thakrar with substantial AI assistance (Claude Code, Anthropic). Separate + agents wrote the word, fill and price checks. Two adversarial reviewers checked independence and claim coverage, + and fixed one overstated diagnostic and one tautological control. The main session reran every command. + Apache-2.0. diff --git a/research/t74-borrow43-independent-check/SOURCES.json b/research/t74-borrow43-independent-check/SOURCES.json new file mode 100644 index 0000000000..392737aa2a --- /dev/null +++ b/research/t74-borrow43-independent-check/SOURCES.json @@ -0,0 +1,18 @@ +{ + "schema_version": 1, + "base_commit": "0fdd7d82de03e43c9e5a1000dfbcd380d1b687d2", + "files": [ + { + "path": "certificates/selected-result.json", + "usage": "provenance", + "git_blob": "ae6a99f28aa468649eb66a361e764d769363bf11", + "sha256": "10b9e340fd8e354a37a0c4813c90e5de1dd42044b5f6aca4a3fc5a42b685fa32" + }, + { + "path": "docs/research/agent-task-catalog.json", + "usage": "provenance", + "git_blob": "e8870e5917057d59b730eb14721a778639eca050", + "sha256": "d46eb6d5b3e279428753d770653663fbdf1063e55c255ea073d768f344927ef7" + } + ] +} diff --git a/research/t74-borrow43-independent-check/TASK.json b/research/t74-borrow43-independent-check/TASK.json new file mode 100644 index 0000000000..dc36320150 --- /dev/null +++ b/research/t74-borrow43-independent-check/TASK.json @@ -0,0 +1,71 @@ +{ + "schema_version": 1, + "task_id": "independent-moment", + "priority_revision": 4, + "base_commit": "0fdd7d82de03e43c9e5a1000dfbcd380d1b687d2", + "original_card": { + "id": "independent-moment", + "question": "Does one changed supplier or assembly claim lack a source-bound independent check of a specific new implication?", + "starting_points": [ + "certificates/selected-result.json" + ], + "methods": [ + "Reconstruct the rank ledger from original operations rather than trusting its aggregate.", + "Implement certified moment inequalities through a different exact enclosure method." + ], + "acceptance_gate": "Demonstrate independence, source binding, positive cases and semantic failure controls. Name the existing checks and the missing coverage. More digits or another equivalent evaluation of an unchanged root is not by itself new verification coverage.", + "first_step": { + "command": [ + "python3", + "-B", + "scripts/research_baseline.py" + ], + "expected": "PASS_RESEARCH_BASELINE_BINDINGS_ONLY", + "inspect": "Record the selected certificate and complex_profile rather than taking a PR headline as input.", + "scope": "Positive control / source-bound orientation only; this is not a new construction or full cold replay." + }, + "first_experiment": "List the existing independent checks for the exact selected or candidate sources. Pick a new changed input, missing binding or distinct failure mode; stop with a handoff if the proposed arithmetic check is already covered.", + "bottleneck_link": "Independent pricing prevents unsupported frontier claims and can reveal genuine accounting slack.", + "allowed_variations": [ + "Reconstruct either a source ledger or a numeric enclosure with a different method." + ], + "scope_change_triggers": [ + "Importing the primary function and calling its output independent verification." + ], + "overlap_terms": [ + "independent moment", + "rank histogram", + "exact enclosure" + ] + }, + "scope_status": "refined", + "actual_scope": "Independent source-bound check of record candidate PR #2269 (head b479fc55, research/gmx-t74-borrow43): the two borrow43 local words (warps, frames, exact replay, paid profiles), the 291,042-role 437-helper owner fill (roles, windows, families, bins, idle recount), and the profile composition with an exact certified moment-root bracket.", + "scope_change_reason": "The card asks for an independent check of a changed supplier claim; this refines it to the newest record candidate, whose new fill and words had no independent check (its shipped INDEPENDENT.json describes the pre-borrow fill).", + "bottleneck_link": "Independent verification of the highest open conditional kappa claim (+1.4% over the selected record) before any frontier decision; it reproduces the construction and isolates the remaining unpriced/unchecked items (zero buffers, X2, outer stack, native level).", + "budget_minutes": 180, + "stop_rule": "Both words, the full fill and the moment bracket checked once with fresh code; two adversarial reviews; no search.", + "outcome": "completed", + "evidence": "check_all.py: PASS_T74_BORROW43_INDEPENDENT_CHECK words=PASS fill=PASS price=PASS (34 s, git mode, 40 pinned inputs at b479fc55). Exact replay over Q, recounted profiles 43base/43extra, 291042-role fill with rebuilt windows, idle {1:23976,3:8673,5:813,7:150,48:24479}, root bracket width 1e-130 containing the claimed b. Positive controls (canonical words, T37 parent) and targeted negative controls in each script.", + "author": "Sagar Thakrar", + "ai_assistance": "Substantial AI assistance: Claude Code (Anthropic, Claude Opus 5.5) subagents wrote words_check.py, fill_check.py, price_check.py and check_all.py from the written specification without importing PR code; two separate agents adversarially reviewed independence and claim coverage; the main session reran every command.", + "open_questions": [ + { + "question": "Does the 437-helper fill satisfy X2 (disjoint pending axes across children sharing a physical family) and the 73-column chart count?", + "why_it_matters": "The only unchecked fill condition that could change b; 37,408 of 54,145 hosted families share children.", + "first_step": "Extend fill_check.py with the T74 port_restriction and the DATA-PHASES pending axes.", + "blocked_by": "Phase data shipped only inside a vendored tarball." + }, + { + "question": "How are the 76 cleanup zero buffers per call priced?", + "why_it_matters": "The package's emitter allocates them eagerly (peak 513 fields vs 480 unborrowed) but physical_stock_identity omits them; PR2226 lists buffer allocation as an open obligation.", + "first_step": "Add a buffer term to physical_stock_identity or a lazy-allocation bound (481/485).", + "blocked_by": "Author/maintainer decision on the buffer model." + }, + { + "question": "Can the borrowed supplier's admission receipt be committed?", + "why_it_matters": "Eight shipped evidence/metadata files describe the pre-borrow #2044 supplier.", + "first_step": "Commit the verify_release.py receipt for b479fc55.", + "blocked_by": "Author action." + } + ] +} diff --git a/research/t74-borrow43-independent-check/VERIFY.json b/research/t74-borrow43-independent-check/VERIFY.json new file mode 100644 index 0000000000..58cc12a3b5 --- /dev/null +++ b/research/t74-borrow43-independent-check/VERIFY.json @@ -0,0 +1,20 @@ +{ + "schema_version": 1, + "status": "ready", + "python": "3.12", + "requirements": [], + "inputs": [], + "commands": [ + { + "argv": [ + "{python}", + "-I", + "-B", + "{package}/check_all.py", + "--fetch" + ], + "timeout_seconds": 600, + "checks": "fetches PR #2269 head b479fc55 if absent (inputs pinned by blob id + sha256); words_check (warps, frames, exact replay, profiles), fill_check (291042-role fill, windows, bins, idle recount), price_check (composition, exact moment bracket); each with positive and negative controls" + } + ] +} diff --git a/research/t74-borrow43-independent-check/check_all.py b/research/t74-borrow43-independent-check/check_all.py new file mode 100644 index 0000000000..7fdf05e85c --- /dev/null +++ b/research/t74-borrow43-independent-check/check_all.py @@ -0,0 +1,352 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: Apache-2.0 +"""Run the three independent checks of PR #2269 (borrow43 on the T74 words) and require each PASS line. + +Object: CrocSwap/integer-mult-bounds PR #2269 (jeremykothe2), head +b479fc5567bc09ab9185bffe89b62594f36d74e5, package research/gmx-t74-borrow43/ +(claimed conditional kappa from b = 0.0016962471390584742207696...). + + words_check.py task A: both BORROW-WORD-43{base,extra}: GF(2) warp algebra, + frame climbs and paid profiles, exact replay over Q. + fill_check.py task B: the 291,042-role OWNERS fill: windows, slices, idle + remainders, global profile, mass and physical-stock facts. + price_check.py task C: global profile from the A and B recounts, and the + exact moment-root bracket around b. + +Each check runs in its own process with this interpreter as `python -I -B`. +Every check must exit 0 with its PASS line as the last stdout line, otherwise +this script prints FAIL_T74_BORROW43_INDEPENDENT_CHECK with the failures. + +Inputs (the PR head blobs) come from one of: + --git-dir PATH a git checkout that contains the head commit (default: the + checkout this script lives in). Blobs are read with + `git cat-file` and pinned by git blob id and sha256. + To obtain the commit: git fetch https://github.com/CrocSwap/integer-mult-bounds pull/2269/head + --blob-dir DIR an exported copy, e.g. + git -C REPO archive b479fc5567bc09ab9185bffe89b62594f36d74e5 research/gmx-t74-borrow43 | tar -x -C DIR + DIR may be the export root or DIR/research/gmx-t74-borrow43. + The same pins are verified on the files. +A preflight step lists every pinned input of the three checks and fails with a +clear message if any is unavailable or does not match its pins. + +Runner negative controls (fast, always run): a sub-check that exits nonzero, a +sub-check that exits 0 without its PASS line, and one altered pin in the +preflight must each be rejected. + +--out first removes, then rewrites words_check.receipt.json, +fill_check.receipt.json, price_check.receipt.json and check_all.receipt.json +next to the scripts (all four are deterministic in the default git mode). + +The final stdout line is + PASS_T74_BORROW43_INDEPENDENT_CHECK words=PASS fill=PASS price=PASS runner_controls=3 commit=... mode=... +or FAIL_T74_BORROW43_INDEPENDENT_CHECK failures= mode=... + +Credit: PR2269 (jeremykothe2); PR2226 (Cinna Davis / 1337isnot1337, with +OpenAI Codex) anticipatory dirty borrowing; PR2260 (Dugongue); the T74 lineage +PR1319/PR1297 (Rohan Arun), PR1625 (mdumitrean), the pivot-554 kernel (PR1672 +lineage); the icekylinx (Zhihao Chen) checker lineage. No package code is +imported or run by any of the checks. + +Prepared with substantial AI assistance (Claude Code, Anthropic); Apache-2.0. + +Usage: python3 -I -B check_all.py [--git-dir PATH [--fetch] | --blob-dir DIR] [--out] +""" + +import sys + +if sys.flags.optimize: + sys.stdout.write('refusing to run under python -O\nFAIL_T74_BORROW43_INDEPENDENT_CHECK\n') + sys.exit(2) + +import argparse +import hashlib +import importlib.util +import json +import os +import subprocess +import time + +PASS_LINE = 'PASS_T74_BORROW43_INDEPENDENT_CHECK' +FAIL_LINE = 'FAIL_T74_BORROW43_INDEPENDENT_CHECK' +COMMIT = 'b479fc5567bc09ab9185bffe89b62594f36d74e5' +PKG = 'research/gmx-t74-borrow43' +HERE = os.path.dirname(os.path.abspath(__file__)) +DEFAULT_GIT_DIR = os.path.dirname(os.path.dirname(HERE)) +RECEIPT_NAME = 'check_all.receipt.json' + +# name, script, PASS token (start of the last stdout line), receipt file, receipt field, receipt value +CHECKS = [ + ('words', 'words_check.py', 'PASS_T74_BORROW43_WORDS_INDEPENDENT', 'words_check.receipt.json', + 'result', 'PASS_T74_BORROW43_WORDS_INDEPENDENT'), + ('fill', 'fill_check.py', 'PASS_INDEPENDENT_T74_BORROW43_FILL_RECOUNT', 'fill_check.receipt.json', + 'status', 'PASS_INDEPENDENT_T74_BORROW43_FILL_RECOUNT'), + ('price', 'price_check.py', 'PASS_T74_BORROW43_PRICE_INDEPENDENT', 'price_check.receipt.json', + 'result', 'PASS_T74_BORROW43_PRICE_INDEPENDENT'), +] + + +def sha256_file(path): + with open(path, 'rb') as fh: + return hashlib.sha256(fh.read()).hexdigest() + + +def git_blob_id(data): + return hashlib.sha1(b'blob %d\0' % len(data) + data).hexdigest() + + +def load_module(script): + """Load one of our own check modules (definitions only; nothing runs at import).""" + path = os.path.join(HERE, script) + spec = importlib.util.spec_from_file_location('t74b43_all_' + script[:-3], path) + mod = importlib.util.module_from_spec(spec) + spec.loader.exec_module(mod) + return mod + + +def required_pins(): + """package-relative path -> (git blob id, sha256), the union over the three checks; pins must agree.""" + req = {} + + def add(rel, blob, sha, who): + if rel in req and req[rel][:2] != (blob, sha): + raise ValueError('inconsistent pins for %s (%s vs %s)' % (rel, req[rel][2], who)) + req.setdefault(rel, (blob, sha, who)) + + words = load_module('words_check.py') + for key in sorted(words.PINS): + rel, blob, sha = words.PINS[key] + add(rel, blob, sha, 'words_check') + fill = load_module('fill_check.py') + for rel in sorted(fill.PINS): + blob, sha = fill.PINS[rel] + add(rel, blob, sha, 'fill_check') + price = load_module('price_check.py') + for rel in sorted(price.PINS): + blob, sha = price.PINS[rel] + add(rel, blob, sha, 'price_check') + for mod, name in ((words, 'words_check'), (price, 'price_check')): + if mod.COMMIT != COMMIT: + raise ValueError(name + ' pins a different commit') + if fill.HEAD != COMMIT: + raise ValueError('fill_check pins a different commit') + return req + + +FETCH_URL = 'https://github.com/CrocSwap/integer-mult-bounds' + + +def git(git_dir, *args): + return subprocess.run(['git', '-C', git_dir] + list(args), stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + +def preflight_git(git_dir, req): + problems = [] + got = git(git_dir, 'rev-parse', '--git-dir') + if got.returncode != 0: + return ['%s is not a git checkout (%s)' % (git_dir, got.stderr.decode('utf-8', 'replace').strip())] + got = git(git_dir, 'cat-file', '-t', COMMIT) + if got.returncode != 0 or got.stdout.strip() != b'commit': + return ['commit %s (PR #2269 head) is not available in %s; fetch it with `git -C %s fetch ' + 'https://github.com/CrocSwap/integer-mult-bounds pull/2269/head` or pass --blob-dir with an exported ' + 'copy' % (COMMIT, git_dir, git_dir)] + got = git(git_dir, 'ls-tree', '-r', COMMIT, PKG + '/') + if got.returncode != 0: + return ['cannot list %s at %s in %s' % (PKG, COMMIT, git_dir)] + tree = {} + for line in got.stdout.decode('utf-8').splitlines(): + meta, path = line.split('\t', 1) + tree[path] = meta.split()[2] + for rel in sorted(req): + blob, sha, who = req[rel] + oid = tree.get(PKG + '/' + rel) + if oid is None: + problems.append('%s/%s (needed by %s) is missing at %s' % (PKG, rel, who, COMMIT)) + elif oid != blob: + problems.append('%s/%s resolves to %s, pinned %s' % (PKG, rel, oid, blob)) + if not problems: + blobs = sorted(set(v[0] for v in req.values())) + got = subprocess.run(['git', '-C', git_dir, 'cat-file', '--batch-check'], input=('\n'.join(blobs) + '\n').encode(), + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + for line in got.stdout.decode('utf-8').splitlines(): + if line.endswith(' missing'): + problems.append('blob %s is not readable in %s' % (line.split()[0], git_dir)) + return problems + + +def preflight_blob_dir(root, req): + problems = [] + for rel in sorted(req): + blob, sha, who = req[rel] + path = os.path.join(root, rel) + if not os.path.isfile(path): + problems.append('%s (needed by %s) is missing' % (path, who)) + continue + with open(path, 'rb') as fh: + data = fh.read() + if git_blob_id(data) != blob or hashlib.sha256(data).hexdigest() != sha: + problems.append('%s does not match its pins (git blob %s, sha256 %s...)' % (path, blob, sha[:16])) + return problems + + +def run_check(name, script, token, mode_args, out_args, quiet=False): + cmd = [sys.executable, '-I', '-B', os.path.join(HERE, script)] + mode_args + out_args + t0 = time.time() + proc = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + elapsed = time.time() - t0 + out = proc.stdout.decode('utf-8', 'replace') + err = proc.stderr.decode('utf-8', 'replace') + lines = [x for x in out.splitlines() if x.strip()] + last = lines[-1] if lines else '' + ok = proc.returncode == 0 and (last == token or last.startswith(token + ' ')) + if quiet: + return dict(ok=ok, returncode=proc.returncode, last_line=last, elapsed=elapsed) + for x in lines: + print(' [%s] %s' % (name, x)) + for x in err.splitlines(): + if x.strip(): + print(' [%s:stderr] %s' % (name, x)) + print(' [%s] exit %d, %.1f s, %s' % (name, proc.returncode, elapsed, 'PASS' if ok else 'FAIL'), flush=True) + return dict(ok=ok, returncode=proc.returncode, last_line=last, elapsed=elapsed) + + +def controls(mode, mode_args, req, git_dir, blob_root): + """Negative controls of this runner: each must be rejected by the check it targets.""" + results = [] + price_token = CHECKS[2][2] + # 1. a sub-check that fails (inputs missing) must be reported as a failure (exit status / last line) + res = run_check('control', 'price_check.py', price_token, + ['--blob-dir', os.path.join(HERE, 'no-such-export-dir')], [], quiet=True) + results.append(dict(name='sub-check run on a missing export exits nonzero', target='runner.exit_and_pass_line', + ok=not res['ok'] and res['returncode'] != 0, detail=res['last_line'][:120])) + # 2. exit status 0 without the PASS line (argparse --help) must not count as a PASS + res = run_check('control', 'price_check.py', price_token, ['--help'], [], quiet=True) + results.append(dict(name='sub-check exits 0 without its PASS line', target='runner.exit_and_pass_line', + ok=not res['ok'] and res['returncode'] == 0, detail=res['last_line'][:120])) + # 3. a single altered pin must be caught by the preflight + rel = 'outer/B.json' + bad = dict(req) + blob, sha, who = bad[rel] + bad[rel] = (blob[:-1] + ('0' if blob[-1] != '0' else '1'), sha, who) + probs = preflight_blob_dir(blob_root, bad) if mode == 'blob-dir' else preflight_git(git_dir, bad) + results.append(dict(name='one altered git blob pin (%s)' % rel, target='runner.preflight', + ok=len(probs) == 1 and rel in probs[0], detail=(probs[0] if probs else 'not detected')[:160])) + return results + + +def main(): + ap = argparse.ArgumentParser(description='Run words_check, fill_check and price_check for PR #2269') + group = ap.add_mutually_exclusive_group() + group.add_argument('--git-dir', default=None, + help='git checkout containing %s (default: %s)' % (COMMIT, DEFAULT_GIT_DIR)) + group.add_argument('--blob-dir', default=None, help='exported copy of %s (export root or the package dir)' % PKG) + ap.add_argument('--out', action='store_true', help='write the receipts next to the scripts') + ap.add_argument('--fetch', action='store_true', + help='git mode only: if the pinned commit is absent, fetch refs/pull/2269/head from %s first ' + '(the commit id and every input blob are still verified against their pins)' % FETCH_URL) + args = ap.parse_args() + started = time.time() + failures = [] + try: + req = required_pins() + except Exception as e: # our own modules are inconsistent: never pass + print('cannot collect the pinned inputs: %s: %s' % (type(e).__name__, e)) + print(FAIL_LINE + ' failures=pins') + return 1 + if args.blob_dir is not None: + root = os.path.abspath(args.blob_dir) + nested = os.path.join(root, PKG) + if os.path.isdir(nested): + root = nested + if not os.path.isdir(root): + problems = ['--blob-dir %s is not a directory' % args.blob_dir] + else: + problems = preflight_blob_dir(root, req) + mode, mode_args = 'blob-dir', ['--blob-dir', root] + else: + git_dir = os.path.abspath(args.git_dir or DEFAULT_GIT_DIR) + if args.fetch: + have = git(git_dir, 'cat-file', '-t', COMMIT) + if have.returncode != 0 or have.stdout.strip() != b'commit': + print('fetching refs/pull/2269/head from %s (commit %s absent)' % (FETCH_URL, COMMIT), flush=True) + got = git(git_dir, 'fetch', '--no-tags', '--quiet', FETCH_URL, 'refs/pull/2269/head') + if got.returncode != 0: + print('fetch failed: %s' % got.stderr.decode('utf-8', 'replace').strip()) + problems = preflight_git(git_dir, req) + mode, mode_args = 'git', ['--repo', git_dir] + print('preflight (%s): %d pinned inputs across the three checks' % (mode, len(req))) + if problems: + print('inputs unavailable or not matching their pins:') + for p in problems[:20]: + print(' ' + p) + if len(problems) > 20: + print(' ... %d more' % (len(problems) - 20)) + print('%s failures=inputs_unavailable(%d) mode=%s' % (FAIL_LINE, len(problems), mode)) + return 1 + print('preflight: all %d inputs present and pinned' % len(req), flush=True) + if args.out: # never leave a receipt of an earlier run next to a failed one + for receipt_name in [c[3] for c in CHECKS] + [RECEIPT_NAME]: + if os.path.exists(os.path.join(HERE, receipt_name)): + os.remove(os.path.join(HERE, receipt_name)) + ctl = controls(mode, mode_args, req, None if mode == 'blob-dir' else git_dir, + root if mode == 'blob-dir' else None) + for c in ctl: + print('runner control: %s -> %s (target %s)' % (c['name'], 'REJECTED-OK' if c['ok'] else 'NOT REJECTED', + c['target'])) + if not c['ok']: + failures.append('control:' + c['name']) + results = {} + for name, script, token, receipt_name, field, value in CHECKS: + print('== %s (%s)' % (name, script), flush=True) + if args.out: + out_args = ['--out', os.path.join(HERE, receipt_name)] if name == 'words' else ['--out'] + else: + out_args = [] + res = run_check(name, script, token, mode_args, out_args) + if res['ok'] and args.out: + path = os.path.join(HERE, receipt_name) + try: + with open(path) as fh: + rec = json.load(fh) + res['receipt_sha256'] = sha256_file(path) + if rec.get(field) != value: + res['ok'] = False + res['last_line'] += ' (receipt %s=%r)' % (field, rec.get(field)) + except (OSError, ValueError) as e: + res['ok'] = False + res['last_line'] += ' (receipt unreadable: %s)' % e + results[name] = res + if not res['ok']: + failures.append('%s:rc=%d:%s' % (name, res['returncode'], res['last_line'][:120])) + print('elapsed %.1f s' % (time.time() - started)) + status = PASS_LINE if not failures else FAIL_LINE + if args.out: + receipt = dict( + checker='check_all.py', object=dict(pr=2269, commit=COMMIT, package=PKG + '/'), mode=mode, + python=sys.version.split()[0], interpreter_flags='-I -B', + pinned_inputs=dict((PKG + '/' + rel, dict(git_blob=v[0], sha256=v[1], used_by=v[2])) + for rel, v in sorted(req.items())), + scripts=dict((script, sha256_file(os.path.join(HERE, script))) + for script in ['check_all.py'] + [c[1] for c in CHECKS]), + checks=dict((name, dict(script=script, pass_token=token, ok=results[name]['ok'], + last_line=results[name]['last_line'], + receipt=receipt_name, receipt_sha256=results[name].get('receipt_sha256'))) + for name, script, token, receipt_name, _f, _v in CHECKS), + runner_controls=ctl, + result=status, + credits='PR2269 jeremykothe2; PR2226 Cinna Davis / 1337isnot1337; PR2260 Dugongue; T74 lineage PR1319/' + 'PR1297 (Rohan Arun), PR1625 (mdumitrean), pivot-554 kernel; icekylinx (Zhihao Chen) checker ' + 'lineage. Prepared with substantial AI assistance (Claude Code, Anthropic); Apache-2.0.') + with open(os.path.join(HERE, RECEIPT_NAME), 'w') as fh: + json.dump(receipt, fh, indent=1, sort_keys=True) + fh.write('\n') + print('receipt written: %s' % os.path.join(HERE, RECEIPT_NAME)) + if failures: + print('%s failures=%s mode=%s' % (FAIL_LINE, ';'.join(failures), mode)) + return 1 + print('%s words=PASS fill=PASS price=PASS runner_controls=%d commit=%s mode=%s' % ( + PASS_LINE, len(ctl), COMMIT[:12], mode)) + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/research/t74-borrow43-independent-check/check_all.receipt.json b/research/t74-borrow43-independent-check/check_all.receipt.json new file mode 100644 index 0000000000..d98583729f --- /dev/null +++ b/research/t74-borrow43-independent-check/check_all.receipt.json @@ -0,0 +1,267 @@ +{ + "checker": "check_all.py", + "checks": { + "fill": { + "last_line": "PASS_INDEPENDENT_T74_BORROW43_FILL_RECOUNT roles=291042 parent_roles=159840 controls=12", + "ok": true, + "pass_token": "PASS_INDEPENDENT_T74_BORROW43_FILL_RECOUNT", + "receipt": "fill_check.receipt.json", + "receipt_sha256": "764f4f0e33298df9a04dfa15aeb8a204e0fef534e732ffe01d98cabb5778c148", + "script": "fill_check.py" + }, + "price": { + "last_line": "PASS_T74_BORROW43_PRICE_INDEPENDENT root=[0.00169624713905847422076962253948..., 0.00169624713905847422076962253948...] b_admissible=1 task_bracket=[0.001696247139058474220,0.001696247139058474221] controls=15", + "ok": true, + "pass_token": "PASS_T74_BORROW43_PRICE_INDEPENDENT", + "receipt": "price_check.receipt.json", + "receipt_sha256": "ef19e53062e5f9efde0d0665e51023978d192536ce695c10b2b7d18df24e6383", + "script": "price_check.py" + }, + "words": { + "last_line": "PASS_T74_BORROW43_WORDS_INDEPENDENT", + "ok": true, + "pass_token": "PASS_T74_BORROW43_WORDS_INDEPENDENT", + "receipt": "words_check.receipt.json", + "receipt_sha256": "99953004227cbdbb8d7d54b88f688536cd0e84a5dbd3a3a6770c43a3dd1798e1", + "script": "words_check.py" + } + }, + "credits": "PR2269 jeremykothe2; PR2226 Cinna Davis / 1337isnot1337; PR2260 Dugongue; T74 lineage PR1319/PR1297 (Rohan Arun), PR1625 (mdumitrean), pivot-554 kernel; icekylinx (Zhihao Chen) checker lineage. Prepared with substantial AI assistance (Claude Code, Anthropic); Apache-2.0.", + "interpreter_flags": "-I -B", + "mode": "git", + "object": { + "commit": "b479fc5567bc09ab9185bffe89b62594f36d74e5", + "package": "research/gmx-t74-borrow43/", + "pr": 2269 + }, + "pinned_inputs": { + "research/gmx-t74-borrow43/CLAIM.json": { + "git_blob": "214e02514d2aba5c3977dae6285bf925c685db3e", + "sha256": "bbcb4b72c86e4ca668256f8bfa6e35c1830a6e0edd77b7ab6230d8a3a7d7d31e", + "used_by": "price_check" + }, + "research/gmx-t74-borrow43/CONSTRUCTION.json": { + "git_blob": "034ec6c6309bd1279661918f2a8706268f9a1200", + "sha256": "37b8605607b2877d82b8403d509f5cd224240064c93fa67ce89a8894acc6b460", + "used_by": "fill_check" + }, + "research/gmx-t74-borrow43/DISPATCH.json": { + "git_blob": "20807cc27c82db1f8f9cd47c79713e066d6ad816", + "sha256": "6aad7f628f4c9b510a95c5b34357736303069ecf92a551659900b1ba540bc7e0", + "used_by": "fill_check" + }, + "research/gmx-t74-borrow43/GLOBAL-TEMPLATE.json.gz": { + "git_blob": "5327fc2f4e8ea82ed356c94ff040d23fc73c731f", + "sha256": "1d31424c4e27e26a35a9932ca778e43f1f3577589275422cc642aa68b31112db", + "used_by": "fill_check" + }, + "research/gmx-t74-borrow43/ORDER.json": { + "git_blob": "7409c4df1092241729739596c7648bda504e6aad", + "sha256": "519d1d5dbb997a219fcfcad34c0b03e7838bef24199784d7e964fa10090f66e1", + "used_by": "fill_check" + }, + "research/gmx-t74-borrow43/OWNERS.json.gz": { + "git_blob": "fc874cb553af5b984e34c1d8696d2213d7458f8f", + "sha256": "5a8c9a18c21f635563c9a6b6a433bcb1e804175ef23d677459033344aa2bd4e6", + "used_by": "fill_check" + }, + "research/gmx-t74-borrow43/PARENT-LIFT-RECEIPT.json": { + "git_blob": "0c6ccc1f8957d0ca97877e81ab83fd06eb10dcad", + "sha256": "925a2c2bae44d69c0ac9d930abe63cf73bf22765b49e6a1eb9d7a0f5f0f4ea84", + "used_by": "fill_check" + }, + "research/gmx-t74-borrow43/PLAN.json": { + "git_blob": "ea617c2fad0a9581723e9c05bb111631a5af7f17", + "sha256": "334709f65761928e02f83bf1f2e7f537d783381bab6689669bffe111b8f60bea", + "used_by": "fill_check" + }, + "research/gmx-t74-borrow43/PRICE.json": { + "git_blob": "c41b950145014912b2b2d176cb4972408c95e23e", + "sha256": "c5ec535fd9edbdec7b64edd5a8b862edb1a7f173d411dacb279172659573e16a", + "used_by": "price_check" + }, + "research/gmx-t74-borrow43/PROFILE.json": { + "git_blob": "48249b94604daccf0552c0c3b2489716344f7ff2", + "sha256": "7012a58b4078d41e3b4412204d7dfdf9eb401bfe7da5429002150bdfc3558865", + "used_by": "fill_check" + }, + "research/gmx-t74-borrow43/README.md": { + "git_blob": "b555bc54dc661658e4d5fcbc5e3bd6503d7af4bd", + "sha256": "2bf8d14e32ea03c614107eccfcce2422287a3a0552ab90f926b464d55767afcf", + "used_by": "price_check" + }, + "research/gmx-t74-borrow43/SPEC.json": { + "git_blob": "5158049eeff8240d59528441d3f1fcfd8f420783", + "sha256": "da49a85190eac2b553fe982ed295b15fcde6d2dd449d976b503de25c277f2029", + "used_by": "fill_check" + }, + "research/gmx-t74-borrow43/evidence/ASSEMBLY.json": { + "git_blob": "6e9debfd552d18846fe55e4cbe6c59a37447b035", + "sha256": "5d9eb1ce551386024b5b6894836f81ed03a83d2e0c0bd0e02e3f6410a596bb2c", + "used_by": "price_check" + }, + "research/gmx-t74-borrow43/evidence/INDEPENDENT.json": { + "git_blob": "16bb558f2472df730076a8163454c6f70b9e9fe3", + "sha256": "78cd00f832ed3c0a4b0e0d202095f7beb6111eaeb4457849d5bb920e983098a0", + "used_by": "fill_check" + }, + "research/gmx-t74-borrow43/inputs/DISPATCH.json": { + "git_blob": "613e01490d24a39e551ba75915320617003c1c81", + "sha256": "b7b971df9dce435556145df307e2bb5138d87e5aa933f1fe61fcc5b5163301c4", + "used_by": "fill_check" + }, + "research/gmx-t74-borrow43/inputs/GLOBAL-TEMPLATE.json.gz": { + "git_blob": "114808c32b1799da53524bdc25cea67efb60009e", + "sha256": "21297b20f1f2dc76eb9dd8124416068c3cb096bab9df17fa4da19bc68dfe082e", + "used_by": "fill_check" + }, + "research/gmx-t74-borrow43/inputs/OWNERS.json.gz": { + "git_blob": "34fa5d69aaa2574af60f1e8f7d43640b03698bca", + "sha256": "3a56f578b2db5647cf6cb811bc6263c7a802ae3e31e9e672596d43185e4e5c9f", + "used_by": "fill_check" + }, + "research/gmx-t74-borrow43/inputs/PLAN.json": { + "git_blob": "5af9dd20821ae5b79778d85cd7183873c5999732", + "sha256": "163431bf8d3bc0d9b894994b1a3cfa7947367b2243b3c0b3a97d740195a1cb08", + "used_by": "fill_check" + }, + "research/gmx-t74-borrow43/inputs/SPEC.json": { + "git_blob": "c15990ace61b32f7233c82580d720e3097a900c3", + "sha256": "2daedf579c8abf30ceed79fe739bdd7659fce4c514de3894a028933143265d98", + "used_by": "fill_check" + }, + "research/gmx-t74-borrow43/new/BORROW-PROVIDERS.json": { + "git_blob": "42563d218a5c7321f686c1cf9b98e75883d85abc", + "sha256": "8324fcf5fd652af9793c1acbc5f5099ee0d2f1eefa0adfbb8335f3d31d891da2", + "used_by": "words_check" + }, + "research/gmx-t74-borrow43/new/PLAN.json": { + "git_blob": "7cacd857edd0f29be5bd2ca9590a17fed4da17ba", + "sha256": "bf1abd33c8ba946371cae37e021747343ef6603a31297bcc962197cc23f535e2", + "used_by": "fill_check" + }, + "research/gmx-t74-borrow43/new/PROFILE.json": { + "git_blob": "3e103605dd46c8754028056eb9dde9a73b9bfdca", + "sha256": "50fcc0960a47f6d35064d3b55ea6dcb4cebbd305aec215c8034f626718595538", + "used_by": "fill_check" + }, + "research/gmx-t74-borrow43/new/SPEC.json": { + "git_blob": "2431d1cebbb2e155356d2da160d60808498bc33d", + "sha256": "bd091ed9e7f4939d06abb467d0d2c56ce0f34ba800d74132669f7b667e125d2d", + "used_by": "fill_check" + }, + "research/gmx-t74-borrow43/new/borrow/inputs/blocks.json": { + "git_blob": "c683574b3861678081fd5c5944dbd7a47309f6fd", + "sha256": "ddfac1dae1fe7cc0a91e7c7205c6d9d0c07c682880aa34eed83bf4ad7384da9f", + "used_by": "words_check" + }, + "research/gmx-t74-borrow43/new/borrow/inputs/extra.canonical.json.gz": { + "git_blob": "e0d670d4351229ce6921ecfbecf180070b17616b", + "sha256": "d7e48dcbafa236a2e1e41f7958244211506f7c7630fe6a2d43d2bdf17b7ae015", + "used_by": "words_check" + }, + "research/gmx-t74-borrow43/new/borrow/inputs/gauge44.canonical.json.gz": { + "git_blob": "4abb6e28f02c95b41ed345d4e4401d16d58ae791", + "sha256": "65c6d17ffee2eacf27bff438f37fc549c9ed0c909cbc7a52976cc75cf2d15b91", + "used_by": "words_check" + }, + "research/gmx-t74-borrow43/new/borrow/inputs/witness_43_base.json": { + "git_blob": "9f4b93f3bc52d4f4ffaa128cfd7ae574fd36c462", + "sha256": "67ffb66d94067f6e53aee9118fe90e14a57f497fc8b3f708b6dac3de2e58ff28", + "used_by": "words_check" + }, + "research/gmx-t74-borrow43/new/borrow/inputs/witness_43_extra.json": { + "git_blob": "864ba533f50c2f1f639a6a3559b185bd321b923a", + "sha256": "d46449c6dbf4477f260cf5baea9bbb570a66ee0b6db81f4a220b9e3086ae9e46", + "used_by": "words_check" + }, + "research/gmx-t74-borrow43/new/borrow/receipts/AUDIT-43base.json": { + "git_blob": "65728eff3ef61c275c873b58f0f8cebc095ef6f9", + "sha256": "9af87b149b8efa58e2454541dd1c5aef86d893c71ec488ae69fb8680c2f7936e", + "used_by": "fill_check" + }, + "research/gmx-t74-borrow43/new/borrow/receipts/AUDIT-43extra.json": { + "git_blob": "f9c2401401612b3b0b6e652e142e65bceadc1170", + "sha256": "849fbe9b9267180ba914237d751b118b4539731249c4482e6264d4772932fd2d", + "used_by": "fill_check" + }, + "research/gmx-t74-borrow43/new/borrow/words/BORROW-WORD-43base.json.gz": { + "git_blob": "448dd795adba29392a90b34aa3f1b1b796c7e0bd", + "sha256": "9492a5537fb87d9ca98dffcd0230f7625b3789744fa94e2f18acf23d91d998b5", + "used_by": "words_check" + }, + "research/gmx-t74-borrow43/new/borrow/words/BORROW-WORD-43extra.json.gz": { + "git_blob": "2b51ba96256283bbc5578f99b694c50edd8a0e35", + "sha256": "87d51f5298101d5947f45c43ee02f0ec45d6acbddabb808d0d02db1eaf063734", + "used_by": "words_check" + }, + "research/gmx-t74-borrow43/new/extra-word-566.json.gz": { + "git_blob": "e86142b352466f54a3da38c96a6e1484145c3b5c", + "sha256": "cd417b904408c221d9840d08faff8af040cc4207f9804284f2f5375d21298a62", + "used_by": "words_check" + }, + "research/gmx-t74-borrow43/new/gauge44-word-566.json.gz": { + "git_blob": "76c01583a0286cddb0f71e0cb13077e4317104f6", + "sha256": "eeb6a236ed0ea8873b8800947d0cd19c36a6fcfdf857fc42913cb45cd984f219", + "used_by": "words_check" + }, + "research/gmx-t74-borrow43/outer/B.json": { + "git_blob": "a66501df3178012477b4c54fb6888e986b52a25e", + "sha256": "631d89563be62a156c2b0119f9d4ba5a31cbf36380768bf8748825cf361bb525", + "used_by": "price_check" + }, + "research/gmx-t74-borrow43/outer/LEDGER.json": { + "git_blob": "3644673ab40b7b3595e94bbb7e118924a1cc48a1", + "sha256": "eab3f0cbd5b5c45c76cee3e2daefd73c994bf7cfa80be118c67e6fab6106a05b", + "used_by": "price_check" + }, + "research/gmx-t74-borrow43/outer/OUTER-CLAIM.json": { + "git_blob": "f1feaefc27028e590fa7992d273c137897b379eb", + "sha256": "ffa05de3c8d7cb7de0114d25df7250909581f4a2c0ce68c8d20eb821bf67f0e5", + "used_by": "price_check" + }, + "research/gmx-t74-borrow43/vendor/pr1297/PROFILE.json": { + "git_blob": "cb96b9560ef7f08512601da484ca3b4550d5c602", + "sha256": "d9bbe0d73ba005749615915a2d884819a6b141e3402d9e7f87f4592a2d27af99", + "used_by": "fill_check" + }, + "research/gmx-t74-borrow43/vendor/pr1297/extra-word.json.gz": { + "git_blob": "4d464f55a2955e5c832b5ce789d5d0e0a39fb4e1", + "sha256": "7b0e9fbda32749aabc7e156d9fe09bceb0624a178628fe69e5dfea783462f905", + "used_by": "fill_check" + }, + "research/gmx-t74-borrow43/vendor/pr1297/gauge44-word.json.gz": { + "git_blob": "eacf8c773cb50637f93a762342b3b5f0853fe29a", + "sha256": "e8e6e78ff7422275c38324499e1f33fb2ecd30de9503aef2b8f1ee80d8c4df8e", + "used_by": "fill_check" + } + }, + "python": "3.14.4", + "result": "PASS_T74_BORROW43_INDEPENDENT_CHECK", + "runner_controls": [ + { + "detail": "FAIL_T74_BORROW43_PRICE_INDEPENDENT", + "name": "sub-check run on a missing export exits nonzero", + "ok": true, + "target": "runner.exit_and_pass_line" + }, + { + "detail": " price_check.receipt.json next to this script)", + "name": "sub-check exits 0 without its PASS line", + "ok": true, + "target": "runner.exit_and_pass_line" + }, + { + "detail": "research/gmx-t74-borrow43/outer/B.json resolves to a66501df3178012477b4c54fb6888e986b52a25e, pinned a66501df3178012477b4c54fb6888e986b52a250", + "name": "one altered git blob pin (outer/B.json)", + "ok": true, + "target": "runner.preflight" + } + ], + "scripts": { + "check_all.py": "34b328fe6ad94b22167ef63474b87bcaa4c5e8ccd9ce237503f5209af68febb8", + "fill_check.py": "6b0e5950876da81238096f29c75ff9b52d6ae6f96435203d46a75e28c7ab8cd6", + "price_check.py": "19fcfb9f4d766959c599223090142edb03998229459cff1266960ca6b7ed1e0f", + "words_check.py": "b66414a39f5ac7b9cd32284027e13a550734901aca5f4457085a034689bc3ce6" + } +} diff --git a/research/t74-borrow43-independent-check/fill_check.py b/research/t74-borrow43-independent-check/fill_check.py new file mode 100644 index 0000000000..3a5a5ff893 --- /dev/null +++ b/research/t74-borrow43-independent-check/fill_check.py @@ -0,0 +1,951 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: Apache-2.0 +"""Independent recount of the whole-helper hosting fill of PR #2269. + +Object: research/gmx-t74-borrow43/OWNERS.json.gz of CrocSwap/integer-mult-bounds +PR #2269 (jeremykothe2) at head b479fc5567bc09ab9185bffe89b62594f36d74e5: +291,042 literal roles that host the 437 live helpers of the two borrowed T74 +local words ('base' = provider gauge44, 249 calls; 'extra', 417 calls) in idle +children of a 74-replica, nine-stage controller. + +This checker is written from the written specification only. It imports and +executes no code from PR #2269, PR #2226, PR #2260 or any vendored directory. +Every input is a git blob of the pinned head, read with `git cat-file`, and is +pinned by git blob id *and* sha256 (both re-derived here at run time). All +accepted facts are integer or GF(2) bit-vector facts (exact); JSON reals are +parsed as Fractions. The script refuses `python -O`. + +Hosting rules implemented (sources: research/complex-double-replica-owners/ +PROOF.md on main, "Actual windows and whole-helper ownership" and "Namespace"; +research/t16-owner-audit-seed67/README.md on main, rules R1-R7/X1; the T74 +package's PLAN.json windows/per_call_widths, GLOBAL-TEMPLATE.json.gz schedule, +CONSTRUCTION.json, SPEC.json and README): + + R-a one role per (call, live helper): 666 calls x 437 helpers; helper index + i is the i-th live helper register (registers 224..703 minus the 43 + `removed` ones, increasing order); role width = dim(final frame) - + dim(start frame) of that helper in the borrowed word (GF(2) ranks). + R-e physical family = owner*896 + (2*pair(child)+side(child))*112 + port, + copy = 112*owner + port; family inside the data namespace [0, 896*T); + not the caller's active pair; at most one helper per family per call. + R-d the call lies strictly inside the owner's actual window: from the last + local sweep / bridge touch of the child's pair on the owner replica to + that child's idle sweep, rebuilt from the template's 30 source events + expanded in the shipped ORDER (bridge-aware). X1: the rebuilt windows + equal PLAN.json windows exactly. + R-b slices [offset, offset+width) lie in [0, rank(child)), are disjoint in + each bin (owner replica, child, port) and form an occupied prefix. + R-c idle remainders rank - occupied per bin (nonzero ones counted) and the + global profile sum_calls P_provider + idle equal the shipped claims; + rank mass and deficit identities. + R-f quantification of the physical-stock charge versus the 76 private zero + buffers of each borrowed word (informational, exact integers). + +Positive control: the same checker on the pre-borrow parent fill shipped in +the package (inputs/OWNERS.json.gz: PR1297 T37 fill, 333 calls x 480 helpers). +Negative controls: each mutation must be rejected by the check it targets. + +Credits: PR #2269 (jeremykothe2; the borrowed T74 fill and package); +PR #2226 (Cinna Davis / 1337isnot1337, anticipatory dirty borrowing); +PR #2260 (Dugongue, concurrent borrowing package); the T74 lineage PR1319 and +PR1297 (Rohan Arun), PR1625 (mdumitrean, pivot-566 kernel) and PR1193 (Jeremy +Diviney, T37 flow fill); the hosting rules of Hao Yan's PR858 / +complex-double-replica-owners PROOF.md; the icekylinx / Zhihao Chen +independent-checker lineage and the T16 owner audit (Josie Elliston) whose +rule list R1-R7/X1 this follows. No code from any of them is reused. + +Prepared with substantial AI assistance (Claude Code, Anthropic); Apache-2.0. + +Usage: python3 -I -B fill_check.py [--repo PATH | --blob-dir DIR] [--out] +""" + +import argparse +import bisect +import gzip +import hashlib +import json +import os +import subprocess +import sys +import time +from collections import Counter +from fractions import Fraction + +if not __debug__: + sys.stderr.write('FAIL_FILL_CHECK refusing to run under python -O\n') + sys.exit(2) + +REPO_DEFAULT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) # repository root +HEAD = 'b479fc5567bc09ab9185bffe89b62594f36d74e5' +PKG = 'research/gmx-t74-borrow43' +RECEIPT_NAME = 'fill_check.receipt.json' + +# relative path in PKG -> (git blob id, sha256 of the blob bytes) +PINS = { + 'OWNERS.json.gz': ('fc874cb553af5b984e34c1d8696d2213d7458f8f', '5a8c9a18c21f635563c9a6b6a433bcb1e804175ef23d677459033344aa2bd4e6'), + 'PROFILE.json': ('48249b94604daccf0552c0c3b2489716344f7ff2', '7012a58b4078d41e3b4412204d7dfdf9eb401bfe7da5429002150bdfc3558865'), + 'new/PROFILE.json': ('3e103605dd46c8754028056eb9dde9a73b9bfdca', '50fcc0960a47f6d35064d3b55ea6dcb4cebbd305aec215c8034f626718595538'), + 'SPEC.json': ('5158049eeff8240d59528441d3f1fcfd8f420783', 'da49a85190eac2b553fe982ed295b15fcde6d2dd449d976b503de25c277f2029'), + 'new/SPEC.json': ('2431d1cebbb2e155356d2da160d60808498bc33d', 'bd091ed9e7f4939d06abb467d0d2c56ce0f34ba800d74132669f7b667e125d2d'), + 'PLAN.json': ('ea617c2fad0a9581723e9c05bb111631a5af7f17', '334709f65761928e02f83bf1f2e7f537d783381bab6689669bffe111b8f60bea'), + 'new/PLAN.json': ('7cacd857edd0f29be5bd2ca9590a17fed4da17ba', 'bf1abd33c8ba946371cae37e021747343ef6603a31297bcc962197cc23f535e2'), + 'CONSTRUCTION.json': ('034ec6c6309bd1279661918f2a8706268f9a1200', '37b8605607b2877d82b8403d509f5cd224240064c93fa67ce89a8894acc6b460'), + 'GLOBAL-TEMPLATE.json.gz': ('5327fc2f4e8ea82ed356c94ff040d23fc73c731f', '1d31424c4e27e26a35a9932ca778e43f1f3577589275422cc642aa68b31112db'), + 'ORDER.json': ('7409c4df1092241729739596c7648bda504e6aad', '519d1d5dbb997a219fcfcad34c0b03e7838bef24199784d7e964fa10090f66e1'), + 'DISPATCH.json': ('20807cc27c82db1f8f9cd47c79713e066d6ad816', '6aad7f628f4c9b510a95c5b34357736303069ecf92a551659900b1ba540bc7e0'), + 'new/BORROW-PROVIDERS.json': ('42563d218a5c7321f686c1cf9b98e75883d85abc', '8324fcf5fd652af9793c1acbc5f5099ee0d2f1eefa0adfbb8335f3d31d891da2'), + 'new/borrow/words/BORROW-WORD-43base.json.gz': ('448dd795adba29392a90b34aa3f1b1b796c7e0bd', '9492a5537fb87d9ca98dffcd0230f7625b3789744fa94e2f18acf23d91d998b5'), + 'new/borrow/words/BORROW-WORD-43extra.json.gz': ('2b51ba96256283bbc5578f99b694c50edd8a0e35', '87d51f5298101d5947f45c43ee02f0ec45d6acbddabb808d0d02db1eaf063734'), + 'new/gauge44-word-566.json.gz': ('76c01583a0286cddb0f71e0cb13077e4317104f6', 'eeb6a236ed0ea8873b8800947d0cd19c36a6fcfdf857fc42913cb45cd984f219'), + 'new/extra-word-566.json.gz': ('e86142b352466f54a3da38c96a6e1484145c3b5c', 'cd417b904408c221d9840d08faff8af040cc4207f9804284f2f5375d21298a62'), + 'new/borrow/receipts/AUDIT-43base.json': ('65728eff3ef61c275c873b58f0f8cebc095ef6f9', '9af87b149b8efa58e2454541dd1c5aef86d893c71ec488ae69fb8680c2f7936e'), + 'new/borrow/receipts/AUDIT-43extra.json': ('f9c2401401612b3b0b6e652e142e65bceadc1170', '849fbe9b9267180ba914237d751b118b4539731249c4482e6264d4772932fd2d'), + 'evidence/INDEPENDENT.json': ('16bb558f2472df730076a8163454c6f70b9e9fe3', '78cd00f832ed3c0a4b0e0d202095f7beb6111eaeb4457849d5bb920e983098a0'), + 'PARENT-LIFT-RECEIPT.json': ('0c6ccc1f8957d0ca97877e81ab83fd06eb10dcad', '925a2c2bae44d69c0ac9d930abe63cf73bf22765b49e6a1eb9d7a0f5f0f4ea84'), + 'inputs/OWNERS.json.gz': ('34fa5d69aaa2574af60f1e8f7d43640b03698bca', '3a56f578b2db5647cf6cb811bc6263c7a802ae3e31e9e672596d43185e4e5c9f'), + 'inputs/PLAN.json': ('5af9dd20821ae5b79778d85cd7183873c5999732', '163431bf8d3bc0d9b894994b1a3cfa7947367b2243b3c0b3a97d740195a1cb08'), + 'inputs/SPEC.json': ('c15990ace61b32f7233c82580d720e3097a900c3', '2daedf579c8abf30ceed79fe739bdd7659fce4c514de3894a028933143265d98'), + 'inputs/GLOBAL-TEMPLATE.json.gz': ('114808c32b1799da53524bdc25cea67efb60009e', '21297b20f1f2dc76eb9dd8124416068c3cb096bab9df17fa4da19bc68dfe082e'), + 'inputs/DISPATCH.json': ('613e01490d24a39e551ba75915320617003c1c81', 'b7b971df9dce435556145df307e2bb5138d87e5aa933f1fe61fcc5b5163301c4'), + 'vendor/pr1297/gauge44-word.json.gz': ('eacf8c773cb50637f93a762342b3b5f0853fe29a', 'e8e6e78ff7422275c38324499e1f33fb2ecd30de9503aef2b8f1ee80d8c4df8e'), + 'vendor/pr1297/extra-word.json.gz': ('4d464f55a2955e5c832b5ce789d5d0e0a39fb4e1', '7b0e9fbda32749aabc7e156d9fe09bceb0624a178628fe69e5dfea783462f905'), + 'vendor/pr1297/PROFILE.json': ('cb96b9560ef7f08512601da484ca3b4550d5c602', 'd9bbe0d73ba005749615915a2d884819a6b141e3402d9e7f87f4592a2d27af99'), +} + +# Geometry of the nine-stage, four-pair, 112-port controller (template/PLAN): +V = 112 # data ports per (pair, side) +H = 9 # local frame dimension +M = 73 # global dimension m +STAGES = 9 +PAIRS = 4 +FAMILIES_PER_REPLICA = 2 * PAIRS * V # 896 +CENTRES, COEFFICIENT_WORK = 8, 2 +ROW_LIMIT = 20161 +ROW_CONSTANTS = 9909 + 252 # retained row formula 2*stock + 9909 + 252 + 2*payload +TAIL_KINDS = ('bank_padding_cover_sweep', 'translate_every_live_family') +ROLE_KEYS = ('child', 'copy', 'family', 'helper', 'offset', 'owner_replica', + 'port', 'replica', 'stage', 'time', 'width') + + +class CheckFailure(Exception): + def __init__(self, check, detail): + Exception.__init__(self, check + ': ' + detail) + self.check = check + self.detail = detail + + +def need(condition, check, detail): + if not condition: + raise CheckFailure(check, detail) + + +# ---------------------------------------------------------------- inputs --- + +def git(repo, *args): + proc = subprocess.run(['git', '-C', repo] + list(args), stdout=subprocess.PIPE, + stderr=subprocess.PIPE, check=False) + need(proc.returncode == 0, 'input.git', 'git ' + ' '.join(args) + ' failed: ' + + proc.stderr.decode('utf-8', 'replace').strip()) + return proc.stdout + + +def load_blobs(repo, blob_dir=None): + """Read every pinned input. Default: git blobs of HEAD in `repo`. With blob_dir: the files + DIR/ of an exported copy (e.g. `git archive HEAD PKG`), which must match + the same git blob ids and sha256 pins (the path-to-blob resolution at HEAD is then not re-done).""" + if blob_dir is None: + need(git(repo, 'cat-file', '-t', HEAD).strip() == b'commit', 'input.pin', 'head commit missing') + blobs, record = {}, {} + for rel in sorted(PINS): + oid, sha = PINS[rel] + path = PKG + '/' + rel + if blob_dir is None: + got = git(repo, 'rev-parse', '--verify', HEAD + ':' + path).decode().strip() + need(got == oid, 'input.pin', path + ' resolves to ' + got + ', pinned ' + oid) + data = git(repo, 'cat-file', 'blob', oid) + else: + src = os.path.join(blob_dir, rel) + need(os.path.isfile(src), 'input.pin', 'exported blob missing: ' + src) + with open(src, 'rb') as handle: + data = handle.read() + header = ('blob %d' % len(data)).encode() + b'\0' + need(hashlib.sha1(header + data).hexdigest() == oid, 'input.pin', 'git blob id of ' + path) + need(hashlib.sha256(data).hexdigest() == sha, 'input.pin', 'sha256 of ' + path) + blobs[rel] = data + record[path] = dict(git_blob=oid, sha256=sha, bytes=len(data)) + return blobs, record + + +def parse(blobs, rel): + data = blobs[rel] + if rel.endswith('.gz'): + data = gzip.decompress(data) + return json.loads(data.decode('utf-8'), parse_float=Fraction) + + +def as_profile(mapping, check, what): + out = Counter() + for key, value in mapping.items(): + need(type(value) is int and value >= 0 and str(int(key)) == str(key), check, what + ' profile entry') + if value: + out[int(key)] = value + return out + + +def plain(counter): + return {str(k): counter[k] for k in sorted(counter) if counter[k]} + + +def mass(counter): + return sum(r * n for r, n in counter.items()) + + +# ------------------------------------------------------------ word widths --- + +FULL = [1 << i for i in range(H)] + + +def gf2_rank(vectors, check): + pivots = {} + for x in vectors: + need(type(x) is int and 0 <= x < 1 << H, check, 'frame vector outside GF(2)^9') + while x: + top = x.bit_length() - 1 + if top in pivots: + x ^= pivots[top] + else: + pivots[top] = x + break + return len(pivots) + + +def word_helpers(word, label): + """Live helper registers, their residual widths and the hyperplane-ended set.""" + check = 'R-a.word' + report = word['report'] + need((report.get('v'), report.get('h'), report.get('R')) == (V, H, 480), check, label + ' dimensions') + need(len(word['ports']) == V, check, label + ' port count') + first, end = 2 * V, 2 * V + 480 + removed = list(word.get('removed', [])) + need(all(type(r) is int and first <= r < end for r in removed) and len(set(removed)) == len(removed), + check, label + ' removed registers') + removed_set = set(removed) + for table in ('helper_final', 'start_extra'): + for key in word[table]: + need(first <= int(key) < end and int(key) not in removed_set, check, + label + ' ' + table + ' names a non-live register ' + key) + live = [r for r in range(first, end) if r not in removed_set] + widths, ended = [], [] + for r in live: + final = word['helper_final'].get(str(r)) + if final is None: + final = FULL + else: + ended.append(r) + start = word['start_extra'].get(str(r), []) + rank_final, rank_start = gf2_rank(final, check), gf2_rank(start, check) + need(rank_final == len(final) and rank_start == len(start), check, label + ' dependent frame list at %d' % r) + need(gf2_rank(list(final) + list(start), check) == rank_final, check, + label + ' start frame not inside final frame at %d' % r) + widths.append(rank_final - rank_start) + return dict(live=live, removed=sorted(removed), widths=widths, hyperplane_ended=ended) + + +# --------------------------------------------------------------- context --- + +def build_context(name, T, helpers, order, dispatch, widths, local_profiles, template, plan, claims): + """Static data of one fill; nothing here reads the OWNERS rows.""" + return dict(name=name, T=T, R=helpers, W=FAMILIES_PER_REPLICA * T, order=order, dispatch=dispatch, + widths=widths, local_profiles=local_profiles, template=template, plan=plan, claims=claims) + + +def derive_schedule(ctx): + """Expand the 30 per-replica source events in call order; rebuild windows.""" + T, template = ctx['T'], ctx['template'] + src = template['execution_schedule'] + need([i for i, e in enumerate(src) if e['kind'] in TAIL_KINDS] == [len(src) - 2, len(src) - 1], + 'R-d.schedule', 'global tail events') + per_replica = [i for i, e in enumerate(src) if e['kind'] not in TAIL_KINDS] + need(per_replica == list(range(30)), 'R-d.schedule', 'thirty per-replica source events') + stage_pair = {} + for e in template['recipe']: + if e['kind'] == 'local': + need(e['stage'] not in stage_pair and 0 <= e['pair'] < PAIRS, 'R-d.schedule', 'recipe stage/pair') + stage_pair[e['stage']] = e['pair'] + need(set(stage_pair) == set(range(STAGES)), 'R-d.schedule', 'recipe stages') + blocks, stage = {}, None + for i in per_replica: + e = src[i] + if e['kind'] == 'local_cover_sweep': + stage = e['stage'] + need(stage not in blocks and e['replicas'] == list(range(T)), 'R-d.schedule', 'local sweep block') + blocks[stage] = [] + need(stage is not None, 'R-d.schedule', 'event before first local sweep') + need(e['kind'] in ('local_cover_sweep', 'idle_cover_sweep', 'bridge', 'terminal_Y_translations', 'terminal'), + 'R-d.schedule', 'unknown source event kind ' + str(e['kind'])) + blocks[stage].append((i, e)) + need(set(blocks) == set(range(STAGES)), 'R-d.schedule', 'stage blocks') + rank = {} + for c in template['idle_children']: + need(c['replicas'] == T and 0 <= c['port'] < V and type(c['rank']) is int and c['rank'] > 0, + 'R-d.schedule', 'idle child record') + need(rank.setdefault(c['child'], c['rank']) == c['rank'], 'R-d.schedule', 'child rank depends on port') + need(len(template['idle_children']) == V * len(rank), 'R-d.schedule', 'idle children per port') + seen = Counter((c['child'], c['port']) for c in template['idle_children']) + need(all(n == 1 for n in seen.values()), 'R-d.schedule', 'duplicate idle child record') + events = [] + for t, (s, r) in enumerate(ctx['order']): + for i, e in blocks[s]: + events.append((i, e, r, t)) + projection = {} + for i, e, r, t in events: + projection.setdefault(r, []).append(i) + need(set(projection) == set(range(T)) and all(p == per_replica for p in projection.values()), + 'R-d.schedule', 'per-replica source-event projection') + last, windows, callpos, child_pair, child_side = {}, {}, {}, {}, {} + rankless = set() + bridges = 0 + for pos, (i, e, r, t) in enumerate(events): + kind = e['kind'] + if kind == 'local_cover_sweep': + callpos[t] = pos + last[r, stage_pair[e['stage']]] = pos + elif kind == 'bridge': + bridges += 1 + last[r, e['src']] = pos + last[r, e['dst']] = pos + elif kind == 'idle_cover_sweep': + for side, child in enumerate(e['child_indices']): + if child not in rank: + # A swept child with no idle_children record has no capacity (rank 0) and hosts nothing. + rankless.add(child) + continue + need((r, child) not in windows, 'R-d.schedule', 'idle sweep child') + need(child_pair.setdefault(child, e['pair']) == e['pair'] and + child_side.setdefault(child, side) == side, 'R-d.schedule', 'child pair/side') + windows[r, child] = (last.get((r, e['pair']), -1), pos) + else: # terminal events touch every pair; they follow every idle sweep of the replica + for p in range(PAIRS): + last[r, p] = pos + need(len(windows) == T * len(rank) and set(callpos) == set(range(len(ctx['order']))), 'R-d.schedule', + 'window inventory') + positions = [callpos[t] for t in range(len(ctx['order']))] + need(all(a < b for a, b in zip(positions, positions[1:])), 'R-d.schedule', 'call positions increase') + times = {} + for key, (lo, hi) in windows.items(): + a = bisect.bisect_right(positions, lo) + b = bisect.bisect_left(positions, hi) + times[key] = list(range(a, b)) + return dict(stage_pair=stage_pair, rank=rank, windows=windows, callpos=positions, child_pair=child_pair, + child_side=child_side, window_times=times, bridges=bridges, events=len(events), + rankless_children=sorted(rankless)) + + +def check_static(ctx, sched): + """Order, dispatch, PLAN widths and X1 (PLAN windows == rebuilt windows).""" + T, order, plan = ctx['T'], ctx['order'], ctx['plan'] + need(len(order) == STAGES * T and set(order) == {(s, r) for s in range(STAGES) for r in range(T)}, + 'R-0.order', 'call inventory') + need(plan['order'] == [list(x) for x in order], 'R-0.order', 'PLAN order') + need(set(ctx['dispatch']) == set(order), 'R-0.dispatch', 'dispatch inventory') + need(len(plan['provider_calls']) == len(order) and len(plan['per_call_widths']) == len(order), + 'R-0.dispatch', 'PLAN call records') + for t, (s, r) in enumerate(order): + pc = plan['provider_calls'][t] + need((pc['stage'], pc['replica']) == (s, r) and pc.get('time', t) == t and + pc['provider'] == ctx['dispatch'][s, r], 'R-0.dispatch', 'PLAN provider call %d' % t) + pw = plan['per_call_widths'][t] + need((pw['stage'], pw['replica']) == (s, r) and pw.get('time', t) == t, 'R-0.widths', 'PLAN width call %d' % t) + need(pw['widths'] == ctx['widths'][ctx['dispatch'][s, r]], 'R-0.widths', 'PLAN per-call widths at %d' % t) + pw = plan['windows'] + need(len(pw) == len(sched['windows']), 'R-d.plan_windows', 'window count') + for (r, c), times in sched['window_times'].items(): + key = '%d,%d' % (r, c) + need(key in pw and pw[key] == [sched['rank'][c], times], 'R-d.plan_windows', 'PLAN window ' + key) + + +def check_roles(ctx, sched, rows): + """Phases R-a, R-e, R-d, R-b, R-c on the literal roles; returns recounts.""" + T, R, W, order = ctx['T'], ctx['R'], ctx['W'], ctx['order'] + at = {key: t for t, key in enumerate(order)} + provider = [ctx['dispatch'][key] for key in order] + # ---- R-a: one role per (call, live helper) at the helper's width + need(len(rows) == len(order) * R, 'R-a.count', '%d roles, expected %d calls x %d helpers' % (len(rows), len(order), R)) + have = [0] * len(order) + seen_helper = set() + for z in rows: + need(type(z) is dict and tuple(sorted(z)) == ROLE_KEYS and all(type(z[k]) is int for k in ROLE_KEYS), + 'R-a.schema', 'role fields') + t = at.get((z['stage'], z['replica'])) + need(t is not None and z['time'] == t, 'R-a.call', 'role call/time') + need(0 <= z['helper'] < R, 'R-a.helper_range', 'helper index') + key = (t, z['helper']) + need(key not in seen_helper, 'R-a.duplicate_helper', 'helper %d twice in call %d' % (z['helper'], t)) + seen_helper.add(key) + need(z['width'] == ctx['widths'][provider[t]][z['helper']], 'R-a.width', + 'width of helper %d in call %d' % (z['helper'], t)) + have[t] += 1 + need(all(n == R for n in have), 'R-a.complete', 'per-call helper inventory') + # ---- R-e: physical family identity, namespace, active pair, one helper per family per call + rank, pair, side, stage_pair = sched['rank'], sched['child_pair'], sched['child_side'], sched['stage_pair'] + seen_family = set() + cross = 0 + for z in rows: + need(0 <= z['owner_replica'] < T and z['child'] in rank and 0 <= z['port'] < V, 'R-e.coords', 'owner coordinates') + need(0 <= z['family'] < W, 'R-e.namespace', 'family %d outside data namespace [0,%d)' % (z['family'], W)) + expect = z['owner_replica'] * FAMILIES_PER_REPLICA + (2 * pair[z['child']] + side[z['child']]) * V + z['port'] + need(z['family'] == expect and z['copy'] == V * z['owner_replica'] + z['port'], 'R-e.family_identity', + 'family/copy identity') + need(not (z['owner_replica'] == z['replica'] and pair[z['child']] == stage_pair[z['stage']]), + 'R-e.active_pair', 'helper hosted on the caller active pair') + key = (z['time'], z['family']) + need(key not in seen_family, 'R-e.family_unique_per_call', 'two helpers on family %d in call %d' % key[::-1]) + seen_family.add(key) + cross += z['owner_replica'] != z['replica'] + # ---- R-d: strictly inside the owner's actual (bridge-aware) window + callpos, windows = sched['callpos'], sched['windows'] + for z in rows: + lo, hi = windows[z['owner_replica'], z['child']] + need(lo < callpos[z['time']] < hi, 'R-d.window', 'role outside window of owner %d child %d' % + (z['owner_replica'], z['child'])) + # ---- R-b: capacity, disjoint slices per bin, occupied prefix + used = {} + for z in rows: + need(z['offset'] >= 0 and z['width'] >= 1 and z['offset'] + z['width'] <= rank[z['child']], 'R-b.capacity', + 'slice outside child capacity') + b = (z['owner_replica'], z['child'], z['port']) + cells = ((1 << z['width']) - 1) << z['offset'] + old = used.get(b, 0) + need(not old & cells, 'R-b.overlap', 'overlapping slices in bin %s' % (b,)) + used[b] = old | cells + for b, cells in used.items(): + need(cells & (cells + 1) == 0, 'R-b.prefix', 'occupied cells of bin %s are not a prefix' % (b,)) + # ---- R-c: idle remainders, global profile, mass identities + idle = Counter() + for (owner, child) in windows: + for port in range(V): + left = rank[child] - bin(used.get((owner, child, port), 0)).count('1') + if left: + idle[left] += 1 + claims = ctx['claims'] + for source, claimed in claims['idle']: + need(idle == claimed, 'R-c.idle', 'idle remainders differ from ' + source) + local = Counter() + for p in provider: + local.update(ctx['local_profiles'][p]) + profile = local + idle + for source, claimed in claims['profile']: + need(profile == claimed, 'R-c.profile', 'global profile differs from ' + source) + total = mass(profile) + need(total == claims['rank_mass'], 'R-c.mass', 'rank mass') + need(M * W - total == claims['deficit'] == 320 * T, 'R-c.mass', 'deficit identity m*W - mass = 320*T') + capacity = T * V * sum(rank.values()) + hosted_width = sum(z['width'] for z in rows) + need(mass(idle) == capacity - hosted_width, 'R-c.mass', 'idle mass = capacity - hosted width') + need(total == mass(local) + capacity - hosted_width, 'R-c.mass', 'mass decomposition') + need(M * M > 2 * max(profile) ** 2, 'R-c.mass', 'halving guard m^2 > 2*maxchild^2') + need(len(rows) == claims['hosted'], 'R-c.counts', 'hosted residual count') + need(cross == claims['cross_replica'], 'R-c.counts', 'cross-replica role count') + need(sum(idle.values()) == claims['idle_remainders'], 'R-c.counts', 'idle remainder count') + family_children = {} + for z in rows: + family_children.setdefault(z['family'], set()).add(z['child']) + return dict(roles=len(rows), calls=len(order), helpers_per_call=R, bins=T * V * len(rank), + occupied_bins=len(used), cross_replica_roles=cross, idle=plain(idle), + hosted_families=len(family_children), + hosted_families_with_slices_of_two_or_more_children=sum(1 for c in family_children.values() if len(c) > 1), + idle_remainders=sum(idle.values()), profile=plain(profile), rank_mass=total, + deficit=M * W - total, live=W, idle_capacity=capacity, hosted_width=hosted_width, + idle_mass=mass(idle), local_mass=mass(local), max_child=max(profile)) + + +def run_pipeline(ctx, sched, rows): + check_static(ctx, sched) + return check_roles(ctx, sched, rows) + + +# ------------------------------------------------------------ case setup --- + +def dispatch_map(records, check): + out = {} + for s, r, p in records: + need((s, r) not in out, check, 'duplicate dispatch') + out[s, r] = p + return out + + +def borrow_case(blobs): + owners = parse(blobs, 'OWNERS.json.gz') + plan = parse(blobs, 'new/PLAN.json') + plan_top = parse(blobs, 'PLAN.json') + spec = parse(blobs, 'new/SPEC.json') + construction = parse(blobs, 'CONSTRUCTION.json') + template = parse(blobs, 'GLOBAL-TEMPLATE.json.gz') + order = [tuple(x) for x in parse(blobs, 'ORDER.json')] + dispatch = dispatch_map(parse(blobs, 'DISPATCH.json'), 'R-0.dispatch') + providers = parse(blobs, 'new/BORROW-PROVIDERS.json') + T = plan['T'] + need(T == 74 and (plan['K'], plan['L'], plan['M']) == (PAIRS, STAGES, M), 'R-0.plan', 'PLAN geometry') + need(order == [tuple(x) for x in plan['order']] == [tuple(x) for x in spec['call_order']], 'R-0.order', + 'ORDER.json = PLAN order = SPEC call_order') + need(dispatch == dispatch_map(spec['dispatch'], 'R-0.dispatch'), 'R-0.dispatch', 'DISPATCH.json = SPEC dispatch') + # The top-level PLAN.json carries the same hosting data as new/PLAN.json. + for key in ('order', 'windows', 'per_call_widths', 'profile', 'T', 'live', 'deficit', 'assignment_sha256', + 'assignment_content_sha256'): + need(plan_top[key] == plan[key], 'R-0.plan', 'PLAN.json and new/PLAN.json differ in ' + key) + for pid in plan['provider_registry']: + for key in ('widths', 'actual_paid_profile'): + need(plan_top['provider_registry'][pid][key] == plan['provider_registry'][pid][key], 'R-0.plan', + 'PLAN.json registry ' + key) + owners_sha = hashlib.sha256(blobs['OWNERS.json.gz']).hexdigest() + need(plan['assignment_sha256'] == owners_sha == spec['data']['owners_sha256'], 'R-0.pins', 'owners pin') + need(spec['data']['plan_sha256'] == hashlib.sha256(blobs['new/PLAN.json']).hexdigest(), 'R-0.pins', 'plan pin') + content = hashlib.sha256(json.dumps(owners, sort_keys=True, separators=(',', ':')).encode()).hexdigest() + need(plan['assignment_content_sha256'] == content, 'R-0.pins', 'owners content identity') + words = {'gauge44': 'new/borrow/words/BORROW-WORD-43base.json.gz', + 'extra': 'new/borrow/words/BORROW-WORD-43extra.json.gz'} + pre_words = {'gauge44': 'new/gauge44-word-566.json.gz', 'extra': 'new/extra-word-566.json.gz'} + audits = {'gauge44': 'new/borrow/receipts/AUDIT-43base.json', 'extra': 'new/borrow/receipts/AUDIT-43extra.json'} + widths, profiles, helpers_info = {}, {}, {} + for pid in ('gauge44', 'extra'): + word = parse(blobs, words[pid]) + pre = parse(blobs, pre_words[pid]) + audit = parse(blobs, audits[pid]) + need(word['base'] == hashlib.sha256(blobs[pre_words[pid]]).hexdigest()[:8], 'R-a.word', + pid + ' borrow word base binding') + info = word_helpers(word, pid) + pre_info = word_helpers(pre, pid + '-pre') + need(len(pre_info['live']) == 480 and not pre_info['removed'], 'R-a.word', pid + ' pre-borrow helper count') + need(len(info['removed']) == 43 and len(info['live']) == 437, 'R-a.word', pid + ' 43 removed helpers') + inventory = Counter(info['widths']) + claimed_widths = [providers[pid]['widths'], plan['provider_registry'][pid]['widths']] + need(all(w == info['widths'] for w in claimed_widths), 'R-a.word', pid + ' provider widths') + for source, inv in (('word report', word['report']['width_inventory']), + ('SPEC inventory', spec['providers'][pid]['inventory']), + ('AUDIT receipt', audit['width_inventory'])): + need(as_profile(inv, 'R-a.word', source) == inventory, 'R-a.word', pid + ' inventory vs ' + source) + local = as_profile(word['report']['local_profile'], 'R-c.local', pid) + for source, prof in (('BORROW-PROVIDERS', providers[pid]['actual_paid_profile']), + ('PLAN registry', plan['provider_registry'][pid]['actual_paid_profile']), + ('SPEC expected_profile', spec['providers'][pid]['expected_profile']), + ('AUDIT receipt', audit['local_profile'])): + need(as_profile(prof, 'R-c.local', source) == local, 'R-c.local', pid + ' local profile vs ' + source) + need(audit['zero_buffers'] == audit['restored_cold'] == len(info['hyperplane_ended']), 'R-f.zero_buffers', + pid + ' zero buffers = hyperplane-ended live helpers') + pre_width = dict(zip(pre_info['live'], pre_info['widths'])) + new_width = dict(zip(info['live'], info['widths'])) + helpers_info[pid] = dict( + removed_registers=info['removed'], removed_helper_indices_of_480=[r - 2 * V for r in info['removed']], + removed_width_histogram_pre=plain(Counter(pre_width[r] for r in info['removed'])), + live_width_changes=[[r, pre_width[r], new_width[r]] for r in info['live'] if pre_width[r] != new_width[r]], + width_inventory_pre=plain(Counter(pre_info['widths'])), width_inventory=plain(inventory), + width_per_call_pre=sum(pre_info['widths']), width_per_call=sum(info['widths']), + local_profile=plain(local), local_mass=mass(local), + local_profile_pre=plain(as_profile(pre['report']['local_profile'], 'R-c.local', 'pre')), + local_mass_pre=mass(as_profile(pre['report']['local_profile'], 'R-c.local', 'pre')), + hyperplane_ended_live=len(info['hyperplane_ended']), hyperplane_ended_pre=len(pre_info['hyperplane_ended'])) + widths[pid] = info['widths'] + profiles[pid] = local + need(helpers_info['gauge44']['removed_registers'] == helpers_info['extra']['removed_registers'], 'R-a.word', + 'both words remove the same registers') + for pid in helpers_info: + helpers_info[pid]['ordered_widths_identical_across_providers'] = widths['gauge44'] == widths['extra'] + counts = Counter(dispatch.values()) + need(counts == as_profile_str(construction['dispatch']) == as_profile_str(spec['expected']['provider_counts']), + 'R-0.dispatch', 'provider call counts') + need(construction['helpers_per_call'] == 437 and construction['roles'] == len(owners), 'R-0.construction', + 'CONSTRUCTION helper/role counts') + exp = spec['expected'] + idle_claims = [('CONSTRUCTION.json idle', as_profile(construction['idle'], 'R-c.idle', 'construction')), + ('new/SPEC.json idle_remainder_profile', as_profile(exp['idle_remainder_profile'], 'R-c.idle', 'spec'))] + profile_claims = [(src, as_profile(parse(blobs, src), 'R-c.profile', src)) for src in ('PROFILE.json', 'new/PROFILE.json')] + profile_claims.append(('new/PLAN.json profile', as_profile(plan['profile'], 'R-c.profile', 'plan'))) + profile_claims.append(('new/SPEC.json global_profile', as_profile(exp['global_profile'], 'R-c.profile', 'spec'))) + claims = dict(idle=idle_claims, profile=profile_claims, rank_mass=exp['rank_mass'], deficit=plan['deficit'], + hosted=exp['hosted_residuals'], cross_replica=exp['cross_replica_helper_roles'], + idle_remainders=exp['idle_remainders']) + need(exp['live'] == plan['live'] == FAMILIES_PER_REPLICA * T, 'R-0.plan', 'live data families') + ctx = build_context('borrow43-T74', T, 437, order, dispatch, widths, profiles, template, plan, claims) + return ctx, owners, helpers_info, dict(spec=spec, template=template, construction=construction) + + +def as_profile_str(mapping): + return Counter({str(k): v for k, v in mapping.items()}) + + +def parent_case(blobs): + owners = parse(blobs, 'inputs/OWNERS.json.gz') + plan = parse(blobs, 'inputs/PLAN.json') + spec = parse(blobs, 'inputs/SPEC.json') + template = parse(blobs, 'inputs/GLOBAL-TEMPLATE.json.gz') + dispatch = dispatch_map(parse(blobs, 'inputs/DISPATCH.json'), 'R-0.dispatch') + T = plan['T'] + need(T == 37, 'R-0.plan', 'parent replicas') + order = [tuple(x) for x in plan['order']] + need(order == [tuple(x) for x in spec['call_order']], 'R-0.order', 'parent PLAN order = SPEC call_order') + need(dispatch == dispatch_map(spec['dispatch'], 'R-0.dispatch'), 'R-0.dispatch', 'parent dispatch') + need(plan['assignment_sha256'] == hashlib.sha256(blobs['inputs/OWNERS.json.gz']).hexdigest() + == spec['data']['owners_sha256'], 'R-0.pins', 'parent owners pin') + widths, profiles = {}, {} + for pid, rel in (('gauge44', 'vendor/pr1297/gauge44-word.json.gz'), ('extra', 'vendor/pr1297/extra-word.json.gz')): + word = parse(blobs, rel) + info = word_helpers(word, 'parent-' + pid) + need(len(info['live']) == 480 and info['widths'] == plan['provider_registry'][pid]['widths'], 'R-a.word', + 'parent widths ' + pid) + need(Counter(info['widths']) == as_profile(spec['providers'][pid]['inventory'], 'R-a.word', 'parent'), + 'R-a.word', 'parent inventory ' + pid) + local = as_profile(word['report']['local_profile'], 'R-c.local', 'parent') + need(local == as_profile(spec['providers'][pid]['expected_profile'], 'R-c.local', 'parent') + == as_profile(plan['provider_registry'][pid]['actual_paid_profile'], 'R-c.local', 'parent'), + 'R-c.local', 'parent local profile ' + pid) + widths[pid], profiles[pid] = info['widths'], local + exp = spec['expected'] + claims = dict(idle=[('inputs/SPEC.json idle_remainder_profile', as_profile(exp['idle_remainder_profile'], 'R-c.idle', 'p'))], + profile=[('inputs/PLAN.json profile', as_profile(plan['profile'], 'R-c.profile', 'p')), + ('inputs/SPEC.json global_profile', as_profile(exp['global_profile'], 'R-c.profile', 'p')), + ('vendor/pr1297/PROFILE.json', as_profile(parse(blobs, 'vendor/pr1297/PROFILE.json'), 'R-c.profile', 'p'))], + rank_mass=exp['rank_mass'], deficit=plan['deficit'], hosted=exp['hosted_residuals'], + cross_replica=exp['cross_replica_helper_roles'], idle_remainders=exp['idle_remainders']) + ctx = build_context('parent-PR1297-T37', T, 480, order, dispatch, widths, profiles, template, plan, claims) + return ctx, owners + + +# ------------------------------------------------------- R-f and staleness --- + +def stock_group(): + """The retained 73-dimensional group factor 2^(36*36) * prod_{i=1}^{36} (2^(2i) - 1).""" + g = 2 ** (36 * 36) + for i in range(1, 37): + g *= 2 ** (2 * i) - 1 + return g + + +def physical_analysis(blobs, ctx, helpers_info, extra): + spec_new, template = extra['spec'], extra['template'] + spec_old = parse(blobs, 'SPEC.json') + independent = parse(blobs, 'evidence/INDEPENDENT.json') + lift = parse(blobs, 'PARENT-LIFT-RECEIPT.json') + W, calls = ctx['W'], len(ctx['order']) + g = stock_group() + payload = 1 << (192 + (M + 1) // 2 + 2 * calls + 4).bit_length() + + def charge(physical): + bits = (g * physical).bit_length() + return dict(physical=physical, stock_bits=bits, row_coefficient=2 * bits + ROW_CONSTANTS + 2 * payload) + + # Formula cross-check against the shipped (pre-borrow) independent receipt. + ref = charge(independent['physical']) + need((ref['stock_bits'], ref['row_coefficient'], independent['charged_prefix_bits']) == + (independent['physical_stock_bits'], independent['physical_row_coefficient'], payload), + 'R-f.formula', 'stock/row formula does not reproduce evidence/INDEPENDENT.json') + geo_old, geo_new = spec_old['geometry'], spec_new['geometry'] + need(geo_old == geo_new, 'R-f.parent', 'parent geometry changed between SPEC.json and new/SPEC.json') + parent_physical = geo_new['parent_physical'] + need(parent_physical == template['physical'] == lift['geometry']['parent_physical'] and + geo_new['parent_live'] == template['live'] and + parent_physical == template['live'] + geo_new['parent_helpers'] + CENTRES + COEFFICIENT_WORK, + 'R-f.parent', 'parent physical = parent live + 504 + 8 + 2') + pre_phys, post_phys = spec_old['expected']['physical'], spec_new['expected']['physical'] + need(pre_phys == W + CENTRES + 480 + COEFFICIENT_WORK, 'R-f.physical', 'pre-borrow hosted physical identity') + need(post_phys == W + CENTRES + 437 + COEFFICIENT_WORK, 'R-f.physical', 'post-borrow hosted physical identity') + zero = {pid: helpers_info[pid]['hyperplane_ended_live'] for pid in helpers_info} + need(set(zero.values()) == {76}, 'R-f.zero_buffers', 'zero buffers per call') + z = 76 + rows = dict(pre_borrow_charged=charge(pre_phys), post_borrow_charged=charge(post_phys), + post_borrow_plus_zero_buffers=charge(post_phys + z), parent_charged=charge(parent_physical), + parent_plus_zero_buffers=charge(parent_physical + z)) + for name, row in rows.items(): + need(row['row_coefficient'] < ROW_LIMIT, 'R-f.row', name + ' row coefficient') + need(rows['post_borrow_plus_zero_buffers']['stock_bits'] == rows['post_borrow_charged']['stock_bits'] == + rows['pre_borrow_charged']['stock_bits'], 'R-f.row', 'hosted stock bits change') + need(rows['parent_plus_zero_buffers']['stock_bits'] == rows['parent_charged']['stock_bits'], 'R-f.row', + 'parent stock bits change') + bits = rows['post_borrow_charged']['stock_bits'] + return dict( + spec_charge='physical = data families W + 8 centres + R local helpers (reserved tableau) + 2 coefficient work; ' + 'parent_physical = parent live + 504 + 8 + 2 (inherited dedicated-bank parent, R0 = 504)', + W=W, helpers_pre=480, helpers_post=437, charged_physical_pre=pre_phys, charged_physical_post=post_phys, + charged_physical_change=post_phys - pre_phys, parent_physical=parent_physical, + parent_geometry_unchanged=True, zero_buffers_per_call=zero, + zero_buffers_in_physical_identity=False, + zero_buffer_note='Each borrowed word allocates one private FULL-frame zero buffer per hyperplane-ended live ' + 'helper (76) inside its final cleanup and frees it; calls are serial, so dedicating them ' + 'costs 76 families once, not per call.', + payload_bits=payload, row_limit=ROW_LIMIT, charges=rows, + max_physical_with_same_stock_bits=((1 << bits) - 1) // g, + formula_reproduces_independent_receipt=dict(physical=independent['physical'], stock_bits=ref['stock_bits'], + row=ref['row_coefficient'])) + + +def package_tree_sha256(repo, blob_dir=None): + """sha256 of every blob in the package tree at the head (to ask whether a cited input is shipped). + With blob_dir: sha256 of every regular file of the exported copy (a full export of the package + gives the same set; a partial export can only under-report what is shipped).""" + if blob_dir is not None: + out, count = set(), 0 + for root, dirs, files in os.walk(blob_dir): + dirs.sort() + for name in sorted(files): + with open(os.path.join(root, name), 'rb') as handle: + out.add(hashlib.sha256(handle.read()).hexdigest()) + count += 1 + return out, count + listing = git(repo, 'ls-tree', '-r', HEAD, PKG).decode().splitlines() + out = set() + for line in listing: + meta, _path = line.split('\t', 1) + _mode, kind, oid = meta.split() + if kind == 'blob': + out.add(hashlib.sha256(git(repo, 'cat-file', 'blob', oid)).hexdigest()) + return out, len(listing) + + +def staleness(blobs, repo, blob_dir=None): + """Arithmetic facts about the shipped pre-borrow evidence (its OWNERS blob is not in the package tree).""" + independent = parse(blobs, 'evidence/INDEPENDENT.json') + spec_old = parse(blobs, 'SPEC.json') + owners_sha = hashlib.sha256(blobs['OWNERS.json.gz']).hexdigest() + ind_owner_sha = [v for k, v in independent['input_sha256'].items() if k.endswith('OWNERS.json.gz')] + shipped, tree_entries = package_tree_sha256(repo, blob_dir) + lp = {p: as_profile(v, 'R-s', 'independent') for p, v in independent['local_profiles'].items()} + counts = independent['provider_counts'] + recomputed = Counter() + for p, n in counts.items(): + for r, c in lp[p].items(): + recomputed[r] += n * c + recomputed += as_profile(independent['idle'], 'R-s', 'independent idle') + widths = {p: sum(int(k) * v for k, v in inv.items()) for p, inv in independent['width_inventories'].items()} + return dict( + independent_roles=independent['roles'], shipped_roles=len(parse(blobs, 'OWNERS.json.gz')), + independent_owner_sha256=ind_owner_sha, shipped_owner_sha256=owners_sha, + independent_owner_blob_in_package_tree=bool(set(ind_owner_sha) & shipped), package_tree_blobs=tree_entries, + spec_owner_blob_in_package_tree=spec_old['data']['owners_sha256'] in shipped, + independent_profile_identity_holds=recomputed == as_profile(independent['profile'], 'R-s', 'profile'), + independent_local_profiles=independent['local_profiles'], + independent_rank_mass_identity=mass(recomputed) == independent['rank_mass'] == 73 * independent['live'] - independent['deficit'], + independent_width_per_call=widths, + top_level_spec_owners_sha256=spec_old['data']['owners_sha256'], + top_level_spec_expected_hosted=spec_old['expected']['hosted_residuals'], + top_level_spec_is_pre_borrow=spec_old['data']['owners_sha256'] != owners_sha) + + +# ------------------------------------------------------- negative controls --- + +def controls(ctx, sched, rows): + T, W = ctx['T'], ctx['W'] + order = ctx['order'] + pair, side, stage_pair, rank = sched['child_pair'], sched['child_side'], sched['stage_pair'], sched['rank'] + by_call = {} + for i, z in enumerate(rows): + by_call.setdefault(z['time'], []).append(i) + family_index = {(z['time'], z['family']): i for i, z in enumerate(rows)} + helper_index = {(z['time'], z['helper']): i for i, z in enumerate(rows)} + out = [] + + def replaced(changes): + new = list(rows) + for i, z in changes.items(): + new[i] = z + return new + + def run(name, expected, mutant_rows, mutant_ctx=None): + try: + run_pipeline(mutant_ctx or ctx, sched, mutant_rows) + except CheckFailure as exc: + need(exc.check == expected, 'control', name + ' rejected by ' + exc.check + ' (' + exc.detail + + '), expected ' + expected) + out.append(dict(name=name, rejected_by=exc.check, detail=exc.detail)) + return + raise CheckFailure('control', 'negative control accepted: ' + name) + + # 1 duplicate a helper inside one call (two equal-width helpers, so R-a.width stays silent) + call0 = by_call[0] + a, b = next((i, j) for i in call0 for j in call0 + if i < j and rows[i]['width'] == rows[j]['width']) + run('duplicate_helper_in_call', 'R-a.duplicate_helper', replaced({b: dict(rows[b], helper=rows[a]['helper'])})) + # 2 drop one role + run('dropped_role', 'R-a.count', rows[1:]) + # 3 narrowed width + i = next(k for k, z in enumerate(rows) if z['width'] > 1) + run('narrowed_width', 'R-a.width', replaced({i: dict(rows[i], width=rows[i]['width'] - 1)})) + # 4 family in the private namespace + run('private_namespace_family', 'R-e.namespace', replaced({0: dict(rows[0], family=W)})) + # 5 consistent role placed on the caller's active pair + z = rows[0] + active = stage_pair[z['stage']] + child = next(c for c in sorted(rank) if pair[c] == active) + fam = z['replica'] * FAMILIES_PER_REPLICA + (2 * active + side[child]) * V + z['port'] + run('caller_active_pair', 'R-e.active_pair', replaced({0: dict(z, owner_replica=z['replica'], child=child, offset=0, + family=fam, copy=V * z['replica'] + z['port'])})) + # 6 two helpers on one family in one invocation + a, b = call0[0], call0[1] + host = {k: rows[a][k] for k in ('owner_replica', 'child', 'port', 'family', 'copy', 'offset')} + run('two_helpers_one_family', 'R-e.family_unique_per_call', replaced({b: dict(rows[b], **host)})) + # 7 role moved outside its owner's window: swap the hosts of one helper between two calls so that + # R-a and R-e still hold for both mutated roles. + swap = None + for i, z in enumerate(rows): + lo, hi = sched['windows'][z['owner_replica'], z['child']] + for t2 in range(len(order) - 1, -1, -1): + if lo < sched['callpos'][t2] < hi: + continue + j = helper_index[t2, z['helper']] + y = rows[j] + s2, r2 = order[t2] + zz = dict(z, stage=s2, replica=r2, time=t2) + yy = dict(y, stage=z['stage'], replica=z['replica'], time=z['time']) + if ctx['widths'][ctx['dispatch'][s2, r2]][z['helper']] != z['width']: + continue + if ctx['widths'][ctx['dispatch'][z['stage'], z['replica']]][y['helper']] != y['width']: + continue + if family_index.get((t2, z['family']), j) != j or family_index.get((z['time'], y['family']), i) != i: + continue + if (zz['owner_replica'] == r2 and pair[zz['child']] == stage_pair[s2]) or \ + (yy['owner_replica'] == z['replica'] and pair[yy['child']] == stage_pair[z['stage']]): + continue + swap = {i: zz, j: yy} + break + if swap: + break + need(swap is not None, 'control', 'no window control could be built') + run('role_outside_owner_window', 'R-d.window', replaced(swap)) + # 8 overlapping slices in one bin (second slice moved onto the first one's offset) + bins = {} + for k, z in enumerate(rows): + bins.setdefault((z['owner_replica'], z['child'], z['port']), []).append(k) + pick = None + for b, members in sorted(bins.items()): + if len(members) >= 2: + members = sorted(members, key=lambda k: rows[k]['offset']) + a, c = members[0], members[1] + if rows[a]['offset'] + rows[c]['width'] <= rank[b[1]]: + pick = (a, c) + break + need(pick is not None, 'control', 'no overlap control could be built') + a, c = pick + run('overlapping_slices', 'R-b.overlap', replaced({c: dict(rows[c], offset=rows[a]['offset'])})) + # 9 gap in the occupied prefix (last slice of a non-full bin shifted up by one) + gap = None + for b, members in sorted(bins.items()): + last = max(members, key=lambda k: rows[k]['offset']) + if rows[last]['offset'] + rows[last]['width'] + 1 <= rank[b[1]]: + gap = last + break + need(gap is not None, 'control', 'no prefix control could be built') + run('gap_in_prefix', 'R-b.prefix', replaced({gap: dict(rows[gap], offset=rows[gap]['offset'] + 1)})) + # 10 tampered idle remainder claim (one 48-remainder claimed as 47) + claims = dict(ctx['claims']) + src, claimed = claims['idle'][0] + tampered = Counter(claimed) + tampered[48] -= 1 + tampered[47] += 1 + claims['idle'] = [(src, +tampered)] + claims['idle'][1:] + run('tampered_idle_remainder', 'R-c.idle', rows, dict(ctx, claims=claims)) + # 11 tampered global profile claim + claims = dict(ctx['claims']) + src, claimed = claims['profile'][0] + tampered = Counter(claimed) + tampered[1] += 1 + claims['profile'] = [(src, tampered)] + claims['profile'][1:] + run('tampered_global_profile', 'R-c.profile', rows, dict(ctx, claims=claims)) + # 12 committed PLAN window time list truncated (X1) + plan = dict(ctx['plan']) + windows = dict(plan['windows']) + key = next(k for k in sorted(windows) if windows[k][1]) + windows[key] = [windows[key][0], windows[key][1][:-1]] + plan['windows'] = windows + run('truncated_plan_window', 'R-d.plan_windows', rows, dict(ctx, plan=plan)) + return out + + +# -------------------------------------------------------------------- main --- + +def main(): + parser = argparse.ArgumentParser(description=__doc__.split('\n')[0]) + parser.add_argument('--repo', default=REPO_DEFAULT) + parser.add_argument('--blob-dir', default=None, + help='exported package copy: DIR/ (instead of git blobs)') + parser.add_argument('--out', action='store_true', help='write ' + RECEIPT_NAME + ' next to this script') + args = parser.parse_args() + started = time.time() + try: + blobs, record = load_blobs(args.repo, args.blob_dir) + ctx, rows, helpers_info, extra = borrow_case(blobs) + sched = derive_schedule(ctx) + result = run_pipeline(ctx, sched, rows) + physical = physical_analysis(blobs, ctx, helpers_info, extra) + stale = staleness(blobs, args.repo, args.blob_dir) + rejected = controls(ctx, sched, rows) + pctx, prows = parent_case(blobs) + psched = derive_schedule(pctx) + presult = run_pipeline(pctx, psched, prows) + calls = result['calls'] + live, deficit = result['live'], result['deficit'] + need(result['rank_mass'] == (M - 1) * live + (live - deficit) and live - deficit == 64 * calls, + 'R-c.mass', 'mass = (m-1)W + (W-D) with W-D = 64 per call') + per_call = {p: helpers_info[p]['local_mass'] - helpers_info[p]['width_per_call'] for p in helpers_info} + per_call_pre = {p: helpers_info[p]['local_mass_pre'] - helpers_info[p]['width_per_call_pre'] for p in helpers_info} + need(len(set(per_call.values()) | set(per_call_pre.values())) == 1, 'R-c.mass', + 'local mass - hosted width per call is one constant before and after borrowing') + except CheckFailure as exc: + print('FAIL_FILL_CHECK ' + str(exc)) + return 1 + except Exception as exc: # malformed input: report, never pass + print('FAIL_FILL_CHECK unexpected ' + type(exc).__name__ + ': ' + str(exc)) + return 1 + identities = dict( + rank_mass='mass = m*W - D = 73*66304 - 23680 = %d' % result['rank_mass'], + decomposition='mass = (m-1)*W + (W - D) = 72*66304 + 42624; W - D = 576*T = 64*(9T) = 64*666', + capacity='idle capacity = T*112*sum(child ranks) = %d; idle mass = capacity - hosted width = %d - %d = %d' + % (result['idle_capacity'], result['idle_capacity'], result['hosted_width'], result['idle_mass']), + per_call='local mass - hosted width per call = %s (pre-borrow %s): the borrowing lowers both by the same ' + 'amount, so the rank mass and deficit are unchanged' % (per_call, per_call_pre), + halving='73^2 = 5329 > 2*%d^2 = %d' % (result['max_child'], 2 * result['max_child'] ** 2)) + receipt = dict( + status='PASS_INDEPENDENT_T74_BORROW43_FILL_RECOUNT', + object=dict(pr=2269, head=HEAD, package=PKG, owners='OWNERS.json.gz'), + inputs=record, + windows=dict(rebuilt=len(sched['windows']), equal_to_plan=True, expanded_events=sched['events'], + bridges=sched['bridges'], child_ranks={str(c): sched['rank'][c] for c in sorted(sched['rank'])}, + swept_children_without_capacity=sched['rankless_children']), + borrow=result, helpers=helpers_info, identities=identities, physical=physical, stale_evidence=stale, + controls_rejected=rejected, + parent_positive_control=dict(package_path=PKG + '/inputs/OWNERS.json.gz', windows_equal_to_plan=True, **presult), + not_checked=['local paid profiles of the borrowed words (taken from the word reports; recount = task A)', + 'X2 pending-axis disjointness and 73-axis charts (DATA-PHASES.json is not shipped outside the ' + 'vendored tarball)', 'native LOCAL-PROGRAMS, controller emission, invoice and prefix bits', + 'physical location of the 76 zero buffers (not stated in the shipped text)'], + scope='Finite recount of the shipped hosting fill under the stated rules. Not a proof of the conditional ' + 'kappa; local words, invoice, moments and outer assembly are outside this check.', + credits='PR2269 jeremykothe2; PR2226 Cinna Davis / 1337isnot1337; PR2260 Dugongue; T74 lineage PR1319, ' + 'PR1625, PR1297 (and PR1193); rules from PR858 / complex-double-replica-owners PROOF.md and the T16 ' + 'owner audit (icekylinx checker lineage). Prepared with substantial AI assistance (Claude Code, ' + 'Anthropic); Apache-2.0.') + if args.blob_dir is not None: # default (git) mode keeps the receipt layout unchanged + receipt['inputs_source'] = ('exported copy (--blob-dir); pins re-verified; package-tree membership ' + 'from the %d files of the copy' % stale['package_tree_blobs']) + if args.out: + path = os.path.join(os.path.dirname(os.path.abspath(__file__)), RECEIPT_NAME) + with open(path, 'w', encoding='utf-8') as handle: + handle.write(json.dumps(receipt, indent=1, sort_keys=True) + '\n') + print('borrow fill: roles=%d calls=%d helpers/call=%d idle=%s' % (result['roles'], calls, + result['helpers_per_call'], result['idle'])) + print('borrow profile=%s mass=%d deficit=%d cross_replica=%d' % (result['profile'], result['rank_mass'], + result['deficit'], result['cross_replica_roles'])) + print('physical: pre=%d post=%d parent=%d zero_buffers/call=%s stock_bits=%s' % ( + physical['charged_physical_pre'], physical['charged_physical_post'], physical['parent_physical'], + physical['zero_buffers_per_call'], + sorted({row['stock_bits'] for row in physical['charges'].values()}))) + print('stale: INDEPENDENT roles=%d (shipped %d), owner blob shipped=%s; top-level SPEC pre-borrow=%s' % ( + stale['independent_roles'], stale['shipped_roles'], stale['independent_owner_blob_in_package_tree'], + stale['top_level_spec_is_pre_borrow'])) + print('parent control: roles=%d idle=%s mass=%d' % (presult['roles'], presult['idle'], presult['rank_mass'])) + print('controls rejected: %d (%s)' % (len(rejected), ', '.join(c['name'] + '->' + c['rejected_by'] for c in rejected))) + print('runtime_s=%.1f' % (time.time() - started)) + print('PASS_INDEPENDENT_T74_BORROW43_FILL_RECOUNT roles=%d parent_roles=%d controls=%d' % ( + result['roles'], presult['roles'], len(rejected))) + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/research/t74-borrow43-independent-check/fill_check.receipt.json b/research/t74-borrow43-independent-check/fill_check.receipt.json new file mode 100644 index 0000000000..8bdf4283e5 --- /dev/null +++ b/research/t74-borrow43-independent-check/fill_check.receipt.json @@ -0,0 +1,710 @@ +{ + "borrow": { + "bins": 149184, + "calls": 666, + "cross_replica_roles": 270118, + "deficit": 23680, + "helpers_per_call": 437, + "hosted_families": 54145, + "hosted_families_with_slices_of_two_or_more_children": 37408, + "hosted_width": 2350314, + "idle": { + "1": 23976, + "3": 8673, + "48": 24479, + "5": 813, + "7": 150 + }, + "idle_capacity": 3580416, + "idle_mass": 1230102, + "idle_remainders": 58091, + "live": 66304, + "local_mass": 3586410, + "max_child": 48, + "occupied_bins": 124705, + "profile": { + "1": 1584738, + "2": 337002, + "3": 286065, + "4": 84246, + "48": 24479, + "5": 28785, + "7": 150, + "8": 5328 + }, + "rank_mass": 4816512, + "roles": 291042 + }, + "controls_rejected": [ + { + "detail": "helper 0 twice in call 0", + "name": "duplicate_helper_in_call", + "rejected_by": "R-a.duplicate_helper" + }, + { + "detail": "291041 roles, expected 666 calls x 437 helpers", + "name": "dropped_role", + "rejected_by": "R-a.count" + }, + { + "detail": "width of helper 0 in call 0", + "name": "narrowed_width", + "rejected_by": "R-a.width" + }, + { + "detail": "family 66304 outside data namespace [0,66304)", + "name": "private_namespace_family", + "rejected_by": "R-e.namespace" + }, + { + "detail": "helper hosted on the caller active pair", + "name": "caller_active_pair", + "rejected_by": "R-e.active_pair" + }, + { + "detail": "two helpers on family 33712 in call 0", + "name": "two_helpers_one_family", + "rejected_by": "R-e.family_unique_per_call" + }, + { + "detail": "role outside window of owner 37 child 6", + "name": "role_outside_owner_window", + "rejected_by": "R-d.window" + }, + { + "detail": "overlapping slices in bin (0, 0, 0)", + "name": "overlapping_slices", + "rejected_by": "R-b.overlap" + }, + { + "detail": "occupied cells of bin (0, 4, 0) are not a prefix", + "name": "gap_in_prefix", + "rejected_by": "R-b.prefix" + }, + { + "detail": "idle remainders differ from CONSTRUCTION.json idle", + "name": "tampered_idle_remainder", + "rejected_by": "R-c.idle" + }, + { + "detail": "global profile differs from PROFILE.json", + "name": "tampered_global_profile", + "rejected_by": "R-c.profile" + }, + { + "detail": "PLAN window 0,0", + "name": "truncated_plan_window", + "rejected_by": "R-d.plan_windows" + } + ], + "credits": "PR2269 jeremykothe2; PR2226 Cinna Davis / 1337isnot1337; PR2260 Dugongue; T74 lineage PR1319, PR1625, PR1297 (and PR1193); rules from PR858 / complex-double-replica-owners PROOF.md and the T16 owner audit (icekylinx checker lineage). Prepared with substantial AI assistance (Claude Code, Anthropic); Apache-2.0.", + "helpers": { + "extra": { + "hyperplane_ended_live": 76, + "hyperplane_ended_pre": 78, + "live_width_changes": [ + [ + 533, + 7, + 8 + ], + [ + 554, + 7, + 8 + ] + ], + "local_mass": 5385, + "local_mass_pre": 5594, + "local_profile": { + "1": 2339, + "2": 509, + "3": 418, + "4": 125, + "5": 42, + "8": 8 + }, + "local_profile_pre": { + "1": 2340, + "2": 508, + "3": 420, + "4": 126, + "5": 82, + "8": 8 + }, + "ordered_widths_identical_across_providers": true, + "removed_helper_indices_of_480": [ + 371, + 373, + 374, + 375, + 379, + 381, + 383, + 387, + 389, + 390, + 391, + 403, + 405, + 406, + 407, + 419, + 421, + 422, + 423, + 427, + 429, + 430, + 431, + 435, + 437, + 438, + 439, + 451, + 453, + 454, + 455, + 459, + 461, + 462, + 463, + 467, + 469, + 470, + 471, + 475, + 477, + 478, + 479 + ], + "removed_registers": [ + 595, + 597, + 598, + 599, + 603, + 605, + 607, + 611, + 613, + 614, + 615, + 627, + 629, + 630, + 631, + 643, + 645, + 646, + 647, + 651, + 653, + 654, + 655, + 659, + 661, + 662, + 663, + 675, + 677, + 678, + 679, + 683, + 685, + 686, + 687, + 691, + 693, + 694, + 695, + 699, + 701, + 702, + 703 + ], + "removed_width_histogram_pre": { + "4": 4, + "5": 39 + }, + "width_inventory": { + "4": 36, + "5": 9, + "7": 36, + "8": 116, + "9": 240 + }, + "width_inventory_pre": { + "4": 40, + "5": 48, + "7": 38, + "8": 114, + "9": 240 + }, + "width_per_call": 3529, + "width_per_call_pre": 3738 + }, + "gauge44": { + "hyperplane_ended_live": 76, + "hyperplane_ended_pre": 78, + "live_width_changes": [ + [ + 533, + 7, + 8 + ], + [ + 554, + 7, + 8 + ] + ], + "local_mass": 5385, + "local_mass_pre": 5590, + "local_profile": { + "1": 2351, + "2": 501, + "3": 414, + "4": 129, + "5": 42, + "8": 8 + }, + "local_profile_pre": { + "1": 2348, + "2": 500, + "3": 416, + "4": 130, + "5": 82, + "8": 8 + }, + "ordered_widths_identical_across_providers": true, + "removed_helper_indices_of_480": [ + 371, + 373, + 374, + 375, + 379, + 381, + 383, + 387, + 389, + 390, + 391, + 403, + 405, + 406, + 407, + 419, + 421, + 422, + 423, + 427, + 429, + 430, + 431, + 435, + 437, + 438, + 439, + 451, + 453, + 454, + 455, + 459, + 461, + 462, + 463, + 467, + 469, + 470, + 471, + 475, + 477, + 478, + 479 + ], + "removed_registers": [ + 595, + 597, + 598, + 599, + 603, + 605, + 607, + 611, + 613, + 614, + 615, + 627, + 629, + 630, + 631, + 643, + 645, + 646, + 647, + 651, + 653, + 654, + 655, + 659, + 661, + 662, + 663, + 675, + 677, + 678, + 679, + 683, + 685, + 686, + 687, + 691, + 693, + 694, + 695, + 699, + 701, + 702, + 703 + ], + "removed_width_histogram_pre": { + "4": 8, + "5": 35 + }, + "width_inventory": { + "4": 36, + "5": 9, + "7": 36, + "8": 116, + "9": 240 + }, + "width_inventory_pre": { + "4": 44, + "5": 44, + "7": 38, + "8": 114, + "9": 240 + }, + "width_per_call": 3529, + "width_per_call_pre": 3734 + } + }, + "identities": { + "capacity": "idle capacity = T*112*sum(child ranks) = 3580416; idle mass = capacity - hosted width = 3580416 - 2350314 = 1230102", + "decomposition": "mass = (m-1)*W + (W - D) = 72*66304 + 42624; W - D = 576*T = 64*(9T) = 64*666", + "halving": "73^2 = 5329 > 2*48^2 = 4608", + "per_call": "local mass - hosted width per call = {'gauge44': 1856, 'extra': 1856} (pre-borrow {'gauge44': 1856, 'extra': 1856}): the borrowing lowers both by the same amount, so the rank mass and deficit are unchanged", + "rank_mass": "mass = m*W - D = 73*66304 - 23680 = 4816512" + }, + "inputs": { + "research/gmx-t74-borrow43/CONSTRUCTION.json": { + "bytes": 427, + "git_blob": "034ec6c6309bd1279661918f2a8706268f9a1200", + "sha256": "37b8605607b2877d82b8403d509f5cd224240064c93fa67ce89a8894acc6b460" + }, + "research/gmx-t74-borrow43/DISPATCH.json": { + "bytes": 10399, + "git_blob": "20807cc27c82db1f8f9cd47c79713e066d6ad816", + "sha256": "6aad7f628f4c9b510a95c5b34357736303069ecf92a551659900b1ba540bc7e0" + }, + "research/gmx-t74-borrow43/GLOBAL-TEMPLATE.json.gz": { + "bytes": 2055625, + "git_blob": "5327fc2f4e8ea82ed356c94ff040d23fc73c731f", + "sha256": "1d31424c4e27e26a35a9932ca778e43f1f3577589275422cc642aa68b31112db" + }, + "research/gmx-t74-borrow43/ORDER.json": { + "bytes": 4573, + "git_blob": "7409c4df1092241729739596c7648bda504e6aad", + "sha256": "519d1d5dbb997a219fcfcad34c0b03e7838bef24199784d7e964fa10090f66e1" + }, + "research/gmx-t74-borrow43/OWNERS.json.gz": { + "bytes": 3384495, + "git_blob": "fc874cb553af5b984e34c1d8696d2213d7458f8f", + "sha256": "5a8c9a18c21f635563c9a6b6a433bcb1e804175ef23d677459033344aa2bd4e6" + }, + "research/gmx-t74-borrow43/PARENT-LIFT-RECEIPT.json": { + "bytes": 487, + "git_blob": "0c6ccc1f8957d0ca97877e81ab83fd06eb10dcad", + "sha256": "925a2c2bae44d69c0ac9d930abe63cf73bf22765b49e6a1eb9d7a0f5f0f4ea84" + }, + "research/gmx-t74-borrow43/PLAN.json": { + "bytes": 1682123, + "git_blob": "ea617c2fad0a9581723e9c05bb111631a5af7f17", + "sha256": "334709f65761928e02f83bf1f2e7f537d783381bab6689669bffe111b8f60bea" + }, + "research/gmx-t74-borrow43/PROFILE.json": { + "bytes": 83, + "git_blob": "48249b94604daccf0552c0c3b2489716344f7ff2", + "sha256": "7012a58b4078d41e3b4412204d7dfdf9eb401bfe7da5429002150bdfc3558865" + }, + "research/gmx-t74-borrow43/SPEC.json": { + "bytes": 76945, + "git_blob": "5158049eeff8240d59528441d3f1fcfd8f420783", + "sha256": "da49a85190eac2b553fe982ed295b15fcde6d2dd449d976b503de25c277f2029" + }, + "research/gmx-t74-borrow43/evidence/INDEPENDENT.json": { + "bytes": 4318, + "git_blob": "16bb558f2472df730076a8163454c6f70b9e9fe3", + "sha256": "78cd00f832ed3c0a4b0e0d202095f7beb6111eaeb4457849d5bb920e983098a0" + }, + "research/gmx-t74-borrow43/inputs/DISPATCH.json": { + "bytes": 12151, + "git_blob": "613e01490d24a39e551ba75915320617003c1c81", + "sha256": "b7b971df9dce435556145df307e2bb5138d87e5aa933f1fe61fcc5b5163301c4" + }, + "research/gmx-t74-borrow43/inputs/GLOBAL-TEMPLATE.json.gz": { + "bytes": 1124331, + "git_blob": "114808c32b1799da53524bdc25cea67efb60009e", + "sha256": "21297b20f1f2dc76eb9dd8124416068c3cb096bab9df17fa4da19bc68dfe082e" + }, + "research/gmx-t74-borrow43/inputs/OWNERS.json.gz": { + "bytes": 1864195, + "git_blob": "34fa5d69aaa2574af60f1e8f7d43640b03698bca", + "sha256": "3a56f578b2db5647cf6cb811bc6263c7a802ae3e31e9e672596d43185e4e5c9f" + }, + "research/gmx-t74-borrow43/inputs/PLAN.json": { + "bytes": 2687598, + "git_blob": "5af9dd20821ae5b79778d85cd7183873c5999732", + "sha256": "163431bf8d3bc0d9b894994b1a3cfa7947367b2243b3c0b3a97d740195a1cb08" + }, + "research/gmx-t74-borrow43/inputs/SPEC.json": { + "bytes": 50653, + "git_blob": "c15990ace61b32f7233c82580d720e3097a900c3", + "sha256": "2daedf579c8abf30ceed79fe739bdd7659fce4c514de3894a028933143265d98" + }, + "research/gmx-t74-borrow43/new/BORROW-PROVIDERS.json": { + "bytes": 6427, + "git_blob": "42563d218a5c7321f686c1cf9b98e75883d85abc", + "sha256": "8324fcf5fd652af9793c1acbc5f5099ee0d2f1eefa0adfbb8335f3d31d891da2" + }, + "research/gmx-t74-borrow43/new/PLAN.json": { + "bytes": 7189365, + "git_blob": "7cacd857edd0f29be5bd2ca9590a17fed4da17ba", + "sha256": "bf1abd33c8ba946371cae37e021747343ef6603a31297bcc962197cc23f535e2" + }, + "research/gmx-t74-borrow43/new/PROFILE.json": { + "bytes": 85, + "git_blob": "3e103605dd46c8754028056eb9dde9a73b9bfdca", + "sha256": "50fcc0960a47f6d35064d3b55ea6dcb4cebbd305aec215c8034f626718595538" + }, + "research/gmx-t74-borrow43/new/SPEC.json": { + "bytes": 83591, + "git_blob": "2431d1cebbb2e155356d2da160d60808498bc33d", + "sha256": "bd091ed9e7f4939d06abb467d0d2c56ce0f34ba800d74132669f7b667e125d2d" + }, + "research/gmx-t74-borrow43/new/borrow/receipts/AUDIT-43base.json": { + "bytes": 1446, + "git_blob": "65728eff3ef61c275c873b58f0f8cebc095ef6f9", + "sha256": "9af87b149b8efa58e2454541dd1c5aef86d893c71ec488ae69fb8680c2f7936e" + }, + "research/gmx-t74-borrow43/new/borrow/receipts/AUDIT-43extra.json": { + "bytes": 1447, + "git_blob": "f9c2401401612b3b0b6e652e142e65bceadc1170", + "sha256": "849fbe9b9267180ba914237d751b118b4539731249c4482e6264d4772932fd2d" + }, + "research/gmx-t74-borrow43/new/borrow/words/BORROW-WORD-43base.json.gz": { + "bytes": 69989, + "git_blob": "448dd795adba29392a90b34aa3f1b1b796c7e0bd", + "sha256": "9492a5537fb87d9ca98dffcd0230f7625b3789744fa94e2f18acf23d91d998b5" + }, + "research/gmx-t74-borrow43/new/borrow/words/BORROW-WORD-43extra.json.gz": { + "bytes": 69991, + "git_blob": "2b51ba96256283bbc5578f99b694c50edd8a0e35", + "sha256": "87d51f5298101d5947f45c43ee02f0ec45d6acbddabb808d0d02db1eaf063734" + }, + "research/gmx-t74-borrow43/new/extra-word-566.json.gz": { + "bytes": 57440, + "git_blob": "e86142b352466f54a3da38c96a6e1484145c3b5c", + "sha256": "cd417b904408c221d9840d08faff8af040cc4207f9804284f2f5375d21298a62" + }, + "research/gmx-t74-borrow43/new/gauge44-word-566.json.gz": { + "bytes": 57438, + "git_blob": "76c01583a0286cddb0f71e0cb13077e4317104f6", + "sha256": "eeb6a236ed0ea8873b8800947d0cd19c36a6fcfdf857fc42913cb45cd984f219" + }, + "research/gmx-t74-borrow43/vendor/pr1297/PROFILE.json": { + "bytes": 104, + "git_blob": "cb96b9560ef7f08512601da484ca3b4550d5c602", + "sha256": "d9bbe0d73ba005749615915a2d884819a6b141e3402d9e7f87f4592a2d27af99" + }, + "research/gmx-t74-borrow43/vendor/pr1297/extra-word.json.gz": { + "bytes": 57374, + "git_blob": "4d464f55a2955e5c832b5ce789d5d0e0a39fb4e1", + "sha256": "7b0e9fbda32749aabc7e156d9fe09bceb0624a178628fe69e5dfea783462f905" + }, + "research/gmx-t74-borrow43/vendor/pr1297/gauge44-word.json.gz": { + "bytes": 57371, + "git_blob": "eacf8c773cb50637f93a762342b3b5f0853fe29a", + "sha256": "e8e6e78ff7422275c38324499e1f33fb2ecd30de9503aef2b8f1ee80d8c4df8e" + } + }, + "not_checked": [ + "local paid profiles of the borrowed words (taken from the word reports; recount = task A)", + "X2 pending-axis disjointness and 73-axis charts (DATA-PHASES.json is not shipped outside the vendored tarball)", + "native LOCAL-PROGRAMS, controller emission, invoice and prefix bits", + "physical location of the 76 zero buffers (not stated in the shipped text)" + ], + "object": { + "head": "b479fc5567bc09ab9185bffe89b62594f36d74e5", + "owners": "OWNERS.json.gz", + "package": "research/gmx-t74-borrow43", + "pr": 2269 + }, + "parent_positive_control": { + "bins": 74592, + "calls": 333, + "cross_replica_roles": 148150, + "deficit": 11840, + "helpers_per_call": 480, + "hosted_families": 27283, + "hosted_families_with_slices_of_two_or_more_children": 19359, + "hosted_width": 1244254, + "idle": { + "1": 2, + "48": 11374 + }, + "idle_capacity": 1790208, + "idle_mass": 545954, + "idle_remainders": 11376, + "live": 33152, + "local_mass": 1862302, + "max_child": 48, + "occupied_bins": 63218, + "package_path": "research/gmx-t74-borrow43/inputs/OWNERS.json.gz", + "profile": { + "1": 779556, + "2": 169496, + "3": 138694, + "4": 42458, + "48": 11374, + "5": 27306, + "8": 2664 + }, + "rank_mass": 2408256, + "roles": 159840, + "windows_equal_to_plan": true + }, + "physical": { + "W": 66304, + "charged_physical_change": -43, + "charged_physical_post": 66751, + "charged_physical_pre": 66794, + "charges": { + "parent_charged": { + "physical": 112178, + "row_coefficient": 19547, + "stock_bits": 2645 + }, + "parent_plus_zero_buffers": { + "physical": 112254, + "row_coefficient": 19547, + "stock_bits": 2645 + }, + "post_borrow_charged": { + "physical": 66751, + "row_coefficient": 19545, + "stock_bits": 2644 + }, + "post_borrow_plus_zero_buffers": { + "physical": 66827, + "row_coefficient": 19545, + "stock_bits": 2644 + }, + "pre_borrow_charged": { + "physical": 66794, + "row_coefficient": 19545, + "stock_bits": 2644 + } + }, + "formula_reproduces_independent_receipt": { + "physical": 66794, + "row": 19545, + "stock_bits": 2644 + }, + "helpers_post": 437, + "helpers_pre": 480, + "max_physical_with_same_stock_bits": 95181, + "parent_geometry_unchanged": true, + "parent_physical": 112178, + "payload_bits": 2048, + "row_limit": 20161, + "spec_charge": "physical = data families W + 8 centres + R local helpers (reserved tableau) + 2 coefficient work; parent_physical = parent live + 504 + 8 + 2 (inherited dedicated-bank parent, R0 = 504)", + "zero_buffer_note": "Each borrowed word allocates one private FULL-frame zero buffer per hyperplane-ended live helper (76) inside its final cleanup and frees it; calls are serial, so dedicating them costs 76 families once, not per call.", + "zero_buffers_in_physical_identity": false, + "zero_buffers_per_call": { + "extra": 76, + "gauge44": 76 + } + }, + "scope": "Finite recount of the shipped hosting fill under the stated rules. Not a proof of the conditional kappa; local words, invoice, moments and outer assembly are outside this check.", + "stale_evidence": { + "independent_local_profiles": { + "extra": { + "1": 2338, + "2": 512, + "3": 418, + "4": 126, + "5": 82, + "8": 8 + }, + "gauge44": { + "1": 2346, + "2": 504, + "3": 414, + "4": 130, + "5": 82, + "8": 8 + } + }, + "independent_owner_blob_in_package_tree": false, + "independent_owner_sha256": [ + "cdfdcdec09592b4fd296ec49efe38573c1a61ecb8385b538ce801ee29355695b" + ], + "independent_profile_identity_holds": true, + "independent_rank_mass_identity": true, + "independent_roles": 319680, + "independent_width_per_call": { + "extra": 3738, + "gauge44": 3734 + }, + "package_tree_blobs": 418, + "shipped_owner_sha256": "5a8c9a18c21f635563c9a6b6a433bcb1e804175ef23d677459033344aa2bd4e6", + "shipped_roles": 291042, + "spec_owner_blob_in_package_tree": false, + "top_level_spec_expected_hosted": 319680, + "top_level_spec_is_pre_borrow": true, + "top_level_spec_owners_sha256": "cdfdcdec09592b4fd296ec49efe38573c1a61ecb8385b538ce801ee29355695b" + }, + "status": "PASS_INDEPENDENT_T74_BORROW43_FILL_RECOUNT", + "windows": { + "bridges": 666, + "child_ranks": { + "0": 16, + "1": 8, + "10": 48, + "11": 8, + "12": 48, + "13": 48, + "14": 32, + "15": 32, + "16": 16, + "17": 16, + "2": 16, + "3": 8, + "4": 32, + "5": 8, + "6": 32, + "7": 8, + "8": 48, + "9": 8 + }, + "equal_to_plan": true, + "expanded_events": 2220, + "rebuilt": 1332, + "swept_children_without_capacity": [ + 18, + 19 + ] + } +} diff --git a/research/t74-borrow43-independent-check/price_check.py b/research/t74-borrow43-independent-check/price_check.py new file mode 100644 index 0000000000..708753e770 --- /dev/null +++ b/research/t74-borrow43-independent-check/price_check.py @@ -0,0 +1,880 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: Apache-2.0 +"""Independent price check (task C) of PR #2269: global profile and an exact moment-root bracket. + +Object: CrocSwap/integer-mult-bounds PR #2269 (jeremykothe2), head +b479fc5567bc09ab9185bffe89b62594f36d74e5, package research/gmx-t74-borrow43/. +The package's complex saving is b = (certified native complex endpoint) - 1e-100 += 0.0016962471390584742207696... (outer/B.json). The claimed conditional kappa +(outer/OUTER-CLAIM.json) is derived from b by the inherited PR1673/PR1786 outer +ledger. + +Credit: PR2269 (jeremykothe2) for the borrow43 package, its profile, endpoints +and ledger; PR2226 (Cinna Davis / 1337isnot1337, with OpenAI Codex) for +anticipatory dirty borrowing; PR2260 (Dugongue) for concurrent application of +PR2226; the T74 lineage PR1319/PR1297 (Rohan Arun), PR1625 (mdumitrean), the +pivot-554 kernel (PR1672 lineage); the retained PR547/PR548/PR559 moment +engines and the icekylinx (Zhihao Chen) / eumemic exact-assembly and +independent-checker lineage. This file shares no code with any of them. It was +written from their written specification (package README, new/SPEC.json, +outer/RETUNED-SLACKS.md, outer/FINE-PADDING-COMPOSITION.md and the moment +formula as stated in code/assemble.py); no package code is imported or run. + +The only imported code is our own: words_check.py (task A) and fill_check.py +(task B), loaded from this directory by explicit file path. + +Prepared with substantial AI assistance (Claude Code, Anthropic); Apache-2.0. + +Usage: python3 -I -B price_check.py [--repo PATH | --blob-dir DIR] [--out [RECEIPT.json]] +--blob-dir DIR: an exported copy of the package, DIR/ +(for example `git archive research/gmx-t74-borrow43 | tar -x`, then +DIR = /research/gmx-t74-borrow43). The receipt (default +price_check.receipt.json) must be next to this script. The final stdout line +starts with PASS_T74_BORROW43_PRICE_INDEPENDENT or FAIL_T74_BORROW43_PRICE_INDEPENDENT. + +MODEL (stated precisely; also written to the receipt field "model"). + 1. Local paid profiles P_gauge44 = profile of BORROW-WORD-43base and + P_extra = profile of BORROW-WORD-43extra, recounted by words_check.frame_check + (nested frame climbs + COPY charges; warps checked by words_check.check_all_warps). + 2. Idle remainders: recounted by the fill_check pipeline from OWNERS.json.gz + (rank minus occupied cells for every (owner replica, child, port) bin). + 3. Composition (new/SPEC.json expected.global_profile; code/assemble.py sums the + dispatched providers' paid profiles over the 666 calls and adds the idle + remainders): H = sum over calls of P_dispatch(call) + idle + = 249 P_gauge44 + 417 P_extra + idle, with the counts taken from DISPATCH.json. + 4. Moment (m = 73, W = 66304 live data families): + mu(a) = sum_r n_r (r/m)^(1-a) / W = sum_r n_r r/(m W) exp(a log(m/r)). + Native complex side (evidence/ASSEMBLY.json surcharge_model complex = false; + code/assemble.py checks complex_lower with surcharge off): no surcharge. + This is the side of new/SPEC.json complex_lower and of outer/B.json b. + Conservative complex side (surcharge on): mu(a) + 32 m N m^a / (10^16 W), + N = sum_r n_r (number of children). It prices conservative_complex_lower. + Every rank satisfies 0 < r < m, so each term is strictly increasing in a; + the root rho is the unique a > 0 with mu(a) = 1 (mu(0) = mass/(mW) < 1). + 'accept a' means mu(a) < 1 is certified; 'reject a' means mu(a) > 1 is certified. + 5. Certified evaluation (exact integers on the grid 2^-PREC, PREC = 800 bits, + every rounding directed): log x = k log 2 + 2 atanh(z) with 2^k <= x < 2^(k+1), + z = (x - 2^k)/(x + 2^k) in [0, 1/3), log 2 = 2 atanh(1/3); atanh(z) by its + positive series plus the remainder bound z^(2N+1)/((2N+1)(1-z^2)); exp(x) for + 0 <= x < 1 by its positive Taylor series (lower: truncated sum) plus the + remainder bound x^N/N! (N+1)/(N+1-x) (upper). mu(a) is then enclosed by an + exact rational interval; comparisons with 1 are exact. Self-tests: log 2 by a + second formula (18 atanh(1/26) - 2 atanh(1/4801) + 8 atanh(1/8749)), log(m/r) + against log m - log r, and exp(log 2) must enclose 2. + 6. Root bracket: bisection on the decimal grid 10^-130 starting from [0, 1/100], + using only certified accept/reject decisions; it does not use any claimed value. +""" + +import sys + +if sys.flags.optimize: + sys.stdout.write('refusing to run under python -O\nFAIL_T74_BORROW43_PRICE_INDEPENDENT\n') + sys.exit(2) + +import argparse +import hashlib +import importlib.util +import json +import os +import subprocess +import time +from collections import Counter +from fractions import Fraction + +PASS_LINE = 'PASS_T74_BORROW43_PRICE_INDEPENDENT' +FAIL_LINE = 'FAIL_T74_BORROW43_PRICE_INDEPENDENT' +COMMIT = 'b479fc5567bc09ab9185bffe89b62594f36d74e5' +PKG = 'research/gmx-t74-borrow43/' +HERE = os.path.dirname(os.path.abspath(__file__)) +DEFAULT_REPO = os.path.dirname(os.path.dirname(HERE)) +RECEIPT_NAME = 'price_check.receipt.json' + +# package-relative path -> (git blob id, sha256 of the blob bytes); asserted at run time +PINS = { + 'PROFILE.json': ('48249b94604daccf0552c0c3b2489716344f7ff2', + '7012a58b4078d41e3b4412204d7dfdf9eb401bfe7da5429002150bdfc3558865'), + 'new/PROFILE.json': ('3e103605dd46c8754028056eb9dde9a73b9bfdca', + '50fcc0960a47f6d35064d3b55ea6dcb4cebbd305aec215c8034f626718595538'), + 'new/SPEC.json': ('2431d1cebbb2e155356d2da160d60808498bc33d', + 'bd091ed9e7f4939d06abb467d0d2c56ce0f34ba800d74132669f7b667e125d2d'), + 'outer/B.json': ('a66501df3178012477b4c54fb6888e986b52a25e', + '631d89563be62a156c2b0119f9d4ba5a31cbf36380768bf8748825cf361bb525'), + 'outer/OUTER-CLAIM.json': ('f1feaefc27028e590fa7992d273c137897b379eb', + 'ffa05de3c8d7cb7de0114d25df7250909581f4a2c0ce68c8d20eb821bf67f0e5'), + 'outer/LEDGER.json': ('3644673ab40b7b3595e94bbb7e118924a1cc48a1', + 'eab3f0cbd5b5c45c76cee3e2daefd73c994bf7cfa80be118c67e6fab6106a05b'), + 'README.md': ('b555bc54dc661658e4d5fcbc5e3bd6503d7af4bd', + '2bf8d14e32ea03c614107eccfcce2422287a3a0552ab90f926b464d55767afcf'), + 'CLAIM.json': ('214e02514d2aba5c3977dae6285bf925c685db3e', + 'bbcb4b72c86e4ca668256f8bfa6e35c1830a6e0edd77b7ab6230d8a3a7d7d31e'), + 'evidence/ASSEMBLY.json': ('6e9debfd552d18846fe55e4cbe6c59a37447b035', + '5d9eb1ce551386024b5b6894836f81ed03a83d2e0c0bd0e02e3f6410a596bb2c'), + 'PRICE.json': ('c41b950145014912b2b2d176cb4972408c95e23e', + 'c5ec535fd9edbdec7b64edd5a8b862edb1a7f173d411dacb279172659573e16a'), +} + +# Claims under test, written here from the README / scout notes (not read from the files). +CLAIMS = dict( + local={'gauge44': {1: 2351, 2: 501, 3: 414, 4: 129, 5: 42, 8: 8}, + 'extra': {1: 2339, 2: 509, 3: 418, 4: 125, 5: 42, 8: 8}}, + local_mass=5385, + counts={'gauge44': 249, 'extra': 417}, + idle={1: 23976, 3: 8673, 5: 813, 7: 150, 48: 24479}, + mass=4816512, m=73, W=66304, T=74, calls=666, max_child=48, + b_decimal_prefix='0.0016962471390584742207696', +) +WORD_OF = {'gauge44': 'base', 'extra': 'extra'} # provider id -> BORROW-WORD-43 + +ONE_Q = Fraction(1) + + +class Reject(Exception): + def __init__(self, check, msg): + Exception.__init__(self, '[%s] %s' % (check, msg)) + self.check = check + self.msg = msg + + +def need(cond, check, msg): + if not cond: + raise Reject(check, msg) + + +# ---------------------------------------------------------------------------- +# Inputs +# ---------------------------------------------------------------------------- + +def git_blob_id(data): + h = hashlib.sha1() + h.update(b'blob %d\0' % len(data)) + h.update(data) + return h.hexdigest() + + +def verify_pin(rel, data): + blob, sha = PINS[rel] + need(git_blob_id(data) == blob, 'pin', 'git blob id mismatch for ' + rel) + need(hashlib.sha256(data).hexdigest() == sha, 'pin', 'sha256 mismatch for ' + rel) + + +def read_inputs(repo, blob_dir): + raw, record = {}, {} + for rel in sorted(PINS): + blob, sha = PINS[rel] + if blob_dir is None: + got = subprocess.run(['git', '-C', repo, 'rev-parse', '--verify', COMMIT + ':' + PKG + rel], + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + need(got.returncode == 0, 'pin', 'cannot resolve %s at %s in %s' % (PKG + rel, COMMIT, repo)) + need(got.stdout.decode().strip() == blob, 'pin', PKG + rel + ' does not resolve to the pinned blob') + got = subprocess.run(['git', '-C', repo, 'cat-file', 'blob', blob], + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + need(got.returncode == 0, 'pin', 'cannot read blob ' + blob) + data = got.stdout + else: + src = os.path.join(blob_dir, rel) + need(os.path.isfile(src), 'pin', 'exported blob missing: ' + src) + with open(src, 'rb') as fh: + data = fh.read() + verify_pin(rel, data) + raw[rel] = data + record[PKG + rel] = dict(git_blob=blob, sha256=sha, bytes=len(data)) + return raw, record + + +def as_json(raw, rel): + return json.loads(raw[rel].decode('utf-8')) + + +def load_sibling(name): + """Load our own task A/B module from this directory by explicit path (python -I drops the script dir).""" + path = os.path.join(HERE, name + '.py') + spec = importlib.util.spec_from_file_location('t74b43_' + name, path) + mod = importlib.util.module_from_spec(spec) + spec.loader.exec_module(mod) + with open(path, 'rb') as fh: + digest = hashlib.sha256(fh.read()).hexdigest() + return mod, digest + + +def int_profile(mapping, check, what): + out = {} + for k, v in mapping.items(): + need(type(v) is int and v > 0 and str(int(k)) == str(k), check, what + ': bad profile entry') + out[int(k)] = v + return out + + +def plain(prof): + return dict((str(r), prof[r]) for r in sorted(prof) if prof[r]) + + +def mass_of(prof): + return sum(r * n for r, n in prof.items()) + + +# ---------------------------------------------------------------------------- +# Certified rational enclosures (integers on the grid 2^-PREC, directed rounding) +# ---------------------------------------------------------------------------- + +PREC = 800 +ONE = 1 << PREC +MAX_TERMS = 4 * PREC + + +def cdiv(a, b): + """ceil(a / b) for integers, b > 0.""" + return -((-a) // b) + + +def atanh_enclosure(p, q, terms=None, tail=True): + """Integers (lo, hi) with lo <= 2^PREC atanh(p/q) <= hi, for 0 <= p/q <= 1/3. + atanh(z) = sum_j z^(2j+1)/(2j+1) (positive terms). Lower: floored partial sum. + Upper: ceiled partial sum of N terms + z^(2N+1)/((2N+1)(1-z^2)) >= the remainder. + terms/tail exist only for the negative controls (fixed truncation, remainder dropped).""" + need(q > 0 and 0 <= 3 * p <= q, 'evaluator', 'atanh argument outside [0, 1/3]') + if p == 0: + return 0, 0 + p2, q2 = p * p, q * q + pl, pu = (ONE * p) // q, cdiv(ONE * p, q) # bounds of 2^PREC z^(2j+1), j = 0 + sl = su = 0 + j = 0 + while (pl > 0) if terms is None else (j < terms): + need(j < MAX_TERMS, 'evaluator', 'atanh series did not terminate') + sl += pl // (2 * j + 1) + su += cdiv(pu, 2 * j + 1) + pl = (pl * p2) // q2 + pu = cdiv(pu * p2, q2) + j += 1 + if tail: # pu >= 2^PREC z^(2j+1): remainder <= pu / ((2j+1)(1 - z^2)) = pu q^2 / ((2j+1)(q^2 - p^2)) + su += cdiv(pu * q2, (2 * j + 1) * (q2 - p2)) + return sl, su + + +_LOG2 = [] + + +def log2_enclosure(): + if not _LOG2: + lo, hi = atanh_enclosure(1, 3) + _LOG2.append((2 * lo, 2 * hi)) + return _LOG2[0] + + +def log_enclosure(p, q): + """Integers (lo, hi) enclosing 2^PREC log(p/q) for p/q >= 1.""" + need(p >= q > 0, 'evaluator', 'log argument below 1') + k = (p // q).bit_length() - 1 # 2^k <= p/q < 2^(k+1) + a, b = p, q << k # y = a/b in [1, 2) + zl, zu = atanh_enclosure(a - b, a + b) + l2l, l2u = log2_enclosure() + return k * l2l + 2 * zl, k * l2u + 2 * zu + + +def exp_enclosure(xl, xu, terms=None, tail=True): + """Integers (lo, hi) with lo <= 2^PREC exp(x) <= hi for every x in [xl, xu] / 2^PREC, 0 <= xl <= xu < 2^PREC. + Lower: floored Taylor partial sum at xl (positive terms). Upper: ceiled partial sum at xu of N terms plus + t_N (N+1)/(N+1-x) with t_N >= 2^PREC x^N/N!, which bounds sum_{i>=N} x^i/i! for 0 <= x < N+1. + terms/tail exist only for the negative controls (fixed truncation of both sums, remainder dropped).""" + need(0 <= xl <= xu < ONE, 'evaluator', 'exp argument outside [0, 1)') + t = s = ONE + j = 1 + while (t > 0) if terms is None else (j < terms): + need(j < MAX_TERMS, 'evaluator', 'exp series did not terminate') + t = ((t * xl) >> PREC) // j + s += t + j += 1 + lo = s + t = s = ONE + j = 1 + while True: + need(j < MAX_TERMS, 'evaluator', 'exp series did not terminate') + t = cdiv(cdiv(t * xu, ONE), j) # >= 2^PREC x^j / j! + if (t <= 1) if terms is None else (j >= terms): + break + s += t + j += 1 + if tail: + s += cdiv(t * (j + 1) * ONE, (j + 1) * ONE - xu) + return lo, s + + +class Evaluator(object): + """mu(a) enclosures for one profile; logs are computed once per rank.""" + + def __init__(self, profile, m, W, surcharge=False): + need(all(type(r) is int and 0 < r < m and type(n) is int and n > 0 for r, n in profile.items()), + 'moment', 'every child must have 0 < rank < m') + self.profile = dict(profile) + self.m, self.W, self.surcharge = m, W, surcharge + self.N = sum(profile.values()) + self.logs = dict((r, log_enclosure(m, r)) for r in sorted(profile)) + self.logm = log_enclosure(m, 1) + + def bounds(self, a): + """Exact rationals lo <= mu(a) <= hi (plus the surcharge if enabled).""" + a = Fraction(a) + need(a >= 0, 'moment', 'negative saving') + an, ad = a.numerator, a.denominator + slo = shi = 0 + for r in sorted(self.profile): + ll, lu = self.logs[r] + el, eu = exp_enclosure((an * ll) // ad, cdiv(an * lu, ad)) + n = self.profile[r] + slo += n * r * el + shi += n * r * eu + lo = Fraction(slo, self.m * self.W * ONE) + hi = Fraction(shi, self.m * self.W * ONE) + if self.surcharge: + ll, lu = self.logm + el, eu = exp_enclosure((an * ll) // ad, cdiv(an * lu, ad)) + c = 32 * self.m * self.N + lo += Fraction(c * el, 10 ** 16 * self.W * ONE) + hi += Fraction(c * eu, 10 ** 16 * self.W * ONE) + need(lo <= hi, 'evaluator', 'empty enclosure') + return lo, hi + + def side(self, a): + lo, hi = self.bounds(a) + if hi < 1: + return -1 + if lo > 1: + return 1 + return 0 + + def root_bracket(self, digits): + """Bisection on the 10^-digits grid from [0, 1/100] with certified decisions only.""" + scale = 10 ** digits + lo, hi = 0, scale // 100 + need(self.side(Fraction(lo, scale)) < 0, 'moment', 'mu(0) >= 1: no positive saving') + need(self.side(Fraction(hi, scale)) > 0, 'moment', 'mu(1/100) <= 1') + steps, undecided = 0, None + while hi - lo > 1: + mid = (lo + hi) // 2 + s = self.side(Fraction(mid, scale)) + steps += 1 + if s < 0: + lo = mid + elif s > 0: + hi = mid + else: + undecided = mid + break + return Fraction(lo, scale), Fraction(hi, scale), steps, undecided + + +# ---------------------------------------------------------------------------- +# Display helpers (display only; never used for a decision) +# ---------------------------------------------------------------------------- + +def sci(x, sig=22, up=False): + """x rounded to `sig` significant digits toward +inf (up) or -inf; display only.""" + x = Fraction(x) + if x == 0: + return '0' + neg = x < 0 + ax = -x if neg else x + e = len(str(ax.numerator)) - len(str(ax.denominator)) + while ax < Fraction(10) ** e: + e -= 1 + while ax >= Fraction(10) ** (e + 1): + e += 1 + y = ax * Fraction(10) ** (sig - 1 - e) + toward_larger_magnitude = (up and not neg) or (neg and not up) + k = cdiv(y.numerator, y.denominator) if toward_larger_magnitude else y.numerator // y.denominator + ds = str(k) + e += len(ds) - sig + return '%s%s.%sE%+d' % ('-' if neg else '', ds[0], ds[1:sig], e) + + +def dec(x, digits): + """Exact decimal string of a rational with denominator dividing 10^digits.""" + x = Fraction(x) + y = x * 10 ** digits + need(y.denominator == 1, 'display', 'not on the decimal grid') + n = y.numerator + s = str(abs(n)).rjust(digits + 1, '0') + return ('-' if n < 0 else '') + s[:-digits] + '.' + s[-digits:] + + +def interval(lo, hi): + return [sci(lo, up=False), sci(hi, up=True)] + + +# ---------------------------------------------------------------------------- +# Composition +# ---------------------------------------------------------------------------- + +def compose(local, counts, idle): + H = Counter() + for pid in sorted(counts): + for r, n in local[pid].items(): + H[r] += counts[pid] * n + for r, n in idle.items(): + H[r] += n + return dict((r, H[r]) for r in sorted(H) if H[r]) + + +def check_composition(H, sources): + for name, prof in sources: + need(H == prof, 'compose.profile', 'composed profile %s != %s %s' % (plain(H), name, plain(prof))) + + +def check_mass(H, m, W, T, calls, deficit_claim): + mass = mass_of(H) + need(W == 896 * T, 'compose.mass', 'W != 896 T (live data families)') + need(calls == 9 * T, 'compose.mass', 'calls != 9 T') + need(m * W - mass == deficit_claim == 320 * T, 'compose.mass', 'deficit m W - mass != 320 T') + need(mass == (m - 1) * W + 64 * calls, 'compose.mass', 'mass != (m-1) W + 64 calls') + need(m * m > 2 * max(H) ** 2, 'compose.mass', 'halving guard m^2 > 2 maxchild^2') + return mass + + +# ---------------------------------------------------------------------------- +# Negative-control harness +# ---------------------------------------------------------------------------- + +def expect_reject(name, target, fn, results): + try: + detail = fn() + except Reject as e: + ok = e.check == target + results.append(dict(name=name, target=target, rejected_by=e.check, ok=ok, detail=e.msg[:300])) + return ok + results.append(dict(name=name, target=target, rejected_by=None, ok=False, detail=str(detail)[:300])) + return False + + +def require_accept(ev, a, what): + lo, hi = ev.bounds(a) + need(hi < 1, 'moment.accept', '%s: mu - 1 in %s is not certified < 0' % (what, interval(lo - 1, hi - 1))) + return lo, hi + + +def require_reject(ev, a, what): + lo, hi = ev.bounds(a) + need(lo > 1, 'moment.reject', '%s: mu - 1 in %s is not certified > 0' % (what, interval(lo - 1, hi - 1))) + return lo, hi + + +# ---------------------------------------------------------------------------- +# Main +# ---------------------------------------------------------------------------- + +def run(args, receipt): + t0 = time.time() + raw, record = read_inputs(args.repo, args.blob_dir) + receipt['pins'] = record + print('pins: %d package blobs verified (sha256 + git blob id)' % len(record), flush=True) + W_mod, w_sha = load_sibling('words_check') + F_mod, f_sha = load_sibling('fill_check') + receipt['imported_own_modules'] = {'words_check.py': w_sha, 'fill_check.py': f_sha} + + # ---- 1. local profiles recounted by task A code + js, wpins, _ = W_mod.load_inputs(args.repo, args.blob_dir) + local, local_mass, canon, word_widths = {}, {}, {}, {} + for pid in ('gauge44', 'extra'): + tag = WORD_OF[pid] + P = W_mod.parse_borrow(js['word_' + tag]) + W_mod.check_all_warps(P) + fr = W_mod.frame_check(P) + local[pid] = dict((r, n) for r, n in sorted(fr['paid'].items()) if n) + need(dict((r, n) for r, n in fr['copies'].items() if n) == {8: 8} and not fr['climbs'].get(8), 'local', + pid + ': the rank-8 entries must be exactly the 8 COPY children') + local_mass[pid] = fr['mass'] + word_widths[pid] = list(fr['widths']) + C = W_mod.parse_canonical(js['canon_' + tag]) + frC = W_mod.frame_check(C) + canon[pid] = dict((r, n) for r, n in sorted(frC['paid'].items()) if n) + need(local[pid] == CLAIMS['local'][pid], 'local', '%s recount %s != claimed %s' % ( + pid, plain(local[pid]), plain(CLAIMS['local'][pid]))) + need(local_mass[pid] == mass_of(local[pid]) == CLAIMS['local_mass'], 'local', pid + ' local mass') + print('local profiles (words_check recount): gauge44 %s extra %s, mass %d each' % ( + plain(local['gauge44']), plain(local['extra']), CLAIMS['local_mass']), flush=True) + + # ---- 2. idle remainders recounted by task B code + try: + fblobs, frecord = F_mod.load_blobs(args.repo, args.blob_dir) + ctx, rows, helpers_info, extra = F_mod.borrow_case(fblobs) + sched = F_mod.derive_schedule(ctx) + fres = F_mod.run_pipeline(ctx, sched, rows) + except F_mod.CheckFailure as e: + raise Reject('fill', 'fill_check pipeline failed: ' + str(e)) + idle = dict((int(r), n) for r, n in fres['idle'].items()) + counts = dict(Counter(ctx['dispatch'].values())) + T, W, calls = ctx['T'], fres['live'], fres['calls'] + need(idle == CLAIMS['idle'], 'idle', 'recounted idle %s != claimed %s' % (plain(idle), plain(CLAIMS['idle']))) + need(counts == CLAIMS['counts'] and sum(counts.values()) == calls == CLAIMS['calls'], 'dispatch', + 'provider call counts %r' % counts) + need((T, W) == (CLAIMS['T'], CLAIMS['W']), 'geometry', 'T/W') + for pid in word_widths: # cross-module consistency: both recounts see the same 437 helper widths + need(word_widths[pid] == list(ctx['widths'][pid]), 'cross', pid + ' helper widths differ between A and B') + print('idle remainders (fill_check recount): %s; dispatch %s' % (plain(idle), counts), flush=True) + + # ---- 3. composition and mass identities + spec = as_json(raw, 'new/SPEC.json') + Bj = as_json(raw, 'outer/B.json') + ledger = as_json(raw, 'outer/LEDGER.json') + m = spec['geometry']['dimension'] + need(m == CLAIMS['m'] == ledger['m'], 'geometry', 'm') + need(spec['expected']['live'] == W == Bj['live'] == ledger['W'], 'geometry', 'W') + H = compose(local, counts, idle) + sources = [('PROFILE.json', int_profile(as_json(raw, 'PROFILE.json'), 'compose.profile', 'PROFILE.json')), + ('new/PROFILE.json', int_profile(as_json(raw, 'new/PROFILE.json'), 'compose.profile', 'new/PROFILE')), + ('new/SPEC.json expected.global_profile', + int_profile(spec['expected']['global_profile'], 'compose.profile', 'SPEC')), + ('outer/B.json profile', int_profile(Bj['profile'], 'compose.profile', 'B.json')), + ('outer/LEDGER.json profile', int_profile(ledger['profile'], 'compose.profile', 'LEDGER'))] + check_composition(H, sources) + deficit = 320 * T + mass = check_mass(H, m, W, T, calls, m * W - spec['expected']['rank_mass']) + need(mass == CLAIMS['mass'] == spec['expected']['rank_mass'], 'compose.mass', 'rank mass') + need(max(H) == CLAIMS['max_child'], 'compose.mass', 'max child') + need(H.get(8, 0) == 8 * calls and 8 not in idle and all(local[p].get(8) == 8 for p in local), 'compose.mass', + 'rank-8 children are exactly the 8 COPY children of each call') + receipt['composition'] = dict( + rule='H = sum over the %d dispatched calls of P_provider + idle = %d P_gauge44 + %d P_extra + idle' % ( + calls, counts['gauge44'], counts['extra']), + local_profiles=dict((p, plain(local[p])) for p in sorted(local)), local_mass=CLAIMS['local_mass'], + provider_counts=counts, idle=plain(idle), global_profile=plain(H), children=sum(H.values()), + equal_to=[s for s, _ in sources], mass=mass, live_W=W, m=m, T=T, calls=calls, deficit=deficit, + identities=['mass = m W - D = 73*66304 - 23680 = %d, D = 320 T' % mass, + 'mass = (m-1) W + 64 calls = 72*66304 + 64*666 = %d; the second term 42624 = W - D = 576 T ' + 'equals the mass of the 5328 = 8*666 rank-8 children, which are exactly the 8 COPY children ' + '(rank 8) of each call: mass - (COPY mass) = (m-1) W' % mass, + 'local: 666*5385 = %d; idle mass = %d' % (calls * CLAIMS['local_mass'], mass_of(idle)), + 'halving guard 73^2 = 5329 > 2*48^2 = 4608']) + print('composition: %s = PROFILE.json = new/PROFILE.json = SPEC = B.json = LEDGER; mass %d = 72W + 64*666' % ( + plain(H), mass), flush=True) + + # ---- 4. evaluator self-tests + l2 = log2_enclosure() + a1, a2, a3 = atanh_enclosure(1, 26), atanh_enclosure(1, 4801), atanh_enclosure(1, 8749) + l2b = (18 * a1[0] - 2 * a2[1] + 8 * a3[0], 18 * a1[1] - 2 * a2[0] + 8 * a3[1]) + + def log2_crosscheck(first, second): + need(max(first[0], second[0]) <= min(first[1], second[1]), 'evaluator.log2_crosscheck', + 'two enclosures of log 2 are disjoint') + return 'overlap' + + log2_crosscheck(l2, l2b) + need(l2[1] - l2[0] < 2 ** 12 and l2b[1] - l2b[0] < 2 ** 12, 'evaluator', 'log 2 enclosure too wide') + + def exp_log2_check(e): + need(e[0] <= 2 * ONE <= e[1], 'evaluator.exp_log2', 'exp(log 2) enclosure %s misses 2' % ( + interval(Fraction(e[0], ONE), Fraction(e[1], ONE)),)) + return 'contains 2' + + exp_log2_check(exp_enclosure(l2[0], l2[1])) + ranks = sorted(set(H) | {47}) + for r in ranks: + direct = log_enclosure(m, r) + lm, lr = log_enclosure(m, 1), log_enclosure(r, 1) + diff = (lm[0] - lr[1], lm[1] - lr[0]) + need(max(direct[0], diff[0]) <= min(direct[1], diff[1]), 'evaluator.log_crosscheck', + 'log(m/%d) disagrees with log m - log %d' % (r, r)) + need(direct[1] - direct[0] < 2 ** 16, 'evaluator', 'log enclosure too wide') + receipt['evaluator'] = dict( + grid_bits=PREC, log2=interval(Fraction(l2[0], ONE), Fraction(l2[1], ONE)), + log2_width_ulps=l2[1] - l2[0], + self_tests=['log 2 = 2 atanh(1/3) overlaps 18 atanh(1/26) - 2 atanh(1/4801) + 8 atanh(1/8749)', + 'exp(log 2) encloses 2', + 'log(73/r) overlaps log 73 - log r for r in %s' % ranks]) + print('evaluator: PREC=%d bits; self-tests PASS' % PREC, flush=True) + + # ---- 5. native moment: root bracket and the package endpoints + native = Evaluator(H, m, W, surcharge=False) + DIG = 130 + r_lo, r_hi, steps, undecided = native.root_bracket(DIG) + need(undecided is None and r_hi - r_lo == Fraction(1, 10 ** DIG), 'moment.bracket', 'bisection stalled') + X = spec['expected'] + complex_lower = Fraction(X['complex_lower']) + b = Fraction(Bj['b']) + b_above = Fraction(Bj['b_above_endpoint']) + + def b_identity(bb, bab): + need(bb == complex_lower - Fraction(1, 10 ** 100), 'claims.b_identity', 'b != complex_lower - 1e-100') + need(bab == complex_lower + Fraction(1, 10 ** 90), 'claims.b_identity', 'b_above != complex_lower + 1e-90') + return 'identity holds' + + b_identity(b, b_above) + need(Fraction(ledger['complex_lower_pinned']['rational']) == complex_lower and + Fraction(ledger['complex_lower_short']['rational']) == b, 'claims.b_identity', 'LEDGER endpoints') + need(dec(b, 100).startswith(CLAIMS['b_decimal_prefix']), 'claims.b_identity', 'b decimal prefix') + cl_acc = require_accept(native, complex_lower, 'complex_lower') + cl_rej = require_reject(native, complex_lower + Fraction(1, 10 ** 90), 'complex_lower + 1e-90') + b_acc = require_accept(native, b, 'b') + ba_rej = require_reject(native, b_above, 'b_above_endpoint') + coarse = Fraction((complex_lower * 10 ** 24).__floor__(), 10 ** 24) + co_acc = require_accept(native, coarse, 'coarse 1e-24 endpoint') + co_rej = require_reject(native, coarse + Fraction(1, 10 ** 24), 'coarse 1e-24 endpoint + 1e-24') + # task bracket: decimal 1e-21 cell containing b + b_lo = Fraction((b * 10 ** 21).__floor__(), 10 ** 21) + b_hi = b_lo + Fraction(1, 10 ** 21) + need(b_lo <= b <= b_hi and b_hi - b_lo <= Fraction(1, 10 ** 20), 'moment.bracket', 'task bracket shape') + tb_lo = require_accept(native, b_lo, 'b_lo') + tb_hi = require_reject(native, b_hi, 'b_hi') + # consistency of the independent root bracket with the claims (monotone mu) + need(complex_lower <= r_lo and r_hi <= complex_lower + Fraction(1, 10 ** 90), 'moment.bracket', + 'root bracket not inside (complex_lower, complex_lower + 1e-90)') + need(b_lo <= r_lo and r_hi <= b_hi, 'moment.bracket', 'root bracket not inside the task bracket') + # the package's own enclosure of mu(b) (outer/LEDGER.json native_moment) must overlap ours + led = [Fraction(v['rational']) for v in ledger['native_moment']] + need(max(led[0], b_acc[0]) <= min(led[1], b_acc[1]), 'moment.ledger', 'LEDGER native_moment(b) disjoint from ours') + gap_lo, gap_hi = r_lo - b, r_hi - b + receipt['native'] = dict( + model='mu(a) = sum_r n_r (r/73)^(1-a) / 66304, no surcharge (native complex side)', + root_bracket=[dec(r_lo, DIG), dec(r_hi, DIG)], root_bracket_width='1E-%d' % DIG, bisection_steps=steps, + complex_lower=dict(value=X['complex_lower'], accept=True, mu_minus_one=interval(cl_acc[0] - 1, cl_acc[1] - 1), + plus_1e90_reject=True, mu_minus_one_plus_1e90=interval(cl_rej[0] - 1, cl_rej[1] - 1)), + b=dict(value=Bj['b'], decimal=dec(b, 100), equals='complex_lower - 1e-100', accept=True, + mu_minus_one=interval(b_acc[0] - 1, b_acc[1] - 1), + ledger_native_moment_overlaps=True, + root_minus_b=interval(gap_lo, gap_hi)), + b_above_endpoint=dict(value=Bj['b_above_endpoint'], reject=True, + mu_minus_one=interval(ba_rej[0] - 1, ba_rej[1] - 1)), + coarse_1e24=dict(endpoint=dec(coarse, 24), accept=True, plus_1e24_reject=True), + task_bracket=dict(b_lo=dec(b_lo, 21), b_hi=dec(b_hi, 21), width='1E-21', b_lo_le_b_le_b_hi=True, + mu_minus_one_at_b_lo=interval(tb_lo[0] - 1, tb_lo[1] - 1), + mu_minus_one_at_b_hi=interval(tb_hi[0] - 1, tb_hi[1] - 1))) + print('native root in [%s, %s]' % (dec(r_lo, DIG)[:60] + '...', dec(r_hi, DIG)[:60] + '...'), flush=True) + print(' complex_lower accepted, complex_lower+1e-90 rejected; b accepted (root - b in %s); task bracket ' + '[%s, %s] PASS' % (interval(gap_lo, gap_hi), dec(b_lo, 21), dec(b_hi, 21)), flush=True) + + # ---- 6. conservative side (surcharge) and the model control of code/assemble.py + cons = Evaluator(H, m, W, surcharge=True) + c_lo, c_hi, c_steps, c_und = cons.root_bracket(DIG) + need(c_und is None, 'moment.bracket', 'conservative bisection stalled') + ccl = Fraction(X['conservative_complex_lower']) + cc_acc = require_accept(cons, ccl, 'conservative_complex_lower') + cc_rej = require_reject(cons, ccl + Fraction(1, 10 ** 90), 'conservative_complex_lower + 1e-90') + need(ccl <= c_lo and c_hi <= ccl + Fraction(1, 10 ** 90), 'moment.bracket', 'conservative bracket') + sur_b = require_reject(cons, b, 'native b under the conservative surcharge') + receipt['conservative'] = dict( + model='mu(a) + 32 m N m^a / (10^16 W), N = %d children' % sum(H.values()), + root_bracket=[dec(c_lo, DIG), dec(c_hi, DIG)], + conservative_complex_lower=dict(value=X['conservative_complex_lower'], accept=True, + mu_minus_one=interval(cc_acc[0] - 1, cc_acc[1] - 1), plus_1e90_reject=True), + native_b_rejected_with_surcharge=dict(reject=True, mu_minus_one=interval(sur_b[0] - 1, sur_b[1] - 1)), + native_minus_conservative_root=interval(r_lo - c_hi, r_hi - c_lo)) + print('conservative root in [%s...]; SPEC conservative_complex_lower accepted, +1e-90 rejected; native b ' + 'rejected under the surcharge (model control)' % dec(c_lo, DIG)[:40], flush=True) + + # ---- 7. claimed kappa as an arithmetic function of b (outer lemmas NOT checked) + oc = as_json(raw, 'outer/OUTER-CLAIM.json') + kappa = Fraction(oc['kappa_rational']) + need(Fraction(oc['kappa']) == kappa, 'claims.kappa', 'OUTER-CLAIM decimal != rational') + + def kappa_identity(kap, bb): + q = bb - Fraction(1, 10 ** 100) + eq = (1 - Fraction(2, 10 ** 100)) * q + floor136 = Fraction((eq * 10 ** 136).__floor__(), 10 ** 136) + need(kap == floor136 - Fraction(1, 10 ** 112), 'claims.kappa', + 'kappa != floor_1e-136((1-2e-100)(b-1e-100)) - 1e-112') + return 'identity holds' + + kappa_identity(kappa, b) + need(Fraction(ledger['rows']['struct_boundary_radix_union']['kappa']['rational']) == kappa, 'claims.kappa', + 'LEDGER kappa') + readme = raw['README.md'].decode('utf-8') + need(('**' + oc['kappa'] + '**') in readme, 'claims.kappa', 'README kappa string') + strict = Fraction(as_json(raw, 'CLAIM.json')['kappa']) + need(strict == Fraction(X['kappa']) == Fraction(ledger['online_final_kappa']['rational']), 'claims.kappa', + 'strict-assembly kappa') + need(0 < strict < kappa < b < r_lo, 'claims.kappa', 'ordering strict kappa < kappa < b < root') + claim = as_json(raw, 'CLAIM.json') + baseline = Fraction(claim['baseline_kappa']) + stated_gain = Fraction(claim['gain_over_claimed_leader']) + half_unit = Fraction(5, 10 ** 11) # half a unit of the 6th significant digit of 1.28346E-5 + need(abs(kappa - baseline - stated_gain) <= half_unit < abs(strict - baseline - stated_gain), 'claims.kappa', + 'CLAIM.json gain field') + doc_notes = [ + 'CLAIM.json kappa (%s...) is the strict-assembly kappa, while its gain_over_claimed_leader %s is the gain of ' + 'the outer-ledger kappa over baseline_kappa (outer: %s; strict: %s).' % ( + claim['kappa_decimal'][:22], claim['gain_over_claimed_leader'], sci(kappa - baseline, 12), + sci(strict - baseline, 12))] + receipt['kappa'] = dict( + claimed=oc['kappa'], identity='kappa = floor_1e-136((1 - 2e-100)(b - 1e-100)) - 1e-112 (exact)', + b_minus_kappa=interval(b - kappa, b - kappa), root_minus_kappa=interval(r_lo - kappa, r_hi - kappa), + strict_assembly_kappa=claim['kappa_decimal'], documentation_notes=doc_notes, + scope='arithmetic link only; the PR1673/PR1786/PR1758 outer lemmas, the bit endpoint and the 47/62 outer ' + 'inequalities are not checked here') + print('kappa: OUTER-CLAIM kappa = floor_136((1-2e-100)(b-1e-100)) - 1e-112 exactly; strict < kappa < b < root', + flush=True) + + # ---- 8. positive control: the pre-borrow assembly (evidence/ASSEMBLY.json = PRICE.json) endpoints + asm = as_json(raw, 'evidence/ASSEMBLY.json') + price = as_json(raw, 'PRICE.json') + old = int_profile(asm['complex_profile'], 'control', 'ASSEMBLY profile') + need(asm['surcharge_model'] == {'complex': False, 'bit': True}, 'control', 'surcharge model') + need(mass_of(old) == mass, 'control', 'old profile mass') + old_native, old_cons = Evaluator(old, m, W), Evaluator(old, m, W, surcharge=True) + oc_l = Fraction(asm['complex_lower']) + occ_l = Fraction(asm['conservative_complex_lower']) + need(Fraction(price['prices']['native']['root']['lower']) == oc_l and + Fraction(price['prices']['conservative']['root']['lower']) == occ_l, 'control', + 'PRICE.json and evidence/ASSEMBLY.json endpoints differ') + require_accept(old_native, oc_l, 'old complex_lower') + require_reject(old_native, oc_l + Fraction(1, 10 ** 24), 'old complex_lower + 1e-24') + require_accept(old_cons, occ_l, 'old conservative_complex_lower') + require_reject(old_cons, occ_l + Fraction(1, 10 ** 24), 'old conservative_complex_lower + 1e-24') + o_lo, o_hi, _, _ = old_native.root_bracket(40) + receipt['positive_control'] = dict( + what='stale evidence/ASSEMBLY.json profile (an older pre-borrow T74 profile, H5 = 54612 = 82*666; the ' + 'top-level PRICE.json carries the same endpoints): its certified 1e-24 native and conservative ' + 'endpoints are reproduced (accept at the endpoint, reject at +1e-24)', + profile=plain(old), native_endpoint=asm['complex_decimal'], conservative_endpoint=asm['conservative_complex_decimal'], + old_root_bracket=[dec(o_lo, 40), dec(o_hi, 40)], + root_minus_stale_assembly_root=interval(r_lo - o_hi, r_hi - o_lo)) + print('positive control: stale-assembly (older pre-borrow) endpoints %s / %s reproduced' % (asm['complex_decimal'], + asm['conservative_complex_decimal']), flush=True) + + # ---- 9. negative controls + results = [] + ok = True + ok &= expect_reject('mu at claimed b + 1e-15 must exceed 1', 'moment.accept', + lambda: require_accept(native, b + Fraction(1, 10 ** 15), 'b + 1e-15'), results) + lo15, hi15 = native.bounds(b + Fraction(1, 10 ** 15)) + need(lo15 > 1, 'moment.reject', 'mu(b + 1e-15) not certified > 1') + split = dict(H) + split[48] -= 1 + split[47] = split.get(47, 0) + 1 + split[1] += 1 + split = dict((r, split[r]) for r in sorted(split)) + need(mass_of(split) == mass, 'control', 'split keeps the mass') + ok &= expect_reject('one idle 48 replaced by 47 + 1: composition', 'compose.profile', + lambda: check_composition(split, sources[:1]), results) + ev_split = Evaluator(split, m, W) + ok &= expect_reject('one idle 48 replaced by 47 + 1: claimed b no longer admissible', 'moment.accept', + lambda: require_accept(ev_split, b, 'b under the split profile'), results) + s_lo, s_hi, _, s_und = ev_split.root_bracket(40) + need(s_und is None, 'moment.bracket', 'split bisection stalled') + moved = s_hi < r_lo or s_lo > r_hi + results.append(dict(name='one idle 48 replaced by 47 + 1: root moves', target='moment.root', ok=moved, + rejected_by='moment.root' if moved else None, + detail='split root in [%s, %s]; original root - split root in %s' % ( + dec(s_lo, 40), dec(s_hi, 40), interval(r_lo - s_hi, r_hi - s_lo)))) + ok &= moved + ok &= expect_reject('provider counts swapped (417 gauge44 + 249 extra)', 'compose.profile', + lambda: check_composition(compose(local, {'gauge44': counts['extra'], 'extra': counts['gauge44']}, + idle), sources[:1]), results) + ok &= expect_reject('pre-borrow (canonical) local profiles with the same idle', 'compose.profile', + lambda: check_composition(compose(canon, counts, idle), sources[:1]), results) + ok &= expect_reject('idle remainders omitted', 'compose.profile', + lambda: check_composition(compose(local, counts, {}), sources[:1]), results) + ok &= expect_reject('W off by one (66305)', 'compose.mass', + lambda: check_mass(H, m, W + 1, T, calls, m * (W + 1) - mass), results) + ok &= expect_reject('b tampered by +1e-80 (B.json identity)', 'claims.b_identity', + lambda: b_identity(b + Fraction(1, 10 ** 80), b_above), results) + ok &= expect_reject('kappa tampered by +1e-130', 'claims.kappa', + lambda: kappa_identity(kappa + Fraction(1, 10 ** 130), b), results) + ok &= expect_reject('surcharge charged on native b (model control of code/assemble.py)', 'moment.accept', + lambda: require_accept(cons, b, 'b with surcharge'), results) + ok &= expect_reject('complex_lower + 1e-90 claimed admissible', 'moment.accept', + lambda: require_accept(native, complex_lower + Fraction(1, 10 ** 90), 'endpoint + 1e-90'), + results) + ok &= expect_reject('log 2 by 10 atanh terms without the remainder bound', 'evaluator.log2_crosscheck', + lambda: log2_crosscheck(tuple(2 * v for v in atanh_enclosure(1, 3, terms=10, tail=False)), l2b), + results) + # same truncation with the remainder bound is accepted (the remainder is what makes it sound) + log2_crosscheck(tuple(2 * v for v in atanh_enclosure(1, 3, terms=10, tail=True)), l2b) + ok &= expect_reject('exp(log 2) by 3 Taylor terms without the remainder bound', 'evaluator.exp_log2', + lambda: exp_log2_check(exp_enclosure(l2[0], l2[1], terms=3, tail=False)), results) + exp_log2_check(exp_enclosure(l2[0], l2[1], terms=3, tail=True)) + bad = bytearray(raw['PROFILE.json']) + bad[2] ^= 1 + ok &= expect_reject('one flipped bit in PROFILE.json', 'pin', lambda: verify_pin('PROFILE.json', bytes(bad)), + results) + receipt['negative_controls'] = results + receipt['positive_mutations_accepted'] = [ + 'log 2 by the same 10 atanh terms WITH the remainder bound overlaps the reference enclosure', + 'exp(log 2) by the same 3 Taylor terms WITH the remainder bound encloses 2'] + receipt['controls_ok'] = bool(ok) + print('negative controls: %d/%d rejected by their targeted checks' % ( + sum(1 for x in results if x['ok']), len(results)), flush=True) + for x in results: + print(' %s %s -> %s' % ('OK ' if x['ok'] else 'BAD ', x['name'], x['rejected_by']), flush=True) + need(ok, 'controls', 'a negative control was not rejected by its targeted check') + + receipt['findings'] = [ + 'Global profile recomposed from the task-A recounted local profiles and the task-B recounted idle ' + 'remainders: 249 P_gauge44 + 417 P_extra + idle = %s; equal to PROFILE.json, new/PROFILE.json, ' + 'new/SPEC.json, outer/B.json and outer/LEDGER.json. Mass %d = 72*66304 + 64*666; the second term is the ' + 'mass of the 8 rank-8 COPY children per call (W - D = 576 T).' % (plain(H), mass), + 'Native moment root (no surcharge, as the T74 assembly prices the complex endpoint) lies in [%s, %s] ' + '(width 1e-%d), inside (complex_lower, complex_lower + 1e-90): the package endpoint certificate is ' + 'reproduced. b = complex_lower - 1e-100 is admissible (mu(b) < 1, root - b in %s) and agrees with the ' + 'package enclosure of mu(b) in outer/LEDGER.json.' % (dec(r_lo, DIG), dec(r_hi, DIG), DIG, + interval(gap_lo, gap_hi)), + 'Task bracket: mu(%s) < 1 < mu(%s), width 1e-21, contains b.' % (dec(b_lo, 21), dec(b_hi, 21)), + 'Conservative side (surcharge 32 m N m^a / (10^16 W)): root in [%s...], SPEC conservative_complex_lower ' + 'accepted and +1e-90 rejected; native b is rejected under the surcharge.' % dec(c_lo, DIG)[:45], + 'Claimed kappa = floor_1e-136((1 - 2e-100)(b - 1e-100)) - 1e-112 exactly (arithmetic only).', + 'Top-level PRICE.json and evidence/ASSEMBLY.json carry an older pre-borrow price (native endpoint %s); they ' + 'do not price the borrowed profile (their endpoints are reproduced here as a positive control).' % ( + asm['complex_decimal'],), + ] + receipt['not_checked'] = [ + 'The outer lemmas (PR1673 capped phase-cell fusion, PR1786 fine primes, PR1758 interiors, union schedule), ' + 'the bit endpoint and its PR589 supplier, and the bootstrap: only the arithmetic link kappa(b) is checked.', + 'Where the 76 private zero buffers per call live. The moment uses only the rank profile, m and W; under ' + 'task B\'s dedicated-family charge for the buffers none of these changes. If the buffers instead had to be ' + 'hosted inside idle children, the idle remainders and hence the root would change; that model is not ' + 'evaluated here.', + 'Native lowering / invoice / precision-tape obligations; the all-size assumptions of the package.', + ] + receipt['summary'] = dict(root_lo=dec(r_lo, DIG), root_hi=dec(r_hi, DIG), b=dec(b, 100), + b_lo=dec(b_lo, 21), b_hi=dec(b_hi, 21)) + return dict(r_lo=r_lo, r_hi=r_hi, b=b, controls=len(results), t=time.time() - t0) + + +def main(): + ap = argparse.ArgumentParser(description='Independent price check of PR2269 (global profile + moment root)') + ap.add_argument('--repo', default=DEFAULT_REPO, help='git checkout containing commit %s' % COMMIT) + ap.add_argument('--blob-dir', default=None, help='exported package copy, DIR/') + ap.add_argument('--out', nargs='?', const=os.path.join(HERE, RECEIPT_NAME), default=None, + help='write the JSON receipt (default %s next to this script)' % RECEIPT_NAME) + args = ap.parse_args() + if args.out is not None and os.path.dirname(os.path.abspath(args.out)) != HERE: + print('--out must name a file next to this script (%s)' % HERE) + print(FAIL_LINE) + return 2 + receipt = dict(checker='price_check.py', object=dict(pr=2269, commit=COMMIT, package=PKG), + python=sys.version.split()[0], + scope='task C: global profile composition and exact moment-root bracket of the native complex ' + 'saving b', + credits='PR2269 jeremykothe2; PR2226 Cinna Davis / 1337isnot1337; PR2260 Dugongue; T74 lineage ' + 'PR1319/PR1297 (Rohan Arun), PR1625 (mdumitrean), pivot-554 kernel; PR547/548/559 moment ' + 'engines; icekylinx (Zhihao Chen) / eumemic checker lineage. Prepared with substantial AI ' + 'assistance (Claude Code, Anthropic); Apache-2.0.') + ok = True + info = None + t0 = time.time() + try: + info = run(args, receipt) + except Reject as e: + ok = False + receipt['failure'] = str(e) + print('FAILED: %s' % e, flush=True) + except Exception as e: # task A/B failures and malformed input: report, never pass + ok = False + receipt['failure'] = '%s: %s' % (type(e).__name__, e) + print('FAILED: %s: %s' % (type(e).__name__, e), flush=True) + receipt['model'] = __doc__.split('MODEL (stated precisely; also written to the receipt field "model").')[1].strip() + receipt['result'] = PASS_LINE if ok else FAIL_LINE + print('elapsed %.1f s' % (time.time() - t0)) + if args.out is not None: + with open(args.out, 'w') as fh: + json.dump(receipt, fh, indent=1, sort_keys=True) + fh.write('\n') + print('receipt written: %s' % args.out) + if ok: + print('%s root=[%s..., %s...] b_admissible=1 task_bracket=[%s,%s] controls=%d' % ( + PASS_LINE, receipt['summary']['root_lo'][:34], receipt['summary']['root_hi'][:34], + receipt['summary']['b_lo'], receipt['summary']['b_hi'], info['controls'])) + return 0 + print(FAIL_LINE) + return 1 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/research/t74-borrow43-independent-check/price_check.receipt.json b/research/t74-borrow43-independent-check/price_check.receipt.json new file mode 100644 index 0000000000..06b3e93a0c --- /dev/null +++ b/research/t74-borrow43-independent-check/price_check.receipt.json @@ -0,0 +1,407 @@ +{ + "checker": "price_check.py", + "composition": { + "T": 74, + "calls": 666, + "children": 2350793, + "deficit": 23680, + "equal_to": [ + "PROFILE.json", + "new/PROFILE.json", + "new/SPEC.json expected.global_profile", + "outer/B.json profile", + "outer/LEDGER.json profile" + ], + "global_profile": { + "1": 1584738, + "2": 337002, + "3": 286065, + "4": 84246, + "48": 24479, + "5": 28785, + "7": 150, + "8": 5328 + }, + "identities": [ + "mass = m W - D = 73*66304 - 23680 = 4816512, D = 320 T", + "mass = (m-1) W + 64 calls = 72*66304 + 64*666 = 4816512; the second term 42624 = W - D = 576 T equals the mass of the 5328 = 8*666 rank-8 children, which are exactly the 8 COPY children (rank 8) of each call: mass - (COPY mass) = (m-1) W", + "local: 666*5385 = 3586410; idle mass = 1230102", + "halving guard 73^2 = 5329 > 2*48^2 = 4608" + ], + "idle": { + "1": 23976, + "3": 8673, + "48": 24479, + "5": 813, + "7": 150 + }, + "live_W": 66304, + "local_mass": 5385, + "local_profiles": { + "extra": { + "1": 2339, + "2": 509, + "3": 418, + "4": 125, + "5": 42, + "8": 8 + }, + "gauge44": { + "1": 2351, + "2": 501, + "3": 414, + "4": 129, + "5": 42, + "8": 8 + } + }, + "m": 73, + "mass": 4816512, + "provider_counts": { + "extra": 417, + "gauge44": 249 + }, + "rule": "H = sum over the 666 dispatched calls of P_provider + idle = 249 P_gauge44 + 417 P_extra + idle" + }, + "conservative": { + "conservative_complex_lower": { + "accept": true, + "mu_minus_one": [ + "-1.888368512122319486807E-90", + "-1.888368512122319486806E-90" + ], + "plus_1e90_reject": true, + "value": "424061784043726029139974148972472238135978180453092883310737030537903509986668069326669/250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + "model": "mu(a) + 32 m N m^a / (10^16 W), N = 2350793 children", + "native_b_rejected_with_surcharge": { + "mu_minus_one": [ + "8.342729336043003662812E-12", + "8.342729336043003662813E-12" + ], + "reject": true + }, + "native_minus_conservative_root": [ + "2.883570104209725943590E-12", + "2.883570104209725943591E-12" + ], + "root_bracket": [ + "0.0016962471361749041165598965958898889525439127218123715332429481221516140399466722773066766526932335909112961276610640863601815096", + "0.0016962471361749041165598965958898889525439127218123715332429481221516140399466722773066766526932335909112961276610640863601815097" + ] + }, + "controls_ok": true, + "credits": "PR2269 jeremykothe2; PR2226 Cinna Davis / 1337isnot1337; PR2260 Dugongue; T74 lineage PR1319/PR1297 (Rohan Arun), PR1625 (mdumitrean), pivot-554 kernel; PR547/548/559 moment engines; icekylinx (Zhihao Chen) / eumemic checker lineage. Prepared with substantial AI assistance (Claude Code, Anthropic); Apache-2.0.", + "evaluator": { + "grid_bits": 800, + "log2": [ + "6.931471805599453094172E-1", + "6.931471805599453094173E-1" + ], + "log2_width_ulps": 506, + "self_tests": [ + "log 2 = 2 atanh(1/3) overlaps 18 atanh(1/26) - 2 atanh(1/4801) + 8 atanh(1/8749)", + "exp(log 2) encloses 2", + "log(73/r) overlaps log 73 - log r for r in [1, 2, 3, 4, 5, 7, 8, 47, 48]" + ] + }, + "findings": [ + "Global profile recomposed from the task-A recounted local profiles and the task-B recounted idle remainders: 249 P_gauge44 + 417 P_extra + idle = {'1': 1584738, '2': 337002, '3': 286065, '4': 84246, '5': 28785, '7': 150, '8': 5328, '48': 24479}; equal to PROFILE.json, new/PROFILE.json, new/SPEC.json, outer/B.json and outer/LEDGER.json. Mass 4816512 = 72*66304 + 64*666; the second term is the mass of the 8 rank-8 COPY children per call (W - D = 576 T).", + "Native moment root (no surcharge, as the T74 assembly prices the complex endpoint) lies in [0.0016962471390584742207696225394800943861284603706821716607210815258272261945561178592716725376787146850319387830720495673160906619, 0.0016962471390584742207696225394800943861284603706821716607210815258272261945561178592716725376787146850319387830720495673160906620] (width 1e-130), inside (complex_lower, complex_lower + 1e-90): the package endpoint certificate is reproduced. b = complex_lower - 1e-100 is admissible (mu(b) < 1, root - b in ['5.376787147850319387830E-91', '5.376787147850319387831E-91']) and agrees with the package enclosure of mu(b) in outer/LEDGER.json.", + "Task bracket: mu(0.001696247139058474220) < 1 < mu(0.001696247139058474221), width 1e-21, contains b.", + "Conservative side (surcharge 32 m N m^a / (10^16 W)): root in [0.0016962471361749041165598965958898889525439...], SPEC conservative_complex_lower accepted and +1e-90 rejected; native b is rejected under the surcharge.", + "Claimed kappa = floor_1e-136((1 - 2e-100)(b - 1e-100)) - 1e-112 exactly (arithmetic only).", + "Top-level PRICE.json and evidence/ASSEMBLY.json carry an older pre-borrow price (native endpoint 0.001679671795504737621542); they do not price the borrowed profile (their endpoints are reproduced here as a positive control)." + ], + "imported_own_modules": { + "fill_check.py": "6b0e5950876da81238096f29c75ff9b52d6ae6f96435203d46a75e28c7ab8cd6", + "words_check.py": "b66414a39f5ac7b9cd32284027e13a550734901aca5f4457085a034689bc3ce6" + }, + "kappa": { + "b_minus_kappa": [ + "1.003392494279116948441E-100", + "1.003392494279116948442E-100" + ], + "claimed": "0.0016962471390584742207696225394800943861284603706821716607210815258272261945561178592716719999999997996607505720883051558460754921039811", + "documentation_notes": [ + "CLAIM.json kappa (0.00169337475697160729...) is the strict-assembly kappa, while its gain_over_claimed_leader 1.28346E-5 is the gain of the outer-ledger kappa over baseline_kappa (outer: 1.28345505158E-5; strict: 9.96216842899E-6)." + ], + "identity": "kappa = floor_1e-136((1 - 2e-100)(b - 1e-100)) - 1e-112 (exact)", + "root_minus_kappa": [ + "5.376787148853711882109E-91", + "5.376787148853711882110E-91" + ], + "scope": "arithmetic link only; the PR1673/PR1786/PR1758 outer lemmas, the bit endpoint and the 47/62 outer inequalities are not checked here", + "strict_assembly_kappa": "0.0016933747569716072928255508000300979096861142515806490772516972557968893652911293239" + }, + "model": "1. Local paid profiles P_gauge44 = profile of BORROW-WORD-43base and\n P_extra = profile of BORROW-WORD-43extra, recounted by words_check.frame_check\n (nested frame climbs + COPY charges; warps checked by words_check.check_all_warps).\n 2. Idle remainders: recounted by the fill_check pipeline from OWNERS.json.gz\n (rank minus occupied cells for every (owner replica, child, port) bin).\n 3. Composition (new/SPEC.json expected.global_profile; code/assemble.py sums the\n dispatched providers' paid profiles over the 666 calls and adds the idle\n remainders): H = sum over calls of P_dispatch(call) + idle\n = 249 P_gauge44 + 417 P_extra + idle, with the counts taken from DISPATCH.json.\n 4. Moment (m = 73, W = 66304 live data families):\n mu(a) = sum_r n_r (r/m)^(1-a) / W = sum_r n_r r/(m W) exp(a log(m/r)).\n Native complex side (evidence/ASSEMBLY.json surcharge_model complex = false;\n code/assemble.py checks complex_lower with surcharge off): no surcharge.\n This is the side of new/SPEC.json complex_lower and of outer/B.json b.\n Conservative complex side (surcharge on): mu(a) + 32 m N m^a / (10^16 W),\n N = sum_r n_r (number of children). It prices conservative_complex_lower.\n Every rank satisfies 0 < r < m, so each term is strictly increasing in a;\n the root rho is the unique a > 0 with mu(a) = 1 (mu(0) = mass/(mW) < 1).\n 'accept a' means mu(a) < 1 is certified; 'reject a' means mu(a) > 1 is certified.\n 5. Certified evaluation (exact integers on the grid 2^-PREC, PREC = 800 bits,\n every rounding directed): log x = k log 2 + 2 atanh(z) with 2^k <= x < 2^(k+1),\n z = (x - 2^k)/(x + 2^k) in [0, 1/3), log 2 = 2 atanh(1/3); atanh(z) by its\n positive series plus the remainder bound z^(2N+1)/((2N+1)(1-z^2)); exp(x) for\n 0 <= x < 1 by its positive Taylor series (lower: truncated sum) plus the\n remainder bound x^N/N! (N+1)/(N+1-x) (upper). mu(a) is then enclosed by an\n exact rational interval; comparisons with 1 are exact. Self-tests: log 2 by a\n second formula (18 atanh(1/26) - 2 atanh(1/4801) + 8 atanh(1/8749)), log(m/r)\n against log m - log r, and exp(log 2) must enclose 2.\n 6. Root bracket: bisection on the decimal grid 10^-130 starting from [0, 1/100],\n using only certified accept/reject decisions; it does not use any claimed value.", + "native": { + "b": { + "accept": true, + "decimal": "0.0016962471390584742207696225394800943861284603706821716607210815258272261945561178592716719999999999", + "equals": "complex_lower - 1e-100", + "ledger_native_moment_overlaps": true, + "mu_minus_one": [ + "-1.555609132104150386725E-90", + "-1.555609132104150386724E-90" + ], + "root_minus_b": [ + "5.376787147850319387830E-91", + "5.376787147850319387831E-91" + ], + "value": "16962471390584742207696225394800943861284603706821716607210815258272261945561178592716719999999999/10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + "b_above_endpoint": { + "mu_minus_one": [ + "1.337585427181417994140E-90", + "1.337585427181417994141E-90" + ], + "reject": true, + "value": "1696247139058474220769622539480094386128460370682171660721081525827226194556117859271673/1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + "bisection_steps": 425, + "coarse_1e24": { + "accept": true, + "endpoint": "0.001696247139058474220769", + "plus_1e24_reject": true + }, + "complex_lower": { + "accept": true, + "mu_minus_one": [ + "-1.555609131814830930826E-90", + "-1.555609131814830930825E-90" + ], + "mu_minus_one_plus_1e90": [ + "1.337585427181417994140E-90", + "1.337585427181417994141E-90" + ], + "plus_1e90_reject": true, + "value": "212030892382309277596202817435011798266057546335271457590135190728403274319514732408959/125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + "model": "mu(a) = sum_r n_r (r/73)^(1-a) / 66304, no surcharge (native complex side)", + "root_bracket": [ + "0.0016962471390584742207696225394800943861284603706821716607210815258272261945561178592716725376787146850319387830720495673160906619", + "0.0016962471390584742207696225394800943861284603706821716607210815258272261945561178592716725376787146850319387830720495673160906620" + ], + "root_bracket_width": "1E-130", + "task_bracket": { + "b_hi": "0.001696247139058474221", + "b_lo": "0.001696247139058474220", + "b_lo_le_b_le_b_hi": true, + "mu_minus_one_at_b_hi": [ + "6.665268152915640701063E-22", + "6.665268152915640701064E-22" + ], + "mu_minus_one_at_b_lo": [ + "-2.226667743704684854857E-21", + "-2.226667743704684854856E-21" + ], + "width": "1E-21" + } + }, + "negative_controls": [ + { + "detail": "b + 1e-15: mu - 1 in ['2.893194558996254221055E-15', '2.893194558996254221056E-15'] is not certified < 0", + "name": "mu at claimed b + 1e-15 must exceed 1", + "ok": true, + "rejected_by": "moment.accept", + "target": "moment.accept" + }, + { + "detail": "composed profile {'1': 1584739, '2': 337002, '3': 286065, '4': 84246, '5': 28785, '7': 150, '8': 5328, '47': 1, '48': 24478} != PROFILE.json {'1': 1584738, '2': 337002, '3': 286065, '4': 84246, '5': 28785, '7': 150, '8': 5328, '48': 24479}", + "name": "one idle 48 replaced by 47 + 1: composition", + "ok": true, + "rejected_by": "compose.profile", + "target": "compose.profile" + }, + { + "detail": "b under the split profile: mu - 1 in ['1.709123387564669456539E-9', '1.709123387564669456540E-9'] is not certified < 0", + "name": "one idle 48 replaced by 47 + 1: claimed b no longer admissible", + "ok": true, + "rejected_by": "moment.accept", + "target": "moment.accept" + }, + { + "detail": "split root in [0.0016962465483194978562166820707363713757, 0.0016962465483194978562166820707363713758]; original root - split root in ['5.907389763645529404687E-10', '5.907389763645529404688E-10']", + "name": "one idle 48 replaced by 47 + 1: root moves", + "ok": true, + "rejected_by": "moment.root", + "target": "moment.root" + }, + { + "detail": "composed profile {'1': 1586754, '2': 335658, '3': 285393, '4': 84918, '5': 28785, '7': 150, '8': 5328, '48': 24479} != PROFILE.json {'1': 1584738, '2': 337002, '3': 286065, '4': 84246, '5': 28785, '7': 150, '8': 5328, '48': 24479}", + "name": "provider counts swapped (417 gauge44 + 249 extra)", + "ok": true, + "rejected_by": "compose.profile", + "target": "compose.profile" + }, + { + "detail": "composed profile {'1': 1584408, '2': 336336, '3': 287397, '4': 84912, '5': 55425, '7': 150, '8': 5328, '48': 24479} != PROFILE.json {'1': 1584738, '2': 337002, '3': 286065, '4': 84246, '5': 28785, '7': 150, '8': 5328, '48': 24479}", + "name": "pre-borrow (canonical) local profiles with the same idle", + "ok": true, + "rejected_by": "compose.profile", + "target": "compose.profile" + }, + { + "detail": "composed profile {'1': 1560762, '2': 337002, '3': 277392, '4': 84246, '5': 27972, '8': 5328} != PROFILE.json {'1': 1584738, '2': 337002, '3': 286065, '4': 84246, '5': 28785, '7': 150, '8': 5328, '48': 24479}", + "name": "idle remainders omitted", + "ok": true, + "rejected_by": "compose.profile", + "target": "compose.profile" + }, + { + "detail": "W != 896 T (live data families)", + "name": "W off by one (66305)", + "ok": true, + "rejected_by": "compose.mass", + "target": "compose.mass" + }, + { + "detail": "b != complex_lower - 1e-100", + "name": "b tampered by +1e-80 (B.json identity)", + "ok": true, + "rejected_by": "claims.b_identity", + "target": "claims.b_identity" + }, + { + "detail": "kappa != floor_1e-136((1-2e-100)(b-1e-100)) - 1e-112", + "name": "kappa tampered by +1e-130", + "ok": true, + "rejected_by": "claims.kappa", + "target": "claims.kappa" + }, + { + "detail": "b with surcharge: mu - 1 in ['8.342729336043003662812E-12', '8.342729336043003662813E-12'] is not certified < 0", + "name": "surcharge charged on native b (model control of code/assemble.py)", + "ok": true, + "rejected_by": "moment.accept", + "target": "moment.accept" + }, + { + "detail": "endpoint + 1e-90: mu - 1 in ['1.337585427181417994140E-90', '1.337585427181417994141E-90'] is not certified < 0", + "name": "complex_lower + 1e-90 claimed admissible", + "ok": true, + "rejected_by": "moment.accept", + "target": "moment.accept" + }, + { + "detail": "two enclosures of log 2 are disjoint", + "name": "log 2 by 10 atanh terms without the remainder bound", + "ok": true, + "rejected_by": "evaluator.log2_crosscheck", + "target": "evaluator.log2_crosscheck" + }, + { + "detail": "exp(log 2) enclosure ['1.933373687519046021750E+0', '1.933373687519046021751E+0'] misses 2", + "name": "exp(log 2) by 3 Taylor terms without the remainder bound", + "ok": true, + "rejected_by": "evaluator.exp_log2", + "target": "evaluator.exp_log2" + }, + { + "detail": "git blob id mismatch for PROFILE.json", + "name": "one flipped bit in PROFILE.json", + "ok": true, + "rejected_by": "pin", + "target": "pin" + } + ], + "not_checked": [ + "The outer lemmas (PR1673 capped phase-cell fusion, PR1786 fine primes, PR1758 interiors, union schedule), the bit endpoint and its PR589 supplier, and the bootstrap: only the arithmetic link kappa(b) is checked.", + "Where the 76 private zero buffers per call live. The moment uses only the rank profile, m and W; under task B's dedicated-family charge for the buffers none of these changes. If the buffers instead had to be hosted inside idle children, the idle remainders and hence the root would change; that model is not evaluated here.", + "Native lowering / invoice / precision-tape obligations; the all-size assumptions of the package." + ], + "object": { + "commit": "b479fc5567bc09ab9185bffe89b62594f36d74e5", + "package": "research/gmx-t74-borrow43/", + "pr": 2269 + }, + "pins": { + "research/gmx-t74-borrow43/CLAIM.json": { + "bytes": 1501, + "git_blob": "214e02514d2aba5c3977dae6285bf925c685db3e", + "sha256": "bbcb4b72c86e4ca668256f8bfa6e35c1830a6e0edd77b7ab6230d8a3a7d7d31e" + }, + "research/gmx-t74-borrow43/PRICE.json": { + "bytes": 5666, + "git_blob": "c41b950145014912b2b2d176cb4972408c95e23e", + "sha256": "c5ec535fd9edbdec7b64edd5a8b862edb1a7f173d411dacb279172659573e16a" + }, + "research/gmx-t74-borrow43/PROFILE.json": { + "bytes": 83, + "git_blob": "48249b94604daccf0552c0c3b2489716344f7ff2", + "sha256": "7012a58b4078d41e3b4412204d7dfdf9eb401bfe7da5429002150bdfc3558865" + }, + "research/gmx-t74-borrow43/README.md": { + "bytes": 10828, + "git_blob": "b555bc54dc661658e4d5fcbc5e3bd6503d7af4bd", + "sha256": "2bf8d14e32ea03c614107eccfcce2422287a3a0552ab90f926b464d55767afcf" + }, + "research/gmx-t74-borrow43/evidence/ASSEMBLY.json": { + "bytes": 84613, + "git_blob": "6e9debfd552d18846fe55e4cbe6c59a37447b035", + "sha256": "5d9eb1ce551386024b5b6894836f81ed03a83d2e0c0bd0e02e3f6410a596bb2c" + }, + "research/gmx-t74-borrow43/new/PROFILE.json": { + "bytes": 85, + "git_blob": "3e103605dd46c8754028056eb9dde9a73b9bfdca", + "sha256": "50fcc0960a47f6d35064d3b55ea6dcb4cebbd305aec215c8034f626718595538" + }, + "research/gmx-t74-borrow43/new/SPEC.json": { + "bytes": 83591, + "git_blob": "2431d1cebbb2e155356d2da160d60808498bc33d", + "sha256": "bd091ed9e7f4939d06abb467d0d2c56ce0f34ba800d74132669f7b667e125d2d" + }, + "research/gmx-t74-borrow43/outer/B.json": { + "bytes": 791, + "git_blob": "a66501df3178012477b4c54fb6888e986b52a25e", + "sha256": "631d89563be62a156c2b0119f9d4ba5a31cbf36380768bf8748825cf361bb525" + }, + "research/gmx-t74-borrow43/outer/LEDGER.json": { + "bytes": 50245, + "git_blob": "3644673ab40b7b3595e94bbb7e118924a1cc48a1", + "sha256": "eab3f0cbd5b5c45c76cee3e2daefd73c994bf7cfa80be118c67e6fab6106a05b" + }, + "research/gmx-t74-borrow43/outer/OUTER-CLAIM.json": { + "bytes": 1669, + "git_blob": "f1feaefc27028e590fa7992d273c137897b379eb", + "sha256": "ffa05de3c8d7cb7de0114d25df7250909581f4a2c0ce68c8d20eb821bf67f0e5" + } + }, + "positive_control": { + "conservative_endpoint": "0.00167967179265877105202", + "native_endpoint": "0.001679671795504737621542", + "old_root_bracket": [ + "0.0016796717955047376215420758089648538525", + "0.0016796717955047376215420758089648538526" + ], + "profile": { + "1": 1559100, + "2": 339000, + "3": 277392, + "4": 84912, + "48": 22748, + "5": 54612, + "8": 5328 + }, + "root_minus_stale_assembly_root": [ + "1.657534355373659922754E-5", + "1.657534355373659922755E-5" + ], + "what": "stale evidence/ASSEMBLY.json profile (an older pre-borrow T74 profile, H5 = 54612 = 82*666; the top-level PRICE.json carries the same endpoints): its certified 1e-24 native and conservative endpoints are reproduced (accept at the endpoint, reject at +1e-24)" + }, + "positive_mutations_accepted": [ + "log 2 by the same 10 atanh terms WITH the remainder bound overlaps the reference enclosure", + "exp(log 2) by the same 3 Taylor terms WITH the remainder bound encloses 2" + ], + "python": "3.14.4", + "result": "PASS_T74_BORROW43_PRICE_INDEPENDENT", + "scope": "task C: global profile composition and exact moment-root bracket of the native complex saving b", + "summary": { + "b": "0.0016962471390584742207696225394800943861284603706821716607210815258272261945561178592716719999999999", + "b_hi": "0.001696247139058474221", + "b_lo": "0.001696247139058474220", + "root_hi": "0.0016962471390584742207696225394800943861284603706821716607210815258272261945561178592716725376787146850319387830720495673160906620", + "root_lo": "0.0016962471390584742207696225394800943861284603706821716607210815258272261945561178592716725376787146850319387830720495673160906619" + } +} diff --git a/research/t74-borrow43-independent-check/words_check.py b/research/t74-borrow43-independent-check/words_check.py new file mode 100644 index 0000000000..0b646b9d55 --- /dev/null +++ b/research/t74-borrow43-independent-check/words_check.py @@ -0,0 +1,1294 @@ +#!/usr/bin/env python3 +"""Independent check (task A) of the two borrowed T74 local words of PR #2269. + +Object: CrocSwap/integer-mult-bounds PR #2269 (jeremykothe2), head +b479fc5567bc09ab9185bffe89b62594f36d74e5, package research/gmx-t74-borrow43/: +new/borrow/words/BORROW-WORD-43{base,extra}.json.gz and their inputs +new/borrow/inputs/* (canonical unborrowed words, block certificate, witnesses). + +Credit: PR2269 (jeremykothe2) for the borrow43 package and words; PR2226 +(Cinna Davis / 1337isnot1337, with OpenAI Codex) for anticipatory dirty +borrowing, the alias rule, the K_G reference changes and the free-operator +replay idea; PR2260 (Dugongue) for concurrent application of PR2226; the T74 +lineage PR1319/PR1297 (Rohan Arun), PR1625 (mdumitrean) and the pivot-554 +kernel; icekylinx (Zhihao Chen) for the Clifford-frame normal forms +(notes/general-clifford-frames.tex) and the local-word checker lineage. + +This file shares no code with those packages. It was written from their +written specification (PR2226 README/PROOF, notes/general-clifford-frames.tex, +the PR2269 README and the JSON field layout); no package code is imported or +executed. Inputs are read as git blobs at the pinned commit (or from +--blob-dir) and are pinned by sha256 and git blob id. + +Prepared with substantial AI assistance (Claude Code, Anthropic); Apache-2.0. + +Usage: python3 -I -B words_check.py [--repo PATH | --blob-dir DIR] [--out RECEIPT.json] +The receipt (if requested) must be written next to this script. The final +stdout line is PASS_T74_BORROW43_WORDS_INDEPENDENT or FAIL_T74_BORROW43_WORDS_INDEPENDENT. + +MODEL (stated precisely; see also the receipt field "model"). + * Registers 0..v-1 are X (sources), v..2v-1 are Y (targets), 2v..2v+R-1 + helpers; n = 2v+R. Removed helpers do not exist. A buffer register b = r+n + exists only for r in helper_final (restored cold helpers) and only in cleanup. + * Frame = GF(2)-subspace of F_2^h (h = 9), given by a list of bit-mask + vectors; compared as spans (reduced echelon form). Start: X_i = span(port_i), + Y = 0, helper = start_extra[r] or 0. End: X = FULL, Y_i = port_i^perp, + helper = helper_final[r] or FULL. + * Every framed gate (add t s c F | scale t c F) climbs each incident register + from its current frame S to F; legal only if S <= F; a strict climb pays one + child of rank dim F - dim S. precondition/compensation are at frame 0. + * After A every target sits at its level (target_levels, here all 0) and + every centre at its centre frame. cut gates (frame null) add c*centre into + a target at its level; each centre pays one COPY child of rank + dim(centre frame) - dim(level) per distinct served level (nested chain). + * warp [pos, L, G, U, E] is inserted before B[pos] (list order inside a + position): requires cur[L] == span U exactly, sets cur[L] = span E, pays + nothing (rank-zero reference change K_G); logically L <- K_G L. + * After B and restore every live register climbs to its end frame (paid). + * cleanup items must all be at FULL, may touch only live registers whose + current frame is FULL, or buffers; they pay nothing. + * Logic: exact replay over Q (rationals x free group on K_1..K_43): + every live register starts as an independent symbol (arbitrary dirty + content), buffers start at 0; add t+=c*s, scale t*=c, warp left-multiplies + by K_k^{+-1} with free-group cancellation. Accept iff after cleanup + Y_i = Y_i + X_i, every other live register is its own input, and every + buffer is 0. The dual orientation replays g^{-T} for every item + (add -> s -= c t, scale -> 1/c, K -> K^{-T} as new free letters) and expects + X_i = X_i - Y_i. + * Warp algebra over GF(2): G (columns = images of unit vectors) invertible, + dim U = dim E, G span U = span E, M = [[G,0],[G+G^-T,G^-T]] symplectic for + w((x,z),(x',z')) = x.z' + z.x', M L_0 = L_0, M L_FULL = L_FULL, + M L_U = L_E where L_W = {(u, u+p): u in W, p in W^perp}, and the Fourier + rank h - dim(L_E cap M L_U) of R_in = T_E K_G T_U^-1 is 0; G^-T U^perp = E^perp. + Exact Clifford phases / Gaussian monomial lifts are NOT checked here. +""" + +import argparse +import copy +import gzip +import hashlib +import json +import os +import subprocess +import sys +import time +from collections import Counter +from fractions import Fraction + +PASS_LINE = 'PASS_T74_BORROW43_WORDS_INDEPENDENT' +FAIL_LINE = 'FAIL_T74_BORROW43_WORDS_INDEPENDENT' +COMMIT = 'b479fc5567bc09ab9185bffe89b62594f36d74e5' +PKG = 'research/gmx-t74-borrow43/' +DEFAULT_REPO = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) # repository root + +# path (relative to PKG) -> (git blob id, sha256 of blob bytes) +PINS = { + 'word_base': ('new/borrow/words/BORROW-WORD-43base.json.gz', + '448dd795adba29392a90b34aa3f1b1b796c7e0bd', + '9492a5537fb87d9ca98dffcd0230f7625b3789744fa94e2f18acf23d91d998b5'), + 'word_extra': ('new/borrow/words/BORROW-WORD-43extra.json.gz', + '2b51ba96256283bbc5578f99b694c50edd8a0e35', + '87d51f5298101d5947f45c43ee02f0ec45d6acbddabb808d0d02db1eaf063734'), + 'canon_base': ('new/borrow/inputs/gauge44.canonical.json.gz', + '4abb6e28f02c95b41ed345d4e4401d16d58ae791', + '65c6d17ffee2eacf27bff438f37fc549c9ed0c909cbc7a52976cc75cf2d15b91'), + 'canon_extra': ('new/borrow/inputs/extra.canonical.json.gz', + 'e0d670d4351229ce6921ecfbecf180070b17616b', + 'd7e48dcbafa236a2e1e41f7958244211506f7c7630fe6a2d43d2bdf17b7ae015'), + 'blocks': ('new/borrow/inputs/blocks.json', + 'c683574b3861678081fd5c5944dbd7a47309f6fd', + 'ddfac1dae1fe7cc0a91e7c7205c6d9d0c07c682880aa34eed83bf4ad7384da9f'), + 'witness_base': ('new/borrow/inputs/witness_43_base.json', + '9f4b93f3bc52d4f4ffaa128cfd7ae574fd36c462', + '67ffb66d94067f6e53aee9118fe90e14a57f497fc8b3f708b6dac3de2e58ff28'), + 'witness_extra': ('new/borrow/inputs/witness_43_extra.json', + '864ba533f50c2f1f639a6a3559b185bd321b923a', + 'd46449c6dbf4477f260cf5baea9bbb570a66ee0b6db81f4a220b9e3086ae9e46'), + 'providers': ('new/BORROW-PROVIDERS.json', + '42563d218a5c7321f686c1cf9b98e75883d85abc', + '8324fcf5fd652af9793c1acbc5f5099ee0d2f1eefa0adfbb8335f3d31d891da2'), + 'word566_base': ('new/gauge44-word-566.json.gz', + '76c01583a0286cddb0f71e0cb13077e4317104f6', + 'eeb6a236ed0ea8873b8800947d0cd19c36a6fcfdf857fc42913cb45cd984f219'), + 'word566_extra': ('new/extra-word-566.json.gz', + 'e86142b352466f54a3da38c96a6e1484145c3b5c', + 'cd417b904408c221d9840d08faff8af040cc4207f9804284f2f5375d21298a62'), +} + +# Claims under test (PR2269 README / scout notes), written here independently of the files. +CLAIMS = { + 'base': dict(profile={1: 2351, 2: 501, 3: 414, 4: 129, 5: 42, 8: 8}, + old_profile={1: 2348, 2: 500, 3: 416, 4: 130, 5: 82, 8: 8}, + providers_key='gauge44', base_tag='eeb6a236'), + 'extra': dict(profile={1: 2339, 2: 509, 3: 418, 4: 125, 5: 42, 8: 8}, + old_profile={1: 2340, 2: 508, 3: 420, 4: 126, 5: 82, 8: 8}, + providers_key='extra', base_tag='cd417b90'), + 'width_inventory': {4: 36, 5: 9, 7: 36, 8: 116, 9: 240}, + 'helpers_before': 480, 'helpers_after': 437, 'warps': 43, 'mass': 5385, + # README: "43 high helpers (8 width-4, 35 width-5)". This holds for the base (gauge44) word; the + # extra word's 43 removed helpers have canonical widths 4 x 4 + 39 x 5 (recorded, see receipt). + 'removed_old_widths': {'base': {4: 8, 5: 35}, 'extra': {4: 4, 5: 39}}, +} + + +class Reject(Exception): + """A failed check; .check names the check family that rejected.""" + + def __init__(self, check, msg): + Exception.__init__(self, '[%s] %s' % (check, msg)) + self.check = check + self.msg = msg + + +def need(cond, check, msg): + if not cond: + raise Reject(check, msg) + + +# ---------------------------------------------------------------------------- +# Input loading and pinning +# ---------------------------------------------------------------------------- + +def git_blob_id(data): + h = hashlib.sha1() + h.update(b'blob %d\0' % len(data)) + h.update(data) + return h.hexdigest() + + +def verify_pin(key, data): + rel, blob, sha = PINS[key] + need(git_blob_id(data) == blob, 'pin', 'git blob id mismatch for %s' % rel) + need(hashlib.sha256(data).hexdigest() == sha, 'pin', 'sha256 mismatch for %s' % rel) + + +def load_inputs(repo, blob_dir): + raw = {} + pins = {} + for key in sorted(PINS): + rel, blob, sha = PINS[key] + path = PKG + rel + if blob_dir is None: + got = subprocess.run(['git', '-C', repo, 'rev-parse', COMMIT + ':' + path], + capture_output=True, text=True) + need(got.returncode == 0, 'pin', 'cannot resolve %s at %s' % (path, COMMIT)) + need(got.stdout.strip() == blob, 'pin', 'path %s does not resolve to pinned blob' % path) + got = subprocess.run(['git', '-C', repo, 'cat-file', 'blob', blob], capture_output=True) + need(got.returncode == 0, 'pin', 'cannot read blob %s' % blob) + data = got.stdout + else: + # Layouts: DIR/ (a `git archive` export of the package, as + # check_all.py uses) or DIR/. Either way the bytes must match both pins. + cands = [os.path.join(blob_dir, rel), os.path.join(blob_dir, os.path.basename(rel))] + src = next((c for c in cands if os.path.isfile(c)), None) + need(src is not None, 'pin', 'blob for %s not found in --blob-dir (tried %s)' % (rel, ', '.join(cands))) + with open(src, 'rb') as fh: + data = fh.read() + verify_pin(key, data) + raw[key] = data + pins[key] = dict(path=path, git_blob=blob, sha256=sha, bytes=len(data)) + js = {} + for key, data in raw.items(): + if PINS[key][0].endswith('.gz'): + data = gzip.decompress(data) + js[key] = json.loads(data.decode('utf-8')) + return js, pins, raw + + +# ---------------------------------------------------------------------------- +# GF(2) linear algebra on integer bit vectors +# ---------------------------------------------------------------------------- + +def parity(x): + return bin(x).count('1') & 1 + + +def echelon(vectors): + """Fully reduced echelon basis {pivot bit: vector} of the span of the vectors.""" + piv = {} + for x in vectors: + x = int(x) + for b in list(piv): + if (x >> b) & 1: + x ^= piv[b] + if x: + lead = x.bit_length() - 1 + for b in list(piv): + if (piv[b] >> lead) & 1: + piv[b] ^= x + piv[lead] = x + return piv + + +def span(vectors): + """Canonical key of a subspace: its reduced echelon basis, sorted decreasingly.""" + return tuple(sorted(echelon(vectors).values(), reverse=True)) + + +def reduce_by(x, piv): + for b, vec in piv.items(): + if (x >> b) & 1: + x ^= vec + return x + + +def contains(small, big): + piv = echelon(big) + return all(reduce_by(x, piv) == 0 for x in small) + + +def dim_sum(a, b): + return len(span(list(a) + list(b))) + + +def perp(sub, h): + return span([x for x in range(1, 1 << h) if all(parity(x & u) == 0 for u in sub)]) + + +def mat_apply(cols, x): + y = 0 + i = 0 + while x: + if x & 1: + y ^= cols[i] + x >>= 1 + i += 1 + return y + + +def mat_inverse(cols, h): + """Columns of G^{-1}, or None if G is singular over GF(2).""" + piv = {} + for i in range(h): + a, b = cols[i], 1 << i # invariant: G(b) = a + for p in list(piv): + pa, pb = piv[p] + if (a >> p) & 1: + a ^= pa + b ^= pb + if a == 0: + return None + lead = a.bit_length() - 1 + for p in list(piv): + pa, pb = piv[p] + if (pa >> lead) & 1: + piv[p] = (pa ^ a, pb ^ b) + piv[lead] = (a, b) + inv = [0] * h + for p, (a, b) in piv.items(): + if a != (1 << p): + return None + inv[p] = b + return inv + + +def mat_transpose(cols, h): + return [sum(((cols[r] >> j) & 1) << r for r in range(h)) for j in range(h)] + + +def lagrangian(sub, h): + """L_W = {(u, u+p): u in W, p in W^perp} encoded as x | z << h.""" + return span([u | (u << h) for u in sub] + [p << h for p in perp(sub, h)]) + + +def symp(a, b, h): + mask = (1 << h) - 1 + return parity((a & mask) & (b >> h)) ^ parity((a >> h) & (b & mask)) + + +# ---------------------------------------------------------------------------- +# Parsing (borrow word and canonical word) into one internal program shape +# ---------------------------------------------------------------------------- + +def is_int(x): + return isinstance(x, int) and not isinstance(x, bool) + + +def dyadic(q): + return q.denominator & (q.denominator - 1) == 0 + + +def unit(q): + a = abs(q.numerator) + return a > 0 and a & (a - 1) == 0 and dyadic(q) + + +def regs_of(item): + if item[0] == 'add': + return (item[1], item[2]) + return (item[1],) + + +def conv_gate(g, frame_of, where, allow_warp=False): + need(isinstance(g, list) and g, 'format', 'gate is not a list at %s' % where) + op = g[0] + if op == 'add': + need(len(g) == 6 and all(is_int(x) for x in g[1:5]), 'format', 'bad add at %s' % where) + need(g[4] > 0 and g[3] != 0, 'format', 'bad add coefficient at %s' % where) + q = Fraction(g[3], g[4]) + need(dyadic(q), 'format', 'non-dyadic coefficient at %s' % where) + need(g[1] != g[2], 'format', 'self add at %s' % where) + return ('add', g[1], g[2], q, frame_of(g[5])) + if op == 'scale': + need(len(g) == 5 and all(is_int(x) for x in g[1:4]), 'format', 'bad scale at %s' % where) + need(g[3] != 0 and g[2] != 0, 'format', 'zero scale at %s' % where) + q = Fraction(g[2], g[3]) + need(unit(q), 'format', 'scale is not a dyadic unit at %s' % where) + return ('scale', g[1], q, frame_of(g[4])) + if op == 'warp' and allow_warp: + need(len(g) == 4 and is_int(g[1]) and is_int(g[2]) and g[2] != 0, 'format', 'bad warp item at %s' % where) + return ('warp', g[1], g[2], frame_of(g[3])) + raise Reject('format', 'unknown primitive %r at %s' % (op, where)) + + +def parse_borrow(w): + need(w.get('kind') == 'BORROW-WORD', 'format', 'not a BORROW-WORD') + rep = w['report'] + v, h, R = rep['v'], rep['h'], rep['R'] + need((v, h, R) == (112, 9, 480), 'format', 'unexpected geometry') + n = 2 * v + R + full = span([1 << i for i in range(h)]) + + def frame_lit(F): + if F is None: + return None + need(isinstance(F, list) and all(is_int(x) and 0 < x < (1 << h) for x in F), 'format', 'bad frame literal') + return span(F) + + ports = w['ports'] + need(len(ports) == v and all(is_int(p) and 0 < p < (1 << h) for p in ports), 'format', 'ports') + removed = w['removed'] + need(len(set(removed)) == len(removed) and all(2 * v <= r < n for r in removed), 'format', 'removed helpers') + removed = set(removed) + live = [r for r in range(n) if r not in removed] + start, end = {}, {} + for i in range(v): + start[i] = span([ports[i]]) + end[i] = full + start[v + i] = () + end[v + i] = perp(span([ports[i]]), h) + for r in live: + if r >= 2 * v: + start[r] = () + end[r] = full + for k, F in w['start_extra'].items(): + r = int(k) + need(r in start and r >= 2 * v, 'format', 'start_extra names a non-live/non-helper register %s' % k) + start[r] = frame_lit(F) + restored = set() + for k, F in w['helper_final'].items(): + r = int(k) + need(r in end and r >= 2 * v, 'format', 'helper_final names a non-live/non-helper register %s' % k) + end[r] = frame_lit(F) + restored.add(r) + need(w.get('initial_corrections') == [], 'anticipatory', + 'initial (anticipatory) corrections present; this checker covers the zero-correction case only') + sec = {} + for name in ('precondition', 'compensation', 'A', 'cut', 'B', 'restore'): + sec[name] = [conv_gate(g, frame_lit, '%s[%d]' % (name, i)) for i, g in enumerate(w[name])] + cleanup = [conv_gate(g, frame_lit, 'cleanup[%d]' % i, allow_warp=True) for i, g in enumerate(w['cleanup'])] + warps = [] + for k, rec in enumerate(w['warps'], 1): + need(isinstance(rec, list) and len(rec) == 5, 'format', 'warp record %d shape' % k) + pos, L, cols, U, E = rec + need(is_int(pos) and 0 <= pos <= len(sec['B']), 'format', 'warp %d position' % k) + need(is_int(L), 'format', 'warp %d lender' % k) + need(isinstance(cols, list) and len(cols) == h and all(is_int(c) and 0 <= c < (1 << h) for c in cols), + 'format', 'warp %d G columns' % k) + need(isinstance(U, list) and isinstance(E, list) and all(is_int(x) and 0 < x < (1 << h) for x in U + E), + 'format', 'warp %d frames' % k) + warps.append(dict(op=k, pos=pos, lender=L, G=list(cols), U_list=list(U), E_list=list(E), + U=span(U), E=span(E))) + by_pos = {} + for wr in warps: + by_pos.setdefault(wr['pos'], []).append(wr) + items = [] + for p in range(len(sec['B']) + 1): + for wr in by_pos.get(p, []): + items.append(('warp', wr['lender'], wr['op'], wr['U'], wr['E'])) + if p < len(sec['B']): + items.append(sec['B'][p]) + return dict(kind='borrow', v=v, h=h, R=R, n=n, full=full, ports=ports, live=live, removed=removed, + start=start, end=end, restored=restored, buffers=set(r + n for r in restored), + centers=list(w['centers']), center_frames=[frame_lit(F) for F in w['center_frames']], + target_levels={int(k): frame_lit(F) for k, F in w['target_levels'].items()}, + pre=sec['precondition'] + sec['compensation'], n_pre=len(sec['precondition']), + A=sec['A'], cut=sec['cut'], B_items=items, post=sec['restore'], cleanup=cleanup, + warps=warps, sections=sec, + claimed_profile={int(k): c for k, c in rep['local_profile'].items()}, + claimed_inventory={int(k): c for k, c in rep['width_inventory'].items()}) + + +def parse_canonical(c): + v, h, R = c['v'], c['h'], c['R'] + need((v, h, R) == (112, 9, 480), 'format', 'unexpected canonical geometry') + n = 2 * v + R + full = span([1 << i for i in range(h)]) + frames = [] + for F in c['frames']: + need(isinstance(F, list) and all(is_int(x) and 0 < x < (1 << h) for x in F), 'format', 'canonical frame') + need(len(span(F)) == len(F), 'format', 'canonical frame basis is dependent') + frames.append(span(F)) + + def frame_idx(F): + if F is None: + return None + need(is_int(F) and 0 <= F < len(frames), 'format', 'canonical frame index') + return frames[F] + + ports = c['ports'] + need(len(c['start']) == n and len(c['final']) == n, 'format', 'canonical start/final length') + start = {r: frames[c['start'][r]] for r in range(n)} + end = {r: frames[c['final'][r]] for r in range(n)} + for i in range(v): + need(start[i] == span([ports[i]]), 'format', 'canonical X start is not its port line') + need(end[i] == full, 'format', 'canonical X end is not FULL') + need(start[v + i] == (), 'format', 'canonical Y start is not 0') + need(end[v + i] == perp(span([ports[i]]), h), 'format', 'canonical Y end is not port-perp') + sec = {} + for name in ('precondition', 'compensation', 'A', 'cut', 'B', 'tail', 'cleanup'): + sec[name] = [conv_gate(g, frame_idx, 'canon %s[%d]' % (name, i)) for i, g in enumerate(c[name])] + return dict(kind='canonical', v=v, h=h, R=R, n=n, full=full, ports=ports, live=list(range(n)), + removed=set(), start=start, end=end, restored=set(), buffers=set(), + centers=list(c['centers']), center_frames=[frames[i] for i in c['center_frames']], + target_levels={int(k): frame_idx(F) for k, F in c['target_levels'].items()}, + pre=sec['precondition'] + sec['compensation'], n_pre=len(sec['precondition']), + A=sec['A'], cut=sec['cut'], B_items=list(sec['B']), post=sec['tail'], cleanup=sec['cleanup'], + warps=[], sections=sec, frames=frames, + claimed_profile={int(k): x for k, x in c['local_profile'].items()}, claimed_inventory=None) + + +# ---------------------------------------------------------------------------- +# Check 1: warp algebra +# ---------------------------------------------------------------------------- + +def check_warp(wr, h, live, v): + k = wr['op'] + cols = wr['G'] + inv = mat_inverse(cols, h) + need(inv is not None, 'warp', 'warp %d: G is singular over GF(2)' % k) + need(all(mat_apply(cols, inv[t]) == 1 << t and mat_apply(inv, cols[t]) == 1 << t for t in range(h)), + 'warp', 'warp %d: inverse witness' % k) + U, E = wr['U'], wr['E'] + need(len(U) == len(wr['U_list']) and len(E) == len(wr['E_list']), 'warp', + 'warp %d: U or E list is linearly dependent' % k) + need(len(U) == len(E), 'warp', 'warp %d: dim U != dim E' % k) + need(span([mat_apply(cols, u) for u in U]) == E, 'warp', 'warp %d: G span U != span E' % k) + git = mat_transpose(inv, h) # G^{-T} + mask = (1 << h) - 1 + + def M(vec): + x, z = vec & mask, vec >> h + gx = mat_apply(cols, x) + return gx | ((gx ^ mat_apply(git, x) ^ mat_apply(git, z)) << h) + + gens = [1 << i for i in range(2 * h)] + imgs = [M(g) for g in gens] + need(len(span(imgs)) == 2 * h, 'warp', 'warp %d: K_G singular' % k) + for a in range(2 * h): + for b in range(a + 1, 2 * h): + need(symp(imgs[a], imgs[b], h) == symp(gens[a], gens[b], h), 'warp', 'warp %d: K_G not symplectic' % k) + full = span([1 << i for i in range(h)]) + L0, LF, LU, LE = lagrangian((), h), lagrangian(full, h), lagrangian(U, h), lagrangian(E, h) + need(len(L0) == len(LF) == len(LU) == len(LE) == h, 'warp', 'warp %d: Lagrangian dimension' % k) + need(span([M(x) for x in L0]) == L0, 'warp', 'warp %d: K_G does not fix L_0' % k) + need(span([M(x) for x in LF]) == LF, 'warp', 'warp %d: K_G does not fix L_FULL' % k) + MLU = span([M(x) for x in LU]) + rank_in = h - (len(LE) + len(MLU) - dim_sum(LE, MLU)) + need(MLU == LE and rank_in == 0, 'warp', 'warp %d: K_G L_U != L_E (Fourier rank %d)' % (k, rank_in)) + need(span([mat_apply(git, p) for p in perp(U, h)]) == perp(E, h), 'warp', 'warp %d: G^-T U^perp != E^perp' % k) + need(wr['lender'] in live and not (v <= wr['lender'] < 2 * v), 'warp', + 'warp %d: lender must be a live non-target register' % k) + # Fourier distance of a plain frame change U -> E (what the transition would cost without K_G) + plain = h - (2 * h - dim_sum(LU, LE)) + by_formula = len(U) + len(E) - 2 * (len(U) + len(E) - dim_sum(U, E)) + need(plain == by_formula, 'warp', 'warp %d: Lagrangian distance lemma inconsistency' % k) + return dict(op=k, pos=wr['pos'], lender=wr['lender'], dim=len(U), plain_fourier_distance=plain, + U_eq_E=(U == E), U_in_E=contains(U, E)) + + +def check_all_warps(P): + out = [check_warp(wr, P['h'], set(P['live']), P['v']) for wr in P['warps']] + lenders = [wr['lender'] for wr in P['warps']] + need(len(set(lenders)) == len(lenders), 'warp', 'a register lends twice') + return out + + +# ---------------------------------------------------------------------------- +# Check 2: frame legality and paid-profile recount +# ---------------------------------------------------------------------------- + +def frame_check(P, charge_warps=False, warp_as_climb=()): + v, full = P['v'], P['full'] + cur = {r: P['start'][r] for r in P['live']} + paid, climbs, copies, warp_charge = Counter(), Counter(), Counter(), Counter() + per_reg = Counter() + istarget = lambda r: v <= r < 2 * v + + def climb(r, F, where): + need(r in cur, 'frame', 'register %d is not live (%s)' % (r, where)) + old = cur[r] + need(contains(old, F), 'frame', 'non-nested climb of %d at %s: %r -> %r' % (r, where, old, F)) + d = len(F) - len(old) + if d: + paid[d] += 1 + climbs[d] += 1 + per_reg[r] += d + cur[r] = F + + for i, g in enumerate(P['pre']): + need(g[-1] == (), 'frame', 'precondition/compensation gate %d not at frame 0' % i) + need(istarget(g[1]), 'frame', 'precondition/compensation gate %d writes a non-target' % i) + for r in regs_of(g): + climb(r, (), 'pre[%d]' % i) + for i, g in enumerate(list(P['A']) + [it for it in P['B_items'] if it[0] != 'warp'] + list(P['post'])): + need(not (g[0] == 'add' and not istarget(g[1]) and istarget(g[2])), 'frame', + 'a non-target register reads a target (item %d of A+B+post)' % i) + for i, g in enumerate(P['A']): + need(g[-1] is not None, 'frame', 'unframed gate in A') + for r in regs_of(g): + climb(r, g[-1], 'A[%d]' % i) + for t in range(v): + need(cur[v + t] == P['target_levels'].get(t, ()), 'frame', 'target %d not at its level after A' % t) + need(len(set(P['centers'])) == len(P['centers']) == len(P['center_frames']), 'frame', 'centres') + for q, U in zip(P['centers'], P['center_frames']): + need(q in cur and cur[q] == U, 'frame', 'centre %d not at its centre frame after A' % q) + served = dict((q, set()) for q in P['centers']) + for i, g in enumerate(P['cut']): + need(g[0] == 'add' and g[-1] is None, 'frame', 'cut[%d] is not an unframed add' % i) + t, s = g[1], g[2] + need(istarget(t) and s in served, 'frame', 'cut[%d] must add a centre into a target' % i) + need(cur[t] == P['target_levels'].get(t - v, ()), 'frame', 'cut[%d] target off its level' % i) + served[s].add(cur[t]) + for q, U in zip(P['centers'], P['center_frames']): + prev = U + for T in sorted(served[q], key=lambda S: (-len(S), S)): + need(contains(T, prev), 'frame', 'centre %d copy levels not nested' % q) + if T != prev: + paid[len(prev) - len(T)] += 1 + copies[len(prev) - len(T)] += 1 + prev = T + for i, it in enumerate(P['B_items']): + if it[0] == 'warp': + _, L, k, U, E = it + need(L in cur and not istarget(L), 'frame', 'warp %d lender %d not a live non-target' % (k, L)) + if k in warp_as_climb: + climb(L, E, 'warp %d treated as an ordinary climb' % k) + continue + need(cur[L] == U, 'frame', 'warp %d: lender %d frame %r != U %r' % (k, L, cur[L], U)) + if charge_warps: + d = len(U) + len(E) - 2 * (len(U) + len(E) - dim_sum(U, E)) + if d: + paid[d] += 1 + warp_charge[d] += 1 + cur[L] = E + else: + need(it[-1] is not None, 'frame', 'unframed gate in B') + for r in regs_of(it): + climb(r, it[-1], 'B item %d' % i) + for i, g in enumerate(P['post']): + need(g[-1] is not None, 'frame', 'unframed gate after B') + for r in regs_of(g): + climb(r, g[-1], 'post-B[%d]' % i) + for r in P['live']: + climb(r, P['end'][r], 'end frame') + for i, it in enumerate(P['cleanup']): + need(it[-1] == full, 'frame', 'cleanup item %d not at FULL' % i) + rr = (it[1],) if it[0] == 'warp' else regs_of(it) + for r in rr: + if r in P['buffers']: + continue + need(r in cur and cur[r] == full, 'frame', + 'cleanup item %d touches register %d whose frame is not FULL' % (i, r)) + for r in P['live']: + need(per_reg[r] == len(P['end'][r]) - len(P['start'][r]), 'frame', 'per-register charge != width for %d' % r) + helpers = [r for r in P['live'] if r >= 2 * v] + inventory = Counter(len(P['end'][r]) - len(P['start'][r]) for r in helpers) + return dict(paid=paid, climbs=climbs, copies=copies, warp_charge=warp_charge, inventory=inventory, + helpers=len(helpers), widths=[len(P['end'][r]) - len(P['start'][r]) for r in sorted(helpers)], + mass=sum(k * c for k, c in paid.items())) + + +# ---------------------------------------------------------------------------- +# Check 3: exact replay over the free-group algebra Q +# ---------------------------------------------------------------------------- + +ONE = Fraction(1) + + +def replay(P, dual=False): + v, n = P['v'], P['n'] + rows = {} + for r in P['live']: + rows[r] = {(r, ()): ONE} + for b in P['buffers']: + rows[b] = {} + istarget = lambda r: v <= r < 2 * v + + def row(r): + need(r in rows, 'replay', 'unknown register %d' % r) + return rows[r] + + def do(it): + kind = it[0] + if kind == 'add': + t, s, c = it[1], it[2], it[3] + if dual: + t, s, c = s, t, -c + src, dst = row(s), row(t) + for key, val in src.items(): + nv = dst.get(key, 0) + c * val + if nv: + dst[key] = nv + else: + del dst[key] + elif kind == 'scale': + t, c = it[1], it[2] + if dual: + c = 1 / c + rr = row(t) + for key in rr: + rr[key] = rr[key] * c + elif kind == 'warp': + reg, k = it[1], it[2] + letter = (abs(k), 1 if dual else 0, 1 if k > 0 else -1) + inverse = (letter[0], letter[1], -letter[2]) + old = row(reg) + new = {} + for (var, word), val in old.items(): + nw = word[1:] if (word and word[0] == inverse) else (letter,) + word + new[(var, nw)] = val + rows[reg] = new + else: + raise Reject('replay', 'unknown item') + + before = list(P['pre']) + list(P['A']) + list(P['cut']) + for it in before: + do(it) + for it in P['B_items']: + if it[0] == 'warp': + do(('warp', it[1], it[2])) + else: + do(it) + for it in P['post']: + do(it) + diag = {} + need(all(not rows[b] for b in P['buffers']), 'replay', 'a buffer is non-zero before cleanup') + if not dual: + for t in range(v): + need(rows[v + t] == {(v + t, ()): ONE, (t, ()): ONE}, 'replay', 'target %d not final before cleanup' % t) + for r in P['restored']: + need(rows[r] == {(r, ()): ONE}, 'replay', 'restored cold register %d is not its own input' % r) + readers = [r for r in P['live'] if r not in P['restored'] and not istarget(r) + and any(var in P['restored'] for var, _ in rows[r])] + need(not readers, 'replay', 'restored inputs still read by %r' % readers[:5]) + diag['rows_with_operator_words_before_cleanup'] = sum( + 1 for r in P['live'] if any(word for _, word in rows[r])) + peak = 0 + first_live = last_live = None + span_of = {} + noop_buffer_reads = 0 + for i, it in enumerate(P['cleanup']): + if it[0] == 'add': + src = it[2] if not dual else it[1] + if src in P['buffers'] and not rows[src]: + noop_buffer_reads += 1 + do(it) + live_buffers = 0 + for b in P['buffers']: + if rows[b]: + live_buffers += 1 + lo, hi = span_of.get(b, (i, i)) + span_of[b] = (min(lo, i), i) + if live_buffers: + first_live = i if first_live is None else first_live + last_live = i + peak = max(peak, live_buffers) + events = sorted([(lo, 1) for lo, hi in span_of.values()] + [(hi + 1, -1) for lo, hi in span_of.values()]) + overlap = best = 0 + for _, d in events: + overlap += d + best = max(best, overlap) + diag['buffers_ever_nonzero'] = len(span_of) + diag['max_overlap_of_buffer_lifetimes'] = best + diag['cleanup_adds_reading_a_zero_buffer'] = noop_buffer_reads + for r in P['live']: + if dual: + exp = {(r, ()): ONE, (r + v, ()): -ONE} if r < v else {(r, ()): ONE} + else: + exp = {(r, ()): ONE, (r - v, ()): ONE} if istarget(r) else {(r, ()): ONE} + need(rows[r] == exp, 'replay', 'final map wrong on register %d (%s)' % (r, 'dual' if dual else 'forward')) + need(all(not rows[b] for b in P['buffers']), 'replay', 'a zero buffer is not returned to zero') + diag.update(peak_nonzero_buffers=peak, buffer_nonzero_window=[first_live, last_live], + buffers=len(P['buffers']), independent_inputs=len(P['live'])) + return diag + + +# ---------------------------------------------------------------------------- +# Links between the borrowed word, its canonical base, witness, providers, 566 word +# ---------------------------------------------------------------------------- + +def coef(g): + return g[3] if g[0] == 'add' else g[2] + + +def norm(g): + return (g[0],) + tuple(regs_of(g)) + (coef(g), g[-1]) + + +def link_checks(tag, P, C, wit, blocks, providers, fr): + out = {} + need(P['ports'] == C['ports'] and P['centers'] == C['centers'], 'link', 'ports/centres differ from canonical') + need(P['center_frames'] == C['center_frames'], 'link', 'centre frames differ from canonical') + removed = P['removed'] + touches = lambda g: any(r in removed for r in regs_of(g)) + need(not any(touches(g) for g in C['sections']['compensation']), 'link', + 'canonical compensation reads a removed helper (a removed helper has non-zero response)') + for name in ('precondition', 'compensation', 'A', 'cut'): + kept = [norm(g) for g in C['sections'][name] if not touches(g)] + need([norm(g) for g in P['sections'][name]] == kept, 'link', 'section %s != canonical minus removed' % name) + out['canonical_%s_gates_dropped' % name] = len(C['sections'][name]) - len(kept) + v, n, h = P['v'], P['n'], P['h'] + for r in P['live']: + if r >= 2 * v: + need(P['start'][r] == C['start'][r], 'link', 'start frame of %d differs from canonical' % r) + for r in P['restored']: + need(P['end'][r] == C['end'][r], 'link', 'cold end frame of %d differs from canonical' % r) + canon_cold = [r for r in range(2 * v, n) if len(C['end'][r]) < h] + out['canonical_cold_helpers'] = len(canon_cold) + out['canonical_cold_helpers_ending_FULL_after_borrowing'] = sorted( + r for r in canon_cold if r not in removed and r not in P['restored']) + # exact mass bookkeeping: local mass = sum of all register widths + COPY mass, so the saving must equal + # (canonical widths of removed helpers) - (width added to canonical cold helpers that now end at FULL) + grown = sum(len(P['end'][r]) - len(C['end'][r]) for r in out['canonical_cold_helpers_ending_FULL_after_borrowing']) + removed_widths = sum(len(C['end'][r]) - len(C['start'][r]) for r in removed) + others_same = all(P['start'][r] == C['start'][r] and P['end'][r] == C['end'][r] for r in P['live'] + if r not in out['canonical_cold_helpers_ending_FULL_after_borrowing']) + need(others_same, 'link', 'some other register changed its start/end frame') + out['mass_identity'] = dict(removed_widths=removed_widths, width_added_to_cold_now_FULL=grown, + predicted_saving=removed_widths - grown) + high = set() + low = set() + for bl in blocks['sources'][0]['blocks']: + high |= set(bl['high']) + low |= set(bl['low']) + need(removed <= high and not (removed & low), 'link', 'removed helpers are not all high helpers') + out['high_helpers_in_blocks'] = len(high) + old_w = Counter(len(C['end'][r]) - len(C['start'][r]) for r in removed) + out['removed_old_widths'] = dict(sorted(old_w.items())) + need(dict(old_w) == CLAIMS['removed_old_widths'][tag], 'link', 'removed helper canonical widths %r' % dict(old_w)) + # witness: pairs <-> warp records + need(wit['initial_corrections'] == [], 'link', 'witness has initial corrections') + pairs = wit['pairs'] + need(len(pairs) == len(P['warps']), 'link', 'witness pair count') + gauss = dict((g['operator'], g['G_columns']) for g in wit['gaussian']['records']) + for wr, pr in zip(P['warps'], pairs): + k = wr['op'] + need(pr['borrow_from'] == wr['lender'], 'link', 'warp %d lender != witness borrow_from' % k) + need(gauss.get(k) == wr['G'], 'link', 'warp %d G != witness Gaussian record' % k) + need(span(pr['retirement_basis']) == wr['U'], 'link', 'warp %d U != witness retirement basis' % k) + need(span(pr['handoff_basis']) == wr['E'], 'link', 'warp %d E != witness handoff basis' % k) + need(pr['anticipate'] is False and pr['low'] is False and pr['handoff_paid_rank'] == 0, 'link', + 'warp %d witness flags' % k) + need(set(p['register'] for p in pairs) == removed, 'link', 'witness registers != removed set') + # B multiset: canonical B plus the 48 moved tail gates, with each removed helper renamed to its lender + rename = dict((p['register'], p['borrow_from']) for p in pairs) + def ren(g): + if g[0] == 'add': + return ('add', rename.get(g[1], g[1]), rename.get(g[2], g[2]), g[3], g[4]) + return ('scale', rename.get(g[1], g[1]), g[2], g[3]) + moved = [C['sections']['tail'][e['old_tail_index']] for e in wit['early_tail_events']] + lhs = Counter(norm(ren(g)) for g in list(C['sections']['B']) + moved) + rhs = Counter(norm(it) for it in P['B_items'] if it[0] != 'warp') + out['B_multiset_equals_canonical_B_plus_moved_tail_renamed'] = (lhs == rhs) + need(lhs == rhs, 'link', 'B multiset != canonical B + moved tail (renamed)') + out['moved_tail_gates'] = len(moved) + # providers (interface to the owner fill) + need(providers['widths'] == fr['widths'], 'link', 'BORROW-PROVIDERS widths != recount') + need(dict((int(k), c) for k, c in providers['actual_paid_profile'].items()) == dict(fr['paid']), 'link', + 'BORROW-PROVIDERS paid profile != recount') + out['providers_widths_match'] = True + return out + + +def link_566(C, o): + """Canonical word == predecessor 566 word up to a register permutation and a linear frame map.""" + h = C['h'] + pi = {} + pairs = {} + + def lit(F): + return None if F is None else span(F) + + def add_pair(a, b, where): + need((a is None) == (b is None), 'link566', 'frame presence differs at %s' % where) + if a is not None: + need(pairs.setdefault(a, b) == b, 'link566', 'inconsistent frame pair at %s' % where) + + def align(cg, og, where): + need(cg[0] == og[0], 'link566', 'op differs at %s' % where) + oc = conv_gate(og, lit, where) + need(coef(cg) == coef(oc), 'link566', 'coefficient differs at %s' % where) + for x, y in zip(regs_of(cg), regs_of(oc)): + need(pi.setdefault(x, y) == y, 'link566', 'register map conflict at %s' % where) + add_pair(cg[-1], oc[-1], where) + + for name in ('precondition', 'A', 'cut', 'B'): + need(len(C['sections'][name]) == len(o[name]), 'link566', 'length of %s' % name) + for i, (cg, og) in enumerate(zip(C['sections'][name], o[name])): + align(cg, og, '%s[%d]' % (name, i)) + early = o['early_cleanup'] + eidx = [e[0] for e in early] + need(len(set(eidx)) == len(eidx) == len(C['sections']['tail']), 'link566', 'early cleanup count') + rest = [g for i, g in enumerate(o['cleanup']) if i not in set(eidx)] + need(len(rest) == len(C['sections']['cleanup']), 'link566', 'cleanup length') + for i, (cg, og) in enumerate(zip(C['sections']['cleanup'], rest)): + align(cg, og, 'cleanup[%d]' % i) + for i, (cg, (j, F)) in enumerate(zip(C['sections']['tail'], early)): + og = list(o['cleanup'][j][:-1]) + [F] + align(cg, og, 'tail[%d]' % i) + need(len(pi) == C['n'] and len(set(pi.values())) == C['n'], 'link566', 'register map is not a bijection') + v = C['v'] + need(all((x < v) == (y < v) and (x < 2 * v) == (y < 2 * v) for x, y in pi.items()), 'link566', 'roles not preserved') + need(all(x == y for x, y in pi.items() if x >= 2 * v), 'link566', 'helpers renumbered') + # linear frame map tau from 1-dim pairs, then verified on every frame + ones = [(a[0], b[0]) for a, b in pairs.items() if len(a) == 1 and b is not None and len(b) == 1] + piv = {} + for a, b in ones: + x, y = a, b + for p in list(piv): + pa, pb = piv[p] + if (x >> p) & 1: + x ^= pa + y ^= pb + if x: + lead = x.bit_length() - 1 + for p in list(piv): + pa, pb = piv[p] + if (pa >> lead) & 1: + piv[p] = (pa ^ x, pb ^ y) + piv[lead] = (x, y) + need(len(piv) == h, 'link566', 'one-dimensional frame pairs do not span F_2^h') + tau = [0] * h + for p, (a, b) in piv.items(): + need(a == 1 << p, 'link566', 'tau construction') + tau[p] = b + need(mat_inverse(tau, h) is not None, 'link566', 'tau singular') + tmap = lambda S: span([mat_apply(tau, x) for x in S]) + for a, b in pairs.items(): + need(tmap(a) == b, 'link566', 'frame pair not induced by the linear map tau') + for i in range(v): + need(mat_apply(tau, C['ports'][i]) == o['ports'][pi[i]], 'link566', 'port %d' % i) + need([pi[q] for q in C['centers']] == o['centers'], 'link566', 'centres') + need([tmap(F) for F in C['center_frames']] == [span(F) for F in o['center_frames']], 'link566', 'centre frames') + full = C['full'] + for r in range(2 * v, C['n']): + os_ = span(o['start_extra'][str(r)]) if str(r) in o['start_extra'] else () + oe = span(o['helper_final'][str(r)]) if str(r) in o['helper_final'] else full + need(tmap(C['start'][r]) == os_, 'link566', 'helper start %d' % r) + need(tmap(C['end'][r]) == oe, 'link566', 'helper end %d' % r) + need(dict((int(k), c) for k, c in o['report']['local_profile'].items()) == C['claimed_profile'], 'link566', + 'canonical local_profile != 566 report local_profile') + return dict(register_permutation_nonidentity=sum(1 for x, y in pi.items() if x != y), + frame_map_tau_columns=tau, aligned_frame_pairs=len(pairs)) + + +# ---------------------------------------------------------------------------- +# Driver +# ---------------------------------------------------------------------------- + +def dsort(c): + return dict((str(k), c[k]) for k in sorted(c)) + + +def expect_reject(name, target, fn, results, also=None): + """Run fn (which must raise Reject from check family `target`).""" + entry = dict(control=name, target_check=target) + try: + fn() + entry.update(rejected=False) + except Reject as e: + entry.update(rejected=True, by=e.check, reason=e.msg[:200]) + entry['ok'] = bool(entry['rejected'] and entry.get('by') == target) + if also is not None: + info = {} + for label, g in also: + try: + g() + info[label] = 'accepted' + except Reject as e: + info[label] = 'rejected[%s]' % e.check + entry['other_checks'] = info + results.append(entry) + print(' control %-58s target=%-8s %s' % (name, target, 'REJECTED-OK' if entry['ok'] else 'NOT-OK ' + str(entry)), flush=True) + return entry['ok'] + + +def mutate_P(P): + Q = dict(P) + for key in ('pre', 'A', 'cut', 'B_items', 'post', 'cleanup'): + Q[key] = list(P[key]) + Q['warps'] = [dict(w) for w in P['warps']] + return Q + + +def profile_check(P, fr, claim): + need(dict(fr['paid']) == P['claimed_profile'], 'profile', 'recount %r != word report %r' % (dsort(fr['paid']), P['claimed_profile'])) + need(dict(fr['paid']) == claim, 'profile', 'recount != claimed profile') + + +def controls_for(tag, P, claim, results): + ok = True + v = P['v'] + warps = P['warps'] + # pick a warp with U != E and its B-item index + k0 = next(w['op'] for w in warps if w['U'] != w['E']) + # 1. drop one warp from the forward word (cleanup keeps its inverse) + Q = mutate_P(P) + Q['B_items'] = [it for it in P['B_items'] if not (it[0] == 'warp' and it[2] == k0)] + ok &= expect_reject('drop forward warp %d' % k0, 'replay', lambda: replay(Q), results, + also=[('frame', lambda: frame_check(Q))]) + # 2. drop one inverse warp in cleanup + Q2 = mutate_P(P) + j = next(i for i, it in enumerate(P['cleanup']) if it[0] == 'warp' and it[2] == -k0) + del Q2['cleanup'][j] + ok &= expect_reject('drop inverse warp %d in cleanup' % k0, 'replay', lambda: replay(Q2), results, + also=[('frame', lambda: frame_check(Q2))]) + # 3. perturb one coefficient (one dyadic step: c -> 2c) in B after the first warp, in compensation, in cleanup + lender = next(w['lender'] for w in warps if w['op'] == k0) + wi = next(i for i, it in enumerate(P['B_items']) if it[0] == 'warp' and it[2] == k0) + bi = next(i for i in range(wi + 1, len(P['B_items'])) if P['B_items'][i][0] == 'add' and lender in regs_of(P['B_items'][i])) + for label, key, idx in (('B item %d (lender %d after its warp)' % (bi, lender), 'B_items', bi), + ('compensation gate 0', 'pre', P['n_pre']), + ('first cleanup add between live registers', 'cleanup', + next(i for i, it in enumerate(P['cleanup']) + if it[0] == 'add' and it[1] not in P['buffers'] and it[2] not in P['buffers']))): + Q3 = mutate_P(P) + g = list(Q3[key][idx]) + g[3] = g[3] * 2 + Q3[key][idx] = tuple(g) + ok &= expect_reject('perturb coefficient x2: %s' % label, 'replay', lambda: replay(Q3), results, + also=[('frame', lambda: frame_check(Q3))]) + # 4a. treat the warp frame change as an ordinary climb (no K_G) + ok &= expect_reject('warp %d as an ordinary climb U->E' % k0, 'frame', + lambda: frame_check(P, warp_as_climb=(k0,)), results) + # 4b. charge every warp its plain Fourier distance d(L_U, L_E) + def charged(): + fr = frame_check(P, charge_warps=True) + profile_check(P, fr, claim) + ok &= expect_reject('charge every warp as a climb of rank d(L_U,L_E)', 'profile', charged, results) + # 5. swap two warp lenders (warps at one position with different U) + pair = None + for a in warps: + for b in warps: + if a['op'] < b['op'] and a['pos'] == b['pos'] and a['U'] != b['U']: + pair = (a['op'], b['op']) + break + if pair: + break + need(pair is not None, 'control', 'no swappable warp pair') + la = next(w['lender'] for w in warps if w['op'] == pair[0]) + lb = next(w['lender'] for w in warps if w['op'] == pair[1]) + Q5 = mutate_P(P) + Q5['B_items'] = [(it[0], lb if it[1] == la else la, it[2], it[3], it[4]) + if it[0] == 'warp' and it[2] in pair else it for it in P['B_items']] + ok &= expect_reject('swap lenders of warps %d,%d' % pair, 'frame', lambda: frame_check(Q5), results, + also=[('replay', lambda: replay(Q5))]) + # 6. warp algebra: singular G, invertible G with G U != E, dimension mismatch + def warp_mut(fn): + wr = dict(warps[0]) + fn(wr) + return lambda: check_warp(wr, P['h'], set(P['live']), v) + + def singular(wr): + wr['G'] = list(wr['G']) + wr['G'][1] = wr['G'][0] + ok &= expect_reject('warp 1: singular G', 'warp', warp_mut(singular), results) + + def wrong_image(wr): + h = P['h'] + for j in range(h): + for i in range(h): + if i == j: + continue + G = list(wr['G']) + G[j] ^= G[i] + if mat_inverse(G, h) is not None and span([mat_apply(G, u) for u in wr['U']]) != wr['E']: + wr['G'] = G + return + raise Reject('control', 'no wrong-image G found') + ok &= expect_reject('warp 1: invertible G with G span U != span E', 'warp', warp_mut(wrong_image), results) + + def dim_drop(wr): + wr['E_list'] = wr['E_list'][:-1] + wr['E'] = span(wr['E_list']) + ok &= expect_reject('warp 1: dim E != dim U', 'warp', warp_mut(dim_drop), results) + # 7. cleanup reads a restored register directly instead of its zero buffer + Q7 = mutate_P(P) + j = next(i for i, it in enumerate(P['cleanup']) if it[0] == 'add' and (it[1] in P['buffers'] or it[2] in P['buffers'])) + it = list(P['cleanup'][j]) + if it[1] in P['buffers']: + it[1] -= P['n'] + else: + it[2] -= P['n'] + Q7['cleanup'][j] = tuple(it) + ok &= expect_reject('cleanup item %d uses the restored register, not its buffer' % j, 'frame', + lambda: frame_check(Q7), results) + # 8. delete one restore gate + Q8 = mutate_P(P) + del Q8['post'][0] + ok &= expect_reject('delete restore gate 0', 'replay', lambda: replay(Q8), results) + # 9. delete one T74 compensation gate (dirty helper inputs are live symbols) + Q9 = mutate_P(P) + del Q9['pre'][P['n_pre']] + ok &= expect_reject('delete compensation gate 0', 'replay', lambda: replay(Q9), results) + # 10. drop the cleanup adds that read a never-yet-written buffer: no-ops in the forward replay, but in the + # dual (s -= c t) they write the buffer, so only the dual replay can reject this + Q10 = mutate_P(P) + written, keep = set(), [] + for it in P['cleanup']: + if it[0] == 'add' and it[2] in P['buffers'] and it[2] not in written: + continue + if it[0] == 'add' and it[1] in P['buffers']: + written.add(it[1]) + keep.append(it) + Q10['cleanup'] = keep + ok &= expect_reject('drop %d forward-no-op cleanup adds (dual replay)' % (len(P['cleanup']) - len(keep)), 'replay', + lambda: replay(Q10, dual=True), results, also=[('forward replay', lambda: replay(Q10))]) + ok &= results[-1]['other_checks']['forward replay'] == 'accepted' # they really are forward no-ops + # positive mutation: re-express U and E of every warp in another basis of the same span + Qp = mutate_P(P) + rebased = [] + for wr in warps: + w2 = dict(wr) + if len(w2['U_list']) > 1: + w2['U_list'] = [w2['U_list'][0] ^ w2['U_list'][1]] + w2['U_list'][1:] + w2['E_list'] = w2['E_list'][1:] + [w2['E_list'][0] ^ w2['E_list'][-1]] + w2['U'], w2['E'] = span(w2['U_list']), span(w2['E_list']) + rebased.append(w2) + entry = dict(control='positive: rebased warp U/E lists (same spans) accepted', target_check='warp+frame') + try: + for w2 in rebased: + check_warp(w2, P['h'], set(P['live']), v) + Qp['warps'] = rebased + frp = frame_check(Qp) + profile_check(Qp, frp, claim) + entry.update(accepted=True, ok=True) + except Reject as e: + entry.update(accepted=False, ok=False, reason=str(e)) + print(' control %-58s %s' % (entry['control'], 'ACCEPTED-OK' if entry['ok'] else 'NOT-OK'), flush=True) + results.append(entry) + ok &= entry['ok'] + return ok + + +def main(): + ap = argparse.ArgumentParser(description='Independent check of PR2269 BORROW-WORD-43{base,extra}') + ap.add_argument('--repo', default=DEFAULT_REPO, help='git checkout containing commit %s' % COMMIT) + ap.add_argument('--blob-dir', default=None, help='directory with exported blobs (basename of each path)') + ap.add_argument('--out', default=None, help='JSON receipt path (must be next to this script)') + ap.add_argument('--skip-controls', action='store_true', help='skip negative controls (not a PASS run)') + args = ap.parse_args() + if sys.flags.optimize: + print('refusing to run under -O') + print(FAIL_LINE) + return 2 + here = os.path.dirname(os.path.abspath(__file__)) + if args.out is not None: + if os.path.dirname(os.path.abspath(args.out)) != here: + print('--out must name a file next to this script (%s)' % here) + print(FAIL_LINE) + return 2 + t0 = time.time() + receipt = dict(checker='words_check.py', object=dict(pr=2269, commit=COMMIT, package=PKG), + python=sys.version.split()[0], scope='task A: BORROW-WORD-43{base,extra} and new/borrow/inputs') + ok = True + try: + js, pins, raw = load_inputs(args.repo, args.blob_dir) + receipt['pins'] = pins + print('pins: %d input blobs verified (sha256 + git blob id)' % len(pins), flush=True) + words = {} + for tag in ('base', 'extra'): + claim = CLAIMS[tag] + print('== word 43%s' % tag, flush=True) + w = js['word_' + tag] + res = dict(base_tag=w.get('base')) + need(w.get('base') == claim['base_tag'], 'link', 'base tag') + need(PINS['word566_' + tag][2].startswith(w['base']), 'link', 'base tag is not the 566 word sha256 prefix') + P = parse_borrow(w) + C = parse_canonical(js['canon_' + tag]) + # 1. warps + wres = check_all_warps(P) + res['warps'] = dict(count=len(wres), dims=dsort(Counter(x['dim'] for x in wres)), + positions=[x['pos'] for x in wres], lenders=[x['lender'] for x in wres], + lenders_that_are_X=[x['lender'] for x in wres if x['lender'] < P['v']], + lenders_that_are_restored_cold=[x['lender'] for x in wres if x['lender'] in P['restored']], + U_equal_E=sum(1 for x in wres if x['U_eq_E']), + U_inside_E=sum(1 for x in wres if x['U_in_E']), + plain_fourier_distance=dsort(Counter(x['plain_fourier_distance'] for x in wres)), + anticipatory_terms=len(w['initial_corrections'])) + need(len(wres) == CLAIMS['warps'], 'warp', 'warp count') + print(' warps: %d PASS (dims %s); anticipatory terms %d' % (len(wres), res['warps']['dims'], len(w['initial_corrections'])), flush=True) + # 2. frames + profile + fr = frame_check(P) + profile_check(P, fr, claim['profile']) + need(dict(fr['inventory']) == CLAIMS['width_inventory'] == P['claimed_inventory'], 'profile', 'width inventory') + need(fr['helpers'] == CLAIMS['helpers_after'] == P['R'] - len(P['removed']), 'profile', 'helper count') + need(fr['mass'] == CLAIMS['mass'], 'profile', 'local mass') + frc = frame_check(P, charge_warps=True) + res['frames'] = dict(model_ok=True, paid_profile=dsort(fr['paid']), climbs=dsort(fr['climbs']), + copy_charges=dsort(fr['copies']), local_mass=fr['mass'], + width_inventory=dsort(fr['inventory']), helpers=fr['helpers'], + if_warps_charged_profile=dsort(frc['paid']), if_warps_charged_mass=frc['mass']) + print(' frames: PASS; paid %s (climbs %s + COPY %s), mass %d, helpers %d, inventory %s' % ( + res['frames']['paid_profile'], res['frames']['climbs'], res['frames']['copy_charges'], fr['mass'], + fr['helpers'], res['frames']['width_inventory']), flush=True) + # 3. replay + rf = replay(P) + rd = replay(P, dual=True) + res['replay'] = dict(forward=rf, dual=rd) + print(' replay: forward PASS %s; dual PASS' % rf, flush=True) + # links + res['links'] = link_checks(tag, P, C, js['witness_' + tag], js['blocks'], + js['providers'][claim['providers_key']], fr) + print(' links: PASS %s' % {k: v for k, v in res['links'].items() if k != 'canonical_cold_helpers_ending_FULL_after_borrowing'}, flush=True) + # 5. positive control: canonical words + frC = frame_check(C) + need(dict(frC['paid']) == C['claimed_profile'] == claim['old_profile'], 'canonical', + 'canonical profile not reproduced: %r' % dsort(frC['paid'])) + rC = replay(C) + l566 = link_566(C, js['word566_' + tag]) + res['canonical'] = dict(paid_profile=dsort(frC['paid']), climbs=dsort(frC['climbs']), + copy_charges=dsort(frC['copies']), local_mass=frC['mass'], + width_inventory=dsort(frC['inventory']), helpers=frC['helpers'], replay=rC, + link_566=l566) + print(' canonical positive control: profile %s mass %d reproduced, replay PASS, 566-link PASS' % ( + res['canonical']['paid_profile'], frC['mass']), flush=True) + res['saving'] = dict(mass_before=frC['mass'], mass_after=fr['mass'], helpers_before=frC['helpers'], + helpers_after=fr['helpers']) + need(frC['mass'] - fr['mass'] == res['links']['mass_identity']['predicted_saving'] and + frC['copies'] == fr['copies'], 'profile', 'saving does not match the width bookkeeping') + if not args.skip_controls: + results = [] + cok = controls_for(tag, P, claim['profile'], results) + # canonical negative controls + CQ = mutate_P(C) + del CQ['pre'][C['n_pre']] + cok &= expect_reject('canonical: delete compensation gate 0', 'replay', lambda: replay(CQ), results) + CF = mutate_P(C) + CF['post'] = list(C['post']) + j = next(i for i, g in enumerate(C['post']) if g[-1] != C['full']) + g = list(C['post'][j]) + g[-1] = C['full'] + CF['post'][j] = tuple(g) + cok &= expect_reject('canonical: tail gate %d lifted to FULL (cold end violated)' % j, 'frame', + lambda: frame_check(CF), results) + o_mut = copy.deepcopy(js['word566_' + tag]) + o_mut['B'][0][-1] = o_mut['B'][1][-1] if span(o_mut['B'][1][-1]) != span(o_mut['B'][0][-1]) else [1] + cok &= expect_reject('566 link: one 566 B-gate frame changed', 'link566', + lambda: link_566(C, o_mut), results) + bad = bytearray(raw['word_' + tag]) + bad[len(bad) // 2] ^= 1 + cok &= expect_reject('pin: one flipped bit in the word blob', 'pin', + lambda: verify_pin('word_' + tag, bytes(bad)), results) + res['controls'] = results + res['controls_ok'] = bool(cok) + ok &= bool(cok) + words[tag] = res + receipt['words'] = words + fb, fe = words['base'], words['extra'] + bf = fb['replay']['forward'] + # the summary below speaks for both words: assert that the shared facts really are shared + for key in ('dims', 'lenders', 'lenders_that_are_X', 'plain_fourier_distance', 'anticipatory_terms'): + need(fb['warps'][key] == fe['warps'][key], 'summary', 'warp fact %s differs between words' % key) + need(fb['replay']['forward'] == fe['replay']['forward'] and fb['replay']['dual'] == fe['replay']['dual'], + 'summary', 'buffer diagnostics differ between words') + bd = fb['replay']['dual'] + need(fb['frames']['local_mass'] == fe['frames']['local_mass'] and + fb['frames']['if_warps_charged_mass'] == fe['frames']['if_warps_charged_mass'], 'summary', 'mass differs') + need(fb['links']['canonical_cold_helpers_ending_FULL_after_borrowing'] == + fe['links']['canonical_cold_helpers_ending_FULL_after_borrowing'], 'summary', 'cold-to-FULL list differs') + need(fb['canonical']['helpers'] == fe['canonical']['helpers'] == CLAIMS['helpers_before'], 'summary', + 'unborrowed helper count') + cold_full = fb['links']['canonical_cold_helpers_ending_FULL_after_borrowing'] + cold_lenders = sorted(set(cold_full) & set(fb['warps']['lenders'])) + ncomp = len(js['canon_base']['compensation']) + receipt['findings'] = [ + 'Both words: 43 warps pass the GF(2) checks (G invertible, dim U = dim E, G span U = span E, ' + 'K_G symplectic, fixes L_0 and L_FULL, K_G L_U = L_E, Fourier rank 0); handoff dims %s; ' + '%d anticipatory/initial correction terms; the %d-gate T74 compensation is the canonical one ' + 'unchanged (%d + %d gates dropped, i.e. none reads a removed helper).' % ( + fb['warps']['dims'], fb['warps']['anticipatory_terms'], ncomp, + fb['links']['canonical_compensation_gates_dropped'], fe['links']['canonical_compensation_gates_dropped']), + 'Paid profiles recounted exactly: base %s, extra %s (climbs + COPY %s); mass %d both; ' + '%d helpers (from %d); width inventory %s.' % ( + fb['frames']['paid_profile'], fe['frames']['paid_profile'], fb['frames']['copy_charges'], + fb['frames']['local_mass'], fb['frames']['helpers'], fb['canonical']['helpers'], + fb['frames']['width_inventory']), + 'Exact replay over Q in both orientations: Y_i <- Y_i + X_i, all other %d non-target registers (X and live helpers) restored, ' + '%d zero buffers returned to zero.' % (bf['independent_inputs'] - 112, bf['buffers']), + 'Canonical inputs reproduce the old profiles (base %s mass %d; extra %s mass %d), replay exactly, ' + 'and equal the pinned 566 predecessor words up to a role-preserving register permutation and a ' + 'linear frame map.' % (fb['canonical']['paid_profile'], fb['canonical']['local_mass'], + fe['canonical']['paid_profile'], fe['canonical']['local_mass']), + 'README imprecision: "8 width-4, 35 width-5" holds for the base word; the extra word removes ' + 'helpers of canonical widths %s.' % fe['links']['removed_old_widths'], + 'Canonical cold helpers %s end at FULL after borrowing (of these, %s also lend); with the removed ' + 'widths this gives the exact mass savings %d (base) and %d (extra).' % ( + cold_full, cold_lenders, + fb['canonical']['local_mass'] - fb['frames']['local_mass'], + fe['canonical']['local_mass'] - fe['frames']['local_mass']), + 'Lenders that are source registers X: %s; lenders that are restored cold helpers: %s.' % ( + fb['warps']['lenders_that_are_X'], fb['warps']['lenders_that_are_restored_cold']), + 'Cleanup uses %d private zero buffers outside the helper inventory. Forward orientation: at most %d are ' + 'non-zero simultaneously (max overlap of lifetimes %d); %d cleanup adds read a still-zero buffer (no-ops ' + 'in the forward replay only: in the dual such an add writes the buffer, and dropping those that read a ' + 'never-written buffer is rejected by the dual replay, see the controls). Dual orientation: at most %d ' + 'non-zero simultaneously (%d ever non-zero). No paid child runs in ' + 'cleanup. Peak helper-like fields during cleanup are %d+%d = %d (lazy, forward), %d+%d = %d (lazy, dual) ' + 'or %d+%d = %d (eager); the unborrowed word uses %d. Whether the global accounting must host them is a ' + 'global-model question that is not decided here.' % ( + bf['buffers'], bf['peak_nonzero_buffers'], bf['max_overlap_of_buffer_lifetimes'], + bf['cleanup_adds_reading_a_zero_buffer'], bd['peak_nonzero_buffers'], bd['buffers_ever_nonzero'], + fb['frames']['helpers'], bf['peak_nonzero_buffers'], + fb['frames']['helpers'] + bf['peak_nonzero_buffers'], fb['frames']['helpers'], + bd['peak_nonzero_buffers'], fb['frames']['helpers'] + bd['peak_nonzero_buffers'], + fb['frames']['helpers'], bf['buffers'], fb['frames']['helpers'] + bf['buffers'], + fb['canonical']['helpers']), + 'Charging each warp as a plain frame change (rank d(L_U,L_E), distances %s) would raise the local mass ' + 'from %d to %d; the saving depends on rank-zero K_G handoffs, checked here only at the binary ' + 'symplectic level.' % (fb['warps']['plain_fourier_distance'], fb['frames']['local_mass'], + fb['frames']['if_warps_charged_mass']), + ] + receipt['not_checked'] = [ + 'Exact Clifford (Gaussian-dyadic, unit quadratic phase) lifts of K_G and their native lowering; only the ' + 'binary symplectic image is checked (it determines the Fourier rank by notes/general-clifford-frames.tex).', + 'Native word lowering, both hosted orientations at the native level, owner/window hosting of the 437 ' + 'helpers and the 76 buffers, precision/tape, global profile, kappa and outer assembly.', + 'Provenance of the 566 predecessor words beyond their pinned blobs (they are taken as the old record inputs).', + ] + receipt['buffers_note'] = ( + 'Each borrowed word uses %d private zero buffers (one per restored cold helper) only inside the ' + 'FULL-frame cleanup; they are not among the 437 helpers of the width inventory. No paid child occurs ' + 'in cleanup (all items at FULL).' % words['base']['replay']['forward']['buffers']) + for line in receipt['findings']: + print('FINDING: ' + line) + except Reject as e: + ok = False + receipt['failure'] = str(e) + print('FAILED: %s' % e, flush=True) + receipt['skip_controls'] = bool(args.skip_controls) + receipt['result'] = PASS_LINE if (ok and not args.skip_controls) else FAIL_LINE + receipt['model'] = __doc__.split('MODEL (stated precisely; see also the receipt field "model").')[1].strip() + print('elapsed %.1f s' % (time.time() - t0)) + if args.out is not None: + with open(args.out, 'w') as fh: + json.dump(receipt, fh, indent=1, sort_keys=True) + fh.write('\n') + print('receipt written: %s' % args.out) + print(receipt['result']) + return 0 if receipt['result'] == PASS_LINE else 1 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/research/t74-borrow43-independent-check/words_check.receipt.json b/research/t74-borrow43-independent-check/words_check.receipt.json new file mode 100644 index 0000000000..a2e757a1c1 --- /dev/null +++ b/research/t74-borrow43-independent-check/words_check.receipt.json @@ -0,0 +1,990 @@ +{ + "buffers_note": "Each borrowed word uses 76 private zero buffers (one per restored cold helper) only inside the FULL-frame cleanup; they are not among the 437 helpers of the width inventory. No paid child occurs in cleanup (all items at FULL).", + "checker": "words_check.py", + "findings": [ + "Both words: 43 warps pass the GF(2) checks (G invertible, dim U = dim E, G span U = span E, K_G symplectic, fixes L_0 and L_FULL, K_G L_U = L_E, Fourier rank 0); handoff dims {'4': 40, '5': 3}; 0 anticipatory/initial correction terms; the 7208-gate T74 compensation is the canonical one unchanged (0 + 0 gates dropped, i.e. none reads a removed helper).", + "Paid profiles recounted exactly: base {'1': 2351, '2': 501, '3': 414, '4': 129, '5': 42, '8': 8}, extra {'1': 2339, '2': 509, '3': 418, '4': 125, '5': 42, '8': 8} (climbs + COPY {'8': 8}); mass 5385 both; 437 helpers (from 480); width inventory {'4': 36, '5': 9, '7': 36, '8': 116, '9': 240}.", + "Exact replay over Q in both orientations: Y_i <- Y_i + X_i, all other 549 non-target registers (X and live helpers) restored, 76 zero buffers returned to zero.", + "Canonical inputs reproduce the old profiles (base {'1': 2348, '2': 500, '3': 416, '4': 130, '5': 82, '8': 8} mass 5590; extra {'1': 2340, '2': 508, '3': 420, '4': 126, '5': 82, '8': 8} mass 5594), replay exactly, and equal the pinned 566 predecessor words up to a role-preserving register permutation and a linear frame map.", + "README imprecision: \"8 width-4, 35 width-5\" holds for the base word; the extra word removes helpers of canonical widths {4: 4, 5: 39}.", + "Canonical cold helpers [533, 554] end at FULL after borrowing (of these, [554] also lend); with the removed widths this gives the exact mass savings 205 (base) and 209 (extra).", + "Lenders that are source registers X: [73]; lenders that are restored cold helpers: [].", + "Cleanup uses 76 private zero buffers outside the helper inventory. Forward orientation: at most 44 are non-zero simultaneously (max overlap of lifetimes 44); 110 cleanup adds read a still-zero buffer (no-ops in the forward replay only: in the dual such an add writes the buffer, and dropping those that read a never-written buffer is rejected by the dual replay, see the controls). Dual orientation: at most 48 non-zero simultaneously (58 ever non-zero). No paid child runs in cleanup. Peak helper-like fields during cleanup are 437+44 = 481 (lazy, forward), 437+48 = 485 (lazy, dual) or 437+76 = 513 (eager); the unborrowed word uses 480. Whether the global accounting must host them is a global-model question that is not decided here.", + "Charging each warp as a plain frame change (rank d(L_U,L_E), distances {'2': 1, '4': 29, '6': 13}) would raise the local mass from 5385 to 5581; the saving depends on rank-zero K_G handoffs, checked here only at the binary symplectic level." + ], + "model": "* Registers 0..v-1 are X (sources), v..2v-1 are Y (targets), 2v..2v+R-1\n helpers; n = 2v+R. Removed helpers do not exist. A buffer register b = r+n\n exists only for r in helper_final (restored cold helpers) and only in cleanup.\n * Frame = GF(2)-subspace of F_2^h (h = 9), given by a list of bit-mask\n vectors; compared as spans (reduced echelon form). Start: X_i = span(port_i),\n Y = 0, helper = start_extra[r] or 0. End: X = FULL, Y_i = port_i^perp,\n helper = helper_final[r] or FULL.\n * Every framed gate (add t s c F | scale t c F) climbs each incident register\n from its current frame S to F; legal only if S <= F; a strict climb pays one\n child of rank dim F - dim S. precondition/compensation are at frame 0.\n * After A every target sits at its level (target_levels, here all 0) and\n every centre at its centre frame. cut gates (frame null) add c*centre into\n a target at its level; each centre pays one COPY child of rank\n dim(centre frame) - dim(level) per distinct served level (nested chain).\n * warp [pos, L, G, U, E] is inserted before B[pos] (list order inside a\n position): requires cur[L] == span U exactly, sets cur[L] = span E, pays\n nothing (rank-zero reference change K_G); logically L <- K_G L.\n * After B and restore every live register climbs to its end frame (paid).\n * cleanup items must all be at FULL, may touch only live registers whose\n current frame is FULL, or buffers; they pay nothing.\n * Logic: exact replay over Q (rationals x free group on K_1..K_43):\n every live register starts as an independent symbol (arbitrary dirty\n content), buffers start at 0; add t+=c*s, scale t*=c, warp left-multiplies\n by K_k^{+-1} with free-group cancellation. Accept iff after cleanup\n Y_i = Y_i + X_i, every other live register is its own input, and every\n buffer is 0. The dual orientation replays g^{-T} for every item\n (add -> s -= c t, scale -> 1/c, K -> K^{-T} as new free letters) and expects\n X_i = X_i - Y_i.\n * Warp algebra over GF(2): G (columns = images of unit vectors) invertible,\n dim U = dim E, G span U = span E, M = [[G,0],[G+G^-T,G^-T]] symplectic for\n w((x,z),(x',z')) = x.z' + z.x', M L_0 = L_0, M L_FULL = L_FULL,\n M L_U = L_E where L_W = {(u, u+p): u in W, p in W^perp}, and the Fourier\n rank h - dim(L_E cap M L_U) of R_in = T_E K_G T_U^-1 is 0; G^-T U^perp = E^perp.\n Exact Clifford phases / Gaussian monomial lifts are NOT checked here.", + "not_checked": [ + "Exact Clifford (Gaussian-dyadic, unit quadratic phase) lifts of K_G and their native lowering; only the binary symplectic image is checked (it determines the Fourier rank by notes/general-clifford-frames.tex).", + "Native word lowering, both hosted orientations at the native level, owner/window hosting of the 437 helpers and the 76 buffers, precision/tape, global profile, kappa and outer assembly.", + "Provenance of the 566 predecessor words beyond their pinned blobs (they are taken as the old record inputs)." + ], + "object": { + "commit": "b479fc5567bc09ab9185bffe89b62594f36d74e5", + "package": "research/gmx-t74-borrow43/", + "pr": 2269 + }, + "pins": { + "blocks": { + "bytes": 50270, + "git_blob": "c683574b3861678081fd5c5944dbd7a47309f6fd", + "path": "research/gmx-t74-borrow43/new/borrow/inputs/blocks.json", + "sha256": "ddfac1dae1fe7cc0a91e7c7205c6d9d0c07c682880aa34eed83bf4ad7384da9f" + }, + "canon_base": { + "bytes": 87678, + "git_blob": "4abb6e28f02c95b41ed345d4e4401d16d58ae791", + "path": "research/gmx-t74-borrow43/new/borrow/inputs/gauge44.canonical.json.gz", + "sha256": "65c6d17ffee2eacf27bff438f37fc549c9ed0c909cbc7a52976cc75cf2d15b91" + }, + "canon_extra": { + "bytes": 87680, + "git_blob": "e0d670d4351229ce6921ecfbecf180070b17616b", + "path": "research/gmx-t74-borrow43/new/borrow/inputs/extra.canonical.json.gz", + "sha256": "d7e48dcbafa236a2e1e41f7958244211506f7c7630fe6a2d43d2bdf17b7ae015" + }, + "providers": { + "bytes": 6427, + "git_blob": "42563d218a5c7321f686c1cf9b98e75883d85abc", + "path": "research/gmx-t74-borrow43/new/BORROW-PROVIDERS.json", + "sha256": "8324fcf5fd652af9793c1acbc5f5099ee0d2f1eefa0adfbb8335f3d31d891da2" + }, + "witness_base": { + "bytes": 45301, + "git_blob": "9f4b93f3bc52d4f4ffaa128cfd7ae574fd36c462", + "path": "research/gmx-t74-borrow43/new/borrow/inputs/witness_43_base.json", + "sha256": "67ffb66d94067f6e53aee9118fe90e14a57f497fc8b3f708b6dac3de2e58ff28" + }, + "witness_extra": { + "bytes": 45306, + "git_blob": "864ba533f50c2f1f639a6a3559b185bd321b923a", + "path": "research/gmx-t74-borrow43/new/borrow/inputs/witness_43_extra.json", + "sha256": "d46449c6dbf4477f260cf5baea9bbb570a66ee0b6db81f4a220b9e3086ae9e46" + }, + "word566_base": { + "bytes": 57438, + "git_blob": "76c01583a0286cddb0f71e0cb13077e4317104f6", + "path": "research/gmx-t74-borrow43/new/gauge44-word-566.json.gz", + "sha256": "eeb6a236ed0ea8873b8800947d0cd19c36a6fcfdf857fc42913cb45cd984f219" + }, + "word566_extra": { + "bytes": 57440, + "git_blob": "e86142b352466f54a3da38c96a6e1484145c3b5c", + "path": "research/gmx-t74-borrow43/new/extra-word-566.json.gz", + "sha256": "cd417b904408c221d9840d08faff8af040cc4207f9804284f2f5375d21298a62" + }, + "word_base": { + "bytes": 69989, + "git_blob": "448dd795adba29392a90b34aa3f1b1b796c7e0bd", + "path": "research/gmx-t74-borrow43/new/borrow/words/BORROW-WORD-43base.json.gz", + "sha256": "9492a5537fb87d9ca98dffcd0230f7625b3789744fa94e2f18acf23d91d998b5" + }, + "word_extra": { + "bytes": 69991, + "git_blob": "2b51ba96256283bbc5578f99b694c50edd8a0e35", + "path": "research/gmx-t74-borrow43/new/borrow/words/BORROW-WORD-43extra.json.gz", + "sha256": "87d51f5298101d5947f45c43ee02f0ec45d6acbddabb808d0d02db1eaf063734" + } + }, + "python": "3.14.4", + "result": "PASS_T74_BORROW43_WORDS_INDEPENDENT", + "scope": "task A: BORROW-WORD-43{base,extra} and new/borrow/inputs", + "skip_controls": false, + "words": { + "base": { + "base_tag": "eeb6a236", + "canonical": { + "climbs": { + "1": 2348, + "2": 500, + "3": 416, + "4": 130, + "5": 82 + }, + "copy_charges": { + "8": 8 + }, + "helpers": 480, + "link_566": { + "aligned_frame_pairs": 1008, + "frame_map_tau_columns": [ + 42, + 41, + 4, + 35, + 16, + 11, + 64, + 128, + 256 + ], + "register_permutation_nonidentity": 220 + }, + "local_mass": 5590, + "paid_profile": { + "1": 2348, + "2": 500, + "3": 416, + "4": 130, + "5": 82, + "8": 8 + }, + "replay": { + "buffer_nonzero_window": [ + null, + null + ], + "buffers": 0, + "buffers_ever_nonzero": 0, + "cleanup_adds_reading_a_zero_buffer": 0, + "independent_inputs": 704, + "max_overlap_of_buffer_lifetimes": 0, + "peak_nonzero_buffers": 0, + "rows_with_operator_words_before_cleanup": 0 + }, + "width_inventory": { + "4": 44, + "5": 44, + "7": 38, + "8": 114, + "9": 240 + } + }, + "controls": [ + { + "by": "replay", + "control": "drop forward warp 1", + "ok": true, + "other_checks": { + "frame": "rejected[frame]" + }, + "reason": "final map wrong on register 240 (forward)", + "rejected": true, + "target_check": "replay" + }, + { + "by": "replay", + "control": "drop inverse warp 1 in cleanup", + "ok": true, + "other_checks": { + "frame": "accepted" + }, + "reason": "final map wrong on register 240 (forward)", + "rejected": true, + "target_check": "replay" + }, + { + "by": "replay", + "control": "perturb coefficient x2: B item 972 (lender 243 after its warp)", + "ok": true, + "other_checks": { + "frame": "accepted" + }, + "reason": "target 81 not final before cleanup", + "rejected": true, + "target_check": "replay" + }, + { + "by": "replay", + "control": "perturb coefficient x2: compensation gate 0", + "ok": true, + "other_checks": { + "frame": "accepted" + }, + "reason": "target 1 not final before cleanup", + "rejected": true, + "target_check": "replay" + }, + { + "by": "replay", + "control": "perturb coefficient x2: first cleanup add between live registers", + "ok": true, + "other_checks": { + "frame": "accepted" + }, + "reason": "a zero buffer is not returned to zero", + "rejected": true, + "target_check": "replay" + }, + { + "by": "frame", + "control": "warp 1 as an ordinary climb U->E", + "ok": true, + "reason": "non-nested climb of 243 at warp 1 treated as an ordinary climb: (261, 133, 85, 45) -> (320, 192, 45, 30)", + "rejected": true, + "target_check": "frame" + }, + { + "by": "profile", + "control": "charge every warp as a climb of rank d(L_U,L_E)", + "ok": true, + "reason": "recount {'1': 2351, '2': 502, '3': 414, '4': 158, '5': 42, '6': 13, '8': 8} != word report {1: 2351, 2: 501, 3: 414, 4: 129, 5: 42, 8: 8}", + "rejected": true, + "target_check": "profile" + }, + { + "by": "frame", + "control": "swap lenders of warps 1,14", + "ok": true, + "other_checks": { + "replay": "rejected[replay]" + }, + "reason": "warp 1: lender 349 frame (416, 70, 19, 13) != U (261, 133, 85, 45)", + "rejected": true, + "target_check": "frame" + }, + { + "by": "warp", + "control": "warp 1: singular G", + "ok": true, + "reason": "warp 1: G is singular over GF(2)", + "rejected": true, + "target_check": "warp" + }, + { + "by": "warp", + "control": "warp 1: invertible G with G span U != span E", + "ok": true, + "reason": "warp 1: G span U != span E", + "rejected": true, + "target_check": "warp" + }, + { + "by": "warp", + "control": "warp 1: dim E != dim U", + "ok": true, + "reason": "warp 1: dim U != dim E", + "rejected": true, + "target_check": "warp" + }, + { + "by": "frame", + "control": "cleanup item 0 uses the restored register, not its buffer", + "ok": true, + "reason": "cleanup item 0 touches register 591 whose frame is not FULL", + "rejected": true, + "target_check": "frame" + }, + { + "by": "replay", + "control": "delete restore gate 0", + "ok": true, + "reason": "restored cold register 572 is not its own input", + "rejected": true, + "target_check": "replay" + }, + { + "by": "replay", + "control": "delete compensation gate 0", + "ok": true, + "reason": "target 1 not final before cleanup", + "rejected": true, + "target_check": "replay" + }, + { + "by": "replay", + "control": "drop 18 forward-no-op cleanup adds (dual replay)", + "ok": true, + "other_checks": { + "forward replay": "accepted" + }, + "reason": "a zero buffer is not returned to zero", + "rejected": true, + "target_check": "replay" + }, + { + "accepted": true, + "control": "positive: rebased warp U/E lists (same spans) accepted", + "ok": true, + "target_check": "warp+frame" + }, + { + "by": "replay", + "control": "canonical: delete compensation gate 0", + "ok": true, + "reason": "target 1 not final before cleanup", + "rejected": true, + "target_check": "replay" + }, + { + "by": "frame", + "control": "canonical: tail gate 0 lifted to FULL (cold end violated)", + "ok": true, + "reason": "non-nested climb of 589 at post-B[31]: (256, 128, 64, 32, 16, 8, 4, 2, 1) -> (256, 128, 64, 32, 18, 10, 6, 1)", + "rejected": true, + "target_check": "frame" + }, + { + "by": "link566", + "control": "566 link: one 566 B-gate frame changed", + "ok": true, + "reason": "inconsistent frame pair at B[0]", + "rejected": true, + "target_check": "link566" + }, + { + "by": "pin", + "control": "pin: one flipped bit in the word blob", + "ok": true, + "reason": "git blob id mismatch for new/borrow/words/BORROW-WORD-43base.json.gz", + "rejected": true, + "target_check": "pin" + } + ], + "controls_ok": true, + "frames": { + "climbs": { + "1": 2351, + "2": 501, + "3": 414, + "4": 129, + "5": 42 + }, + "copy_charges": { + "8": 8 + }, + "helpers": 437, + "if_warps_charged_mass": 5581, + "if_warps_charged_profile": { + "1": 2351, + "2": 502, + "3": 414, + "4": 158, + "5": 42, + "6": 13, + "8": 8 + }, + "local_mass": 5385, + "model_ok": true, + "paid_profile": { + "1": 2351, + "2": 501, + "3": 414, + "4": 129, + "5": 42, + "8": 8 + }, + "width_inventory": { + "4": 36, + "5": 9, + "7": 36, + "8": 116, + "9": 240 + } + }, + "links": { + "B_multiset_equals_canonical_B_plus_moved_tail_renamed": true, + "canonical_A_gates_dropped": 0, + "canonical_cold_helpers": 78, + "canonical_cold_helpers_ending_FULL_after_borrowing": [ + 533, + 554 + ], + "canonical_compensation_gates_dropped": 0, + "canonical_cut_gates_dropped": 0, + "canonical_precondition_gates_dropped": 0, + "high_helpers_in_blocks": 48, + "mass_identity": { + "predicted_saving": 205, + "removed_widths": 207, + "width_added_to_cold_now_FULL": 2 + }, + "moved_tail_gates": 48, + "providers_widths_match": true, + "removed_old_widths": { + "4": 8, + "5": 35 + } + }, + "replay": { + "dual": { + "buffer_nonzero_window": [ + 0, + 4498 + ], + "buffers": 76, + "buffers_ever_nonzero": 58, + "cleanup_adds_reading_a_zero_buffer": 355, + "independent_inputs": 661, + "max_overlap_of_buffer_lifetimes": 48, + "peak_nonzero_buffers": 48 + }, + "forward": { + "buffer_nonzero_window": [ + 1, + 4470 + ], + "buffers": 76, + "buffers_ever_nonzero": 76, + "cleanup_adds_reading_a_zero_buffer": 110, + "independent_inputs": 661, + "max_overlap_of_buffer_lifetimes": 44, + "peak_nonzero_buffers": 44, + "rows_with_operator_words_before_cleanup": 88 + } + }, + "saving": { + "helpers_after": 437, + "helpers_before": 480, + "mass_after": 5385, + "mass_before": 5590 + }, + "warps": { + "U_equal_E": 0, + "U_inside_E": 0, + "anticipatory_terms": 0, + "count": 43, + "dims": { + "4": 40, + "5": 3 + }, + "lenders": [ + 243, + 250, + 266, + 259, + 333, + 317, + 554, + 285, + 281, + 301, + 297, + 313, + 329, + 349, + 345, + 365, + 361, + 381, + 377, + 397, + 393, + 225, + 227, + 229, + 234, + 241, + 245, + 257, + 261, + 73, + 401, + 403, + 405, + 410, + 417, + 419, + 421, + 426, + 433, + 435, + 437, + 442, + 542 + ], + "lenders_that_are_X": [ + 73 + ], + "lenders_that_are_restored_cold": [], + "plain_fourier_distance": { + "2": 1, + "4": 29, + "6": 13 + }, + "positions": [ + 965, + 1073, + 1073, + 1073, + 1113, + 1113, + 1093, + 1161, + 1161, + 1201, + 1201, + 1201, + 1201, + 965, + 1181, + 965, + 965, + 1181, + 1181, + 1181, + 1161, + 1161, + 1141, + 1141, + 1141, + 1141, + 1113, + 1113, + 1073, + 1093, + 985, + 985, + 985, + 1005, + 1005, + 1005, + 1005, + 1033, + 1033, + 1033, + 1033, + 1093, + 1093 + ] + } + }, + "extra": { + "base_tag": "cd417b90", + "canonical": { + "climbs": { + "1": 2340, + "2": 508, + "3": 420, + "4": 126, + "5": 82 + }, + "copy_charges": { + "8": 8 + }, + "helpers": 480, + "link_566": { + "aligned_frame_pairs": 1008, + "frame_map_tau_columns": [ + 42, + 41, + 4, + 35, + 16, + 11, + 64, + 128, + 256 + ], + "register_permutation_nonidentity": 220 + }, + "local_mass": 5594, + "paid_profile": { + "1": 2340, + "2": 508, + "3": 420, + "4": 126, + "5": 82, + "8": 8 + }, + "replay": { + "buffer_nonzero_window": [ + null, + null + ], + "buffers": 0, + "buffers_ever_nonzero": 0, + "cleanup_adds_reading_a_zero_buffer": 0, + "independent_inputs": 704, + "max_overlap_of_buffer_lifetimes": 0, + "peak_nonzero_buffers": 0, + "rows_with_operator_words_before_cleanup": 0 + }, + "width_inventory": { + "4": 40, + "5": 48, + "7": 38, + "8": 114, + "9": 240 + } + }, + "controls": [ + { + "by": "replay", + "control": "drop forward warp 1", + "ok": true, + "other_checks": { + "frame": "rejected[frame]" + }, + "reason": "final map wrong on register 240 (forward)", + "rejected": true, + "target_check": "replay" + }, + { + "by": "replay", + "control": "drop inverse warp 1 in cleanup", + "ok": true, + "other_checks": { + "frame": "accepted" + }, + "reason": "final map wrong on register 240 (forward)", + "rejected": true, + "target_check": "replay" + }, + { + "by": "replay", + "control": "perturb coefficient x2: B item 972 (lender 243 after its warp)", + "ok": true, + "other_checks": { + "frame": "accepted" + }, + "reason": "target 81 not final before cleanup", + "rejected": true, + "target_check": "replay" + }, + { + "by": "replay", + "control": "perturb coefficient x2: compensation gate 0", + "ok": true, + "other_checks": { + "frame": "accepted" + }, + "reason": "target 1 not final before cleanup", + "rejected": true, + "target_check": "replay" + }, + { + "by": "replay", + "control": "perturb coefficient x2: first cleanup add between live registers", + "ok": true, + "other_checks": { + "frame": "accepted" + }, + "reason": "a zero buffer is not returned to zero", + "rejected": true, + "target_check": "replay" + }, + { + "by": "frame", + "control": "warp 1 as an ordinary climb U->E", + "ok": true, + "reason": "non-nested climb of 243 at warp 1 treated as an ordinary climb: (261, 133, 85, 45) -> (320, 192, 45, 30)", + "rejected": true, + "target_check": "frame" + }, + { + "by": "profile", + "control": "charge every warp as a climb of rank d(L_U,L_E)", + "ok": true, + "reason": "recount {'1': 2339, '2': 510, '3': 418, '4': 154, '5': 42, '6': 13, '8': 8} != word report {1: 2339, 2: 509, 3: 418, 4: 125, 5: 42, 8: 8}", + "rejected": true, + "target_check": "profile" + }, + { + "by": "frame", + "control": "swap lenders of warps 1,14", + "ok": true, + "other_checks": { + "replay": "rejected[replay]" + }, + "reason": "warp 1: lender 349 frame (416, 70, 19, 13) != U (261, 133, 85, 45)", + "rejected": true, + "target_check": "frame" + }, + { + "by": "warp", + "control": "warp 1: singular G", + "ok": true, + "reason": "warp 1: G is singular over GF(2)", + "rejected": true, + "target_check": "warp" + }, + { + "by": "warp", + "control": "warp 1: invertible G with G span U != span E", + "ok": true, + "reason": "warp 1: G span U != span E", + "rejected": true, + "target_check": "warp" + }, + { + "by": "warp", + "control": "warp 1: dim E != dim U", + "ok": true, + "reason": "warp 1: dim U != dim E", + "rejected": true, + "target_check": "warp" + }, + { + "by": "frame", + "control": "cleanup item 0 uses the restored register, not its buffer", + "ok": true, + "reason": "cleanup item 0 touches register 591 whose frame is not FULL", + "rejected": true, + "target_check": "frame" + }, + { + "by": "replay", + "control": "delete restore gate 0", + "ok": true, + "reason": "restored cold register 572 is not its own input", + "rejected": true, + "target_check": "replay" + }, + { + "by": "replay", + "control": "delete compensation gate 0", + "ok": true, + "reason": "target 1 not final before cleanup", + "rejected": true, + "target_check": "replay" + }, + { + "by": "replay", + "control": "drop 18 forward-no-op cleanup adds (dual replay)", + "ok": true, + "other_checks": { + "forward replay": "accepted" + }, + "reason": "a zero buffer is not returned to zero", + "rejected": true, + "target_check": "replay" + }, + { + "accepted": true, + "control": "positive: rebased warp U/E lists (same spans) accepted", + "ok": true, + "target_check": "warp+frame" + }, + { + "by": "replay", + "control": "canonical: delete compensation gate 0", + "ok": true, + "reason": "target 1 not final before cleanup", + "rejected": true, + "target_check": "replay" + }, + { + "by": "frame", + "control": "canonical: tail gate 0 lifted to FULL (cold end violated)", + "ok": true, + "reason": "non-nested climb of 589 at post-B[31]: (256, 128, 64, 32, 16, 8, 4, 2, 1) -> (256, 128, 64, 32, 18, 10, 6, 1)", + "rejected": true, + "target_check": "frame" + }, + { + "by": "link566", + "control": "566 link: one 566 B-gate frame changed", + "ok": true, + "reason": "inconsistent frame pair at B[0]", + "rejected": true, + "target_check": "link566" + }, + { + "by": "pin", + "control": "pin: one flipped bit in the word blob", + "ok": true, + "reason": "git blob id mismatch for new/borrow/words/BORROW-WORD-43extra.json.gz", + "rejected": true, + "target_check": "pin" + } + ], + "controls_ok": true, + "frames": { + "climbs": { + "1": 2339, + "2": 509, + "3": 418, + "4": 125, + "5": 42 + }, + "copy_charges": { + "8": 8 + }, + "helpers": 437, + "if_warps_charged_mass": 5581, + "if_warps_charged_profile": { + "1": 2339, + "2": 510, + "3": 418, + "4": 154, + "5": 42, + "6": 13, + "8": 8 + }, + "local_mass": 5385, + "model_ok": true, + "paid_profile": { + "1": 2339, + "2": 509, + "3": 418, + "4": 125, + "5": 42, + "8": 8 + }, + "width_inventory": { + "4": 36, + "5": 9, + "7": 36, + "8": 116, + "9": 240 + } + }, + "links": { + "B_multiset_equals_canonical_B_plus_moved_tail_renamed": true, + "canonical_A_gates_dropped": 0, + "canonical_cold_helpers": 78, + "canonical_cold_helpers_ending_FULL_after_borrowing": [ + 533, + 554 + ], + "canonical_compensation_gates_dropped": 0, + "canonical_cut_gates_dropped": 0, + "canonical_precondition_gates_dropped": 0, + "high_helpers_in_blocks": 48, + "mass_identity": { + "predicted_saving": 209, + "removed_widths": 211, + "width_added_to_cold_now_FULL": 2 + }, + "moved_tail_gates": 48, + "providers_widths_match": true, + "removed_old_widths": { + "4": 4, + "5": 39 + } + }, + "replay": { + "dual": { + "buffer_nonzero_window": [ + 0, + 4498 + ], + "buffers": 76, + "buffers_ever_nonzero": 58, + "cleanup_adds_reading_a_zero_buffer": 355, + "independent_inputs": 661, + "max_overlap_of_buffer_lifetimes": 48, + "peak_nonzero_buffers": 48 + }, + "forward": { + "buffer_nonzero_window": [ + 1, + 4470 + ], + "buffers": 76, + "buffers_ever_nonzero": 76, + "cleanup_adds_reading_a_zero_buffer": 110, + "independent_inputs": 661, + "max_overlap_of_buffer_lifetimes": 44, + "peak_nonzero_buffers": 44, + "rows_with_operator_words_before_cleanup": 88 + } + }, + "saving": { + "helpers_after": 437, + "helpers_before": 480, + "mass_after": 5385, + "mass_before": 5594 + }, + "warps": { + "U_equal_E": 0, + "U_inside_E": 0, + "anticipatory_terms": 0, + "count": 43, + "dims": { + "4": 40, + "5": 3 + }, + "lenders": [ + 243, + 250, + 266, + 259, + 333, + 317, + 554, + 285, + 281, + 301, + 297, + 313, + 329, + 349, + 345, + 365, + 361, + 381, + 377, + 397, + 393, + 225, + 227, + 229, + 234, + 241, + 245, + 257, + 261, + 73, + 401, + 403, + 405, + 410, + 417, + 419, + 421, + 426, + 433, + 435, + 437, + 442, + 542 + ], + "lenders_that_are_X": [ + 73 + ], + "lenders_that_are_restored_cold": [], + "plain_fourier_distance": { + "2": 1, + "4": 29, + "6": 13 + }, + "positions": [ + 965, + 1073, + 1073, + 1073, + 1113, + 1113, + 1093, + 1161, + 1161, + 1201, + 1201, + 1201, + 1201, + 965, + 1181, + 965, + 965, + 1181, + 1181, + 1181, + 1161, + 1161, + 1141, + 1141, + 1141, + 1141, + 1113, + 1113, + 1073, + 1093, + 985, + 985, + 985, + 1005, + 1005, + 1005, + 1005, + 1033, + 1033, + 1033, + 1033, + 1093, + 1093 + ] + } + } + } +}