diff --git a/.github/workflows/p112-common-slice.yml b/.github/workflows/p112-common-slice.yml index 37f99ca573..48047f61c4 100644 --- a/.github/workflows/p112-common-slice.yml +++ b/.github/workflows/p112-common-slice.yml @@ -15,9 +15,9 @@ jobs: if: github.repository == 'CrocSwap/integer-mult-bounds' runs-on: ubuntu-24.04 timeout-minutes: 20 - env: - TMPDIR: ${{ runner.temp }}/p112-common-slice steps: + - name: Initialise P112 work directory + run: echo "TMPDIR=$RUNNER_TEMP/p112-common-slice" >> "$GITHUB_ENV" - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 with: fetch-depth: 0 diff --git a/research/p104-role-exchange-residue/PROOF.md b/research/p104-role-exchange-residue/PROOF.md new file mode 100644 index 0000000000..3bac5b4b2e --- /dev/null +++ b/research/p104-role-exchange-residue/PROOF.md @@ -0,0 +1,69 @@ +# Exact boundary and sharp residual replacement bound + +## 1. Algebra and inherited channel + +Let D be `Z[i,1/2]`, the Gaussian dyadic ring. All identities below hold for arbitrary elements of a free D-module, hence coordinatewise on arbitrary finite arrays. No input target is zero, and no dirty helper is clean. Write x and y for the original 104 source and target fields. The retained channel has normalised boundary `(x,y,h) -> (x,v=y+A x,h)` for 72 independent dirty fields h. This boundary theorem and its native chart interpretation are inherited from PR1972/PR1991. + +The source extraction constructs the 120 unoriented doubled E8 root representatives in canonical sorted order and deletes the 16 retained F0/C vectors. The resulting matrix R satisfies `RR^t=104I`. Set `A=R^t R/8`. The eight chosen pivot columns J are an orthogonal frame, so `R_J^t R_J=8I` and `R_J R_J^t=8I`. With `B=R_J^t R_N/8`, direct multiplication gives + +``` +A = [[I, B], [B^t, B^t B]] +``` + +in J,N order. Thus `v_J=y_J+x_J+B x_N` and `v_N=y_N+B^t(x_J+B x_N)`. Every nonzero entry of B is a signed half. The finite verifier checks each entry and every identity used here. + +## 2. A source-consuming tail without a clean bank + +All source arrays finish in FULL. First lift every Y target from its existing eight-dimensional hyperplane to FULL. The following common-chart equations are then legal scalar operations on the available banks. + +For each unchanged nonpivot source, add its signed half to each incident pivot X and subtract that same signed half from the corresponding pivot Y. The two streams may be interleaved because no nonpivot source has yet been changed permanently. They give `X_J=q=x_J+B x_N` and `Y_J=w_J=x_J+y_J`. + +Next subtract `B^t q` from X_N and then add Y_N. This gives + +``` +X_N = x_N - B^t q + v_N = x_N+y_N = w_N. +``` + +Return X_N to the target hyperplanes indexed by N and Y_J to those indexed by J. The residual banks X_J and Y_N remain in FULL. This is an explicit output-role assignment, not a claim that data movement or arbitrary caller relabelling is free. The 72 inherited dirty-helper banks are never targeted or read by this tail. Their inherited logical restoration is therefore preserved. + +The literal scalar schedule halves each X_N once, applies all of its incident unit additions and subtractions, and doubles it before proceeding. It then halves each pivot q once, applies its incident scatter subtractions, and doubles it. Finally it performs 96 direct X_N += Y_N additions. This uses 1,248 unit Gaussian ADDs, 104 halves, and 104 doubles. Every arithmetic source and target is in FULL. The 104 initial lifts and 104 final descents are rank-one pairs, for 208 formal native occurrences. They require their usual paid native implementation, not free frame relabelling. + +The inverse boundary is explicit. From `(w,q,v_N)`, compute `x_N=w_N-v_N+B^t q`, then `x_J=q-B x_N`, and finally `y=w-x`. These are D-linear equations. Their existence proves an invertible encoding, but not the cost or legal availability of a physical downstream decoder. + +The statement does not preserve the original source bank. In particular, Y_N still contains the original channel-produced v_N, whereas the eight would-be residual values v_J are replaced by q. Requiring the original source outputs again changes the contract and demands a priced continuation. + +## 3. Why every old residual cannot be retained + +Consider the tempting alternative boundary that returns all corrected sums w and all old residuals v, with arbitrary dirty helpers restored and no other persistent source-dependent output. Its data matrix is + +``` +T = [[I,I], [A,I]]. +``` + +The previously known covariance identity implies `A^2=13A`, with A of rational rank eight. Hence `C=I-A` has eigenvalues 1 with multiplicity 96 and -12 with multiplicity eight, and `det(T)=det(C)=12^8`. This determinant was already implicit in the predecessor correction certificate; the new use is its odd-prime obstruction to this changed return contract. + +Reduce D modulo 3. The quotient is the field F9 because `z^2+1` is irreducible over F3 and 2 remains invertible. The matrix R has rank eight modulo 3 since `RR^t=104I=2I`. Therefore A is an idempotent of rank eight, C has rank 96, and T has rank 200 rather than 208. The primary checker separately eliminates both C and T modulo 3. Since all entries of these particular matrices are rational dyadics, their rank over F3 equals their rank after scalar extension to F9. + +A reversible D-linear circuit must remain invertible modulo 3. This includes arbitrary invertible D-linear recoding, exact dyadic scaling, phase multiplication, and invertible dyadic native chart changes. Appending any number of arbitrary dirty inputs and returning them unchanged only adds an identity block, so it cannot repair T's eight-dimensional defect. Clean temporary banks that are returned to zero likewise do not provide a final source-dependent observation. + +Now keep every w output but permit replacing k of the old v outputs by arbitrary D-linear outputs. Modulo 3, replacing k scalar rows increases rank by at most k. Reversibility therefore requires `200+k >= 208`, or `k >= 8`. Our boundary replaces exactly the eight v_J outputs and has the explicit D-linear inverse in section 2. Eight is thus the exact minimum in this residual-row replacement model. + +For arrays with d Gaussian coordinates, the naive defect has dimension 8d. Replacing k whole arrays contributes at most kd scalar rows even when arbitrary cross-coordinate D-linear mixing is allowed, so the whole-array minimum remains eight. This is a count of changed residual outputs, not a transport-rank, lifetime, storage-width, or recursive-cost lower bound. + +A related necessary statement holds when all v outputs are retained and extra persistent clean-carrier output coordinates are allowed. They must supply at least 8d independent residues modulo 3. This does not establish a physical attaining carrier scheme or allow an arbitrary dirty bank to be treated as clean. + +## 4. Scope controls + +The ordinary source-preserving correction shear `[[I,0],[C,I]]` is invertible over D for every C. The verifier checks its full rank modulo 3 as a positive scope control. Thus the argument is not an impossibility theorem for correcting P104. + +The lower bound also does not cover division by an odd Gaussian prime, nonlinear rounding/residue encoders, nonzero private erasure, extra persistent source-dependent outputs, restricted correlated input domains, or a consumer that requires fewer sums or a different residual contract. Those are separate hypotheses and have their own implementation and price obligations. In particular, the ideal dyadic argument does not silently validate the literal signed-floor execution on arbitrary integer arrays. + +The fixed-cover support and source-preconditioner models preserve different data contracts. Reading and modifying channel Y, consuming X, and replacing residual outputs are explicit changes here. The result neither repeats the 208-flag static cover nor refutes the 23-dimensional preconditioner obstruction reported in PR3810. + +## 5. Exact evidence and budget boundary + +The primary implementation replays every new scalar instruction on 280 independent columns, including all original dirty variables. It verifies every sum, every residual, every helper, and every final frame dimension. Its separate inverse calculation uses the boundary equations rather than reversing the instruction list. The second implementation rebuilds the root geometry by a different enumeration and evaluates the endpoint in quarter-integer coefficients with a block ordering distinct from the primary schedule. It compares the full 280 by 280 endpoint digest. + +With normalised integer x,y inputs, every scalar prefix coefficient is a multiple of one quarter. A quarter is actually attained, so two fractional bits are sharp for this scalar instruction list. The maximum row one-norm is 26, including the channel-exit input rows; this bounds each real component by 26H when every original component is at most H. Neither statement includes the native frame-conversion arithmetic or proves that an outer physical producer supplies these normalised integer inputs. + +The formal added native profile is 208 H1. The retained profile therefore becomes `(1282,58,86,104,48,24,8,8)` and has mass 2576. Under the unchanged width-nine, 280-role bare mass relaxation, `2576/(9*280)=46/45>1` already fails. This is the predecessor terminal-tariff stop applied to the same numeric profile, not a lower bound for all changed consumer laws. Owner routing, a physical residual consumer or decoder, literal native admission, precision, tape, and complete all-size hosting remain unresolved. Their costs are unknown, not zero. diff --git a/research/p104-role-exchange-residue/README.md b/research/p104-role-exchange-residue/README.md new file mode 100644 index 0000000000..432e946398 --- /dev/null +++ b/research/p104-role-exchange-residue/README.md @@ -0,0 +1,84 @@ +# P104 source-consuming role exchange with eight residual replacements + +This is a changed terminal consumer contract, not another fixed-cover census and not an admitted multiplication supplier. It starts after the retained PR1972/PR1991 forward channel, consumes its source bank, and produces every corrected sum `w = x+y`. It returns an explicit invertible encoding of the remaining data instead of pretending that the original source bank is restored. + +The new result has two parts. An exact chronological tail returns `(w,q,v_N)` without adding a clean bank or touching the 72 original dirty helpers. A modulo-three argument proves that replacing at least eight of the naive 104 residual outputs is necessary in the specified reversible dyadic-linear model, even when arbitrary dyadic recoding and native chart changes are granted. Our tail replaces exactly eight. The corrected sums are not left in the original Y bank locations. + +Canonical base is `20ecf2891d80b5acf18d980b2164fb44ea7faa90`, priority revision 6. The selected conditional kappa remains `0.001672660197076918`. Only this opt-in package is added. `TASK.json` records the explicit user assignment and changed scope. + +## The exact boundary + +Write `A=G/2=R^t R/8`, where R is the retained 8 by 104 doubled-root matrix. The predecessor channel leaves X holding x in FULL, Y holding `v=y+A x` in each target hyperplane, and its 72 arbitrary dirty helpers logically restored in FULL. Its native channel identity is inherited, not re-proved by this package. + +Choose the eight mutually orthogonal retained roots `2(e0 +/- e2)`, `2(e1 +/- e3)`, `2(e4 +/- e6)`, and `2(e5 +/- e7)`. In canonical port order their indices are + +``` +J = [0, 1, 3, 6, 22, 31, 93, 103]. +``` + +Let N be the other 96 indices and `B=A[J,N]`. All 384 nonzero B entries are signed halves. The pivot block is `A[J,J]=I`, and `A[N,N]=B^t B`. + +Lift all 104 Y arrays to FULL. While every X_N source is still unchanged, perform both `X_J += B X_N` and `Y_J -= B X_N`. Thus X_J becomes `q=x_J+B x_N`, and Y_J already equals `w_J`. Then perform `X_N -= B^t X_J` and `X_N += Y_N`, producing `w_N`. Return X_N and Y_J to their respective target hyperplanes. Leave X_J and Y_N in FULL. + +The final corrected-sum locations are X_N and Y_J. The residual locations are X_J for q and Y_N for v_N. All original dirty helper locations are untouched by the tail. Logical restoration at a changed frame is not a claim that the original physical input array is bitwise unchanged. + +The inverse boundary equations are + +``` +x_N = w_N - v_N + B^t q, +x_J = q - B x_N, +y = w - x. +``` + +They use only dyadic coefficients. They prove information preservation, not a free decoder or a caller that already accepts this representation. PROOF.md proves the identity, the modulo-three lower bound, and its precise exclusions. + +## Invoice and stopping decision + +The generated tail contains 1,664 formal events. These comprise 1,248 unit Gaussian array additions/subtractions, 104 exact array halvings, 104 restoring doublings, and 208 rank-one frame conversions. There are no new banks, private erasures, or clean-input assumptions. No source-independent dirty helper is substituted for a data pivot. + +Under the inherited native dimension-gap tariff, the added profile is `208 H1`. Adding it to the retained channel gives `(1282,58,86,104,48,24,8,8)` at ranks 1 through 8, with total rank mass 2,576. These are formal frame conversions of the same hyperplane/FULL pairs already considered by the predecessor terminal audit. We have not recompiled their native recipes or executed their signed-floor implementations under the changed bank roles. + +For 512 complex words per array, the scalar part alone has 1,277,952 real additions/subtractions, 106,496 real halvings, and 106,496 real doublings. These counts exclude native-pair arithmetic, addressing, movement, and control. In normalised common-chart coordinates, integer initial x and y require at most two fractional bits during the scalar tail, with a sharp coefficient denominator of four. The maximum row one-norm, including the channel-exit entrance, is exactly 26, giving a `26H` bound per real component. This does not certify the physical native entrance, the original channel's internal width, or accumulated rounding error. + +Even granting the unchanged width-nine, 280-role bare local-mass relaxation, this profile has `M(0)=2576/(9*280)=46/45>1`. That numerical stop is inherited from the earlier 208-rank terminal-correction tariff, not a new general P104 lower bound. The changed logical boundary supplies no additional capacity or coverage by itself. A different consumer needs its own law and complete bill. + +The decision is **NARROW**. Retain the exact changed-boundary module and the sharp eight-replacement result. Do not expand it into a supplier construction under the unchanged failed budget. + +## Reproduction and evidence boundaries + +From a complete checkout at the contribution head, use Python 3.12 and the standard library. + +```sh +python3.12 -I -B scripts/research_package.py --package research/p104-role-exchange-residue +``` + +The default primary command authenticates all three frozen source files, compares the 16-root extraction, and binds every original X, Y, and dirty-helper exit frame. It then checks all 280 independent input columns through the newly generated tail. The second implementation imports no primary code and reconstructs the complete endpoint using quarter-integer arithmetic and a different root enumeration. It also checks 16 signed fixtures. Tests distinguish the new output locations, arbitrary dirty inputs, the ordinary source-preserving correction shear, and malformed or altered receipts. + +A portable algebra-only mode is deliberately weaker. + +```sh +python3 -I -B research/p104-role-exchange-residue/verify.py --algebra-only +python3 -I -O -B research/p104-role-exchange-residue/verify.py --algebra-only +python3 -I -B research/p104-role-exchange-residue/independent.py --algebra-only +python3 -I -O -B research/p104-role-exchange-residue/test_verify.py +``` + +This mode uses the explicitly transcribed geometry and prints `ALGEBRA_ONLY`. It does not authenticate the complete repository sources. Normal mode fails closed when those files are missing. Frozen RESULT.json is compared without rewriting it. The canonical result digest is `0b869d0e68b8e21468a15977a31432d8b17f5a528558edec7eaf6c5461d63b78`. + +Local algebra replays passed on CPython 3.13.5. Full source-bound and registered Python 3.12 results, where subsequently observed, belong in the PR handoff with their exact public head and run identifier. No native recipe replay, original 4,058-event channel replay, full selected cold replay, independent human review, or formal proof-kernel acceptance is claimed here. + +## Relationship to predecessor work + +Rohan Arun's PR1972 and Chafik Boukhalfa's PR1991 supply the forward channel and native lineage. The retained `p104-side-correction-rank-obstruction` package already proves the rational correction rank and determinant, the root-coordinate factorisation, and the 208-rank terminal screen. Its 2,376-add common-chart word and 1,352-add snapshot word are not new contributions here. The covariance identity `RR^t=104I`, ordinary Gaussian elimination, and modular rank arguments are likewise not claimed as new mathematics. + +PR2383 already grants the complete root code for free under its monotone immutable-source contract. PR3427 and Sagar Thakrar's PR3810 address changed source preconditioning and fixed-cover support; the latter's channel-Y-read probe motivates testing coefficients and dirty-state semantics rather than interpreting support as a circuit. Their bounds do not transfer to a source-consuming changed output interface. Our eight-replacement result does not contradict PR3810's rank-23 preconditioner bound. + +Clear1nsight's PR3609 uses eight in-place data pivots for a different dual-entrance completion. That pivot technique is related, not a newly discovered general technique here. The present object is the original forward 104-source/104-target terminal channel, with a different returned-source contract and a sharp modular obstruction to leaving every old channel-Y residual intact. PR3620 and the later caller audit reinforce the need to price the actual changed consumer rather than donate a boundary conversion. + +Prepared by Clear1nsight with substantial OpenAI assistance. The two checking implementations share the same assisted session and sources. New work is Apache-2.0; source geometry and predecessor results retain their authorship and notices. See SOURCES.json for immutable source bindings and bounded overlap coverage. + +## Open next questions + +A useful continuation must name an actual consumer of `(w,q,v_N)` and prove its input/output intertwiner, ownership, return, and complete coverage law. Its first test is the full budget, because the unchanged width-nine relaxation already fails. Original-source decoding, residual erasure, and physical bank relabelling are not free operations. + +Only after that gate passes should the 208 hyperplane/FULL recipes be rebound to the new bank roles and replayed with an actually supplied physical entrance. The scalar two-bit result alone does not establish exact native halves, finite-width safety, routing, tape use, or all-size admission. TASK.json records these concrete blockers without reserving them. diff --git a/research/p104-role-exchange-residue/RESULT.json b/research/p104-role-exchange-residue/RESULT.json new file mode 100644 index 0000000000..aea655ec6c --- /dev/null +++ b/research/p104-role-exchange-residue/RESULT.json @@ -0,0 +1,32 @@ +{ + "schema_version": 1, + "base_commit": "20ecf2891d80b5acf18d980b2164fb44ea7faa90", + "scope": "changed source-consuming boundary; no supplier or kappa", + "ports": 104, + "pivots": [0, 1, 3, 6, 22, 31, 93, 103], + "nonpivots": [2, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 94, 95, 96, 97, 98, 99, 100, 101, 102], + "root_nonzeros": 568, + "B_nonzeros": 384, + "program_sha256": "d39c433ecd7b50828a0b1f957e8f212bc40cd54af7e3f0ed82c90eee65dbf7fb", + "endpoint_sha256": "6c0b0574f2eaa6b91d260206958eb87136e5c722f26b5f4d7627ed9d65983bcd", + "operation_counts": {"add": 1248, "double": 104, "drop": 104, "half": 104, "lift": 104}, + "total_tail_events": 1664, + "tail_native_profile": {"1": 208}, + "inherited_channel_mass": 2368, + "combined_mass": 2576, + "combined_native_profile": [1282, 58, 86, 104, 48, 24, 8, 8], + "scalar_real_adds_at_512_complex_words": 1277952, + "scalar_real_halves_at_512_complex_words": 106496, + "scalar_real_doubles_at_512_complex_words": 106496, + "maximum_scalar_coefficient_denominator": 4, + "maximum_scalar_row_l1": "26", + "sum_outputs": 104, + "dirty_helpers_restored": 72, + "rank_C_mod3": 96, + "rank_naive_mod3": 200, + "rank_repaired_mod3": 208, + "minimum_replaced_residual_arrays_in_stated_linear_model": 8, + "det_naive": "429981696", + "native_lowering_replayed": false, + "complete_consumer_admitted": false +} diff --git a/research/p104-role-exchange-residue/SOURCES.json b/research/p104-role-exchange-residue/SOURCES.json new file mode 100644 index 0000000000..b17d3f350f --- /dev/null +++ b/research/p104-role-exchange-residue/SOURCES.json @@ -0,0 +1,49 @@ +{ + "schema_version": 1, + "base_commit": "20ecf2891d80b5acf18d980b2164fb44ea7faa90", + "files": [ + { + "path": "docs/research/agent-task-catalog.json", + "usage": "provenance", + "git_blob": "67f085acd86acd7d4e03922d9cf4b26bca66fed5", + "sha256": "47b42433f5a85809a3aadd29c2c339da2c6ed728e4f7762df6b88bccb7874cf0" + }, + { + "path": "certificates/selected-result.json", + "usage": "provenance", + "git_blob": "b1fea0c94436b236cc2b7d41a7be032811b94c81", + "sha256": "bb2eaa58647b353f88d0aec2eafb9d30df1be53589231b23e12ceef3e4bad129" + }, + { + "path": "research/p104-native-channel/inputs/P104-FIXTURE.json", + "usage": "input", + "git_blob": "2e16f99b295bb386fd13bd8fbd57b42ef54143a9", + "sha256": "516c06f6ec3cb84be588c546108de897650288576dd5fbf5fe44b9c5546ad8a4" + }, + { + "path": "research/p104-native-channel/inputs/LOWRANK-WITNESS.json", + "usage": "input", + "git_blob": "86beaf424e9f0f800ae3a62797d94ec9386b7706", + "sha256": "0f541bef7f19fdeffd67157684e9f03d785f42c89973632f508fc1a0452b580e" + }, + { + "path": "research/p104-native-channel/PROOF.md", + "usage": "input", + "git_blob": "a69311b74f74a2f8e8f411c1451baacd9bacddce", + "sha256": "5d743145d389ffdfaffc66096fa7e32c7155b18f73d74755403151d0435bb94c" + } + ], + "overlap": { + "closest": [ + "PR1972 / PR1991 native forward channel", + "research/p104-side-correction-rank-obstruction", + "PR2383 private root-code relay floor", + "PR3427 source preconditioning", + "PR3609 in-place dual entrance", + "PR3620 changed dual caller screen", + "PR3810 fixed-cover audit and channel-Y-read support probe" + ], + "checked": "Canonical main, priorities, family status, task card, selected record, P104 support and lifetime maps; targeted open/all PR searches and visible Discussions 1163, 1166, 2245. A 19 October updated-P104 query returned no further matching open PRs.", + "limits": "Not exhaustive Discussion pagination, all historical diffs, or unpublished work. Container DNS prevented a canonical Git fetch; GitHub branch API reads pinned the source. No claim of global novelty or a completed find_overlap.py run." + } +} diff --git a/research/p104-role-exchange-residue/TASK.json b/research/p104-role-exchange-residue/TASK.json new file mode 100644 index 0000000000..43b86d01ce --- /dev/null +++ b/research/p104-role-exchange-residue/TASK.json @@ -0,0 +1,109 @@ +{ + "schema_version": 1, + "task_id": "p104-side-correction", + "priority_revision": 6, + "base_commit": "20ecf2891d80b5acf18d980b2164fb44ea7faa90", + "original_card": { + "id": "p104-side-correction", + "question": "Can the proposed P104 joint endpoint flags be realized by a chronological correction program with coefficients, dirty restoration and an affordable complete bill?", + "starting_points": [ + "docs/research/research-family-status.md", + "research/p104-native-channel/README.md", + "research/p104-native-channel/PROOF.md", + "docs/research/community-efficient1000-review.md", + "research/p104-joint-unit-flags/README.md" + ], + "methods": [ + "Construct one side-correction word at an explicit chronological cut with the needed frames still available.", + "Derive a lower bound on the side correction and hosting costs that decides whether this channel can beat the selected budget." + ], + "acceptance_gate": "An exact arbitrary-input identity, source/target frame availability and restoration at the chosen cut, plus the complete channel+correction+idle/hosting bill or an explicit favorable bound. The native channel alone is not a supplier. A scoped local result may be retained without a complete supplier. Expanding it into further construction rounds requires the family-level budget and obligation gate in research-family-status.md; an optimistic passing relaxation alone is not acceptance.", + "first_step": { + "command": [ + "python3", + "-B", + "scripts/research_baseline.py" + ], + "expected": "PASS_RESEARCH_BASELINE_BINDINGS_ONLY", + "inspect": "Read the revision-6 family record and #2981 static joint flags, alongside the reviewed #1991 channel. #2981 is an author-checked source archive, not an independently validated executable correction or a refutation of program-level lifetime floors.", + "scope": "Source-bound orientation only. Read the named package and review before relying on its local evidence; this command is not its replay or supplier admission." + }, + "first_experiment": "After checking live handoffs, pin one named collection from #2981 and attach acquisition/delivery times, source dependencies and coefficient requirements. Test legal access and arbitrary dirty restoration; price any completion against the full channel/endpoint/hosting allowance. Stop with the exact missing implication or a scoped counterexample rather than expanding the static cover census.", + "bottleneck_link": "Completing an already realized changed channel tests a concrete construction opportunity, instead of refining the incumbent packing. A positive local result still needs global and all-size admission.", + "allowed_variations": [ + "One correction factorization, one chronological cut, or one explicit hosting obstruction.", + "A changed correction schedule with an updated full bill and native frame contract." + ], + "scope_change_triggers": [ + "Recompiling the already certified low-rank channel without closing a new obligation.", + "Treating a pending ancestor, local histogram or unpriced side correction as an admitted global supplier.", + "Repeating a correction or physical conversion already supplied by a pending follow-up without adding independent coverage or a different unresolved obligation.", + "Repeating the 208-flag static matching or calling a static nested cover a chronological correction program. Independent audit of that certificate is distinct and remains useful." + ], + "overlap_terms": [ + "P104", + "I-G/2", + "side correction", + "native channel", + "1972", + "1991", + "2586", + "endpoint transport", + "physical dual", + "relay composition", + "2981", + "joint unit flags", + "acquisition delivery", + "static nesting" + ], + "existing_checks": [ + { + "scope": "PR #2981 reports static joint endpoint flags and a matching of 208 departure and arrival flags; archival intake is not independent verification.", + "evidence": "research/p104-joint-unit-flags/README.md", + "remaining": "Independent flag check and a chronological coefficient program with dirty restoration and a complete cost.", + "status": "author-checked", + "source_commit": "3d24b92d8ba057b57cb2d480170ec407520e6882", + "selected_record_sha256": "bb2eaa58647b353f88d0aec2eafb9d30df1be53589231b23e12ceef3e4bad129" + } + ] + }, + "scope_status": "changed", + "actual_scope": "Source-consuming terminal P104 role exchange with eight replaced residual outputs, an exact arbitrary-input dyadic tail, and a sharp modulo-three lower bound on residual replacements under reversible dyadic-linear execution.", + "scope_change_reason": "User explicitly assigned a genuinely different source or consumer contract. This candidate changes immutable sources, unread targets, and the returned-source boundary, rather than rerunning the static fixed-cover support census or preconditioning the same required source bank.", + "bottleneck_link": "It converts channel-produced Y content into all 104 corrected sums with explicit source consumption and an exact minimal residual-interface change. The unchanged 280-role width-nine mass screen fails, so the result is a local contract, not a supplier.", + "budget_minutes": 60, + "selection": "Explicit user assignment; no random task reroll. Canonical Discussion posting is unsupported by the available connector; overlap was read and the focused PR is the handoff.", + "stop_rule": "Retain this bounded exact interface and its obstruction. Do not expand into native or outer supplier construction without a named consumer, full coverage/ownership law, and a favourable complete bill. Do not treat unpriced obligations as zero.", + "outcome": "partial", + "evidence": "RESULT.json; exact 280-column Fraction execution; separate quarter-integer reconstruction; modulo-three ranks 96, 200, and 208; explicit dyadic inverse; behavioural controls; normal and optimised algebra replays. Full source authentication is a distinct default-mode gate, and native lowering is not replayed.", + "author": "Clear1nsight", + "ai_assistance": "Substantial OpenAI assistance in derivation, implementation, testing, and documentation. The two implementations share the same assisted session; no independent human or formal proof-kernel review is claimed.", + "open_questions": [ + { + "question": "Can a named downstream caller consume (w,q,v_N) directly and provide a changed complete coverage law that passes its budget?", + "why_it_matters": "The original source bank is not returned. The local 280-role width-nine screen still fails at 46/45, so scalar savings alone cannot reopen supplier construction.", + "first_step": "Specify the exact linear input/output intertwiner and physical owners for one consumer, including all uses of the encoded residual. Price its complete local, idle, restoration, routing, and precision costs before native expansion.", + "blocked_by": "No actual outer consumer or favourable fully charged replacement law has been supplied." + }, + { + "question": "Does the literal signed-floor implementation of this tail satisfy a physically supplied entrance and its full frame schedule?", + "why_it_matters": "Exact dyadic coefficients and formal rank-one frame conversions do not prove rounding, fixed-width, or native recipe admission.", + "first_step": "Only after a passing consumer gate, bind the 208 existing hyperplane/FULL recipes to the new bank roles and prove divisibility at every scalar and native prefix.", + "blocked_by": "The two-bit and 26H certificates concern the normalised scalar stage only; native recipe replay, physical entrance, and caller widths remain separate." + } + ], + "checkpoints": [ + { + "round": "orientation", + "canonical_main": "20ecf2891d80b5acf18d980b2164fb44ea7faa90", + "priority_revision": 6, + "selected_record_sha256": "bb2eaa58647b353f88d0aec2eafb9d30df1be53589231b23e12ceef3e4bad129" + }, + { + "round": "changed-contract gate", + "canonical_main": "20ecf2891d80b5acf18d980b2164fb44ea7faa90", + "utc": "2026-10-19T01:49:00Z", + "decision": "NARROW; preserve the exact tail and modulo-three result, stop supplier expansion on the failed fixed-width screen." + } + ] +} diff --git a/research/p104-role-exchange-residue/VERIFY.json b/research/p104-role-exchange-residue/VERIFY.json new file mode 100644 index 0000000000..5ab1f99ff6 --- /dev/null +++ b/research/p104-role-exchange-residue/VERIFY.json @@ -0,0 +1,57 @@ +{ + "schema_version": 1, + "status": "ready", + "python": "3.12", + "requirements": [], + "inputs": [ + "research/p104-native-channel/inputs/P104-FIXTURE.json", + "research/p104-native-channel/inputs/LOWRANK-WITNESS.json", + "research/p104-native-channel/PROOF.md", + "research/p104-role-exchange-residue/geometry.json", + "research/p104-role-exchange-residue/RESULT.json" + ], + "commands": [ + { + "argv": [ + "{python}", + "-I", + "-B", + "{package}/verify.py" + ], + "timeout_seconds": 120, + "checks": "Exact source hashes and extraction; original exit-frame binding; complete new-tail coefficients, inverse, modulo-three ranks, typed frozen result, and formal invoice." + }, + { + "argv": [ + "{python}", + "-I", + "-O", + "-B", + "{package}/verify.py" + ], + "timeout_seconds": 120, + "checks": "Optimised source-bound replay; explicit failure checks remain active." + }, + { + "argv": [ + "{python}", + "-I", + "-B", + "{package}/independent.py" + ], + "timeout_seconds": 120, + "checks": "Independent integer-quarter geometry and all 280 by 280 endpoint coefficients, plus 16 signed fixtures; no primary implementation import." + }, + { + "argv": [ + "{python}", + "-I", + "-O", + "-B", + "{package}/test_verify.py" + ], + "timeout_seconds": 120, + "checks": "Word mutation, dirty-state, changed-output-bank, shear-scope, typed-result, JSON, and sharp scalar-grid controls." + } + ] +} diff --git a/research/p104-role-exchange-residue/geometry.json b/research/p104-role-exchange-residue/geometry.json new file mode 100644 index 0000000000..ba6d82f8a8 --- /dev/null +++ b/research/p104-role-exchange-residue/geometry.json @@ -0,0 +1,9 @@ +{ + "schema_version": 1, + "source_path": "research/p104-native-channel/inputs/P104-FIXTURE.json", + "source_commit": "20ecf2891d80b5acf18d980b2164fb44ea7faa90", + "source_sha256": "516c06f6ec3cb84be588c546108de897650288576dd5fbf5fe44b9c5546ad8a4", + "extraction": "section4_explicit_P104.F0 and section4_explicit_P104.C, in original order", + "F0": [[0,0,0,0,0,0,2,-2],[0,0,0,0,0,0,2,2],[0,0,0,0,2,-2,0,0],[0,0,0,0,2,2,0,0],[0,0,2,-2,0,0,0,0],[0,0,2,2,0,0,0,0],[2,-2,0,0,0,0,0,0],[2,2,0,0,0,0,0,0]], + "C": [[0,0,0,0,0,2,-2,0],[0,0,0,2,-2,0,0,0],[0,2,-2,0,0,0,0,0],[1,-1,-1,-1,-1,-1,-1,1],[1,-1,-1,1,1,1,1,1],[1,1,1,-1,-1,1,1,1],[1,1,1,1,1,-1,-1,1],[2,0,0,0,0,0,0,-2]] +} diff --git a/research/p104-role-exchange-residue/independent.py b/research/p104-role-exchange-residue/independent.py new file mode 100644 index 0000000000..a808c0cf1a --- /dev/null +++ b/research/p104-role-exchange-residue/independent.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 +"""Separate quarter-integer endpoint reconstruction, without importing verify.py. +Apache-2.0. This is a second implementation, not independent human review. +""" +from __future__ import annotations +import argparse +import hashlib +import itertools +import json +from pathlib import Path +from fractions import Fraction + +P = Path(__file__).resolve().parent + +def require(ok, message): + if not ok: + raise ValueError(message) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--algebra-only', action='store_true') + args = parser.parse_args() + extract = json.loads((P/'geometry.json').read_text()) + if not args.algebra_only: + raw = (P.parents[1]/extract['source_path']).read_bytes() + require(hashlib.sha256(raw).hexdigest() == extract['source_sha256'], 'source hash') + f = json.loads(raw)['section4_explicit_P104'] + require(f['F0'] == extract['F0'] and f['C'] == extract['C'], 'extraction') + roots = set() + for v in itertools.product((-2,0,2), repeat=8): + if sum(t != 0 for t in v) == 2: + first = next(t for t in v if t) + roots.add(tuple(t if first > 0 else -t for t in v)) + for v in itertools.product((-1,1), repeat=8): + if sum(t < 0 for t in v) % 2 == 0: + roots.add(tuple(t*v[0] for t in v)) + deleted = {tuple(v) for v in extract['F0']+extract['C']} + roots = sorted(roots-deleted) + require(len(roots) == 104, 'port count') + # Choose the frame by the supports, rather than constructing its vectors. + supports = {(0,2),(1,3),(4,6),(5,7)} + J = [i for i,r in enumerate(roots) if tuple(j for j,t in enumerate(r) if t) in supports] + N = [i for i in range(104) if i not in J] + require(len(J) == 8, 'pivot frame') + dot = [[sum(a*b for a,b in zip(r,s)) for s in roots] for r in roots] + require(all(dot[i][j] == 8*(i == j) for i in J for j in J), 'orthogonal pivots') + sign = [[dot[j][i]//4 for i in N] for j in J] + require(all(dot[j][i] in (-4,0,4) for j in J for i in N), 'coefficient alphabet') + # Every row stores four times its exact coefficient on 280 independent inputs. + rows = [[4*int(i == k) for k in range(280)] for i in range(280)] + for i in range(104): + require(all(v%2 == 0 for v in dot[i]), 'quarter grid at channel exit') + rows[104+i][:104] = [v//2 for v in dot[i]] + saved = [r[:] for r in rows] + # This reconstruction uses block ordering distinct from the primary word. + for b,j in enumerate(J): + for a,i in enumerate(N): + s = sign[b][a] + if s: + require(all(v%2 == 0 for v in saved[i]), 'source half') + inc = [s*(v//2) for v in saved[i]] + rows[j] = [x+y for x,y in zip(rows[j],inc)] + rows[104+j] = [x-y for x,y in zip(rows[104+j],inc)] + for a,i in enumerate(N): + rows[i] = [x+y for x,y in zip(saved[i],saved[104+i])] + for b,j in enumerate(J): + s = sign[b][a] + if s: + require(all(v%2 == 0 for v in rows[j]), 'query half') + rows[i] = [x-s*(y//2) for x,y in zip(rows[i],rows[j])] + for i in range(104): + t = 104+i if i in J else i + require(rows[t] == [4*int(k in (i,104+i)) for k in range(280)], 'sum row') + require(rows[208:] == saved[208:], 'arbitrary dirty restoration') + data = [[str(Fraction(v,4)) for v in row] for row in rows] + raw = (json.dumps(data, sort_keys=True, separators=(',',':'))+'\n').encode() + result = json.loads((P/'RESULT.json').read_text()) + require(hashlib.sha256(raw).hexdigest() == result['endpoint_sha256'], 'endpoint digest') + require(J == result['pivots'], 'pivot order') + # Check signed dense inputs through the independently obtained boundary. + for seed in range(16): + values = [((k+3)*(seed+11)*17 % 101)-50 for k in range(280)] + output = [sum(c*v for c,v in zip(row,values)) for row in rows] + for i in range(104): + t = 104+i if i in J else i + require(output[t] == 4*(values[i]+values[104+i]), 'signed fixture') + marker = 'ALGEBRA_ONLY' if args.algebra_only else 'SOURCE_BOUND' + print(f'PASS_P104_ROLE_EXCHANGE_INDEPENDENT_{marker} rows=280 columns=280 signed_fixtures=16') + +if __name__ == '__main__': + main() diff --git a/research/p104-role-exchange-residue/test_verify.py b/research/p104-role-exchange-residue/test_verify.py new file mode 100644 index 0000000000..fd7da6aa66 --- /dev/null +++ b/research/p104-role-exchange-residue/test_verify.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python3 +"""Mutation and contract controls for the new tail only. Apache-2.0.""" +from __future__ import annotations +import importlib.util +import json +import subprocess +import sys +import tempfile +from pathlib import Path + +P = Path(__file__).resolve().parent +spec = importlib.util.spec_from_file_location('role_exchange', P/'verify.py') +m = importlib.util.module_from_spec(spec) +spec.loader.exec_module(m) +R,A,J,N,B = m.geometry() +ops = m.program(J,N,B) + + +def reject(word): + try: + state,frames,_,_ = m.execute(A,word) + m.verify_endpoint(state,frames,A,J,N,B) + except ValueError: + return + raise ValueError('mutation accepted') + + +def main(): + cases = 0 + word = ops[:] + k = next(i for i,op in enumerate(word) if op[0] == 'add') + op = word[k] + word[k] = op[:-1]+(-op[-1],) + reject(word); cases += 1 + for kind in ('double','lift','drop'): + word = ops[:] + del word[next(i for i,op in enumerate(word) if op[0] == kind)] + reject(word); cases += 1 + # Omit the old-Y subtraction; roots alone must not substitute for dirty Y. + reject([op for op in ops if not(op[0]=='add' and op[1] in [104+j for j in J])]); cases += 1 + # Replacing the data pivot by an old arbitrary dirty helper is not free. + word = ops[:] + k = next(i for i,op in enumerate(word) if op[0] == 'add') + word[k] = ('add',208,word[k][2],word[k][3]) + reject(word); cases += 1 + state,frames,_,_ = m.execute(A,ops) + m.verify_endpoint(state,frames,A,J,N,B) + m.need(any(state[104+i] != [m.F(k in (i,104+i)) for k in range(280)] for i in N), + 'old bank names falsely accepted as corrected outputs'); cases += 1 + # The source-preserving correction is unimodular, despite rank(C mod 3)=96. + shear = [[m.F(i==j) for j in range(208)] for i in range(208)] + for i in range(104): + for j in range(104): + shear[104+i][j] = m.F(i==j)-A[i][j] + m.need(m.mod_rank(shear)==208, 'scope control: ordinary shear'); cases += 1 + result = m.calculate() + bad = dict(result); bad['schema_version'] = True + m.need(m.encoded(bad) != m.encoded(result), 'Boolean schema accepted'); cases += 1 + bad = dict(result); bad['tail_native_profile'] = {'1': 104} + m.need(m.encoded(bad) != m.encoded(result), 'half-price frame invoice accepted'); cases += 1 + # Authenticating the source is mandatory in normal mode, even without a checkout. + with tempfile.TemporaryDirectory() as d: + q = Path(d)/'duplicate.json'; q.write_text('{"schema_version":1,"schema_version":1}') + try: + m.load(q) + except ValueError: + pass + else: + raise ValueError('duplicate JSON key accepted') + cases += 1 + # A single original integer basis input attains denominator four transiently. + m.need(result['maximum_scalar_coefficient_denominator']==4, 'sharp scalar grid') + cases += 1 + # Actual isolated CLI rejection, including immutable bytes after failure. + with tempfile.TemporaryDirectory() as d: + q = Path(d) + (q/'verify.py').write_bytes((P/'verify.py').read_bytes()) + for label, replacement, expected in ( + ('boolean', dict(result, schema_version=True), 'typed result mismatch'), + ('invoice', dict(result, tail_native_profile={'1':104}), 'typed result mismatch'), + ): + (q/'RESULT.json').write_text(json.dumps(replacement)) + before = {f.name:f.read_bytes() for f in q.iterdir() if f.is_file()} + run = subprocess.run([sys.executable,'-I','-O','-B',str(q/'verify.py'),'--algebra-only'],capture_output=True,text=True) + m.need(run.returncode != 0 and expected in run.stderr and not run.stdout, 'CLI '+label) + m.need(before == {f.name:f.read_bytes() for f in q.iterdir() if f.is_file()}, 'CLI changed files') + cases += 1 + (q/'RESULT.json').write_text(json.dumps(result)) + run = subprocess.run([sys.executable,'-I','-B',str(q/'verify.py')],capture_output=True,text=True) + m.need(run.returncode != 0 and 'FileNotFoundError' in run.stderr and not run.stdout, 'missing source accepted') + cases += 1 + print(f'PASS_P104_ROLE_EXCHANGE_CONTROLS cases={cases} positive=1') + +if __name__ == '__main__': + main() diff --git a/research/p104-role-exchange-residue/verify.py b/research/p104-role-exchange-residue/verify.py new file mode 100644 index 0000000000..093e21df60 --- /dev/null +++ b/research/p104-role-exchange-residue/verify.py @@ -0,0 +1,291 @@ +#!/usr/bin/env python3 +"""Exact P104 changed-boundary experiment. Apache-2.0; see README for scope.""" +from __future__ import annotations + +import argparse +import hashlib +import itertools +import json +from collections import Counter +from fractions import Fraction as F +from pathlib import Path + +HERE = Path(__file__).resolve().parent +REPO = HERE.parents[1] +BASE = "20ecf2891d80b5acf18d980b2164fb44ea7faa90" +F0 = [[0,0,0,0,0,0,2,-2],[0,0,0,0,0,0,2,2], + [0,0,0,0,2,-2,0,0],[0,0,0,0,2,2,0,0], + [0,0,2,-2,0,0,0,0],[0,0,2,2,0,0,0,0], + [2,-2,0,0,0,0,0,0],[2,2,0,0,0,0,0,0]] +PUNCTURE_C = [[0,0,0,0,0,2,-2,0],[0,0,0,2,-2,0,0,0], + [0,2,-2,0,0,0,0,0],[1,-1,-1,-1,-1,-1,-1,1], + [1,-1,-1,1,1,1,1,1],[1,1,1,-1,-1,1,1,1], + [1,1,1,1,1,-1,-1,1],[2,0,0,0,0,0,0,-2]] +SOURCE_HASHES = { + "research/p104-native-channel/inputs/P104-FIXTURE.json": + "516c06f6ec3cb84be588c546108de897650288576dd5fbf5fe44b9c5546ad8a4", + "research/p104-native-channel/inputs/LOWRANK-WITNESS.json": + "0f541bef7f19fdeffd67157684e9f03d785f42c89973632f508fc1a0452b580e", + "research/p104-native-channel/PROOF.md": + "5d743145d389ffdfaffc66096fa7e32c7155b18f73d74755403151d0435bb94c", +} + + +def need(condition: bool, message: str) -> None: + if not condition: + raise ValueError(message) + + +def load(path: Path): + def unique(pairs): + out = {} + for key, value in pairs: + need(key not in out, f"duplicate JSON key: {key}") + out[key] = value + return out + return json.loads(path.read_text(), object_pairs_hook=unique) + + +def encoded(value) -> bytes: + return (json.dumps(value, sort_keys=True, separators=(",", ":")) + "\n").encode() + + +def digest(value) -> str: + return hashlib.sha256(encoded(value)).hexdigest() + + +def geometry(): + roots = set() + for i, j in itertools.combinations(range(8), 2): + for sign in (-1, 1): + row = [0] * 8 + row[i], row[j] = 2, 2 * sign + roots.add(tuple(row)) + for tail in itertools.product((-1, 1), repeat=7): + if sum(t < 0 for t in tail) % 2 == 0: + roots.add((1,) + tail) + removed = {tuple(r) for r in F0 + PUNCTURE_C} + need(len(roots) == 120 and len(removed) == 16 and removed <= roots, + "root universe or puncture changed") + ports = sorted(roots - removed) + R = list(map(list, zip(*ports))) + need(len(ports) == 104, "wrong port count") + for a in range(8): + for b in range(8): + need(sum(R[a][i] * R[b][i] for i in range(104)) == 104 * (a == b), + "RR^t is not 104 I") + J = [] + for a, b in ((0, 2), (1, 3), (4, 6), (5, 7)): + for sign in (-1, 1): + r = [0] * 8 + r[a], r[b] = 2, 2 * sign + J.append(ports.index(tuple(r))) + J.sort() + N = [i for i in range(104) if i not in J] + A = [[F(sum(x*y for x,y in zip(r,s)), 8) for s in ports] for r in ports] + need(all(A[i][j] == (i == j) for i in J for j in J), "J not orthogonal") + B = [[A[j][i] for i in N] for j in J] + need(all(v in (F(-1,2), 0, F(1,2)) for row in B for v in row), "B alphabet") + need(sum(v != 0 for row in B for v in row) == 384, "B support") + for a, i in enumerate(N): + for b, k in enumerate(N): + need(A[i][k] == sum(B[j][a] * B[j][b] for j in range(8)), + "A_NN != B^t B") + return R, A, J, N, B + + +def source_binding(J): + data = {} + for path, expected in SOURCE_HASHES.items(): + raw = (REPO / path).read_bytes() + need(hashlib.sha256(raw).hexdigest() == expected, f"source hash: {path}") + data[path] = raw + fixture = json.loads(data[next(iter(SOURCE_HASHES))]) + section = fixture["section4_explicit_P104"] + need(section["F0"] == F0 and section["C"] == PUNCTURE_C, "source extraction") + word = json.loads(data["research/p104-native-channel/inputs/LOWRANK-WITNESS.json"]) + full = [1 << i for i in range(9)] + final = word["final_frames"] + need(all(final[f"X{i}"] == full for i in range(104)), "source exit frame") + helpers = [f"Q{i}" for i in range(8)] + [f"G{i}" for i in range(32)] + [f"D{i}" for i in range(32)] + need(all(final[h] == full for h in helpers), "dirty helper exit frames") + need(all(len(final[f"Y{i}"]) == 8 and binary_rank(final[f"Y{i}"]) == 8 + for i in range(104)), "target exit hyperplane") + proof = data["research/p104-native-channel/PROOF.md"] + need(b"y_t + sum_s x_s/2" in proof, "inherited channel statement") + return {"bound_sources": len(data), "target_frame_digest": digest([final[f"Y{i}"] for i in range(104)]), + "pivot_input_frames": [word["initial_frames"][f"X{i}"] for i in J]} + + +def binary_rank(rows): + pivots = {} + for row in rows: + need(type(row) is int and 0 < row < 512, "invalid binary vector") + while row: + k = row.bit_length() - 1 + if k in pivots: + row ^= pivots[k] + else: + pivots[k] = row + break + return len(pivots) + + +def program(J, N, B): + ops = [("lift", 104+i) for i in range(104)] + for a, i in enumerate(N): + ops.append(("half", i)) + for b, j in enumerate(J): + if B[b][a]: + s = int(2 * B[b][a]) + ops.extend([("add", j, i, s), ("add", 104+j, i, -s)]) + ops.append(("double", i)) + for b, j in enumerate(J): + ops.append(("half", j)) + for a, i in enumerate(N): + if B[b][a]: + ops.append(("add", i, j, -int(2 * B[b][a]))) + ops.append(("double", j)) + ops.extend(("add", i, 104+i, 1) for i in N) + ops.extend(("drop", i) for i in N) + ops.extend(("drop", 104+j) for j in J) + return ops + + +def execute(A, ops): + # The 72 arbitrary dirty inputs are explicit independent columns, not zero. + state = [[F(i == j) for j in range(280)] for i in range(280)] + for i in range(104): + state[104+i][:104] = A[i][:] + frames = [9]*104 + [8]*104 + [9]*72 + max_denominator = max(x.denominator for row in state for x in row) + peak_row_norm = max(sum(abs(x) for x in row) for row in state) + for op in ops: + kind, target = op[:2] + need(type(target) is int and 0 <= target < 208, "helper mutation or bad register") + if kind == "lift": + need(frames[target] == 8, "lift source frame") + frames[target] = 9 + continue + if kind == "drop": + need(frames[target] == 9, "drop source frame") + frames[target] = 8 + continue + need(frames[target] == 9, "arithmetic target not FULL") + if kind == "add": + source, sign = op[2:] + need(source != target and 0 <= source < 208 and frames[source] == 9, + "arithmetic source or frame") + need(type(sign) is int and sign in (-1, 1), "ADD coefficient") + state[target] = [x + sign*y for x,y in zip(state[target], state[source])] + else: + need(kind in ("half", "double"), "unknown operation") + scalar = F(1, 2) if kind == "half" else F(2) + state[target] = [scalar*x for x in state[target]] + max_denominator = max(max_denominator, *(x.denominator for x in state[target])) + peak_row_norm = max(peak_row_norm, sum(abs(x) for x in state[target])) + return state, frames, max_denominator, peak_row_norm + + +def mod_rank(matrix, prime=3): + a = [[int(F(x).numerator * pow(F(x).denominator, -1, prime) % prime) + for x in row] for row in matrix] + rank = 0 + for col in range(len(a[0])): + pivot = next((i for i in range(rank, len(a)) if a[i][col]), None) + if pivot is None: + continue + a[rank], a[pivot] = a[pivot], a[rank] + inv = pow(a[rank][col], -1, prime) + a[rank] = [(v*inv) % prime for v in a[rank]] + for i in range(rank+1, len(a)): + c = a[i][col] + if c: + a[i] = [(x-c*y) % prime for x,y in zip(a[i], a[rank])] + rank += 1 + if rank == len(a): + break + return rank + + +def verify_endpoint(state, frames, A, J, N, B): + for i in range(104): + target = 104+i if i in J else i + expected = [F(k in (i,104+i)) for k in range(280)] + need(state[target] == expected and frames[target] == 8, f"sum endpoint {i}") + for b,j in enumerate(J): + expected = [F(k == j) for k in range(280)] + for a,i in enumerate(N): + expected[i] = B[b][a] + need(state[j] == expected and frames[j] == 9, f"q residual {j}") + for i in N: + expected = [F(k == 104+i) for k in range(280)] + expected[:104] = A[i][:] + need(state[104+i] == expected and frames[104+i] == 9, f"v residual {i}") + for i in range(208,280): + need(state[i] == [F(i == k) for k in range(280)] and frames[i] == 9, + f"dirty helper {i}") + + +def calculate(): + R,A,J,N,B = geometry() + ops = program(J,N,B) + state,frames,den,norm = execute(A,ops) + verify_endpoint(state,frames,A,J,N,B) + # Separate endpoint formula and explicit inverse, not the gate interpreter. + xs = [] + for a,i in enumerate(N): + w = state[i] + v = state[104+i] + xs.append([w[k]-v[k]+sum(B[b][a]*state[j][k] for b,j in enumerate(J)) + for k in range(280)]) + for a,i in enumerate(N): + need(xs[a] == [F(k == i) for k in range(280)], "inverse x_N") + for b,j in enumerate(J): + restored = [state[j][k]-sum(B[b][a]*xs[a][k] for a in range(96)) + for k in range(280)] + need(restored == [F(k == j) for k in range(280)], "inverse x_J") + C = [[F(i == j)-A[i][j] for j in range(104)] for i in range(104)] + naive = [[F(i == j) for j in range(104)]+[F(i == j) for j in range(104)] + for i in range(104)] + naive += [A[i][:]+[F(i == j) for j in range(104)] for i in range(104)] + need(mod_rank(C) == 96 and mod_rank(naive) == 200, "mod-three obstruction") + need(mod_rank([r[:208] for r in state[:208]]) == 208, "repaired rank") + need(mod_rank(R) == 8, "root rank modulo three") + counts = Counter(op[0] for op in ops) + need(counts == Counter(add=1248,half=104,double=104,lift=104,drop=104), "invoice") + need(den == 4, "two-bit transient bound") + return { + "schema_version": 1, "base_commit": BASE, "scope": "changed source-consuming boundary; no supplier or kappa", + "ports": 104, "pivots": J, "nonpivots": N, "root_nonzeros": sum(v != 0 for r in R for v in r), + "B_nonzeros": 384, "program_sha256": digest(ops), "endpoint_sha256": digest([[str(v) for v in r] for r in state]), + "operation_counts": dict(sorted(counts.items())), "total_tail_events": len(ops), + "tail_native_profile": {"1": 208}, "inherited_channel_mass": 2368, "combined_mass": 2576, + "combined_native_profile": [1282,58,86,104,48,24,8,8], + "scalar_real_adds_at_512_complex_words": 1248*1024, + "scalar_real_halves_at_512_complex_words": 104*1024, + "scalar_real_doubles_at_512_complex_words": 104*1024, + "maximum_scalar_coefficient_denominator": den, "maximum_scalar_row_l1": str(norm), + "sum_outputs": 104, "dirty_helpers_restored": 72, + "rank_C_mod3": 96, "rank_naive_mod3": 200, "rank_repaired_mod3": 208, + "minimum_replaced_residual_arrays_in_stated_linear_model": 8, + "det_naive": str(12**8), "native_lowering_replayed": False, "complete_consumer_admitted": False, + } + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--algebra-only", action="store_true", help="Do not claim full-repository source authentication.") + args = parser.parse_args() + result = calculate() + need(encoded(result) == encoded(load(HERE/"RESULT.json")), "typed result mismatch") + if args.algebra_only: + marker = "PASS_P104_ROLE_EXCHANGE_ALGEBRA_ONLY" + else: + print(json.dumps(source_binding(result["pivots"]), sort_keys=True)) + marker = "PASS_P104_ROLE_EXCHANGE_SOURCE_BOUND" + print(f"{marker} replaced=8 sums=104 dirt=72 tail_H1=208 result={digest(result)}") + + +if __name__ == "__main__": + main()