diff --git a/research/invoice-realpath-replay/EXPECTED.json b/research/invoice-realpath-replay/EXPECTED.json new file mode 100644 index 0000000000..3c7c36dd3c --- /dev/null +++ b/research/invoice-realpath-replay/EXPECTED.json @@ -0,0 +1,518 @@ +{ + "status": "PASS_INVOICE_MUTANT_COVERAGE", + "checked_mutants": 37, + "rejected": 31, + "accepted": 6, + "positive": { + "status": "PASS_POSITIVE_CONTROL_REPRODUCES_ARCHIVED_INVOICE", + "invoice_sha256": "212cf4ee3b16081bf66f300fa18b4070d25c17210c21c78c2967892c91870d12" + }, + "pins": { + "upstream1087": "d4acf04daef85d4514f80ec5fcd2492d0c60e5d6c49fa71b3e6523f8db2dea86", + "selected_replay": "f1da80610bf33c58527f18ad63b4350d0b864e1d4486141ee17ac9bed4d529d6", + "invoice_allcold_py": "71eb57514e28ced97251e0507105f654f59885ec4d40486a780bf166098858a8", + "retained_invoice": "ce1bfa49be88ae67a404f606a11db2232b7e1f2610d4418058e39749d86d8478" + }, + "records": [ + { + "name": "A1_raw_template_live", + "mutant_class": "A", + "verdict": "rejected", + "detail": "line 175: assert template_hash==control['complex_template_sha256']==owners['template_sha256']==summary['template_sha256'] | ", + "summary": null, + "downstream": null + }, + { + "name": "A2_raw_template_bank_padding", + "mutant_class": "A", + "verdict": "rejected", + "detail": "line 175: assert template_hash==control['complex_template_sha256']==owners['template_sha256']==summary['template_sha256'] | ", + "summary": null, + "downstream": null + }, + { + "name": "B1_template_live_plus1", + "mutant_class": "B", + "verdict": "rejected", + "detail": "line 253: assert m*live-mass==owners['deficit']==5120 | ", + "summary": null, + "downstream": null + }, + { + "name": "B2_template_live_physical_plus1", + "mutant_class": "B", + "verdict": "rejected", + "detail": "line 253: assert m*live-mass==owners['deficit']==5120 | ", + "summary": null, + "downstream": null + }, + { + "name": "B3_template_bank_padding_family", + "mutant_class": "B", + "verdict": "rejected", + "detail": "line 258: assert not template['bank_padding']['families'] | ", + "summary": null, + "downstream": null + }, + { + "name": "B4_template_drop_call", + "mutant_class": "B", + "verdict": "rejected", + "detail": "line 200: assert call_count==stages*replicas==control['complete_invocations'] | ", + "summary": null, + "downstream": null + }, + { + "name": "B5_template_wrong_sweep_provider", + "mutant_class": "B", + "verdict": "rejected", + "detail": "line 230: assert e['provider_id']==c['provider_id'] | ", + "summary": null, + "downstream": null + }, + { + "name": "B6_template_call_owner_changed", + "mutant_class": "B", + "verdict": "rejected", + "detail": "line 212: assert orientation==old['orientation'] and c['owners'][:2*v]==old['owners'][:2*v] | ", + "summary": null, + "downstream": null + }, + { + "name": "B7_template_call_orientation_changed", + "mutant_class": "B", + "verdict": "rejected", + "detail": "line 212: assert orientation==old['orientation'] and c['owners'][:2*v]==old['owners'][:2*v] | ", + "summary": null, + "downstream": null + }, + { + "name": "B8_template_recipe_changed", + "mutant_class": "B", + "verdict": "rejected", + "detail": "line 177: assert template['recipe']==parent['recipe'] | ", + "summary": null, + "downstream": null + }, + { + "name": "B9_template_call_program_hash", + "mutant_class": "B", + "verdict": "rejected", + "detail": "line 213: assert c['local_program_sha256']==p['program_hashes'][orientation] | ", + "summary": null, + "downstream": null + }, + { + "name": "B10_template_registry_checks_cleared", + "mutant_class": "B", + "verdict": "rejected", + "detail": "line 39: assert checks==registry['local_program_checks'] | ", + "summary": null, + "downstream": null + }, + { + "name": "B11_template_registry_v_changed", + "mutant_class": "B", + "verdict": "rejected", + "detail": "line 44: assert registry['v']==v and registry['R']==helpers and registry['h']==h | ", + "summary": null, + "downstream": null + }, + { + "name": "C1_owner_deficit_5119", + "mutant_class": "C", + "verdict": "rejected", + "detail": "line 253: assert m*live-mass==owners['deficit']==5120 | ", + "summary": null, + "downstream": null + }, + { + "name": "C2_owner_rank_mass_off_profile", + "mutant_class": "C", + "verdict": "rejected", + "detail": "line 253: assert m*live-mass==owners['deficit']==5120 | ", + "summary": null, + "downstream": null + }, + { + "name": "C3_owner_profile_halving_guard", + "mutant_class": "C", + "verdict": "rejected", + "detail": "line 284: assert all(inequalities.values()) | ", + "summary": null, + "downstream": null + }, + { + "name": "C3b_owner_profile_same_mass_same_max", + "mutant_class": "C", + "verdict": "accepted", + "detail": "", + "summary": { + "status": "PASS_INDEPENDENT_MIXED_ASYNC_SCALAR_PREFIX_AND_FINITE_INVOICE", + "provider_counts": { + "gauge44": 144 + }, + "selected_real_component_primitives": 28625376, + "selected_coefficient_work_primitive_count": 14162000, + "global_prefix_bits": 397, + "finite": { + "physical_stock_bits": 2642, + "router_bits": 7988, + "literal_bits": 35284, + "physical_row_coefficient": 16469, + "retained_row_coefficient": 20161, + "required_C0_bits": 200012, + "halving_integer_inequality": [ + 5329, + 4608 + ], + "G_exponent": 30000, + "E_exponent": 100000, + "C0_exponent": 210000 + }, + "strict_checks": { + "local_primitive_bound": true, + "logical": true, + "router": true, + "literal": true, + "mass": true, + "precision": true, + "tape": true, + "row": true, + "halving": true + } + }, + "downstream": "assemble_rejected: line 130: idle=Counter({int(r):n for r,n in owner['paid_profile'].items()});idle.subtract(paid);assert all(n>=0 for n in idle.values()) | " + }, + { + "name": "C4_owner_explicit_idle_remainders", + "mutant_class": "C", + "verdict": "accepted", + "detail": "", + "summary": { + "status": "PASS_INDEPENDENT_MIXED_ASYNC_SCALAR_PREFIX_AND_FINITE_INVOICE", + "provider_counts": { + "gauge44": 144 + }, + "selected_real_component_primitives": 28625376, + "selected_coefficient_work_primitive_count": 14162000, + "global_prefix_bits": 397, + "finite": { + "physical_stock_bits": 2642, + "router_bits": 7988, + "literal_bits": 35284, + "physical_row_coefficient": 16469, + "retained_row_coefficient": 20161, + "required_C0_bits": 200012, + "halving_integer_inequality": [ + 5329, + 4608 + ], + "G_exponent": 30000, + "E_exponent": 100000, + "C0_exponent": 210000 + }, + "strict_checks": { + "local_primitive_bound": true, + "logical": true, + "router": true, + "literal": true, + "mass": true, + "precision": true, + "tape": true, + "row": true, + "halving": true + } + }, + "downstream": "assemble_rejected: line 69: pin('expected.idle_remainders',owner['explicit_idle_remainder_children']) | SPEC MISMATCH expected.idle_remainders: expected 7526 got 7527" + }, + { + "name": "C5_owner_template_sha_raw", + "mutant_class": "C", + "verdict": "rejected", + "detail": "line 175: assert template_hash==control['complex_template_sha256']==owners['template_sha256']==summary['template_sha256'] | ", + "summary": null, + "downstream": null + }, + { + "name": "C6_owner_actual_73column_sigmas", + "mutant_class": "C", + "verdict": "accepted", + "detail": "", + "summary": { + "status": "PASS_INDEPENDENT_MIXED_ASYNC_SCALAR_PREFIX_AND_FINITE_INVOICE", + "provider_counts": { + "gauge44": 144 + }, + "selected_real_component_primitives": 28625376, + "selected_coefficient_work_primitive_count": 14162000, + "global_prefix_bits": 397, + "finite": { + "physical_stock_bits": 2642, + "router_bits": 7988, + "literal_bits": 35284, + "physical_row_coefficient": 16469, + "retained_row_coefficient": 20161, + "required_C0_bits": 200012, + "halving_integer_inequality": [ + 5329, + 4608 + ], + "G_exponent": 30000, + "E_exponent": 100000, + "C0_exponent": 210000 + }, + "strict_checks": { + "local_primitive_bound": true, + "logical": true, + "router": true, + "literal": true, + "mass": true, + "precision": true, + "tape": true, + "row": true, + "halving": true + } + }, + "downstream": "assemble_rejected: line 68: pin('expected.actual_73column_sigmas',owner['actual_73column_sigmas']);pin('expected.cross_replica_helper_roles',owner['cross_replica_helper_roles']) | SPEC MISMATCH expected.actual_73column_sigmas: expected 10002 got 1000" + }, + { + "name": "C7_owner_source_artifact_hash", + "mutant_class": "C", + "verdict": "rejected", + "detail": "line 190: assert owners['source_artifacts'][path]==p['artifacts'][name] | ", + "summary": null, + "downstream": null + }, + { + "name": "C8_control_complete_invocations", + "mutant_class": "C", + "verdict": "rejected", + "detail": "line 200: assert call_count==stages*replicas==control['complete_invocations'] | ", + "summary": null, + "downstream": null + }, + { + "name": "C9_control_one_owner_flag", + "mutant_class": "C", + "verdict": "rejected", + "detail": "line 201: assert control['one_owner_per_complete_invocation'] | ", + "summary": null, + "downstream": null + }, + { + "name": "C10_control_mutation_claims_cleared", + "mutant_class": "C", + "verdict": "accepted", + "detail": "", + "summary": { + "status": "PASS_INDEPENDENT_MIXED_ASYNC_SCALAR_PREFIX_AND_FINITE_INVOICE", + "provider_counts": { + "gauge44": 144 + }, + "selected_real_component_primitives": 28625376, + "selected_coefficient_work_primitive_count": 14162000, + "global_prefix_bits": 397, + "finite": { + "physical_stock_bits": 2642, + "router_bits": 7988, + "literal_bits": 35284, + "physical_row_coefficient": 16469, + "retained_row_coefficient": 20161, + "required_C0_bits": 200012, + "halving_integer_inequality": [ + 5329, + 4608 + ], + "G_exponent": 30000, + "E_exponent": 100000, + "C0_exponent": 210000 + }, + "strict_checks": { + "local_primitive_bound": true, + "logical": true, + "router": true, + "literal": true, + "mass": true, + "precision": true, + "tape": true, + "row": true, + "halving": true + } + }, + "downstream": "assemble_rejected: line 75: assert invoice['controller_audit_sha256']==owner['controller_audit_sha256'] | " + }, + { + "name": "C11_control_template_sha_raw", + "mutant_class": "C", + "verdict": "rejected", + "detail": "line 175: assert template_hash==control['complex_template_sha256']==owners['template_sha256']==summary['template_sha256'] | ", + "summary": null, + "downstream": null + }, + { + "name": "C12_summary_template_sha_raw", + "mutant_class": "C", + "verdict": "rejected", + "detail": "line 175: assert template_hash==control['complex_template_sha256']==owners['template_sha256']==summary['template_sha256'] | ", + "summary": null, + "downstream": null + }, + { + "name": "C13_summary_source_artifact_hash", + "mutant_class": "C", + "verdict": "rejected", + "detail": "line 189: assert summary['source_artifacts'][path]==p['artifacts'][name] | ", + "summary": null, + "downstream": null + }, + { + "name": "D1_provider_checks_paid_profile", + "mutant_class": "D", + "verdict": "rejected", + "detail": "line 39: assert checks==registry['local_program_checks'] | ", + "summary": null, + "downstream": null + }, + { + "name": "D2_provider_residual_adapter_rank", + "mutant_class": "D", + "verdict": "rejected", + "detail": "line 41: assert filehash(local_dir/'RESIDUAL-ADAPTERS.json')==registry['residual_adapter_sha256'] | ", + "summary": null, + "downstream": null + }, + { + "name": "D3_provider_replay_status", + "mutant_class": "D", + "verdict": "rejected", + "detail": "line 35: assert replay['status']=='PASS_INDEPENDENT_LOCAL_SCALAR_FRAME_AND_WRAPPER_REPLAY' | ", + "summary": null, + "downstream": null + }, + { + "name": "D4_provider_phase_review_semantics", + "mutant_class": "D", + "verdict": "rejected", + "detail": "line 189: assert summary['source_artifacts'][path]==p['artifacts'][name] | ", + "summary": null, + "downstream": null + }, + { + "name": "F1_consistent_stock_inflation_row_threshold", + "mutant_class": "F", + "verdict": "rejected", + "detail": "line 284: assert all(inequalities.values()) | ", + "summary": null, + "downstream": null + }, + { + "name": "F2_consistent_stock_inflation_row_subthreshold", + "mutant_class": "F", + "verdict": "accepted", + "detail": "", + "summary": { + "status": "PASS_INDEPENDENT_MIXED_ASYNC_SCALAR_PREFIX_AND_FINITE_INVOICE", + "provider_counts": { + "gauge44": 144 + }, + "selected_real_component_primitives": 28625376, + "selected_coefficient_work_primitive_count": 14162000, + "global_prefix_bits": 397, + "finite": { + "physical_stock_bits": 4487, + "router_bits": 13513, + "literal_bits": 38974, + "physical_row_coefficient": 20159, + "retained_row_coefficient": 20161, + "required_C0_bits": 200012, + "halving_integer_inequality": [ + 5329, + 2 + ], + "G_exponent": 30000, + "E_exponent": 100000, + "C0_exponent": 210000 + }, + "strict_checks": { + "local_primitive_bound": true, + "logical": true, + "router": true, + "literal": true, + "mass": true, + "precision": true, + "tape": true, + "row": true, + "halving": true + } + }, + "downstream": "assemble_rejected: line 67: pin('expected.rank_mass',owner['rank_mass']) | SPEC MISMATCH expected.rank_mass: expected 1041408 got 263597880136826" + }, + { + "name": "E1_retained_charged_prefix_bits", + "mutant_class": "E", + "verdict": "rejected", + "detail": "line 266: assert previous['compiler']==compiler and previous['charged_prefix_bits']==payload | ", + "summary": null, + "downstream": null + }, + { + "name": "E2_retained_previous_bound_zero", + "mutant_class": "E", + "verdict": "accepted", + "detail": "", + "summary": { + "status": "PASS_INDEPENDENT_MIXED_ASYNC_SCALAR_PREFIX_AND_FINITE_INVOICE", + "provider_counts": { + "gauge44": 144 + }, + "selected_real_component_primitives": 28625376, + "selected_coefficient_work_primitive_count": 14162000, + "global_prefix_bits": 397, + "finite": { + "physical_stock_bits": 2642, + "router_bits": 7987, + "literal_bits": 35284, + "physical_row_coefficient": 16469, + "retained_row_coefficient": 20161, + "required_C0_bits": 200012, + "halving_integer_inequality": [ + 5329, + 4608 + ], + "G_exponent": 30000, + "E_exponent": 100000, + "C0_exponent": 210000 + }, + "strict_checks": { + "local_primitive_bound": true, + "logical": true, + "router": true, + "literal": true, + "mass": true, + "precision": true, + "tape": true, + "row": true, + "halving": true + } + }, + "downstream": "assemble_rejected: line 153: assert hash_ok(prior['sha256']) and type(prior['previous_pervertex_allowance']) is int and prior['previous_pervertex_allowance']>0 | " + }, + { + "name": "E3_retained_previous_bound_inflated", + "mutant_class": "E", + "verdict": "rejected", + "detail": "line 284: assert all(inequalities.values()) | ", + "summary": null, + "downstream": null + }, + { + "name": "E4_retained_compiler", + "mutant_class": "E", + "verdict": "rejected", + "detail": "line 266: assert previous['compiler']==compiler and previous['charged_prefix_bits']==payload | ", + "summary": null, + "downstream": null + } + ] +} diff --git a/research/invoice-realpath-replay/README.md b/research/invoice-realpath-replay/README.md new file mode 100644 index 0000000000..ae5e3893f7 --- /dev/null +++ b/research/invoice-realpath-replay/README.md @@ -0,0 +1,111 @@ +# Make the selected invoice audit tolerate temporary-root aliases + +The one-line repair in `REPAIR.patch` canonicalizes `work` before PR2158's +extraction containment checks. It fixes a real false rejection of benign +temporary-root aliases while retaining the file-only guard, resolved-member +containment, archive/member pins, and every invoice assertion. The complete +37-mutant replay still matches the original receipt: 31 mutations are rejected +by the invoice, and all six accepted mutations are rejected downstream. + +This addresses [PR2158](https://github.com/CrocSwap/integer-mult-bounds/pull/2158) +at `8051d06df24704915fa7a6ec930a2c103a9f66f5`. The maintainer already diagnosed +the path alias and tried `TMPDIR=/private/tmp`; the latest c3c94c2e review records +a batch execution timeout after that workaround. **The diagnosis and workaround +are not claimed as new.** This contribution adds a portable source repair, +rejection regressions and a completed replay of that existing scientific audit. + +## Exact cause and fix + +Previously `prepare` compared a resolved member path against an unresolved +`src` or `fixture` root. A legitimate path such as `spelling/../work` names the +same directory as `work`, but it is not a lexical prefix of the resolved member. +The same mismatch occurs with macOS `/tmp` versus `/private/tmp`, or a Windows +directory junction. The resulting `unsafe archive member` assertion confuses a +path spelling with a containment failure. + +The source fix is exactly: + +```diff + def prepare(work): + """Extract the pinned PR1087 source and the archived selected fixture.""" ++ work = work.resolve() + src = work / 'src1087' +``` + +Both child roots now start in the same canonical coordinate system as every +resolved member. The existing pre-extraction validation still rejects relative +escapes, absolute escapes and non-regular members. The fixture archive retains +the same separate containment check. This is not a general hostile-filesystem +or concurrent symlink-race hardening claim; the existing trusted pinned archive +and private temporary-directory model is unchanged. + +`audit.py` is the exact predecessor verifier with that single line inserted. +`verify.py` removes the unique inserted line and checks the reconstructed bytes +against the original source SHA-256 on every replay. `EXPECTED.json` is the +unchanged original receipt. All nine original external inputs are byte-pinned. +No original invoice or selected archive is edited, and no check is bypassed to +obtain the result. + +## What is actually checked + +The replay first demonstrates that the original function rejects a benign +dot-dot alias, then that the repaired function extracts both actual pinned +archives through the same kind of alias and returns canonical roots. Four bad +source archives exercise relative escape, absolute escape, symlink and directory +members; a separate bad fixture exercises its containment guard. + +It then launches the minimally changed audit in an assertion-enabled isolated +Python process. That process executes its original positive control, all 37 +mutations and all six downstream admission probes. The wrapper compares every +field and type of the emitted receipt with the unchanged predecessor receipt. +It does not replace the original scientific checks with aggregate counts. + +Local validation also uses a real Windows junction for the temporary directory, +separately from the portable dot-dot regression. Execution evidence and its +limits are recorded in `VALIDATION.md`. The archive guard is intentionally not +assertion-disabled: `-O` is rejected because the retained invoice relies on +assertions. + +## Reproduce + +Python 3.12, standard library only, from the repository root: + +```sh +python3 -I -B research/invoice-realpath-replay/verify.py +python3 scripts/research_package.py --package research/invoice-realpath-replay +``` + +Expected summary: + +```text +PASS_INVOICE_REALPATH_REPLAY original_alias_rejected repaired_alias_passed traversal_controls=5 mutants=37 invoice_rejected=31 downstream_rejected=6 +``` + +The repair can also be applied directly to the pinned original package using +`REPAIR.patch`; its original commands and original receipt then remain valid. +The wrapper's default replay writes only into private temporary directories. + +## Scope, credit and stopping decision + +The selected finite invoice findings belong to Aaron Wang / navinor and the +retained PR1087 invoice lineage, including Jeremy Kothe, Hao Yan, Rohan Arun, +the selected frontier audit and Josie Elliston's mutation-audit handoff. The +original source's attribution is retained verbatim in `audit.py`. Credit the +maintainer's efficient1200 review for the path-alias diagnosis and workaround. +This repair and regression wrapper were prepared by ywz65 with substantial +OpenAI Codex assistance. Apache-2.0; no independent human review is claimed. + +The picker on base `6bd33bc0` selected the bit register model; its required +baseline passed, and current finite algebra scopes were already covered or +claimed. TASK.json records the change to this concrete review blocker and its +[canonical claim](https://github.com/CrocSwap/integer-mult-bounds/pull/2158#issuecomment-6198945252). +The contribution stops at the source portability and exact replay obligation. +It is not a new mutation census, invoice theorem, selected-supplier cold replay, +complete multiplication audit, native runtime result or new kappa. + +## Open next questions + +Can the original PR incorporate the one-line repair and completed replay +evidence? Apply `REPAIR.patch` at the pinned head and rerun its unchanged commands +under a temporary-root alias. Original-author or maintainer integration remains; +no larger mathematical search is needed for this fix. diff --git a/research/invoice-realpath-replay/REPAIR.patch b/research/invoice-realpath-replay/REPAIR.patch new file mode 100644 index 0000000000..ce7aaec7a7 --- /dev/null +++ b/research/invoice-realpath-replay/REPAIR.patch @@ -0,0 +1,10 @@ +--- a/research/invoice-mutant-coverage/verify.py ++++ b/research/invoice-mutant-coverage/verify.py +@@ -73,6 +73,7 @@ + + def prepare(work): + """Extract the pinned PR1087 source and the archived selected fixture.""" ++ work = work.resolve() + src = work / 'src1087' + src.mkdir() + with tarfile.open(ARCHIVE) as t: diff --git a/research/invoice-realpath-replay/SOURCES.json b/research/invoice-realpath-replay/SOURCES.json new file mode 100644 index 0000000000..c8e59f1032 --- /dev/null +++ b/research/invoice-realpath-replay/SOURCES.json @@ -0,0 +1,95 @@ +{ + "schema_version": 1, + "base_commit": "6bd33bc0b87a01e9c9d8b1c01576f3ddbcaee850", + "files": [ + { + "path": "certificates/selected-result.json", + "usage": "provenance", + "git_blob": "ae6a99f28aa468649eb66a361e764d769363bf11", + "sha256": "10b9e340fd8e354a37a0c4813c90e5de1dd42044b5f6aca4a3fc5a42b685fa32" + }, + { + "path": "docs/research/agent-task-catalog.json", + "usage": "provenance", + "git_blob": "889b95d936746df124872133ae1e7cc339adcb92", + "sha256": "7d185cd8c2af35988d638d969748ad7b670f902606444dbfc748e4402c340df6" + }, + { + "path": "research/community-frontier1094-audit/selected-replay.tar.gz", + "usage": "input", + "git_blob": "c24daf067f9c543421d89ca2eeaa4eb78a57fb6f", + "sha256": "f1da80610bf33c58527f18ad63b4350d0b864e1d4486141ee17ac9bed4d529d6" + }, + { + "path": "research/complex-t16-rare-pattern-exchanges/upstream1087.tar.gz", + "usage": "input", + "git_blob": "2970ef79b0441e937449bed30f68f2e0558186ba", + "sha256": "d4acf04daef85d4514f80ec5fcd2492d0c60e5d6c49fa71b3e6523f8db2dea86" + }, + { + "path": "research/complex-t16-rare-pattern-exchanges/data/OWNERS.json.gz", + "usage": "input", + "git_blob": "d3ba33d7e703a3229d9fb8a360f69d2f318bbb70", + "sha256": "87902c528dfab7d503dcf8a784260e3ab6fb7424c418a1820f7261f25be7b6bc" + }, + { + "path": "research/complex-t16-rare-pattern-exchanges/data/PLAN.json", + "usage": "input", + "git_blob": "f1bec76e8e9b7a1f09c1e05cb6cce973b6e59f1b", + "sha256": "7bd786ba8e66408f02aa9ef446eaf20c1bfe981ea2e4dd1e5a929f0aa7767bc0" + }, + { + "path": "research/complex-t16-rare-pattern-exchanges/data/SPEC.json", + "usage": "input", + "git_blob": "af013ccc2975d9d575d116f8a463cc947f220c8d", + "sha256": "8cb51f25a5da4a29d3783853025b73ff1f452429d4fdb30c599e598bcab0e71d" + }, + { + "path": "research/complex-k492-owner-repair/vendor/multicold/vendor/pr558/vendor/pr552/complex-global/vendor531/evidence/audit/PREFIX-AND-INVOICE.json", + "usage": "input", + "git_blob": "a16bf40bccc81278a443e0d5f09b44495035de81", + "sha256": "ce1bfa49be88ae67a404f606a11db2232b7e1f2610d4418058e39749d86d8478" + }, + { + "path": "research/complex-k492-owner-repair/vendor/multicold/engines/moment.py", + "usage": "input", + "git_blob": "7d697cb45203fe72d97037403d6da41f71f3b7fd", + "sha256": "81cbc864e106418fc7854322746f72180cb8110ff39f74450a3b8d55a82c1482" + }, + { + "path": "research/complex-k492-owner-repair/vendor/multicold/engines/base_two_moment.py", + "usage": "input", + "git_blob": "14a90fa0e788217856f070382c9e61bd7c603c61", + "sha256": "aee70c242a2f1d225528fabe2002e1564d1dc884797c07d28a831c7878ee9098" + }, + { + "path": "research/complex-k492-owner-repair/vendor/multicold/engines/outer.py", + "usage": "input", + "git_blob": "43007488ad2c43187c77cc6798beff8b1cd76ad2", + "sha256": "c1ebb52163a7219504c728a5c2b098bf1e50bf20148a2879c5a74c3cadc7c03c" + } + ], + "derived_source": { + "path": "research/invoice-realpath-replay/audit.py", + "source_commit": "8051d06df24704915fa7a6ec930a2c103a9f66f5", + "source_path": "research/invoice-mutant-coverage/verify.py", + "git_blob": "8284e045082bc9ba153b06242e54f008a3bd40b1", + "sha256": "674c04027dc8a6c58a8e6e4044845c45e7457ff7137dcbcdc2b02895c5783f4d", + "repair": "Insert work = work.resolve() as the first prepare operation; removing this unique line reproduces every original byte." + }, + "vendored_files": [ + { + "path": "research/invoice-realpath-replay/EXPECTED.json", + "usage": "input", + "source_commit": "8051d06df24704915fa7a6ec930a2c103a9f66f5", + "source_path": "research/invoice-mutant-coverage/EXPECTED.json", + "git_blob": "3c7c36dd3c09497ec69463408b50ea665104f7d8", + "sha256": "47b35631d846b44998ae73134a2bdb233314ed5c813cb0fda3afcd53fe51dd29" + } + ], + "review_context": { + "commit": "c3c94c2ea2ebcd5d69d1e51b5fe8a36bf79819f5", + "path": "docs/research/community-efficient1200-review.md", + "credit": "Maintainer already diagnosed path alias and tried TMPDIR=/private/tmp; latest disposition is batch execution timeout." + } +} diff --git a/research/invoice-realpath-replay/TASK.json b/research/invoice-realpath-replay/TASK.json new file mode 100644 index 0000000000..881ab2abec --- /dev/null +++ b/research/invoice-realpath-replay/TASK.json @@ -0,0 +1,86 @@ +{ + "schema_version": 1, + "task_id": "bit-new-register-model", + "priority_revision": 5, + "base_commit": "6bd33bc0b87a01e9c9d8b1c01576f3ddbcaee850", + "original_card": { + "id": "bit-new-register-model", + "question": "Can an explicitly larger or nonabelian register model escape the scoped three-register obstruction?", + "starting_points": [ + "docs/research/research-family-status.md", + "research/bit-three-register-lower-bound/README.md", + "certificates/selected-result.json", + "research/bit-gl3-mixed-targets-length10/README.md", + "docs/research/community-efficient1000-review.md" + ], + "methods": [ + "Construct the smallest exact identity in a newly specified legal operation alphabet.", + "Derive a target-specific relaxation bound for that same explicit alphabet." + ], + "acceptance_gate": "Name the changed hypothesis, all counted roles and a uniform identity; finite column tests alone do not certify it. 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 Model section 1 of the three-register bound and identify the exact excluded free operations.", + "scope": "Positive control / source-bound orientation only; this is not a new construction or full cold replay." + }, + "first_experiment": "First compare the alphabet, role count and length with the fully replayed #1974 census and #2027 mixed-root tariff. Identify a changed premise and a legal native implementation; then price one smallest completed instance before searching larger words.", + "bottleneck_link": "A small-width completed saving changes the bit primitive; a finite-address identity alone is insufficient.", + "allowed_variations": [ + "Choose a fixed larger register count or a specified nonabelian operation family." + ], + "scope_change_triggers": [ + "Remaining inside the already-excluded three-register abelian model.", + "Repeating the two-register GL3 census or a covered three-register length without changing a hypothesis; a formal group-algebra word without native conversion is a partial result." + ], + "overlap_terms": [ + "three-register", + "nonabelian", + "group algebra" + ] + }, + "scope_status": "changed", + "actual_scope": "Portable extraction-root repair and completed source-bound PR2158 invoice mutation replay.", + "scope_change_reason": "Primary register mechanisms are covered or actively claimed. A precise current reviewer execution blocker remains after a documented platform workaround; this fixes source behavior and finishes that replay without claiming a new diagnosis.", + "bottleneck_link": "Selected finite invoice acceptance audit; closes an execution blocker, not a new supplier or bound.", + "budget_minutes": 60, + "stop_rule": "Stop after one-line source repair, alias/traversal regressions and complete unchanged37-mutant receipt agreement; no broader archive or invoice redesign.", + "outcome": "completed", + "evidence": "audit.py, REPAIR.patch, unchanged EXPECTED.json, verify.py and VALIDATION.md.", + "author": "ywz65", + "ai_assistance": "Substantial OpenAI Codex assistance in diagnosis, implementation, validation and writing.", + "open_questions": [ + { + "question": "Can the original PR incorporate the one-line canonical-root repair and the completed replay evidence?", + "why_it_matters": "The maintained review records alias failure then a workaround timeout.", + "first_step": "Apply REPAIR.patch and run the unchanged full37-mutant receipt under a temporary-root alias.", + "blocked_by": "Original-author or maintainer integration; no scientific census expansion required." + } + ], + "picker_nonce": "98795ea2eaeadaf92e422932c9e52655", + "canonical_thread": "https://github.com/CrocSwap/integer-mult-bounds/pull/2158#issuecomment-6198945252", + "first_steps": [ + "PASS_RESEARCH_BASELINE_BINDINGS_ONLY; read exact three-register excluded free operations and current GL3 coverage." + ], + "family_decision": { + "boundary": "Exact PR2158 source and selected fixture; arbitrary benign extraction-root spellings; pins, file-only guards, containment and assertion-enabled invoice semantics unchanged.", + "proved": "Canonical root and member paths use one coordinate system; original source reconstructed byte-for-byte after removing one line.", + "unknown": "No new invoice completeness, supplier or exponent conclusion.", + "consumer": "No input validation or mutant obligation is waived.", + "decision": "Finish the current source portability and replay obligation; stop." + }, + "overlap": { + "open_prs": "767 complete records at2026-10-15T18:06:42.717923UTC", + "discussions": "1239 complete cached records at2026-10-15T15:22:22.047084UTC; later changes outside coverage", + "targeted": "PR2158 head8051d06d unchanged; no owner fix; canonical claim updated to credit new maintainer diagnosis/workaround" + }, + "upstream_checkpoint": { + "commit": "c3c94c2ea2ebcd5d69d1e51b5fe8a36bf79819f5", + "priority_revision": 5, + "decision": "Retain6bd33 scientific/startbase; unchanged guidance, selected inputs and actual source head; changed review disposition credited." + } +} diff --git a/research/invoice-realpath-replay/VALIDATION.md b/research/invoice-realpath-replay/VALIDATION.md new file mode 100644 index 0000000000..66e01fc8ac --- /dev/null +++ b/research/invoice-realpath-replay/VALIDATION.md @@ -0,0 +1,38 @@ +# Validation record + +Observed locally on Windows with CPython 3.12.14, October 15, 2026: + +- The original byte-pinned verifier completed the entire 37-mutant census on + an ordinary canonical temporary root, matching every original receipt field. +- The original `prepare` rejected a benign `spelling/../work` root with + `unsafe archive member`; the repaired function extracted both actual pinned + archives through the same spelling and returned canonical roots. +- A real Windows directory junction reproduced the old rejection. The one-line + repair passed through that junction. This uses an actual filesystem alias, + separately from the portable dot-dot regression; no macOS execution is claimed. +- The registered replay passed with both `TEMP` and `TMP` set to that junction. + It checked the source reconstruction, all five traversal/non-file controls, + all 37 original mutations, the archived positive invoice and six downstream + rejection probes. The emitted complete receipt was compared with type-sensitive + recursive equality against unchanged `EXPECTED.json`. +- A Git-free export containing this package and only its nine declared external + files passed the same complete replay, also using the junction temporary root. + Default replay changed no exported bytes. Mutated external input, original + receipt and reconstructed source were rejected; `-O` and an unknown CLI flag + were rejected. All files matched their initial hashes after restoration. + +The maintainer's c3c94c2e checkpoint already contains the macOS alias diagnosis +and `TMPDIR=/private/tmp` workaround. Its updated review reports a batch timeout; +this note credits that diagnosis and records the completed local replay rather +than inferring a mathematical failure from the timeout. + +Prepublication overlap used the complete 767-open-PR title/body snapshot at +18:06:42 UTC and the complete cached Discussion snapshot at 15:22:22 UTC. +Later Discussion changes and every code diff are outside that coverage. +Targeted REST checks retained PR2158 head `8051d06d` with no owner repair. +Canonical main `c3c94c2e` has unchanged guidance and selected inputs relative to +the exact starting base `6bd33bc0`. + +These are source portability and finite acceptance-boundary checks, not a +new invoice theorem, a general hostile-filesystem proof, independent human +review, hosted CI, selected cold replay or a complete supplier audit. diff --git a/research/invoice-realpath-replay/VERIFY.json b/research/invoice-realpath-replay/VERIFY.json new file mode 100644 index 0000000000..c403c0beaa --- /dev/null +++ b/research/invoice-realpath-replay/VERIFY.json @@ -0,0 +1,29 @@ +{ + "schema_version": 1, + "status": "ready", + "python": "3.12", + "requirements": [], + "inputs": [ + "research/community-frontier1094-audit/selected-replay.tar.gz", + "research/complex-t16-rare-pattern-exchanges/upstream1087.tar.gz", + "research/complex-t16-rare-pattern-exchanges/data/OWNERS.json.gz", + "research/complex-t16-rare-pattern-exchanges/data/PLAN.json", + "research/complex-t16-rare-pattern-exchanges/data/SPEC.json", + "research/complex-k492-owner-repair/vendor/multicold/vendor/pr558/vendor/pr552/complex-global/vendor531/evidence/audit/PREFIX-AND-INVOICE.json", + "research/complex-k492-owner-repair/vendor/multicold/engines/moment.py", + "research/complex-k492-owner-repair/vendor/multicold/engines/base_two_moment.py", + "research/complex-k492-owner-repair/vendor/multicold/engines/outer.py" + ], + "commands": [ + { + "argv": [ + "{python}", + "-I", + "-B", + "{package}/verify.py" + ], + "timeout_seconds": 600, + "checks": "Actual old/fixed aliased-root behavior, preserved traversal guards, one-line source reconstruction and full unchanged37-mutant receipt." + } + ] +} diff --git a/research/invoice-realpath-replay/audit.py b/research/invoice-realpath-replay/audit.py new file mode 100644 index 0000000000..3caed7bcc7 --- /dev/null +++ b/research/invoice-realpath-replay/audit.py @@ -0,0 +1,574 @@ +#!/usr/bin/env python3 +"""Mutation coverage of the selected finite invoice (frozen PR1087 invoice_allcold.run()). + +Adversarial audit of one named current condition of the selected #1094 chain. +Object: code/invoice_allcold.py in research/complex-t16-rare-pattern-exchanges/ +upstream1087.tar.gz (SHA-256 pinned below), run on the archived selected fixture +research/community-frontier1094-audit/selected-replay.tar.gz. The invoice stage +carries the finite inequalities (prefix required < 512 payload, row < 20161, +halving, mass, router, literal, precision, tape, local-primitive) and has no +mutation-control block of its own. This harness applies one-field semantic +mutants of its inputs, records the first rejecting assertion or acceptance, and +probes whether the downstream receipt admission (assemble(), the layer the 69 +admission controls exercise) rejects the mutants the invoice accepts. + +Scope: the invoice stage's acceptance boundary only. No kappa, certificate, +supplier or frontier change; not a cold replay. Open question 3 of +research/t16-audit-mutant-coverage/README.md (PR1959, Josie Elliston). + +Aaron Wang, with help from opencode. Apache-2.0. Stdlib only; CPython 3.10+. +""" +import argparse +import contextlib +import gzip +import hashlib +import importlib +import io +import json +import os +from pathlib import Path +import shutil +import sys +import tarfile +import tempfile +import traceback + +ROOT = Path(__file__).resolve().parents[2] +PKG = Path(__file__).resolve().parent +ARCHIVE = ROOT / 'research/complex-t16-rare-pattern-exchanges/upstream1087.tar.gz' +FIXTURE = ROOT / 'research/community-frontier1094-audit/selected-replay.tar.gz' +RETAINED = ROOT / ('research/complex-k492-owner-repair/vendor/multicold/vendor/pr558/' + 'vendor/pr552/complex-global/vendor531/evidence/audit/PREFIX-AND-INVOICE.json') +MULTICOLD = ROOT / 'research/complex-k492-owner-repair/vendor/multicold' +EXPECT = PKG / 'EXPECTED.json' + +PINS = { + 'upstream1087.tar.gz': 'd4acf04daef85d4514f80ec5fcd2492d0c60e5d6c49fa71b3e6523f8db2dea86', +} + + +def sha(path): + return hashlib.sha256(Path(path).read_bytes()).hexdigest() + + +def read_json(path): + return json.loads(Path(path).read_bytes()) + + +def read_gz_json(path): + return json.loads(gzip.decompress(Path(path).read_bytes())) + + +def dumps(value): + return json.dumps(value, indent=2).encode() + + +def contenthash_bytes(raw): + return hashlib.sha256(gzip.decompress(raw)).hexdigest() + + +# -------------------------------------------------------------------------- +# Environment and module loading (mirrors verify_t16.py's stage environment). + + +def prepare(work): + """Extract the pinned PR1087 source and the archived selected fixture.""" + work = work.resolve() + src = work / 'src1087' + src.mkdir() + with tarfile.open(ARCHIVE) as t: + for m in t.getmembers(): + assert m.isfile() and (src / m.name).resolve().is_relative_to(src), 'unsafe archive member' + t.extractall(src, filter='data') + assert sha(ARCHIVE) == PINS['upstream1087.tar.gz'], 'PR1087 archive pin' + manifest = read_json(src / 'MANIFEST.json') + for name, digest in manifest.items(): + if name.startswith('code/') or name.startswith('data/'): + assert sha(src / name) == digest, 'archive member pin: ' + name + # The pipeline copies the pinned package data over the source data/ (verify.py). + package = ROOT / 'research/complex-t16-rare-pattern-exchanges' + for name in ('OWNERS.json.gz', 'PLAN.json', 'SPEC.json'): + shutil.copyfile(package / 'data' / name, src / 'data' / name) + + fixture = work / 'fixture' + fixture.mkdir() + with tarfile.open(FIXTURE) as t: + for m in t.getmembers(): + assert m.isfile() and (fixture / m.name).resolve().is_relative_to(fixture), 'unsafe fixture member' + t.extractall(fixture, filter='data') + global_dir = fixture / 'candidate/strict/global' + return src, global_dir + + +def load_invoice(src): + os.environ['WITNESS_SPEC'] = str(src / 'data/SPEC.json') + os.environ['GAIN_PR564_SOURCE'] = str(MULTICOLD) + for key in ('PYTHONOPTIMIZE', 'WITNESS_DISCOVER', 'WITNESS_RECORD'): + os.environ.pop(key, None) + sys.path.insert(0, str(src / 'code')) + assert __debug__, 'Assertions must remain enabled' + mod = importlib.import_module('invoice_allcold') + return mod + + +# -------------------------------------------------------------------------- +# Input tree: pristine bytes, mutation, restoration. Inputs are mutated in +# place and restored from an in-memory pristine copy after every run. + + +INPUT_FILES = ( + 'hosted/GLOBAL-TEMPLATE.json.gz', + 'hosted/HOSTED.json', + 'audit/OWNERS-AND-PROFILE.json', + 'audit/ASYNC-AUDIT.json', + 'base/split-centres/GLOBAL-TEMPLATE.json.gz', + 'base/providers/gauge44/LOCAL-CHECKS.json', + 'base/providers/gauge44/RESIDUAL-ADAPTERS.json', + 'base/providers/gauge44/INDEPENDENT-LOCAL-REPLAY.json', + 'base/providers/gauge44/CLIFFORD-REVIEW.json', +) + + +class InputTree: + def __init__(self, base): + self.base = base + self.pristine = {name: (base / name).read_bytes() for name in INPUT_FILES} + + def restore(self): + for name, raw in self.pristine.items(): + (self.base / name).write_bytes(raw) + + def load(self, name): + raw = (self.base / name).read_bytes() + if name.endswith('.gz'): + return json.loads(gzip.decompress(raw)) + return json.loads(raw) + + def store(self, name, value): + raw = dumps(value) + if name.endswith('.gz'): + raw = gzip.compress(raw) + (self.base / name).write_bytes(raw) + return raw + + +def sync_template_hashes(tree, template_raw, targets): + """Class B: make the stored template hashes agree with mutated content.""" + digest = contenthash_bytes(template_raw) + for name, key in targets: + value = tree.load(name) + value[key] = digest + tree.store(name, value) + return digest + + +# -------------------------------------------------------------------------- +# Mutant catalogue. Each entry: name, class, function(tree) -> applied. + + +def mutants(): + out = [] + + def add(name, cls, fn): + out.append((name, cls, fn)) + + # Class A: raw template content mutation; stored hashes untouched. + def a1(tree): + t = tree.load('hosted/GLOBAL-TEMPLATE.json.gz') + t['live'] += 1 + tree.store('hosted/GLOBAL-TEMPLATE.json.gz', t) + add('A1_raw_template_live', 'A', a1) + + def a2(tree): + t = tree.load('hosted/GLOBAL-TEMPLATE.json.gz') + t['bank_padding']['families'] = ['x'] + tree.store('hosted/GLOBAL-TEMPLATE.json.gz', t) + add('A2_raw_template_bank_padding', 'A', a2) + + # Class B: template content mutation with the three stored hashes resynced. + hash_targets = (('audit/ASYNC-AUDIT.json', 'complex_template_sha256'), + ('audit/OWNERS-AND-PROFILE.json', 'template_sha256'), + ('hosted/HOSTED.json', 'template_sha256')) + + def class_b(name, edit): + def fn(tree): + t = tree.load('hosted/GLOBAL-TEMPLATE.json.gz') + edit(t) + raw = tree.store('hosted/GLOBAL-TEMPLATE.json.gz', t) + sync_template_hashes(tree, raw, hash_targets) + add(name, 'B', fn) + + class_b('B1_template_live_plus1', lambda t: t.__setitem__('live', t['live'] + 1)) + + def b2(t): + t['live'] += 1 + t['physical'] += 1 + class_b('B2_template_live_physical_plus1', b2) + + class_b('B3_template_bank_padding_family', + lambda t: t['bank_padding']['families'].append('x')) + + def b4(t): + t['calls'].pop() + class_b('B4_template_drop_call', b4) + + def b5(t): + for e in t['execution_schedule']: + if e['kind'] == 'local_cover_sweep': + e['provider_id'] = '__wrong__' + break + class_b('B5_template_wrong_sweep_provider', b5) + + def b6(t): + first = t['calls'][0]['owners'][0] + if isinstance(first, list): + first[0] = (first[0] + 1) % 20000 + else: + t['calls'][0]['owners'][0] = (first + 1) % 20000 + class_b('B6_template_call_owner_changed', b6) + + def b7(t): + t['calls'][0]['orientation'] = 'backward' if t['calls'][0]['orientation'] == 'forward' else 'forward' + class_b('B7_template_call_orientation_changed', b7) + + def b8(t): + t['recipe'][0] = dict(t['recipe'][0], kind='__wrong__') + class_b('B8_template_recipe_changed', b8) + + def b9(t): + t['calls'][0]['local_program_sha256'] = '0' * 64 + class_b('B9_template_call_program_hash', b9) + + def b10(t): + pid = sorted(t['local_providers'])[0] + t['local_providers'][pid]['local_program_checks'] = {} + class_b('B10_template_registry_checks_cleared', b10) + + def b11(t): + pid = sorted(t['local_providers'])[0] + t['local_providers'][pid]['v'] = 113 + class_b('B11_template_registry_v_changed', b11) + + # Class C: audit receipt mutations (their file hashes are recorded, not pinned). + def c1(tree): + o = tree.load('audit/OWNERS-AND-PROFILE.json') + o['deficit'] = 5119 + tree.store('audit/OWNERS-AND-PROFILE.json', o) + add('C1_owner_deficit_5119', 'C', c1) + + def c2(tree): + o = tree.load('audit/OWNERS-AND-PROFILE.json') + o['rank_mass'] += 73 + tree.store('audit/OWNERS-AND-PROFILE.json', o) + add('C2_owner_rank_mass_off_profile', 'C', c2) + + def c3(tree): + # Same rank mass, but max child rank 52 must break the halving guard. + o = tree.load('audit/OWNERS-AND-PROFILE.json') + p = dict(o['paid_profile']) + donor = next((r for r in (1, 2, 4, 13, 26) if int(p.get(str(r), 0)) >= 52 // r), None) + assert donor is not None, 'C3 needs a donor rank dividing 52' + p[str(donor)] = int(p[str(donor)]) - 52 // donor + p['52'] = int(p.get('52', 0)) + 1 + o['paid_profile'] = p + tree.store('audit/OWNERS-AND-PROFILE.json', o) + add('C3_owner_profile_halving_guard', 'C', c3) + + def c3b(tree): + # Same rank mass and same max child rank: run() alone must accept this + # profile change; the downstream probe records what assemble() does. + o = tree.load('audit/OWNERS-AND-PROFILE.json') + p = dict(o['paid_profile']) + assert int(p.get('2', 0)) >= 1 + p['2'] = int(p['2']) - 1 + p['1'] = int(p.get('1', 0)) + 2 + o['paid_profile'] = p + tree.store('audit/OWNERS-AND-PROFILE.json', o) + add('C3b_owner_profile_same_mass_same_max', 'C', c3b) + + def c4(tree): + o = tree.load('audit/OWNERS-AND-PROFILE.json') + o['explicit_idle_remainder_children'] += 1 + tree.store('audit/OWNERS-AND-PROFILE.json', o) + add('C4_owner_explicit_idle_remainders', 'C', c4) + + def c5(tree): + o = tree.load('audit/OWNERS-AND-PROFILE.json') + o['template_sha256'] = '0' * 64 + tree.store('audit/OWNERS-AND-PROFILE.json', o) + add('C5_owner_template_sha_raw', 'C', c5) + + def c6(tree): + o = tree.load('audit/OWNERS-AND-PROFILE.json') + o['actual_73column_sigmas'] += 1 + tree.store('audit/OWNERS-AND-PROFILE.json', o) + add('C6_owner_actual_73column_sigmas', 'C', c6) + + def c7(tree): + o = tree.load('audit/OWNERS-AND-PROFILE.json') + key = sorted(o['source_artifacts'])[0] + o['source_artifacts'][key] = '0' * 64 + tree.store('audit/OWNERS-AND-PROFILE.json', o) + add('C7_owner_source_artifact_hash', 'C', c7) + + def c8(tree): + c = tree.load('audit/ASYNC-AUDIT.json') + c['complete_invocations'] = 143 + tree.store('audit/ASYNC-AUDIT.json', c) + add('C8_control_complete_invocations', 'C', c8) + + def c9(tree): + c = tree.load('audit/ASYNC-AUDIT.json') + c['one_owner_per_complete_invocation'] = False + tree.store('audit/ASYNC-AUDIT.json', c) + add('C9_control_one_owner_flag', 'C', c9) + + def c10(tree): + c = tree.load('audit/ASYNC-AUDIT.json') + c['mutations_rejected'] = [] + c['mutation_controls_run'] = False + tree.store('audit/ASYNC-AUDIT.json', c) + add('C10_control_mutation_claims_cleared', 'C', c10) + + def c11(tree): + c = tree.load('audit/ASYNC-AUDIT.json') + c['complex_template_sha256'] = '0' * 64 + tree.store('audit/ASYNC-AUDIT.json', c) + add('C11_control_template_sha_raw', 'C', c11) + + def c12(tree): + s = tree.load('hosted/HOSTED.json') + s['template_sha256'] = '0' * 64 + tree.store('hosted/HOSTED.json', s) + add('C12_summary_template_sha_raw', 'C', c12) + + def c13(tree): + s = tree.load('hosted/HOSTED.json') + key = sorted(s['source_artifacts'])[0] + s['source_artifacts'][key] = '0' * 64 + tree.store('hosted/HOSTED.json', s) + add('C13_summary_source_artifact_hash', 'C', c13) + + # Class D: provider inputs. + def d1(tree): + c = tree.load('base/providers/gauge44/LOCAL-CHECKS.json') + c['forward']['paid_profile']['1'] = str(int(c['forward']['paid_profile']['1']) + 1) + tree.store('base/providers/gauge44/LOCAL-CHECKS.json', c) + add('D1_provider_checks_paid_profile', 'D', d1) + + def d2(tree): + r = tree.load('base/providers/gauge44/RESIDUAL-ADAPTERS.json') + recipe = next(iter(r['recipes'].values())) + recipe['rank'] = 8 + tree.store('base/providers/gauge44/RESIDUAL-ADAPTERS.json', r) + add('D2_provider_residual_adapter_rank', 'D', d2) + + def d3(tree): + r = tree.load('base/providers/gauge44/INDEPENDENT-LOCAL-REPLAY.json') + r['status'] = 'FAIL' + tree.store('base/providers/gauge44/INDEPENDENT-LOCAL-REPLAY.json', r) + add('D3_provider_replay_status', 'D', d3) + + def d4(tree): + r = tree.load('base/providers/gauge44/CLIFFORD-REVIEW.json') + r['seconds'] = 0 + tree.store('base/providers/gauge44/CLIFFORD-REVIEW.json', r) + add('D4_provider_phase_review_semantics', 'D', d4) + + # Class F: fully hash-consistent multi-file stock inflation. Every run() + # arithmetic identity is preserved (deficit literal included); only the + # finite inequality guards see the inflated stock. With payload 512 the + # guard reads row = 2*stock_bits + 11185 < 20161, i.e. stock_bits < 4488. + # F1 lands exactly on the failing side (stock bit length 4488, row == 20161), + # F2 one bit below it: the smallest falsifying pair for the row obligation. + def class_f(name, target_stock_bits): + def fn(tree): + invoice = read_json(tree.base / 'audit/PREFIX-AND-INVOICE.json') + helpers, centres = invoice['helpers'], invoice['centres'] + parent = read_gz_json(tree.base / 'base/split-centres/GLOBAL-TEMPLATE.json.gz') + parent_r = read_gz_json(tree.base / 'base/split-centres/CANONICAL-WORD.json.gz')['R'] + half = 73 // 2 + group = 2 ** (half * half) + for i in range(1, half + 1): + group *= 2 ** (2 * i) - 1 + n = None + for cand_bits in range(target_stock_bits - group.bit_length() - 2, + target_stock_bits - group.bit_length() + 8): + cand = 2 ** cand_bits + cand += (63 - cand % 73) % 73 # make (cand + 5120) divisible by m = 73 + physical = (cand + 5120) // 73 + helpers + centres + 2 + if (group * physical).bit_length() == target_stock_bits: + n = cand + break + assert n is not None, 'no exact stock-width candidate' + live = (n + 5120) // 73 + physical = live + helpers + centres + 2 + o = tree.load('audit/OWNERS-AND-PROFILE.json') + o['live'], o['physical'] = live, physical + o['rank_mass'] = n + o['paid_profile'] = {'1': n} + tree.store('audit/OWNERS-AND-PROFILE.json', o) + t = tree.load('hosted/GLOBAL-TEMPLATE.json.gz') + t['live'], t['physical'] = live, physical + raw = tree.store('hosted/GLOBAL-TEMPLATE.json.gz', t) + sync_template_hashes(tree, raw, hash_targets) + parent_live = live + max(0, helpers - parent_r) + parent_live += (8 - parent_live % 9) % 9 # (parent_live - data_stock) divisible by 9 + parent['live'] = parent_live + parent['physical'] = parent_live + parent_r + centres + 2 + tree.store('base/split-centres/GLOBAL-TEMPLATE.json.gz', parent) + add(name, 'F', fn) + + class_f('F1_consistent_stock_inflation_row_threshold', 4488) + class_f('F2_consistent_stock_inflation_row_subthreshold', 4487) + + return out + + +# -------------------------------------------------------------------------- +# Retained-invoice mutants run on a scratch copy, never on the pinned file. + + +def retained_mutants(): + def edit(name, fn): + return (name, fn) + + def e1(v): + v['charged_prefix_bits'] = 511 + def e2(v): + v['conservative_pervertex_used'] = 0 + def e3(v): + v['conservative_pervertex_used'] = 2 ** 6050 + def e4(v): + v['compiler'] = 1 + return [edit('E1_retained_charged_prefix_bits', e1), + edit('E2_retained_previous_bound_zero', e2), + edit('E3_retained_previous_bound_inflated', e3), + edit('E4_retained_compiler', e4)] + + +# -------------------------------------------------------------------------- +# Execution. + + +def run_invoice(mod, base, out_dir, retained): + out_dir.mkdir(parents=True, exist_ok=True) + buf = io.StringIO() + with contextlib.redirect_stdout(buf): + receipt = mod.run(base / 'base', base / 'hosted', base / 'audit', out_dir, retained) + return receipt, buf.getvalue() + + +def probe_assemble(owner_path, invoice_path): + """Downstream admission layer: does assemble() reject the emitted pair?""" + os.environ['GAIN_PR564_SOURCE'] = str(MULTICOLD) + assemble_mod = importlib.import_module('assemble') + owner = read_json(owner_path) + invoice = read_json(invoice_path) + try: + assemble_mod.assemble(owner, invoice, sha(owner_path), sha(invoice_path)) + except (AssertionError, KeyError, ValueError) as exc: + tb = traceback.extract_tb(exc.__traceback__) + frame = next((f for f in reversed(tb) if f.filename.endswith('assemble.py')), None) + where = 'line %s: %s' % (frame.lineno, (frame.line or '').strip()) if frame else 'unknown' + return 'assemble_rejected: %s | %s' % (where, str(exc)[:70] or '') + return 'assemble_accepted' + + +def failure(mod, base, out_dir, retained): + try: + _, summary = run_invoice(mod, base, out_dir, retained) + except AssertionError as exc: + tb = traceback.extract_tb(exc.__traceback__) + frame = next((f for f in reversed(tb) if f.filename.endswith('invoice_allcold.py')), None) + where = 'line %s: %s' % (frame.lineno, (frame.line or '').strip()) if frame else 'unknown' + return 'rejected', '%s | %s' % (where, str(exc)[:70] or ''), None + except Exception as exc: # incidental type errors still reject the input + return 'rejected', 'exception %s: %s' % (type(exc).__name__, str(exc)[:60]), None + return 'accepted', '', json.loads(summary) + + +def main(): + ap = argparse.ArgumentParser(description=__doc__) + ap.add_argument('--write', action='store_true', help='regenerate EXPECTED.json') + ap.add_argument('--expect', type=Path, default=EXPECT, help='receipt to compare against') + ap.add_argument('--json', type=Path, help='also dump the full result here') + a = ap.parse_args() + assert __debug__, 'Assertions must remain enabled' + + with tempfile.TemporaryDirectory(prefix='invoice-mutant-coverage.') as tmp: + work = Path(tmp) + src, global_dir = prepare(work) + tree = InputTree(global_dir) + mod = load_invoice(src) + + # Positive control: reproduce the archived selected invoice exactly. + out = work / 'out-positive' + run_invoice(mod, global_dir, out, RETAINED) + archived_invoice = read_json(global_dir / 'audit/PREFIX-AND-INVOICE.json') + archived_prefix = read_json(global_dir / 'audit/GLOBAL-PREFIX.json') + assert read_json(out / 'PREFIX-AND-INVOICE.json') == archived_invoice, \ + 'positive control: PREFIX-AND-INVOICE differs' + assert read_json(out / 'GLOBAL-PREFIX.json') == archived_prefix, 'positive control: GLOBAL-PREFIX differs' + positive = dict(status='PASS_POSITIVE_CONTROL_REPRODUCES_ARCHIVED_INVOICE', + invoice_sha256=sha(global_dir / 'audit/PREFIX-AND-INVOICE.json')) + + records = [] + for name, cls, edit in mutants(): + tree.restore() + edit(tree) + verdict, detail, summary = failure(mod, global_dir, work / ('out-' + name), RETAINED) + record = dict(name=name, mutant_class=cls, verdict=verdict, detail=detail, + summary=summary, downstream=None) + if verdict == 'accepted': + record['downstream'] = probe_assemble(global_dir / 'audit/OWNERS-AND-PROFILE.json', + work / ('out-' + name) / 'PREFIX-AND-INVOICE.json') + records.append(record) + tree.restore() + + # Retained-invoice mutants use a scratch copy of the pinned file. + pristine_retained = RETAINED.read_bytes() + scratch_retained = work / 'retained-invoice.json' + for name, edit in retained_mutants(): + value = json.loads(pristine_retained) + edit(value) + scratch_retained.write_bytes(dumps(value)) + verdict, detail, summary = failure(mod, global_dir, work / ('out-' + name), scratch_retained) + record = dict(name=name, mutant_class='E', verdict=verdict, detail=detail, + summary=summary, downstream=None) + if verdict == 'accepted': + record['downstream'] = probe_assemble(global_dir / 'audit/OWNERS-AND-PROFILE.json', + work / ('out-' + name) / 'PREFIX-AND-INVOICE.json') + records.append(record) + assert sha(RETAINED) == hashlib.sha256(pristine_retained).hexdigest(), 'retained invoice unchanged' + + result = dict(status='PASS_INVOICE_MUTANT_COVERAGE', + checked_mutants=len(records), + rejected=sum(1 for r in records if r['verdict'] == 'rejected'), + accepted=sum(1 for r in records if r['verdict'] == 'accepted'), + positive=positive, + pins=dict(upstream1087=PINS['upstream1087.tar.gz'], + selected_replay=sha(FIXTURE), + invoice_allcold_py=sha(src / 'code/invoice_allcold.py'), + retained_invoice=sha(RETAINED)), + records=records) + + if a.json: + Path(a.json).write_text(json.dumps(result, indent=2) + '\n') + if a.write: + EXPECT.write_text(json.dumps(result, indent=2) + '\n') + print('WROTE', EXPECT) + else: + expected = read_json(a.expect) + assert expected == result, ('mutant census differs from receipt; rerun with --write only after ' + 'reviewing the change: ' + a.expect.name) + print(result['status'], '%d mutants: %d rejected, %d accepted' % + (result['checked_mutants'], result['rejected'], result['accepted'])) + for r in result['records']: + if r['verdict'] == 'accepted': + print(' ACCEPTED', r['name'], '->', r['downstream']) + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/research/invoice-realpath-replay/verify.py b/research/invoice-realpath-replay/verify.py new file mode 100644 index 0000000000..fcc6e4a2ee --- /dev/null +++ b/research/invoice-realpath-replay/verify.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python3 +"""Source-bound portable replay of PR2158. ywz65/Codex, Apache-2.0.""" +import argparse +from hashlib import sha256 +import json +from pathlib import Path +import subprocess +import sys +import tarfile +import tempfile +import types + +PACKAGE = Path(__file__).resolve().parent +ROOT = PACKAGE.parents[1] +REPAIR = b" work = work.resolve()\n" + + +def require(ok, message): + if not ok: + raise ValueError(message) + + +def same(a, b): + if type(a) is not type(b): + return False + if isinstance(a, dict): + return a.keys() == b.keys() and all(same(a[k], b[k]) for k in a) + if isinstance(a, list): + return len(a) == len(b) and all(same(x, y) for x, y in zip(a, b)) + return a == b + + +def load(raw): + module = types.ModuleType('invoice_alias_fixture') + module.__file__ = str(PACKAGE / 'audit.py') + exec(compile(raw, module.__file__, 'exec'), module.__dict__) + return module + + +def rejected_prepare(module, work, expected): + try: + module.prepare(work) + except AssertionError as exc: + require(str(exc) == expected, 'wrong rejection: ' + str(exc)) + else: + raise ValueError('expected preparation rejection') + + +def main(): + argparse.ArgumentParser(description=__doc__).parse_args() + require(__debug__, 'Assertions must remain enabled for the unchanged invoice') + manifest = json.loads((PACKAGE / 'SOURCES.json').read_bytes()) + for row in manifest['files'] + manifest['vendored_files']: + if row['usage'] == 'input': + require(sha256((ROOT / row['path']).read_bytes()).hexdigest() == row['sha256'], + 'source hash: ' + row['path']) + fixed = (PACKAGE / 'audit.py').read_bytes() + require(fixed.count(REPAIR) == 1, 'exact repair line') + original = fixed.replace(REPAIR, b'') + require(sha256(original).hexdigest() == manifest['derived_source']['sha256'], 'original source reconstruction') + old, repaired = load(original), load(fixed) + + with tempfile.TemporaryDirectory(prefix='invoice-alias-controls.') as name: + # Resolve the containing test root so the deliberate aliases below are + # the only difference even when the operating-system temp root is aliased. + root = Path(name).resolve() + spelling = root / 'spelling'; spelling.mkdir() + first = root / 'old'; first.mkdir() + rejected_prepare(old, spelling / '..' / 'old', 'unsafe archive member') + second = root / 'fixed'; second.mkdir() + src, fixture = repaired.prepare(spelling / '..' / 'fixed') + require(src == src.resolve() and fixture == fixture.resolve(), 'canonical returned roots') + require((src / 'code/invoice_allcold.py').is_file(), 'actual invoice extracted') + require((fixture / 'audit/PREFIX-AND-INVOICE.json').is_file(), 'actual fixture extracted') + + cases = [('../outside', tarfile.REGTYPE), + (str((root.parent / 'invoice-escape').resolve()), tarfile.REGTYPE), + ('link', tarfile.SYMTYPE), ('directory', tarfile.DIRTYPE)] + for index, (member_name, member_type) in enumerate(cases): + archive = root / ('bad-%d.tar' % index) + with tarfile.open(archive, 'w') as stream: + member = tarfile.TarInfo(member_name); member.type = member_type + if member_type == tarfile.SYMTYPE: + member.linkname = '../outside' + stream.addfile(member) + module = load(fixed); module.ARCHIVE = archive + work = root / ('bad-work-%d' % index); work.mkdir() + rejected_prepare(module, work, 'unsafe archive member') + require(not (work / 'outside').exists(), 'no traversal output') + module = load(fixed); module.FIXTURE = root / 'bad-0.tar' + work = root / 'bad-fixture'; work.mkdir() + rejected_prepare(module, work, 'unsafe fixture member') + + # The child runs the actual minimally changed audit, with its original + # assertion semantics. It retains all positive, mutation and downstream + # checks and emits the entire receipt for a separate typed comparison. + output = root / 'complete-receipt.json' + run = subprocess.run([sys.executable, '-I', '-B', str(PACKAGE / 'audit.py'), + '--json', str(output)], capture_output=True, text=True, timeout=540) + require(run.returncode == 0, run.stdout + run.stderr) + actual = json.loads(output.read_bytes()) + expected = json.loads((PACKAGE / 'EXPECTED.json').read_bytes()) + require(same(actual, expected), 'complete typed receipt mismatch') + require((actual['checked_mutants'], actual['rejected'], actual['accepted']) == (37, 31, 6), + 'declared invoice coverage') + require(all(r['downstream'].startswith('assemble_rejected') for r in actual['records'] + if r['verdict'] == 'accepted'), 'all accepted mutants rejected downstream') + print('PASS_INVOICE_REALPATH_REPLAY original_alias_rejected repaired_alias_passed ' + 'traversal_controls=5 mutants=37 invoice_rejected=31 downstream_rejected=6') + + +if __name__ == '__main__': + main()