From 90e89063ed8f9be65eaca885eeb94e27f490d6a4 Mon Sep 17 00:00:00 2001 From: Dylan Roy Date: Tue, 29 Sep 2026 19:18:08 -0500 Subject: [PATCH 1/2] Expose exact GP DATA 114 embedded source and historical receipt Decode the already-public clean wrapper as inert data. Preserve original payload identities, compressed-carrier lineage and historical status. Add hostile decoder controls; scientific effect NONE. --- .github/workflows/gpdata114-inert-custody.yml | 52 +++ .../GP-DATA-114-v1.0_receipt.json | 197 ++++++++++++ ...ATA-114-v1.0_uniform_q_degree4_interval.py | 300 ++++++++++++++++++ .../MANIFEST.json | 58 ++++ .../gp_data_114_embedded_20260930/README.md | 83 +++++ .../SOURCES.json | 70 ++++ .../VALIDATION.json | 105 ++++++ .../inert_decoder.py | 171 ++++++++++ .../test_inert_decoder.py | 136 ++++++++ 9 files changed, 1172 insertions(+) create mode 100644 .github/workflows/gpdata114-inert-custody.yml create mode 100644 imports/gp_data_114_embedded_20260930/GP-DATA-114-v1.0_receipt.json create mode 100644 imports/gp_data_114_embedded_20260930/GP-DATA-114-v1.0_uniform_q_degree4_interval.py create mode 100644 imports/gp_data_114_embedded_20260930/MANIFEST.json create mode 100644 imports/gp_data_114_embedded_20260930/README.md create mode 100644 imports/gp_data_114_embedded_20260930/SOURCES.json create mode 100644 imports/gp_data_114_embedded_20260930/VALIDATION.json create mode 100644 imports/gp_data_114_embedded_20260930/inert_decoder.py create mode 100644 imports/gp_data_114_embedded_20260930/test_inert_decoder.py diff --git a/.github/workflows/gpdata114-inert-custody.yml b/.github/workflows/gpdata114-inert-custody.yml new file mode 100644 index 000000000..2845a2b38 --- /dev/null +++ b/.github/workflows/gpdata114-inert-custody.yml @@ -0,0 +1,52 @@ +name: GP DATA 114 inert custody +'on': + pull_request: + paths: + - 'imports/gp_data_114_embedded_20260930/**' + - '.github/workflows/gpdata114-inert-custody.yml' + push: + branches: [main] + paths: + - 'imports/gp_data_114_embedded_20260930/**' + - '.github/workflows/gpdata114-inert-custody.yml' + workflow_dispatch: +permissions: + contents: read +jobs: + inert-custody: + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 + with: + persist-credentials: false + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 + with: + python-version: '3.11.16' + - name: Verify inert bytes and decoder controls only + run: | + set -euo pipefail + packet=imports/gp_data_114_embedded_20260930 + python -B -S - <<'PY' + import hashlib, json, pathlib, urllib.parse, urllib.request + packet = pathlib.Path('imports/gp_data_114_embedded_20260930') + source = json.loads((packet / 'SOURCES.json').read_text())['wrapper'] + url = 'https://raw.githubusercontent.com/' + source['repository'] + '/' + source['commit'] + '/' + urllib.parse.quote(source['path'], safe='/') + raw = urllib.request.urlopen(url, timeout=30).read(65537) + if len(raw) != source['bytes'] or hashlib.sha256(raw).hexdigest() != source['sha256']: + raise SystemExit('exact public wrapper identity mismatch') + pathlib.Path('/tmp/gpdata114-wrapper.txt').write_bytes(raw) + manifest = json.loads((packet / 'MANIFEST.json').read_text()) + for entry in manifest['files']: + data = (packet / entry['path']).read_bytes() + framed = b'blob ' + str(len(data)).encode() + b'\0' + data + if len(data) != entry['bytes'] or hashlib.sha256(data).hexdigest() != entry['sha256'] or hashlib.sha1(framed).hexdigest() != entry['git_blob']: + raise SystemExit('packet file identity mismatch: ' + entry['path']) + PY + python -B -S "$packet/inert_decoder.py" --wrapper-input /tmp/gpdata114-wrapper.txt --verify-existing "$packet" > /tmp/gpdata114-normal.json + python -B -O -S "$packet/inert_decoder.py" --wrapper-input /tmp/gpdata114-wrapper.txt --verify-existing "$packet" > /tmp/gpdata114-optimized.json + cmp /tmp/gpdata114-normal.json /tmp/gpdata114-optimized.json + python -B -S "$packet/test_inert_decoder.py" --wrapper-input /tmp/gpdata114-wrapper.txt > /tmp/gpdata114-tests-normal.json + python -B -O -S "$packet/test_inert_decoder.py" --wrapper-input /tmp/gpdata114-wrapper.txt > /tmp/gpdata114-tests-optimized.json + cmp /tmp/gpdata114-tests-normal.json /tmp/gpdata114-tests-optimized.json + git diff --exit-code diff --git a/imports/gp_data_114_embedded_20260930/GP-DATA-114-v1.0_receipt.json b/imports/gp_data_114_embedded_20260930/GP-DATA-114-v1.0_receipt.json new file mode 100644 index 000000000..77c511eaa --- /dev/null +++ b/imports/gp_data_114_embedded_20260930/GP-DATA-114-v1.0_receipt.json @@ -0,0 +1,197 @@ +{ + "box_id": "P01-UNIFORMQ-D4-BOX-001", + "explicit_exclusions": [ + "NO Gaussian or Palm mass lower bound in this source", + "NO exact-field transfer", + "NO exact full-field Palm or adjacency theorem", + "NO P0.1/P0.2/Theorem B promotion" + ], + "negative_controls": [ + { + "id": "NC1_ZERO_WIDTH", + "observed": "FULL_DIMENSIONAL_BOX_FAIL", + "pass": true, + "required": "FULL_DIMENSIONAL_BOX_FAIL" + }, + { + "id": "NC2_TYPING_DESTROYED", + "observed": [ + "saddle_det_negative_margin", + "maximum_A_negative_margin", + "maximum_det_positive_margin", + "cone_axis_margin", + "central_drift_margin", + "capture_gershgorin_margin_1" + ], + "pass": true, + "required_any_failed_gate": [ + "saddle_det_negative_margin", + "maximum_det_positive_margin" + ] + }, + { + "id": "NC3_Q_BOX_CROSSES_ZERO", + "observed": "Q_NEGATIVITY_FAIL", + "pass": true, + "required": "Q_NEGATIVITY_FAIL" + }, + { + "id": "NC4_CONE_TOO_NARROW", + "observed": [ + "cone_slope_margin", + "cone_lower_inward_margin" + ], + "pass": true, + "required_failed_gate": "cone_slope_margin" + }, + { + "id": "NC5_CAPTURE_CHART_DESTROYED", + "observed": [ + "cone_slope_margin", + "cone_upper_inward_margin", + "cone_lower_inward_margin", + "handoff_margin", + "strip_top_inward_margin", + "strip_bottom_inward_margin", + "central_drift_margin", + "chart_x_margin", + "chart_y_margin", + "capture_gershgorin_margin_1" + ], + "pass": true, + "required_any_failed_gate": [ + "chart_x_margin", + "capture_gershgorin_margin_1" + ] + } + ], + "overall": "PASS_UNIFORM_R_FIXED_Q_FULL_DIMENSIONAL_DEGREE4_INTERVAL_BOX", + "primary": { + "box": { + "a": [ + 0.0024000000000000002, + 0.0026 + ], + "c04": [ + -0.01, + 0.01 + ], + "c13": [ + -0.01, + 0.01 + ], + "c22": [ + -0.01, + 0.01 + ], + "c31": [ + -0.01, + 0.01 + ], + "c40": [ + -0.01, + 0.01 + ], + "q": [ + -1.02, + -0.98 + ], + "w": [ + -0.001, + 0.001 + ], + "z": [ + 0.99, + 1.01 + ] + }, + "derived_intervals": { + "W": [ + 0.016970562748477133, + 0.018974031961839034 + ], + "rho": [ + 0.20285955732969546, + 0.20356830685437158 + ], + "tau_upper": 6.513136004191066e-05 + }, + "failed_gates": [], + "failure_class": null, + "fixed": { + "kappa": 0.01, + "mu_interval": [ + 0.017677669529663684, + 0.01767766952966369 + ], + "q_interval": [ + -1.02, + -0.98 + ], + "r_interval": [ + 0.0, + 0.05 + ], + "s_upper_worst": -19.599999999999998, + "sigma": 0.1 + }, + "lower_bounds": { + "axial_gap_margin": 20.599395833333325, + "capture_gershgorin_margin_1": 0.589931481037461, + "capture_gershgorin_margin_2": 19.391268980780914, + "central_drift_margin": 0.08996598847018418, + "chart_x_margin": 0.04643169314562845, + "chart_y_margin": 0.7964316931456284, + "cone_axis_margin": 0.8999287018324998, + "cone_lower_inward_margin": 0.20363763551749148, + "cone_slope_margin": 0.009869737279916179, + "cone_upper_inward_margin": 0.20600236151749143, + "handoff_margin": 0.007485281374238566, + "maximum_A_negative_margin": 0.9999583333333333, + "maximum_D_negative_margin": 19.599437499999993, + "maximum_det_positive_margin": 19.59861905670138, + "partial_y_contraction_margin": 19.58039234290867, + "saddle_det_negative_margin": 19.598622198506934, + "strip_bottom_inward_margin": 0.33241853805878996, + "strip_top_inward_margin": 0.3325271710449011, + "threshold_slack": 19.562591224677412 + }, + "monotonicity_ledger": { + "affected_gates": [ + "threshold", + "endpoint typing", + "axial gap", + "cone faces", + "strip faces", + "partial-y contraction", + "capture h22" + ], + "domain": "0 float: + return float(x.a) + + +def upper(x) -> float: + return float(x.b) + + +def absmax(x) -> float: + return max(abs(lower(x)), abs(upper(x))) + + +CENTER = { + 'a': 0.0025, + 'w': 0.0, + 'z': 1.0, + 'q': -1.0, + 'c40': 0.0, + 'c31': 0.0, + 'c22': 0.0, + 'c13': 0.0, + 'c04': 0.0, +} + +RADII = { + 'a': 0.0001, + 'w': 0.001, + 'z': 0.01, + 'q': 0.02, + 'c40': 0.01, + 'c31': 0.01, + 'c22': 0.01, + 'c13': 0.01, + 'c04': 0.01, +} + +R = I('0', '0.05') +R_MAX = 0.05 +SIGMA = 0.1 +KAPPA = 0.01 +MU = 1 / (40 * iv.sqrt(I(2))) + + +def flow_x(X, Y, p): + r, a, w = R, p['a'], p['w'] + c40, c31, c22, c13 = p['c40'], p['c31'], p['c22'], p['c13'] + return ( + X**2 - I('0.25') + a*X*Y + w*Y**2/2 + + r*( + c40*(X**3-X/4)/6 + + c31*(3*X**2-I('0.25'))*Y/6 + + c22*X*Y**2/2 + + c13*Y**3/6 + ) + ) + + +def flow_y(X, Y, p): + r, a, w, z, s = R, p['a'], p['w'], p['z'], p['_s'] + c31, c22, c13, c04 = p['c31'], p['c22'], p['c13'], p['c04'] + return ( + a*(X**2-I('0.25'))/2 + s*Y + w*X*Y + z*Y**2/2 + + r*( + c31*(X**3-X/4)/6 + + c22*X**2*Y/2 + + c13*X*Y**2/2 + + c04*Y**3/6 + ) + ) + + +def hessian(X, Y, p): + r, a, w, z, s = R, p['a'], p['w'], p['z'], p['_s'] + c40, c31, c22, c13, c04 = p['c40'], p['c31'], p['c22'], p['c13'], p['c04'] + j11 = ( + 2*X + a*Y + + r*(c40*(3*X**2-I('0.25'))/6 + c31*X*Y + c22*Y**2/2) + ) + j12 = ( + a*X + w*Y + + r*( + c31*(3*X**2-I('0.25'))/6 + + c22*X*Y + + c13*Y**2/2 + ) + ) + j22 = ( + s + w*X + z*Y + + r*(c22*X**2/2 + c13*X*Y + c04*Y**2/2) + ) + return j11, j12, j22 + + +def cone_axis(xi, t, p): + # Continuous quotient xi_dot/xi after X=1/2-xi, Y=t*xi. + r, a, w = R, p['a'], p['w'] + c40, c31, c22, c13 = p['c40'], p['c31'], p['c22'], p['c13'] + return ( + 12*a*t*xi - 6*a*t + - 2*c13*r*t**3*xi**2 + + 6*c22*r*t**2*xi**2 - 3*c22*r*t**2*xi + - 6*c31*r*t*xi**2 + 6*c31*r*t*xi - c31*r*t + + 2*c40*r*xi**2 - 3*c40*r*xi + c40*r + - 6*t**2*w*xi - 12*xi + 12 + )/12 + + +def cone_y_quotient(xi, t, p): + # Continuous quotient y_dot/xi after X=1/2-xi, Y=t*xi. + r, a, w, z, s = R, p['a'], p['w'], p['z'], p['_s'] + c31, c22, c13, c04 = p['c31'], p['c22'], p['c13'], p['c04'] + return ( + 12*a*xi - 12*a + + 4*c04*r*t**3*xi**2 + - 12*c13*r*t**2*xi**2 + 6*c13*r*t**2*xi + + 12*c22*r*t*xi**2 - 12*c22*r*t*xi + 3*c22*r*t + - 4*c31*r*xi**2 + 6*c31*r*xi - 2*c31*r + + 24*s*t + 12*t**2*xi*z - 24*t*w*xi + 12*t*w + )/24 + + +def make_box(radii=None): + radii = RADII if radii is None else radii + return {k: I(CENTER[k]-radii[k], CENTER[k]+radii[k]) for k in CENTER} + + +def certify(radii=None, kappa=KAPPA): + radii = RADII if radii is None else radii + if any(radii[k] <= 0 for k in CENTER): + return {'pass': False, 'failure_class': 'FULL_DIMENSIONAL_BOX_FAIL', 'failed_gates': ['positive_width_all_coordinates']} + + p = make_box(radii) + q_hi = CENTER['q'] + radii['q'] + if not (q_hi < 0): + return {'pass': False, 'failure_class': 'Q_NEGATIVITY_FAIL', 'failed_gates': ['q_strictly_negative']} + s_worst = q_hi / R_MAX + p['_s'] = I(s_worst) + kap = I(kappa) + xi = I(0, SIGMA) + t = I(-kappa, kappa) + + F = abs(p['a'])/8 + R*abs(p['c31'])/48 + A = (abs(p['z']) + R*abs(p['c13'])/2)*F + B = R*abs(p['c04'])*F**2/2 + C = abs(p['w'])/2 + MU + R*abs(p['c22'])/8 + A/MU + B/MU**2 + W = F/MU + + AS = 1 + R*p['c40']/12 + BS = p['a']/2 + R*p['c31']/12 + DS = p['_s'] + p['w']/2 + R*p['c22']/8 + AM = -1 + R*p['c40']/12 + BM = -p['a']/2 + R*p['c31']/12 + DM = p['_s'] - p['w']/2 + R*p['c22']/8 + detS = AS*DS - BS**2 + detM = AM*DM - BM**2 + axial = AS-DS + tau_upper = float('inf') if lower(axial) <= 0 else absmax(BS)/lower(axial) + + axis = cone_axis(xi, t, p) + upper_cone = kap*cone_axis(xi, kap, p) - cone_y_quotient(xi, kap, p) + lower_cone = kap*cone_axis(xi, -kap, p) + cone_y_quotient(xi, -kap, p) + + Xc = I(-0.5+SIGMA, 0.5-SIGMA) + top = -flow_y(Xc, W, p) + bottom = flow_y(Xc, -W, p) + Ystrip = I(-upper(W), upper(W)) + drift = -flow_x(Xc, Ystrip, p) + _, _, py = hessian(Xc, Ystrip, p) + + rho = 2*iv.sqrt(I(SIGMA**2)+W**2) + rho_upper = upper(rho) + Xcap = I(-0.5-rho_upper, -0.5+rho_upper) + Ycap = I(-rho_upper, rho_upper) + h11, h12, h22 = hessian(Xcap, Ycap, p) + offdiag = absmax(h12) + + bounds = { + 'threshold_slack': lower(-p['_s']-C), + 'saddle_det_negative_margin': -upper(detS), + 'maximum_A_negative_margin': -upper(AM), + 'maximum_D_negative_margin': -upper(DM), + 'maximum_det_positive_margin': lower(detM), + 'axial_gap_margin': lower(axial), + 'cone_slope_margin': kappa-2*tau_upper, + 'cone_axis_margin': lower(axis), + 'cone_upper_inward_margin': lower(upper_cone), + 'cone_lower_inward_margin': lower(lower_cone), + 'handoff_margin': lower(W)/2-kappa*SIGMA, + 'strip_top_inward_margin': lower(top), + 'strip_bottom_inward_margin': lower(bottom), + 'central_drift_margin': lower(drift), + 'partial_y_contraction_margin': -upper(py), + 'chart_x_margin': 0.75-(0.5+rho_upper), + 'chart_y_margin': 1-rho_upper, + 'capture_gershgorin_margin_1': lower(-h11)-offdiag, + 'capture_gershgorin_margin_2': lower(-h22)-offdiag, + } + failed = [k for k,v in bounds.items() if not (v > 0)] + return { + 'pass': not failed, + 'failure_class': None if not failed else 'INTERVAL_GATE_FAIL', + 'failed_gates': failed, + 'box': {k: [CENTER[k]-radii[k], CENTER[k]+radii[k]] for k in CENTER}, + 'radii': radii, + 'fixed': {'r_interval': [0.0, R_MAX], 'q_interval': [CENTER['q']-radii['q'], CENTER['q']+radii['q']], 's_upper_worst': s_worst, 'sigma': SIGMA, 'kappa': kappa, 'mu_interval': [lower(MU), upper(MU)]}, + 'derived_intervals': {'W': [lower(W), upper(W)], 'rho': [lower(rho), upper(rho)], 'tau_upper': tau_upper}, + 'lower_bounds': bounds, + 'monotonicity_ledger': { + 'domain': '0 spec.source.bytes or inflater.unconsumed_tail: + raise ValueError("payload size exceeds declared limit") + if not inflater.eof: + raise ValueError("incomplete gzip stream") + if inflater.unused_data: + raise ValueError("trailing gzip bytes or concatenated member") + check_identity(raw, spec.source, "payload") + return raw + + +def declared(section, key): + values = re.findall(r"^" + re.escape(key) + r": ([^\r\n]+)$", section, re.MULTILINE) + if len(values) != 1: + raise ValueError(f"declared {key} count") + return values[0] + + +def decode_wrapper(raw, wrapper_identity=None): + check_identity(raw, wrapper_identity or WRAPPER_IDENTITY, "wrapper") + try: + text = raw.decode("utf-8-sig").replace("\r\n", "\n") + except UnicodeDecodeError as exc: + raise ValueError("wrapper is not UTF-8") from exc + result = {} + for spec in SPECS: + begin = f"BEGIN_{spec.label}_GZIP_BASE64" + end = f"END_{spec.label}_GZIP_BASE64" + if text.count(begin) != 1 or text.count(end) != 1: + raise ValueError("marker count must be exactly one pair per payload") + before, rest = text.split(begin) + encoded, after = rest.split(end) + if before.rfind("\n" + spec.label + "\n") == -1: + raise ValueError("missing payload declaration heading") + section = before[before.rfind("\n" + spec.label + "\n"):] + fields = (("filename", spec.source.name), ("bytes", str(spec.source.bytes)), + ("sha256", spec.source.sha256), ("gzip bytes", str(spec.gzip.bytes)), + ("gzip sha256", spec.gzip.sha256)) + for key, expected in fields: + if declared(section, key) != expected: + raise ValueError(f"declared {key} mismatch") + compact = re.sub(r"[\r\n\t ]", "", encoded) + try: + compressed = base64.b64decode(compact, validate=True) + except (binascii.Error, ValueError) as exc: + raise ValueError("invalid base64") from exc + result[spec.source.name] = decode_member(compressed, spec) + return result + + +def verify_existing(directory, decoded): + directory = Path(directory) + if directory.is_symlink(): + raise ValueError("directory symlink") + for name, raw in decoded.items(): + safe_basename(name) + path = directory / name + if path.is_symlink(): + raise ValueError("payload symlink") + if not path.is_file() or path.read_bytes() != raw: + raise ValueError(f"existing payload mismatch: {name}") + + +def report(decoded): + return {"scientific_effect": "NONE", "archived_code_executed": False, + "complete_single_gzip_member_per_payload": True, + "payloads": [{"path": name, "bytes": len(raw), + "sha256": hashlib.sha256(raw).hexdigest(), "git_blob": git_blob(raw)} + for name, raw in decoded.items()]} + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--wrapper-input", required=True, help="Exact UTF-8 wrapper file, or '-' for stdin bytes") + output = parser.add_mutually_exclusive_group(required=True) + output.add_argument("--verify-existing", type=Path, help="Verify the original two payload files") + output.add_argument("--write-new", type=Path, help="Create a NEW directory only after both payloads verify") + args = parser.parse_args() + try: + raw = sys.stdin.buffer.read(65537) if args.wrapper_input == "-" else Path(args.wrapper_input).read_bytes() + decoded = decode_wrapper(raw) + if args.verify_existing: + verify_existing(args.verify_existing, decoded) + else: + if args.write_new.is_symlink() or args.write_new.exists(): + raise ValueError("output directory must not already exist") + args.write_new.mkdir() + for name, payload in decoded.items(): + (args.write_new / name).write_bytes(payload) + print(json.dumps(report(decoded), sort_keys=True)) + return 0 + except (ValueError, OSError) as exc: + print(json.dumps({"passed": False, "error": str(exc)}, sort_keys=True), file=sys.stderr) + return 1 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/imports/gp_data_114_embedded_20260930/test_inert_decoder.py b/imports/gp_data_114_embedded_20260930/test_inert_decoder.py new file mode 100644 index 000000000..b12294300 --- /dev/null +++ b/imports/gp_data_114_embedded_20260930/test_inert_decoder.py @@ -0,0 +1,136 @@ +"""Real malformed-input controls; never import either recovered payload.""" +import argparse +import dataclasses +import gzip +import hashlib +import json +from pathlib import Path +import sys +import tempfile +import unittest + +import inert_decoder as decoder + +WRAPPER = b"" +HERE = Path(__file__).resolve().parent + + +def identity(name, raw): + return decoder.Identity(name, len(raw), hashlib.sha256(raw).hexdigest()) + + +def fixture(raw=b"nonexecutable fixture\n"): + compressed = gzip.compress(raw, mtime=0) + spec = decoder.PayloadSpec("SOURCE", identity("fixture.py", raw), + identity("fixture.gz", compressed)) + return raw, compressed, spec + + +class DecoderControls(unittest.TestCase): + def test_complete_single_member_decodes_exactly(self): + raw, compressed, spec = fixture() + self.assertEqual(decoder.decode_member(compressed, spec), raw) + + def test_truncation_rejects_even_when_compressed_identity_matches(self): + _, compressed, spec = fixture() + broken = compressed[:-1] + spec = dataclasses.replace(spec, gzip=identity("fixture.gz", broken)) + with self.assertRaisesRegex(ValueError, "incomplete gzip"): + decoder.decode_member(broken, spec) + + def test_trailing_byte_rejects_even_when_compressed_identity_matches(self): + _, compressed, spec = fixture() + broken = compressed + b"x" + spec = dataclasses.replace(spec, gzip=identity("fixture.gz", broken)) + with self.assertRaisesRegex(ValueError, "trailing gzip"): + decoder.decode_member(broken, spec) + + def test_concatenated_member_rejects(self): + _, compressed, spec = fixture() + broken = compressed + gzip.compress(b"second member", mtime=0) + spec = dataclasses.replace(spec, gzip=identity("fixture.gz", broken)) + with self.assertRaisesRegex(ValueError, "trailing gzip"): + decoder.decode_member(broken, spec) + + def test_invalid_crc_rejects(self): + _, compressed, spec = fixture() + broken = compressed[:-8] + bytes([compressed[-8] ^ 1]) + compressed[-7:] + spec = dataclasses.replace(spec, gzip=identity("fixture.gz", broken)) + with self.assertRaisesRegex(ValueError, "invalid gzip"): + decoder.decode_member(broken, spec) + + def test_payload_size_mismatch_rejects(self): + raw, compressed, spec = fixture() + spec = dataclasses.replace(spec, source=dataclasses.replace(spec.source, bytes=len(raw)+1)) + with self.assertRaisesRegex(ValueError, "payload size"): + decoder.decode_member(compressed, spec) + + def test_payload_hash_mismatch_rejects(self): + _, compressed, spec = fixture() + spec = dataclasses.replace(spec, source=dataclasses.replace(spec.source, sha256="0"*64)) + with self.assertRaisesRegex(ValueError, "payload sha256"): + decoder.decode_member(compressed, spec) + + def test_unsafe_filename_rejects(self): + _, compressed, spec = fixture() + spec = dataclasses.replace(spec, source=dataclasses.replace(spec.source, name="../fixture.py")) + with self.assertRaisesRegex(ValueError, "unsafe filename"): + decoder.decode_member(compressed, spec) + + def test_exact_public_wrapper_reconstructs_original_basename_pair(self): + decoded = decoder.decode_wrapper(WRAPPER) + self.assertEqual(set(decoded), {"GP-DATA-114-v1.0_uniform_q_degree4_interval.py", + "GP-DATA-114-v1.0_receipt.json"}) + self.assertEqual(len(decoded["GP-DATA-114-v1.0_uniform_q_degree4_interval.py"]), 9787) + self.assertEqual(len(decoded["GP-DATA-114-v1.0_receipt.json"]), 5047) + + def test_altered_wrapper_identity_rejects(self): + with self.assertRaisesRegex(ValueError, "wrapper sha256"): + decoder.decode_wrapper(WRAPPER.replace(b"ACTIVE WRAPPER", b"XCTIVE WRAPPER", 1)) + + def test_duplicate_marker_rejects_after_rebinding_wrapper_fixture(self): + broken = WRAPPER.replace(b"BEGIN_SOURCE_GZIP_BASE64", b"BEGIN_SOURCE_GZIP_BASE64\r\nBEGIN_SOURCE_GZIP_BASE64", 1) + with self.assertRaisesRegex(ValueError, "marker count"): + decoder.decode_wrapper(broken, identity("wrapper.txt", broken)) + + def test_declared_compressed_size_rejects_after_rebinding_wrapper_fixture(self): + broken = WRAPPER.replace(b"gzip bytes: 3416", b"gzip bytes: 3417", 1) + with self.assertRaisesRegex(ValueError, "declared gzip bytes"): + decoder.decode_wrapper(broken, identity("wrapper.txt", broken)) + + def test_invalid_base64_rejects_after_rebinding_wrapper_fixture(self): + broken = WRAPPER.replace(b"BEGIN_SOURCE_GZIP_BASE64\r\nH", b"BEGIN_SOURCE_GZIP_BASE64\r\n!", 1) + with self.assertRaisesRegex(ValueError, "invalid base64"): + decoder.decode_wrapper(broken, identity("wrapper.txt", broken)) + + def test_changed_existing_payload_rejects(self): + decoded = decoder.decode_wrapper(WRAPPER) + with tempfile.TemporaryDirectory(prefix="controls_", dir=HERE) as directory: + for name, raw in decoded.items(): + Path(directory, name).write_bytes(raw) + Path(directory, "GP-DATA-114-v1.0_receipt.json").write_bytes(b"altered") + with self.assertRaisesRegex(ValueError, "existing payload"): + decoder.verify_existing(Path(directory), decoded) + + def test_existing_payload_symlink_rejects(self): + decoded = decoder.decode_wrapper(WRAPPER) + self.assertIn("GP-DATA-114-v1.0_receipt.json", decoded) + with tempfile.TemporaryDirectory(prefix="controls_", dir=HERE) as directory: + for name, raw in decoded.items(): + Path(directory, name).write_bytes(raw) + leaf = Path(directory, "GP-DATA-114-v1.0_receipt.json") + leaf.unlink() + leaf.symlink_to("GP-DATA-114-v1.0_uniform_q_degree4_interval.py") + with self.assertRaisesRegex(ValueError, "symlink"): + decoder.verify_existing(Path(directory), decoded) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("--wrapper-input", required=True, help="Exact UTF-8 wrapper file, or '-' for stdin bytes") + args = parser.parse_args() + WRAPPER = sys.stdin.buffer.read() if args.wrapper_input == "-" else Path(args.wrapper_input).read_bytes() + result = unittest.TextTestRunner(verbosity=2).run(unittest.defaultTestLoader.loadTestsFromTestCase(DecoderControls)) + print(json.dumps({"tests_run": result.testsRun, "failures": len(result.failures), + "errors": len(result.errors), "passed": result.wasSuccessful()}, sort_keys=True)) + sys.exit(0 if result.wasSuccessful() else 1) From e0b1b2eb257e2da8ebd63cc920e5c5dbe4efc9ff Mon Sep 17 00:00:00 2001 From: Dylan Roy Date: Tue, 29 Sep 2026 19:33:09 -0500 Subject: [PATCH 2/2] Repair exact packet membership and published payload lineage checks Preserve both original GP-DATA-114 payload blobs. Add targeted failure controls and bind SOURCES metadata to pinned decoded originals; scientific effect NONE. --- .github/workflows/gpdata114-inert-custody.yml | 12 +- .../MANIFEST.json | 26 ++- .../gp_data_114_embedded_20260930/README.md | 13 ++ .../VALIDATION.json | 50 ++++- .../test_verify_packet.py | 188 ++++++++++++++++++ .../verify_packet.py | 157 +++++++++++++++ 6 files changed, 431 insertions(+), 15 deletions(-) create mode 100644 imports/gp_data_114_embedded_20260930/test_verify_packet.py create mode 100644 imports/gp_data_114_embedded_20260930/verify_packet.py diff --git a/.github/workflows/gpdata114-inert-custody.yml b/.github/workflows/gpdata114-inert-custody.yml index 2845a2b38..c0b665b88 100644 --- a/.github/workflows/gpdata114-inert-custody.yml +++ b/.github/workflows/gpdata114-inert-custody.yml @@ -36,13 +36,13 @@ jobs: if len(raw) != source['bytes'] or hashlib.sha256(raw).hexdigest() != source['sha256']: raise SystemExit('exact public wrapper identity mismatch') pathlib.Path('/tmp/gpdata114-wrapper.txt').write_bytes(raw) - manifest = json.loads((packet / 'MANIFEST.json').read_text()) - for entry in manifest['files']: - data = (packet / entry['path']).read_bytes() - framed = b'blob ' + str(len(data)).encode() + b'\0' + data - if len(data) != entry['bytes'] or hashlib.sha256(data).hexdigest() != entry['sha256'] or hashlib.sha1(framed).hexdigest() != entry['git_blob']: - raise SystemExit('packet file identity mismatch: ' + entry['path']) PY + python -B -S "$packet/verify_packet.py" --packet "$packet" --wrapper-input /tmp/gpdata114-wrapper.txt > /tmp/gpdata114-packet-normal.json + python -B -O -S "$packet/verify_packet.py" --packet "$packet" --wrapper-input /tmp/gpdata114-wrapper.txt > /tmp/gpdata114-packet-optimized.json + cmp /tmp/gpdata114-packet-normal.json /tmp/gpdata114-packet-optimized.json + python -B -S "$packet/test_verify_packet.py" --wrapper-input /tmp/gpdata114-wrapper.txt > /tmp/gpdata114-packet-tests-normal.json + python -B -O -S "$packet/test_verify_packet.py" --wrapper-input /tmp/gpdata114-wrapper.txt > /tmp/gpdata114-packet-tests-optimized.json + cmp /tmp/gpdata114-packet-tests-normal.json /tmp/gpdata114-packet-tests-optimized.json python -B -S "$packet/inert_decoder.py" --wrapper-input /tmp/gpdata114-wrapper.txt --verify-existing "$packet" > /tmp/gpdata114-normal.json python -B -O -S "$packet/inert_decoder.py" --wrapper-input /tmp/gpdata114-wrapper.txt --verify-existing "$packet" > /tmp/gpdata114-optimized.json cmp /tmp/gpdata114-normal.json /tmp/gpdata114-optimized.json diff --git a/imports/gp_data_114_embedded_20260930/MANIFEST.json b/imports/gp_data_114_embedded_20260930/MANIFEST.json index 6c6c5bffb..c21f10d61 100644 --- a/imports/gp_data_114_embedded_20260930/MANIFEST.json +++ b/imports/gp_data_114_embedded_20260930/MANIFEST.json @@ -16,11 +16,11 @@ "sha256": "9d7cb5d6e13579533c5b485775e67c77da83c149c0bf8bbbe7b7bf85aefdb4ef" }, { - "bytes": 4824, - "git_blob": "a10edfb259432bfc569afdbef161ddcd4719f8f6", + "bytes": 5754, + "git_blob": "410f7a4a0598e093e8458ec6fa8f8aec14657f19", "path": "README.md", "role": "NEW_CUSTODY_CODE_OR_RECORD", - "sha256": "5563293f379a380a044e36ab81d50433460b517a8344307bd409ec375a7fbf79" + "sha256": "7139b03d1e6263107aa43f4559457eb4e9f59b318a89266457973c5b30c6599a" }, { "bytes": 3819, @@ -30,11 +30,11 @@ "sha256": "4c28b3fa16ba607ef675276d263add69354d9583b891174f2e1a75742cafac37" }, { - "bytes": 4125, - "git_blob": "73b3e18c756f299258c736700b8b2050eebbe3f1", + "bytes": 5698, + "git_blob": "4786a22aac19b28cfd008f6d4f90e1a0d0e2d58b", "path": "VALIDATION.json", "role": "NEW_CUSTODY_CODE_OR_RECORD", - "sha256": "5f1d1b69eabfb30570e2f24e7be79f89e3ede3b1ee2ecac73e76a8b84aef7e74" + "sha256": "04195d5e5b2f68b46af02c65d1b26be353525f9bf9e9795ade50af3c7cf5ca74" }, { "bytes": 6590, @@ -49,6 +49,20 @@ "path": "test_inert_decoder.py", "role": "NEW_CUSTODY_CODE_OR_RECORD", "sha256": "4966503339c8ae6de674f57f97d514c4068b134af3b1fcf97710d34e444eed42" + }, + { + "bytes": 9588, + "git_blob": "45b2c48d43065365d2049dc21c274afae9e1694c", + "path": "test_verify_packet.py", + "role": "NEW_CUSTODY_CODE_OR_RECORD", + "sha256": "7c2796dd9442b95ab3320d826a9cd8700e3474580b875b63e31cac08d425ef46" + }, + { + "bytes": 6999, + "git_blob": "3b933da10745f58821ccea239263c2a941b92947", + "path": "verify_packet.py", + "role": "NEW_CUSTODY_CODE_OR_RECORD", + "sha256": "f4aecd8163e77bfb9ed66c77f64f81cd9e4017bbc338a879d562b1f18ea3de51" } ], "manifest_self_excluded": true, diff --git a/imports/gp_data_114_embedded_20260930/README.md b/imports/gp_data_114_embedded_20260930/README.md index a10edfb25..410f7a4a0 100644 --- a/imports/gp_data_114_embedded_20260930/README.md +++ b/imports/gp_data_114_embedded_20260930/README.md @@ -41,6 +41,10 @@ separate temporary file, preserving BOM, CRLF and all bytes. From this directory python -B -S inert_decoder.py --wrapper-input /path/to/exact-wrapper.txt --verify-existing . python -B -S test_inert_decoder.py --wrapper-input /path/to/exact-wrapper.txt python -B -O -S test_inert_decoder.py --wrapper-input /path/to/exact-wrapper.txt +python -B -S verify_packet.py --packet . --wrapper-input /path/to/exact-wrapper.txt +python -B -O -S verify_packet.py --packet . --wrapper-input /path/to/exact-wrapper.txt +python -B -S test_verify_packet.py --wrapper-input /path/to/exact-wrapper.txt +python -B -O -S test_verify_packet.py --wrapper-input /path/to/exact-wrapper.txt ``` `--wrapper-input -` accepts exact bytes on stdin. To reproduce the two files in @@ -60,6 +64,15 @@ itself. Test-first failures and all verification boundaries are retained in [VALIDATION.json](VALIDATION.json). [MANIFEST.json](MANIFEST.json) binds every packet file except itself; its exclusion avoids self-reference. +The successor whole-packet verifier requires the exact directory set declared +by the manifest, rejects duplicate or unsafe paths and symlinks, and checks +sizes, SHA256 and Git blobs. It also binds every published payload identity in +SOURCES.json to the decoder's fixed specifications, decoded originals and +manifest. Re-signing a manifest cannot authorize a false payload identity. +Twelve additional controls include an undeclared file and falsified SOURCES +metadata with a re-signed manifest. These repair two actual PR review findings; +the original source and saved receipt remain byte-identical. + ## Historical scope and limits The source header describes an outward interval certificate for a degree-four diff --git a/imports/gp_data_114_embedded_20260930/VALIDATION.json b/imports/gp_data_114_embedded_20260930/VALIDATION.json index 73b3e18c7..4786a22aa 100644 --- a/imports/gp_data_114_embedded_20260930/VALIDATION.json +++ b/imports/gp_data_114_embedded_20260930/VALIDATION.json @@ -3,7 +3,7 @@ "object": "OA-GP-DATA-114-EMBEDDED-CUSTODY-20260930-v1", "scientific_effect": "NONE", "verification_context_date": "2026-09-30", - "verification_scope": "New standard-library custody decoder and tests, exact public wrapper and original payload identities only", + "verification_scope": "New standard-library custody decoder, whole-packet verifier and tests; exact public wrapper and original payload identities only", "archive_execution": { "source_executed": false, "source_imported": false, @@ -67,12 +67,45 @@ "stage": "initial packet manifest generation", "exit_code": 1, "outcome": "Final readback rejected a generated manifest with a literal backslash-n terminator; its generator also used literal backslash-zero instead of the NUL byte in Git framing. Both transient metadata defects were corrected with explicit byte/newline construction. Original payload bytes were unchanged. The final verifier checks known payload Git identities and every manifest identity." + }, + { + "stage": "actual PR review of initial workflow", + "outcome": "Two valid P2 findings: an undeclared file escaped the manifest loop; falsified SOURCES.payload metadata escaped after its manifest entry was re-signed. Original archived bytes were unaffected.", + "review_comments": [ + 4139634150, + 4139634156 + ] + }, + { + "stage": "whole-packet verifier test-first legacy reproduction", + "tests_run": 2, + "failures": 2, + "errors": 0, + "exit_code": 1, + "outcome": "Both targeted rejection assertions failed with ValueError not raised before replacing the legacy checker." + }, + { + "stage": "successor whole-packet verifier controls", + "mode": "python -B -S", + "tests_run": 12, + "failures": 0, + "errors": 0, + "exit_code": 0 + }, + { + "stage": "successor whole-packet verifier controls", + "mode": "python -B -O -S", + "tests_run": 12, + "failures": 0, + "errors": 0, + "exit_code": 0 } ], "paired_output": { "test_json_stdout_identical": true, "original_file_verification_stdout_identical": true, - "unittest_timing_and_stderr_are_not_byte_identity_claims": true + "unittest_timing_and_stderr_are_not_byte_identity_claims": true, + "whole_packet_test_json_stdout_identical": true }, "failure_controls": [ "incomplete gzip with rebound compressed identity", @@ -87,7 +120,18 @@ "wrong declared gzip size after rebinding wrapper fixture", "invalid base64 after rebinding wrapper fixture", "changed existing receipt bytes", - "existing receipt symlink" + "existing receipt symlink", + "undeclared packet file", + "duplicate manifest path", + "missing declared file", + "unsafe manifest path", + "packet directory or file symlink", + "nonfile directory entry", + "false SOURCES payload identity after manifest re-signing", + "jointly re-signed changed archived bytes, SOURCES and manifest", + "changed packet data or identity fields", + "duplicate or missing SOURCES payloads", + "CLI rejection exit one in normal and optimized modes" ], "baseline_controls": [ "complete single fixture gzip decodes to exact inert bytes", diff --git a/imports/gp_data_114_embedded_20260930/test_verify_packet.py b/imports/gp_data_114_embedded_20260930/test_verify_packet.py new file mode 100644 index 000000000..45b2c48d4 --- /dev/null +++ b/imports/gp_data_114_embedded_20260930/test_verify_packet.py @@ -0,0 +1,188 @@ +"""Packet-boundary controls; archived Python is copied and read as bytes only.""" +import argparse +import hashlib +import json +from pathlib import Path +import shutil +import subprocess +import sys +import tempfile +import unittest + +import verify_packet as verifier + +HERE = Path(__file__).resolve().parent +ORIGINAL_FILES = ( + 'GP-DATA-114-v1.0_receipt.json', + 'GP-DATA-114-v1.0_uniform_q_degree4_interval.py', + 'MANIFEST.json', 'README.md', 'SOURCES.json', 'VALIDATION.json', + 'inert_decoder.py', 'test_inert_decoder.py', +) +WRAPPER_RAW = None + + +class PacketControls(unittest.TestCase): + def setUp(self): + self.temporary = tempfile.TemporaryDirectory(prefix='gpdata114_packet_') + self.addCleanup(self.temporary.cleanup) + self.directory = Path(self.temporary.name) / 'packet' + self.directory.mkdir() + for name in ORIGINAL_FILES: + shutil.copyfile(HERE / name, self.directory / name) + self.resign_manifest() + self.wrapper = WRAPPER_RAW if WRAPPER_RAW is not None else Path('/tmp/gpdata114-public-wrapper.txt').read_bytes() + + def resign_manifest(self): + manifest = json.loads((self.directory / 'MANIFEST.json').read_text()) + entries = [] + for name in ORIGINAL_FILES: + if name == 'MANIFEST.json': + continue + data = (self.directory / name).read_bytes() + framed = b'blob ' + str(len(data)).encode() + b'\0' + data + entries.append({'path': name, 'bytes': len(data), + 'sha256': hashlib.sha256(data).hexdigest(), + 'git_blob': hashlib.sha1(framed).hexdigest()}) + manifest['files'] = entries + (self.directory / 'MANIFEST.json').write_text(json.dumps(manifest, sort_keys=True)) + + def test_reject_undeclared_packet_file(self): + (self.directory / 'undeclared.py').write_bytes(b'inert unexpected bytes\n') + with self.assertRaisesRegex(ValueError, 'file set'): + verifier.verify_packet(self.directory, self.wrapper) + + def test_reject_false_sources_identity_after_manifest_resigning(self): + original = (self.directory / 'SOURCES.json').read_text() + wrong_values = {'label': 'OTHER', 'path': 'wrong.py', 'bytes': 9788, + 'sha256': '0' * 64, 'git_blob': '0' * 40, + 'gzip_bytes': 3417, 'gzip_sha256': '0' * 64} + for field, value in wrong_values.items(): + with self.subTest(field=field): + sources = json.loads(original) + sources['payloads'][0][field] = value + (self.directory / 'SOURCES.json').write_text(json.dumps(sources, sort_keys=True)) + self.resign_manifest() + with self.assertRaisesRegex(ValueError, 'SOURCES payload'): + verifier.verify_packet(self.directory, self.wrapper) + + def test_known_eight_file_fixture_passes(self): + report = verifier.verify_packet(self.directory, self.wrapper) + self.assertTrue(report['passed']) + self.assertEqual(report['packet_files'], 8) + self.assertEqual(report['manifest_entries'], 7) + self.assertEqual(report['sources_payload_bindings'], 2) + self.assertEqual(report['scientific_effect'], 'NONE') + self.assertFalse(report['archived_code_executed']) + + def test_reject_duplicate_manifest_path(self): + manifest = json.loads((self.directory / 'MANIFEST.json').read_text()) + manifest['files'].append(dict(manifest['files'][0])) + (self.directory / 'MANIFEST.json').write_text(json.dumps(manifest)) + with self.assertRaisesRegex(ValueError, 'duplicate manifest path'): + verifier.verify_packet(self.directory, self.wrapper) + + def test_reject_missing_declared_file(self): + (self.directory / 'README.md').unlink() + with self.assertRaisesRegex(ValueError, 'file set'): + verifier.verify_packet(self.directory, self.wrapper) + + def test_reject_unsafe_manifest_paths_before_reading(self): + original = (self.directory / 'MANIFEST.json').read_text() + for path in ('../README.md', 'nested/file', '/absolute', '\\absolute', '.', '..', '', 'bad\0name', 'MANIFEST.json'): + with self.subTest(path=path): + manifest = json.loads(original) + manifest['files'][0]['path'] = path + (self.directory / 'MANIFEST.json').write_text(json.dumps(manifest)) + with self.assertRaisesRegex(ValueError, 'unsafe manifest path'): + verifier.verify_packet(self.directory, self.wrapper) + + def test_reject_file_and_directory_symlinks(self): + leaf = self.directory / 'README.md' + leaf.unlink() + leaf.symlink_to('SOURCES.json') + with self.assertRaisesRegex(ValueError, 'symlink'): + verifier.verify_packet(self.directory, self.wrapper) + link = self.directory.parent / 'linked-packet' + link.symlink_to(self.directory, target_is_directory=True) + with self.assertRaisesRegex(ValueError, 'symlink'): + verifier.verify_packet(link, self.wrapper) + + def test_reject_nonfile_directory_entry(self): + leaf = self.directory / 'README.md' + leaf.unlink() + leaf.mkdir() + with self.assertRaisesRegex(ValueError, 'regular file'): + verifier.verify_packet(self.directory, self.wrapper) + + def test_reject_changed_data_and_each_manifest_identity_field(self): + readme = self.directory / 'README.md' + original_bytes = readme.read_bytes() + readme.write_bytes(original_bytes + b'changed') + with self.assertRaisesRegex(ValueError, 'packet file identity'): + verifier.verify_packet(self.directory, self.wrapper) + readme.write_bytes(original_bytes) + original_manifest = (self.directory / 'MANIFEST.json').read_text() + for field, value in (('bytes', -1), ('sha256', '0' * 64), ('git_blob', '0' * 40)): + with self.subTest(field=field): + manifest = json.loads(original_manifest) + entry = next(item for item in manifest['files'] if item['path'] == 'README.md') + entry[field] = value + (self.directory / 'MANIFEST.json').write_text(json.dumps(manifest)) + with self.assertRaisesRegex(ValueError, 'packet file identity'): + verifier.verify_packet(self.directory, self.wrapper) + + def test_reject_duplicate_and_missing_sources_payloads(self): + original = (self.directory / 'SOURCES.json').read_text() + for variant in ('duplicate', 'missing'): + with self.subTest(variant=variant): + sources = json.loads(original) + payloads = sources['payloads'] + sources['payloads'] = [payloads[0], payloads[0]] if variant == 'duplicate' else payloads[:1] + (self.directory / 'SOURCES.json').write_text(json.dumps(sources)) + self.resign_manifest() + with self.assertRaisesRegex(ValueError, 'SOURCES payload'): + verifier.verify_packet(self.directory, self.wrapper) + + def test_reject_jointly_resigned_archived_bytes_and_sources(self): + name = 'GP-DATA-114-v1.0_uniform_q_degree4_interval.py' + payload = self.directory / name + changed = payload.read_bytes() + b'\n' + payload.write_bytes(changed) + sources = json.loads((self.directory / 'SOURCES.json').read_text()) + source = sources['payloads'][0] + source['bytes'] = len(changed) + source['sha256'] = hashlib.sha256(changed).hexdigest() + source['git_blob'] = hashlib.sha1(b'blob ' + str(len(changed)).encode() + b'\0' + changed).hexdigest() + (self.directory / 'SOURCES.json').write_text(json.dumps(sources)) + self.resign_manifest() + with self.assertRaisesRegex(ValueError, 'SOURCES payload'): + verifier.verify_packet(self.directory, self.wrapper) + + def test_cli_failure_exits_one_and_matches_in_both_modes(self): + (self.directory / 'undeclared.txt').write_bytes(b'extra') + wrapper_path = self.directory.parent / 'wrapper.txt' + wrapper_path.write_bytes(self.wrapper) + outputs = [] + for flags in (('-B', '-S'), ('-B', '-O', '-S')): + command = [sys.executable, *flags, str(HERE / 'verify_packet.py'), + '--packet', str(self.directory), '--wrapper-input', str(wrapper_path)] + result = subprocess.run(command, capture_output=True, text=True) + self.assertEqual(result.returncode, 1) + summary = json.loads(result.stdout) + self.assertFalse(summary['passed']) + self.assertIn('file set', summary['error']) + self.assertEqual(summary['scientific_effect'], 'NONE') + outputs.append(result.stdout) + self.assertEqual(*outputs) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--wrapper-input', default='/tmp/gpdata114-public-wrapper.txt') + args = parser.parse_args() + WRAPPER_RAW = Path(args.wrapper_input).read_bytes() + result = unittest.TextTestRunner(verbosity=2).run(unittest.defaultTestLoader.loadTestsFromTestCase(PacketControls)) + print(json.dumps({'tests_run': result.testsRun, 'failures': len(result.failures), + 'errors': len(result.errors), 'passed': result.wasSuccessful(), + 'scientific_effect': 'NONE', 'archived_code_executed': False}, sort_keys=True)) + sys.exit(0 if result.wasSuccessful() else 1) diff --git a/imports/gp_data_114_embedded_20260930/verify_packet.py b/imports/gp_data_114_embedded_20260930/verify_packet.py new file mode 100644 index 000000000..3b933da10 --- /dev/null +++ b/imports/gp_data_114_embedded_20260930/verify_packet.py @@ -0,0 +1,157 @@ +"""Verify exact packet custody; never execute, import or compile archived code. + +Only the new inert_decoder module is imported. Both recovered payloads, +including the archived .py file, are handled solely as bytes. A re-signed +manifest cannot override the decoder's independent original payload pins. +This verifier supplies custody checks, not mathematical or status acceptance. +""" +import argparse +import hashlib +import json +from pathlib import Path +import sys + +import inert_decoder as decoder + +MANIFEST = 'MANIFEST.json' +DEFAULT_WRAPPER = '/tmp/gpdata114-public-wrapper.txt' + + +def require(condition, message): + if not condition: + raise ValueError(message) + + +def unique_object(pairs): + result = {} + for key, value in pairs: + require(key not in result, 'duplicate JSON key: ' + key) + result[key] = value + return result + + +def load_record(raw, context): + value = json.loads(raw, object_pairs_hook=unique_object) + require(isinstance(value, dict), context + ' must be a JSON object') + return value + + +def safe_manifest_path(name): + require(isinstance(name, str) and name and name not in {'.', '..', MANIFEST} + and not any(c in name for c in '/\\\0'), 'unsafe manifest path') + + +def identity(raw): + framed = b'blob ' + str(len(raw)).encode('ascii') + b'\0' + raw + return {'bytes': len(raw), 'sha256': hashlib.sha256(raw).hexdigest(), + 'git_blob': hashlib.sha1(framed).hexdigest()} + + +def exact_field(record, field, expected, context): + actual = record.get(field) + require(type(actual) is type(expected) and actual == expected, + context + ': ' + field) + + +def verify_packet(directory, wrapper_raw): + directory = Path(directory) + require(not directory.is_symlink(), 'packet directory symlink') + require(directory.is_dir(), 'packet must be a directory') + observed = {} + for path in directory.iterdir(): + require(not path.is_symlink(), 'packet file symlink: ' + path.name) + require(path.is_file(), 'packet entry must be a regular file: ' + path.name) + observed[path.name] = path + require(MANIFEST in observed, 'packet file set missing MANIFEST.json') + manifest = load_record(observed[MANIFEST].read_bytes(), 'manifest') + require(manifest.get('manifest_self_excluded') is True, 'manifest self-exclusion required') + require(isinstance(manifest.get('files'), list), 'manifest files must be a list') + entries = {} + for entry in manifest['files']: + require(isinstance(entry, dict), 'manifest entry must be an object') + name = entry.get('path') + safe_manifest_path(name) + require(name not in entries, 'duplicate manifest path: ' + name) + entries[name] = entry + expected_names = set(entries) | {MANIFEST} + actual_names = set(observed) + require(actual_names == expected_names, + 'packet file set mismatch: extra=' + ','.join(sorted(actual_names - expected_names)) + + ' missing=' + ','.join(sorted(expected_names - actual_names))) + + stored = {} + for name, entry in entries.items(): + data = observed[name].read_bytes() + for field, expected in identity(data).items(): + exact_field(entry, field, expected, 'packet file identity mismatch: ' + name) + stored[name] = data + + require('SOURCES.json' in stored, 'SOURCES record missing from manifest') + sources = load_record(stored['SOURCES.json'], 'SOURCES') + payloads = sources.get('payloads') + require(isinstance(payloads, list) and len(payloads) == len(decoder.SPECS), + 'SOURCES payload list must contain exactly the canonical pair') + source_entries = {} + for payload in payloads: + require(isinstance(payload, dict), 'SOURCES payload must be an object') + label = payload.get('label') + require(isinstance(label, str) and label not in source_entries, + 'SOURCES payload duplicate or invalid label') + source_entries[label] = payload + require(set(source_entries) == {spec.label for spec in decoder.SPECS}, + 'SOURCES payload labels differ from canonical pair') + + require(isinstance(wrapper_raw, bytes), 'wrapper input must be exact bytes') + decoded = decoder.decode_wrapper(wrapper_raw) + wrapper = sources.get('wrapper') + require(isinstance(wrapper, dict), 'SOURCES wrapper must be an object') + wrapper_pin = decoder.WRAPPER_IDENTITY + for field, expected in (('bytes', wrapper_pin.bytes), ('sha256', wrapper_pin.sha256), + ('git_blob', wrapper_pin.blob)): + exact_field(wrapper, field, expected, 'SOURCES wrapper identity mismatch') + + for spec in decoder.SPECS: + payload = source_entries[spec.label] + expected_fields = { + 'label': spec.label, 'path': spec.source.name, 'bytes': spec.source.bytes, + 'sha256': spec.source.sha256, 'git_blob': spec.source.blob, + 'gzip_bytes': spec.gzip.bytes, 'gzip_sha256': spec.gzip.sha256, + } + for field, expected in expected_fields.items(): + exact_field(payload, field, expected, 'SOURCES payload identity mismatch: ' + spec.label) + require(spec.source.name in entries, 'payload missing from manifest: ' + spec.label) + # decode_wrapper already binds each compressed member, its declarations, + # and decoded bytes to SPECS. Bind the resulting raw identity again to + # both independently pinned SPECS and the two packet metadata records. + for field, actual in identity(decoded[spec.source.name]).items(): + exact_field(payload, field, actual, 'SOURCES payload decoded identity mismatch: ' + spec.label) + exact_field(entries[spec.source.name], field, actual, 'manifest decoded payload identity mismatch: ' + spec.label) + decoder.verify_existing(directory, decoded) + report = decoder.report(decoded) + report.update({'passed': True, 'packet_files': len(observed), + 'manifest_entries': len(entries), 'sources_payload_bindings': len(source_entries), + 'archived_code_imported': False, 'archived_code_compiled': False}) + return report + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--packet', type=Path, default=Path(__file__).resolve().parent) + parser.add_argument('--wrapper-input', type=Path, default=Path(DEFAULT_WRAPPER)) + args = parser.parse_args() + try: + with args.wrapper_input.open('rb') as stream: + wrapper_raw = stream.read(65537) + report = verify_packet(args.packet, wrapper_raw) + exit_code = 0 + except (OSError, ValueError) as exc: + report = {'passed': False, 'error': str(exc), 'scientific_effect': 'NONE', + 'archived_code_executed': False, 'archived_code_imported': False, + 'archived_code_compiled': False} + exit_code = 1 + print(json.dumps(report, sort_keys=True)) + return exit_code + + +if __name__ == '__main__': + sys.exit(main())