Repository navigation
Port decoded legacy statement validation (3f-2a) - #122
Merged
Merged
Conversation
Contributor
Author
|
U04 exposure audit: PASS at exact head
Signed: Janitor ( Posted on behalf of @schickling
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
3f-2a ports the decoded-statement structural guard from statement_of. The owned legacy Value API retains unknown fields, integer lexemes and empty string argv entries. It validates subject/digest shape, both predicate URIs, schema-version Python equality (including true and 1.0), change/tier/signer/observed/check/input fields, lowercase OIDs/digests, integer-only exit codes and timezone-aware ISO timestamps. Python whitespace includes U+001C..U+001F. Clock validation covers basic/extended calendar and ISO-week dates, arbitrary one-character date/time separators, partial times, comma/dot fractions and fractional-second offsets. Candidate validity grants no signer trust.
Python source lines ported
Pinned oracle cff667c (v0.6.0), scripts/evidence-verify 637-665, with the parse_time zoned-time condition at 655-657. The source file is unchanged. README and PROVENANCE record the boundary.
Split plan
The complete byte-oriented statement_of needs a further 3f-2b slice: Python-compatible JSON byte decoding at 635-636 and exception handling at 666-667. This includes UTF-16/32/BOM handling, NaN/Infinity, lone surrogates, recursion and integer conversion limits. The existing shared Rust JSON decoder deliberately has narrower limits; this change does NOT silently substitute that decoder for Python's loader. The public guard takes a decoded Value, not bytes. Tests use the existing parser only to construct ordinary-JSON fixture values.
The decoded guard plus its differential matrix uses almost the entire 280-line cap; adding a correct byte decoder and its distinct fixtures cannot fit here. After 3f-2b, 3f-3 ports read_statement/load and the owned cache; signature integration, 3g selection and 3h require_all follow. CLI/native behavior remains unchanged. The projection OID/end-of-options and input_git output-bound Janitor P3s do not touch this code and remain the next focused hardening slice before wiring.
Differential tests
legacy_statement_shapes_match_oracle compares the public structural guard with unchanged statement_of on ordinary JSON: valid/missing/wrong fields; schema boolean/float distinctions; both predicate URIs; subject/digest shape; whitespace; tier and signer types; runner/input/check/argv/hash types; empty checks/argv strings; integer/float/bool exits and 100/4300/4301-digit integers; calendar/week/basic dates, arbitrary Unicode separators, zones, comma and submicrosecond fractions, offset seconds/normalization, naive timestamps, bad dates/hours/year/offsets. It checks a retained change_id in returned data; empty argv strings remain exercised by the accepted baseline and matrix. Rust differential tests have not run locally; hosted failure corrections are recorded below.
Evidence
On dev3, pinned rustfmt 1.9.0 from /nix/store/jpcqlbhkwxwvq507mq0hkacpxbxcdwjj-rustfmt-1.98.1 (nixpkgs 4ba99f3209788ed04f01af38f77ddb803ad6ec63) formatted the changed Rust files with repo rustfmt.toml. A subsequent rustfmt --check --config-path rustfmt.toml on statement.rs, statement_tests.rs and legacy_verify.rs exited 0.
On dev5, prepared the pinned shell with:
gate-slot --class eval --max-wait 1800 --max-hold 600 -- nix develop --override-input fractal-fixture path:/var/tmp/mergemaster-port3f-fractal --no-write-lock-file --profile /var/tmp/mergemaster-statement-shell --command true
This admitted after 1618s and exited 0. The override source is the exact e2721e52 Git archive transferred in 3f-1; Python oracles retain their pinned store paths.
Attempted all requested checks through a Python runner importing the shell profile's exported environment, with CARGO_TARGET_DIR=/var/tmp/mergemaster-statement-target:
gate-slot --lane build --profile disk=cargo-cold --max-wait 1800 -- python3 /var/tmp/mergemaster-statement-verify.py
Build admission never occurred (38 initially ahead); gate-slot withdrew with max-wait exit 94 at 2026-11-10T18:37:50Z. No runner command or Cargo process executed. Stopped remote attempts at the required 30-minute build-admission ceiling. No Cargo targets were created under ~/.megarepo.
NOT RUN
CI review correction
Chrono validates calendar values only after an exact ASCII date-shape check:
YYYY-MM-DD, YYYYMMDD, YYYY-Www[-D] or YYYYWww[D]. This rejects Chrono's otherwise
permitted short/signed/space-prefixed numeric fields before parsing. The differential
matrix now includes all four reported failures (2026-1-1T12:00Z, 2026-W1T12Z,
26-01-01T12Z, 2026- 1-01T12Z), plus an explicit 2026-01-01T24:00Z case alongside
the existing T24Z case. No broadening of the accepted timestamp grammar is intended.
OID parity: evidence/mod.rs:213-221 requires byte length 40 or 64 and every byte
to be ASCII 0-9/a-f. This is exactly Python's full lowercase OID regex, including
its strict end anchor (LF/CR/trailing bytes fail). Existing gate integration tests
legacy_tree_record_indexes_match_real_oracle exercise SHA-1/SHA-256, uppercase
and newline refusals through this helper; legacy_input_indexes_and_note_presence_match_real_oracle
also covers uppercase and 39/64-character input keys. There is no claimed standalone oid unit test.
Pinned CI Python: flake.nix's evidence check uses pkgs.python3 from nixpkgs
4ba99f3209788ed04f01af38f77ddb803ad6ec63; the prepared shell uses that same
interpreter with packages. Its executable
/nix/store/6cg92xlgwwwl88fiwrid0l924fmy8slp-python3-3.14.7-env/bin/python3
reported Python 3.14.7 on dev5. Calendar/week and 24:00 expectations come from
the oracle under this pinned interpreter, not the host's ambient Python.
Pinned local rustfmt formatting and --check passed again after the correction.
Hosted fixture failure correction: the mutation matrix includes /predicate/observed/inputs,
so the baseline now explicitly declares inputs: {} before pointer_mut is used.
A separate case removes that key again to retain coverage of the optional-inputs default.
No dev3 Cargo tests were attempted; Fleet Load r179 permits only the optional small check there.
Repair verification attempt on dev5:
gate-slot --lane build --profile disk=cargo-cold --max-wait 1800 -- python3 /var/tmp/mergemaster-statement-verify-fix.py
The already prepared pinned shell environment and /var/tmp target were reused.
No admission: initially 34 ahead; withdrew at 2026-11-10T19:15:03Z after 1801s,
exit 94. No Cargo command ran. Clippy, focused oracle test and full suite remain
NOT RUN for the repair. Stopped at the 30-minute admission ceiling; no dev3 test fallback.
Fraction and midnight correction
The same clock guard now requires seconds before either a local-time fraction
or an offset fraction (basic length 6 / extended length 8). Whole-hour/minute
offsets remain allowed when they have no fraction. The expanded matrix covers
both refused partial fractions and accepted basic/extended offset-second fractions.
The requested local oracle pass also found that pinned Python 3.14.7 ACCEPTS
24Z and 24:00Z, rolling to the next date. The guard now accepts only zero-valued
24-hour times, using Python's first-six-fractional-digits truncation, and refuses
overflow beyond 9999-12-31. This closes a conservative mismatch already present
in the matrix, rather than waiting for another hosted failure.
Executed locally on dev3 with
/nix/store/6cg92xlgwwwl88fiwrid0l924fmy8slp-python3-3.14.7-env/bin/python3
and runpy.run_path('/nix/store/bbj5s0bmhsv4a9mjqb97x80r8dvkas45-source/scripts/evidence-verify')['parse_time'].
Every matrix timestamp was extracted directly from the Rust concat fixture.
An additional 108 local-time/offset combinations were probed, including partial
times, fractions before seconds, offset hours/minutes/seconds and normalization.
A Python transcription of the intended Rust clock/shape/rollover guards matched
all 145 oracle verdicts. This is NOT a Rust test/build claim; calendar validity
in the transcription used Python date.fromisoformat after the same exact shape guard.
Pinned rustfmt --check passed again. Cargo checks remain NOT RUN locally.
Python aware-time verdict table (intended Rust guard agrees on every row):
2026-01-01 false
2026-01-01T12:30:00 false
20260101T1230Z true
2026-W01-1T12Z true
2026W011T12Z true
2026-W01T12Z true
2026W01T12Z true
2026-01-01🐍12:30:00,123456789+013045.25 true
2026-01-01Z12Z false
2026-01-01T12.5-00 false
2026-01-01T24Z true
2026-01-01T24:00Z true
2026-1-1T12:00Z false
2026-W1T12Z false
26-01-01T12Z false
2026- 1-01T12Z false
2026-02-30T12Z false
0000-01-01T12Z false
2026-01-01T12+24:00 false
2026-01-01T12+00:99 true
2026-01-01T12+23:59:59.99 true
2026-01-01T12+ false
2026-01-01T1Z false
2026-01-01T1230.5Z false
2026-01-01T12:30.5Z false
2026-01-01T12+01.5 false
2026-01-01T12+0130.5 false
2026-01-01T12+01:30.5 false
2026-01-01T12+013045.5 true
2026-01-01T12+01:30:45.5 true
2026-01-01T12+00:00:99 true
2026-01-01T12+23:59:60 false
2026-01-01T24:00:00.0000001Z true
2026-01-01T24:00:00.1Z false
2026-01-01T24:00:01Z false
2026-01-01T24:01Z false
9999-12-31T24Z false
Posted on behalf of @schickling
agent_identitysessionagent_personaagent_supervisoragent_toolagent_tool_versionagent_runtimeagent_modelworktree