From 8882d54f4e72112d3e875a939109a200334d5cbd Mon Sep 17 00:00:00 2001 From: Cinna Davis <1337isnot1337@users.noreply.github.com> Date: Thu, 22 Oct 2026 09:01:28 -0500 Subject: [PATCH 1/3] Audit PR4633 physical contracts and bound endpoint-preserving repairs --- research/pr4633-contract-audit/README.md | 173 +++++++++++++ research/pr4633-contract-audit/RESULT.json | 110 +++++++++ research/pr4633-contract-audit/SOURCES.json | 96 ++++++++ research/pr4633-contract-audit/TASK.json | 96 ++++++++ research/pr4633-contract-audit/VENDORED.json | 48 ++++ research/pr4633-contract-audit/VERIFY.json | 39 +++ .../QUOTIENT-BIT-WORD.json.gz | Bin 0 -> 83523 bytes .../vendor/bit-ambient-quotient/RESULT.json | 55 +++++ .../vendor/bit-ambient-quotient/build.py | 206 ++++++++++++++++ .../vendor/bit-ambient-quotient/verify.py | 231 ++++++++++++++++++ .../QUOTIENT-WORD.json.gz | Bin 0 -> 3979 bytes .../complex-ambient-quotient/RESULT.json | 45 ++++ research/pr4633-contract-audit/verify.py | 224 +++++++++++++++++ 13 files changed, 1323 insertions(+) create mode 100644 research/pr4633-contract-audit/README.md create mode 100644 research/pr4633-contract-audit/RESULT.json create mode 100644 research/pr4633-contract-audit/SOURCES.json create mode 100644 research/pr4633-contract-audit/TASK.json create mode 100644 research/pr4633-contract-audit/VENDORED.json create mode 100644 research/pr4633-contract-audit/VERIFY.json create mode 100644 research/pr4633-contract-audit/vendor/bit-ambient-quotient/QUOTIENT-BIT-WORD.json.gz create mode 100644 research/pr4633-contract-audit/vendor/bit-ambient-quotient/RESULT.json create mode 100644 research/pr4633-contract-audit/vendor/bit-ambient-quotient/build.py create mode 100644 research/pr4633-contract-audit/vendor/bit-ambient-quotient/verify.py create mode 100644 research/pr4633-contract-audit/vendor/complex-ambient-quotient/QUOTIENT-WORD.json.gz create mode 100644 research/pr4633-contract-audit/vendor/complex-ambient-quotient/RESULT.json create mode 100644 research/pr4633-contract-audit/verify.py diff --git a/research/pr4633-contract-audit/README.md b/research/pr4633-contract-audit/README.md new file mode 100644 index 0000000000..b143a4ed68 --- /dev/null +++ b/research/pr4633-contract-audit/README.md @@ -0,0 +1,173 @@ +# PR4633 contract audit and bounded repair attempts + +**The submitted quotient screens do not establish a new κ.** This audit reviews +PR4633 at `b390d64abfcdba1a3816b86fc763cbc95d43c12c` and keeps every submitted +package unchanged. The GitHub headline describes kernel 150 and BIT 0.012401086416; +the checked commit actually ships kernel span{150,102,255} and BIT screen +0.032249423394893. Both variants are checked here, along with the stacked complex +kernel-153 artifact. This is a finite audit, not a full multiplication theorem. + +The publication package is based on canonical main and vendors six exact inputs +from the reviewed PR under `vendor/`; `VENDORED.json` records their original +paths, commit, Git blobs and SHA256 hashes. The vendored Python files are +unchanged. The audit binds the copied builder's `SOURCE` path to the original +PR589 source directory before calling it. `SOURCES.json` pins the remaining +inputs from main. Every audit input is available in the publication checkout. + +## What reproduces + +The submitted BIT and complex verifiers reproduce their committed RESULT.json +files exactly. Their metadata/source-pin checks also pass. Logical maps, owned +cleanup and replay against the artifacts' own endpoints are consistent. Those +checks do not verify that the resulting physical local calls are the operators +used by the controller. `PASS` below means the audit detects that mismatch. + +The controller's `replay_events` multiplies both fields of every LOCAL call by +the same stage symbol. Its `inventories` then credits all main outputs using +block 7 (BIT) or block 8 (complex), retaining a rank-one central factor. The +actual source contracts have X entrance P, X final full ambient, Y entrance +zero, Y final H, with P a line complementary to H. The original sources pass +these checks on every port. Checking these dimensions and complements allows +chart changes; it does not require equality of source frame labels. + +## Finding 1: neither quotient satisfies its priced main-port contract + +| word | main widths | ports meeting the invoiced contract | +| --- | --- | ---: | +| rational BIT source | {7:222} | 111/111 | +| BIT kernel 150 | {6:107,7:105,8:10} | 0/111 | +| BIT kernel span{150,102,255} | {4:103,7:70,8:49} | 0/111 | +| complex source | {8:224} | 112/112 | +| complex kernel 153 | {7:168,8:56} | 0/112 | + +For complex kernel 153, 56 ports have widths (7,7) and a surviving central +complement; the other 56 have widths (7,8) and X entrance contained in Y final. +Neither type is the block-8 call priced by the invoice. + +There is a general obstruction for the submitted global full-image padding. +Let h be the original ambient dimension and K a nonzero k-dimensional kernel. +For a source hyperplane H, dim(phi(H)) is h-k or h-k-1. In the former case the +image is the full quotient and the builder re-pads it to dimension h. In the +latter case it remains dimension h-k-1 <= h-2. Thus **no Y terminal can have the +required dimension h-1**, for any nonzero kernel in this construction. This +rules out repairing the existing priced contract by searching more kernels. +It does not rule out a new controller with different operator contracts. + +The correct BIT rank-mass decomposition is: + +| word | paid mass | main mass | helper mass | owned COPY mass | +| --- | ---: | ---: | ---: | ---: | +| source | 5129 | 1554 | 3512 | 63 | +| kernel 150 | 5023 | 1457 | 3512 | 54 | +| submitted three-dimensional kernel | 4842 | 1294 | 3512 | 36 | + +Paid mass equals main + helper + COPY mass. Relative to the source, the +one-dimensional saving is **97 removed main ranks + 9 COPY ranks**, totaling +106. The submitted saving is **260 main + 27 COPY**, totaling 287. The increase +in the unchanged invoice's surplus is 18 times these totals. This slightly +corrects the earlier review's attribution of all 106 ranks to mains; the +contract objection still applies. No corrected complete invoice is asserted. + +## Finding 2: BIT's GF(2) conversion changes the source geometry + +The BIT source stores rational E8 frames. Its `frame_projectors` constructs +exact rational orthogonal projectors from B using B^t (B B^t)^-1 B. The quotient +builder instead reduces A's coefficients modulo 2 and takes a GF(2) nullspace. +These operations do not preserve the required incidence/orthogonality data. + +An explicit witness is port 8: + +``` +u = (0,1,1,0,1,0,0,1) +H = {x : u dot x = 0} +u dot u = 4 over Q, but 0 modulo 2. +``` + +The rational entrance line is complementary to its terminal H. Its reduced +binary line is inside the reduced H. Even before applying any quotient, this +conversion leaves only 8 of 111 complementary pairs; the 111 distinct rational +entrance lines reduce to 22 binary lines. Matching every frame dimension and +recovering the old bill are insufficient calibration: those tests miss this +change in incidence. The source itself is not accused of this error. + +## Repair attempts and what they establish + +1. **Restore the source geometry through a monotone contraction.** For each + rational source frame S, compute the span of all source entrance lines + contained in S. This span equals S for **all 636 frames**, checked with exact + rational elimination and A/B kernel-image consistency. If a framewise map F + is monotone, fixes those entrance lines, and satisfies F(S) contained in S, + then S is contained in F(S), hence F(S)=S. This entire contraction repair + class therefore returns the original profile and screen 0.003464248972024. + The lemma does not cover arbitrary resynthesis or role-dependent retiming. +2. **Expand frames while preserving all endpoints.** Replace S by the + intersection of all source Y hyperplanes containing S (full ambient if + there are none). This is a monotone expansion; all 661 start/final endpoints + remain exactly fixed. It changes 36 frames and replays both logical + directions. Its paid mass rises to 5138, surplus falls to 591, and the same + screen drops to approximately 0.002750034070107. It is rejected as a repair + before native lowering; native realizability is not claimed. + +These checks supply no profitable repair of PR4633. A valid replacement would +need a different physical construction/controller and a fresh complete invoice. + +## Finding 3: the outer admission is also missing + +The two-constraint roots are supplier screens. They do not supply the ordinary +BIT conversion and full outer chain. The pinned query-thinned verifier separately +uses before/after cover savings, an old atom, an admitted BIT saving, and all +strict outer predicates. The submitted packages do not replace that chain or +replay it at a larger value. Increasing declared constants would require proof +of their hypotheses, including a supplier implementing the actual LOCAL operator. +The large outer value in the GitHub title/body is therefore unsupported as well. + +## Reproduce + +From the repository root, with CPython 3.12 and only its standard library: + +```sh +python3 -I -B research/pr4633-contract-audit/verify.py +python3 -B scripts/research_package.py --package research/pr4633-contract-audit +``` + +The first command authenticates 19 inputs, checks the original source as a +positive control, recomputes both BIT logical replays and their contracts, +checks the stacked complex source/quotient geometry, proves the bounded +contraction obstruction, prices the expansion, and rejects five mutations: +wrong MOVE rank, dependent basis, changed source entrance, omitted source ADD, +and spoofed width metadata. The expected marker is +`PASS_PR4633_CONTRACT_AUDIT_NO_NEW_KAPPA`. + +`RESULT.json` is the deterministic audit receipt. Float roots are labelled as +screens; only ranks, counts, incidences and source pins are exact claims. +The full submitted complex logical replay was independently rerun during the +review; this audit's registered command reconstructs its source and checks its +endpoint geometry, without repeating its full physical lowering. + +## Open next questions + +- Can an alternative local word preserve the invoiced operator while reducing + the paid moment? Start with the original rational BIT frames or original + complex endpoints and check them independently before pricing. The present + global quotient with full-image padding cannot do this. +- Can a different controller use the quotient operators? Derive each actual + main operator, its central factor and stage ranks, then factor the controller + and reprice all outputs and idles. The existing block-7/block-8 invoice cannot + be reused. This is a new construction, not a literal-constant repair. +- Any eventual supplier improvement still needs ordinary BIT conversion and + the complete outer admission with strict predicates and sound source pins. + +## Credit + +DaysSky supplied both quotient packages (#4633 and #4629), built on +DreamingOfClouds's PR589 BIT word and the retained eumemic lineage, and Cinna +Davis's PR4470 complex construction on the credited zxv supplier work. The +endpoint concern was raised by pinterbanget (#4604), the quotient-kernel census +by Nick Petalas (#4627), and the per-port controller-contract audit by Rohan +Arun in his PR4633 comment. This audit independently checks those concerns, +adds the rational/GF(2) witness, covers the actual three-dimensional artifact, +corrects the COPY/main rank attribution, and bounds two repair routes. + +Prepared for Cinna Davis with substantial OpenAI Codex assistance. Apache-2.0. +This package changes no selected-result record and claims no new κ. Its local +checks and publication status are separate from maintainer acceptance. diff --git a/research/pr4633-contract-audit/RESULT.json b/research/pr4633-contract-audit/RESULT.json new file mode 100644 index 0000000000..4f6a14be02 --- /dev/null +++ b/research/pr4633-contract-audit/RESULT.json @@ -0,0 +1,110 @@ +{ + "authenticated_inputs": 19, + "bit_field_mismatch_witness": { + "port": 8, + "source_dot_mod_2": 0, + "source_dot_over_Q": 4 + }, + "bit_gf2_reduction_before_quotient": { + "accepted": 8, + "intersection_dimensions": { + "0": 8, + "1": 103 + }, + "main_widths": { + "7": 222 + }, + "rejected": 103 + }, + "bit_quotients": { + "headline_kernel_150": { + "accepted": 0, + "copy_mass": 54, + "helper_mass": 3512, + "intersection_dimensions": { + "0": 10, + "1": 101 + }, + "kernel": [ + 150 + ], + "logical_replay": true, + "main_mass": 1457, + "main_widths": { + "6": 107, + "7": 105, + "8": 10 + }, + "mispriced_float_screen": 0.01240108641606724, + "mispriced_surplus": 2661, + "paid_mass": 5023, + "rejected": 111 + }, + "submitted_kernel_150_102_255": { + "accepted": 0, + "copy_mass": 36, + "helper_mass": 3512, + "intersection_dimensions": { + "0": 41, + "1": 70 + }, + "kernel": [ + 150, + 102, + 255 + ], + "logical_replay": true, + "main_mass": 1294, + "main_widths": { + "4": 103, + "7": 70, + "8": 49 + }, + "mispriced_float_screen": 0.03224942339489283, + "mispriced_surplus": 5919, + "paid_mass": 4842, + "rejected": 111 + } + }, + "bit_rational_frames_forced_by_fixed_lines": 636, + "bit_source_ports_accepted": 111, + "complex_quotient": { + "accepted": 0, + "intersection_dimensions": { + "0": 56, + "1": 56 + }, + "main_widths": { + "7": 168, + "8": 56 + }, + "rejected": 112 + }, + "complex_source": { + "accepted": 112, + "intersection_dimensions": { + "0": 112 + }, + "main_widths": { + "8": 224 + }, + "rejected": 0 + }, + "expansion_repair_screen_only": { + "changed_frames": 36, + "float_screen": 0.0027500340701070436, + "native_lowering_checked": false, + "paid_mass": 5138, + "surplus": 591 + }, + "negative_controls": { + "changed_source_entrance": true, + "dependent_frame_basis": true, + "omitted_source_add": true, + "spoofed_main_width_metadata": true, + "wrong_move_rank": true + }, + "reviewed_head": "b390d64abfcdba1a3816b86fc763cbc95d43c12c", + "scope": "Finite endpoint and geometry audit; no new kappa, native realization or outer admission.", + "status": "PASS_PR4633_CONTRACT_AUDIT_NO_NEW_KAPPA" +} diff --git a/research/pr4633-contract-audit/SOURCES.json b/research/pr4633-contract-audit/SOURCES.json new file mode 100644 index 0000000000..c064fb56eb --- /dev/null +++ b/research/pr4633-contract-audit/SOURCES.json @@ -0,0 +1,96 @@ +{ + "schema_version": 1, + "base_commit": "fbc9ea0249746acca4f504d4fda2b84e0e36cf0d", + "files": [ + { + "path": "certificates/selected-result.json", + "usage": "provenance", + "git_blob": "c35482cd9035843b15a634cc8276a7e1e40e8395", + "sha256": "6fe0a099b89aa2aed796a13c3a21dafc63f3388ebf397464e44e0451893b9375" + }, + { + "path": "docs/research/agent-task-catalog.json", + "usage": "provenance", + "git_blob": "f126dd2e2dad2b669e75d1d0d0bd05c600725602", + "sha256": "f7a48bfa2659b88378282a8eee7d9fe52cdf505594124c4d1686b58510fffd72" + }, + { + "path": "research/fresh-helper-boundary/CHANGES.json", + "usage": "input", + "git_blob": "45744fedd0e28967aa72586048b8bc0c72f419a9", + "sha256": "cde73b8ff5b3c0d06e69e2293b991b24fd14a16dd4ccab7ff6b3439074a94624" + }, + { + "path": "research/fresh-helper-boundary/native.py", + "usage": "input", + "git_blob": "1b36f6cb5f205c33bf48811e0b1b3621c55e8154", + "sha256": "9b55a2d3c3972148fae9d112e745d9244968166bd89bd900c938f429fc76ab29" + }, + { + "path": "research/joint-helper-lattice/PATCH.json", + "usage": "input", + "git_blob": "51304a6601061ed4e698f910b09135ef109555e3", + "sha256": "296d0e8c58cc70febe042c681ef30d6bb469818c0835fbcaac8aa8d330f5b727" + }, + { + "path": "research/joint-helper-lattice/native_joint.py", + "usage": "input", + "git_blob": "0315f80e2fdef5e0eef13e3e9b8f72066238164d", + "sha256": "50869b1bcad7493e6b4cb2a4cd5d2fd9a193a5921100483fa2c3f2c999ddfd46" + }, + { + "path": "research/kappa-rebuild/bit/mixed_productive_bit.py", + "usage": "input", + "git_blob": "9c7a8bd5d3ae4c19952648c815031858d6627b96", + "sha256": "b32291b0db7fc0d332ec444c70746ab0fb03351d2e50546f8bcb64060e3ff95e" + }, + { + "path": "research/kappa-rebuild/bit/sources/pr589-regenerated/WORD.json.gz", + "usage": "input", + "git_blob": "85a4499bf9e4911a705d50567a2c2ef6cf23739a", + "sha256": "e3e301e62bc2b41dbf1ceac0acf3d35824ebeab1848c5a2142d4577b109da52f" + }, + { + "path": "research/kappa-rebuild/bit/sources/pr589-regenerated/records/249-records.bin", + "usage": "input", + "git_blob": "bdf9ab4ca0fd74cde6837f95f5f4e88133704e0e", + "sha256": "ea44aa047a2a9cf034de8b56b2166c49cf2dbdf9cd9ed6a20299a4f2b05ef09a" + }, + { + "path": "research/kappa-rebuild/bit/sources/pr589-regenerated/records/frames.json", + "usage": "input", + "git_blob": "a9a932b9268da28af9ba4bccdab205c5bcd50ad3", + "sha256": "d006b3bfe0c04afecfea7aecfa59dfe4298b99501c70da3938e40289bc2f5010" + }, + { + "path": "research/kappa-rebuild/complex/full-identity-certificates/THREE-base-FULL-IDENTITY-CANONICAL.json.gz", + "usage": "input", + "git_blob": "4a8c4ed26e53a72362d571c972e65aff546be784", + "sha256": "6418ec3da24d548a57f5c3fe5b9062c26c9478e638504a61c387f5cfb5f4ed61" + }, + { + "path": "research/kappa-rebuild/complex/full-identity-certificates/THREE-base-FULL-IDENTITY-NATIVE.json.gz", + "usage": "input", + "git_blob": "b46d44c6ee624968dd57be928b0c15d9d45f3b2c", + "sha256": "c54b0a3e129d28e6dbf74fa731fc3bb70fe3c6705f07256750fbecddcc842d39" + }, + { + "path": "research/missing-join-frame/PATCH.json", + "usage": "input", + "git_blob": "f96d295d40014d4dd503f58eb3cdabcbb4b8e101", + "sha256": "9ab5328245ff02c9d0be21d39bcc375f50bc5d7909e9f7b9a3a9a6f812f5bd6e" + }, + { + "path": "research/query-thinned-controllers/controller.py", + "usage": "input", + "git_blob": "d4557e08cfb9fe57cc1ae4024705a72dc95f3583", + "sha256": "8b462d660487b1be4940357c4c7522967b1bfaede3c02b1c66109b85acae0fd2" + }, + { + "path": "research/query-thinned-controllers/verify.py", + "usage": "input", + "git_blob": "f1114036fff66f57014e5c1256141fb78ff4c4a9", + "sha256": "07dea601d6bbaa4d90e576f20c8607c37fb01e8778c798d919fa9df435049950" + } + ] +} diff --git a/research/pr4633-contract-audit/TASK.json b/research/pr4633-contract-audit/TASK.json new file mode 100644 index 0000000000..dd0fe0b28e --- /dev/null +++ b/research/pr4633-contract-audit/TASK.json @@ -0,0 +1,96 @@ +{ + "schema_version": 1, + "task_id": "supplier-boundary-audit", + "priority_revision": 7, + "base_commit": "fbc9ea0249746acca4f504d4fda2b84e0e36cf0d", + "original_card": { + "id": "supplier-boundary-audit", + "question": "Can the #4088 four-provider dispatch satisfy the complete ordinary/outer admission contract?", + "starting_points": [ + "docs/research/research-family-status.md", + "certificates/selected-result.json", + "research/staged544-mixed-fourth-entry/README.md", + "research/scatter-boundary-decision/README.md" + ], + "methods": [ + "Trace one hypothesis through the source, checker and complete caller.", + "Construct one semantically invalid but superficially well-formed fixture and test rejection." + ], + "acceptance_gate": "Pin the current sources and one obligation; the historical owner audit is an example, not evidence of a current bug.", + "first_step": { + "command": [ + "python3", + "-B", + "scripts/research_baseline.py" + ], + "expected": "PASS_RESEARCH_BASELINE_BINDINGS_ONLY", + "inspect": "Read #4088 Scope and Open next questions: local words, native receipts and literal fill do not include a rerun of the mixed four-provider ordinary/outer engine. #3801 is the newer scatter-boundary decision; do not restart #2977 as if untouched.", + "scope": "Source-binding orientation only; no scientific replay, theorem acceptance or supplier admission. Budget any heavy replay separately." + }, + "first_experiment": "Pin the provider registry, four native source closures and dispatch. Make a bounded acceptance coverage map or one registry adapter preserving every inherited admission predicate and rejection control (including an omitted fourth provider). Record remaining ordinary/outer obligations and a resource estimate before heavy execution. Stop at unresolved source/caller dependencies; no selected-result promotion from a local pass.", + "bottleneck_link": "Closing a current acceptance gap or proof obligation strengthens reliability even without changing kappa.", + "allowed_variations": [ + "One provider-registry, dispatch, native-closure or admission-predicate obligation; separate branches must name distinct coverage." + ], + "scope_change_triggers": [ + "Reporting the historical timing-only diagnostic as a new current acceptance bug.", + "Calling a malformed mutant a failure of the selected construction, or importing an opt-in repair without testing the exporter boundary.", + "Running another root enclosure instead of validating dispatch or weakening an inherited predicate to make mixed admission pass." + ], + "overlap_terms": [ + "owner boundary", + "bridge omission", + "hosting", + "2977", + "scatter export", + "duplicate index", + "parity semantics", + "4088", + "3801", + "staged544-mixed-fourth-entry", + "scatter-boundary-decision" + ], + "existing_checks": [ + { + "scope": "PR #4088: author-checked local words, native receipts, owner/phase fill and exact moment.", + "evidence": "research/staged544-mixed-fourth-entry/README.md", + "remaining": "Rebind and validate ordinary/outer admission with all four providers; full mixed release not established.", + "status": "author-checked", + "source_commit": "72d7efc181edb21806a878f174847c96dd410ab0", + "selected_record_sha256": "bb2eaa58647b353f88d0aec2eafb9d30df1be53589231b23e12ceef3e4bad129" + }, + { + "scope": "PR #3801: successor scatter-boundary decision package.", + "evidence": "research/scatter-boundary-decision/README.md", + "remaining": "Consult its exact acceptance scope before any new exporter audit; not proof of a selected failure.", + "status": "author-checked", + "source_commit": "911f8800ba7a4b03603ef62c5ffc6240e53cb5fd", + "selected_record_sha256": "bb2eaa58647b353f88d0aec2eafb9d30df1be53589231b23e12ceef3e4bad129" + } + ] + }, + "scope_status": "changed", + "actual_scope": "User-assigned audit of PR4633 physical main-port contracts and bounded repairs at exact head b390d64a.", + "scope_change_reason": "Explicit user task overrides the historical supplier-boundary card assignment.", + "bottleneck_link": "Reject a supplier screen that does not implement its invoiced local operator; do not promote it to a new outer kappa.", + "budget_minutes": 60, + "stop_rule": "Reproduce artifacts, independently test physical endpoint contracts, and finish two bounded endpoint-preserving repair checks.", + "outcome": "completed", + "evidence": "RESULT.json and README.md; five rejection controls and exact source pins.", + "author": "Cinna Davis", + "ai_assistance": "Substantial OpenAI Codex assistance.", + "open_questions": [ + { + "question": "Can a different local word improve the paid moment while preserving the physical operator?", + "why_it_matters": "The present quotient changes the main-port contract.", + "first_step": "Use original rational BIT frames and independently verify endpoints before pricing.", + "blocked_by": "No candidate operator-preserving construction is supplied." + }, + { + "question": "Can a different controller use the quotient local operators?", + "why_it_matters": "The current controller and invoice assume uniform main stage ranks and a central line.", + "first_step": "Derive every actual local operator and re-factor and reprice the complete controller.", + "blocked_by": "The current global quotient cannot preserve the invoiced Y-terminal dimension." + } + ] +} diff --git a/research/pr4633-contract-audit/VENDORED.json b/research/pr4633-contract-audit/VENDORED.json new file mode 100644 index 0000000000..b274f9e0c8 --- /dev/null +++ b/research/pr4633-contract-audit/VENDORED.json @@ -0,0 +1,48 @@ +{ + "schema_version": 1, + "source_repository": "https://github.com/CrocSwap/integer-mult-bounds", + "files": [ + { + "local_path": "vendor/bit-ambient-quotient/QUOTIENT-BIT-WORD.json.gz", + "source_path": "research/bit-ambient-quotient/QUOTIENT-BIT-WORD.json.gz", + "source_commit": "b390d64abfcdba1a3816b86fc763cbc95d43c12c", + "git_blob": "fa2fa7618a66b98a4e78711f307bc893c86b1405", + "sha256": "a1b9555b38d234e3921cdabd280e6a754619e26dd620a069a2a85a93efa31b2c" + }, + { + "local_path": "vendor/bit-ambient-quotient/RESULT.json", + "source_path": "research/bit-ambient-quotient/RESULT.json", + "source_commit": "b390d64abfcdba1a3816b86fc763cbc95d43c12c", + "git_blob": "ba73ce57db43d7a1535751c50bcb25b01b2dc677", + "sha256": "fdb1059a80c345004259eea514585a7ac2f199b1825af46477b9dc0bff8aaf90" + }, + { + "local_path": "vendor/bit-ambient-quotient/build.py", + "source_path": "research/bit-ambient-quotient/build.py", + "source_commit": "b390d64abfcdba1a3816b86fc763cbc95d43c12c", + "git_blob": "ae55584ddb9555f62975a07ae28efaf71b30c291", + "sha256": "1d6601e57f4d8809065ed6821b1bda35621fb6a08a8fd48cc3fdf95ed59e19c7" + }, + { + "local_path": "vendor/bit-ambient-quotient/verify.py", + "source_path": "research/bit-ambient-quotient/verify.py", + "source_commit": "b390d64abfcdba1a3816b86fc763cbc95d43c12c", + "git_blob": "f0acb7c51ebb095853e55dd6f997db8a898dab38", + "sha256": "d60e8db9aea2dbee786432143aac8c18996bf491b513b57d1729a4bbb3f7464e" + }, + { + "local_path": "vendor/complex-ambient-quotient/QUOTIENT-WORD.json.gz", + "source_path": "research/complex-ambient-quotient/QUOTIENT-WORD.json.gz", + "source_commit": "b390d64abfcdba1a3816b86fc763cbc95d43c12c", + "git_blob": "31444b48850cbe220d4ddbf88496722682581fb8", + "sha256": "10155f81100e9cd6283f1d9dfd071bc0c3e0e89dc3794a66e4129a1f34d99dc4" + }, + { + "local_path": "vendor/complex-ambient-quotient/RESULT.json", + "source_path": "research/complex-ambient-quotient/RESULT.json", + "source_commit": "b390d64abfcdba1a3816b86fc763cbc95d43c12c", + "git_blob": "dc50c5a29a471de8183d9d371954b31947f34a6a", + "sha256": "1cfcda8517c945e3a3a61c86b2d3e724bdcfc86b453668131ecbf741f8a1b90f" + } + ] +} diff --git a/research/pr4633-contract-audit/VERIFY.json b/research/pr4633-contract-audit/VERIFY.json new file mode 100644 index 0000000000..c9cf7304a7 --- /dev/null +++ b/research/pr4633-contract-audit/VERIFY.json @@ -0,0 +1,39 @@ +{ + "schema_version": 1, + "status": "ready", + "python": "3.12", + "requirements": [], + "inputs": [ + "research/fresh-helper-boundary/CHANGES.json", + "research/fresh-helper-boundary/native.py", + "research/joint-helper-lattice/PATCH.json", + "research/joint-helper-lattice/native_joint.py", + "research/kappa-rebuild/bit/mixed_productive_bit.py", + "research/kappa-rebuild/bit/sources/pr589-regenerated/WORD.json.gz", + "research/kappa-rebuild/bit/sources/pr589-regenerated/records/249-records.bin", + "research/kappa-rebuild/bit/sources/pr589-regenerated/records/frames.json", + "research/kappa-rebuild/complex/full-identity-certificates/THREE-base-FULL-IDENTITY-CANONICAL.json.gz", + "research/kappa-rebuild/complex/full-identity-certificates/THREE-base-FULL-IDENTITY-NATIVE.json.gz", + "research/missing-join-frame/PATCH.json", + "research/query-thinned-controllers/controller.py", + "research/query-thinned-controllers/verify.py", + "research/pr4633-contract-audit/vendor/bit-ambient-quotient/QUOTIENT-BIT-WORD.json.gz", + "research/pr4633-contract-audit/vendor/bit-ambient-quotient/RESULT.json", + "research/pr4633-contract-audit/vendor/bit-ambient-quotient/build.py", + "research/pr4633-contract-audit/vendor/bit-ambient-quotient/verify.py", + "research/pr4633-contract-audit/vendor/complex-ambient-quotient/QUOTIENT-WORD.json.gz", + "research/pr4633-contract-audit/vendor/complex-ambient-quotient/RESULT.json" + ], + "commands": [ + { + "argv": [ + "{python}", + "-I", + "-B", + "{package}/verify.py" + ], + "timeout_seconds": 120, + "checks": "Exact endpoint geometry, rational/GF2 mismatch, 636-frame contraction obstruction, both logical BIT directions, complex source/quotient endpoint contracts, expansion screen and five semantic rejection controls; no new kappa." + } + ] +} diff --git a/research/pr4633-contract-audit/vendor/bit-ambient-quotient/QUOTIENT-BIT-WORD.json.gz b/research/pr4633-contract-audit/vendor/bit-ambient-quotient/QUOTIENT-BIT-WORD.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..fa2fa7618a66b98a4e78711f307bc893c86b1405 GIT binary patch literal 83523 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 literal 0 HcmV?d00001 diff --git a/research/pr4633-contract-audit/vendor/bit-ambient-quotient/RESULT.json b/research/pr4633-contract-audit/vendor/bit-ambient-quotient/RESULT.json new file mode 100644 index 0000000000..ba73ce57db --- /dev/null +++ b/research/pr4633-contract-audit/vendor/bit-ambient-quotient/RESULT.json @@ -0,0 +1,55 @@ +{ + "ambient_dim": 8, + "directions_agree": true, + "emitted_kappa": 0.003464248972023964, + "emitted_paid": { + "1": 1323, + "2": 1342, + "3": 79, + "4": 44, + "5": 102, + "6": 11, + "7": 19 + }, + "emitted_paid_mass": 5129, + "emitted_surplus": 753, + "endpoint_failures": 0, + "frames": 65, + "gain_absolute": 0.02878517442286887, + "gain_relative": 8.309210641419726, + "helper_widths": { + "8": 439 + }, + "kernel_basis": [ + 150, + 102, + 255 + ], + "kernel_dimension": 3, + "local_checks": { + "adds": 24305, + "copies": 9 + }, + "main_rank_mass": 1294, + "main_widths": { + "4": 103, + "7": 70, + "8": 49 + }, + "package": "bit-ambient-quotient", + "quotient_kappa": 0.03224942339489283, + "quotient_paid": { + "1": 1020, + "2": 495, + "3": 75, + "4": 442, + "5": 143, + "6": 4, + "7": 12, + "8": 2 + }, + "quotient_paid_mass": 4842, + "quotient_surplus": 5919, + "roles": 661, + "status": "PASS_BIT_AMBIENT_QUOTIENT" +} diff --git a/research/pr4633-contract-audit/vendor/bit-ambient-quotient/build.py b/research/pr4633-contract-audit/vendor/bit-ambient-quotient/build.py new file mode 100644 index 0000000000..ae55584ddb --- /dev/null +++ b/research/pr4633-contract-audit/vendor/bit-ambient-quotient/build.py @@ -0,0 +1,206 @@ +#!/usr/bin/env python3 +"""Build a quotient of the BIT local word by a kernel subspace. Apache-2.0. + +The BIT supplier's local word is PR589's E8 word: `h = 8`, `V = 111` roles per +side, `R = 439` helpers, 661 roles, 636 frames and 249 records. Frames are +stored by annihilator rows, so a frame is the GF(2) nullspace of its rows. + +For a kernel subspace `K` of dimension `k` the linear map + + phi : F2^8 -> F2^(8-k), phi(x) = (r_1.x, ..., r_(8-k).x) + +over a basis `r` of the annihilator of `K` is surjective with kernel exactly `K`. +It shrinks exactly the frames meeting `K`, so a MOVE whose destination meets `K` +more than its source does loses that many ranks. Frames with the same image are +identified, the helper finals are restored to the full F2^8 (the contract requires +every helper to be physically `D_I8` and the tensor block to stay 7), and every +MOVE rank is recomputed from the new dimensions. + +The kernel is chosen by replay, not arithmetic: `scan_kernels.py` builds, replays +and prices the candidates. One dimension gives 0.0124, two give 0.0218, three give +0.0322, and four fall back to 0.0175. + + python3 -B build.py +""" +import gzip +import json +import struct +import sys +from collections import Counter +from hashlib import sha256 +from pathlib import Path + +sys.dont_write_bytecode = True +HERE = Path(__file__).resolve().parent +ROOT = HERE.parents[1] +SOURCE = ROOT/'research/kappa-rebuild/bit/sources/pr589-regenerated' +V, R, H = 111, 439, 8 +ROLES = 2*V+R +KERNEL_BASIS = (150, 102, 255) + + +def need(ok, message): + if not ok: + raise ValueError(message) + + +def mask(row): + return sum((row[j] & 1) << j for j in range(H)) + + +def frame_vectors(annihilator): + rows = [mask(r) for r in annihilator] + return [x for x in range(1 << H) + if all(bin(r & x).count('1') % 2 == 0 for r in rows)] + + +def rref(rows): + piv = {} + for r in [x for x in rows if x]: + y = r + for p in sorted(piv, reverse=True): + if y >> p & 1: + y ^= piv[p] + if y: + piv[y.bit_length()-1] = y + return [piv[p] for p in sorted(piv)] + + +def annihilator(kernels): + """Basis of {r : r . k = 0 for every k in the kernel basis}.""" + basis = rref(kernels) + pivots = {b.bit_length()-1 for b in basis} + out = [] + for f in [j for j in range(H) if j not in pivots]: + v = 1 << f + for b in basis: + if bin(b & v).count('1') & 1: + v |= 1 << (b.bit_length()-1) + out.append(v) + return out + + +def span_of(vectors): + out = {0} + for v in vectors: + out |= {x ^ v for x in out} + return frozenset(out) + + +def dedupe(vectors): + pivots, keep = {}, [] + for v in vectors: + y = v + while y: + b = y.bit_length()-1 + if b in pivots: + y ^= pivots[b] + else: + pivots[b] = y + keep.append(v) + break + return keep + + +def build(kernels=KERNEL_BASIS): + kernels = list(kernels) + need(len(rref(kernels)) == len(kernels), 'kernel basis must be independent') + width = H-len(kernels) + rows = annihilator(kernels) + need(len(rows) == width, 'annihilator dimension') + + def phi(x): + return sum((bin(r & x).count('1') & 1) << i for i, r in enumerate(rows)) + + word = json.load(gzip.open(SOURCE/'WORD.json.gz')) + need((word['h'], word['v'], word['R']) == (H, V, R), 'Pinned local type') + frames_raw = json.loads((SOURCE/'records/frames.json').read_text())['frames'] + records = list(struct.iter_unpack('<6i', (SOURCE/'records/249-records.bin').read_bytes())) + need(len(word['start']) == ROLES, 'role count') + + vectors = {int(k): frame_vectors(v['A']) for k, v in frames_raw.items()} + need(len(vectors[1]) == 1 << H, 'frame 1 is the full ambient') + + table, table_dim, table_basis = {}, {}, [] + + def index_of(mapped): + basis = dedupe(mapped) + key = span_of(basis) + if key not in table: + table[key] = len(table) + table_dim[table[key]] = len(key).bit_length()-1 + table_basis.append(sorted(basis)) + return table[key] + + image = {f: index_of([phi(x) for x in vectors[f]]) for f in vectors} + + # The full ambient meets every kernel direction, so its image is (8-k)- + # dimensional. Restore it: the frame becomes the whole of F2^8 again, so + # every role that ended there ends there again and helper ranks are preserved. + full_image = image[1] + base = next(key for key, idx in table.items() if idx == full_image) + freed = [1 << j for j in range(width, H)] + extras = [sum(1 << (width+i) for i in bits) for bits in _subsets(len(freed))] + pad_key = frozenset(x | e for x in base for e in extras) + need(len(pad_key) == 1 << H, 'padded frame must be the full ambient') + if pad_key not in table: + table[pad_key] = len(table) + table_dim[table[pad_key]] = H + table_basis.append([1 << i for i in range(H)]) + pad_index = table[pad_key] + for f in image: + if image[f] == full_image: + image[f] = pad_index + + start = [image[s] for s in word['start']] + final = [image[f] for f in word['final']] + + rewritten = [] + for op, x, y, c, f, z in records: + if op == 0: + old, new = image[y], image[c] + rewritten.append([op, x, old, new, table_dim[new]-table_dim[old], z]) + elif op == 1: + rewritten.append([op, x, y, c, image[f], z]) + else: + rewritten.append([op, x, y, image[c], image[f], z]) + + helpers = list(range(2*V, ROLES)) + need(all(table_dim[final[r]] == H for r in helpers), 'helper finals must be D_I8') + need(all(table_dim[start[r]] == 0 for r in helpers), 'helper starts must be ground') + + mains = Counter(table_dim[final[r]]-table_dim[start[r]] for r in range(2*V)) + return {'kernel_basis': kernels, 'ambient_dim': H, 'quotient_width': width, + 'roles': ROLES, 'pairs': V, 'helpers': R, + 'source_frames': len(vectors), 'frames': len(table), + 'frame_dims': table_dim, 'frame_bases': table_basis, + 'start': start, 'final': final, + 'records': rewritten, + 'main_widths': {str(k): v for k, v in sorted(mains.items())}, + 'main_rank_mass': sum(k*v for k, v in mains.items()), + 'helper_rank_mass': sum(table_dim[final[r]]-table_dim[start[r]] + for r in helpers), + 'source_word_sha256': sha256((SOURCE/'WORD.json.gz').read_bytes()).hexdigest()} + + +def _subsets(n): + return [[j for j in range(n) if i >> j & 1] for i in range(1 << n)] + + +def main(): + artifact = build() + print('kernel %s frames %d -> %d roles %d' + % (artifact['kernel_basis'], artifact['source_frames'], + artifact['frames'], ROLES)) + print('frame dims %s' % dict(sorted(Counter(artifact['frame_dims'].values()).items()))) + print('main widths %s (mass %d)' + % (artifact['main_widths'], artifact['main_rank_mass'])) + print('helper rank mass %d' % artifact['helper_rank_mass']) + with open(HERE/'QUOTIENT-BIT-WORD.json.gz', 'wb') as raw: + with gzip.GzipFile(fileobj=raw, mode='wb', mtime=0) as handle: + handle.write(json.dumps(artifact, sort_keys=True).encode()) + print('wrote QUOTIENT-BIT-WORD.json.gz') + + +if __name__ == '__main__': + main() diff --git a/research/pr4633-contract-audit/vendor/bit-ambient-quotient/verify.py b/research/pr4633-contract-audit/vendor/bit-ambient-quotient/verify.py new file mode 100644 index 0000000000..f0acb7c51e --- /dev/null +++ b/research/pr4633-contract-audit/vendor/bit-ambient-quotient/verify.py @@ -0,0 +1,231 @@ +#!/usr/bin/env python3 +"""Independent verifier for the BIT ambient quotient. Apache-2.0. + +Loads the artifact written by `build.py` and the pinned source word, replays both +with the shipped local-word semantics (`mixed_productive_bit.audit_local`'s +record interpreter), and prices the emitted and quotient invoices with the +two-constraint screen. + +It does not import `build.py`. + + python3 -B verify.py +""" +import gzip +import json +import struct +import sys +from collections import Counter +from pathlib import Path + +sys.dont_write_bytecode = True +HERE = Path(__file__).resolve().parent +ROOT = HERE.parents[1] +SOURCE = ROOT/'research/kappa-rebuild/bit/sources/pr589-regenerated' + +PAIRS, HELPERS, AMBIENT = 111, 439, 8 +STAGES = 16 +ROLES = 2*PAIRS+HELPERS +CALLS, SPLIT = 18, 7 +PORTS, BLOCK = 111, 7 +TAIL_OFFSET, CUTOFF, TARGET_GAMMA = 0.2, 20.0, 0.97 +LOCAL = Counter({1: 1323, 2: 1342, 3: 79, 4: 44, 5: 102, 6: 11, 7: 19}) +ADDS, COPIES = 24305, 9 + + +def need(ok, message): + if not ok: + raise ValueError(message) + + +def _rank(rows): + piv = {} + for r in [x for x in rows if x]: + y = r + for p in sorted(piv, reverse=True): + if y >> p & 1: + y ^= piv[p] + if y: + piv[y.bit_length()-1] = y + return len(piv) + + +def moment(profile, exponent): + return sum(n*(r**exponent) for r, n in profile.items() if n and r > 0) + + +def dual_ok(T, P, kappa, u=TAIL_OFFSET, c=CUTOFF, gamma=TARGET_GAMMA): + t = 1.0-kappa + return moment(P, t) < moment(T, t) and moment(P, t+u) < gamma*(c**u)*moment(T, t) + + +def admissible_kappa(T, P, lo=1e-7, hi=0.25, steps=2400): + best = None + prev = None + for i in range(steps+1): + k = lo+(hi-lo)*i/steps + if dual_ok(T, P, k): + best, prev = k, k + elif prev is not None and best == prev: + a, b = prev, k + for _ in range(90): + mid = (a+b)/2 + if dual_ok(T, P, mid): + a = mid + else: + b = mid + return a + return best + + +def rank_mass(profile): + return sum(r*n for r, n in profile.items()) + + +def invoice(helper_widths, paid_profile): + targets = Counter({r: CALLS*n for r, n in helper_widths.items()}) + paid = Counter({r: CALLS*n for r, n in paid_profile.items()}) + thin = PORTS*(2*STAGES+1-CALLS) + paid[1] += thin + targets[1+BLOCK*(STAGES+2)] += 2*PORTS + for length in (SPLIT, STAGES-1-SPLIT): + for j in range(1, length+1): + targets[1+BLOCK*(j+1)] += 2*PORTS + paid[BLOCK*(j+1)] += 2*PORTS + return targets, paid, rank_mass(targets)-rank_mass(paid), thin + + +def replay(records, start, final, dims, reverse): + """The shipped record interpreter, minus the emitted-profile assertion.""" + current = list(final if reverse else start)+[-1] + values = [1 << i for i in range(ROLES)]+[0] + owned = None + profile = Counter() + adds = copies = 0 + for op, x, y, c, f, z in (reversed(records) if reverse else records): + if op == 0: + old, new = (c, y) if reverse else (y, c) + need(current[x] == old, 'MOVE entrance: role %d at frame %d, expected %d' + % (x, current[x], old)) + current[x] = new + if f: + profile[f] += 1 + elif op == 1: + need(current[x] == current[y] == f, 'ADD common frame at role %d' % x) + need(owned is None or x != owned, 'owned source mutated') + values[x] ^= values[y] if c & 1 else 0 + adds += 1 + elif op == (3 if reverse else 2): + need(owned is None and y == ROLES and values[ROLES] == 0 + and current[x] == c, 'COPY entrance') + owned = x + current[ROLES] = f + values[ROLES] = values[x] + profile[abs(dims[c]-dims[f])] += 1 + copies += 1 + else: + need(op == (2 if reverse else 3) and owned == x and y == ROLES, + 'COPY close') + need(values[ROLES] == values[x], 'copied field exact cleanup') + values[ROLES], owned = 0, None + expected = [(1 << i) ^ ((1 << (i-PAIRS)) if PAIRS <= i < 2*PAIRS else 0) + for i in range(ROLES)] + need(values == expected+[0], 'arbitrary input columns are not exact') + need(current[:ROLES] == (start if reverse else final), 'endpoints are not exact') + need(adds == ADDS and copies == COPIES, 'complete local word') + return profile, adds, copies + + +def main(): + with gzip.open(HERE/'QUOTIENT-BIT-WORD.json.gz', 'rt') as handle: + artifact = json.load(handle) + kernels = [int(v) for v in artifact['kernel_basis']] + dims = {int(k): v for k, v in artifact['frame_dims'].items()} + start, final = artifact['start'], artifact['final'] + records = [tuple(r) for r in artifact['records']] + + need(artifact['ambient_dim'] == AMBIENT, 'ambient is not eight') + need(len(start) == len(final) == ROLES, 'role count') + need(1 <= len(kernels) < AMBIENT, 'kernel dimension out of range') + need(all(0 < k < (1 << AMBIENT) for k in kernels), 'kernel vector out of range') + need(_rank(kernels) == len(kernels), 'kernel basis is not independent') + need(artifact['quotient_width'] == AMBIENT - len(kernels), + 'quotient width does not match the kernel dimension') + need(max(dims.values()) == AMBIENT, 'no frame reaches the full ambient') + need(all(dims[final[r]] == AMBIENT for r in range(2*PAIRS, ROLES)), + 'a helper final is not D_I8') + need(all(dims[start[r]] == 0 for r in range(2*PAIRS, ROLES)), + 'a helper start is not ground') + + mains = Counter(dims[final[r]]-dims[start[r]] for r in range(2*PAIRS)) + helpers = Counter(dims[final[r]]-dims[start[r]] for r in range(2*PAIRS, ROLES)) + print('artifact: kernel %s (dim %d), %d frames, %d roles, ambient %d' + % (kernels, len(kernels), len(dims), ROLES, AMBIENT)) + print('main widths %s ; helper widths %s' + % (dict(sorted(mains.items())), dict(sorted(helpers.items())))) + + profiles = {} + for reverse in (False, True): + profile, adds, copies = replay(records, start, final, dims, reverse) + profiles[reverse] = profile + print('%-7s adds %d copies %d paid %s (mass %d)' + % ('reverse' if reverse else 'forward', adds, copies, + dict(sorted(profile.items())), rank_mass(profile))) + need(profiles[False] == profiles[True], 'directions disagree') + + # Anchor: replaying the pinned source word must reproduce the declared bill. + source_word = json.load(gzip.open(SOURCE/'WORD.json.gz')) + source_frames = json.loads((SOURCE/'records/frames.json').read_text())['frames'] + source_dims = {int(k): v['dim'] for k, v in source_frames.items()} + source_records = list(struct.iter_unpack('<6i', (SOURCE/'records/249-records.bin').read_bytes())) + emitted = Counter() + for reverse in (False, True): + profile, _, _ = replay(list(source_records), source_word['start'], + source_word['final'], source_dims, reverse) + need(profile == LOCAL, 'source word does not reproduce the declared bill') + emitted = profile + print('source paid %s (mass %d) matches the declared local bill' + % (dict(sorted(emitted.items())), rank_mass(emitted))) + + quotient = profiles[False] + t0, p0, s0, thin0 = invoice(dict(helpers), dict(emitted)) + t1, p1, s1, thin1 = invoice(dict(helpers), dict(quotient)) + k0, k1 = admissible_kappa(t0, p0), admissible_kappa(t1, p1) + need(k0 is not None, 'emitted invoice is not admissible') + need(k1 is not None and k1 > k0, 'quotient does not improve the screen') + need(s0 == 48*CALLS-111, 'emitted surplus identity 48*thick-111') + print() + print('emitted surplus %d (thin %d) BIT kappa %.15f' % (s0, thin0, k0)) + print('quotient surplus %d (thin %d) BIT kappa %.15f' % (s1, thin1, k1)) + print('gain %+.15f %+.2f%%' % (k1-k0, 100*(k1/k0-1))) + + result = { + 'package': 'bit-ambient-quotient', + 'status': 'PASS_BIT_AMBIENT_QUOTIENT', + 'kernel_basis': kernels, + 'kernel_dimension': len(kernels), + 'frames': len(dims), + 'roles': ROLES, + 'ambient_dim': AMBIENT, + 'helper_widths': {str(r): n for r, n in sorted(helpers.items())}, + 'main_widths': {str(r): n for r, n in sorted(mains.items())}, + 'main_rank_mass': rank_mass(mains), + 'emitted_paid': {str(r): n for r, n in sorted(emitted.items())}, + 'quotient_paid': {str(r): n for r, n in sorted(quotient.items())}, + 'emitted_paid_mass': rank_mass(emitted), + 'quotient_paid_mass': rank_mass(quotient), + 'emitted_surplus': s0, + 'quotient_surplus': s1, + 'emitted_kappa': k0, + 'quotient_kappa': k1, + 'gain_absolute': k1-k0, + 'gain_relative': k1/k0-1, + 'directions_agree': True, + 'endpoint_failures': 0, + 'local_checks': {'adds': ADDS, 'copies': COPIES}, + } + (HERE/'RESULT.json').write_text(json.dumps(result, indent=2, sort_keys=True)+'\n') + print('wrote RESULT.json') + + +if __name__ == '__main__': + main() diff --git a/research/pr4633-contract-audit/vendor/complex-ambient-quotient/QUOTIENT-WORD.json.gz b/research/pr4633-contract-audit/vendor/complex-ambient-quotient/QUOTIENT-WORD.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..31444b48850cbe220d4ddbf88496722682581fb8 GIT binary patch literal 3979 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 literal 0 HcmV?d00001 diff --git a/research/pr4633-contract-audit/vendor/complex-ambient-quotient/RESULT.json b/research/pr4633-contract-audit/vendor/complex-ambient-quotient/RESULT.json new file mode 100644 index 0000000000..dc50c5a29a --- /dev/null +++ b/research/pr4633-contract-audit/vendor/complex-ambient-quotient/RESULT.json @@ -0,0 +1,45 @@ +{ + "alpha_slack": 1.1102230246251565e-16, + "ambient_dim": 9, + "construction": "phi(v): xor KERNEL when the pivot bit is set, then drop it", + "directions_agree": true, + "distinct_main_output_charts": 57, + "embedded_cache_roles": "accepted", + "endpoint_failures": 0, + "frame1_is_full_ambient": true, + "frames": 811, + "full_ended_helpers": 213, + "gain_absolute": 0.01261698311386594, + "gain_relative": 4.177579381360274, + "gamma_slack": 0.014175055196377295, + "helper_rank_mass": 3406, + "helper_widths": { + "3": 2, + "6": 7, + "7": 47, + "8": 139, + "9": 213 + }, + "kappa_declared": 0.00302015, + "kappa_emitted": 0.003020165977015543, + "kappa_quotient": 0.015637149090881482, + "kernel_vector": 153, + "local_deficit": 1688, + "main_rank_mass": 1624, + "main_widths": { + "7": 168, + "8": 56 + }, + "paid_profile": { + "1": 2177, + "2": 424, + "3": 389, + "4": 147, + "5": 50, + "8": 8 + }, + "paid_rank_mass": 5094, + "peak_vector": 256, + "surplus_emitted": 752, + "surplus_quotient": 3776 +} diff --git a/research/pr4633-contract-audit/verify.py b/research/pr4633-contract-audit/verify.py new file mode 100644 index 0000000000..a0d2db1b2f --- /dev/null +++ b/research/pr4633-contract-audit/verify.py @@ -0,0 +1,224 @@ +#!/usr/bin/env python3 +"""PR4633 endpoint audit; Apache-2.0, substantial OpenAI Codex assistance. + +Exact finite geometry and contract checks. All float roots are pricing screens. +No new kappa, physical lowering or complete outer admission is claimed. +""" +import argparse +from collections import Counter +from copy import deepcopy +from fractions import Fraction as Q +import gzip +from hashlib import sha1, sha256 +import importlib.util +import json +from pathlib import Path +import struct +import sys + +sys.dont_write_bytecode = True +HERE = Path(__file__).resolve().parent +ROOT = HERE.parents[1] +BIT = ROOT/'research/kappa-rebuild/bit/sources/pr589-regenerated' + + +def need(ok, message): + if not ok: + raise ValueError(message) + + +def load(path, name): + spec = importlib.util.spec_from_file_location(name, path) + module = importlib.util.module_from_spec(spec) + sys.modules[name] = module + spec.loader.exec_module(module) + return module + + +def read(path): + raw = path.read_bytes() + return json.loads(gzip.decompress(raw) if path.suffix == '.gz' else raw) + + +def authenticate(): + pins = read(HERE/'SOURCES.json')['files'] + for row in pins: + if row['usage'] != 'input': + continue + path = ROOT/row['path']; raw = path.read_bytes() + need(not path.is_symlink(), 'Source alias') + need(sha256(raw).hexdigest() == row['sha256'], 'Source SHA256: '+row['path']) + need(sha1(b'blob '+str(len(raw)).encode()+b'\0'+raw).hexdigest() == row['git_blob'], 'Source Git blob') + vendors = read(HERE/'VENDORED.json')['files'] + for row in vendors: + path = HERE/row['local_path']; raw = path.read_bytes() + need(not path.is_symlink(), 'Vendored source alias') + need(sha256(raw).hexdigest() == row['sha256'], 'Vendored source SHA256') + need(sha1(b'blob '+str(len(raw)).encode()+b'\0'+raw).hexdigest() == row['git_blob'], + 'Vendored original Git blob') + return sum(row['usage'] == 'input' for row in pins)+len(vendors) + + +def rational_basis(vectors): + pivots, kept = {}, [] + for vector in vectors: + row = list(map(Q, vector)) + for p, basis in sorted(pivots.items()): + amount = row[p]; row = [x-amount*y for x, y in zip(row, basis)] + p = next((i for i, x in enumerate(row) if x), None) + if p is not None: + scale = row[p]; pivots[p] = [x/scale for x in row]; kept.append(vector) + return kept + + +def span(vectors): + out = {0} + for v in vectors: + out |= {x ^ v for x in tuple(out)} + return frozenset(out) + + +def histogram(values): + return {str(k): v for k, v in sorted(Counter(values).items())} + + +def bit_contract(frames, start, final): + bad = [] + for p in range(111): + P, X, Y0, Y = [frames[f] for f in (start[p], final[p], start[111+p], final[111+p])] + if [len(rational_basis(F)) for F in (P, X, Y0, Y)] != [1, 8, 0, 7] or len(rational_basis(P+Y)) != 8: + bad.append(p) + return bad + + +def binary_contract(frames, start, final, ports, ambient): + bad, widths, intersections = [], [], [] + for p in range(ports): + P, X, Y0, Y = [span(frames[f]) for f in (start[p], final[p], start[ports+p], final[ports+p])] + d = lambda F: len(F).bit_length()-1 + widths.extend((d(X)-d(P), d(Y)-d(Y0))); intersections.append(d(P & Y)) + if [d(P), d(X), d(Y0), d(Y)] != [1, ambient, 0, ambient-1] or P & Y != {0}: + bad.append(p) + return {'accepted': ports-len(bad), 'rejected': len(bad), + 'main_widths': histogram(widths), 'intersection_dimensions': histogram(intersections)} + + +def validate_binary_frames(artifact): + F = artifact['frame_bases']; dims = {int(f): d for f, d in artifact['frame_dims'].items()} + need(set(dims) == set(range(len(F))), 'Complete frame dimensions') + for f, basis in enumerate(F): + need(all(isinstance(v, int) and 0 < v < 256 for v in basis), 'Eight binary axes') + need(len(span(basis)) == 2**len(basis) and len(basis) == dims[f], 'Frame basis and dimension') + for op, x, old, new, rank, z in artifact['records']: + if op == 0: + need(span(F[old]) <= span(F[new]), 'Nested MOVE') + need(rank == dims[new]-dims[old] >= 0, 'Actual MOVE rank') + + +def rejected(fn): + try: + fn() + except (ValueError, AssertionError): + return True + return False + + +def run(): + pins = authenticate() + B = load(HERE/'vendor/bit-ambient-quotient/build.py', 'audit4633_builder') + B.SOURCE = BIT # Bind the unchanged vendored builder to its original source inputs. + V = load(HERE/'vendor/bit-ambient-quotient/verify.py', 'audit4633_logical_replay') + source = read(BIT/'WORD.json.gz'); raw = read(BIT/'records/frames.json')['frames'] + rational = {int(f): row['B'] for f, row in raw.items()}; ds = {int(f): row['dim'] for f, row in raw.items()} + records = list(struct.iter_unpack('<6i', (BIT/'records/249-records.bin').read_bytes())) + need(not bit_contract(rational, source['start'], source['final']), 'All 111 rational source ports') + profiles = [V.replay(records, source['start'], source['final'], ds, reverse)[0] for reverse in (False, True)] + need(profiles[0] == profiles[1] == V.LOCAL, 'Source logical map and complete invoice') + reduced = {int(f): sorted(B.dedupe(B.frame_vectors(row['A']))) for f, row in raw.items()} + mod2_source = binary_contract(reduced, source['start'], source['final'], 111, 8) + need(mod2_source['accepted'] == 8, 'GF(2) reduction loses 103 rational complements') + roots = [rational[source['start'][p]][0] for p in range(111)] + need(len({tuple(v) for v in roots}) == 111, 'Distinct rational entrance representatives') + need(len({span(reduced[source['start'][p]]) for p in range(111)}) == 22, '22 reduced entrance lines') + u = roots[8]; normal = raw[str(source['final'][111+8])]['A'][0] + dot = sum(a*b for a, b in zip(u, normal)) + need(dot == 4 and dot % 2 == 0, 'Rational complement becomes binary containment') + quotient_rows = {} + for name, artifact in [('headline_kernel_150', B.build([150])), + ('submitted_kernel_150_102_255', read(HERE/'vendor/bit-ambient-quotient/QUOTIENT-BIT-WORD.json.gz'))]: + validate_binary_frames(artifact); dims = {int(f): d for f, d in artifact['frame_dims'].items()} + replay = [V.replay(artifact['records'], artifact['start'], artifact['final'], dims, reverse)[0] for reverse in (False, True)] + need(replay[0] == replay[1], 'Both quotient logical directions') + contract = binary_contract(dict(enumerate(artifact['frame_bases'])), artifact['start'], artifact['final'], 111, 8) + need(contract['rejected'] == 111, 'No BIT port satisfies the block-7 call') + main_mass = sum(dims[artifact['final'][r]]-dims[artifact['start'][r]] for r in range(222)) + helper_mass = sum(dims[artifact['final'][r]]-dims[artifact['start'][r]] for r in range(222, 661)) + copy_mass = sum(abs(dims[c]-dims[f]) for op, x, y, c, f, z in artifact['records'] if op == 2) + paid_mass = V.rank_mass(replay[0]) + need(paid_mass == main_mass+helper_mass+copy_mass, 'MOVE telescope plus owned COPY cost') + T, P, surplus, _ = V.invoice({8: 439}, replay[0]) + quotient_rows[name] = {**contract, 'kernel': artifact['kernel_basis'], 'logical_replay': True, + 'paid_mass': paid_mass, 'main_mass': main_mass, 'helper_mass': helper_mass, + 'copy_mass': copy_mass, 'mispriced_surplus': surplus, 'mispriced_float_screen': V.admissible_kappa(T, P)} + # Any monotone frame contraction fixing all entrance lines fixes every source frame. + lower, upper_codim = {}, {} + normals = [raw[str(source['final'][111+p])]['A'][0] for p in range(111)] + for f, row in raw.items(): + need(len(rational_basis(row['B'])) == row['dim'] and + len(rational_basis(row['A'])) == 8-row['dim'], 'Source rational frame ranks') + need(all(sum(a*b for a, b in zip(n, u)) == 0 for n in row['A'] for u in row['B']), + 'Source rational kernel and image agree') + inside = [u for u in roots if all(sum(a*b for a, b in zip(n, u)) == 0 for n in row['A'])] + lower[int(f)] = len(rational_basis(inside)) + containing = [n for n in normals if all(sum(a*b for a, b in zip(n, u)) == 0 for u in row['B'])] + upper_codim[int(f)] = len(rational_basis(containing)) + need(lower == ds and len(lower) == 636, '636 source frames forced by fixed entrance lines') + upper = {f: 8-d for f, d in upper_codim.items()} + need(all(upper[source[k][r]] == ds[source[k][r]] for k in ('start', 'final') for r in range(661)), 'Expansion endpoints') + expanded_records = [(op, x, y, c, upper[c]-upper[y], z) if op == 0 else (op, x, y, c, f, z) for op, x, y, c, f, z in records] + expanded_profiles = [V.replay(expanded_records, source['start'], source['final'], upper, reverse)[0] for reverse in (False, True)] + need(expanded_profiles[0] == expanded_profiles[1], 'Expansion both logical directions') + T, P, expanded_surplus, _ = V.invoice({8: 439}, expanded_profiles[0]) + expanded_screen = V.admissible_kappa(T, P) + need(expanded_screen < .00346424, 'Expansion does not repair the gain') + J = load(ROOT/'research/joint-helper-lattice/native_joint.py', 'audit4633_complex_source') + original, *_ = J.construct(); complex_word = read(HERE/'vendor/complex-ambient-quotient/QUOTIENT-WORD.json.gz') + complex_source = binary_contract(dict(enumerate(original['frames'])), original['start'], original['final'], 112, 9) + complex_quotient = binary_contract(dict(enumerate(complex_word['frames'])), complex_word['start'], complex_word['final'], 112, 9) + need(complex_source['accepted'] == 112 and complex_quotient['accepted'] == 0, 'Complex contract') + need(complex_quotient['main_widths'] == {'7': 168, '8': 56}, 'Complex widths') + artifact = read(HERE/'vendor/bit-ambient-quotient/QUOTIENT-BIT-WORD.json.gz') + bad = deepcopy(artifact); next(e for e in bad['records'] if e[0] == 0)[4] += 1 + bad_basis = deepcopy(artifact); bad_basis['frame_bases'][0] = [1, 1] + wrong_start = list(source['start']); wrong_start[0] = source['start'][111] + omitted = list(records); omitted.pop(next(i for i, e in enumerate(omitted) if e[0] == 1 and e[3] & 1)) + spoofed = deepcopy(artifact); spoofed['main_widths'] = {'7': 222} + controls = {'wrong_move_rank': rejected(lambda: validate_binary_frames(bad)), + 'dependent_frame_basis': rejected(lambda: validate_binary_frames(bad_basis)), + 'changed_source_entrance': bool(bit_contract(rational, wrong_start, source['final'])), + 'omitted_source_add': rejected(lambda: V.replay(omitted, source['start'], source['final'], ds, False)), + 'spoofed_main_width_metadata': binary_contract(dict(enumerate(spoofed['frame_bases'])), spoofed['start'], spoofed['final'], 111, 8)['rejected'] == 111} + need(all(controls.values()), 'Semantic mutation controls') + # For any nonzero k-dimensional kernel, a hyperplane image has dimension + # h-k or h-k-1. Re-padding full images yields h; proper images are <= h-2. + for h in (8, 9): + for k in range(1, h): + need(h-1 not in {h if d == h-k else d for d in (h-k, h-k-1)}, 'Padded hyperplane obstruction') + return {'status': 'PASS_PR4633_CONTRACT_AUDIT_NO_NEW_KAPPA', 'reviewed_head': 'b390d64abfcdba1a3816b86fc763cbc95d43c12c', + 'authenticated_inputs': pins, 'bit_source_ports_accepted': 111, 'bit_rational_frames_forced_by_fixed_lines': 636, + 'bit_gf2_reduction_before_quotient': mod2_source, 'bit_field_mismatch_witness': {'port': 8, 'source_dot_over_Q': dot, 'source_dot_mod_2': dot % 2}, + 'bit_quotients': quotient_rows, 'expansion_repair_screen_only': {'changed_frames': sum(upper[f] != ds[f] for f in ds), + 'paid_mass': V.rank_mass(expanded_profiles[0]), 'surplus': expanded_surplus, 'float_screen': expanded_screen, 'native_lowering_checked': False}, + 'complex_source': complex_source, 'complex_quotient': complex_quotient, 'negative_controls': controls, + 'scope': 'Finite endpoint and geometry audit; no new kappa, native realization or outer admission.'} + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description=__doc__); parser.add_argument('--write', action='store_true'); args = parser.parse_args() + result = run() + if args.write: + (HERE/'RESULT.json').write_text(json.dumps(result, indent=2, sort_keys=True)+'\n') + else: + need(result == read(HERE/'RESULT.json'), 'Deterministic audit receipt') + print(result['status']) + print('bit_ports_rejected=111 complex_ports_rejected=112 forced_rational_frames=636 controls=5') From be3212f37259d9ec626cc4d19974e8079d9a3e9e Mon Sep 17 00:00:00 2001 From: Cinna Davis <1337isnot1337@users.noreply.github.com> Date: Thu, 22 Oct 2026 09:11:21 -0500 Subject: [PATCH 2/3] Credit overlapping audits and focus publication on repair bounds --- research/pr4633-contract-audit/OVERLAP.json | 24 +++++++++++++++++++ research/pr4633-contract-audit/README.md | 26 +++++++++++++++++++-- research/pr4633-contract-audit/TASK.json | 4 ++-- 3 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 research/pr4633-contract-audit/OVERLAP.json diff --git a/research/pr4633-contract-audit/OVERLAP.json b/research/pr4633-contract-audit/OVERLAP.json new file mode 100644 index 0000000000..3f04d1b023 --- /dev/null +++ b/research/pr4633-contract-audit/OVERLAP.json @@ -0,0 +1,24 @@ +{ + "checked_after_requested_wait": true, + "checked_at_utc": "2026-10-22T14:08:51Z", + "coverage": { + "recent_prs_all_states": 1000, + "recent_discussions": 30, + "comments_per_discussion": 20, + "latest_handoff_comments": 30, + "additional_targeted_pr_search": "repo:CrocSwap/integer-mult-bounds is:pr 4633" + }, + "related": [ + { + "pr": 4636, + "head": "b0a325a3e312b7c5ebceb420de4b8cb13181f43e", + "scope": "Broader negative audit, rational mismatch, endpoint failures, mutations and full scans. README and both short verifiers inspected." + }, + { + "pr": 4642, + "head": "d8c59e36a8efb301f0298871218cfe00f4e043f7", + "scope": "Complex re-padding ledger and price; body and file inventory inspected." + } + ], + "publication_scope": "636-frame monotone contraction obstruction, global padded-hyperplane dimension obstruction, and failed endpoint-preserving expansion. No new kappa. No global novelty claim outside the recorded coverage." +} diff --git a/research/pr4633-contract-audit/README.md b/research/pr4633-contract-audit/README.md index b143a4ed68..2e11f8cda0 100644 --- a/research/pr4633-contract-audit/README.md +++ b/research/pr4633-contract-audit/README.md @@ -1,4 +1,4 @@ -# PR4633 contract audit and bounded repair attempts +# Endpoint-preserving repair bounds for PR4633 **The submitted quotient screens do not establish a new κ.** This audit reviews PR4633 at `b390d64abfcdba1a3816b86fc763cbc95d43c12c` and keeps every submitted @@ -14,6 +14,25 @@ unchanged. The audit binds the copied builder's `SOURCE` path to the original PR589 source directory before calling it. `SOURCES.json` pins the remaining inputs from main. Every audit input is available in the publication checkout. +## Overlap and the contribution here + +The publication overlap check found [PR4636](https://github.com/CrocSwap/integer-mult-bounds/pull/4636) +at `b0a325a3e312b7c5ebceb420de4b8cb13181f43e`, which already supplies a broader +negative audit: rational-field counterexamples, endpoint failures, verifier +false positives and full scan discrepancies. Those objections are prior +concurrent findings; the endpoint and field checks below provide reproducible +context for this package's repair tests. + +This package contributes the exact **636-frame contraction obstruction**, the +**general hyperplane-dimension obstruction for global full-image padding**, and +the **endpoint-preserving expansion candidate and its failed price**. PR4636's +README and both short verifiers were inspected at that head; no equivalent +repair-bound certificate was found in that scope. +[PR4642](https://github.com/CrocSwap/integer-mult-bounds/pull/4642), at +`d8c59e36a8efb301f0298871218cfe00f4e043f7`, independently audits complex re-padding +and its invoice. Its ledger corrections are separate from the repair bounds +here. `OVERLAP.json` records the bounded search coverage and exact related heads. + ## What reproduces The submitted BIT and complex verifiers reproduce their committed RESULT.json @@ -166,7 +185,10 @@ endpoint concern was raised by pinterbanget (#4604), the quotient-kernel census by Nick Petalas (#4627), and the per-port controller-contract audit by Rohan Arun in his PR4633 comment. This audit independently checks those concerns, adds the rational/GF(2) witness, covers the actual three-dimensional artifact, -corrects the COPY/main rank attribution, and bounds two repair routes. +corrects the COPY/main rank attribution, and bounds two repair routes. The +broader independent audit in #4636 already establishes the rational-field, +endpoint and verifier objections; this package's publication focuses on the +complementary repair bounds described above. Prepared for Cinna Davis with substantial OpenAI Codex assistance. Apache-2.0. This package changes no selected-result record and claims no new κ. Its local diff --git a/research/pr4633-contract-audit/TASK.json b/research/pr4633-contract-audit/TASK.json index dd0fe0b28e..752cdf1422 100644 --- a/research/pr4633-contract-audit/TASK.json +++ b/research/pr4633-contract-audit/TASK.json @@ -70,8 +70,8 @@ ] }, "scope_status": "changed", - "actual_scope": "User-assigned audit of PR4633 physical main-port contracts and bounded repairs at exact head b390d64a.", - "scope_change_reason": "Explicit user task overrides the historical supplier-boundary card assignment.", + "actual_scope": "User-assigned PR4633 review, published after overlap refresh as complementary exact endpoint-preserving repair bounds alongside PR4636 and PR4642.", + "scope_change_reason": "Explicit user assignment; publication narrowed after finding PR4636 already covers the broader negative audit.", "bottleneck_link": "Reject a supplier screen that does not implement its invoiced local operator; do not promote it to a new outer kappa.", "budget_minutes": 60, "stop_rule": "Reproduce artifacts, independently test physical endpoint contracts, and finish two bounded endpoint-preserving repair checks.", From 5db0c0a056f4dce2ee4d38d0ee76499a38a074ba Mon Sep 17 00:00:00 2001 From: Cinna Davis <1337isnot1337@users.noreply.github.com> Date: Thu, 22 Oct 2026 09:12:41 -0500 Subject: [PATCH 3/3] Clarify that global padding obstruction applies to the BIT builder --- research/pr4633-contract-audit/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/research/pr4633-contract-audit/README.md b/research/pr4633-contract-audit/README.md index 2e11f8cda0..7356320f8d 100644 --- a/research/pr4633-contract-audit/README.md +++ b/research/pr4633-contract-audit/README.md @@ -63,13 +63,13 @@ For complex kernel 153, 56 ports have widths (7,7) and a surviving central complement; the other 56 have widths (7,8) and X entrance contained in Y final. Neither type is the block-8 call priced by the invoice. -There is a general obstruction for the submitted global full-image padding. +There is a general obstruction for the BIT builder's global full-image padding. Let h be the original ambient dimension and K a nonzero k-dimensional kernel. For a source hyperplane H, dim(phi(H)) is h-k or h-k-1. In the former case the image is the full quotient and the builder re-pads it to dimension h. In the latter case it remains dimension h-k-1 <= h-2. Thus **no Y terminal can have the required dimension h-1**, for any nonzero kernel in this construction. This -rules out repairing the existing priced contract by searching more kernels. +rules out repairing the existing priced BIT contract by searching more kernels. It does not rule out a new controller with different operator contracts. The correct BIT rank-mass decomposition is: