P28-02-EQ: 意味を保つ軽量化:同等性の先行固定(harness)
This commit is contained in:
@@ -0,0 +1,579 @@
|
||||
# P28-02-EQ S4 implementation — retained completion r03
|
||||
|
||||
S4 retains the existing driver/verifier and all 134 prior test bodies (including
|
||||
the original 119). The only production-code correction in this completion is
|
||||
to require `check_probe(...)["ok"]` in driver admission and verifier recompute,
|
||||
with every error included in the rejection. `--check` and `--run` share the same
|
||||
admission gate. Unit tests mock the run boundary; no engine is launched.
|
||||
|
||||
The call-site check was limited to run_eq.py and verify_eq.py as instructed.
|
||||
Other calls to check_python_imports, check_observation and check_lifecycle raise
|
||||
on rejection and return True on success; check_report already requires `ok`.
|
||||
DIAG check_imports/bound_raw and collector stage_gate/guard_gate reject by
|
||||
exception. In particular, the collector gates' successful None is not false.
|
||||
No further ignored verdict-dictionary call was found in these two files.
|
||||
|
||||
## Complete S4 requirement-to-code and test map
|
||||
|
||||
The following is the current S4 map. Earlier stage notes below are preserved
|
||||
historical records, including statements of work that was pending at that time.
|
||||
All tests cited here are engine-free, synthetic evidence tests, not native proof.
|
||||
|
||||
| Retained requirement (S4 must / binding / r01-r03) | Code | Unit coverage |
|
||||
| --- | --- | --- |
|
||||
| S1: pin full source map, EQ and allowed dependencies, engine, fixture, admission | run_eq.DEPENDENCIES/FROZEN, load_dependencies, actual_pins, frozen_commit; verify_eq.verify repeats actual pins | SourcesAndMetrics source closure/pin tests; S4Bundle.test_import_closure_rejections; S4NativeBundleLogic.test_receipt_and_source_rejection_matrix |
|
||||
| S2: independently bind lifecycle and audio SHA; reject missing/error even with stdout | verify_eq.NAMES, phase_evidence, check_audio; lifecycle inventory excludes only lifecycle/audio | S4Bundle.test_missing_private_evidence_and_extra_rejected, test_phase_role_pid_audio_and_guard_rejected, test_rebound_lifecycle_and_scenario_contradictions |
|
||||
| S2: retain raw and joined separately with normalization evidence; join before compare | phase_evidence calls check.join_report; run writes raw/joined/proofs/checker JSON; seal hashes all; recompute compares joined reports | S4Bundle.test_synthetic_phase_all_real_checkers_not_native_proof; S4RemainingBindings.test_nonzero_determinism_rejected_after_real_join; Normalization sidecar rejection tests |
|
||||
| S2: full observation bytes/SHA and lifecycle guard/preparation/cleanup | phase_evidence calls check_observation for all 31 checkpoints and check_lifecycle(raw, life, guard) | S2Format observation/lifecycle tests; S4Bundle positive and contradiction tests |
|
||||
| S3a: strict_json, measurement passed, all private files SHA bound | verify_eq.read, check.read_report_stdout, phase_evidence exact inventory and check_report(raw, life.measurement, life.e3, life.e3_b1, life.e45) | S3a.test_duplicate_JSON_key_rejected; S4Bundle positive, missing evidence and contradictions |
|
||||
| S3a: lifecycle.e3/e3_b1, all 18 e3 files, full package evidence and checker outcomes | phase_evidence binds each e3 row to lifecycle and raw; package bytes remain inside e3 evidence; copy_profile also retains all package/log/config files | S3a package/NA/code/event rejection tests; S4Bundle scenario/b1 rejection matrix |
|
||||
| S3b: lifecycle.e45, all 21 e45 files, 39 ordered scenarios, continuous intervals | NAMES, phase_evidence count/copy checks; existing check_report/check_e45 continuity checks | S4Bundle contradictions; S3b scenario ordering/continuity and ownership tests |
|
||||
| S3b: join_facts sidecars/proofs and checker results with raw facts | check.join_report/check.join_facts reused unchanged; phase_evidence returns raw/joined/proofs/checker; verify compares their stored copies with recomputation | S3b facts/normalization tests; S4Bundle positive; S4NativeBundleLogic.test_synthetic_full_bundle_positive_not_native_evidence |
|
||||
| S3b: separate R-A/R-B and O-A/O-B comparisons; zero differences required | verify_eq.recompute explicit role loop, requires ok and empty differences | S4NativeBundleLogic positive and cross-role rejection; S4RemainingBindings determinism rejection |
|
||||
| S3b: preserve existing-defect, aliasing, cached digest facts, never manufacture PASS | phase_evidence preserves existing checker outcomes and raw facts | S4Bundle positive explicitly asserts existing-defect; S3b.test_aliasing_cannot_be_PASS, test_aliasing_missing_record and digest tests |
|
||||
| r01: seven owned phases in exact order, parse --check-only, headless runtime | run_eq.plan/run; verify_eq.PHASES/recompute validates commands, phase, role, PID and timestamps | S4NativeBundleLogic positive and receipt matrix; S4RemainingBindings owned lifecycle matrix |
|
||||
| r01: guard before parent, unique fresh startup/runtime profiles, env/role/fixture bindings | wrapper_text, plan, run_private_engine, guard_gate; recompute validates wrapper, 14 distinct profiles and 7 PIDs | S4Bundle guard/role/audio matrix; S4NativeBundleLogic startup-name rejection; S4RemainingBindings profile-reuse rejection |
|
||||
| r01: gates return None; absent profile empty inventory is not export success | run uses gates directly; copy_evidence requires exact existing inventory; copy_profile records exists separately | S4NativeBundleLogic.test_gate_none_success_not_boolean; S4Bundle.test_missing_profile_not_export_success |
|
||||
| r01: original absolute input destinations, never substitute copied root | actual_pins invokes collector.inputs on original readonly and checks nine unique destinations | S4NativeBundleLogic.test_copied_manifest_root_and_destination_count_rejected; S4RemainingBindings.test_nine_original_destinations_required |
|
||||
| r01: finally cleanup, source/project/default-player preservation; failures retained without seal | run finally captures cleanup/errors, profiles, pins and execution; recompute validates preservation/cleanup; seal only on success | S4NativeBundleLogic.test_failure_keeps_raw_and_no_bundle_without_starting_engine and cleanup/source matrix |
|
||||
| r01: complete copies, exact evidence inventory, final manifest/seal, no overwrite | copy_evidence/copy_profile verify before/after copy; inventory/pin; seal writes manifest then seal; write uses x mode | S4Bundle seal/missing/changed/extra/existing-output tests; S4NativeBundleLogic full synthetic bundle |
|
||||
| r01: verifier reads bundle at BUILD_OUTPUT_DIR/p28-02-eq-evidence, recomputes raw checks and stored results | verify_eq.main/verify/check_seal/recompute; no writes in verification | S4Bundle missing bundle/seal/manifest tests; S4NativeBundleLogic full verify positive |
|
||||
| r02: collector read-only import in closed D1+DIAG+EQ set; never import restart_pair | load_dependencies pins all 11 external files, checks loaded module closure and Python imports; copying implemented in EQ | S4Bundle.test_import_closure_rejections explicitly rejects restart_pair and other unapproved imports |
|
||||
| r02: exact raw3 stdout.log, stderr.log, engine-native.log; exit comes from owned process.json, not raw3 | collector.run_private_engine and DIAG.bound_raw reused; recompute checks owned JSON/diagnostics | S4NativeBundleLogic receipt matrix missing native log/owned/exit-in-raw; S4RemainingBindings exit/start/end/diagnostic rejection |
|
||||
| r02: exact private names and API arguments | NAMES = checkpoint 00..30, observation 00..30, e3 00..17, e45 00..20, events/report/lifecycle/audio-close; phase_evidence passes all five check_report args and guard to check_lifecycle | S4Bundle positive, missing/extra evidence and scenario matrix |
|
||||
| r02: synthetic writes outside checkout; verifier read-only | test_eq.synthetic_directory uses BUILD_OUTPUT_DIR or tempfile.gettempdir and rejects checkout descendants; verify outputs only stdout | S4Bundle.test_checkout_temp_destination_rejected; full synthetic verify test |
|
||||
| r03: enforce false static verdict, include all errors, both driver modes and verifier | run_eq.main and verify_eq.recompute require static.ok | S4ProbeAdmission four tests; S4RemainingBindings verifier false/true tests |
|
||||
| r03: preserve original context bytes and all plans; retain old failures and test bodies | S4_SUPPLEMENTARY.json loads Root original JSON unchanged, records five source pins and eight verified plan hashes; retained test prefix reconstructs original SHA | Source/plan assertions recorded in supplementary; final unit output and SHA recorded separately |
|
||||
| r01-r03: S_eq native is not Q; no acceptance/credit from units; exact submitted/base | admission/recompute carry S_eq-native-not-Q, candidate_Q_measured false, formal_acceptance false, original_credit 0 | S4NativeBundleLogic Q-label rejection and positive; final worker JSON uses submitted only after full local PASS |
|
||||
|
||||
## Completion evidence and limits
|
||||
|
||||
The original 134-test file can be recovered by removing only the newly appended
|
||||
classes and retaining its original unittest main; its SHA is
|
||||
cb742b252dbc278113b3c11c2431adac35b0c2e201a762a8ea1ac926e4af414b,
|
||||
matching Root's retained record. This also preserves all 119 earlier bodies.
|
||||
S4_SUPPLEMENTARY preserves all eight plans/API notes/clarification references
|
||||
directly from the supplied r09 JSON, plus the exact r03 text and decision.
|
||||
All five source SHA checks and all eight plan SHA checks succeeded.
|
||||
|
||||
Attempt 07 exposed a newly added test's overbroad comparator mock: it injected a
|
||||
difference into the report's self-check before the intended cross-PID gate.
|
||||
Only that new test was corrected to retain the real identity self-comparison.
|
||||
Attempt 07 raw/exit/SHA remain a failure. Attempt 08 rechecks the added classes
|
||||
(9 tests, 86.276 seconds, OK, exit 0). Attempt 09 covers the three added
|
||||
S4StoredResultBindings tests (0.025 seconds, OK, exit 0): verify must reject a
|
||||
cached verdict differing from recomputation, missing sidecars, and raw/joined
|
||||
substitution even when the supplied files have a valid seal. These isolate the
|
||||
stored-result equality gate with a recomputation mock; full real recomputation
|
||||
remains covered by the existing and new native-bundle-logic classes.
|
||||
Prior attempt 01 syntax, 02 unit, 04 recompute and supplementary assert failures
|
||||
remain historical failures. Attempt 05's 132 PASS and late attempt 06's 134 OK
|
||||
do not prove this version; the latter has no provider completion/exit receipt.
|
||||
Final full local evidence: attempt 10 ran all 146 tests in 293.277 seconds,
|
||||
OK, exit 0 (outer wall time 293.5742515 seconds). Raw is retained in
|
||||
UNIT_OUTPUT_S4_ATTEMPT_10.txt and UNIT_OUTPUT.txt, SHA-256
|
||||
ff6fc0065772434f9ca35a1267e24d199057e339869a868942a41829327503bb.
|
||||
This was the single final full run after the targeted fixes and all additions.
|
||||
|
||||
An attempted read of Root's external retained test copy returned PermissionError.
|
||||
No permission change was attempted; exact retained-prefix SHA verification
|
||||
provided the same preservation check inside the allowed workspace. A shell
|
||||
heredoc read also failed before execution; subsequent reads used python -c.
|
||||
|
||||
Root still must run the exact submitted S in seven native phases, place the
|
||||
bundle, run p28-02-eq-unit and p28-02-eq-native-verify, obtain fresh independent
|
||||
Opus review of all six conditions, and complete qualification/approval/
|
||||
integration/final before OPT and whole-unit gates. Original credit is zero;
|
||||
23/88 and 4/30 are unchanged. No native, accepted S, Q or product PASS is claimed.
|
||||
|
||||
## Retained S1-S3b implementation history
|
||||
|
||||
# P28-02-EQ S1 implementation
|
||||
|
||||
## Scope and authority
|
||||
|
||||
This run implements only staged plan r02 S1: `compare_versions.py`, synthetic
|
||||
`test_eq.py`, progress and unit evidence. No product, SPEC, TASK, references,
|
||||
registration, git, engine, Runner, or other worker operations are performed.
|
||||
S2–S4 and all six formal acceptance gates remain pending. A successful comparison
|
||||
is not a product E3/E5 PASS and does not establish native harness acceptance.
|
||||
|
||||
Read-only clarification SHA-256 checks matched the supplied values:
|
||||
|
||||
- r01: `25d323fd562d29e80782b6f075fc7a0e8b49457a6c4fbd7c30e74b31a6b6a126`
|
||||
- r02: `777accdd652f85db6b9014d85e3c8b3b60ca94b20768e6173b36bc769d360fd9`
|
||||
- r03: `12b27f984ef5843d98327200ad261dccaf64968402192b08ad55b15ed5454ea2`
|
||||
|
||||
SPEC file bytes SHA is `3791ccdcb87e8d71fe9205e1e692ebca9e0f974ea3b5fbc4fbb3943882131f1c`,
|
||||
matching `registration/ROOT_PROPOSAL_BYTE_TRANSFER.json`. Removing the final LF
|
||||
gives the supplied contract text SHA `cf75af22a803bf492e30f8a04a39f5187ece5b94cd54207aad8ece1683d4bc93`.
|
||||
Neither representation was rewritten.
|
||||
|
||||
## Internal transport choices for S2
|
||||
|
||||
- Standard-library-only Python; no product or unapproved dependency imports.
|
||||
- Nodes follow plan r02 A1. Scalars retain their Variant codes. Float payloads
|
||||
are 16 lowercase hex digits for little-endian f64, including signed zero and
|
||||
NaN bit patterns. Strings are never coerced to StringName. NodePath uses type
|
||||
22 with its string payload. RID/Object/Callable/Signal are rejected.
|
||||
- Composite math types use flat scalar components (AABB: 6, Basis: 9,
|
||||
Transform3D: 12, Projection: 16). Packed arrays retain their type code.
|
||||
- Array `typed_info` is null or `[builtin_int_node, class_StringName_node,
|
||||
script_null_node]`. Dictionary metadata is null or `[key_info, value_info]`
|
||||
using that same triple. Object/script-bearing values are not transported.
|
||||
- A path is a list of `["key", key_node]` or `["index", integer]` segments.
|
||||
Dictionary keys retain types and insertion order; indexes address Arrays.
|
||||
Empty path addresses the root. Mutations operate on deep copies, validate
|
||||
bounds and duplicate keys, and reject unknown operation fields.
|
||||
- `array_splice` uses `nodes` for the inserted list; `dict_insert` uses `index`,
|
||||
`key_node`, `value_node`. Other operation names/fields follow A3.
|
||||
- A transport record has exactly `tree` or `diff`, `tree_sha`,
|
||||
`raw_bytes_sha`, `roundtrip_ok`. Checkpoint S diffs apply to the previous S;
|
||||
latest diffs apply to current S. latest may instead have `same_as_S: true`
|
||||
and the three proof fields, with matching S raw-byte SHA.
|
||||
- `tree_sha` is SHA-256 of compact, insertion-order UTF-8 JSON, no ASCII escaping,
|
||||
no whitespace, no terminal newline. S2 must produce this representation and
|
||||
prove Godot byte roundtrip. Python never claims it can independently recreate
|
||||
Godot's var_to_bytes from a reported SHA or boolean.
|
||||
- There is no application depth cutoff or depth-4 hash summary. Entire trees
|
||||
are reconstructed and checked at each checkpoint. Resource/JSON parser limits
|
||||
remain ordinary process limits; malformed evidence is not a PASS.
|
||||
- Exact tree equality comes first. Text-key dictionary fallback preserves every
|
||||
key's type, every typed-info value, and array order, records all changed
|
||||
dictionary orders, and rejects duplicate textual keys. Scalar key spellings
|
||||
use their string/integer/bool/null text; float and compound keys use lossless
|
||||
compact typed JSON spelling, without decimal conversion. Original key nodes
|
||||
are always compared as well, so this sorting cannot erase key type or bits.
|
||||
|
||||
## F1–F3 and restoration
|
||||
|
||||
The required four functions return/consume `(normalized, sidecar)` with precisely
|
||||
`entries`, `violations`, `profile_root` as sidecar keys. `profile_root` input is
|
||||
`{"root": <simplified absolute user root>, "actual_user_data_dir": <guard value>}`.
|
||||
The sidecar adds `matches_guard: true` inside this object after checking equality.
|
||||
|
||||
Only top-level E2 event payloads, or elements of snapshot
|
||||
`systems.runtime.domain_events.recent_events`, qualify. Nested event-shaped
|
||||
payload data and lookalike events elsewhere do not qualify. The nine event types
|
||||
and `save_service` source are closed. Both timing fields must exist and be
|
||||
nonnegative ints. Their markers are typed Dictionary nodes representing the
|
||||
r02 marker, not numeric substitutes. F3 preserves the whole original String
|
||||
node and root, and replaces every exact root-plus-slash occurrence. A preexisting
|
||||
reserved token is rejected to avoid ambiguous inversion.
|
||||
|
||||
Entries retain event index (null for snapshot trees), typed path, key and original
|
||||
node; F3 also retains root. Tree paths preserve event position, while comparison
|
||||
separately checks the actual event_id without remapping. Unknown timing/profile
|
||||
values remain unchanged and recorded as violations. Violation presence alone is
|
||||
not failure. Their actual differences are ordinary full-tree differences.
|
||||
|
||||
Restoration re-applies the closed normalization policy to reject missing,
|
||||
duplicate, forged or unauthorized entries. The independent original tree SHA
|
||||
must also match after restoration: changing a timing value in a sidecar to
|
||||
another valid timing cannot be detected from the marker alone. The comparator
|
||||
performs this SHA check against retained raw transport trees; unit tests include
|
||||
this forgery. A sidecar is not an independent authority for its own integrity.
|
||||
|
||||
`validate_scenario_paths` accepts only fixed `user://p28_eq/{r,o}/` names:
|
||||
good, tampered_world, missing_key, wrong_type, out_of_range, duplicate_id.
|
||||
S3 must use these names and deterministic metadata/tamper rules.
|
||||
|
||||
## Joined comparison report interface
|
||||
|
||||
Report keys are closed: `schema` (`p28-02-eq/typed-v1`), `role` (R/O),
|
||||
`profile_root`, `checkpoints`, `events`, `event_start`, `event_end`, `signal_order`,
|
||||
`scenarios`. No missing value is defaulted to zero. Manifest/package records
|
||||
belong to the bundle, not the S comparison report.
|
||||
|
||||
- Main checkpoints: 31 records, consecutive minutes. Each contains `minute`, S
|
||||
and latest transports, `latest_digest`, `computed_latest_digest`,
|
||||
`harness_normalized_digest`, K, C, and `observation`.
|
||||
- Observation has `before`/`after`, each with complete S/K/C bytes SHA values.
|
||||
Equality is mandatory before environment normalization. S2 must obtain these
|
||||
from the complete raw layers, including telemetry and instance IDs.
|
||||
- Digest self-consistency is mandatory in each PID. If latest has F1–F3 entries,
|
||||
compare the explicitly labeled harness normalized digest and preserve both
|
||||
product digests with an exclusion reason. Otherwise compare product digests.
|
||||
Full S and latest comparison is mandatory in either case.
|
||||
- K uses the SPEC names, `_accumulator` as f64 hex, `_phase_handlers` as phase
|
||||
string to handler-ID list (compared as sets), and `performance_budget` with
|
||||
`_sample_counts`, `_samples`, `_totals`. Unknown/missing fields are rejected.
|
||||
- C has `_mvp_manifest_cache_generation`, `catalog_is_current`,
|
||||
`_mvp_manifest_cache_bytes` (complete base64 var_to_bytes),
|
||||
`catalog_instance_id`, `current_catalog_instance_id`.
|
||||
- Each excluded telemetry/instance-ID field retains a reason and both raw values.
|
||||
- `event_start` has counter and published_ids_count. A mismatch invalidates
|
||||
correspondence. Event rows have sequence (zero-based receive order), transport,
|
||||
and original_field_types. All original types and all tree fields are compared;
|
||||
no cap is applied. S2's checker must enforce the exact product event shape and
|
||||
required original type observations. `event_end` and signal order also compare.
|
||||
- Scenarios have id, operation, result, checkpoints and events (raw typed event
|
||||
trees). Result retains actual codes, ownership results, changed paths/values,
|
||||
boundaries and event counts defined by S3. State checkpoints use the same
|
||||
full-state machinery. Matching existing product failures remain matching
|
||||
failures, never rewritten as PASS. S3's checker must enforce scenario coverage,
|
||||
allowed operations and absolute product acceptance separately.
|
||||
|
||||
`compare_reports` reports differences with both actual values, dictionary-order
|
||||
paths, exclusions, violations and digest mode. Evidence errors yield `ok: false`.
|
||||
It does not replace `check_eq` or native/source admission: empty synthetic
|
||||
scenario lists can be compared in S1 tests; they cannot satisfy S3 acceptance.
|
||||
|
||||
## Source closure and performance
|
||||
|
||||
`check_source_closure` hard-pins the collector's sorted compact JSON map digest
|
||||
`651f703621c8ed06a724709f75d8bc05b1eef2988c3b3d5d3466096a3f759bf0` and 1407 entries.
|
||||
Each row is bytes plus SHA-256. Added/missing paths fail. The exact changed set
|
||||
must equal the supplied registered set, which must be a subset of the six OPT
|
||||
paths. The caller cannot replace the before pin. S4 must separately pin all
|
||||
EQ/DIAG/RESTART/collector bytes, engine, fixture and admission metadata.
|
||||
|
||||
Source closure unit tests inject a synthetic map pin *only within unittest mock*
|
||||
to exercise positive closure mechanics; a separate test proves the real function
|
||||
rejects that synthetic map with the production pin. No product hooks are replaced.
|
||||
|
||||
`classify_improvement` implements SPEC §4 strict disjoint ranges of three finite,
|
||||
nonnegative measurements; markers and absent samples are rejected. Actual metric
|
||||
collection and the combined OPT adoption decision remain later native work.
|
||||
|
||||
## Validation and preservation
|
||||
|
||||
Only `python3 test_eq.py` is executed, with synthetic inputs and bytecode disabled.
|
||||
The first run's missing-F3-sidecar failure is preserved unchanged in
|
||||
`UNIT_OUTPUT_ATTEMPT_01.txt` with SHA. The implementation now rejects the leftover
|
||||
reserved token after restoration. The intermediate successful run is also kept.
|
||||
`UNIT_OUTPUT.txt` is the latest complete raw output, with a separate SHA file.
|
||||
These are local unit results, not Runner/native validation or Q measurements.
|
||||
|
||||
## S2 implementation (repair 4)
|
||||
|
||||
S2 only is complete. S1 compare_versions.py is byte-identical to its supplied
|
||||
058f3fef... pin. The original 43 test bodies are retained; S2 adds 29 tests.
|
||||
E3/E4/E5 execution and S4 driver/verification are deliberately not implemented
|
||||
by this run. All six formal acceptance conditions remain pending.
|
||||
|
||||
### Probe and evidence
|
||||
|
||||
- eq_probe.gd follows the six DIAG lifecycle stages: public paused preparation;
|
||||
main with two deferred frames; 30 warm steps; 30 observed steps; outside-tick
|
||||
observations; observer teardown and close_requested.emit(). R uses the pinned
|
||||
fixture and starts B0 at 602/B1 at 632. O keeps the new 360-minute state, lets
|
||||
main enable Ops, and uses the same warm sequence (B1 390). The actual Ops
|
||||
result and all preparation/frame/B0/B1 values are retained, never substituted.
|
||||
- THE_TREE_EQ_ROLE is R or O. THE_TREE_P28_FIXTURE supplies R. The fixture SHA
|
||||
is pinned in the probe. The existing guard wrapper supplies
|
||||
THE_TREE_PACK_PROFILE_REPORT. No separate profile root from environment is
|
||||
trusted: bind_profile reads the receipt, reads the live globalized user root,
|
||||
checks OS.get_user_data_dir too, and records the receipt and SHA.
|
||||
- Every supported Variant is encoded using the S1 A1 representation. All math
|
||||
components, packed arrays, StringName/NodePath and typed container metadata
|
||||
retain their types. Unsupported object-bearing nodes append an error and
|
||||
fail transport/proof; they are not silently stringified. Full bytes roundtrip
|
||||
is performed by encode -> decode -> var_to_bytes in Godot. Python's synthetic
|
||||
tests do not establish that Godot execution succeeded.
|
||||
- Diff production uses exact recursive set operations and array_splice. Changed
|
||||
Dictionary key lists/order/metadata replace the whole affected subtree using
|
||||
set; unchanged key lists recurse into every value. This is a valid subset of
|
||||
A3 operations and has no depth limit. The emitted operations are replayed in
|
||||
Godot and checked before export, then replayed independently by the existing
|
||||
Python comparator. No S1 diff interface changes.
|
||||
- evidence/checkpoint-00.json holds the full B1 S tree; checkpoint-01..30.json
|
||||
hold S diffs from the previous checkpoint. Latest uses same_as_S only for
|
||||
equal bytes; otherwise it holds a diff from that checkpoint's S.
|
||||
- evidence/observation-00..30.json retain complete before/after S/K/C bytes
|
||||
(base64) plus hashes, K/C actual values. K includes all telemetry and C includes
|
||||
actual instance IDs. Reading a state witness also checks that create_snapshot
|
||||
did not change K or C. Cache filling is an explicit recorded preparation.
|
||||
- Domain events are captured through wildcard subscription after B1 and through
|
||||
the last tick/frame, without a cap. to_dictionary() transport includes its own
|
||||
byte roundtrip proof and receive-order sequence. original_field_types observes
|
||||
all seven object fields; entity_ids and payload include typed_info.
|
||||
- evidence/events.json, report.json, lifecycle.json and audio-close.json retain
|
||||
the run data. lifecycle has preparation, Ops/save policy, raw baseline/frame
|
||||
values, warm signals, guard binding, observer inventories, error list, and
|
||||
file hashes. File writes refuse overwrites. The lifecycle inventory excludes
|
||||
its own hash and the later audio receipt; S4 must bind both independently.
|
||||
S4 must reject missing lifecycle/audio or errors even if a stdout report exists.
|
||||
- stdout emits exactly one P28_02_EQ_REPORT= line with the unchanged S1 closed
|
||||
schema. Report also contains full transports; private files are independently
|
||||
bound copies, not substitutes for raw output.
|
||||
|
||||
### Python joining and checking
|
||||
|
||||
- S1 calls this a *joined comparison report*. The raw probe leaves
|
||||
harness_normalized_digest null because F1-F3 has one implementation, in Python.
|
||||
check_eq.join_report(raw) reconstructs all trees, checks their proof hashes,
|
||||
normalizes/restores using S1, and returns a copy plus complete sidecars. It
|
||||
fills that existing field with a harness-only typed canonical SHA, not a
|
||||
product SimulationDigest. Only Dictionary enumeration order is canonicalized;
|
||||
key node types, scalar bits, metadata and Array order remain exact. This avoids
|
||||
turning an allowed Dictionary-order fallback into a spurious digest failure.
|
||||
normalized_tree_sha remains insertion-order sensitive for transport binding.
|
||||
S4 must preserve and hash raw and joined outputs separately, call this join
|
||||
before compare_reports, and retain normalization evidence. Product latest_digest
|
||||
and computed_latest_digest always remain the actual Godot values.
|
||||
- check_report is explicitly an S2 format/contradiction check with
|
||||
formal_acceptance=false. It enforces 31 checkpoints, minute/counter coherence,
|
||||
full S/latest/K/C, observation proof, actual event field types, unaltered event
|
||||
IDs, and event coverage against endpoint published_ids. Empty or unknown
|
||||
transport fields do not pass as a digest-only comparison.
|
||||
- check_observation binds full raw bytes to SHA witnesses. check_lifecycle binds
|
||||
the separately collected guard receipt and checks actual preparation/teardown
|
||||
evidence. These functions must be called by S4 when copied evidence is joined.
|
||||
- check_probe is a conservative static screen, not a Godot parser or proof of
|
||||
arbitrary GDScript safety. It rejects inferred declarations, static autoload
|
||||
references/imports, live writes, unlisted/dynamic live dispatch, mutation calls
|
||||
outside preparation/stepping, nontextual sort, event truncation, and missing
|
||||
full-state/roundtrip/guard operations. Native parse-base/parse-wrapper and
|
||||
independent source review remain mandatory.
|
||||
- E3/E4/E5 scenarios are absent and check_report explicitly rejects nonempty
|
||||
scenario lists at this stage. S3 must extend coverage/absolute product-outcome
|
||||
checking and static allowed scenario boundaries without weakening S2 checks.
|
||||
|
||||
### Local validation and preserved history
|
||||
|
||||
Engine-free command: python3 -B test_eq.py. S2 attempts 01/02/03 passed
|
||||
68/71/72 tests respectively. Each complete raw output and SHA is retained.
|
||||
The final 72 include all 43 S1 tests and 29 S2 tests.
|
||||
UNIT_OUTPUT.txt is the final raw output; UNIT_OUTPUT_S1_FINAL.txt preserves the
|
||||
previous 43-test final output. Original UNIT_OUTPUT_ATTEMPT_01 (failure) and
|
||||
ATTEMPT_02 remain unchanged with their hashes. No failure was rewritten.
|
||||
|
||||
The first attempted shell heredoc was refused by the environment before it wrote
|
||||
a file (temporary-file creation denied). apply_patch and direct Python writes
|
||||
inside eq/ succeeded; no engine or Runner operation was attempted.
|
||||
|
||||
S2_SUPPLEMENTARY.json contains one actual_commander_context key with the full
|
||||
unedited r01/r02 plans, the full supplied RUN decision, and the read-only
|
||||
clarification paths/SHA. Both full plan texts reproduce their supplied hashes.
|
||||
This is a preserved instruction packet, not a new commander decision.
|
||||
|
||||
## S3a implementation (repair 5)
|
||||
|
||||
Only the two specified S2 checker fixes and E3 are implemented. S3b (E4/E5),
|
||||
S4, all native phases, both formal validations and all six acceptance conditions
|
||||
remain pending. No product/engine/Runner/git-write/other-agent operation occurred.
|
||||
The S1 comparator is unchanged (058f3fef57c2ebe6951a48d85d570a110b982e08a13c805c244fec7d5e9a0fe8).
|
||||
Existing test bodies remain, except the S2 format helpers now provide the
|
||||
required measurement inventory and full 30-minute pairs; S1 fixtures are unchanged.
|
||||
|
||||
### Measurement binding
|
||||
|
||||
check_report(raw, measurement=None, e3_evidence=None, b1_record=None) requires
|
||||
the separately retained lifecycle.measurement. This keeps process object IDs
|
||||
out of the unchanged joined-report schema and of cross-PID comparisons.
|
||||
The inventory contains probe_object (actual instance ID), start_minute and the
|
||||
full get_connections inventory. Both observer methods must belong to that
|
||||
probe object exactly once. Every measured checkpoint after B1 must have exactly
|
||||
snapshot_published then state_updated. Missing inventory never downgrades the
|
||||
expectation. The exact string phase keys are 0 through 10; aliases such as 00
|
||||
fail. strict_json rejects duplicate object keys before they can be discarded.
|
||||
S4 must use strict_json for raw JSON, pass measurement to check_report, and
|
||||
bind lifecycle and all private files by SHA. The CLI now requires --lifecycle.
|
||||
|
||||
### E3 intervals and raw evidence
|
||||
|
||||
The measured stream closes before run_e3. There are 18 ordered entries:
|
||||
restore_snapshot, validate, load_from_path, each with missing_key, wrong_type,
|
||||
out_of_range, duplicate_published_ids, duplicate_facility, tampered_world.
|
||||
Every entry retains applied/NA, its reason, invocation fact, actual B1 facility
|
||||
count, code/null and API reason, bool/errors, migration fact and actual event
|
||||
count. Dictionary-only world cases are NA. Envelope duplicate checks are invoked
|
||||
and their whole return is retained, but remain NA, never an acceptance or defect
|
||||
claim. O's zero-facility cases do not construct, substitute R or invent instances.
|
||||
|
||||
B1 is decoded from its already observed lossless transport. Inputs are deep
|
||||
copies with the specified fixed mutations. The unsupported manifest format is
|
||||
the fixed integer 2147483647. Save metadata is empty. Duplicate packages share
|
||||
the allowed fixed duplicate_id path sequentially; each original, modified and
|
||||
post-operation package file is copied into that interval's evidence before any
|
||||
later overwrite. The four-file inventory retains complete base64 bytes and SHA,
|
||||
including absent files as null. world.bin uses offset len//2 XOR 1. Package
|
||||
preparation uses SaveService.save_snapshot only inside the active E3 interval;
|
||||
its actual return and exact input are retained. A refused duplicate save makes
|
||||
load NA; a refused mandatory nonduplicate preparation fails the harness.
|
||||
|
||||
Each scenario retains two full S/latest/K/C checkpoints in the existing S1
|
||||
schema. lifecycle.e3 and evidence/e3-NN.json additionally bind full raw layer
|
||||
bytes, layer typed transports, observation witnesses, invocation boundary,
|
||||
whole typed API return, all scenario event transports, separate signal records,
|
||||
latest_save_operation_result and SaveService diagnostic budgets before/after.
|
||||
check_e3 checks full byte witnesses, binds report to raw evidence and requires
|
||||
continuity between intervals (starting at the last measured checkpoint).
|
||||
No scenario reset or state repair is performed: later intervals use the actual
|
||||
new baseline, including any unexpected product changes.
|
||||
|
||||
join_report now derives the existing normalized digest field for scenario
|
||||
checkpoints as well as measured checkpoints, using the unchanged S1 policy.
|
||||
E3 report result summaries contain deterministic API facts; whole returns and
|
||||
package diagnostics remain in SHA-bound raw evidence, not silently discarded.
|
||||
Package timestamps and SaveService static diagnostic budgets have explicit
|
||||
exclusion reasons and actual values in checker output. S1 continues to compare
|
||||
the full normalized scenario state/events and deterministic results.
|
||||
|
||||
### Product outcomes versus malformed evidence
|
||||
|
||||
check_e3 derives source-backed expectations and outputs actual results,
|
||||
expected event counts, typed path/value differences, dropped recent event,
|
||||
normalization sidecars and existing-defect-candidate entries. It does not accept
|
||||
a caller's PASS/defect label. Wrong counts, accepted invalid inputs or changed
|
||||
state are recorded product candidates; a forged count versus the retained event
|
||||
list is malformed harness evidence and fails admission. Missing load code,
|
||||
invented restore/validate code, false NA/applicability, missing raw evidence or
|
||||
unrecorded interval gaps also fail admission.
|
||||
|
||||
For failed loads, X(B, ev_fail) increments the counter, sort-inserts the actual
|
||||
unchanged ID and appends the event, retaining the dropped head at the 256 limit.
|
||||
The full normalized state must match this expected tree. The checker also binds
|
||||
payload to latest_save_operation_result and return facts, checks pause/restore
|
||||
outcomes, and retains full K/C differences. Such differences are not suppressed
|
||||
even when caused by the product's load accounting. Envelope duplicate acceptance
|
||||
alone is explicitly not a defect.
|
||||
|
||||
### Handoff and validation boundary
|
||||
|
||||
The static screen admits the listed calls only in run_e3's active interval and
|
||||
the sole package-preparation helper; it remains a conservative screen, not a
|
||||
Godot parser. S3b extends scenario dispatch/coverage and the static count policy
|
||||
for its own authorized operations. S4 must bind lifecycle.e3/e3_b1/measurement,
|
||||
all e3-NN files, package evidence, raw/joined outputs and checker outcomes, and
|
||||
call check_report and check_lifecycle. The current S2 synthetic empty-scenario
|
||||
fixture remains useful for historical format tests; a S3a lifecycle requires
|
||||
the complete 18-entry table and cannot pass with an empty scenario list.
|
||||
|
||||
S3A_SUPPLEMENTARY.json has the single actual_commander_context key, containing
|
||||
both unmodified staged plans, both S3 plans and the full effective RUN decision.
|
||||
All four plan hashes match the supplied pins; read-only r01/r02/r03 paths remain
|
||||
in eq-staged-readonly-r04. This is preserved authority, not a new decision.
|
||||
|
||||
The local tests use synthetic bytes for Godot proof fields. Their PASS does not
|
||||
prove native parsing, Godot roundtrip, fixture behavior or product acceptance.
|
||||
Native execution is deliberately left to Root after S4, followed by Runner
|
||||
validation and the fresh independent review.
|
||||
|
||||
## S3b implementation (repair 7; E4-1 r02)
|
||||
|
||||
S3b reuses the S1 transport/comparison, S2 measurement, and S3a observations.
|
||||
E3's implementation and the original 91 test bodies remain unchanged. Rebuilding
|
||||
the original test file from its retained prefix plus its original unittest main
|
||||
reproduces f81185e506954964bb96b31a569233202a1a7e7c78b2121aba6ab3f2e24d7e1e.
|
||||
The previous run 7da027a85548460bb008b562a79a52ae remains historical evidence:
|
||||
its blocked enumeration question was resolved by the supplied S3b r02, not
|
||||
retroactively labeled an implementation success.
|
||||
|
||||
### Native scenario producer and raw binding
|
||||
|
||||
- E4 runs after all 18 E3 intervals: build_facility, tick, restore_snapshot,
|
||||
load_from_path, rejected_command. The next interval starts from the actual
|
||||
previous end. All observations reuse e3_observation's complete immutable
|
||||
S/K/C, bytes, typed proof, latest and both digest values.
|
||||
- Registry IDs come from that PID's definition_registry.get_facility_ids().
|
||||
Both registered order and textual sorted order retain Array[StringName].
|
||||
Bounds come from world_service.get_bounds(); x and y are inclusive.
|
||||
WorldService's public FRONT/BACK layers are 0 and 1. ID is the outer loop,
|
||||
then x/y/z lexical order, rotation 0. Every tried candidate and complete
|
||||
public preview dictionary is transported without truncation. The whole
|
||||
read-only search has complete before/after observations; it does not repeat
|
||||
large snapshots per candidate. Empty registry is a harness error; NA requires
|
||||
exhausting a nonempty registry's entire nonempty world range.
|
||||
- Chosen payload is passed to the ordinary submit_command API. Product source
|
||||
:505-515 processes ready commands immediately when paused, and may publish
|
||||
there. The harness records this actual submit boundary, then exactly one
|
||||
advance_minutes(1), then the processed command result. It does not force
|
||||
delayed command execution, unpause, or replace any executor.
|
||||
- E4 load uses the already allowed fixed user://p28_eq/{r,o}/good path and empty
|
||||
metadata. Complete package bytes/SHA, whole returns, static SaveService
|
||||
diagnostic budgets and latest_save_operation_result are retained. Restore
|
||||
requires zero events; load requires one SAVE_LOADED and the existing e3_x
|
||||
implementation of X(P,event). Payload is bound to latest_save_operation_result.
|
||||
- E4 rejected command records the full submit and tick deltas separately:
|
||||
bookkeeping, clock and any other actual changed path/value remain visible.
|
||||
No current-run cache-staleness verdict is invented from publication timing.
|
||||
- E5 covers all four targets, both fixed nested locations and both directions.
|
||||
Signal handlers only retain references and record signals. Mutations occur
|
||||
after the handler has returned. Each interval has start, preparation-tick
|
||||
baseline, immediate operation result, and reset-tick end observations.
|
||||
Deep copies and original returned values have complete transport proofs.
|
||||
Each next baseline follows a recorded publication, with no direct repair.
|
||||
- lifecycle.e45 and evidence/e45-00..20.json bind these 21 intervals.
|
||||
report.scenarios contains the original 18 E3 rows followed by these 21 rows.
|
||||
Scenario events are uncapped typed transports. All scenario signals remain
|
||||
separate from measured signals, and are also bound into comparison facts.
|
||||
|
||||
### Checker, comparison and existing defects
|
||||
|
||||
check_report retains its original first four parameters and adds optional
|
||||
e45_evidence. S3a-only callers continue to work; S3b lifecycle admission requires
|
||||
all 39 scenarios and all raw evidence. check_e3 itself is unchanged; its caller
|
||||
passes exactly the retained first 18 rows for S3b.
|
||||
|
||||
check_e45 rejects missing/reordered paths/combinations, interval gaps, false NA,
|
||||
wrong registry/order/bounds/rotation, missing trials/previews, unmatched chosen
|
||||
candidates, event count/identity coverage gaps, malformed signals, missing
|
||||
ownership mutation/proof, and caller-supplied PASS or cache-staleness verdicts.
|
||||
Outcome status is derived: recorded, NA, or existing-defect. Actual full typed
|
||||
differences and both digest values are retained per scenario.
|
||||
|
||||
Raw result.facts is bound exactly to detail before joining. join_facts transports
|
||||
all deterministic selection/command/signal facts and normalizes only snapshot
|
||||
transports (input/held_before/held_after) using S1's unchanged closed F1-F3 policy.
|
||||
Full inverse proofs and raw facts are retained. Package/API diagnostics remain
|
||||
in raw evidence with explicit exclusion reasons/values, never discarded.
|
||||
Search raw S/K/C stays in lifecycle evidence; its immutability is checked, and
|
||||
the enclosing scenario checkpoints retain cross-PID K/C comparison.
|
||||
|
||||
Two failing added tests justified narrow S1 comparator extensions:
|
||||
1. Only checkpoint index 2 of one of the eight named E5 outside_in intervals
|
||||
(four checkpoints, matching operation) can record a cached/computed digest
|
||||
mismatch as a product fact. Other checkpoint/self-consistency checks remain.
|
||||
Both sides' consistency outcomes compare, and digest exclusions follow the
|
||||
same F1-F3 rule. check_e45 reports cached_digest_aliasing as an existing defect.
|
||||
2. Joined S3b result facts contain typed trees; they use the existing full
|
||||
compare_trees dictionary-order-only fallback, preserving type/value/array
|
||||
differences and recording every dictionary-order path.
|
||||
Neither exception turns product ownership failures into PASS.
|
||||
|
||||
The static checker extends only the listed E4/E5 operations and active intervals,
|
||||
checks selection-source proof snippets, forbids handler mutation and extra
|
||||
dispatches, and retains all previous checks. It remains a conservative screen;
|
||||
native parse and independent source review are still required.
|
||||
|
||||
### S4 binding requirements (additional to the retained S3a requirements)
|
||||
|
||||
S4 must copy/hash lifecycle.e45 and every e45-NN.json, bind them to the stdout/raw
|
||||
report, call check_report with lifecycle.e45, and call check_lifecycle for S3b.
|
||||
Join raw reports before compare_reports; retain join_facts sidecars/proofs and
|
||||
checker outcomes with the raw values. Compare R-A/R-B and O-A/O-B separately.
|
||||
Preserve existing-defect outcomes, including aliasing, in the final bundle.
|
||||
Do not call unit evidence a native run, accepted S, Q measurement, or product PASS.
|
||||
|
||||
S3B_SUPPLEMENTARY.json has one actual_commander_context key with all six full
|
||||
plans, the full effective RUN decision, and read-only clarification references.
|
||||
All six plan content hashes match the user-provided pins. SPEC, TASK, references,
|
||||
registration and prior supplementary files are unchanged. No engine, Runner,
|
||||
git write, other agent, product edit or full regression has run.
|
||||
|
||||
|
||||
Final S3b local validation: python3 -B test_eq.py, 119 tests, OK, exit 0.
|
||||
Raw: UNIT_OUTPUT_S3B_ATTEMPT_09.txt and UNIT_OUTPUT.txt. SHA-256: 8360a2065b303099d5c546b3e4aecc0cc0ab0c2c1e5120b8034b6a1a64317030.
|
||||
Attempts 02/03/07/08 retain the syntax, digest, dictionary-order and fixture
|
||||
failures respectively; all earlier evidence remains unchanged.
|
||||
|
||||
## S4 binding map (implementation in progress)
|
||||
|
||||
| Retained requirement | Implementation / additional unit coverage |
|
||||
| --- | --- |
|
||||
| Full raw observations and checkpoint SHA | verify_eq: evidence inventory, check_observation, altered/missing witness rejection |
|
||||
| Lifecycle and audio independently bound | verify_eq: exact evidence names, lifecycle.files, audio/PID checks |
|
||||
| Measurement, E3, B1, E45 supplied explicitly | verify_eq: check_report with all five arguments; 39 scenarios and raw file equality |
|
||||
| Guard before parent and fresh profiles | run_eq: collector guard_gate and run_private_engine; distinct startup/runtime bindings |
|
||||
| Raw versus joined state, join_facts proofs | verify_eq: recompute join_report, preserve separate joined/proof/checker files |
|
||||
| Same-role determinism and existing defects | verify_eq: R-A/R-B and O-A/O-B only, preserve checker outcomes |
|
||||
| Seven owned phases and complete raw3/owned5 | run_eq/verify_eq: ordered phases, collector receipts, strict diagnostic recheck |
|
||||
| Closure, source 1407, frozen S and pins | run_eq: checked dependency import and full inventories; verifier repeats actual-file checks |
|
||||
| Original absolute input destinations | run_eq: collector.inputs on original readonly; no copied-root substitution |
|
||||
| Finally cleanup and failure preservation | run_eq: collector owned cleanup, failure receipt, seal only after successful checks |
|
||||
| Manifest/seal and read-only verification | verify_eq: full relative inventory and final seal; synthetic units outside checkout |
|
||||
|
||||
This table records the required implementation targets, not completed validation.
|
||||
No native or formal validation is authorized for this worker.
|
||||
@@ -0,0 +1,236 @@
|
||||
# P28-02-EQ progress — S4 retained completion r03
|
||||
|
||||
S4 の保持済み実装に対する残作業を完了し、局所unitの証拠として提出する。
|
||||
正式受入は保留、原本加算0。
|
||||
以下の旧段階の記録は履歴であり、現在の提出状態を表すものではない。
|
||||
|
||||
- run_eq.main と verify_eq.recompute の check_probe 戻り値を検査し、
|
||||
ok:false を全 errors 付きで拒否する。driver の両モードで共通。
|
||||
両ファイル内の他の checker 呼出しも戻り値契約を確認済み。
|
||||
- 既存134件(元119件を含む)の試験本体を変更せず、12件を追加。
|
||||
driver/verifier の false/true、owned start/end/exit/diagnostic、profile、
|
||||
nine destinations、join 後の決定性不一致、保存済み結果・sidecar・
|
||||
raw/joined 入替えの拒否を対象とする。engine は全て不使用。
|
||||
- 対象クラス attempt 07: 8件中1件失敗。追加試験の模擬不一致が自己比較にも
|
||||
作用したため、試験だけを修正。失敗の raw/exit/SHA を保存。
|
||||
- attempt 08: 9件、86.276秒、OK、exit 0。
|
||||
- attempt 09: 保存済み結果の結合試験3件、0.025秒、OK、exit 0。
|
||||
- 最後の全件試験 attempt 10: `python3 -B test_eq.py`、146件、
|
||||
293.277秒、OK、exit 0(外側の所要時間293.5742515秒)。
|
||||
生出力は UNIT_OUTPUT_S4_ATTEMPT_10.txt と UNIT_OUTPUT.txt に保存。
|
||||
SHA-256: ff6fc0065772434f9ca35a1267e24d199057e339869a868942a41829327503bb。
|
||||
開始は01:05:07 UTCまで、期限まで300秒以上を確保した。全件実行は今回1回。
|
||||
- S4_SUPPLEMENTARY.json は Root の r09 JSON を直接読み、内容を変えず
|
||||
actual_commander_context に保存。追加 r03 と判断も提供ファイルから読む。
|
||||
5資料、過去8計画、API notes の SHA を照合済み。
|
||||
134件の元ファイル再構成SHAは cb742b252dbc278113b3c11c2431adac35b0c2e201a762a8ea1ac926e4af414b。
|
||||
- IMPLEMENTATION.md 冒頭に、全 S4 must、S4 binding、r01/r02/r03 の
|
||||
要件・コード・試験の対応表を記録した。旧文書と全失敗履歴は保持。
|
||||
- 外部 retained copy の読取りは PermissionError となったため、権限を変えず、
|
||||
W 内の保持prefixと元mainから元ファイルSHAを再現して確認した。
|
||||
読取り用heredocも実行前に失敗し、その後は python -c を使用した。
|
||||
|
||||
過去のS4 attempt 01/02/04と補足生成assertは失敗のまま保持。
|
||||
attempt 05 の132件PASSはその版だけの事実。遅着した attempt 06 は
|
||||
134件/206.531秒/OKだが、provider exit124・完了通知/exit受領なし・未提出の
|
||||
事実は変更しない。今回の全件結果とは区別する。
|
||||
|
||||
提出後は Root の正確な S の native 7 phase → bundle 配置 →
|
||||
p28-02-eq-unit と p28-02-eq-native-verify → fresh 独立 Opus の全6条件レビュー →
|
||||
通常の資格確認・承認・統合・final → OPT/whole-unit。23/88、4/30は不変。
|
||||
worker は engine、正式validation、Runner、git書込み、他agent、製品変更、
|
||||
全回帰を実行していない。局所unitをnative、受入済みS、Q測定、製品PASSとは呼ばない。
|
||||
|
||||
## Retained prior progress (unchanged)
|
||||
|
||||
# P28-02-EQ progress — current S3b (repair 7)
|
||||
|
||||
stage S3b complete (not a failure; next is S4)
|
||||
|
||||
段階 S3b 完了(失敗ではない。次は S4)。指定に従い正式 status は blocked。
|
||||
S_eq は未提出。全6受入条件の正式判定は保留、原本加算0。
|
||||
|
||||
- E4: 両 role に共通の5経路を実装。E4-1 はその PID の
|
||||
definition_registry.get_facility_ids() を使い、登録順/文字順/件数、
|
||||
公開 bounds、全候補の preview、最初の配置可能候補、submit/処理結果を保持。
|
||||
空 registry、誤った列挙元、欠落した試行、false NA は拒否する。
|
||||
- E5: 4対象×dict/array×2方向の16組。handler 外で操作し、
|
||||
完全な前後 S/K/C、返却値、digest、全イベント、別区間の signal を保持。
|
||||
aliasing は changed path/value 付きの existing-defect として出力し、PASS にしない。
|
||||
- checker: 39 scenario(既存E3の18 + E4の5 + E5の16)の結合、
|
||||
区間連続、全イベント、restore 0/load 1、X(P,event)、所有権を検査。
|
||||
caller の PASS や、publish 時点だけによる cache_stale 判定は拒否する。
|
||||
- 比較器の局所修正は、追加試験の失敗で確認した2点だけ:
|
||||
E5外から内の直後の cached digest 不整合を既存不具合として保持すること、
|
||||
返却値の typed facts にも辞書順だけの fallback を適用すること。
|
||||
- 既存91件の試験ソースを元の構成に再結合した SHA は
|
||||
f81185e506954964bb96b31a569233202a1a7e7c78b2121aba6ab3f2e24d7e1e と一致。
|
||||
E3本体、過去の進捗と全試験履歴は保持した。
|
||||
- 最終局所 unit: python3 -B test_eq.py、119 tests、OK、終了コード0。
|
||||
既存91 + S3b追加28。Godot/native・正式validationは未実行。
|
||||
生出力は UNIT_OUTPUT_S3B_ATTEMPT_09.txt と UNIT_OUTPUT.txt、対応SHAを保存。
|
||||
- S3b試行履歴(すべて生出力/SHAを保存):
|
||||
01=91件PASS、02=追加試験の構文エラー、
|
||||
03=114件中digest既存不具合の比較試験1件失敗、
|
||||
04/05=114件PASS、06=118件PASS、
|
||||
07=辞書順fallbackの単独試験1件失敗、
|
||||
08=119件中そのfixtureのcheckpoint欠落で1件失敗、
|
||||
09=119件PASS。失敗を成功で上書きしていない。
|
||||
- S3B_SUPPLEMENTARY.json の単一 actual_commander_context key に
|
||||
両S3b計画、両S3計画、両段階計画、今回のRUN判断全文を保持。
|
||||
計画6件のSHA、SPEC/TASK、references/registration、読取専用補足、
|
||||
S2/S3a補足、既存出力のSHAを照合した。
|
||||
|
||||
次はS4(driver・verify・bundleと提出)。IMPLEMENTATION.md末尾に、
|
||||
lifecycle.e45、e45-NN、raw/joined facts、sidecar、既存不具合の結合を追記。
|
||||
その後にRootの凍結Sで7 native phase、両validation、独立Opusレビュー、
|
||||
通常の資格確認・承認・統合・final。S3bのunit結果をnative/Qの結果とは呼ばない。
|
||||
|
||||
engine、Runner、git書込み、他agent、製品変更、全回帰は実行していない。
|
||||
|
||||
## Retained prior S3b-blocked/S3a/S2/S1 history (unchanged)
|
||||
|
||||
Final S3b unit SHA-256: 8360a2065b303099d5c546b3e4aecc0cc0ab0c2c1e5120b8034b6a1a64317030
|
||||
|
||||
# P28-02-EQ progress — S3b blocked before implementation
|
||||
|
||||
S3b is not complete. S_eq is not submitted. All six acceptance gates remain
|
||||
pending; original credit remains 0. The retained S3a history follows unchanged.
|
||||
|
||||
## Specification/API mismatch affecting E4-1 coverage
|
||||
|
||||
EQ_S3B_STAGE_PLAN.txt E4-1 explicitly chooses the facility definition list from
|
||||
`mvp_content_catalog`. The product's `scripts/data/mvp_content_catalog.gd:26-31`
|
||||
DEFAULT_PATHS contains only guest_classes, species, staff_candidates and
|
||||
unique_characters. Its get_ids(content_type) at :217-223 returns an empty list
|
||||
for an absent content type. It supplies no facility definition enumeration.
|
||||
|
||||
Facility definitions instead belong to `definition_registry`:
|
||||
`scripts/core/definition_registry.gd:64-75` exposes get_facility,
|
||||
get_facility_ids and get_all_facilities. Runtime initializes this registry from
|
||||
FacilityCatalog paths at `autoload/simulation_runtime.gd:446-447`, and the
|
||||
public preview_build_facility at :7660-7668 looks up that registry.
|
||||
|
||||
Using an absent catalog type and reporting NA would not prove that no facility
|
||||
is placeable. Replacing the explicitly fixed enumeration source with the
|
||||
registry changes the candidates used by the required E4-1 acceptance scenario.
|
||||
Per the instruction not to supplement missing specifications, this needs an
|
||||
explicit correction of E4-1 to authorize the actual definition source. Proposed
|
||||
correction: enumerate runtime.definition_registry.get_facility_ids() in textual
|
||||
ID order, retaining the specified cell scan and public placement check. This is
|
||||
a proposal only, not an implemented or approved change.
|
||||
|
||||
Only this progress note changed. No implementation or tests were changed or
|
||||
removed. The supplied SHA values for IMPLEMENTATION.md, eq_probe.gd, check_eq.py,
|
||||
compare_versions.py, test_eq.py and UNIT_OUTPUT.txt matched before this note.
|
||||
The 91-test result below is retained S3a evidence, not a test execution in this
|
||||
run. No new unit test, engine, Runner, git write, agent, or product operation ran.
|
||||
The first progress-note write attempt failed before writing because zsh could
|
||||
not create a heredoc temporary file; this note was then written by apply_patch.
|
||||
S3b E4/E5 and then S4 remain pending. Do not label this run S3b complete.
|
||||
|
||||
## Retained S3a/S2/S1 progress (unchanged historical text)
|
||||
|
||||
# P28-02-EQ progress — current S3a
|
||||
|
||||
stage S3a complete (not a failure; next is S3b)
|
||||
|
||||
段階 S3a 完了(失敗ではない。次は S3b)。計画に従い正式 status は blocked。
|
||||
S_eq は未提出。6受入条件はすべて保留、原本加算0。
|
||||
|
||||
- checker: phase key は正確に0..10。重複JSON keyも拒否。
|
||||
30分各checkpointにsnapshot_published → state_updatedがちょうど1組必要。
|
||||
測定開始の接続一覧にprobe自身の接続がなければ失敗。
|
||||
- probe/checker: E3の3 API × 6分類を、適用/NAの18行で記録・検査。
|
||||
B1の固定変異、実際のAPI戻り値、package全bytes/SHA、完全S/K/C、
|
||||
全イベント差、scenario signal、区間の連続性、X(B, ev_fail)を保持。
|
||||
codeを創作せず、期待外の製品結果は既存不具合候補として残す。
|
||||
- S1 comparatorは元のSHAのまま。S1/S2の試験本体を保持
|
||||
(指定checker修正に必要なS2 fixture/呼出しの変更のみ)。
|
||||
- 最終局所試験: python3 -B test_eq.py、**91 tests, OK**、終了コード0。
|
||||
S3a追加19件。Godot/native/正式validationは未実行。
|
||||
- 生出力: UNIT_OUTPUT.txt と UNIT_OUTPUT_S3A_ATTEMPT_04.txt。
|
||||
SHA-256: 02221ae41e5dd40ecdac0ec0d7ffc657f265d3194c3817583c2b88ad375f132b。
|
||||
S3aの01/02/03/04試行(72/85/91/91件、全件PASS)を個別に保存。
|
||||
既存のS1失敗出力・S2出力とSHAは変更せず保持。
|
||||
- S3A_SUPPLEMENTARY.json: 単一actual_commander_context keyに
|
||||
両S3計画・両段階計画・今回のRUN判断全文を保存。4計画のSHA一致。
|
||||
- SPEC/TASK/references/registration、read-only補足3件、S2補足、
|
||||
S1 comparatorと全ての既存UNIT_OUTPUT履歴のSHA一致を確認。
|
||||
|
||||
次はS3b(E4/E5)だけ。その後S4(driver/bundleと提出)、
|
||||
Rootの7 native phase、両validation、新しい独立Opusレビュー、
|
||||
通常の承認・統合・final。S4でlifecycle.measurement/e3/e3_b1と
|
||||
private evidenceを結合する必要がある。詳細はIMPLEMENTATION.md末尾。
|
||||
|
||||
engine、Runner、git書込み、他agent、製品変更、全回帰は実行していない。
|
||||
|
||||
## Retained S2/S1 progress (unchanged historical text)
|
||||
|
||||
# P28-02-EQ progress — current S2
|
||||
|
||||
stage S2 complete (not a failure; next is S3)
|
||||
|
||||
段階 S2 完了(失敗ではない。次は S3)。計画 G4 に従い status は blocked。
|
||||
正式提出はしていない。6受入条件はすべて保留、原本加算0。
|
||||
|
||||
- eq_probe.gd: DIAG の6段階起動、A1 encode/decode、A2 bytes roundtrip、
|
||||
A3 全 B1/毎 tick 差分、31 checkpoint、B の全イベント記録、
|
||||
guard 実値照合、private evidence、単一 report 行、close_requested を実装。
|
||||
- check_eq.py: S1 schema の形式/矛盾、正規化の結合、raw 観測/起動証跡、
|
||||
静的禁止の検査を追加。S3 の scenario は未着手。
|
||||
- test_eq.py: S1 43件を保持し、S2 29件を追加。最終 **72 tests, OK**。
|
||||
実行は python3 -B test_eq.py のみ。native・正式 validation は未実行。
|
||||
- 生出力: UNIT_OUTPUT.txt。SHA-256: 9d323abda9bfffa02faf3a9d5cb56aa87e647017c991eb55b4807cf734386698。
|
||||
S2 の3試行も UNIT_OUTPUT_S2_ATTEMPT_01/02/03.txt と SHA に保存。
|
||||
S1 の最終出力は UNIT_OUTPUT_S1_FINAL.txt に保存。下記の失敗履歴と
|
||||
UNIT_OUTPUT_ATTEMPT_01/02 は変更せず保持。
|
||||
- S2_SUPPLEMENTARY.json: 単一 actual_commander_context key に両計画全文、
|
||||
RUN判断全文、read-only 補足の path/SHA を保持。両計画の SHA 一致を確認。
|
||||
|
||||
次は S3 の E3/E4/E5 操作・結果・検査。その後 S4 の driver/bundle を実装し、
|
||||
Root/Runner の7 native phase、両 validation、新しい独立レビュー、承認・統合・final。
|
||||
engine、Runner、git 書込み、他 agent、製品変更、全回帰は実行していない。
|
||||
|
||||
## Retained S1 progress (unchanged historical text)
|
||||
|
||||
# P28-02-EQ progress
|
||||
|
||||
## Current stage
|
||||
|
||||
stage S1 complete (not a failure; next is S2)
|
||||
|
||||
段階 S1 完了(失敗ではない。次は S2)。正式な返却 status は計画 G4 に従い blocked。
|
||||
S_eq の提出、受入の自己確定、原本への加算はしていない。
|
||||
|
||||
## Completed
|
||||
|
||||
- compare_versions.py: typed tree 比較、F1–F3 の4つの normalize/restore 関数、
|
||||
全 checkpoint の差分再構成と tree SHA 再計算、report の S/latest/K/C/E2/
|
||||
scenario 比較、source map 1407件の固定と許可された変更集合の完全一致検査。
|
||||
- test_eq.py: 合成入力のみの43試験。型・挿入順・深い tree・可逆性・guard・
|
||||
violations・sidecar 改ざん・全イベント・比較除外・source 閉包の正常/拒否を検査。
|
||||
- IMPLEMENTATION.md: S2 向けの内部データ形式と、後続 checker/native の責任を記録。
|
||||
|
||||
## Unit evidence
|
||||
|
||||
実行: `python3 test_eq.py`(engine 不使用)。最新結果: **43 tests, OK**、終了コード0。
|
||||
生出力: `UNIT_OUTPUT.txt`。
|
||||
SHA-256: `cdca0cdd551ce76c6100c4dd90e04559551f9d88c054a19a2bc6a77e6572ae15`。
|
||||
|
||||
初回の36試験中1失敗(F3 sidecar の欠落を見逃した)は
|
||||
`UNIT_OUTPUT_ATTEMPT_01.txt` と `.sha256` にそのまま保持した。
|
||||
予約 token の復元漏れを拒否する修正後、41試験 PASS の中間出力も
|
||||
`UNIT_OUTPUT_ATTEMPT_02.txt` と `.sha256` に保持した。
|
||||
失敗を成功に書き換えていない。作成したファイルは削除していない。
|
||||
|
||||
## Remaining stages and gates
|
||||
|
||||
- S2: eq_probe.gd の6段階起動、Godot encode/decode と bytes roundtrip、31 checkpoint
|
||||
と E2 の evidence 書出し、check_eq.py の形式/静的検査、対応 unit。
|
||||
- S3: E3/E4/E5 専用区間、全ての場面/入力の実行と実値の保存、絶対条件の checker。
|
||||
- S4: run_eq.py と verify_eq.py、全依存 SHA の固定、bundle 結合/拒否試験、正式提出。
|
||||
- Root/Runner: 凍結した S_eq で7 native phase、両正式 validation、独立レビュー、
|
||||
通常の承認・統合・final。6受入条件は全て保留。
|
||||
|
||||
engine、Runner、git 書込み、他 agent、製品変更、全回帰は実行していない。
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
ff6fc0065772434f9ca35a1267e24d199057e339869a868942a41829327503bb UNIT_OUTPUT.txt
|
||||
@@ -0,0 +1,154 @@
|
||||
test_all_operations (__main__.Diffs) ... ok
|
||||
test_invalid_operations (__main__.Diffs) ... ok
|
||||
test_reconstruction_and_proofs (__main__.Diffs) ... ok
|
||||
test_attempt_to_normalize_violation_rejected (__main__.Normalization) ... ok
|
||||
test_environment_values_differ_but_normal_form_equal (__main__.Normalization) ... ok
|
||||
test_every_save_event_reversible (__main__.Normalization) ... ok
|
||||
test_f3_keeps_relative_paths_and_words (__main__.Normalization) ... ok
|
||||
test_guard_mismatch (__main__.Normalization) ... ok
|
||||
test_nested_lookalike_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_original_transport_sha_detects_forged_timing (__main__.Normalization) ... ok
|
||||
test_partial_timing_payload_rejected (__main__.Normalization) ... ok
|
||||
test_prefix_boundary_and_reserved_token (__main__.Normalization) ... ok
|
||||
test_sidecar_missing_duplicate_and_forged_paths (__main__.Normalization) ... ok
|
||||
test_snapshot_and_latest_reversible (__main__.Normalization) ... ok
|
||||
test_snapshot_event_outside_recent_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_wrong_event_and_source_are_preserved (__main__.Normalization) ... ok
|
||||
test_wrong_timing_type_and_negative (__main__.Normalization) ... ok
|
||||
test_all_events_beyond_recent_window (__main__.Reports) ... ok
|
||||
test_all_semantic_layers_compared (__main__.Reports) ... ok
|
||||
test_digest_alone_is_not_enough (__main__.Reports) ... ok
|
||||
test_event_original_types_and_order (__main__.Reports) ... ok
|
||||
test_event_start_and_ids (__main__.Reports) ... ok
|
||||
test_exclusions_keep_actual_values (__main__.Reports) ... ok
|
||||
test_handler_sets_and_counts (__main__.Reports) ... ok
|
||||
test_observation_full_layers (__main__.Reports) ... ok
|
||||
test_product_digest_self_consistency (__main__.Reports) ... ok
|
||||
test_same_report (__main__.Reports) ... ok
|
||||
test_scenario_existing_failures_preserved (__main__.Reports) ... ok
|
||||
test_timing_digest_rule (__main__.Reports) ... ok
|
||||
test_unknown_or_missing_fields_rejected (__main__.Reports) ... ok
|
||||
test_violation_presence_and_difference (__main__.Reports) ... ok
|
||||
test_O_cadence (__main__.S2Format) ... ok
|
||||
test_counter_and_published_ids_binding (__main__.S2Format) ... ok
|
||||
test_diff_and_same_as_S_transport (__main__.S2Format) ... ok
|
||||
test_digest_and_scenario_contradiction (__main__.S2Format) ... ok
|
||||
test_event_no_drop_duplicate_remap (__main__.S2Format) ... ok
|
||||
test_event_original_field_types_mandatory (__main__.S2Format) ... ok
|
||||
test_guard_actual_not_assumed (__main__.S2Format) ... ok
|
||||
test_harness_digest_allows_only_dictionary_order (__main__.S2Format) ... ok
|
||||
test_join_is_copy_and_retains_normalization_proof (__main__.S2Format) ... ok
|
||||
test_kernel_cache_contradictions (__main__.S2Format) ... ok
|
||||
test_lifecycle_guard_errors_and_boundaries (__main__.S2Format) ... ok
|
||||
test_missing_full_state_not_digest_only (__main__.S2Format) ... ok
|
||||
test_normalized_digest_and_raw_tree_are_both_bound (__main__.S2Format) ... ok
|
||||
test_product_event_shape_and_typed_array (__main__.S2Format) ... ok
|
||||
test_raw_observation_binding (__main__.S2Format) ... ok
|
||||
test_roundtrip_tree_sha_and_raw_sha (__main__.S2Format) ... ok
|
||||
test_s2_valid_and_not_formal_acceptance (__main__.S2Format) ... ok
|
||||
test_state_witness_and_observation_mutation (__main__.S2Format) ... ok
|
||||
test_stdout_exactly_one_line (__main__.S2Format) ... ok
|
||||
test_autoload_class_and_script_import (__main__.S2Static) ... ok
|
||||
test_comment_does_not_supply_proof (__main__.S2Static) ... ok
|
||||
test_current_probe (__main__.S2Static) ... ok
|
||||
test_full_state_and_godot_roundtrip_required (__main__.S2Static) ... ok
|
||||
test_no_changes_outside_preparation_or_step (__main__.S2Static) ... ok
|
||||
test_no_event_cap_or_duplicate_report (__main__.S2Static) ... ok
|
||||
test_pause_and_step_arguments (__main__.S2Static) ... ok
|
||||
test_textual_stringname_ordering (__main__.S2Static) ... ok
|
||||
test_unlisted_live_method_and_late_preparation (__main__.S2Static) ... ok
|
||||
test_variant_inference (__main__.S2Static) ... ok
|
||||
test_X_recent_limit_and_counter (__main__.S3a) ... ok
|
||||
test_duplicate_JSON_key_rejected (__main__.S3a) ... ok
|
||||
test_e3_NA_cannot_be_PASS_or_applied (__main__.S3a) ... ok
|
||||
test_e3_coverage_input_and_event_count_binding (__main__.S3a) ... ok
|
||||
test_e3_invented_codes_and_missing_load_code (__main__.S3a) ... ok
|
||||
test_e3_valid_R_and_O_records (__main__.S3a) ... ok
|
||||
test_envelope_duplicates_not_defect (__main__.S3a) ... ok
|
||||
test_event_count_defect_not_silently_accepted (__main__.S3a) ... ok
|
||||
test_exact_phase_keys (__main__.S3a) ... ok
|
||||
test_interval_gap_rejected (__main__.S3a) ... ok
|
||||
test_invalid_input_accepted_is_not_PASS (__main__.S3a) ... ok
|
||||
test_load_payload_and_pause_outcome (__main__.S3a) ... ok
|
||||
test_operation_moved_outside_scenario_rejected (__main__.S3a) ... ok
|
||||
test_package_fixed_mutations_and_hashes (__main__.S3a) ... ok
|
||||
test_probe_connection_required (__main__.S3a) ... ok
|
||||
test_rejection_mutation_retained_as_defect (__main__.S3a) ... ok
|
||||
test_save_refusal_makes_load_NA (__main__.S3a) ... ok
|
||||
test_scenario_mutation_static_boundary (__main__.S3a) ... ok
|
||||
test_signals_all_minutes_and_order (__main__.S3a) ... ok
|
||||
test_E5_cached_digest_defect_is_comparable (__main__.S3b) ... ok
|
||||
test_NA_not_PASS (__main__.S3b) ... ok
|
||||
test_aliasing_cannot_be_PASS (__main__.S3b) ... ok
|
||||
test_aliasing_missing_record (__main__.S3b) ... ok
|
||||
test_all_paths_and_ownership_R_O (__main__.S3b) ... ok
|
||||
test_digest_defect_other_checkpoint_still_rejected (__main__.S3b) ... ok
|
||||
test_digest_materialization_required (__main__.S3b) ... ok
|
||||
test_empty_registry_not_NA (__main__.S3b) ... ok
|
||||
test_event_count_mismatch (__main__.S3b) ... ok
|
||||
test_facts_normalization_is_reversible (__main__.S3b) ... ok
|
||||
test_first_placeable_choice (__main__.S3b) ... ok
|
||||
test_interval_gap (__main__.S3b) ... ok
|
||||
test_joined_s3b_self_comparison (__main__.S3b) ... ok
|
||||
test_load_X_not_digest_only (__main__.S3b) ... ok
|
||||
test_load_extra_event (__main__.S3b) ... ok
|
||||
test_missing_path_and_combination (__main__.S3b) ... ok
|
||||
test_missing_preview_observation (__main__.S3b) ... ok
|
||||
test_missing_trial (__main__.S3b) ... ok
|
||||
test_nested_mutation_required (__main__.S3b) ... ok
|
||||
test_no_staleness_assertion_for_non_tick (__main__.S3b) ... ok
|
||||
test_ownership_fact_dictionary_order_fallback (__main__.S3b) ... ok
|
||||
test_path_order (__main__.S3b) ... ok
|
||||
test_restore_extra_event (__main__.S3b) ... ok
|
||||
test_signal_facts_cannot_be_dropped (__main__.S3b) ... ok
|
||||
test_sort_rule_rejected (__main__.S3b) ... ok
|
||||
test_static_handler_and_outside_mutations (__main__.S3b) ... ok
|
||||
test_unpreviewed_choice (__main__.S3b) ... ok
|
||||
test_wrong_registry_in_either_role (__main__.S3b) ... ok
|
||||
test_checkout_temp_destination_rejected (__main__.S4Bundle) ... ok
|
||||
test_existing_output_never_overwritten (__main__.S4Bundle) ... ok
|
||||
test_import_closure_rejections (__main__.S4Bundle) ... ok
|
||||
test_missing_bundle_manifest_seal_and_changed_bytes (__main__.S4Bundle) ... ok
|
||||
test_missing_private_evidence_and_extra_rejected (__main__.S4Bundle) ... ok
|
||||
test_missing_profile_not_export_success (__main__.S4Bundle) ... ok
|
||||
test_phase_role_pid_audio_and_guard_rejected (__main__.S4Bundle) ... ok
|
||||
test_rebound_lifecycle_and_scenario_contradictions (__main__.S4Bundle) ... ok
|
||||
test_seal_normal_and_changes_not_native_proof (__main__.S4Bundle) ... ok
|
||||
test_synthetic_phase_all_real_checkers_not_native_proof (__main__.S4Bundle) ... ok
|
||||
test_copied_manifest_root_and_destination_count_rejected (__main__.S4NativeBundleLogic) ... ok
|
||||
test_failure_keeps_raw_and_no_bundle_without_starting_engine (__main__.S4NativeBundleLogic) ... ok
|
||||
test_gate_none_success_not_boolean (__main__.S4NativeBundleLogic) ... ok
|
||||
test_receipt_and_source_rejection_matrix (__main__.S4NativeBundleLogic) ... ok
|
||||
test_synthetic_full_bundle_positive_not_native_evidence (__main__.S4NativeBundleLogic) ... ok
|
||||
test_check_accepts_true (__main__.S4ProbeAdmission) ... ok
|
||||
test_check_rejects_false_all_errors (__main__.S4ProbeAdmission) ... ok
|
||||
test_run_admission_accepts_true_mock_launch_only (__main__.S4ProbeAdmission) ... ok
|
||||
test_run_admission_rejects_false_without_engine (__main__.S4ProbeAdmission) ... ok
|
||||
test_nine_original_destinations_required (__main__.S4RemainingBindings) ... ok
|
||||
test_nonzero_determinism_rejected_after_real_join (__main__.S4RemainingBindings) ... ok
|
||||
test_owned_lifecycle_exit_diagnostic_and_profile_rejections (__main__.S4RemainingBindings) ... ok
|
||||
test_verifier_accepts_true_recomputes_raw (__main__.S4RemainingBindings) ... ok
|
||||
test_verifier_rejects_false_with_every_error (__main__.S4RemainingBindings) ... ok
|
||||
test_cached_verdict_not_trusted (__main__.S4StoredResultBindings) ... ok
|
||||
test_missing_sidecar_rejected_after_seal (__main__.S4StoredResultBindings) ... ok
|
||||
test_raw_joined_substitution_rejected_after_seal (__main__.S4StoredResultBindings) ... ok
|
||||
test_fixed_scenario_paths (__main__.SourcesAndMetrics) ... ok
|
||||
test_metric_ranges (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_closure_synthetic_registered_map (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_pin_is_not_caller_controlled (__main__.SourcesAndMetrics) ... ok
|
||||
test_array_order_and_all_differences (__main__.TypedTrees) ... ok
|
||||
test_components_and_sha (__main__.TypedTrees) ... ok
|
||||
test_deep_state_not_truncated (__main__.TypedTrees) ... ok
|
||||
test_duplicate_textual_keys_rejected (__main__.TypedTrees) ... ok
|
||||
test_exact_and_types (__main__.TypedTrees) ... ok
|
||||
test_nested_order_all_paths (__main__.TypedTrees) ... ok
|
||||
test_nonstring_keys_keep_types_and_values (__main__.TypedTrees) ... ok
|
||||
test_unsupported_and_malformed (__main__.TypedTrees) ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 146 tests in 293.277s
|
||||
|
||||
OK
|
||||
|
||||
exit_code=0
|
||||
wall_seconds=293.5742515
|
||||
+1
@@ -0,0 +1 @@
|
||||
307486177b76602cbe68acae24c9560d501b3b866136d8e69802ec24c28e8be8 UNIT_OUTPUT_ATTEMPT_01.txt
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
test_all_operations (__main__.Diffs) ... ok
|
||||
test_invalid_operations (__main__.Diffs) ... ok
|
||||
test_reconstruction_and_proofs (__main__.Diffs) ... ok
|
||||
test_attempt_to_normalize_violation_rejected (__main__.Normalization) ... ok
|
||||
test_environment_values_differ_but_normal_form_equal (__main__.Normalization) ... ok
|
||||
test_every_save_event_reversible (__main__.Normalization) ... ok
|
||||
test_guard_mismatch (__main__.Normalization) ... ok
|
||||
test_nested_lookalike_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_original_transport_sha_detects_forged_timing (__main__.Normalization) ... ok
|
||||
test_sidecar_missing_duplicate_and_forged_paths (__main__.Normalization) ... test_snapshot_and_latest_reversible (__main__.Normalization) ... ok
|
||||
test_snapshot_event_outside_recent_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_wrong_event_and_source_are_preserved (__main__.Normalization) ... ok
|
||||
test_wrong_timing_type_and_negative (__main__.Normalization) ... ok
|
||||
test_all_semantic_layers_compared (__main__.Reports) ... ok
|
||||
test_digest_alone_is_not_enough (__main__.Reports) ... ok
|
||||
test_event_start_and_ids (__main__.Reports) ... ok
|
||||
test_exclusions_keep_actual_values (__main__.Reports) ... ok
|
||||
test_handler_sets_and_counts (__main__.Reports) ... ok
|
||||
test_observation_full_layers (__main__.Reports) ... ok
|
||||
test_product_digest_self_consistency (__main__.Reports) ... ok
|
||||
test_same_report (__main__.Reports) ... ok
|
||||
test_scenario_existing_failures_preserved (__main__.Reports) ... ok
|
||||
test_timing_digest_rule (__main__.Reports) ... ok
|
||||
test_unknown_or_missing_fields_rejected (__main__.Reports) ... ok
|
||||
test_violation_presence_and_difference (__main__.Reports) ... ok
|
||||
test_metric_ranges (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_closure_synthetic_registered_map (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_pin_is_not_caller_controlled (__main__.SourcesAndMetrics) ... ok
|
||||
test_array_order_and_all_differences (__main__.TypedTrees) ... ok
|
||||
test_components_and_sha (__main__.TypedTrees) ... ok
|
||||
test_deep_state_not_truncated (__main__.TypedTrees) ... ok
|
||||
test_duplicate_textual_keys_rejected (__main__.TypedTrees) ... ok
|
||||
test_exact_and_types (__main__.TypedTrees) ... ok
|
||||
test_nested_order_all_paths (__main__.TypedTrees) ... ok
|
||||
test_unsupported_and_malformed (__main__.TypedTrees) ... ok
|
||||
|
||||
======================================================================
|
||||
FAIL: test_sidecar_missing_duplicate_and_forged_paths (__main__.Normalization) (bad={'entries': [{'event_index': 0, 'path': [['key', [4, 'payload']], ['key', [4, 'duration_us']]], 'key': 'duration_us', 'original_node': [2, 7]}, {'event_index': 0, 'path': [['key', [4, 'payload']], ['key', [4, 'runtime_duration_us']]], 'key': 'runtime_duration_us', 'original_node': [2, 8]}], 'violations': [], 'profile_root': {'root': '/private/a', 'actual_user_data_dir': '/private/a', 'matches_guard': True}})
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 218, in test_sidecar_missing_duplicate_and_forged_paths
|
||||
eq.restore_events(n, bad, profile())
|
||||
AssertionError: EvidenceError not raised
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 36 tests in 0.847s
|
||||
|
||||
FAILED (failures=1)
|
||||
+1
@@ -0,0 +1 @@
|
||||
07144a7f1941162227f54fefd1961ed0f209e97282432723bbda534079582e4e UNIT_OUTPUT_ATTEMPT_02.txt
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
test_all_operations (__main__.Diffs) ... ok
|
||||
test_invalid_operations (__main__.Diffs) ... ok
|
||||
test_reconstruction_and_proofs (__main__.Diffs) ... ok
|
||||
test_attempt_to_normalize_violation_rejected (__main__.Normalization) ... ok
|
||||
test_environment_values_differ_but_normal_form_equal (__main__.Normalization) ... ok
|
||||
test_every_save_event_reversible (__main__.Normalization) ... ok
|
||||
test_f3_keeps_relative_paths_and_words (__main__.Normalization) ... ok
|
||||
test_guard_mismatch (__main__.Normalization) ... ok
|
||||
test_nested_lookalike_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_original_transport_sha_detects_forged_timing (__main__.Normalization) ... ok
|
||||
test_prefix_boundary_and_reserved_token (__main__.Normalization) ... ok
|
||||
test_sidecar_missing_duplicate_and_forged_paths (__main__.Normalization) ... ok
|
||||
test_snapshot_and_latest_reversible (__main__.Normalization) ... ok
|
||||
test_snapshot_event_outside_recent_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_wrong_event_and_source_are_preserved (__main__.Normalization) ... ok
|
||||
test_wrong_timing_type_and_negative (__main__.Normalization) ... ok
|
||||
test_all_events_beyond_recent_window (__main__.Reports) ... ok
|
||||
test_all_semantic_layers_compared (__main__.Reports) ... ok
|
||||
test_digest_alone_is_not_enough (__main__.Reports) ... ok
|
||||
test_event_original_types_and_order (__main__.Reports) ... ok
|
||||
test_event_start_and_ids (__main__.Reports) ... ok
|
||||
test_exclusions_keep_actual_values (__main__.Reports) ... ok
|
||||
test_handler_sets_and_counts (__main__.Reports) ... ok
|
||||
test_observation_full_layers (__main__.Reports) ... ok
|
||||
test_product_digest_self_consistency (__main__.Reports) ... ok
|
||||
test_same_report (__main__.Reports) ... ok
|
||||
test_scenario_existing_failures_preserved (__main__.Reports) ... ok
|
||||
test_timing_digest_rule (__main__.Reports) ... ok
|
||||
test_unknown_or_missing_fields_rejected (__main__.Reports) ... ok
|
||||
test_violation_presence_and_difference (__main__.Reports) ... ok
|
||||
test_fixed_scenario_paths (__main__.SourcesAndMetrics) ... ok
|
||||
test_metric_ranges (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_closure_synthetic_registered_map (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_pin_is_not_caller_controlled (__main__.SourcesAndMetrics) ... ok
|
||||
test_array_order_and_all_differences (__main__.TypedTrees) ... ok
|
||||
test_components_and_sha (__main__.TypedTrees) ... ok
|
||||
test_deep_state_not_truncated (__main__.TypedTrees) ... ok
|
||||
test_duplicate_textual_keys_rejected (__main__.TypedTrees) ... ok
|
||||
test_exact_and_types (__main__.TypedTrees) ... ok
|
||||
test_nested_order_all_paths (__main__.TypedTrees) ... ok
|
||||
test_unsupported_and_malformed (__main__.TypedTrees) ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 41 tests in 1.382s
|
||||
|
||||
OK
|
||||
+1
@@ -0,0 +1 @@
|
||||
cdca0cdd551ce76c6100c4dd90e04559551f9d88c054a19a2bc6a77e6572ae15 UNIT_OUTPUT_S1_FINAL.txt
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
test_all_operations (__main__.Diffs) ... ok
|
||||
test_invalid_operations (__main__.Diffs) ... ok
|
||||
test_reconstruction_and_proofs (__main__.Diffs) ... ok
|
||||
test_attempt_to_normalize_violation_rejected (__main__.Normalization) ... ok
|
||||
test_environment_values_differ_but_normal_form_equal (__main__.Normalization) ... ok
|
||||
test_every_save_event_reversible (__main__.Normalization) ... ok
|
||||
test_f3_keeps_relative_paths_and_words (__main__.Normalization) ... ok
|
||||
test_guard_mismatch (__main__.Normalization) ... ok
|
||||
test_nested_lookalike_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_original_transport_sha_detects_forged_timing (__main__.Normalization) ... ok
|
||||
test_partial_timing_payload_rejected (__main__.Normalization) ... ok
|
||||
test_prefix_boundary_and_reserved_token (__main__.Normalization) ... ok
|
||||
test_sidecar_missing_duplicate_and_forged_paths (__main__.Normalization) ... ok
|
||||
test_snapshot_and_latest_reversible (__main__.Normalization) ... ok
|
||||
test_snapshot_event_outside_recent_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_wrong_event_and_source_are_preserved (__main__.Normalization) ... ok
|
||||
test_wrong_timing_type_and_negative (__main__.Normalization) ... ok
|
||||
test_all_events_beyond_recent_window (__main__.Reports) ... ok
|
||||
test_all_semantic_layers_compared (__main__.Reports) ... ok
|
||||
test_digest_alone_is_not_enough (__main__.Reports) ... ok
|
||||
test_event_original_types_and_order (__main__.Reports) ... ok
|
||||
test_event_start_and_ids (__main__.Reports) ... ok
|
||||
test_exclusions_keep_actual_values (__main__.Reports) ... ok
|
||||
test_handler_sets_and_counts (__main__.Reports) ... ok
|
||||
test_observation_full_layers (__main__.Reports) ... ok
|
||||
test_product_digest_self_consistency (__main__.Reports) ... ok
|
||||
test_same_report (__main__.Reports) ... ok
|
||||
test_scenario_existing_failures_preserved (__main__.Reports) ... ok
|
||||
test_timing_digest_rule (__main__.Reports) ... ok
|
||||
test_unknown_or_missing_fields_rejected (__main__.Reports) ... ok
|
||||
test_violation_presence_and_difference (__main__.Reports) ... ok
|
||||
test_fixed_scenario_paths (__main__.SourcesAndMetrics) ... ok
|
||||
test_metric_ranges (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_closure_synthetic_registered_map (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_pin_is_not_caller_controlled (__main__.SourcesAndMetrics) ... ok
|
||||
test_array_order_and_all_differences (__main__.TypedTrees) ... ok
|
||||
test_components_and_sha (__main__.TypedTrees) ... ok
|
||||
test_deep_state_not_truncated (__main__.TypedTrees) ... ok
|
||||
test_duplicate_textual_keys_rejected (__main__.TypedTrees) ... ok
|
||||
test_exact_and_types (__main__.TypedTrees) ... ok
|
||||
test_nested_order_all_paths (__main__.TypedTrees) ... ok
|
||||
test_nonstring_keys_keep_types_and_values (__main__.TypedTrees) ... ok
|
||||
test_unsupported_and_malformed (__main__.TypedTrees) ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 43 tests in 1.432s
|
||||
|
||||
OK
|
||||
+1
@@ -0,0 +1 @@
|
||||
25953dfc5f8bc3759ae66f6403b162100fb0217c4476f308616b8ab78a2cc67e UNIT_OUTPUT_S2_ATTEMPT_01.txt
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
test_all_operations (__main__.Diffs) ... ok
|
||||
test_invalid_operations (__main__.Diffs) ... ok
|
||||
test_reconstruction_and_proofs (__main__.Diffs) ... ok
|
||||
test_attempt_to_normalize_violation_rejected (__main__.Normalization) ... ok
|
||||
test_environment_values_differ_but_normal_form_equal (__main__.Normalization) ... ok
|
||||
test_every_save_event_reversible (__main__.Normalization) ... ok
|
||||
test_f3_keeps_relative_paths_and_words (__main__.Normalization) ... ok
|
||||
test_guard_mismatch (__main__.Normalization) ... ok
|
||||
test_nested_lookalike_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_original_transport_sha_detects_forged_timing (__main__.Normalization) ... ok
|
||||
test_partial_timing_payload_rejected (__main__.Normalization) ... ok
|
||||
test_prefix_boundary_and_reserved_token (__main__.Normalization) ... ok
|
||||
test_sidecar_missing_duplicate_and_forged_paths (__main__.Normalization) ... ok
|
||||
test_snapshot_and_latest_reversible (__main__.Normalization) ... ok
|
||||
test_snapshot_event_outside_recent_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_wrong_event_and_source_are_preserved (__main__.Normalization) ... ok
|
||||
test_wrong_timing_type_and_negative (__main__.Normalization) ... ok
|
||||
test_all_events_beyond_recent_window (__main__.Reports) ... ok
|
||||
test_all_semantic_layers_compared (__main__.Reports) ... ok
|
||||
test_digest_alone_is_not_enough (__main__.Reports) ... ok
|
||||
test_event_original_types_and_order (__main__.Reports) ... ok
|
||||
test_event_start_and_ids (__main__.Reports) ... ok
|
||||
test_exclusions_keep_actual_values (__main__.Reports) ... ok
|
||||
test_handler_sets_and_counts (__main__.Reports) ... ok
|
||||
test_observation_full_layers (__main__.Reports) ... ok
|
||||
test_product_digest_self_consistency (__main__.Reports) ... ok
|
||||
test_same_report (__main__.Reports) ... ok
|
||||
test_scenario_existing_failures_preserved (__main__.Reports) ... ok
|
||||
test_timing_digest_rule (__main__.Reports) ... ok
|
||||
test_unknown_or_missing_fields_rejected (__main__.Reports) ... ok
|
||||
test_violation_presence_and_difference (__main__.Reports) ... ok
|
||||
test_O_cadence (__main__.S2Format) ... ok
|
||||
test_counter_and_published_ids_binding (__main__.S2Format) ... ok
|
||||
test_diff_and_same_as_S_transport (__main__.S2Format) ... ok
|
||||
test_digest_and_scenario_contradiction (__main__.S2Format) ... ok
|
||||
test_event_no_drop_duplicate_remap (__main__.S2Format) ... ok
|
||||
test_event_original_field_types_mandatory (__main__.S2Format) ... ok
|
||||
test_guard_actual_not_assumed (__main__.S2Format) ... ok
|
||||
test_join_is_copy_and_retains_normalization_proof (__main__.S2Format) ... ok
|
||||
test_kernel_cache_contradictions (__main__.S2Format) ... ok
|
||||
test_missing_full_state_not_digest_only (__main__.S2Format) ... ok
|
||||
test_product_event_shape_and_typed_array (__main__.S2Format) ... ok
|
||||
test_raw_observation_binding (__main__.S2Format) ... ok
|
||||
test_roundtrip_tree_sha_and_raw_sha (__main__.S2Format) ... ok
|
||||
test_s2_valid_and_not_formal_acceptance (__main__.S2Format) ... ok
|
||||
test_state_witness_and_observation_mutation (__main__.S2Format) ... ok
|
||||
test_stdout_exactly_one_line (__main__.S2Format) ... ok
|
||||
test_autoload_class_and_script_import (__main__.S2Static) ... ok
|
||||
test_comment_does_not_supply_proof (__main__.S2Static) ... ok
|
||||
test_current_probe (__main__.S2Static) ... ok
|
||||
test_full_state_and_godot_roundtrip_required (__main__.S2Static) ... ok
|
||||
test_no_changes_outside_preparation_or_step (__main__.S2Static) ... ok
|
||||
test_no_event_cap_or_duplicate_report (__main__.S2Static) ... ok
|
||||
test_pause_and_step_arguments (__main__.S2Static) ... ok
|
||||
test_textual_stringname_ordering (__main__.S2Static) ... ok
|
||||
test_variant_inference (__main__.S2Static) ... ok
|
||||
test_fixed_scenario_paths (__main__.SourcesAndMetrics) ... ok
|
||||
test_metric_ranges (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_closure_synthetic_registered_map (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_pin_is_not_caller_controlled (__main__.SourcesAndMetrics) ... ok
|
||||
test_array_order_and_all_differences (__main__.TypedTrees) ... ok
|
||||
test_components_and_sha (__main__.TypedTrees) ... ok
|
||||
test_deep_state_not_truncated (__main__.TypedTrees) ... ok
|
||||
test_duplicate_textual_keys_rejected (__main__.TypedTrees) ... ok
|
||||
test_exact_and_types (__main__.TypedTrees) ... ok
|
||||
test_nested_order_all_paths (__main__.TypedTrees) ... ok
|
||||
test_nonstring_keys_keep_types_and_values (__main__.TypedTrees) ... ok
|
||||
test_unsupported_and_malformed (__main__.TypedTrees) ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 68 tests in 4.042s
|
||||
|
||||
OK
|
||||
+1
@@ -0,0 +1 @@
|
||||
e26c986dda41b83143723e4c1c5b2ff1051a36b9a947b319341a2239cc3188de UNIT_OUTPUT_S2_ATTEMPT_02.txt
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
test_all_operations (__main__.Diffs) ... ok
|
||||
test_invalid_operations (__main__.Diffs) ... ok
|
||||
test_reconstruction_and_proofs (__main__.Diffs) ... ok
|
||||
test_attempt_to_normalize_violation_rejected (__main__.Normalization) ... ok
|
||||
test_environment_values_differ_but_normal_form_equal (__main__.Normalization) ... ok
|
||||
test_every_save_event_reversible (__main__.Normalization) ... ok
|
||||
test_f3_keeps_relative_paths_and_words (__main__.Normalization) ... ok
|
||||
test_guard_mismatch (__main__.Normalization) ... ok
|
||||
test_nested_lookalike_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_original_transport_sha_detects_forged_timing (__main__.Normalization) ... ok
|
||||
test_partial_timing_payload_rejected (__main__.Normalization) ... ok
|
||||
test_prefix_boundary_and_reserved_token (__main__.Normalization) ... ok
|
||||
test_sidecar_missing_duplicate_and_forged_paths (__main__.Normalization) ... ok
|
||||
test_snapshot_and_latest_reversible (__main__.Normalization) ... ok
|
||||
test_snapshot_event_outside_recent_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_wrong_event_and_source_are_preserved (__main__.Normalization) ... ok
|
||||
test_wrong_timing_type_and_negative (__main__.Normalization) ... ok
|
||||
test_all_events_beyond_recent_window (__main__.Reports) ... ok
|
||||
test_all_semantic_layers_compared (__main__.Reports) ... ok
|
||||
test_digest_alone_is_not_enough (__main__.Reports) ... ok
|
||||
test_event_original_types_and_order (__main__.Reports) ... ok
|
||||
test_event_start_and_ids (__main__.Reports) ... ok
|
||||
test_exclusions_keep_actual_values (__main__.Reports) ... ok
|
||||
test_handler_sets_and_counts (__main__.Reports) ... ok
|
||||
test_observation_full_layers (__main__.Reports) ... ok
|
||||
test_product_digest_self_consistency (__main__.Reports) ... ok
|
||||
test_same_report (__main__.Reports) ... ok
|
||||
test_scenario_existing_failures_preserved (__main__.Reports) ... ok
|
||||
test_timing_digest_rule (__main__.Reports) ... ok
|
||||
test_unknown_or_missing_fields_rejected (__main__.Reports) ... ok
|
||||
test_violation_presence_and_difference (__main__.Reports) ... ok
|
||||
test_O_cadence (__main__.S2Format) ... ok
|
||||
test_counter_and_published_ids_binding (__main__.S2Format) ... ok
|
||||
test_diff_and_same_as_S_transport (__main__.S2Format) ... ok
|
||||
test_digest_and_scenario_contradiction (__main__.S2Format) ... ok
|
||||
test_event_no_drop_duplicate_remap (__main__.S2Format) ... ok
|
||||
test_event_original_field_types_mandatory (__main__.S2Format) ... ok
|
||||
test_guard_actual_not_assumed (__main__.S2Format) ... ok
|
||||
test_join_is_copy_and_retains_normalization_proof (__main__.S2Format) ... ok
|
||||
test_kernel_cache_contradictions (__main__.S2Format) ... ok
|
||||
test_lifecycle_guard_errors_and_boundaries (__main__.S2Format) ... ok
|
||||
test_missing_full_state_not_digest_only (__main__.S2Format) ... ok
|
||||
test_normalized_digest_and_raw_tree_are_both_bound (__main__.S2Format) ... ok
|
||||
test_product_event_shape_and_typed_array (__main__.S2Format) ... ok
|
||||
test_raw_observation_binding (__main__.S2Format) ... ok
|
||||
test_roundtrip_tree_sha_and_raw_sha (__main__.S2Format) ... ok
|
||||
test_s2_valid_and_not_formal_acceptance (__main__.S2Format) ... ok
|
||||
test_state_witness_and_observation_mutation (__main__.S2Format) ... ok
|
||||
test_stdout_exactly_one_line (__main__.S2Format) ... ok
|
||||
test_autoload_class_and_script_import (__main__.S2Static) ... ok
|
||||
test_comment_does_not_supply_proof (__main__.S2Static) ... ok
|
||||
test_current_probe (__main__.S2Static) ... ok
|
||||
test_full_state_and_godot_roundtrip_required (__main__.S2Static) ... ok
|
||||
test_no_changes_outside_preparation_or_step (__main__.S2Static) ... ok
|
||||
test_no_event_cap_or_duplicate_report (__main__.S2Static) ... ok
|
||||
test_pause_and_step_arguments (__main__.S2Static) ... ok
|
||||
test_textual_stringname_ordering (__main__.S2Static) ... ok
|
||||
test_unlisted_live_method_and_late_preparation (__main__.S2Static) ... ok
|
||||
test_variant_inference (__main__.S2Static) ... ok
|
||||
test_fixed_scenario_paths (__main__.SourcesAndMetrics) ... ok
|
||||
test_metric_ranges (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_closure_synthetic_registered_map (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_pin_is_not_caller_controlled (__main__.SourcesAndMetrics) ... ok
|
||||
test_array_order_and_all_differences (__main__.TypedTrees) ... ok
|
||||
test_components_and_sha (__main__.TypedTrees) ... ok
|
||||
test_deep_state_not_truncated (__main__.TypedTrees) ... ok
|
||||
test_duplicate_textual_keys_rejected (__main__.TypedTrees) ... ok
|
||||
test_exact_and_types (__main__.TypedTrees) ... ok
|
||||
test_nested_order_all_paths (__main__.TypedTrees) ... ok
|
||||
test_nonstring_keys_keep_types_and_values (__main__.TypedTrees) ... ok
|
||||
test_unsupported_and_malformed (__main__.TypedTrees) ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 71 tests in 4.371s
|
||||
|
||||
OK
|
||||
+1
@@ -0,0 +1 @@
|
||||
9d323abda9bfffa02faf3a9d5cb56aa87e647017c991eb55b4807cf734386698 UNIT_OUTPUT_S2_ATTEMPT_03.txt
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
test_all_operations (__main__.Diffs) ... ok
|
||||
test_invalid_operations (__main__.Diffs) ... ok
|
||||
test_reconstruction_and_proofs (__main__.Diffs) ... ok
|
||||
test_attempt_to_normalize_violation_rejected (__main__.Normalization) ... ok
|
||||
test_environment_values_differ_but_normal_form_equal (__main__.Normalization) ... ok
|
||||
test_every_save_event_reversible (__main__.Normalization) ... ok
|
||||
test_f3_keeps_relative_paths_and_words (__main__.Normalization) ... ok
|
||||
test_guard_mismatch (__main__.Normalization) ... ok
|
||||
test_nested_lookalike_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_original_transport_sha_detects_forged_timing (__main__.Normalization) ... ok
|
||||
test_partial_timing_payload_rejected (__main__.Normalization) ... ok
|
||||
test_prefix_boundary_and_reserved_token (__main__.Normalization) ... ok
|
||||
test_sidecar_missing_duplicate_and_forged_paths (__main__.Normalization) ... ok
|
||||
test_snapshot_and_latest_reversible (__main__.Normalization) ... ok
|
||||
test_snapshot_event_outside_recent_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_wrong_event_and_source_are_preserved (__main__.Normalization) ... ok
|
||||
test_wrong_timing_type_and_negative (__main__.Normalization) ... ok
|
||||
test_all_events_beyond_recent_window (__main__.Reports) ... ok
|
||||
test_all_semantic_layers_compared (__main__.Reports) ... ok
|
||||
test_digest_alone_is_not_enough (__main__.Reports) ... ok
|
||||
test_event_original_types_and_order (__main__.Reports) ... ok
|
||||
test_event_start_and_ids (__main__.Reports) ... ok
|
||||
test_exclusions_keep_actual_values (__main__.Reports) ... ok
|
||||
test_handler_sets_and_counts (__main__.Reports) ... ok
|
||||
test_observation_full_layers (__main__.Reports) ... ok
|
||||
test_product_digest_self_consistency (__main__.Reports) ... ok
|
||||
test_same_report (__main__.Reports) ... ok
|
||||
test_scenario_existing_failures_preserved (__main__.Reports) ... ok
|
||||
test_timing_digest_rule (__main__.Reports) ... ok
|
||||
test_unknown_or_missing_fields_rejected (__main__.Reports) ... ok
|
||||
test_violation_presence_and_difference (__main__.Reports) ... ok
|
||||
test_O_cadence (__main__.S2Format) ... ok
|
||||
test_counter_and_published_ids_binding (__main__.S2Format) ... ok
|
||||
test_diff_and_same_as_S_transport (__main__.S2Format) ... ok
|
||||
test_digest_and_scenario_contradiction (__main__.S2Format) ... ok
|
||||
test_event_no_drop_duplicate_remap (__main__.S2Format) ... ok
|
||||
test_event_original_field_types_mandatory (__main__.S2Format) ... ok
|
||||
test_guard_actual_not_assumed (__main__.S2Format) ... ok
|
||||
test_harness_digest_allows_only_dictionary_order (__main__.S2Format) ... ok
|
||||
test_join_is_copy_and_retains_normalization_proof (__main__.S2Format) ... ok
|
||||
test_kernel_cache_contradictions (__main__.S2Format) ... ok
|
||||
test_lifecycle_guard_errors_and_boundaries (__main__.S2Format) ... ok
|
||||
test_missing_full_state_not_digest_only (__main__.S2Format) ... ok
|
||||
test_normalized_digest_and_raw_tree_are_both_bound (__main__.S2Format) ... ok
|
||||
test_product_event_shape_and_typed_array (__main__.S2Format) ... ok
|
||||
test_raw_observation_binding (__main__.S2Format) ... ok
|
||||
test_roundtrip_tree_sha_and_raw_sha (__main__.S2Format) ... ok
|
||||
test_s2_valid_and_not_formal_acceptance (__main__.S2Format) ... ok
|
||||
test_state_witness_and_observation_mutation (__main__.S2Format) ... ok
|
||||
test_stdout_exactly_one_line (__main__.S2Format) ... ok
|
||||
test_autoload_class_and_script_import (__main__.S2Static) ... ok
|
||||
test_comment_does_not_supply_proof (__main__.S2Static) ... ok
|
||||
test_current_probe (__main__.S2Static) ... ok
|
||||
test_full_state_and_godot_roundtrip_required (__main__.S2Static) ... ok
|
||||
test_no_changes_outside_preparation_or_step (__main__.S2Static) ... ok
|
||||
test_no_event_cap_or_duplicate_report (__main__.S2Static) ... ok
|
||||
test_pause_and_step_arguments (__main__.S2Static) ... ok
|
||||
test_textual_stringname_ordering (__main__.S2Static) ... ok
|
||||
test_unlisted_live_method_and_late_preparation (__main__.S2Static) ... ok
|
||||
test_variant_inference (__main__.S2Static) ... ok
|
||||
test_fixed_scenario_paths (__main__.SourcesAndMetrics) ... ok
|
||||
test_metric_ranges (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_closure_synthetic_registered_map (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_pin_is_not_caller_controlled (__main__.SourcesAndMetrics) ... ok
|
||||
test_array_order_and_all_differences (__main__.TypedTrees) ... ok
|
||||
test_components_and_sha (__main__.TypedTrees) ... ok
|
||||
test_deep_state_not_truncated (__main__.TypedTrees) ... ok
|
||||
test_duplicate_textual_keys_rejected (__main__.TypedTrees) ... ok
|
||||
test_exact_and_types (__main__.TypedTrees) ... ok
|
||||
test_nested_order_all_paths (__main__.TypedTrees) ... ok
|
||||
test_nonstring_keys_keep_types_and_values (__main__.TypedTrees) ... ok
|
||||
test_unsupported_and_malformed (__main__.TypedTrees) ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 72 tests in 4.753s
|
||||
|
||||
OK
|
||||
+1
@@ -0,0 +1 @@
|
||||
5cf84b792b5f87cd4183f41cf3a846962a53dc0aa33049c3c55f290356584641 UNIT_OUTPUT_S3A_ATTEMPT_01.txt
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
test_all_operations (__main__.Diffs) ... ok
|
||||
test_invalid_operations (__main__.Diffs) ... ok
|
||||
test_reconstruction_and_proofs (__main__.Diffs) ... ok
|
||||
test_attempt_to_normalize_violation_rejected (__main__.Normalization) ... ok
|
||||
test_environment_values_differ_but_normal_form_equal (__main__.Normalization) ... ok
|
||||
test_every_save_event_reversible (__main__.Normalization) ... ok
|
||||
test_f3_keeps_relative_paths_and_words (__main__.Normalization) ... ok
|
||||
test_guard_mismatch (__main__.Normalization) ... ok
|
||||
test_nested_lookalike_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_original_transport_sha_detects_forged_timing (__main__.Normalization) ... ok
|
||||
test_partial_timing_payload_rejected (__main__.Normalization) ... ok
|
||||
test_prefix_boundary_and_reserved_token (__main__.Normalization) ... ok
|
||||
test_sidecar_missing_duplicate_and_forged_paths (__main__.Normalization) ... ok
|
||||
test_snapshot_and_latest_reversible (__main__.Normalization) ... ok
|
||||
test_snapshot_event_outside_recent_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_wrong_event_and_source_are_preserved (__main__.Normalization) ... ok
|
||||
test_wrong_timing_type_and_negative (__main__.Normalization) ... ok
|
||||
test_all_events_beyond_recent_window (__main__.Reports) ... ok
|
||||
test_all_semantic_layers_compared (__main__.Reports) ... ok
|
||||
test_digest_alone_is_not_enough (__main__.Reports) ... ok
|
||||
test_event_original_types_and_order (__main__.Reports) ... ok
|
||||
test_event_start_and_ids (__main__.Reports) ... ok
|
||||
test_exclusions_keep_actual_values (__main__.Reports) ... ok
|
||||
test_handler_sets_and_counts (__main__.Reports) ... ok
|
||||
test_observation_full_layers (__main__.Reports) ... ok
|
||||
test_product_digest_self_consistency (__main__.Reports) ... ok
|
||||
test_same_report (__main__.Reports) ... ok
|
||||
test_scenario_existing_failures_preserved (__main__.Reports) ... ok
|
||||
test_timing_digest_rule (__main__.Reports) ... ok
|
||||
test_unknown_or_missing_fields_rejected (__main__.Reports) ... ok
|
||||
test_violation_presence_and_difference (__main__.Reports) ... ok
|
||||
test_O_cadence (__main__.S2Format) ... ok
|
||||
test_counter_and_published_ids_binding (__main__.S2Format) ... ok
|
||||
test_diff_and_same_as_S_transport (__main__.S2Format) ... ok
|
||||
test_digest_and_scenario_contradiction (__main__.S2Format) ... ok
|
||||
test_event_no_drop_duplicate_remap (__main__.S2Format) ... ok
|
||||
test_event_original_field_types_mandatory (__main__.S2Format) ... ok
|
||||
test_guard_actual_not_assumed (__main__.S2Format) ... ok
|
||||
test_harness_digest_allows_only_dictionary_order (__main__.S2Format) ... ok
|
||||
test_join_is_copy_and_retains_normalization_proof (__main__.S2Format) ... ok
|
||||
test_kernel_cache_contradictions (__main__.S2Format) ... ok
|
||||
test_lifecycle_guard_errors_and_boundaries (__main__.S2Format) ... ok
|
||||
test_missing_full_state_not_digest_only (__main__.S2Format) ... ok
|
||||
test_normalized_digest_and_raw_tree_are_both_bound (__main__.S2Format) ... ok
|
||||
test_product_event_shape_and_typed_array (__main__.S2Format) ... ok
|
||||
test_raw_observation_binding (__main__.S2Format) ... ok
|
||||
test_roundtrip_tree_sha_and_raw_sha (__main__.S2Format) ... ok
|
||||
test_s2_valid_and_not_formal_acceptance (__main__.S2Format) ... ok
|
||||
test_state_witness_and_observation_mutation (__main__.S2Format) ... ok
|
||||
test_stdout_exactly_one_line (__main__.S2Format) ... ok
|
||||
test_autoload_class_and_script_import (__main__.S2Static) ... ok
|
||||
test_comment_does_not_supply_proof (__main__.S2Static) ... ok
|
||||
test_current_probe (__main__.S2Static) ... ok
|
||||
test_full_state_and_godot_roundtrip_required (__main__.S2Static) ... ok
|
||||
test_no_changes_outside_preparation_or_step (__main__.S2Static) ... ok
|
||||
test_no_event_cap_or_duplicate_report (__main__.S2Static) ... ok
|
||||
test_pause_and_step_arguments (__main__.S2Static) ... ok
|
||||
test_textual_stringname_ordering (__main__.S2Static) ... ok
|
||||
test_unlisted_live_method_and_late_preparation (__main__.S2Static) ... ok
|
||||
test_variant_inference (__main__.S2Static) ... ok
|
||||
test_fixed_scenario_paths (__main__.SourcesAndMetrics) ... ok
|
||||
test_metric_ranges (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_closure_synthetic_registered_map (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_pin_is_not_caller_controlled (__main__.SourcesAndMetrics) ... ok
|
||||
test_array_order_and_all_differences (__main__.TypedTrees) ... ok
|
||||
test_components_and_sha (__main__.TypedTrees) ... ok
|
||||
test_deep_state_not_truncated (__main__.TypedTrees) ... ok
|
||||
test_duplicate_textual_keys_rejected (__main__.TypedTrees) ... ok
|
||||
test_exact_and_types (__main__.TypedTrees) ... ok
|
||||
test_nested_order_all_paths (__main__.TypedTrees) ... ok
|
||||
test_nonstring_keys_keep_types_and_values (__main__.TypedTrees) ... ok
|
||||
test_unsupported_and_malformed (__main__.TypedTrees) ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 72 tests in 4.846s
|
||||
|
||||
OK
|
||||
+1
@@ -0,0 +1 @@
|
||||
000152e51d23db3d4397583b3f4540f5ed0ae469010c993fa1d122fd51537431 UNIT_OUTPUT_S3A_ATTEMPT_02.txt
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
test_all_operations (__main__.Diffs) ... ok
|
||||
test_invalid_operations (__main__.Diffs) ... ok
|
||||
test_reconstruction_and_proofs (__main__.Diffs) ... ok
|
||||
test_attempt_to_normalize_violation_rejected (__main__.Normalization) ... ok
|
||||
test_environment_values_differ_but_normal_form_equal (__main__.Normalization) ... ok
|
||||
test_every_save_event_reversible (__main__.Normalization) ... ok
|
||||
test_f3_keeps_relative_paths_and_words (__main__.Normalization) ... ok
|
||||
test_guard_mismatch (__main__.Normalization) ... ok
|
||||
test_nested_lookalike_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_original_transport_sha_detects_forged_timing (__main__.Normalization) ... ok
|
||||
test_partial_timing_payload_rejected (__main__.Normalization) ... ok
|
||||
test_prefix_boundary_and_reserved_token (__main__.Normalization) ... ok
|
||||
test_sidecar_missing_duplicate_and_forged_paths (__main__.Normalization) ... ok
|
||||
test_snapshot_and_latest_reversible (__main__.Normalization) ... ok
|
||||
test_snapshot_event_outside_recent_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_wrong_event_and_source_are_preserved (__main__.Normalization) ... ok
|
||||
test_wrong_timing_type_and_negative (__main__.Normalization) ... ok
|
||||
test_all_events_beyond_recent_window (__main__.Reports) ... ok
|
||||
test_all_semantic_layers_compared (__main__.Reports) ... ok
|
||||
test_digest_alone_is_not_enough (__main__.Reports) ... ok
|
||||
test_event_original_types_and_order (__main__.Reports) ... ok
|
||||
test_event_start_and_ids (__main__.Reports) ... ok
|
||||
test_exclusions_keep_actual_values (__main__.Reports) ... ok
|
||||
test_handler_sets_and_counts (__main__.Reports) ... ok
|
||||
test_observation_full_layers (__main__.Reports) ... ok
|
||||
test_product_digest_self_consistency (__main__.Reports) ... ok
|
||||
test_same_report (__main__.Reports) ... ok
|
||||
test_scenario_existing_failures_preserved (__main__.Reports) ... ok
|
||||
test_timing_digest_rule (__main__.Reports) ... ok
|
||||
test_unknown_or_missing_fields_rejected (__main__.Reports) ... ok
|
||||
test_violation_presence_and_difference (__main__.Reports) ... ok
|
||||
test_O_cadence (__main__.S2Format) ... ok
|
||||
test_counter_and_published_ids_binding (__main__.S2Format) ... ok
|
||||
test_diff_and_same_as_S_transport (__main__.S2Format) ... ok
|
||||
test_digest_and_scenario_contradiction (__main__.S2Format) ... ok
|
||||
test_event_no_drop_duplicate_remap (__main__.S2Format) ... ok
|
||||
test_event_original_field_types_mandatory (__main__.S2Format) ... ok
|
||||
test_guard_actual_not_assumed (__main__.S2Format) ... ok
|
||||
test_harness_digest_allows_only_dictionary_order (__main__.S2Format) ... ok
|
||||
test_join_is_copy_and_retains_normalization_proof (__main__.S2Format) ... ok
|
||||
test_kernel_cache_contradictions (__main__.S2Format) ... ok
|
||||
test_lifecycle_guard_errors_and_boundaries (__main__.S2Format) ... ok
|
||||
test_missing_full_state_not_digest_only (__main__.S2Format) ... ok
|
||||
test_normalized_digest_and_raw_tree_are_both_bound (__main__.S2Format) ... ok
|
||||
test_product_event_shape_and_typed_array (__main__.S2Format) ... ok
|
||||
test_raw_observation_binding (__main__.S2Format) ... ok
|
||||
test_roundtrip_tree_sha_and_raw_sha (__main__.S2Format) ... ok
|
||||
test_s2_valid_and_not_formal_acceptance (__main__.S2Format) ... ok
|
||||
test_state_witness_and_observation_mutation (__main__.S2Format) ... ok
|
||||
test_stdout_exactly_one_line (__main__.S2Format) ... ok
|
||||
test_autoload_class_and_script_import (__main__.S2Static) ... ok
|
||||
test_comment_does_not_supply_proof (__main__.S2Static) ... ok
|
||||
test_current_probe (__main__.S2Static) ... ok
|
||||
test_full_state_and_godot_roundtrip_required (__main__.S2Static) ... ok
|
||||
test_no_changes_outside_preparation_or_step (__main__.S2Static) ... ok
|
||||
test_no_event_cap_or_duplicate_report (__main__.S2Static) ... ok
|
||||
test_pause_and_step_arguments (__main__.S2Static) ... ok
|
||||
test_textual_stringname_ordering (__main__.S2Static) ... ok
|
||||
test_unlisted_live_method_and_late_preparation (__main__.S2Static) ... ok
|
||||
test_variant_inference (__main__.S2Static) ... ok
|
||||
test_X_recent_limit_and_counter (__main__.S3a) ... ok
|
||||
test_e3_NA_cannot_be_PASS_or_applied (__main__.S3a) ... ok
|
||||
test_e3_coverage_input_and_event_count_binding (__main__.S3a) ... ok
|
||||
test_e3_invented_codes_and_missing_load_code (__main__.S3a) ... ok
|
||||
test_e3_valid_R_and_O_records (__main__.S3a) ... ok
|
||||
test_envelope_duplicates_not_defect (__main__.S3a) ... ok
|
||||
test_exact_phase_keys (__main__.S3a) ... ok
|
||||
test_invalid_input_accepted_is_not_PASS (__main__.S3a) ... ok
|
||||
test_package_fixed_mutations_and_hashes (__main__.S3a) ... ok
|
||||
test_probe_connection_required (__main__.S3a) ... ok
|
||||
test_rejection_mutation_retained_as_defect (__main__.S3a) ... ok
|
||||
test_scenario_mutation_static_boundary (__main__.S3a) ... ok
|
||||
test_signals_all_minutes_and_order (__main__.S3a) ... ok
|
||||
test_fixed_scenario_paths (__main__.SourcesAndMetrics) ... ok
|
||||
test_metric_ranges (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_closure_synthetic_registered_map (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_pin_is_not_caller_controlled (__main__.SourcesAndMetrics) ... ok
|
||||
test_array_order_and_all_differences (__main__.TypedTrees) ... ok
|
||||
test_components_and_sha (__main__.TypedTrees) ... ok
|
||||
test_deep_state_not_truncated (__main__.TypedTrees) ... ok
|
||||
test_duplicate_textual_keys_rejected (__main__.TypedTrees) ... ok
|
||||
test_exact_and_types (__main__.TypedTrees) ... ok
|
||||
test_nested_order_all_paths (__main__.TypedTrees) ... ok
|
||||
test_nonstring_keys_keep_types_and_values (__main__.TypedTrees) ... ok
|
||||
test_unsupported_and_malformed (__main__.TypedTrees) ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 85 tests in 15.941s
|
||||
|
||||
OK
|
||||
+1
@@ -0,0 +1 @@
|
||||
7c14e8ecf4540e412467408cad267d53358940c86f87a0c8e519b305153f3cb8 UNIT_OUTPUT_S3A_ATTEMPT_03.txt
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
test_all_operations (__main__.Diffs) ... ok
|
||||
test_invalid_operations (__main__.Diffs) ... ok
|
||||
test_reconstruction_and_proofs (__main__.Diffs) ... ok
|
||||
test_attempt_to_normalize_violation_rejected (__main__.Normalization) ... ok
|
||||
test_environment_values_differ_but_normal_form_equal (__main__.Normalization) ... ok
|
||||
test_every_save_event_reversible (__main__.Normalization) ... ok
|
||||
test_f3_keeps_relative_paths_and_words (__main__.Normalization) ... ok
|
||||
test_guard_mismatch (__main__.Normalization) ... ok
|
||||
test_nested_lookalike_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_original_transport_sha_detects_forged_timing (__main__.Normalization) ... ok
|
||||
test_partial_timing_payload_rejected (__main__.Normalization) ... ok
|
||||
test_prefix_boundary_and_reserved_token (__main__.Normalization) ... ok
|
||||
test_sidecar_missing_duplicate_and_forged_paths (__main__.Normalization) ... ok
|
||||
test_snapshot_and_latest_reversible (__main__.Normalization) ... ok
|
||||
test_snapshot_event_outside_recent_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_wrong_event_and_source_are_preserved (__main__.Normalization) ... ok
|
||||
test_wrong_timing_type_and_negative (__main__.Normalization) ... ok
|
||||
test_all_events_beyond_recent_window (__main__.Reports) ... ok
|
||||
test_all_semantic_layers_compared (__main__.Reports) ... ok
|
||||
test_digest_alone_is_not_enough (__main__.Reports) ... ok
|
||||
test_event_original_types_and_order (__main__.Reports) ... ok
|
||||
test_event_start_and_ids (__main__.Reports) ... ok
|
||||
test_exclusions_keep_actual_values (__main__.Reports) ... ok
|
||||
test_handler_sets_and_counts (__main__.Reports) ... ok
|
||||
test_observation_full_layers (__main__.Reports) ... ok
|
||||
test_product_digest_self_consistency (__main__.Reports) ... ok
|
||||
test_same_report (__main__.Reports) ... ok
|
||||
test_scenario_existing_failures_preserved (__main__.Reports) ... ok
|
||||
test_timing_digest_rule (__main__.Reports) ... ok
|
||||
test_unknown_or_missing_fields_rejected (__main__.Reports) ... ok
|
||||
test_violation_presence_and_difference (__main__.Reports) ... ok
|
||||
test_O_cadence (__main__.S2Format) ... ok
|
||||
test_counter_and_published_ids_binding (__main__.S2Format) ... ok
|
||||
test_diff_and_same_as_S_transport (__main__.S2Format) ... ok
|
||||
test_digest_and_scenario_contradiction (__main__.S2Format) ... ok
|
||||
test_event_no_drop_duplicate_remap (__main__.S2Format) ... ok
|
||||
test_event_original_field_types_mandatory (__main__.S2Format) ... ok
|
||||
test_guard_actual_not_assumed (__main__.S2Format) ... ok
|
||||
test_harness_digest_allows_only_dictionary_order (__main__.S2Format) ... ok
|
||||
test_join_is_copy_and_retains_normalization_proof (__main__.S2Format) ... ok
|
||||
test_kernel_cache_contradictions (__main__.S2Format) ... ok
|
||||
test_lifecycle_guard_errors_and_boundaries (__main__.S2Format) ... ok
|
||||
test_missing_full_state_not_digest_only (__main__.S2Format) ... ok
|
||||
test_normalized_digest_and_raw_tree_are_both_bound (__main__.S2Format) ... ok
|
||||
test_product_event_shape_and_typed_array (__main__.S2Format) ... ok
|
||||
test_raw_observation_binding (__main__.S2Format) ... ok
|
||||
test_roundtrip_tree_sha_and_raw_sha (__main__.S2Format) ... ok
|
||||
test_s2_valid_and_not_formal_acceptance (__main__.S2Format) ... ok
|
||||
test_state_witness_and_observation_mutation (__main__.S2Format) ... ok
|
||||
test_stdout_exactly_one_line (__main__.S2Format) ... ok
|
||||
test_autoload_class_and_script_import (__main__.S2Static) ... ok
|
||||
test_comment_does_not_supply_proof (__main__.S2Static) ... ok
|
||||
test_current_probe (__main__.S2Static) ... ok
|
||||
test_full_state_and_godot_roundtrip_required (__main__.S2Static) ... ok
|
||||
test_no_changes_outside_preparation_or_step (__main__.S2Static) ... ok
|
||||
test_no_event_cap_or_duplicate_report (__main__.S2Static) ... ok
|
||||
test_pause_and_step_arguments (__main__.S2Static) ... ok
|
||||
test_textual_stringname_ordering (__main__.S2Static) ... ok
|
||||
test_unlisted_live_method_and_late_preparation (__main__.S2Static) ... ok
|
||||
test_variant_inference (__main__.S2Static) ... ok
|
||||
test_X_recent_limit_and_counter (__main__.S3a) ... ok
|
||||
test_duplicate_JSON_key_rejected (__main__.S3a) ... ok
|
||||
test_e3_NA_cannot_be_PASS_or_applied (__main__.S3a) ... ok
|
||||
test_e3_coverage_input_and_event_count_binding (__main__.S3a) ... ok
|
||||
test_e3_invented_codes_and_missing_load_code (__main__.S3a) ... ok
|
||||
test_e3_valid_R_and_O_records (__main__.S3a) ... ok
|
||||
test_envelope_duplicates_not_defect (__main__.S3a) ... ok
|
||||
test_event_count_defect_not_silently_accepted (__main__.S3a) ... ok
|
||||
test_exact_phase_keys (__main__.S3a) ... ok
|
||||
test_interval_gap_rejected (__main__.S3a) ... ok
|
||||
test_invalid_input_accepted_is_not_PASS (__main__.S3a) ... ok
|
||||
test_load_payload_and_pause_outcome (__main__.S3a) ... ok
|
||||
test_operation_moved_outside_scenario_rejected (__main__.S3a) ... ok
|
||||
test_package_fixed_mutations_and_hashes (__main__.S3a) ... ok
|
||||
test_probe_connection_required (__main__.S3a) ... ok
|
||||
test_rejection_mutation_retained_as_defect (__main__.S3a) ... ok
|
||||
test_save_refusal_makes_load_NA (__main__.S3a) ... ok
|
||||
test_scenario_mutation_static_boundary (__main__.S3a) ... ok
|
||||
test_signals_all_minutes_and_order (__main__.S3a) ... ok
|
||||
test_fixed_scenario_paths (__main__.SourcesAndMetrics) ... ok
|
||||
test_metric_ranges (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_closure_synthetic_registered_map (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_pin_is_not_caller_controlled (__main__.SourcesAndMetrics) ... ok
|
||||
test_array_order_and_all_differences (__main__.TypedTrees) ... ok
|
||||
test_components_and_sha (__main__.TypedTrees) ... ok
|
||||
test_deep_state_not_truncated (__main__.TypedTrees) ... ok
|
||||
test_duplicate_textual_keys_rejected (__main__.TypedTrees) ... ok
|
||||
test_exact_and_types (__main__.TypedTrees) ... ok
|
||||
test_nested_order_all_paths (__main__.TypedTrees) ... ok
|
||||
test_nonstring_keys_keep_types_and_values (__main__.TypedTrees) ... ok
|
||||
test_unsupported_and_malformed (__main__.TypedTrees) ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 91 tests in 18.225s
|
||||
|
||||
OK
|
||||
+1
@@ -0,0 +1 @@
|
||||
02221ae41e5dd40ecdac0ec0d7ffc657f265d3194c3817583c2b88ad375f132b UNIT_OUTPUT_S3A_ATTEMPT_04.txt
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
test_all_operations (__main__.Diffs) ... ok
|
||||
test_invalid_operations (__main__.Diffs) ... ok
|
||||
test_reconstruction_and_proofs (__main__.Diffs) ... ok
|
||||
test_attempt_to_normalize_violation_rejected (__main__.Normalization) ... ok
|
||||
test_environment_values_differ_but_normal_form_equal (__main__.Normalization) ... ok
|
||||
test_every_save_event_reversible (__main__.Normalization) ... ok
|
||||
test_f3_keeps_relative_paths_and_words (__main__.Normalization) ... ok
|
||||
test_guard_mismatch (__main__.Normalization) ... ok
|
||||
test_nested_lookalike_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_original_transport_sha_detects_forged_timing (__main__.Normalization) ... ok
|
||||
test_partial_timing_payload_rejected (__main__.Normalization) ... ok
|
||||
test_prefix_boundary_and_reserved_token (__main__.Normalization) ... ok
|
||||
test_sidecar_missing_duplicate_and_forged_paths (__main__.Normalization) ... ok
|
||||
test_snapshot_and_latest_reversible (__main__.Normalization) ... ok
|
||||
test_snapshot_event_outside_recent_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_wrong_event_and_source_are_preserved (__main__.Normalization) ... ok
|
||||
test_wrong_timing_type_and_negative (__main__.Normalization) ... ok
|
||||
test_all_events_beyond_recent_window (__main__.Reports) ... ok
|
||||
test_all_semantic_layers_compared (__main__.Reports) ... ok
|
||||
test_digest_alone_is_not_enough (__main__.Reports) ... ok
|
||||
test_event_original_types_and_order (__main__.Reports) ... ok
|
||||
test_event_start_and_ids (__main__.Reports) ... ok
|
||||
test_exclusions_keep_actual_values (__main__.Reports) ... ok
|
||||
test_handler_sets_and_counts (__main__.Reports) ... ok
|
||||
test_observation_full_layers (__main__.Reports) ... ok
|
||||
test_product_digest_self_consistency (__main__.Reports) ... ok
|
||||
test_same_report (__main__.Reports) ... ok
|
||||
test_scenario_existing_failures_preserved (__main__.Reports) ... ok
|
||||
test_timing_digest_rule (__main__.Reports) ... ok
|
||||
test_unknown_or_missing_fields_rejected (__main__.Reports) ... ok
|
||||
test_violation_presence_and_difference (__main__.Reports) ... ok
|
||||
test_O_cadence (__main__.S2Format) ... ok
|
||||
test_counter_and_published_ids_binding (__main__.S2Format) ... ok
|
||||
test_diff_and_same_as_S_transport (__main__.S2Format) ... ok
|
||||
test_digest_and_scenario_contradiction (__main__.S2Format) ... ok
|
||||
test_event_no_drop_duplicate_remap (__main__.S2Format) ... ok
|
||||
test_event_original_field_types_mandatory (__main__.S2Format) ... ok
|
||||
test_guard_actual_not_assumed (__main__.S2Format) ... ok
|
||||
test_harness_digest_allows_only_dictionary_order (__main__.S2Format) ... ok
|
||||
test_join_is_copy_and_retains_normalization_proof (__main__.S2Format) ... ok
|
||||
test_kernel_cache_contradictions (__main__.S2Format) ... ok
|
||||
test_lifecycle_guard_errors_and_boundaries (__main__.S2Format) ... ok
|
||||
test_missing_full_state_not_digest_only (__main__.S2Format) ... ok
|
||||
test_normalized_digest_and_raw_tree_are_both_bound (__main__.S2Format) ... ok
|
||||
test_product_event_shape_and_typed_array (__main__.S2Format) ... ok
|
||||
test_raw_observation_binding (__main__.S2Format) ... ok
|
||||
test_roundtrip_tree_sha_and_raw_sha (__main__.S2Format) ... ok
|
||||
test_s2_valid_and_not_formal_acceptance (__main__.S2Format) ... ok
|
||||
test_state_witness_and_observation_mutation (__main__.S2Format) ... ok
|
||||
test_stdout_exactly_one_line (__main__.S2Format) ... ok
|
||||
test_autoload_class_and_script_import (__main__.S2Static) ... ok
|
||||
test_comment_does_not_supply_proof (__main__.S2Static) ... ok
|
||||
test_current_probe (__main__.S2Static) ... ok
|
||||
test_full_state_and_godot_roundtrip_required (__main__.S2Static) ... ok
|
||||
test_no_changes_outside_preparation_or_step (__main__.S2Static) ... ok
|
||||
test_no_event_cap_or_duplicate_report (__main__.S2Static) ... ok
|
||||
test_pause_and_step_arguments (__main__.S2Static) ... ok
|
||||
test_textual_stringname_ordering (__main__.S2Static) ... ok
|
||||
test_unlisted_live_method_and_late_preparation (__main__.S2Static) ... ok
|
||||
test_variant_inference (__main__.S2Static) ... ok
|
||||
test_X_recent_limit_and_counter (__main__.S3a) ... ok
|
||||
test_duplicate_JSON_key_rejected (__main__.S3a) ... ok
|
||||
test_e3_NA_cannot_be_PASS_or_applied (__main__.S3a) ... ok
|
||||
test_e3_coverage_input_and_event_count_binding (__main__.S3a) ... ok
|
||||
test_e3_invented_codes_and_missing_load_code (__main__.S3a) ... ok
|
||||
test_e3_valid_R_and_O_records (__main__.S3a) ... ok
|
||||
test_envelope_duplicates_not_defect (__main__.S3a) ... ok
|
||||
test_event_count_defect_not_silently_accepted (__main__.S3a) ... ok
|
||||
test_exact_phase_keys (__main__.S3a) ... ok
|
||||
test_interval_gap_rejected (__main__.S3a) ... ok
|
||||
test_invalid_input_accepted_is_not_PASS (__main__.S3a) ... ok
|
||||
test_load_payload_and_pause_outcome (__main__.S3a) ... ok
|
||||
test_operation_moved_outside_scenario_rejected (__main__.S3a) ... ok
|
||||
test_package_fixed_mutations_and_hashes (__main__.S3a) ... ok
|
||||
test_probe_connection_required (__main__.S3a) ... ok
|
||||
test_rejection_mutation_retained_as_defect (__main__.S3a) ... ok
|
||||
test_save_refusal_makes_load_NA (__main__.S3a) ... ok
|
||||
test_scenario_mutation_static_boundary (__main__.S3a) ... ok
|
||||
test_signals_all_minutes_and_order (__main__.S3a) ... ok
|
||||
test_fixed_scenario_paths (__main__.SourcesAndMetrics) ... ok
|
||||
test_metric_ranges (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_closure_synthetic_registered_map (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_pin_is_not_caller_controlled (__main__.SourcesAndMetrics) ... ok
|
||||
test_array_order_and_all_differences (__main__.TypedTrees) ... ok
|
||||
test_components_and_sha (__main__.TypedTrees) ... ok
|
||||
test_deep_state_not_truncated (__main__.TypedTrees) ... ok
|
||||
test_duplicate_textual_keys_rejected (__main__.TypedTrees) ... ok
|
||||
test_exact_and_types (__main__.TypedTrees) ... ok
|
||||
test_nested_order_all_paths (__main__.TypedTrees) ... ok
|
||||
test_nonstring_keys_keep_types_and_values (__main__.TypedTrees) ... ok
|
||||
test_unsupported_and_malformed (__main__.TypedTrees) ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 91 tests in 18.329s
|
||||
|
||||
OK
|
||||
+1
@@ -0,0 +1 @@
|
||||
c89f4f1ca1ea9b985079cd236ffff4193fa5c76d9bfa28fa65ac08cfc93b569c UNIT_OUTPUT_S3B_ATTEMPT_01.txt
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
test_all_operations (__main__.Diffs) ... ok
|
||||
test_invalid_operations (__main__.Diffs) ... ok
|
||||
test_reconstruction_and_proofs (__main__.Diffs) ... ok
|
||||
test_attempt_to_normalize_violation_rejected (__main__.Normalization) ... ok
|
||||
test_environment_values_differ_but_normal_form_equal (__main__.Normalization) ... ok
|
||||
test_every_save_event_reversible (__main__.Normalization) ... ok
|
||||
test_f3_keeps_relative_paths_and_words (__main__.Normalization) ... ok
|
||||
test_guard_mismatch (__main__.Normalization) ... ok
|
||||
test_nested_lookalike_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_original_transport_sha_detects_forged_timing (__main__.Normalization) ... ok
|
||||
test_partial_timing_payload_rejected (__main__.Normalization) ... ok
|
||||
test_prefix_boundary_and_reserved_token (__main__.Normalization) ... ok
|
||||
test_sidecar_missing_duplicate_and_forged_paths (__main__.Normalization) ... ok
|
||||
test_snapshot_and_latest_reversible (__main__.Normalization) ... ok
|
||||
test_snapshot_event_outside_recent_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_wrong_event_and_source_are_preserved (__main__.Normalization) ... ok
|
||||
test_wrong_timing_type_and_negative (__main__.Normalization) ... ok
|
||||
test_all_events_beyond_recent_window (__main__.Reports) ... ok
|
||||
test_all_semantic_layers_compared (__main__.Reports) ... ok
|
||||
test_digest_alone_is_not_enough (__main__.Reports) ... ok
|
||||
test_event_original_types_and_order (__main__.Reports) ... ok
|
||||
test_event_start_and_ids (__main__.Reports) ... ok
|
||||
test_exclusions_keep_actual_values (__main__.Reports) ... ok
|
||||
test_handler_sets_and_counts (__main__.Reports) ... ok
|
||||
test_observation_full_layers (__main__.Reports) ... ok
|
||||
test_product_digest_self_consistency (__main__.Reports) ... ok
|
||||
test_same_report (__main__.Reports) ... ok
|
||||
test_scenario_existing_failures_preserved (__main__.Reports) ... ok
|
||||
test_timing_digest_rule (__main__.Reports) ... ok
|
||||
test_unknown_or_missing_fields_rejected (__main__.Reports) ... ok
|
||||
test_violation_presence_and_difference (__main__.Reports) ... ok
|
||||
test_O_cadence (__main__.S2Format) ... ok
|
||||
test_counter_and_published_ids_binding (__main__.S2Format) ... ok
|
||||
test_diff_and_same_as_S_transport (__main__.S2Format) ... ok
|
||||
test_digest_and_scenario_contradiction (__main__.S2Format) ... ok
|
||||
test_event_no_drop_duplicate_remap (__main__.S2Format) ... ok
|
||||
test_event_original_field_types_mandatory (__main__.S2Format) ... ok
|
||||
test_guard_actual_not_assumed (__main__.S2Format) ... ok
|
||||
test_harness_digest_allows_only_dictionary_order (__main__.S2Format) ... ok
|
||||
test_join_is_copy_and_retains_normalization_proof (__main__.S2Format) ... ok
|
||||
test_kernel_cache_contradictions (__main__.S2Format) ... ok
|
||||
test_lifecycle_guard_errors_and_boundaries (__main__.S2Format) ... ok
|
||||
test_missing_full_state_not_digest_only (__main__.S2Format) ... ok
|
||||
test_normalized_digest_and_raw_tree_are_both_bound (__main__.S2Format) ... ok
|
||||
test_product_event_shape_and_typed_array (__main__.S2Format) ... ok
|
||||
test_raw_observation_binding (__main__.S2Format) ... ok
|
||||
test_roundtrip_tree_sha_and_raw_sha (__main__.S2Format) ... ok
|
||||
test_s2_valid_and_not_formal_acceptance (__main__.S2Format) ... ok
|
||||
test_state_witness_and_observation_mutation (__main__.S2Format) ... ok
|
||||
test_stdout_exactly_one_line (__main__.S2Format) ... ok
|
||||
test_autoload_class_and_script_import (__main__.S2Static) ... ok
|
||||
test_comment_does_not_supply_proof (__main__.S2Static) ... ok
|
||||
test_current_probe (__main__.S2Static) ... ok
|
||||
test_full_state_and_godot_roundtrip_required (__main__.S2Static) ... ok
|
||||
test_no_changes_outside_preparation_or_step (__main__.S2Static) ... ok
|
||||
test_no_event_cap_or_duplicate_report (__main__.S2Static) ... ok
|
||||
test_pause_and_step_arguments (__main__.S2Static) ... ok
|
||||
test_textual_stringname_ordering (__main__.S2Static) ... ok
|
||||
test_unlisted_live_method_and_late_preparation (__main__.S2Static) ... ok
|
||||
test_variant_inference (__main__.S2Static) ... ok
|
||||
test_X_recent_limit_and_counter (__main__.S3a) ... ok
|
||||
test_duplicate_JSON_key_rejected (__main__.S3a) ... ok
|
||||
test_e3_NA_cannot_be_PASS_or_applied (__main__.S3a) ... ok
|
||||
test_e3_coverage_input_and_event_count_binding (__main__.S3a) ... ok
|
||||
test_e3_invented_codes_and_missing_load_code (__main__.S3a) ... ok
|
||||
test_e3_valid_R_and_O_records (__main__.S3a) ... ok
|
||||
test_envelope_duplicates_not_defect (__main__.S3a) ... ok
|
||||
test_event_count_defect_not_silently_accepted (__main__.S3a) ... ok
|
||||
test_exact_phase_keys (__main__.S3a) ... ok
|
||||
test_interval_gap_rejected (__main__.S3a) ... ok
|
||||
test_invalid_input_accepted_is_not_PASS (__main__.S3a) ... ok
|
||||
test_load_payload_and_pause_outcome (__main__.S3a) ... ok
|
||||
test_operation_moved_outside_scenario_rejected (__main__.S3a) ... ok
|
||||
test_package_fixed_mutations_and_hashes (__main__.S3a) ... ok
|
||||
test_probe_connection_required (__main__.S3a) ... ok
|
||||
test_rejection_mutation_retained_as_defect (__main__.S3a) ... ok
|
||||
test_save_refusal_makes_load_NA (__main__.S3a) ... ok
|
||||
test_scenario_mutation_static_boundary (__main__.S3a) ... ok
|
||||
test_signals_all_minutes_and_order (__main__.S3a) ... ok
|
||||
test_fixed_scenario_paths (__main__.SourcesAndMetrics) ... ok
|
||||
test_metric_ranges (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_closure_synthetic_registered_map (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_pin_is_not_caller_controlled (__main__.SourcesAndMetrics) ... ok
|
||||
test_array_order_and_all_differences (__main__.TypedTrees) ... ok
|
||||
test_components_and_sha (__main__.TypedTrees) ... ok
|
||||
test_deep_state_not_truncated (__main__.TypedTrees) ... ok
|
||||
test_duplicate_textual_keys_rejected (__main__.TypedTrees) ... ok
|
||||
test_exact_and_types (__main__.TypedTrees) ... ok
|
||||
test_nested_order_all_paths (__main__.TypedTrees) ... ok
|
||||
test_nonstring_keys_keep_types_and_values (__main__.TypedTrees) ... ok
|
||||
test_unsupported_and_malformed (__main__.TypedTrees) ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 91 tests in 18.303s
|
||||
|
||||
OK
|
||||
+1
@@ -0,0 +1 @@
|
||||
7bd19a6a3c84385f754261d51779f05b6e39c116459086d5aad3a83afa7225c0 UNIT_OUTPUT_S3B_ATTEMPT_02.txt
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1108
|
||||
self.reject(lambda r, e, p: e[3]['detail'].update(input=transport(snapshot()))))
|
||||
^
|
||||
SyntaxError: unmatched ')'
|
||||
+1
@@ -0,0 +1 @@
|
||||
0872061bbc2c1403d2cd04877b8456f3fead35236be008b1a07f02ae5d85b11a UNIT_OUTPUT_S3B_ATTEMPT_03.txt
|
||||
+127
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
63204c3415c9b1719fa6aa596b714077a57f530896f979d12b89a15eb2d827e9 UNIT_OUTPUT_S3B_ATTEMPT_04.txt
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
test_all_operations (__main__.Diffs) ... ok
|
||||
test_invalid_operations (__main__.Diffs) ... ok
|
||||
test_reconstruction_and_proofs (__main__.Diffs) ... ok
|
||||
test_attempt_to_normalize_violation_rejected (__main__.Normalization) ... ok
|
||||
test_environment_values_differ_but_normal_form_equal (__main__.Normalization) ... ok
|
||||
test_every_save_event_reversible (__main__.Normalization) ... ok
|
||||
test_f3_keeps_relative_paths_and_words (__main__.Normalization) ... ok
|
||||
test_guard_mismatch (__main__.Normalization) ... ok
|
||||
test_nested_lookalike_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_original_transport_sha_detects_forged_timing (__main__.Normalization) ... ok
|
||||
test_partial_timing_payload_rejected (__main__.Normalization) ... ok
|
||||
test_prefix_boundary_and_reserved_token (__main__.Normalization) ... ok
|
||||
test_sidecar_missing_duplicate_and_forged_paths (__main__.Normalization) ... ok
|
||||
test_snapshot_and_latest_reversible (__main__.Normalization) ... ok
|
||||
test_snapshot_event_outside_recent_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_wrong_event_and_source_are_preserved (__main__.Normalization) ... ok
|
||||
test_wrong_timing_type_and_negative (__main__.Normalization) ... ok
|
||||
test_all_events_beyond_recent_window (__main__.Reports) ... ok
|
||||
test_all_semantic_layers_compared (__main__.Reports) ... ok
|
||||
test_digest_alone_is_not_enough (__main__.Reports) ... ok
|
||||
test_event_original_types_and_order (__main__.Reports) ... ok
|
||||
test_event_start_and_ids (__main__.Reports) ... ok
|
||||
test_exclusions_keep_actual_values (__main__.Reports) ... ok
|
||||
test_handler_sets_and_counts (__main__.Reports) ... ok
|
||||
test_observation_full_layers (__main__.Reports) ... ok
|
||||
test_product_digest_self_consistency (__main__.Reports) ... ok
|
||||
test_same_report (__main__.Reports) ... ok
|
||||
test_scenario_existing_failures_preserved (__main__.Reports) ... ok
|
||||
test_timing_digest_rule (__main__.Reports) ... ok
|
||||
test_unknown_or_missing_fields_rejected (__main__.Reports) ... ok
|
||||
test_violation_presence_and_difference (__main__.Reports) ... ok
|
||||
test_O_cadence (__main__.S2Format) ... ok
|
||||
test_counter_and_published_ids_binding (__main__.S2Format) ... ok
|
||||
test_diff_and_same_as_S_transport (__main__.S2Format) ... ok
|
||||
test_digest_and_scenario_contradiction (__main__.S2Format) ... ok
|
||||
test_event_no_drop_duplicate_remap (__main__.S2Format) ... ok
|
||||
test_event_original_field_types_mandatory (__main__.S2Format) ... ok
|
||||
test_guard_actual_not_assumed (__main__.S2Format) ... ok
|
||||
test_harness_digest_allows_only_dictionary_order (__main__.S2Format) ... ok
|
||||
test_join_is_copy_and_retains_normalization_proof (__main__.S2Format) ... ok
|
||||
test_kernel_cache_contradictions (__main__.S2Format) ... ok
|
||||
test_lifecycle_guard_errors_and_boundaries (__main__.S2Format) ... ok
|
||||
test_missing_full_state_not_digest_only (__main__.S2Format) ... ok
|
||||
test_normalized_digest_and_raw_tree_are_both_bound (__main__.S2Format) ... ok
|
||||
test_product_event_shape_and_typed_array (__main__.S2Format) ... ok
|
||||
test_raw_observation_binding (__main__.S2Format) ... ok
|
||||
test_roundtrip_tree_sha_and_raw_sha (__main__.S2Format) ... ok
|
||||
test_s2_valid_and_not_formal_acceptance (__main__.S2Format) ... ok
|
||||
test_state_witness_and_observation_mutation (__main__.S2Format) ... ok
|
||||
test_stdout_exactly_one_line (__main__.S2Format) ... ok
|
||||
test_autoload_class_and_script_import (__main__.S2Static) ... ok
|
||||
test_comment_does_not_supply_proof (__main__.S2Static) ... ok
|
||||
test_current_probe (__main__.S2Static) ... ok
|
||||
test_full_state_and_godot_roundtrip_required (__main__.S2Static) ... ok
|
||||
test_no_changes_outside_preparation_or_step (__main__.S2Static) ... ok
|
||||
test_no_event_cap_or_duplicate_report (__main__.S2Static) ... ok
|
||||
test_pause_and_step_arguments (__main__.S2Static) ... ok
|
||||
test_textual_stringname_ordering (__main__.S2Static) ... ok
|
||||
test_unlisted_live_method_and_late_preparation (__main__.S2Static) ... ok
|
||||
test_variant_inference (__main__.S2Static) ... ok
|
||||
test_X_recent_limit_and_counter (__main__.S3a) ... ok
|
||||
test_duplicate_JSON_key_rejected (__main__.S3a) ... ok
|
||||
test_e3_NA_cannot_be_PASS_or_applied (__main__.S3a) ... ok
|
||||
test_e3_coverage_input_and_event_count_binding (__main__.S3a) ... ok
|
||||
test_e3_invented_codes_and_missing_load_code (__main__.S3a) ... ok
|
||||
test_e3_valid_R_and_O_records (__main__.S3a) ... ok
|
||||
test_envelope_duplicates_not_defect (__main__.S3a) ... ok
|
||||
test_event_count_defect_not_silently_accepted (__main__.S3a) ... ok
|
||||
test_exact_phase_keys (__main__.S3a) ... ok
|
||||
test_interval_gap_rejected (__main__.S3a) ... ok
|
||||
test_invalid_input_accepted_is_not_PASS (__main__.S3a) ... ok
|
||||
test_load_payload_and_pause_outcome (__main__.S3a) ... ok
|
||||
test_operation_moved_outside_scenario_rejected (__main__.S3a) ... ok
|
||||
test_package_fixed_mutations_and_hashes (__main__.S3a) ... ok
|
||||
test_probe_connection_required (__main__.S3a) ... ok
|
||||
test_rejection_mutation_retained_as_defect (__main__.S3a) ... ok
|
||||
test_save_refusal_makes_load_NA (__main__.S3a) ... ok
|
||||
test_scenario_mutation_static_boundary (__main__.S3a) ... ok
|
||||
test_signals_all_minutes_and_order (__main__.S3a) ... ok
|
||||
test_E5_cached_digest_defect_is_comparable (__main__.S3b) ... ok
|
||||
test_NA_not_PASS (__main__.S3b) ... ok
|
||||
test_aliasing_cannot_be_PASS (__main__.S3b) ... ok
|
||||
test_aliasing_missing_record (__main__.S3b) ... ok
|
||||
test_all_paths_and_ownership_R_O (__main__.S3b) ... ok
|
||||
test_digest_materialization_required (__main__.S3b) ... ok
|
||||
test_empty_registry_not_NA (__main__.S3b) ... ok
|
||||
test_event_count_mismatch (__main__.S3b) ... ok
|
||||
test_facts_normalization_is_reversible (__main__.S3b) ... ok
|
||||
test_first_placeable_choice (__main__.S3b) ... ok
|
||||
test_interval_gap (__main__.S3b) ... ok
|
||||
test_load_X_not_digest_only (__main__.S3b) ... ok
|
||||
test_load_extra_event (__main__.S3b) ... ok
|
||||
test_missing_path_and_combination (__main__.S3b) ... ok
|
||||
test_missing_trial (__main__.S3b) ... ok
|
||||
test_nested_mutation_required (__main__.S3b) ... ok
|
||||
test_no_staleness_assertion_for_non_tick (__main__.S3b) ... ok
|
||||
test_path_order (__main__.S3b) ... ok
|
||||
test_restore_extra_event (__main__.S3b) ... ok
|
||||
test_sort_rule_rejected (__main__.S3b) ... ok
|
||||
test_static_handler_and_outside_mutations (__main__.S3b) ... ok
|
||||
test_unpreviewed_choice (__main__.S3b) ... ok
|
||||
test_wrong_registry_in_either_role (__main__.S3b) ... ok
|
||||
test_fixed_scenario_paths (__main__.SourcesAndMetrics) ... ok
|
||||
test_metric_ranges (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_closure_synthetic_registered_map (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_pin_is_not_caller_controlled (__main__.SourcesAndMetrics) ... ok
|
||||
test_array_order_and_all_differences (__main__.TypedTrees) ... ok
|
||||
test_components_and_sha (__main__.TypedTrees) ... ok
|
||||
test_deep_state_not_truncated (__main__.TypedTrees) ... ok
|
||||
test_duplicate_textual_keys_rejected (__main__.TypedTrees) ... ok
|
||||
test_exact_and_types (__main__.TypedTrees) ... ok
|
||||
test_nested_order_all_paths (__main__.TypedTrees) ... ok
|
||||
test_nonstring_keys_keep_types_and_values (__main__.TypedTrees) ... ok
|
||||
test_unsupported_and_malformed (__main__.TypedTrees) ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 114 tests in 26.408s
|
||||
|
||||
OK
|
||||
+1
@@ -0,0 +1 @@
|
||||
bfcb263bf6d7f284fb2b20ee229d96b7c4a9bd7cd5e7b513df1d3ea32580ed6e UNIT_OUTPUT_S3B_ATTEMPT_05.txt
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
test_all_operations (__main__.Diffs) ... ok
|
||||
test_invalid_operations (__main__.Diffs) ... ok
|
||||
test_reconstruction_and_proofs (__main__.Diffs) ... ok
|
||||
test_attempt_to_normalize_violation_rejected (__main__.Normalization) ... ok
|
||||
test_environment_values_differ_but_normal_form_equal (__main__.Normalization) ... ok
|
||||
test_every_save_event_reversible (__main__.Normalization) ... ok
|
||||
test_f3_keeps_relative_paths_and_words (__main__.Normalization) ... ok
|
||||
test_guard_mismatch (__main__.Normalization) ... ok
|
||||
test_nested_lookalike_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_original_transport_sha_detects_forged_timing (__main__.Normalization) ... ok
|
||||
test_partial_timing_payload_rejected (__main__.Normalization) ... ok
|
||||
test_prefix_boundary_and_reserved_token (__main__.Normalization) ... ok
|
||||
test_sidecar_missing_duplicate_and_forged_paths (__main__.Normalization) ... ok
|
||||
test_snapshot_and_latest_reversible (__main__.Normalization) ... ok
|
||||
test_snapshot_event_outside_recent_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_wrong_event_and_source_are_preserved (__main__.Normalization) ... ok
|
||||
test_wrong_timing_type_and_negative (__main__.Normalization) ... ok
|
||||
test_all_events_beyond_recent_window (__main__.Reports) ... ok
|
||||
test_all_semantic_layers_compared (__main__.Reports) ... ok
|
||||
test_digest_alone_is_not_enough (__main__.Reports) ... ok
|
||||
test_event_original_types_and_order (__main__.Reports) ... ok
|
||||
test_event_start_and_ids (__main__.Reports) ... ok
|
||||
test_exclusions_keep_actual_values (__main__.Reports) ... ok
|
||||
test_handler_sets_and_counts (__main__.Reports) ... ok
|
||||
test_observation_full_layers (__main__.Reports) ... ok
|
||||
test_product_digest_self_consistency (__main__.Reports) ... ok
|
||||
test_same_report (__main__.Reports) ... ok
|
||||
test_scenario_existing_failures_preserved (__main__.Reports) ... ok
|
||||
test_timing_digest_rule (__main__.Reports) ... ok
|
||||
test_unknown_or_missing_fields_rejected (__main__.Reports) ... ok
|
||||
test_violation_presence_and_difference (__main__.Reports) ... ok
|
||||
test_O_cadence (__main__.S2Format) ... ok
|
||||
test_counter_and_published_ids_binding (__main__.S2Format) ... ok
|
||||
test_diff_and_same_as_S_transport (__main__.S2Format) ... ok
|
||||
test_digest_and_scenario_contradiction (__main__.S2Format) ... ok
|
||||
test_event_no_drop_duplicate_remap (__main__.S2Format) ... ok
|
||||
test_event_original_field_types_mandatory (__main__.S2Format) ... ok
|
||||
test_guard_actual_not_assumed (__main__.S2Format) ... ok
|
||||
test_harness_digest_allows_only_dictionary_order (__main__.S2Format) ... ok
|
||||
test_join_is_copy_and_retains_normalization_proof (__main__.S2Format) ... ok
|
||||
test_kernel_cache_contradictions (__main__.S2Format) ... ok
|
||||
test_lifecycle_guard_errors_and_boundaries (__main__.S2Format) ... ok
|
||||
test_missing_full_state_not_digest_only (__main__.S2Format) ... ok
|
||||
test_normalized_digest_and_raw_tree_are_both_bound (__main__.S2Format) ... ok
|
||||
test_product_event_shape_and_typed_array (__main__.S2Format) ... ok
|
||||
test_raw_observation_binding (__main__.S2Format) ... ok
|
||||
test_roundtrip_tree_sha_and_raw_sha (__main__.S2Format) ... ok
|
||||
test_s2_valid_and_not_formal_acceptance (__main__.S2Format) ... ok
|
||||
test_state_witness_and_observation_mutation (__main__.S2Format) ... ok
|
||||
test_stdout_exactly_one_line (__main__.S2Format) ... ok
|
||||
test_autoload_class_and_script_import (__main__.S2Static) ... ok
|
||||
test_comment_does_not_supply_proof (__main__.S2Static) ... ok
|
||||
test_current_probe (__main__.S2Static) ... ok
|
||||
test_full_state_and_godot_roundtrip_required (__main__.S2Static) ... ok
|
||||
test_no_changes_outside_preparation_or_step (__main__.S2Static) ... ok
|
||||
test_no_event_cap_or_duplicate_report (__main__.S2Static) ... ok
|
||||
test_pause_and_step_arguments (__main__.S2Static) ... ok
|
||||
test_textual_stringname_ordering (__main__.S2Static) ... ok
|
||||
test_unlisted_live_method_and_late_preparation (__main__.S2Static) ... ok
|
||||
test_variant_inference (__main__.S2Static) ... ok
|
||||
test_X_recent_limit_and_counter (__main__.S3a) ... ok
|
||||
test_duplicate_JSON_key_rejected (__main__.S3a) ... ok
|
||||
test_e3_NA_cannot_be_PASS_or_applied (__main__.S3a) ... ok
|
||||
test_e3_coverage_input_and_event_count_binding (__main__.S3a) ... ok
|
||||
test_e3_invented_codes_and_missing_load_code (__main__.S3a) ... ok
|
||||
test_e3_valid_R_and_O_records (__main__.S3a) ... ok
|
||||
test_envelope_duplicates_not_defect (__main__.S3a) ... ok
|
||||
test_event_count_defect_not_silently_accepted (__main__.S3a) ... ok
|
||||
test_exact_phase_keys (__main__.S3a) ... ok
|
||||
test_interval_gap_rejected (__main__.S3a) ... ok
|
||||
test_invalid_input_accepted_is_not_PASS (__main__.S3a) ... ok
|
||||
test_load_payload_and_pause_outcome (__main__.S3a) ... ok
|
||||
test_operation_moved_outside_scenario_rejected (__main__.S3a) ... ok
|
||||
test_package_fixed_mutations_and_hashes (__main__.S3a) ... ok
|
||||
test_probe_connection_required (__main__.S3a) ... ok
|
||||
test_rejection_mutation_retained_as_defect (__main__.S3a) ... ok
|
||||
test_save_refusal_makes_load_NA (__main__.S3a) ... ok
|
||||
test_scenario_mutation_static_boundary (__main__.S3a) ... ok
|
||||
test_signals_all_minutes_and_order (__main__.S3a) ... ok
|
||||
test_E5_cached_digest_defect_is_comparable (__main__.S3b) ... ok
|
||||
test_NA_not_PASS (__main__.S3b) ... ok
|
||||
test_aliasing_cannot_be_PASS (__main__.S3b) ... ok
|
||||
test_aliasing_missing_record (__main__.S3b) ... ok
|
||||
test_all_paths_and_ownership_R_O (__main__.S3b) ... ok
|
||||
test_digest_materialization_required (__main__.S3b) ... ok
|
||||
test_empty_registry_not_NA (__main__.S3b) ... ok
|
||||
test_event_count_mismatch (__main__.S3b) ... ok
|
||||
test_facts_normalization_is_reversible (__main__.S3b) ... ok
|
||||
test_first_placeable_choice (__main__.S3b) ... ok
|
||||
test_interval_gap (__main__.S3b) ... ok
|
||||
test_load_X_not_digest_only (__main__.S3b) ... ok
|
||||
test_load_extra_event (__main__.S3b) ... ok
|
||||
test_missing_path_and_combination (__main__.S3b) ... ok
|
||||
test_missing_trial (__main__.S3b) ... ok
|
||||
test_nested_mutation_required (__main__.S3b) ... ok
|
||||
test_no_staleness_assertion_for_non_tick (__main__.S3b) ... ok
|
||||
test_path_order (__main__.S3b) ... ok
|
||||
test_restore_extra_event (__main__.S3b) ... ok
|
||||
test_sort_rule_rejected (__main__.S3b) ... ok
|
||||
test_static_handler_and_outside_mutations (__main__.S3b) ... ok
|
||||
test_unpreviewed_choice (__main__.S3b) ... ok
|
||||
test_wrong_registry_in_either_role (__main__.S3b) ... ok
|
||||
test_fixed_scenario_paths (__main__.SourcesAndMetrics) ... ok
|
||||
test_metric_ranges (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_closure_synthetic_registered_map (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_pin_is_not_caller_controlled (__main__.SourcesAndMetrics) ... ok
|
||||
test_array_order_and_all_differences (__main__.TypedTrees) ... ok
|
||||
test_components_and_sha (__main__.TypedTrees) ... ok
|
||||
test_deep_state_not_truncated (__main__.TypedTrees) ... ok
|
||||
test_duplicate_textual_keys_rejected (__main__.TypedTrees) ... ok
|
||||
test_exact_and_types (__main__.TypedTrees) ... ok
|
||||
test_nested_order_all_paths (__main__.TypedTrees) ... ok
|
||||
test_nonstring_keys_keep_types_and_values (__main__.TypedTrees) ... ok
|
||||
test_unsupported_and_malformed (__main__.TypedTrees) ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 114 tests in 26.528s
|
||||
|
||||
OK
|
||||
+1
@@ -0,0 +1 @@
|
||||
7d9bf9c602a93aca06d03eb06025beeea35603d453e293c07e7a6f81ca9ca000 UNIT_OUTPUT_S3B_ATTEMPT_06.txt
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
test_all_operations (__main__.Diffs) ... ok
|
||||
test_invalid_operations (__main__.Diffs) ... ok
|
||||
test_reconstruction_and_proofs (__main__.Diffs) ... ok
|
||||
test_attempt_to_normalize_violation_rejected (__main__.Normalization) ... ok
|
||||
test_environment_values_differ_but_normal_form_equal (__main__.Normalization) ... ok
|
||||
test_every_save_event_reversible (__main__.Normalization) ... ok
|
||||
test_f3_keeps_relative_paths_and_words (__main__.Normalization) ... ok
|
||||
test_guard_mismatch (__main__.Normalization) ... ok
|
||||
test_nested_lookalike_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_original_transport_sha_detects_forged_timing (__main__.Normalization) ... ok
|
||||
test_partial_timing_payload_rejected (__main__.Normalization) ... ok
|
||||
test_prefix_boundary_and_reserved_token (__main__.Normalization) ... ok
|
||||
test_sidecar_missing_duplicate_and_forged_paths (__main__.Normalization) ... ok
|
||||
test_snapshot_and_latest_reversible (__main__.Normalization) ... ok
|
||||
test_snapshot_event_outside_recent_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_wrong_event_and_source_are_preserved (__main__.Normalization) ... ok
|
||||
test_wrong_timing_type_and_negative (__main__.Normalization) ... ok
|
||||
test_all_events_beyond_recent_window (__main__.Reports) ... ok
|
||||
test_all_semantic_layers_compared (__main__.Reports) ... ok
|
||||
test_digest_alone_is_not_enough (__main__.Reports) ... ok
|
||||
test_event_original_types_and_order (__main__.Reports) ... ok
|
||||
test_event_start_and_ids (__main__.Reports) ... ok
|
||||
test_exclusions_keep_actual_values (__main__.Reports) ... ok
|
||||
test_handler_sets_and_counts (__main__.Reports) ... ok
|
||||
test_observation_full_layers (__main__.Reports) ... ok
|
||||
test_product_digest_self_consistency (__main__.Reports) ... ok
|
||||
test_same_report (__main__.Reports) ... ok
|
||||
test_scenario_existing_failures_preserved (__main__.Reports) ... ok
|
||||
test_timing_digest_rule (__main__.Reports) ... ok
|
||||
test_unknown_or_missing_fields_rejected (__main__.Reports) ... ok
|
||||
test_violation_presence_and_difference (__main__.Reports) ... ok
|
||||
test_O_cadence (__main__.S2Format) ... ok
|
||||
test_counter_and_published_ids_binding (__main__.S2Format) ... ok
|
||||
test_diff_and_same_as_S_transport (__main__.S2Format) ... ok
|
||||
test_digest_and_scenario_contradiction (__main__.S2Format) ... ok
|
||||
test_event_no_drop_duplicate_remap (__main__.S2Format) ... ok
|
||||
test_event_original_field_types_mandatory (__main__.S2Format) ... ok
|
||||
test_guard_actual_not_assumed (__main__.S2Format) ... ok
|
||||
test_harness_digest_allows_only_dictionary_order (__main__.S2Format) ... ok
|
||||
test_join_is_copy_and_retains_normalization_proof (__main__.S2Format) ... ok
|
||||
test_kernel_cache_contradictions (__main__.S2Format) ... ok
|
||||
test_lifecycle_guard_errors_and_boundaries (__main__.S2Format) ... ok
|
||||
test_missing_full_state_not_digest_only (__main__.S2Format) ... ok
|
||||
test_normalized_digest_and_raw_tree_are_both_bound (__main__.S2Format) ... ok
|
||||
test_product_event_shape_and_typed_array (__main__.S2Format) ... ok
|
||||
test_raw_observation_binding (__main__.S2Format) ... ok
|
||||
test_roundtrip_tree_sha_and_raw_sha (__main__.S2Format) ... ok
|
||||
test_s2_valid_and_not_formal_acceptance (__main__.S2Format) ... ok
|
||||
test_state_witness_and_observation_mutation (__main__.S2Format) ... ok
|
||||
test_stdout_exactly_one_line (__main__.S2Format) ... ok
|
||||
test_autoload_class_and_script_import (__main__.S2Static) ... ok
|
||||
test_comment_does_not_supply_proof (__main__.S2Static) ... ok
|
||||
test_current_probe (__main__.S2Static) ... ok
|
||||
test_full_state_and_godot_roundtrip_required (__main__.S2Static) ... ok
|
||||
test_no_changes_outside_preparation_or_step (__main__.S2Static) ... ok
|
||||
test_no_event_cap_or_duplicate_report (__main__.S2Static) ... ok
|
||||
test_pause_and_step_arguments (__main__.S2Static) ... ok
|
||||
test_textual_stringname_ordering (__main__.S2Static) ... ok
|
||||
test_unlisted_live_method_and_late_preparation (__main__.S2Static) ... ok
|
||||
test_variant_inference (__main__.S2Static) ... ok
|
||||
test_X_recent_limit_and_counter (__main__.S3a) ... ok
|
||||
test_duplicate_JSON_key_rejected (__main__.S3a) ... ok
|
||||
test_e3_NA_cannot_be_PASS_or_applied (__main__.S3a) ... ok
|
||||
test_e3_coverage_input_and_event_count_binding (__main__.S3a) ... ok
|
||||
test_e3_invented_codes_and_missing_load_code (__main__.S3a) ... ok
|
||||
test_e3_valid_R_and_O_records (__main__.S3a) ... ok
|
||||
test_envelope_duplicates_not_defect (__main__.S3a) ... ok
|
||||
test_event_count_defect_not_silently_accepted (__main__.S3a) ... ok
|
||||
test_exact_phase_keys (__main__.S3a) ... ok
|
||||
test_interval_gap_rejected (__main__.S3a) ... ok
|
||||
test_invalid_input_accepted_is_not_PASS (__main__.S3a) ... ok
|
||||
test_load_payload_and_pause_outcome (__main__.S3a) ... ok
|
||||
test_operation_moved_outside_scenario_rejected (__main__.S3a) ... ok
|
||||
test_package_fixed_mutations_and_hashes (__main__.S3a) ... ok
|
||||
test_probe_connection_required (__main__.S3a) ... ok
|
||||
test_rejection_mutation_retained_as_defect (__main__.S3a) ... ok
|
||||
test_save_refusal_makes_load_NA (__main__.S3a) ... ok
|
||||
test_scenario_mutation_static_boundary (__main__.S3a) ... ok
|
||||
test_signals_all_minutes_and_order (__main__.S3a) ... ok
|
||||
test_E5_cached_digest_defect_is_comparable (__main__.S3b) ... ok
|
||||
test_NA_not_PASS (__main__.S3b) ... ok
|
||||
test_aliasing_cannot_be_PASS (__main__.S3b) ... ok
|
||||
test_aliasing_missing_record (__main__.S3b) ... ok
|
||||
test_all_paths_and_ownership_R_O (__main__.S3b) ... ok
|
||||
test_digest_defect_other_checkpoint_still_rejected (__main__.S3b) ... ok
|
||||
test_digest_materialization_required (__main__.S3b) ... ok
|
||||
test_empty_registry_not_NA (__main__.S3b) ... ok
|
||||
test_event_count_mismatch (__main__.S3b) ... ok
|
||||
test_facts_normalization_is_reversible (__main__.S3b) ... ok
|
||||
test_first_placeable_choice (__main__.S3b) ... ok
|
||||
test_interval_gap (__main__.S3b) ... ok
|
||||
test_joined_s3b_self_comparison (__main__.S3b) ... ok
|
||||
test_load_X_not_digest_only (__main__.S3b) ... ok
|
||||
test_load_extra_event (__main__.S3b) ... ok
|
||||
test_missing_path_and_combination (__main__.S3b) ... ok
|
||||
test_missing_preview_observation (__main__.S3b) ... ok
|
||||
test_missing_trial (__main__.S3b) ... ok
|
||||
test_nested_mutation_required (__main__.S3b) ... ok
|
||||
test_no_staleness_assertion_for_non_tick (__main__.S3b) ... ok
|
||||
test_path_order (__main__.S3b) ... ok
|
||||
test_restore_extra_event (__main__.S3b) ... ok
|
||||
test_signal_facts_cannot_be_dropped (__main__.S3b) ... ok
|
||||
test_sort_rule_rejected (__main__.S3b) ... ok
|
||||
test_static_handler_and_outside_mutations (__main__.S3b) ... ok
|
||||
test_unpreviewed_choice (__main__.S3b) ... ok
|
||||
test_wrong_registry_in_either_role (__main__.S3b) ... ok
|
||||
test_fixed_scenario_paths (__main__.SourcesAndMetrics) ... ok
|
||||
test_metric_ranges (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_closure_synthetic_registered_map (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_pin_is_not_caller_controlled (__main__.SourcesAndMetrics) ... ok
|
||||
test_array_order_and_all_differences (__main__.TypedTrees) ... ok
|
||||
test_components_and_sha (__main__.TypedTrees) ... ok
|
||||
test_deep_state_not_truncated (__main__.TypedTrees) ... ok
|
||||
test_duplicate_textual_keys_rejected (__main__.TypedTrees) ... ok
|
||||
test_exact_and_types (__main__.TypedTrees) ... ok
|
||||
test_nested_order_all_paths (__main__.TypedTrees) ... ok
|
||||
test_nonstring_keys_keep_types_and_values (__main__.TypedTrees) ... ok
|
||||
test_unsupported_and_malformed (__main__.TypedTrees) ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 118 tests in 31.744s
|
||||
|
||||
OK
|
||||
+1
@@ -0,0 +1 @@
|
||||
f7c7c045ea98a366810b7c309fc1a87a77ccc5d8e823750eebaa742c9529e2ca UNIT_OUTPUT_S3B_ATTEMPT_07.txt
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
test_ownership_fact_dictionary_order_fallback (__main__.S3b) ... FAIL
|
||||
|
||||
======================================================================
|
||||
FAIL: test_ownership_fact_dictionary_order_fallback (__main__.S3b)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1233, in test_ownership_fact_dictionary_order_fallback
|
||||
self.assertTrue(result['ok'], result['differences'])
|
||||
AssertionError: False is not true : [{'path': ['scenarios', 0, 'result'], 'a': {'facts': {'held_before': [27, [[[4, 'a'], [2, 1]], [[4, 'b'], [2, 2]]], None]}}, 'b': {'facts': {'held_before': [27, [[[4, 'b'], [2, 2]], [[4, 'a'], [2, 1]]], None]}}}]
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 1 test in 0.036s
|
||||
|
||||
FAILED (failures=1)
|
||||
+1
@@ -0,0 +1 @@
|
||||
19c3f115d6a73bf91413877878f5d5f9d78a3e253dae3ddba7dfec9b5d46eaba UNIT_OUTPUT_S3B_ATTEMPT_08.txt
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
test_all_operations (__main__.Diffs) ... ok
|
||||
test_invalid_operations (__main__.Diffs) ... ok
|
||||
test_reconstruction_and_proofs (__main__.Diffs) ... ok
|
||||
test_attempt_to_normalize_violation_rejected (__main__.Normalization) ... ok
|
||||
test_environment_values_differ_but_normal_form_equal (__main__.Normalization) ... ok
|
||||
test_every_save_event_reversible (__main__.Normalization) ... ok
|
||||
test_f3_keeps_relative_paths_and_words (__main__.Normalization) ... ok
|
||||
test_guard_mismatch (__main__.Normalization) ... ok
|
||||
test_nested_lookalike_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_original_transport_sha_detects_forged_timing (__main__.Normalization) ... ok
|
||||
test_partial_timing_payload_rejected (__main__.Normalization) ... ok
|
||||
test_prefix_boundary_and_reserved_token (__main__.Normalization) ... ok
|
||||
test_sidecar_missing_duplicate_and_forged_paths (__main__.Normalization) ... ok
|
||||
test_snapshot_and_latest_reversible (__main__.Normalization) ... ok
|
||||
test_snapshot_event_outside_recent_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_wrong_event_and_source_are_preserved (__main__.Normalization) ... ok
|
||||
test_wrong_timing_type_and_negative (__main__.Normalization) ... ok
|
||||
test_all_events_beyond_recent_window (__main__.Reports) ... ok
|
||||
test_all_semantic_layers_compared (__main__.Reports) ... ok
|
||||
test_digest_alone_is_not_enough (__main__.Reports) ... ok
|
||||
test_event_original_types_and_order (__main__.Reports) ... ok
|
||||
test_event_start_and_ids (__main__.Reports) ... ok
|
||||
test_exclusions_keep_actual_values (__main__.Reports) ... ok
|
||||
test_handler_sets_and_counts (__main__.Reports) ... ok
|
||||
test_observation_full_layers (__main__.Reports) ... ok
|
||||
test_product_digest_self_consistency (__main__.Reports) ... ok
|
||||
test_same_report (__main__.Reports) ... ok
|
||||
test_scenario_existing_failures_preserved (__main__.Reports) ... ok
|
||||
test_timing_digest_rule (__main__.Reports) ... ok
|
||||
test_unknown_or_missing_fields_rejected (__main__.Reports) ... ok
|
||||
test_violation_presence_and_difference (__main__.Reports) ... ok
|
||||
test_O_cadence (__main__.S2Format) ... ok
|
||||
test_counter_and_published_ids_binding (__main__.S2Format) ... ok
|
||||
test_diff_and_same_as_S_transport (__main__.S2Format) ... ok
|
||||
test_digest_and_scenario_contradiction (__main__.S2Format) ... ok
|
||||
test_event_no_drop_duplicate_remap (__main__.S2Format) ... ok
|
||||
test_event_original_field_types_mandatory (__main__.S2Format) ... ok
|
||||
test_guard_actual_not_assumed (__main__.S2Format) ... ok
|
||||
test_harness_digest_allows_only_dictionary_order (__main__.S2Format) ... ok
|
||||
test_join_is_copy_and_retains_normalization_proof (__main__.S2Format) ... ok
|
||||
test_kernel_cache_contradictions (__main__.S2Format) ... ok
|
||||
test_lifecycle_guard_errors_and_boundaries (__main__.S2Format) ... ok
|
||||
test_missing_full_state_not_digest_only (__main__.S2Format) ... ok
|
||||
test_normalized_digest_and_raw_tree_are_both_bound (__main__.S2Format) ... ok
|
||||
test_product_event_shape_and_typed_array (__main__.S2Format) ... ok
|
||||
test_raw_observation_binding (__main__.S2Format) ... ok
|
||||
test_roundtrip_tree_sha_and_raw_sha (__main__.S2Format) ... ok
|
||||
test_s2_valid_and_not_formal_acceptance (__main__.S2Format) ... ok
|
||||
test_state_witness_and_observation_mutation (__main__.S2Format) ... ok
|
||||
test_stdout_exactly_one_line (__main__.S2Format) ... ok
|
||||
test_autoload_class_and_script_import (__main__.S2Static) ... ok
|
||||
test_comment_does_not_supply_proof (__main__.S2Static) ... ok
|
||||
test_current_probe (__main__.S2Static) ... ok
|
||||
test_full_state_and_godot_roundtrip_required (__main__.S2Static) ... ok
|
||||
test_no_changes_outside_preparation_or_step (__main__.S2Static) ... ok
|
||||
test_no_event_cap_or_duplicate_report (__main__.S2Static) ... ok
|
||||
test_pause_and_step_arguments (__main__.S2Static) ... ok
|
||||
test_textual_stringname_ordering (__main__.S2Static) ... ok
|
||||
test_unlisted_live_method_and_late_preparation (__main__.S2Static) ... ok
|
||||
test_variant_inference (__main__.S2Static) ... ok
|
||||
test_X_recent_limit_and_counter (__main__.S3a) ... ok
|
||||
test_duplicate_JSON_key_rejected (__main__.S3a) ... ok
|
||||
test_e3_NA_cannot_be_PASS_or_applied (__main__.S3a) ... ok
|
||||
test_e3_coverage_input_and_event_count_binding (__main__.S3a) ... ok
|
||||
test_e3_invented_codes_and_missing_load_code (__main__.S3a) ... ok
|
||||
test_e3_valid_R_and_O_records (__main__.S3a) ... ok
|
||||
test_envelope_duplicates_not_defect (__main__.S3a) ... ok
|
||||
test_event_count_defect_not_silently_accepted (__main__.S3a) ... ok
|
||||
test_exact_phase_keys (__main__.S3a) ... ok
|
||||
test_interval_gap_rejected (__main__.S3a) ... ok
|
||||
test_invalid_input_accepted_is_not_PASS (__main__.S3a) ... ok
|
||||
test_load_payload_and_pause_outcome (__main__.S3a) ... ok
|
||||
test_operation_moved_outside_scenario_rejected (__main__.S3a) ... ok
|
||||
test_package_fixed_mutations_and_hashes (__main__.S3a) ... ok
|
||||
test_probe_connection_required (__main__.S3a) ... ok
|
||||
test_rejection_mutation_retained_as_defect (__main__.S3a) ... ok
|
||||
test_save_refusal_makes_load_NA (__main__.S3a) ... ok
|
||||
test_scenario_mutation_static_boundary (__main__.S3a) ... ok
|
||||
test_signals_all_minutes_and_order (__main__.S3a) ... ok
|
||||
test_E5_cached_digest_defect_is_comparable (__main__.S3b) ... ok
|
||||
test_NA_not_PASS (__main__.S3b) ... ok
|
||||
test_aliasing_cannot_be_PASS (__main__.S3b) ... ok
|
||||
test_aliasing_missing_record (__main__.S3b) ... ok
|
||||
test_all_paths_and_ownership_R_O (__main__.S3b) ... ok
|
||||
test_digest_defect_other_checkpoint_still_rejected (__main__.S3b) ... ok
|
||||
test_digest_materialization_required (__main__.S3b) ... ok
|
||||
test_empty_registry_not_NA (__main__.S3b) ... ok
|
||||
test_event_count_mismatch (__main__.S3b) ... ok
|
||||
test_facts_normalization_is_reversible (__main__.S3b) ... ok
|
||||
test_first_placeable_choice (__main__.S3b) ... ok
|
||||
test_interval_gap (__main__.S3b) ... ok
|
||||
test_joined_s3b_self_comparison (__main__.S3b) ... ok
|
||||
test_load_X_not_digest_only (__main__.S3b) ... ok
|
||||
test_load_extra_event (__main__.S3b) ... ok
|
||||
test_missing_path_and_combination (__main__.S3b) ... ok
|
||||
test_missing_preview_observation (__main__.S3b) ... ok
|
||||
test_missing_trial (__main__.S3b) ... ok
|
||||
test_nested_mutation_required (__main__.S3b) ... ok
|
||||
test_no_staleness_assertion_for_non_tick (__main__.S3b) ... ok
|
||||
test_ownership_fact_dictionary_order_fallback (__main__.S3b) ... FAIL
|
||||
test_path_order (__main__.S3b) ... ok
|
||||
test_restore_extra_event (__main__.S3b) ... ok
|
||||
test_signal_facts_cannot_be_dropped (__main__.S3b) ... ok
|
||||
test_sort_rule_rejected (__main__.S3b) ... ok
|
||||
test_static_handler_and_outside_mutations (__main__.S3b) ... ok
|
||||
test_unpreviewed_choice (__main__.S3b) ... ok
|
||||
test_wrong_registry_in_either_role (__main__.S3b) ... ok
|
||||
test_fixed_scenario_paths (__main__.SourcesAndMetrics) ... ok
|
||||
test_metric_ranges (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_closure_synthetic_registered_map (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_pin_is_not_caller_controlled (__main__.SourcesAndMetrics) ... ok
|
||||
test_array_order_and_all_differences (__main__.TypedTrees) ... ok
|
||||
test_components_and_sha (__main__.TypedTrees) ... ok
|
||||
test_deep_state_not_truncated (__main__.TypedTrees) ... ok
|
||||
test_duplicate_textual_keys_rejected (__main__.TypedTrees) ... ok
|
||||
test_exact_and_types (__main__.TypedTrees) ... ok
|
||||
test_nested_order_all_paths (__main__.TypedTrees) ... ok
|
||||
test_nonstring_keys_keep_types_and_values (__main__.TypedTrees) ... ok
|
||||
test_unsupported_and_malformed (__main__.TypedTrees) ... ok
|
||||
|
||||
======================================================================
|
||||
FAIL: test_ownership_fact_dictionary_order_fallback (__main__.S3b)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1233, in test_ownership_fact_dictionary_order_fallback
|
||||
self.assertTrue(result['ok'], result['differences'])
|
||||
AssertionError: False is not true : []
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 119 tests in 31.877s
|
||||
|
||||
FAILED (failures=1)
|
||||
+1
@@ -0,0 +1 @@
|
||||
8360a2065b303099d5c546b3e4aecc0cc0ab0c2c1e5120b8034b6a1a64317030 UNIT_OUTPUT_S3B_ATTEMPT_09.txt
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
test_all_operations (__main__.Diffs) ... ok
|
||||
test_invalid_operations (__main__.Diffs) ... ok
|
||||
test_reconstruction_and_proofs (__main__.Diffs) ... ok
|
||||
test_attempt_to_normalize_violation_rejected (__main__.Normalization) ... ok
|
||||
test_environment_values_differ_but_normal_form_equal (__main__.Normalization) ... ok
|
||||
test_every_save_event_reversible (__main__.Normalization) ... ok
|
||||
test_f3_keeps_relative_paths_and_words (__main__.Normalization) ... ok
|
||||
test_guard_mismatch (__main__.Normalization) ... ok
|
||||
test_nested_lookalike_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_original_transport_sha_detects_forged_timing (__main__.Normalization) ... ok
|
||||
test_partial_timing_payload_rejected (__main__.Normalization) ... ok
|
||||
test_prefix_boundary_and_reserved_token (__main__.Normalization) ... ok
|
||||
test_sidecar_missing_duplicate_and_forged_paths (__main__.Normalization) ... ok
|
||||
test_snapshot_and_latest_reversible (__main__.Normalization) ... ok
|
||||
test_snapshot_event_outside_recent_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_wrong_event_and_source_are_preserved (__main__.Normalization) ... ok
|
||||
test_wrong_timing_type_and_negative (__main__.Normalization) ... ok
|
||||
test_all_events_beyond_recent_window (__main__.Reports) ... ok
|
||||
test_all_semantic_layers_compared (__main__.Reports) ... ok
|
||||
test_digest_alone_is_not_enough (__main__.Reports) ... ok
|
||||
test_event_original_types_and_order (__main__.Reports) ... ok
|
||||
test_event_start_and_ids (__main__.Reports) ... ok
|
||||
test_exclusions_keep_actual_values (__main__.Reports) ... ok
|
||||
test_handler_sets_and_counts (__main__.Reports) ... ok
|
||||
test_observation_full_layers (__main__.Reports) ... ok
|
||||
test_product_digest_self_consistency (__main__.Reports) ... ok
|
||||
test_same_report (__main__.Reports) ... ok
|
||||
test_scenario_existing_failures_preserved (__main__.Reports) ... ok
|
||||
test_timing_digest_rule (__main__.Reports) ... ok
|
||||
test_unknown_or_missing_fields_rejected (__main__.Reports) ... ok
|
||||
test_violation_presence_and_difference (__main__.Reports) ... ok
|
||||
test_O_cadence (__main__.S2Format) ... ok
|
||||
test_counter_and_published_ids_binding (__main__.S2Format) ... ok
|
||||
test_diff_and_same_as_S_transport (__main__.S2Format) ... ok
|
||||
test_digest_and_scenario_contradiction (__main__.S2Format) ... ok
|
||||
test_event_no_drop_duplicate_remap (__main__.S2Format) ... ok
|
||||
test_event_original_field_types_mandatory (__main__.S2Format) ... ok
|
||||
test_guard_actual_not_assumed (__main__.S2Format) ... ok
|
||||
test_harness_digest_allows_only_dictionary_order (__main__.S2Format) ... ok
|
||||
test_join_is_copy_and_retains_normalization_proof (__main__.S2Format) ... ok
|
||||
test_kernel_cache_contradictions (__main__.S2Format) ... ok
|
||||
test_lifecycle_guard_errors_and_boundaries (__main__.S2Format) ... ok
|
||||
test_missing_full_state_not_digest_only (__main__.S2Format) ... ok
|
||||
test_normalized_digest_and_raw_tree_are_both_bound (__main__.S2Format) ... ok
|
||||
test_product_event_shape_and_typed_array (__main__.S2Format) ... ok
|
||||
test_raw_observation_binding (__main__.S2Format) ... ok
|
||||
test_roundtrip_tree_sha_and_raw_sha (__main__.S2Format) ... ok
|
||||
test_s2_valid_and_not_formal_acceptance (__main__.S2Format) ... ok
|
||||
test_state_witness_and_observation_mutation (__main__.S2Format) ... ok
|
||||
test_stdout_exactly_one_line (__main__.S2Format) ... ok
|
||||
test_autoload_class_and_script_import (__main__.S2Static) ... ok
|
||||
test_comment_does_not_supply_proof (__main__.S2Static) ... ok
|
||||
test_current_probe (__main__.S2Static) ... ok
|
||||
test_full_state_and_godot_roundtrip_required (__main__.S2Static) ... ok
|
||||
test_no_changes_outside_preparation_or_step (__main__.S2Static) ... ok
|
||||
test_no_event_cap_or_duplicate_report (__main__.S2Static) ... ok
|
||||
test_pause_and_step_arguments (__main__.S2Static) ... ok
|
||||
test_textual_stringname_ordering (__main__.S2Static) ... ok
|
||||
test_unlisted_live_method_and_late_preparation (__main__.S2Static) ... ok
|
||||
test_variant_inference (__main__.S2Static) ... ok
|
||||
test_X_recent_limit_and_counter (__main__.S3a) ... ok
|
||||
test_duplicate_JSON_key_rejected (__main__.S3a) ... ok
|
||||
test_e3_NA_cannot_be_PASS_or_applied (__main__.S3a) ... ok
|
||||
test_e3_coverage_input_and_event_count_binding (__main__.S3a) ... ok
|
||||
test_e3_invented_codes_and_missing_load_code (__main__.S3a) ... ok
|
||||
test_e3_valid_R_and_O_records (__main__.S3a) ... ok
|
||||
test_envelope_duplicates_not_defect (__main__.S3a) ... ok
|
||||
test_event_count_defect_not_silently_accepted (__main__.S3a) ... ok
|
||||
test_exact_phase_keys (__main__.S3a) ... ok
|
||||
test_interval_gap_rejected (__main__.S3a) ... ok
|
||||
test_invalid_input_accepted_is_not_PASS (__main__.S3a) ... ok
|
||||
test_load_payload_and_pause_outcome (__main__.S3a) ... ok
|
||||
test_operation_moved_outside_scenario_rejected (__main__.S3a) ... ok
|
||||
test_package_fixed_mutations_and_hashes (__main__.S3a) ... ok
|
||||
test_probe_connection_required (__main__.S3a) ... ok
|
||||
test_rejection_mutation_retained_as_defect (__main__.S3a) ... ok
|
||||
test_save_refusal_makes_load_NA (__main__.S3a) ... ok
|
||||
test_scenario_mutation_static_boundary (__main__.S3a) ... ok
|
||||
test_signals_all_minutes_and_order (__main__.S3a) ... ok
|
||||
test_E5_cached_digest_defect_is_comparable (__main__.S3b) ... ok
|
||||
test_NA_not_PASS (__main__.S3b) ... ok
|
||||
test_aliasing_cannot_be_PASS (__main__.S3b) ... ok
|
||||
test_aliasing_missing_record (__main__.S3b) ... ok
|
||||
test_all_paths_and_ownership_R_O (__main__.S3b) ... ok
|
||||
test_digest_defect_other_checkpoint_still_rejected (__main__.S3b) ... ok
|
||||
test_digest_materialization_required (__main__.S3b) ... ok
|
||||
test_empty_registry_not_NA (__main__.S3b) ... ok
|
||||
test_event_count_mismatch (__main__.S3b) ... ok
|
||||
test_facts_normalization_is_reversible (__main__.S3b) ... ok
|
||||
test_first_placeable_choice (__main__.S3b) ... ok
|
||||
test_interval_gap (__main__.S3b) ... ok
|
||||
test_joined_s3b_self_comparison (__main__.S3b) ... ok
|
||||
test_load_X_not_digest_only (__main__.S3b) ... ok
|
||||
test_load_extra_event (__main__.S3b) ... ok
|
||||
test_missing_path_and_combination (__main__.S3b) ... ok
|
||||
test_missing_preview_observation (__main__.S3b) ... ok
|
||||
test_missing_trial (__main__.S3b) ... ok
|
||||
test_nested_mutation_required (__main__.S3b) ... ok
|
||||
test_no_staleness_assertion_for_non_tick (__main__.S3b) ... ok
|
||||
test_ownership_fact_dictionary_order_fallback (__main__.S3b) ... ok
|
||||
test_path_order (__main__.S3b) ... ok
|
||||
test_restore_extra_event (__main__.S3b) ... ok
|
||||
test_signal_facts_cannot_be_dropped (__main__.S3b) ... ok
|
||||
test_sort_rule_rejected (__main__.S3b) ... ok
|
||||
test_static_handler_and_outside_mutations (__main__.S3b) ... ok
|
||||
test_unpreviewed_choice (__main__.S3b) ... ok
|
||||
test_wrong_registry_in_either_role (__main__.S3b) ... ok
|
||||
test_fixed_scenario_paths (__main__.SourcesAndMetrics) ... ok
|
||||
test_metric_ranges (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_closure_synthetic_registered_map (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_pin_is_not_caller_controlled (__main__.SourcesAndMetrics) ... ok
|
||||
test_array_order_and_all_differences (__main__.TypedTrees) ... ok
|
||||
test_components_and_sha (__main__.TypedTrees) ... ok
|
||||
test_deep_state_not_truncated (__main__.TypedTrees) ... ok
|
||||
test_duplicate_textual_keys_rejected (__main__.TypedTrees) ... ok
|
||||
test_exact_and_types (__main__.TypedTrees) ... ok
|
||||
test_nested_order_all_paths (__main__.TypedTrees) ... ok
|
||||
test_nonstring_keys_keep_types_and_values (__main__.TypedTrees) ... ok
|
||||
test_unsupported_and_malformed (__main__.TypedTrees) ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 119 tests in 32.034s
|
||||
|
||||
OK
|
||||
+1
@@ -0,0 +1 @@
|
||||
ff9620ce295f2f2edc25e9b0014ac4db221e1b26e8ba1b0f20c20e7e5d045ce9 UNIT_OUTPUT_S4_ATTEMPT_01.txt
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
Traceback (most recent call last):
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1241, in <module>
|
||||
import run_eq as driver
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/run_eq.py", line 16, in <module>
|
||||
import verify_eq as verify
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/verify_eq.py", line 18, in <module>
|
||||
NAMES = {f'{prefix}-{i:02d}.json' for prefix, count in
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/verify_eq.py", line 18, in <setcomp>
|
||||
NAMES = {f'{prefix}-{i:02d}.json' for prefix, count in
|
||||
NameError: name 'i' is not defined
|
||||
+1
@@ -0,0 +1 @@
|
||||
140d2c270f7c15297bed638c23dd38295381eebacc123fccdc112d32162dcefe UNIT_OUTPUT_S4_ATTEMPT_02.txt
|
||||
+328
@@ -0,0 +1,328 @@
|
||||
test_all_operations (__main__.Diffs) ... ok
|
||||
test_invalid_operations (__main__.Diffs) ... ok
|
||||
test_reconstruction_and_proofs (__main__.Diffs) ... ok
|
||||
test_attempt_to_normalize_violation_rejected (__main__.Normalization) ... ok
|
||||
test_environment_values_differ_but_normal_form_equal (__main__.Normalization) ... ok
|
||||
test_every_save_event_reversible (__main__.Normalization) ... ok
|
||||
test_f3_keeps_relative_paths_and_words (__main__.Normalization) ... ok
|
||||
test_guard_mismatch (__main__.Normalization) ... ok
|
||||
test_nested_lookalike_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_original_transport_sha_detects_forged_timing (__main__.Normalization) ... ok
|
||||
test_partial_timing_payload_rejected (__main__.Normalization) ... ok
|
||||
test_prefix_boundary_and_reserved_token (__main__.Normalization) ... ok
|
||||
test_sidecar_missing_duplicate_and_forged_paths (__main__.Normalization) ... ok
|
||||
test_snapshot_and_latest_reversible (__main__.Normalization) ... ok
|
||||
test_snapshot_event_outside_recent_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_wrong_event_and_source_are_preserved (__main__.Normalization) ... ok
|
||||
test_wrong_timing_type_and_negative (__main__.Normalization) ... ok
|
||||
test_all_events_beyond_recent_window (__main__.Reports) ... ok
|
||||
test_all_semantic_layers_compared (__main__.Reports) ... ok
|
||||
test_digest_alone_is_not_enough (__main__.Reports) ... ok
|
||||
test_event_original_types_and_order (__main__.Reports) ... ok
|
||||
test_event_start_and_ids (__main__.Reports) ... ok
|
||||
test_exclusions_keep_actual_values (__main__.Reports) ... ok
|
||||
test_handler_sets_and_counts (__main__.Reports) ... ok
|
||||
test_observation_full_layers (__main__.Reports) ... ok
|
||||
test_product_digest_self_consistency (__main__.Reports) ... ok
|
||||
test_same_report (__main__.Reports) ... ok
|
||||
test_scenario_existing_failures_preserved (__main__.Reports) ... ok
|
||||
test_timing_digest_rule (__main__.Reports) ... ok
|
||||
test_unknown_or_missing_fields_rejected (__main__.Reports) ... ok
|
||||
test_violation_presence_and_difference (__main__.Reports) ... ok
|
||||
test_O_cadence (__main__.S2Format) ... ok
|
||||
test_counter_and_published_ids_binding (__main__.S2Format) ... ok
|
||||
test_diff_and_same_as_S_transport (__main__.S2Format) ... ok
|
||||
test_digest_and_scenario_contradiction (__main__.S2Format) ... ok
|
||||
test_event_no_drop_duplicate_remap (__main__.S2Format) ... ok
|
||||
test_event_original_field_types_mandatory (__main__.S2Format) ... ok
|
||||
test_guard_actual_not_assumed (__main__.S2Format) ... ok
|
||||
test_harness_digest_allows_only_dictionary_order (__main__.S2Format) ... ok
|
||||
test_join_is_copy_and_retains_normalization_proof (__main__.S2Format) ... ok
|
||||
test_kernel_cache_contradictions (__main__.S2Format) ... ok
|
||||
test_lifecycle_guard_errors_and_boundaries (__main__.S2Format) ... ok
|
||||
test_missing_full_state_not_digest_only (__main__.S2Format) ... ok
|
||||
test_normalized_digest_and_raw_tree_are_both_bound (__main__.S2Format) ... ok
|
||||
test_product_event_shape_and_typed_array (__main__.S2Format) ... ok
|
||||
test_raw_observation_binding (__main__.S2Format) ... ok
|
||||
test_roundtrip_tree_sha_and_raw_sha (__main__.S2Format) ... ok
|
||||
test_s2_valid_and_not_formal_acceptance (__main__.S2Format) ... ok
|
||||
test_state_witness_and_observation_mutation (__main__.S2Format) ... ok
|
||||
test_stdout_exactly_one_line (__main__.S2Format) ... ok
|
||||
test_autoload_class_and_script_import (__main__.S2Static) ... ok
|
||||
test_comment_does_not_supply_proof (__main__.S2Static) ... ok
|
||||
test_current_probe (__main__.S2Static) ... ok
|
||||
test_full_state_and_godot_roundtrip_required (__main__.S2Static) ... ok
|
||||
test_no_changes_outside_preparation_or_step (__main__.S2Static) ... ok
|
||||
test_no_event_cap_or_duplicate_report (__main__.S2Static) ... ok
|
||||
test_pause_and_step_arguments (__main__.S2Static) ... ok
|
||||
test_textual_stringname_ordering (__main__.S2Static) ... ok
|
||||
test_unlisted_live_method_and_late_preparation (__main__.S2Static) ... ok
|
||||
test_variant_inference (__main__.S2Static) ... ok
|
||||
test_X_recent_limit_and_counter (__main__.S3a) ... ok
|
||||
test_duplicate_JSON_key_rejected (__main__.S3a) ... ok
|
||||
test_e3_NA_cannot_be_PASS_or_applied (__main__.S3a) ... ok
|
||||
test_e3_coverage_input_and_event_count_binding (__main__.S3a) ... ok
|
||||
test_e3_invented_codes_and_missing_load_code (__main__.S3a) ... ok
|
||||
test_e3_valid_R_and_O_records (__main__.S3a) ... ok
|
||||
test_envelope_duplicates_not_defect (__main__.S3a) ... ok
|
||||
test_event_count_defect_not_silently_accepted (__main__.S3a) ... ok
|
||||
test_exact_phase_keys (__main__.S3a) ... ok
|
||||
test_interval_gap_rejected (__main__.S3a) ... ok
|
||||
test_invalid_input_accepted_is_not_PASS (__main__.S3a) ... ok
|
||||
test_load_payload_and_pause_outcome (__main__.S3a) ... ok
|
||||
test_operation_moved_outside_scenario_rejected (__main__.S3a) ... ok
|
||||
test_package_fixed_mutations_and_hashes (__main__.S3a) ... ok
|
||||
test_probe_connection_required (__main__.S3a) ... ok
|
||||
test_rejection_mutation_retained_as_defect (__main__.S3a) ... ok
|
||||
test_save_refusal_makes_load_NA (__main__.S3a) ... ok
|
||||
test_scenario_mutation_static_boundary (__main__.S3a) ... ok
|
||||
test_signals_all_minutes_and_order (__main__.S3a) ... ok
|
||||
test_E5_cached_digest_defect_is_comparable (__main__.S3b) ... ok
|
||||
test_NA_not_PASS (__main__.S3b) ... ok
|
||||
test_aliasing_cannot_be_PASS (__main__.S3b) ... ok
|
||||
test_aliasing_missing_record (__main__.S3b) ... ok
|
||||
test_all_paths_and_ownership_R_O (__main__.S3b) ... ok
|
||||
test_digest_defect_other_checkpoint_still_rejected (__main__.S3b) ... ok
|
||||
test_digest_materialization_required (__main__.S3b) ... ok
|
||||
test_empty_registry_not_NA (__main__.S3b) ... ok
|
||||
test_event_count_mismatch (__main__.S3b) ... ok
|
||||
test_facts_normalization_is_reversible (__main__.S3b) ... ok
|
||||
test_first_placeable_choice (__main__.S3b) ... ok
|
||||
test_interval_gap (__main__.S3b) ... ok
|
||||
test_joined_s3b_self_comparison (__main__.S3b) ... ok
|
||||
test_load_X_not_digest_only (__main__.S3b) ... ok
|
||||
test_load_extra_event (__main__.S3b) ... ok
|
||||
test_missing_path_and_combination (__main__.S3b) ... ok
|
||||
test_missing_preview_observation (__main__.S3b) ... ok
|
||||
test_missing_trial (__main__.S3b) ... ok
|
||||
test_nested_mutation_required (__main__.S3b) ... ok
|
||||
test_no_staleness_assertion_for_non_tick (__main__.S3b) ... ok
|
||||
test_ownership_fact_dictionary_order_fallback (__main__.S3b) ... ok
|
||||
test_path_order (__main__.S3b) ... ok
|
||||
test_restore_extra_event (__main__.S3b) ... ok
|
||||
test_signal_facts_cannot_be_dropped (__main__.S3b) ... ok
|
||||
test_sort_rule_rejected (__main__.S3b) ... ok
|
||||
test_static_handler_and_outside_mutations (__main__.S3b) ... ok
|
||||
test_unpreviewed_choice (__main__.S3b) ... ok
|
||||
test_wrong_registry_in_either_role (__main__.S3b) ... ok
|
||||
test_checkout_temp_destination_rejected (__main__.S4Bundle) ... ok
|
||||
test_existing_output_never_overwritten (__main__.S4Bundle) ... ok
|
||||
test_import_closure_rejections (__main__.S4Bundle) ... ok
|
||||
test_missing_bundle_manifest_seal_and_changed_bytes (__main__.S4Bundle) ... ok
|
||||
test_missing_private_evidence_and_extra_rejected (__main__.S4Bundle) ... test_missing_profile_not_export_success (__main__.S4Bundle) ... ok
|
||||
test_phase_role_pid_audio_and_guard_rejected (__main__.S4Bundle) ... ERROR
|
||||
test_seal_normal_and_changes_not_native_proof (__main__.S4Bundle) ... ok
|
||||
test_synthetic_phase_all_real_checkers_not_native_proof (__main__.S4Bundle) ... ERROR
|
||||
test_fixed_scenario_paths (__main__.SourcesAndMetrics) ... ok
|
||||
test_metric_ranges (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_closure_synthetic_registered_map (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_pin_is_not_caller_controlled (__main__.SourcesAndMetrics) ... ok
|
||||
test_array_order_and_all_differences (__main__.TypedTrees) ... ok
|
||||
test_components_and_sha (__main__.TypedTrees) ... ok
|
||||
test_deep_state_not_truncated (__main__.TypedTrees) ... ok
|
||||
test_duplicate_textual_keys_rejected (__main__.TypedTrees) ... ok
|
||||
test_exact_and_types (__main__.TypedTrees) ... ok
|
||||
test_nested_order_all_paths (__main__.TypedTrees) ... ok
|
||||
test_nonstring_keys_keep_types_and_values (__main__.TypedTrees) ... ok
|
||||
test_unsupported_and_malformed (__main__.TypedTrees) ... ok
|
||||
|
||||
======================================================================
|
||||
ERROR: test_missing_private_evidence_and_extra_rejected (__main__.S4Bundle) (filename='lifecycle.json')
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1365, in test_missing_private_evidence_and_extra_rejected
|
||||
directory = Path(name); row = s4_phase_fixture(directory)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1285, in s4_phase_fixture
|
||||
raw, e3, b1, e45 = s4_report_fixture(role)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1270, in s4_report_fixture
|
||||
add_world(e3raw); add_world(e3); add_world(b1)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1269, in add_world
|
||||
for child in value: add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1267, in add_world
|
||||
for child in value.values(): add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1267, in add_world
|
||||
for child in value.values(): add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1267, in add_world
|
||||
for child in value.values(): add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1266, in add_world
|
||||
value['tree_sha'] = eq.tree_sha(tree)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/compare_versions.py", line 109, in tree_sha
|
||||
validate_tree(tree)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/compare_versions.py", line 70, in validate_tree
|
||||
require(key not in seen, 'duplicate dictionary key')
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/compare_versions.py", line 29, in require
|
||||
raise EvidenceError(message)
|
||||
compare_versions.EvidenceError: duplicate dictionary key
|
||||
|
||||
======================================================================
|
||||
ERROR: test_missing_private_evidence_and_extra_rejected (__main__.S4Bundle) (filename='audio-close.json')
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1365, in test_missing_private_evidence_and_extra_rejected
|
||||
directory = Path(name); row = s4_phase_fixture(directory)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1285, in s4_phase_fixture
|
||||
raw, e3, b1, e45 = s4_report_fixture(role)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1270, in s4_report_fixture
|
||||
add_world(e3raw); add_world(e3); add_world(b1)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1269, in add_world
|
||||
for child in value: add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1267, in add_world
|
||||
for child in value.values(): add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1267, in add_world
|
||||
for child in value.values(): add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1267, in add_world
|
||||
for child in value.values(): add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1266, in add_world
|
||||
value['tree_sha'] = eq.tree_sha(tree)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/compare_versions.py", line 109, in tree_sha
|
||||
validate_tree(tree)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/compare_versions.py", line 70, in validate_tree
|
||||
require(key not in seen, 'duplicate dictionary key')
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/compare_versions.py", line 29, in require
|
||||
raise EvidenceError(message)
|
||||
compare_versions.EvidenceError: duplicate dictionary key
|
||||
|
||||
======================================================================
|
||||
ERROR: test_missing_private_evidence_and_extra_rejected (__main__.S4Bundle) (filename='e3-17.json')
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1365, in test_missing_private_evidence_and_extra_rejected
|
||||
directory = Path(name); row = s4_phase_fixture(directory)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1285, in s4_phase_fixture
|
||||
raw, e3, b1, e45 = s4_report_fixture(role)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1270, in s4_report_fixture
|
||||
add_world(e3raw); add_world(e3); add_world(b1)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1269, in add_world
|
||||
for child in value: add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1267, in add_world
|
||||
for child in value.values(): add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1267, in add_world
|
||||
for child in value.values(): add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1267, in add_world
|
||||
for child in value.values(): add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1266, in add_world
|
||||
value['tree_sha'] = eq.tree_sha(tree)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/compare_versions.py", line 109, in tree_sha
|
||||
validate_tree(tree)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/compare_versions.py", line 70, in validate_tree
|
||||
require(key not in seen, 'duplicate dictionary key')
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/compare_versions.py", line 29, in require
|
||||
raise EvidenceError(message)
|
||||
compare_versions.EvidenceError: duplicate dictionary key
|
||||
|
||||
======================================================================
|
||||
ERROR: test_missing_private_evidence_and_extra_rejected (__main__.S4Bundle) (filename='e45-20.json')
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1365, in test_missing_private_evidence_and_extra_rejected
|
||||
directory = Path(name); row = s4_phase_fixture(directory)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1285, in s4_phase_fixture
|
||||
raw, e3, b1, e45 = s4_report_fixture(role)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1270, in s4_report_fixture
|
||||
add_world(e3raw); add_world(e3); add_world(b1)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1269, in add_world
|
||||
for child in value: add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1267, in add_world
|
||||
for child in value.values(): add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1267, in add_world
|
||||
for child in value.values(): add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1267, in add_world
|
||||
for child in value.values(): add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1266, in add_world
|
||||
value['tree_sha'] = eq.tree_sha(tree)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/compare_versions.py", line 109, in tree_sha
|
||||
validate_tree(tree)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/compare_versions.py", line 70, in validate_tree
|
||||
require(key not in seen, 'duplicate dictionary key')
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/compare_versions.py", line 29, in require
|
||||
raise EvidenceError(message)
|
||||
compare_versions.EvidenceError: duplicate dictionary key
|
||||
|
||||
======================================================================
|
||||
ERROR: test_missing_private_evidence_and_extra_rejected (__main__.S4Bundle) (filename='extra.json')
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1365, in test_missing_private_evidence_and_extra_rejected
|
||||
directory = Path(name); row = s4_phase_fixture(directory)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1285, in s4_phase_fixture
|
||||
raw, e3, b1, e45 = s4_report_fixture(role)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1270, in s4_report_fixture
|
||||
add_world(e3raw); add_world(e3); add_world(b1)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1269, in add_world
|
||||
for child in value: add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1267, in add_world
|
||||
for child in value.values(): add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1267, in add_world
|
||||
for child in value.values(): add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1267, in add_world
|
||||
for child in value.values(): add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1266, in add_world
|
||||
value['tree_sha'] = eq.tree_sha(tree)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/compare_versions.py", line 109, in tree_sha
|
||||
validate_tree(tree)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/compare_versions.py", line 70, in validate_tree
|
||||
require(key not in seen, 'duplicate dictionary key')
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/compare_versions.py", line 29, in require
|
||||
raise EvidenceError(message)
|
||||
compare_versions.EvidenceError: duplicate dictionary key
|
||||
|
||||
======================================================================
|
||||
ERROR: test_phase_role_pid_audio_and_guard_rejected (__main__.S4Bundle)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1373, in test_phase_role_pid_audio_and_guard_rejected
|
||||
directory = Path(name); row = s4_phase_fixture(directory)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1285, in s4_phase_fixture
|
||||
raw, e3, b1, e45 = s4_report_fixture(role)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1270, in s4_report_fixture
|
||||
add_world(e3raw); add_world(e3); add_world(b1)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1269, in add_world
|
||||
for child in value: add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1267, in add_world
|
||||
for child in value.values(): add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1267, in add_world
|
||||
for child in value.values(): add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1267, in add_world
|
||||
for child in value.values(): add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1266, in add_world
|
||||
value['tree_sha'] = eq.tree_sha(tree)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/compare_versions.py", line 109, in tree_sha
|
||||
validate_tree(tree)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/compare_versions.py", line 70, in validate_tree
|
||||
require(key not in seen, 'duplicate dictionary key')
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/compare_versions.py", line 29, in require
|
||||
raise EvidenceError(message)
|
||||
compare_versions.EvidenceError: duplicate dictionary key
|
||||
|
||||
======================================================================
|
||||
ERROR: test_synthetic_phase_all_real_checkers_not_native_proof (__main__.S4Bundle)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1336, in test_synthetic_phase_all_real_checkers_not_native_proof
|
||||
row = s4_phase_fixture(directory)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1285, in s4_phase_fixture
|
||||
raw, e3, b1, e45 = s4_report_fixture(role)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1270, in s4_report_fixture
|
||||
add_world(e3raw); add_world(e3); add_world(b1)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1269, in add_world
|
||||
for child in value: add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1267, in add_world
|
||||
for child in value.values(): add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1267, in add_world
|
||||
for child in value.values(): add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1267, in add_world
|
||||
for child in value.values(): add_world(child)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1266, in add_world
|
||||
value['tree_sha'] = eq.tree_sha(tree)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/compare_versions.py", line 109, in tree_sha
|
||||
validate_tree(tree)
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/compare_versions.py", line 70, in validate_tree
|
||||
require(key not in seen, 'duplicate dictionary key')
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/compare_versions.py", line 29, in require
|
||||
raise EvidenceError(message)
|
||||
compare_versions.EvidenceError: duplicate dictionary key
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 128 tests in 34.518s
|
||||
|
||||
FAILED (errors=7)
|
||||
+1
@@ -0,0 +1 @@
|
||||
9f27f201325809a590375b7842101ef6b7d08c7de0aa4e66b4de2b7f7fd673d1 UNIT_OUTPUT_S4_ATTEMPT_03.txt
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
test_checkout_temp_destination_rejected (__main__.S4Bundle) ... ok
|
||||
test_existing_output_never_overwritten (__main__.S4Bundle) ... ok
|
||||
test_import_closure_rejections (__main__.S4Bundle) ... ok
|
||||
test_missing_bundle_manifest_seal_and_changed_bytes (__main__.S4Bundle) ... ok
|
||||
test_missing_private_evidence_and_extra_rejected (__main__.S4Bundle) ... ok
|
||||
test_missing_profile_not_export_success (__main__.S4Bundle) ... ok
|
||||
test_phase_role_pid_audio_and_guard_rejected (__main__.S4Bundle) ... ok
|
||||
test_seal_normal_and_changes_not_native_proof (__main__.S4Bundle) ... ok
|
||||
test_synthetic_phase_all_real_checkers_not_native_proof (__main__.S4Bundle) ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 9 tests in 19.447s
|
||||
|
||||
OK
|
||||
+1
@@ -0,0 +1 @@
|
||||
76738bb4138955e5fec02a93358c55446183492e99fd4d4360ac7fad58caacf9 UNIT_OUTPUT_S4_ATTEMPT_04.txt
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
test_copied_manifest_root_and_destination_count_rejected (__main__.S4NativeBundleLogic) ... ok
|
||||
test_gate_none_success_not_boolean (__main__.S4NativeBundleLogic) ... ok
|
||||
test_receipt_and_source_rejection_matrix (__main__.S4NativeBundleLogic) ... ok
|
||||
test_synthetic_full_bundle_positive_not_native_evidence (__main__.S4NativeBundleLogic) ... ERROR
|
||||
|
||||
======================================================================
|
||||
ERROR: test_synthetic_full_bundle_positive_not_native_evidence (__main__.S4NativeBundleLogic)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1506, in test_synthetic_full_bundle_positive_not_native_evidence
|
||||
patch.object(driver, 'load_dependencies', return_value=(self.collector, self.standard, self.outer, self.diag)):
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/verify_eq.py", line 217, in verify
|
||||
from run_eq import load_dependencies, actual_pins
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/compare_versions.py", line 29, in require
|
||||
raise EvidenceError(message)
|
||||
compare_versions.EvidenceError: recomputed results differ
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 4 tests in 124.325s
|
||||
|
||||
FAILED (errors=1)
|
||||
+1
@@ -0,0 +1 @@
|
||||
aa13731a56337065e1a74acbfb640d56655cb4f774c9780dc265c40cf097101e UNIT_OUTPUT_S4_ATTEMPT_05.txt
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
test_all_operations (__main__.Diffs) ... ok
|
||||
test_invalid_operations (__main__.Diffs) ... ok
|
||||
test_reconstruction_and_proofs (__main__.Diffs) ... ok
|
||||
test_attempt_to_normalize_violation_rejected (__main__.Normalization) ... ok
|
||||
test_environment_values_differ_but_normal_form_equal (__main__.Normalization) ... ok
|
||||
test_every_save_event_reversible (__main__.Normalization) ... ok
|
||||
test_f3_keeps_relative_paths_and_words (__main__.Normalization) ... ok
|
||||
test_guard_mismatch (__main__.Normalization) ... ok
|
||||
test_nested_lookalike_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_original_transport_sha_detects_forged_timing (__main__.Normalization) ... ok
|
||||
test_partial_timing_payload_rejected (__main__.Normalization) ... ok
|
||||
test_prefix_boundary_and_reserved_token (__main__.Normalization) ... ok
|
||||
test_sidecar_missing_duplicate_and_forged_paths (__main__.Normalization) ... ok
|
||||
test_snapshot_and_latest_reversible (__main__.Normalization) ... ok
|
||||
test_snapshot_event_outside_recent_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_wrong_event_and_source_are_preserved (__main__.Normalization) ... ok
|
||||
test_wrong_timing_type_and_negative (__main__.Normalization) ... ok
|
||||
test_all_events_beyond_recent_window (__main__.Reports) ... ok
|
||||
test_all_semantic_layers_compared (__main__.Reports) ... ok
|
||||
test_digest_alone_is_not_enough (__main__.Reports) ... ok
|
||||
test_event_original_types_and_order (__main__.Reports) ... ok
|
||||
test_event_start_and_ids (__main__.Reports) ... ok
|
||||
test_exclusions_keep_actual_values (__main__.Reports) ... ok
|
||||
test_handler_sets_and_counts (__main__.Reports) ... ok
|
||||
test_observation_full_layers (__main__.Reports) ... ok
|
||||
test_product_digest_self_consistency (__main__.Reports) ... ok
|
||||
test_same_report (__main__.Reports) ... ok
|
||||
test_scenario_existing_failures_preserved (__main__.Reports) ... ok
|
||||
test_timing_digest_rule (__main__.Reports) ... ok
|
||||
test_unknown_or_missing_fields_rejected (__main__.Reports) ... ok
|
||||
test_violation_presence_and_difference (__main__.Reports) ... ok
|
||||
test_O_cadence (__main__.S2Format) ... ok
|
||||
test_counter_and_published_ids_binding (__main__.S2Format) ... ok
|
||||
test_diff_and_same_as_S_transport (__main__.S2Format) ... ok
|
||||
test_digest_and_scenario_contradiction (__main__.S2Format) ... ok
|
||||
test_event_no_drop_duplicate_remap (__main__.S2Format) ... ok
|
||||
test_event_original_field_types_mandatory (__main__.S2Format) ... ok
|
||||
test_guard_actual_not_assumed (__main__.S2Format) ... ok
|
||||
test_harness_digest_allows_only_dictionary_order (__main__.S2Format) ... ok
|
||||
test_join_is_copy_and_retains_normalization_proof (__main__.S2Format) ... ok
|
||||
test_kernel_cache_contradictions (__main__.S2Format) ... ok
|
||||
test_lifecycle_guard_errors_and_boundaries (__main__.S2Format) ... ok
|
||||
test_missing_full_state_not_digest_only (__main__.S2Format) ... ok
|
||||
test_normalized_digest_and_raw_tree_are_both_bound (__main__.S2Format) ... ok
|
||||
test_product_event_shape_and_typed_array (__main__.S2Format) ... ok
|
||||
test_raw_observation_binding (__main__.S2Format) ... ok
|
||||
test_roundtrip_tree_sha_and_raw_sha (__main__.S2Format) ... ok
|
||||
test_s2_valid_and_not_formal_acceptance (__main__.S2Format) ... ok
|
||||
test_state_witness_and_observation_mutation (__main__.S2Format) ... ok
|
||||
test_stdout_exactly_one_line (__main__.S2Format) ... ok
|
||||
test_autoload_class_and_script_import (__main__.S2Static) ... ok
|
||||
test_comment_does_not_supply_proof (__main__.S2Static) ... ok
|
||||
test_current_probe (__main__.S2Static) ... ok
|
||||
test_full_state_and_godot_roundtrip_required (__main__.S2Static) ... ok
|
||||
test_no_changes_outside_preparation_or_step (__main__.S2Static) ... ok
|
||||
test_no_event_cap_or_duplicate_report (__main__.S2Static) ... ok
|
||||
test_pause_and_step_arguments (__main__.S2Static) ... ok
|
||||
test_textual_stringname_ordering (__main__.S2Static) ... ok
|
||||
test_unlisted_live_method_and_late_preparation (__main__.S2Static) ... ok
|
||||
test_variant_inference (__main__.S2Static) ... ok
|
||||
test_X_recent_limit_and_counter (__main__.S3a) ... ok
|
||||
test_duplicate_JSON_key_rejected (__main__.S3a) ... ok
|
||||
test_e3_NA_cannot_be_PASS_or_applied (__main__.S3a) ... ok
|
||||
test_e3_coverage_input_and_event_count_binding (__main__.S3a) ... ok
|
||||
test_e3_invented_codes_and_missing_load_code (__main__.S3a) ... ok
|
||||
test_e3_valid_R_and_O_records (__main__.S3a) ... ok
|
||||
test_envelope_duplicates_not_defect (__main__.S3a) ... ok
|
||||
test_event_count_defect_not_silently_accepted (__main__.S3a) ... ok
|
||||
test_exact_phase_keys (__main__.S3a) ... ok
|
||||
test_interval_gap_rejected (__main__.S3a) ... ok
|
||||
test_invalid_input_accepted_is_not_PASS (__main__.S3a) ... ok
|
||||
test_load_payload_and_pause_outcome (__main__.S3a) ... ok
|
||||
test_operation_moved_outside_scenario_rejected (__main__.S3a) ... ok
|
||||
test_package_fixed_mutations_and_hashes (__main__.S3a) ... ok
|
||||
test_probe_connection_required (__main__.S3a) ... ok
|
||||
test_rejection_mutation_retained_as_defect (__main__.S3a) ... ok
|
||||
test_save_refusal_makes_load_NA (__main__.S3a) ... ok
|
||||
test_scenario_mutation_static_boundary (__main__.S3a) ... ok
|
||||
test_signals_all_minutes_and_order (__main__.S3a) ... ok
|
||||
test_E5_cached_digest_defect_is_comparable (__main__.S3b) ... ok
|
||||
test_NA_not_PASS (__main__.S3b) ... ok
|
||||
test_aliasing_cannot_be_PASS (__main__.S3b) ... ok
|
||||
test_aliasing_missing_record (__main__.S3b) ... ok
|
||||
test_all_paths_and_ownership_R_O (__main__.S3b) ... ok
|
||||
test_digest_defect_other_checkpoint_still_rejected (__main__.S3b) ... ok
|
||||
test_digest_materialization_required (__main__.S3b) ... ok
|
||||
test_empty_registry_not_NA (__main__.S3b) ... ok
|
||||
test_event_count_mismatch (__main__.S3b) ... ok
|
||||
test_facts_normalization_is_reversible (__main__.S3b) ... ok
|
||||
test_first_placeable_choice (__main__.S3b) ... ok
|
||||
test_interval_gap (__main__.S3b) ... ok
|
||||
test_joined_s3b_self_comparison (__main__.S3b) ... ok
|
||||
test_load_X_not_digest_only (__main__.S3b) ... ok
|
||||
test_load_extra_event (__main__.S3b) ... ok
|
||||
test_missing_path_and_combination (__main__.S3b) ... ok
|
||||
test_missing_preview_observation (__main__.S3b) ... ok
|
||||
test_missing_trial (__main__.S3b) ... ok
|
||||
test_nested_mutation_required (__main__.S3b) ... ok
|
||||
test_no_staleness_assertion_for_non_tick (__main__.S3b) ... ok
|
||||
test_ownership_fact_dictionary_order_fallback (__main__.S3b) ... ok
|
||||
test_path_order (__main__.S3b) ... ok
|
||||
test_restore_extra_event (__main__.S3b) ... ok
|
||||
test_signal_facts_cannot_be_dropped (__main__.S3b) ... ok
|
||||
test_sort_rule_rejected (__main__.S3b) ... ok
|
||||
test_static_handler_and_outside_mutations (__main__.S3b) ... ok
|
||||
test_unpreviewed_choice (__main__.S3b) ... ok
|
||||
test_wrong_registry_in_either_role (__main__.S3b) ... ok
|
||||
test_checkout_temp_destination_rejected (__main__.S4Bundle) ... ok
|
||||
test_existing_output_never_overwritten (__main__.S4Bundle) ... ok
|
||||
test_import_closure_rejections (__main__.S4Bundle) ... ok
|
||||
test_missing_bundle_manifest_seal_and_changed_bytes (__main__.S4Bundle) ... ok
|
||||
test_missing_private_evidence_and_extra_rejected (__main__.S4Bundle) ... ok
|
||||
test_missing_profile_not_export_success (__main__.S4Bundle) ... ok
|
||||
test_phase_role_pid_audio_and_guard_rejected (__main__.S4Bundle) ... ok
|
||||
test_seal_normal_and_changes_not_native_proof (__main__.S4Bundle) ... ok
|
||||
test_synthetic_phase_all_real_checkers_not_native_proof (__main__.S4Bundle) ... ok
|
||||
test_copied_manifest_root_and_destination_count_rejected (__main__.S4NativeBundleLogic) ... ok
|
||||
test_gate_none_success_not_boolean (__main__.S4NativeBundleLogic) ... ok
|
||||
test_receipt_and_source_rejection_matrix (__main__.S4NativeBundleLogic) ... ok
|
||||
test_synthetic_full_bundle_positive_not_native_evidence (__main__.S4NativeBundleLogic) ... ok
|
||||
test_fixed_scenario_paths (__main__.SourcesAndMetrics) ... ok
|
||||
test_metric_ranges (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_closure_synthetic_registered_map (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_pin_is_not_caller_controlled (__main__.SourcesAndMetrics) ... ok
|
||||
test_array_order_and_all_differences (__main__.TypedTrees) ... ok
|
||||
test_components_and_sha (__main__.TypedTrees) ... ok
|
||||
test_deep_state_not_truncated (__main__.TypedTrees) ... ok
|
||||
test_duplicate_textual_keys_rejected (__main__.TypedTrees) ... ok
|
||||
test_exact_and_types (__main__.TypedTrees) ... ok
|
||||
test_nested_order_all_paths (__main__.TypedTrees) ... ok
|
||||
test_nonstring_keys_keep_types_and_values (__main__.TypedTrees) ... ok
|
||||
test_unsupported_and_malformed (__main__.TypedTrees) ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 132 tests in 194.460s
|
||||
|
||||
OK
|
||||
+1
@@ -0,0 +1 @@
|
||||
3c41e4442e2c21315e484fd2c8cdb9de70272af115a618083fca2d2e6428d187 UNIT_OUTPUT_S4_ATTEMPT_06.txt
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
test_all_operations (__main__.Diffs) ... ok
|
||||
test_invalid_operations (__main__.Diffs) ... ok
|
||||
test_reconstruction_and_proofs (__main__.Diffs) ... ok
|
||||
test_attempt_to_normalize_violation_rejected (__main__.Normalization) ... ok
|
||||
test_environment_values_differ_but_normal_form_equal (__main__.Normalization) ... ok
|
||||
test_every_save_event_reversible (__main__.Normalization) ... ok
|
||||
test_f3_keeps_relative_paths_and_words (__main__.Normalization) ... ok
|
||||
test_guard_mismatch (__main__.Normalization) ... ok
|
||||
test_nested_lookalike_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_original_transport_sha_detects_forged_timing (__main__.Normalization) ... ok
|
||||
test_partial_timing_payload_rejected (__main__.Normalization) ... ok
|
||||
test_prefix_boundary_and_reserved_token (__main__.Normalization) ... ok
|
||||
test_sidecar_missing_duplicate_and_forged_paths (__main__.Normalization) ... ok
|
||||
test_snapshot_and_latest_reversible (__main__.Normalization) ... ok
|
||||
test_snapshot_event_outside_recent_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_wrong_event_and_source_are_preserved (__main__.Normalization) ... ok
|
||||
test_wrong_timing_type_and_negative (__main__.Normalization) ... ok
|
||||
test_all_events_beyond_recent_window (__main__.Reports) ... ok
|
||||
test_all_semantic_layers_compared (__main__.Reports) ... ok
|
||||
test_digest_alone_is_not_enough (__main__.Reports) ... ok
|
||||
test_event_original_types_and_order (__main__.Reports) ... ok
|
||||
test_event_start_and_ids (__main__.Reports) ... ok
|
||||
test_exclusions_keep_actual_values (__main__.Reports) ... ok
|
||||
test_handler_sets_and_counts (__main__.Reports) ... ok
|
||||
test_observation_full_layers (__main__.Reports) ... ok
|
||||
test_product_digest_self_consistency (__main__.Reports) ... ok
|
||||
test_same_report (__main__.Reports) ... ok
|
||||
test_scenario_existing_failures_preserved (__main__.Reports) ... ok
|
||||
test_timing_digest_rule (__main__.Reports) ... ok
|
||||
test_unknown_or_missing_fields_rejected (__main__.Reports) ... ok
|
||||
test_violation_presence_and_difference (__main__.Reports) ... ok
|
||||
test_O_cadence (__main__.S2Format) ... ok
|
||||
test_counter_and_published_ids_binding (__main__.S2Format) ... ok
|
||||
test_diff_and_same_as_S_transport (__main__.S2Format) ... ok
|
||||
test_digest_and_scenario_contradiction (__main__.S2Format) ... ok
|
||||
test_event_no_drop_duplicate_remap (__main__.S2Format) ... ok
|
||||
test_event_original_field_types_mandatory (__main__.S2Format) ... ok
|
||||
test_guard_actual_not_assumed (__main__.S2Format) ... ok
|
||||
test_harness_digest_allows_only_dictionary_order (__main__.S2Format) ... ok
|
||||
test_join_is_copy_and_retains_normalization_proof (__main__.S2Format) ... ok
|
||||
test_kernel_cache_contradictions (__main__.S2Format) ... ok
|
||||
test_lifecycle_guard_errors_and_boundaries (__main__.S2Format) ... ok
|
||||
test_missing_full_state_not_digest_only (__main__.S2Format) ... ok
|
||||
test_normalized_digest_and_raw_tree_are_both_bound (__main__.S2Format) ... ok
|
||||
test_product_event_shape_and_typed_array (__main__.S2Format) ... ok
|
||||
test_raw_observation_binding (__main__.S2Format) ... ok
|
||||
test_roundtrip_tree_sha_and_raw_sha (__main__.S2Format) ... ok
|
||||
test_s2_valid_and_not_formal_acceptance (__main__.S2Format) ... ok
|
||||
test_state_witness_and_observation_mutation (__main__.S2Format) ... ok
|
||||
test_stdout_exactly_one_line (__main__.S2Format) ... ok
|
||||
test_autoload_class_and_script_import (__main__.S2Static) ... ok
|
||||
test_comment_does_not_supply_proof (__main__.S2Static) ... ok
|
||||
test_current_probe (__main__.S2Static) ... ok
|
||||
test_full_state_and_godot_roundtrip_required (__main__.S2Static) ... ok
|
||||
test_no_changes_outside_preparation_or_step (__main__.S2Static) ... ok
|
||||
test_no_event_cap_or_duplicate_report (__main__.S2Static) ... ok
|
||||
test_pause_and_step_arguments (__main__.S2Static) ... ok
|
||||
test_textual_stringname_ordering (__main__.S2Static) ... ok
|
||||
test_unlisted_live_method_and_late_preparation (__main__.S2Static) ... ok
|
||||
test_variant_inference (__main__.S2Static) ... ok
|
||||
test_X_recent_limit_and_counter (__main__.S3a) ... ok
|
||||
test_duplicate_JSON_key_rejected (__main__.S3a) ... ok
|
||||
test_e3_NA_cannot_be_PASS_or_applied (__main__.S3a) ... ok
|
||||
test_e3_coverage_input_and_event_count_binding (__main__.S3a) ... ok
|
||||
test_e3_invented_codes_and_missing_load_code (__main__.S3a) ... ok
|
||||
test_e3_valid_R_and_O_records (__main__.S3a) ... ok
|
||||
test_envelope_duplicates_not_defect (__main__.S3a) ... ok
|
||||
test_event_count_defect_not_silently_accepted (__main__.S3a) ... ok
|
||||
test_exact_phase_keys (__main__.S3a) ... ok
|
||||
test_interval_gap_rejected (__main__.S3a) ... ok
|
||||
test_invalid_input_accepted_is_not_PASS (__main__.S3a) ... ok
|
||||
test_load_payload_and_pause_outcome (__main__.S3a) ... ok
|
||||
test_operation_moved_outside_scenario_rejected (__main__.S3a) ... ok
|
||||
test_package_fixed_mutations_and_hashes (__main__.S3a) ... ok
|
||||
test_probe_connection_required (__main__.S3a) ... ok
|
||||
test_rejection_mutation_retained_as_defect (__main__.S3a) ... ok
|
||||
test_save_refusal_makes_load_NA (__main__.S3a) ... ok
|
||||
test_scenario_mutation_static_boundary (__main__.S3a) ... ok
|
||||
test_signals_all_minutes_and_order (__main__.S3a) ... ok
|
||||
test_E5_cached_digest_defect_is_comparable (__main__.S3b) ... ok
|
||||
test_NA_not_PASS (__main__.S3b) ... ok
|
||||
test_aliasing_cannot_be_PASS (__main__.S3b) ... ok
|
||||
test_aliasing_missing_record (__main__.S3b) ... ok
|
||||
test_all_paths_and_ownership_R_O (__main__.S3b) ... ok
|
||||
test_digest_defect_other_checkpoint_still_rejected (__main__.S3b) ... ok
|
||||
test_digest_materialization_required (__main__.S3b) ... ok
|
||||
test_empty_registry_not_NA (__main__.S3b) ... ok
|
||||
test_event_count_mismatch (__main__.S3b) ... ok
|
||||
test_facts_normalization_is_reversible (__main__.S3b) ... ok
|
||||
test_first_placeable_choice (__main__.S3b) ... ok
|
||||
test_interval_gap (__main__.S3b) ... ok
|
||||
test_joined_s3b_self_comparison (__main__.S3b) ... ok
|
||||
test_load_X_not_digest_only (__main__.S3b) ... ok
|
||||
test_load_extra_event (__main__.S3b) ... ok
|
||||
test_missing_path_and_combination (__main__.S3b) ... ok
|
||||
test_missing_preview_observation (__main__.S3b) ... ok
|
||||
test_missing_trial (__main__.S3b) ... ok
|
||||
test_nested_mutation_required (__main__.S3b) ... ok
|
||||
test_no_staleness_assertion_for_non_tick (__main__.S3b) ... ok
|
||||
test_ownership_fact_dictionary_order_fallback (__main__.S3b) ... ok
|
||||
test_path_order (__main__.S3b) ... ok
|
||||
test_restore_extra_event (__main__.S3b) ... ok
|
||||
test_signal_facts_cannot_be_dropped (__main__.S3b) ... ok
|
||||
test_sort_rule_rejected (__main__.S3b) ... ok
|
||||
test_static_handler_and_outside_mutations (__main__.S3b) ... ok
|
||||
test_unpreviewed_choice (__main__.S3b) ... ok
|
||||
test_wrong_registry_in_either_role (__main__.S3b) ... ok
|
||||
test_checkout_temp_destination_rejected (__main__.S4Bundle) ... ok
|
||||
test_existing_output_never_overwritten (__main__.S4Bundle) ... ok
|
||||
test_import_closure_rejections (__main__.S4Bundle) ... ok
|
||||
test_missing_bundle_manifest_seal_and_changed_bytes (__main__.S4Bundle) ... ok
|
||||
test_missing_private_evidence_and_extra_rejected (__main__.S4Bundle) ... ok
|
||||
test_missing_profile_not_export_success (__main__.S4Bundle) ... ok
|
||||
test_phase_role_pid_audio_and_guard_rejected (__main__.S4Bundle) ... ok
|
||||
test_rebound_lifecycle_and_scenario_contradictions (__main__.S4Bundle) ... ok
|
||||
test_seal_normal_and_changes_not_native_proof (__main__.S4Bundle) ... ok
|
||||
test_synthetic_phase_all_real_checkers_not_native_proof (__main__.S4Bundle) ... ok
|
||||
test_copied_manifest_root_and_destination_count_rejected (__main__.S4NativeBundleLogic) ... ok
|
||||
test_failure_keeps_raw_and_no_bundle_without_starting_engine (__main__.S4NativeBundleLogic) ... ok
|
||||
test_gate_none_success_not_boolean (__main__.S4NativeBundleLogic) ... ok
|
||||
test_receipt_and_source_rejection_matrix (__main__.S4NativeBundleLogic) ... ok
|
||||
test_synthetic_full_bundle_positive_not_native_evidence (__main__.S4NativeBundleLogic) ... ok
|
||||
test_fixed_scenario_paths (__main__.SourcesAndMetrics) ... ok
|
||||
test_metric_ranges (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_closure_synthetic_registered_map (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_pin_is_not_caller_controlled (__main__.SourcesAndMetrics) ... ok
|
||||
test_array_order_and_all_differences (__main__.TypedTrees) ... ok
|
||||
test_components_and_sha (__main__.TypedTrees) ... ok
|
||||
test_deep_state_not_truncated (__main__.TypedTrees) ... ok
|
||||
test_duplicate_textual_keys_rejected (__main__.TypedTrees) ... ok
|
||||
test_exact_and_types (__main__.TypedTrees) ... ok
|
||||
test_nested_order_all_paths (__main__.TypedTrees) ... ok
|
||||
test_nonstring_keys_keep_types_and_values (__main__.TypedTrees) ... ok
|
||||
test_unsupported_and_malformed (__main__.TypedTrees) ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 134 tests in 206.531s
|
||||
|
||||
OK
|
||||
+1
@@ -0,0 +1 @@
|
||||
29d1a5dec792ae865725220ec4d11c11bb62d08cba9a614ad7bf2d120948ab97 UNIT_OUTPUT_S4_ATTEMPT_07.txt
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
test_check_accepts_true (__main__.S4ProbeAdmission) ... ok
|
||||
test_check_rejects_false_all_errors (__main__.S4ProbeAdmission) ... ok
|
||||
test_run_admission_accepts_true_mock_launch_only (__main__.S4ProbeAdmission) ... ok
|
||||
test_run_admission_rejects_false_without_engine (__main__.S4ProbeAdmission) ... ok
|
||||
test_nonzero_determinism_rejected_after_real_join (__main__.S4RemainingBindings) ... FAIL
|
||||
test_owned_lifecycle_exit_diagnostic_and_profile_rejections (__main__.S4RemainingBindings) ... ok
|
||||
test_verifier_accepts_true_recomputes_raw (__main__.S4RemainingBindings) ... ok
|
||||
test_verifier_rejects_false_with_every_error (__main__.S4RemainingBindings) ... ok
|
||||
|
||||
======================================================================
|
||||
FAIL: test_nonzero_determinism_rejected_after_real_join (__main__.S4RemainingBindings)
|
||||
----------------------------------------------------------------------
|
||||
compare_versions.EvidenceError: report checker: ['report self-check: []']
|
||||
|
||||
During handling of the above exception, another exception occurred:
|
||||
|
||||
Traceback (most recent call last):
|
||||
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p28-02-eq/P28-02-EQ-implement/docs/plans/original-completion-2026-10-02/execution/p28-02/eq/test_eq.py", line 1647, in test_nonzero_determinism_rejected_after_real_join
|
||||
self.recompute(self.execution)
|
||||
AssertionError: "same-role determinism failed" does not match "report checker: ['report self-check: []']"
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 8 tests in 54.265s
|
||||
|
||||
FAILED (failures=1)
|
||||
|
||||
exit_code=1
|
||||
wall_seconds=54.554559917
|
||||
+1
@@ -0,0 +1 @@
|
||||
d470e6ee7a07a3b6d4ad2182b545e8708ae735b0d106c0800a813eb73f7353ce UNIT_OUTPUT_S4_ATTEMPT_08.txt
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
test_check_accepts_true (__main__.S4ProbeAdmission) ... ok
|
||||
test_check_rejects_false_all_errors (__main__.S4ProbeAdmission) ... ok
|
||||
test_run_admission_accepts_true_mock_launch_only (__main__.S4ProbeAdmission) ... ok
|
||||
test_run_admission_rejects_false_without_engine (__main__.S4ProbeAdmission) ... ok
|
||||
test_nine_original_destinations_required (__main__.S4RemainingBindings) ... ok
|
||||
test_nonzero_determinism_rejected_after_real_join (__main__.S4RemainingBindings) ... ok
|
||||
test_owned_lifecycle_exit_diagnostic_and_profile_rejections (__main__.S4RemainingBindings) ... ok
|
||||
test_verifier_accepts_true_recomputes_raw (__main__.S4RemainingBindings) ... ok
|
||||
test_verifier_rejects_false_with_every_error (__main__.S4RemainingBindings) ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 9 tests in 86.276s
|
||||
|
||||
OK
|
||||
|
||||
exit_code=0
|
||||
wall_seconds=86.551909958
|
||||
+1
@@ -0,0 +1 @@
|
||||
3f33b134a48cfabd8794329bec69ed0678ad71f06052f4e34a78c5955475c450 UNIT_OUTPUT_S4_ATTEMPT_09.txt
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
test_cached_verdict_not_trusted (__main__.S4StoredResultBindings) ... ok
|
||||
test_missing_sidecar_rejected_after_seal (__main__.S4StoredResultBindings) ... ok
|
||||
test_raw_joined_substitution_rejected_after_seal (__main__.S4StoredResultBindings) ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 3 tests in 0.025s
|
||||
|
||||
OK
|
||||
|
||||
exit_code=0
|
||||
wall_seconds=0.2951165
|
||||
+1
@@ -0,0 +1 @@
|
||||
ff6fc0065772434f9ca35a1267e24d199057e339869a868942a41829327503bb UNIT_OUTPUT_S4_ATTEMPT_10.txt
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
test_all_operations (__main__.Diffs) ... ok
|
||||
test_invalid_operations (__main__.Diffs) ... ok
|
||||
test_reconstruction_and_proofs (__main__.Diffs) ... ok
|
||||
test_attempt_to_normalize_violation_rejected (__main__.Normalization) ... ok
|
||||
test_environment_values_differ_but_normal_form_equal (__main__.Normalization) ... ok
|
||||
test_every_save_event_reversible (__main__.Normalization) ... ok
|
||||
test_f3_keeps_relative_paths_and_words (__main__.Normalization) ... ok
|
||||
test_guard_mismatch (__main__.Normalization) ... ok
|
||||
test_nested_lookalike_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_original_transport_sha_detects_forged_timing (__main__.Normalization) ... ok
|
||||
test_partial_timing_payload_rejected (__main__.Normalization) ... ok
|
||||
test_prefix_boundary_and_reserved_token (__main__.Normalization) ... ok
|
||||
test_sidecar_missing_duplicate_and_forged_paths (__main__.Normalization) ... ok
|
||||
test_snapshot_and_latest_reversible (__main__.Normalization) ... ok
|
||||
test_snapshot_event_outside_recent_is_not_eligible (__main__.Normalization) ... ok
|
||||
test_wrong_event_and_source_are_preserved (__main__.Normalization) ... ok
|
||||
test_wrong_timing_type_and_negative (__main__.Normalization) ... ok
|
||||
test_all_events_beyond_recent_window (__main__.Reports) ... ok
|
||||
test_all_semantic_layers_compared (__main__.Reports) ... ok
|
||||
test_digest_alone_is_not_enough (__main__.Reports) ... ok
|
||||
test_event_original_types_and_order (__main__.Reports) ... ok
|
||||
test_event_start_and_ids (__main__.Reports) ... ok
|
||||
test_exclusions_keep_actual_values (__main__.Reports) ... ok
|
||||
test_handler_sets_and_counts (__main__.Reports) ... ok
|
||||
test_observation_full_layers (__main__.Reports) ... ok
|
||||
test_product_digest_self_consistency (__main__.Reports) ... ok
|
||||
test_same_report (__main__.Reports) ... ok
|
||||
test_scenario_existing_failures_preserved (__main__.Reports) ... ok
|
||||
test_timing_digest_rule (__main__.Reports) ... ok
|
||||
test_unknown_or_missing_fields_rejected (__main__.Reports) ... ok
|
||||
test_violation_presence_and_difference (__main__.Reports) ... ok
|
||||
test_O_cadence (__main__.S2Format) ... ok
|
||||
test_counter_and_published_ids_binding (__main__.S2Format) ... ok
|
||||
test_diff_and_same_as_S_transport (__main__.S2Format) ... ok
|
||||
test_digest_and_scenario_contradiction (__main__.S2Format) ... ok
|
||||
test_event_no_drop_duplicate_remap (__main__.S2Format) ... ok
|
||||
test_event_original_field_types_mandatory (__main__.S2Format) ... ok
|
||||
test_guard_actual_not_assumed (__main__.S2Format) ... ok
|
||||
test_harness_digest_allows_only_dictionary_order (__main__.S2Format) ... ok
|
||||
test_join_is_copy_and_retains_normalization_proof (__main__.S2Format) ... ok
|
||||
test_kernel_cache_contradictions (__main__.S2Format) ... ok
|
||||
test_lifecycle_guard_errors_and_boundaries (__main__.S2Format) ... ok
|
||||
test_missing_full_state_not_digest_only (__main__.S2Format) ... ok
|
||||
test_normalized_digest_and_raw_tree_are_both_bound (__main__.S2Format) ... ok
|
||||
test_product_event_shape_and_typed_array (__main__.S2Format) ... ok
|
||||
test_raw_observation_binding (__main__.S2Format) ... ok
|
||||
test_roundtrip_tree_sha_and_raw_sha (__main__.S2Format) ... ok
|
||||
test_s2_valid_and_not_formal_acceptance (__main__.S2Format) ... ok
|
||||
test_state_witness_and_observation_mutation (__main__.S2Format) ... ok
|
||||
test_stdout_exactly_one_line (__main__.S2Format) ... ok
|
||||
test_autoload_class_and_script_import (__main__.S2Static) ... ok
|
||||
test_comment_does_not_supply_proof (__main__.S2Static) ... ok
|
||||
test_current_probe (__main__.S2Static) ... ok
|
||||
test_full_state_and_godot_roundtrip_required (__main__.S2Static) ... ok
|
||||
test_no_changes_outside_preparation_or_step (__main__.S2Static) ... ok
|
||||
test_no_event_cap_or_duplicate_report (__main__.S2Static) ... ok
|
||||
test_pause_and_step_arguments (__main__.S2Static) ... ok
|
||||
test_textual_stringname_ordering (__main__.S2Static) ... ok
|
||||
test_unlisted_live_method_and_late_preparation (__main__.S2Static) ... ok
|
||||
test_variant_inference (__main__.S2Static) ... ok
|
||||
test_X_recent_limit_and_counter (__main__.S3a) ... ok
|
||||
test_duplicate_JSON_key_rejected (__main__.S3a) ... ok
|
||||
test_e3_NA_cannot_be_PASS_or_applied (__main__.S3a) ... ok
|
||||
test_e3_coverage_input_and_event_count_binding (__main__.S3a) ... ok
|
||||
test_e3_invented_codes_and_missing_load_code (__main__.S3a) ... ok
|
||||
test_e3_valid_R_and_O_records (__main__.S3a) ... ok
|
||||
test_envelope_duplicates_not_defect (__main__.S3a) ... ok
|
||||
test_event_count_defect_not_silently_accepted (__main__.S3a) ... ok
|
||||
test_exact_phase_keys (__main__.S3a) ... ok
|
||||
test_interval_gap_rejected (__main__.S3a) ... ok
|
||||
test_invalid_input_accepted_is_not_PASS (__main__.S3a) ... ok
|
||||
test_load_payload_and_pause_outcome (__main__.S3a) ... ok
|
||||
test_operation_moved_outside_scenario_rejected (__main__.S3a) ... ok
|
||||
test_package_fixed_mutations_and_hashes (__main__.S3a) ... ok
|
||||
test_probe_connection_required (__main__.S3a) ... ok
|
||||
test_rejection_mutation_retained_as_defect (__main__.S3a) ... ok
|
||||
test_save_refusal_makes_load_NA (__main__.S3a) ... ok
|
||||
test_scenario_mutation_static_boundary (__main__.S3a) ... ok
|
||||
test_signals_all_minutes_and_order (__main__.S3a) ... ok
|
||||
test_E5_cached_digest_defect_is_comparable (__main__.S3b) ... ok
|
||||
test_NA_not_PASS (__main__.S3b) ... ok
|
||||
test_aliasing_cannot_be_PASS (__main__.S3b) ... ok
|
||||
test_aliasing_missing_record (__main__.S3b) ... ok
|
||||
test_all_paths_and_ownership_R_O (__main__.S3b) ... ok
|
||||
test_digest_defect_other_checkpoint_still_rejected (__main__.S3b) ... ok
|
||||
test_digest_materialization_required (__main__.S3b) ... ok
|
||||
test_empty_registry_not_NA (__main__.S3b) ... ok
|
||||
test_event_count_mismatch (__main__.S3b) ... ok
|
||||
test_facts_normalization_is_reversible (__main__.S3b) ... ok
|
||||
test_first_placeable_choice (__main__.S3b) ... ok
|
||||
test_interval_gap (__main__.S3b) ... ok
|
||||
test_joined_s3b_self_comparison (__main__.S3b) ... ok
|
||||
test_load_X_not_digest_only (__main__.S3b) ... ok
|
||||
test_load_extra_event (__main__.S3b) ... ok
|
||||
test_missing_path_and_combination (__main__.S3b) ... ok
|
||||
test_missing_preview_observation (__main__.S3b) ... ok
|
||||
test_missing_trial (__main__.S3b) ... ok
|
||||
test_nested_mutation_required (__main__.S3b) ... ok
|
||||
test_no_staleness_assertion_for_non_tick (__main__.S3b) ... ok
|
||||
test_ownership_fact_dictionary_order_fallback (__main__.S3b) ... ok
|
||||
test_path_order (__main__.S3b) ... ok
|
||||
test_restore_extra_event (__main__.S3b) ... ok
|
||||
test_signal_facts_cannot_be_dropped (__main__.S3b) ... ok
|
||||
test_sort_rule_rejected (__main__.S3b) ... ok
|
||||
test_static_handler_and_outside_mutations (__main__.S3b) ... ok
|
||||
test_unpreviewed_choice (__main__.S3b) ... ok
|
||||
test_wrong_registry_in_either_role (__main__.S3b) ... ok
|
||||
test_checkout_temp_destination_rejected (__main__.S4Bundle) ... ok
|
||||
test_existing_output_never_overwritten (__main__.S4Bundle) ... ok
|
||||
test_import_closure_rejections (__main__.S4Bundle) ... ok
|
||||
test_missing_bundle_manifest_seal_and_changed_bytes (__main__.S4Bundle) ... ok
|
||||
test_missing_private_evidence_and_extra_rejected (__main__.S4Bundle) ... ok
|
||||
test_missing_profile_not_export_success (__main__.S4Bundle) ... ok
|
||||
test_phase_role_pid_audio_and_guard_rejected (__main__.S4Bundle) ... ok
|
||||
test_rebound_lifecycle_and_scenario_contradictions (__main__.S4Bundle) ... ok
|
||||
test_seal_normal_and_changes_not_native_proof (__main__.S4Bundle) ... ok
|
||||
test_synthetic_phase_all_real_checkers_not_native_proof (__main__.S4Bundle) ... ok
|
||||
test_copied_manifest_root_and_destination_count_rejected (__main__.S4NativeBundleLogic) ... ok
|
||||
test_failure_keeps_raw_and_no_bundle_without_starting_engine (__main__.S4NativeBundleLogic) ... ok
|
||||
test_gate_none_success_not_boolean (__main__.S4NativeBundleLogic) ... ok
|
||||
test_receipt_and_source_rejection_matrix (__main__.S4NativeBundleLogic) ... ok
|
||||
test_synthetic_full_bundle_positive_not_native_evidence (__main__.S4NativeBundleLogic) ... ok
|
||||
test_check_accepts_true (__main__.S4ProbeAdmission) ... ok
|
||||
test_check_rejects_false_all_errors (__main__.S4ProbeAdmission) ... ok
|
||||
test_run_admission_accepts_true_mock_launch_only (__main__.S4ProbeAdmission) ... ok
|
||||
test_run_admission_rejects_false_without_engine (__main__.S4ProbeAdmission) ... ok
|
||||
test_nine_original_destinations_required (__main__.S4RemainingBindings) ... ok
|
||||
test_nonzero_determinism_rejected_after_real_join (__main__.S4RemainingBindings) ... ok
|
||||
test_owned_lifecycle_exit_diagnostic_and_profile_rejections (__main__.S4RemainingBindings) ... ok
|
||||
test_verifier_accepts_true_recomputes_raw (__main__.S4RemainingBindings) ... ok
|
||||
test_verifier_rejects_false_with_every_error (__main__.S4RemainingBindings) ... ok
|
||||
test_cached_verdict_not_trusted (__main__.S4StoredResultBindings) ... ok
|
||||
test_missing_sidecar_rejected_after_seal (__main__.S4StoredResultBindings) ... ok
|
||||
test_raw_joined_substitution_rejected_after_seal (__main__.S4StoredResultBindings) ... ok
|
||||
test_fixed_scenario_paths (__main__.SourcesAndMetrics) ... ok
|
||||
test_metric_ranges (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_closure_synthetic_registered_map (__main__.SourcesAndMetrics) ... ok
|
||||
test_source_pin_is_not_caller_controlled (__main__.SourcesAndMetrics) ... ok
|
||||
test_array_order_and_all_differences (__main__.TypedTrees) ... ok
|
||||
test_components_and_sha (__main__.TypedTrees) ... ok
|
||||
test_deep_state_not_truncated (__main__.TypedTrees) ... ok
|
||||
test_duplicate_textual_keys_rejected (__main__.TypedTrees) ... ok
|
||||
test_exact_and_types (__main__.TypedTrees) ... ok
|
||||
test_nested_order_all_paths (__main__.TypedTrees) ... ok
|
||||
test_nonstring_keys_keep_types_and_values (__main__.TypedTrees) ... ok
|
||||
test_unsupported_and_malformed (__main__.TypedTrees) ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 146 tests in 293.277s
|
||||
|
||||
OK
|
||||
|
||||
exit_code=0
|
||||
wall_seconds=293.5742515
|
||||
@@ -0,0 +1,873 @@
|
||||
"""S3a format/static and E3 evidence checks. Not native admission or acceptance.
|
||||
|
||||
Raw records remain immutable. join_report derives normalized digests/sidecars on
|
||||
copies using S1's sole F1-F3 implementation; it does not manufacture Godot proof.
|
||||
"""
|
||||
import base64
|
||||
import ast
|
||||
import copy
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
import re
|
||||
import sys
|
||||
|
||||
sys.dont_write_bytecode = True
|
||||
import compare_versions as eq
|
||||
|
||||
|
||||
def check_python_imports(text):
|
||||
"""Closed EQ/stdlib import screen; dynamic file loading is separately pinned by run_eq."""
|
||||
allowed = {'argparse', 'ast', 'base64', 'copy', 'hashlib', 'importlib', 'json', 'math',
|
||||
'os', 'pathlib', 're', 'shutil', 'struct', 'subprocess', 'sys', 'tempfile',
|
||||
'unittest', 'uuid', 'check_eq', 'compare_versions', 'run_eq', 'verify_eq'}
|
||||
tree = ast.parse(text)
|
||||
for node in ast.walk(tree):
|
||||
if isinstance(node, (ast.Import, ast.ImportFrom)):
|
||||
names = [node.module] if isinstance(node, ast.ImportFrom) else [a.name for a in node.names]
|
||||
eq.require(all(n and n.split('.')[0] in allowed for n in names), 'import outside EQ closure')
|
||||
eq.require(not isinstance(node, ast.ImportFrom) or node.level == 0, 'relative import outside closure')
|
||||
if isinstance(node, ast.Call):
|
||||
name = getattr(node.func, 'id', getattr(node.func, 'attr', ''))
|
||||
eq.require(name not in ('eval', 'exec', '__import__', 'import_module'), 'unapproved dynamic import/code')
|
||||
if name == 'spec_from_file_location':
|
||||
expected = ast.parse('importlib.util.spec_from_file_location(module_name, root / relative)').body[0].value
|
||||
eq.require(ast.dump(node) == ast.dump(expected) and
|
||||
"require(relative in DEPENDENCIES and relative.endswith('.py'), 'import outside closure')" in text,
|
||||
'unapproved dynamic file loader')
|
||||
for value in ast.walk(node):
|
||||
if isinstance(value, ast.Constant) and isinstance(value.value, str):
|
||||
eq.require(not value.value.endswith('.py'), 'unapproved literal file loader')
|
||||
return True
|
||||
|
||||
|
||||
def sha(value):
|
||||
return hashlib.sha256(value).hexdigest()
|
||||
|
||||
|
||||
def hex_sha(value):
|
||||
return type(value) is str and re.fullmatch('[0-9a-f]{64}', value) is not None
|
||||
|
||||
|
||||
def integer(value):
|
||||
return type(value) is int and value >= 0
|
||||
|
||||
|
||||
def fields(tree):
|
||||
eq.require(tree[0] == 27, 'dictionary required')
|
||||
result = {}
|
||||
for key, value in tree[1]:
|
||||
eq.require(key[0] in (4, 21) and key[1] not in result, 'text key collision/type')
|
||||
result[key[1]] = value
|
||||
return result
|
||||
|
||||
|
||||
def counts(tree):
|
||||
runtime = fields(fields(fields(tree)['systems'])['runtime'])
|
||||
counters = fields(fields(runtime['id_generator'])['counters'])
|
||||
# Product get_counter has an explicit zero default for an absent prefix.
|
||||
# At B1 the prefix must exist, so absent evidence is never defaulted here.
|
||||
counter = counters['domain_event']
|
||||
ids = fields(runtime['domain_events'])['published_ids']
|
||||
eq.require(counter[0] == 2 and integer(counter[1]), 'domain counter type')
|
||||
eq.require(ids[0] == 28, 'published IDs array')
|
||||
eq.require(all(n[0] == 4 for n in ids[1]), 'published ID types')
|
||||
names = [n[1] for n in ids[1]]
|
||||
eq.require(names == sorted(set(names)), 'published ID order/duplicates')
|
||||
return {'counter': counter[1], 'published_ids_count': len(names)}, names
|
||||
|
||||
|
||||
def normalized_digest(tree):
|
||||
"""Harness-only typed canonical digest; never claim this is a product digest.
|
||||
|
||||
Key nodes remain exact. Only Dictionary enumeration order is canonicalized,
|
||||
matching S1 fallback; floats, metadata and Array order remain untouched.
|
||||
"""
|
||||
def canonical(node):
|
||||
result = copy.deepcopy(node)
|
||||
if node[0] == 27:
|
||||
names = [eq._key_text(k) for k, _ in node[1]]
|
||||
eq.require(len(set(names)) == len(names), 'digest textual key collision')
|
||||
result[1] = [[copy.deepcopy(k), canonical(v)] for k, v in sorted(node[1], key=lambda p: eq._key_text(p[0]))]
|
||||
elif node[0] == 28 or 5 <= node[0] <= 20 or 30 <= node[0] <= 38:
|
||||
result[1] = [canonical(v) for v in node[1]]
|
||||
return result
|
||||
eq.validate_tree(tree)
|
||||
return eq.tree_sha(canonical(tree))
|
||||
|
||||
|
||||
def join_report(raw):
|
||||
"""Return (joined report, reversible normalization evidence), never edit raw."""
|
||||
joined = copy.deepcopy(raw)
|
||||
proofs = []
|
||||
trees = eq.reconstruct_checkpoints(raw['checkpoints'])
|
||||
for cp, (s, latest) in zip(joined['checkpoints'], trees):
|
||||
row = {}
|
||||
for name, tree in (('S', s), ('latest', latest)):
|
||||
normalized, side = eq.normalize_tree(tree, raw['profile_root'])
|
||||
restored = eq.restore_tree(normalized, side, raw['profile_root'])
|
||||
eq.require(eq.tree_sha(restored) == eq.tree_sha(tree), 'normalization restore SHA')
|
||||
row[name] = {'normalized_tree_sha': eq.tree_sha(normalized), 'normalized_digest': normalized_digest(normalized), 'sidecar': side,
|
||||
'restored_tree_sha': eq.tree_sha(restored)}
|
||||
expected = row['latest']['normalized_digest']
|
||||
eq.require(cp['harness_normalized_digest'] in (None, expected), 'forged normalized digest')
|
||||
cp['harness_normalized_digest'] = expected
|
||||
proofs.append(row)
|
||||
for i, scenario in enumerate(raw.get('scenarios', [])):
|
||||
derived, scenario_proofs = join_report({'profile_root': raw['profile_root'], 'checkpoints': scenario['checkpoints']})
|
||||
joined['scenarios'][i]['checkpoints'] = derived['checkpoints']
|
||||
proofs.append({'scenario': scenario['id'], 'checkpoints': scenario_proofs})
|
||||
if scenario['id'].startswith(('E4/', 'E5/')):
|
||||
joined['scenarios'][i]['result']['facts'], fact_proofs = join_facts(scenario['result']['facts'], raw['profile_root'])
|
||||
proofs.append({'scenario': scenario['id'], 'facts': fact_proofs})
|
||||
return joined, proofs
|
||||
|
||||
|
||||
def check_measurement(raw, measurement):
|
||||
eq.require(type(measurement) is dict, 'measurement connection inventory missing')
|
||||
eq.require(set(measurement) == {'probe_object', 'connections', 'start_minute'}, 'measurement inventory fields')
|
||||
eq.require(measurement['start_minute'] == raw['checkpoints'][0]['minute'], 'inventory B1 minute')
|
||||
probe = measurement['probe_object']
|
||||
eq.require(type(probe) is str and re.fullmatch('[1-9][0-9]*', probe), 'probe object identity')
|
||||
for signal, method in (('snapshot_published', 'observe_snapshot'), ('state_updated', 'observe_state')):
|
||||
rows = measurement['connections'][signal]
|
||||
eq.require(type(rows) is list, 'connection list')
|
||||
for row in rows:
|
||||
eq.require(set(row) == {'object', 'method', 'flags'}, 'connection fields')
|
||||
eq.require(sum(r['object'] == probe and r['method'] == method for r in rows) == 1,
|
||||
'missing/duplicate probe connection: ' + signal)
|
||||
expected = [{'signal': signal, 'minute': cp['minute']} for cp in raw['checkpoints'][1:]
|
||||
for signal in ('snapshot_published', 'state_updated')]
|
||||
eq.require(eq.exact(raw['signal_order'], expected), 'exact measured signal pairs/checkpoint minutes required')
|
||||
|
||||
|
||||
def check_report(raw, measurement=None, e3_evidence=None, b1_record=None, e45_evidence=None):
|
||||
out = {'ok': False, 'stage': 'S2', 'formal_acceptance': False, 'errors': []}
|
||||
try:
|
||||
report, proofs = join_report(raw)
|
||||
compared = eq.compare_reports(report, report)
|
||||
eq.require(compared['ok'], 'report self-check: ' + repr(compared['errors']))
|
||||
if raw['scenarios'] or e3_evidence is not None:
|
||||
eq.require(e3_evidence is not None and b1_record is not None, 'E3 raw evidence missing')
|
||||
e3_raw = dict(raw, scenarios=raw['scenarios'][:18]) if e45_evidence is not None else raw
|
||||
out['e3'] = check_e3(e3_raw, e3_evidence, b1_record)
|
||||
out['stage'] = 'S3a'
|
||||
if e45_evidence is not None:
|
||||
out['e45'] = check_e45(raw, e45_evidence, e3_evidence[-1]['end'])
|
||||
out['stage'] = 'S3b'
|
||||
cps = raw['checkpoints']
|
||||
start_minute = 632 if raw['role'] == 'R' else 390
|
||||
eq.require(cps[0]['minute'] == start_minute, 'B1 minute')
|
||||
for cp in cps:
|
||||
eq.require(type(cp['minute']) is int, 'minute type')
|
||||
k, c = cp['K'], cp['C']
|
||||
for key in ('absolute_minute', 'speed', 'snapshot_version', '_pause_request_serial'):
|
||||
eq.require(integer(k[key]), 'K integer: ' + key)
|
||||
for key in ('paused', '_skip_next_process', '_abort_current_tick_requested', '_last_tick_advanced'):
|
||||
eq.require(type(k[key]) is bool, 'K boolean: ' + key)
|
||||
eq.require(k['paused'] and k['absolute_minute'] == cp['minute'], 'clock contradiction')
|
||||
eq.require(type(k['_phase_handlers']) is dict and set(k['_phase_handlers']) == {str(i) for i in range(11)}, 'exact phase key set 0..10')
|
||||
for key in ('latest_digest', 'computed_latest_digest'):
|
||||
eq.require(hex_sha(cp[key]), 'digest format')
|
||||
eq.require(cp['observation']['before']['S'] == cp['S']['raw_bytes_sha'], 'S witness/transport contradiction')
|
||||
eq.require(type(c['_mvp_manifest_cache_generation']) is int, 'cache generation')
|
||||
eq.require(c['catalog_is_current'] is True, 'unfilled checkpoint cache')
|
||||
ids = [c['catalog_instance_id'], c['current_catalog_instance_id']]
|
||||
eq.require(all(type(v) is str and re.fullmatch('[1-9][0-9]*', v) for v in ids), 'cache instance IDs')
|
||||
eq.require(ids[0] == ids[1], 'cache identity contradiction')
|
||||
eq.validate_tree([29, c['_mvp_manifest_cache_bytes']])
|
||||
trees = eq.reconstruct_checkpoints(cps)
|
||||
begin, begin_ids = counts(trees[0][0])
|
||||
end, end_ids = counts(trees[-1][0])
|
||||
eq.require(eq.exact(raw['event_start'], begin) and eq.exact(raw['event_end'], end), 'event counter/state contradiction')
|
||||
event_ids = []
|
||||
for row in raw['events']:
|
||||
tree = eq._transport(row['transport'], None)
|
||||
data = fields(tree)
|
||||
expected_keys = {'event_id', 'event_type', 'absolute_minute', 'source_service', 'entity_ids', 'payload', 'causation_command_id'}
|
||||
eq.require(set(data) == expected_keys and tree[2] is None, 'event to_dictionary shape')
|
||||
for name in ('event_id', 'event_type', 'source_service'):
|
||||
eq.require(data[name][0] == 4 and bool(data[name][1]), 'serialized event String: ' + name)
|
||||
for name in ('absolute_minute', 'causation_command_id'):
|
||||
eq.require(data[name][0] == 2 and integer(data[name][1]), 'serialized event int: ' + name)
|
||||
eq.require(start_minute <= data['absolute_minute'][1] <= start_minute + 30, 'event outside measurement')
|
||||
ids = data['entity_ids']
|
||||
eq.require(ids[0] == 28 and ids[2] == [[2, 4], [21, ''], [0]] and all(v[0] == 4 for v in ids[1]), 'serialized entity_ids Array[String]')
|
||||
eq.require(data['payload'][0] == 27, 'event payload Dictionary')
|
||||
original = {'event_id': 21, 'event_type': 21, 'absolute_minute': 2, 'source_service': 21,
|
||||
'entity_ids': {'type': 28, 'typed_info': [[2, 21], [21, ''], [0]]},
|
||||
'payload': {'type': 27, 'typed_info': data['payload'][2]}, 'causation_command_id': 2}
|
||||
eq.require(eq.exact(row['original_field_types'], original), 'original event field types')
|
||||
event_ids.append(data['event_id'][1])
|
||||
eq.require(len(set(event_ids)) == len(event_ids) and not set(event_ids).intersection(begin_ids), 'duplicate/reused event ID')
|
||||
eq.require(set(end_ids) == set(begin_ids) | set(event_ids), 'missing/extra E2 events')
|
||||
eq.require(end['counter'] - begin['counter'] == len(event_ids), 'event counter delta')
|
||||
for row in raw['signal_order']:
|
||||
eq.require(set(row) == {'signal', 'minute'} and row['signal'] in ('snapshot_published', 'state_updated'), 'signal record')
|
||||
eq.require(type(row['minute']) is int and start_minute <= row['minute'] <= start_minute+30, 'signal minute')
|
||||
check_measurement(raw, measurement)
|
||||
out.update(ok=True, normalization=proofs, comparison=compared)
|
||||
except (eq.EvidenceError, KeyError, TypeError, ValueError, IndexError) as exc:
|
||||
out['errors'].append(str(exc))
|
||||
return out
|
||||
|
||||
|
||||
def check_observation(cp, evidence):
|
||||
"""Bind retained full bytes to report SHA, not merely asserted equality."""
|
||||
eq.require(set(evidence) == {'before', 'after'}, 'observation evidence fields')
|
||||
for side in ('before', 'after'):
|
||||
row = evidence[side]
|
||||
eq.require(set(row) == {'sha', 'S', 'K', 'C', 'kernel', 'cache'}, 'raw layer fields')
|
||||
eq.require(eq.exact(row['kernel'], cp['K']) and eq.exact(row['cache'], cp['C']), 'raw layer value contradiction')
|
||||
for layer in ('S', 'K', 'C'):
|
||||
eq.validate_tree([29, row[layer]])
|
||||
actual = sha(base64.b64decode(row[layer], validate=True))
|
||||
eq.require(actual == row['sha'][layer] == cp['observation'][side][layer], 'raw layer SHA mismatch')
|
||||
eq.require(all(evidence['before'][k] == evidence['after'][k] for k in ('S', 'K', 'C')), 'raw observation bytes differ')
|
||||
return True
|
||||
|
||||
|
||||
def read_report_stdout(stdout):
|
||||
lines = [line[len('P28_02_EQ_REPORT='):] for line in stdout.splitlines() if line.startswith('P28_02_EQ_REPORT=')]
|
||||
eq.require(len(lines) == 1, 'exactly one report line required')
|
||||
return strict_json(lines[0])
|
||||
|
||||
|
||||
def strict_json(text):
|
||||
def unique(pairs):
|
||||
result = {}
|
||||
for key, value in pairs:
|
||||
eq.require(key not in result, 'duplicate JSON key: ' + key)
|
||||
result[key] = value
|
||||
return result
|
||||
return json.loads(text, object_pairs_hook=unique)
|
||||
|
||||
|
||||
def check_lifecycle(raw, lifecycle, guard):
|
||||
"""S2 startup proof; S4 must supply the separately SHA-bound guard receipt."""
|
||||
eq.require(lifecycle['stage'] in ('S2', 'S3a', 'S3b') and lifecycle['errors'] == [], 'probe errors/stage')
|
||||
eq.require(lifecycle['stop_reason'] == {'S2': 'S2_complete_S3_pending', 'S3a': 'S3a_complete_S3b_pending', 'S3b': 'S3b_complete_S4_pending'}[lifecycle['stage']], 'probe did not finish stage')
|
||||
if lifecycle['stage'] in ('S3a', 'S3b'):
|
||||
check_measurement(raw, lifecycle['measurement'])
|
||||
check_e3(dict(raw, scenarios=raw['scenarios'][:18]), lifecycle['e3'], lifecycle['e3_b1'])
|
||||
if lifecycle['stage'] == 'S3b':
|
||||
check_e45(raw, lifecycle['e45'], lifecycle['e3'][-1]['end'])
|
||||
binding = lifecycle['guard']
|
||||
eq.require(guard['verified'] is True and eq.exact(binding['receipt'], guard), 'independent guard differs')
|
||||
root = eq._profile(raw['profile_root'])
|
||||
eq.require(root == binding['live_root'] == guard['actual_user_data_dir'], 'live/guard profile contradiction')
|
||||
eq.require(hex_sha(binding['sha256']), 'guard SHA missing')
|
||||
eq.require(eq.exact(lifecycle['observer_before'], lifecycle['observer_disconnected']), 'observers not restored')
|
||||
eq.require(not eq.exact(lifecycle['observer_before'], lifecycle['observer_connected']), 'observers never connected')
|
||||
b0 = 602 if raw['role'] == 'R' else 360
|
||||
for label, minute in (('B0', b0), ('B1', b0+30), ('outside', b0+60)):
|
||||
row = lifecycle[label]
|
||||
eq.require(row['kernel']['paused'] is True and row['kernel']['absolute_minute'] == minute, 'lifecycle minute: '+label)
|
||||
for layer in ('S', 'K', 'C'):
|
||||
eq.validate_tree([29, row[layer]])
|
||||
eq.require(sha(base64.b64decode(row[layer], validate=True)) == row['sha'][layer], 'lifecycle raw SHA')
|
||||
for label in ('before_main', 'after_main', 'frame1', 'frame2'):
|
||||
eq.require(type(lifecycle[label]) is dict and lifecycle[label]['kernel']['paused'] is True, 'startup frame evidence')
|
||||
ops = lifecycle['ops']
|
||||
eq.require(ops['code'] == 'INVALID_START_TIME' if raw['role'] == 'R' else ops['ok'] is True, 'startup Ops outcome')
|
||||
if raw['role'] == 'R':
|
||||
restores = [r for r in lifecycle['preparation'] if r['operation'] == 'fixture_restore']
|
||||
eq.require(len(restores) == 1 and restores[0]['ok'] is True and restores[0]['input_sha256'] ==
|
||||
'eb4f770071eb07cd7e136fe54c3f78768cc8de7a4264e62a9af1f06a8f90f9bd', 'fixture preparation')
|
||||
return True
|
||||
|
||||
|
||||
def _code(text):
|
||||
# Mask strings/comments while retaining line positions. Tests exercise decoys.
|
||||
return re.sub(r'"(?:\\.|[^"\\])*"|\'(?:\\.|[^\'\\])*\'|#[^\n]*',
|
||||
lambda m: ' ' * len(m.group()), text)
|
||||
|
||||
|
||||
def check_probe(text):
|
||||
"""Conservative S2 static policy, not a replacement for Godot parse/review."""
|
||||
errors = []
|
||||
code = _code(text)
|
||||
if ':=' in code:
|
||||
errors.append('inferred declarations forbidden; explicitly type Variant reads')
|
||||
if re.search(r'\b(?:SimulationRuntimeService|GameClock|GameState|SimulationRuntime|EventBus)\s*\.', code):
|
||||
errors.append('autoload static reference')
|
||||
if re.search(r'\b(?:preload|load)\s*\(\s*["\']res://autoload/', text):
|
||||
errors.append('autoload script import')
|
||||
if re.search(r'\.(?:set_script|set|call|callv|call_deferred|set_deferred)\s*\(', code):
|
||||
errors.append('dynamic product mutation/hook dispatch')
|
||||
if re.search(r'\b(?:runtime|clock|main)\s*(?:\.[A-Za-z_]\w*|\[[^\n]*?\])+\s*(?:[+*/-]?=(?!=))', code):
|
||||
errors.append('direct live assignment')
|
||||
if re.search(r'\.(?:sort|sort_custom)\(', code):
|
||||
for line in code.splitlines():
|
||||
if '.sort(' in line or ('.sort_custom(' in line and 'str(a) < str(b)' not in line and 'json_text(a) < json_text(b)' not in line):
|
||||
errors.append('ordering must compare textual keys')
|
||||
function = None
|
||||
functions = {}
|
||||
for line in text.splitlines():
|
||||
match = re.match(r'func (\w+)\(', line)
|
||||
if match:
|
||||
function = match[1]
|
||||
functions[function] = []
|
||||
if function: functions[function].append(line)
|
||||
clean = _code(line)
|
||||
allowed_live = {
|
||||
'runtime': {'get', 'create_snapshot', 'restore_snapshot', 'load_from_path', 'get_save_policy', 'get_counter', 'subscribe', 'unsubscribe', 'connect', 'disconnect', 'get_facility_ids', 'get_bounds', 'preview_build_facility', 'submit_command', 'get_processed_result'},
|
||||
'clock': {'get', 'set_paused', 'advance_minutes'},
|
||||
'main': {'get', 'connect'},
|
||||
}
|
||||
for receiver, method in re.findall(r'\b(runtime|clock|main)\s*(?:\.\w+)*\.(\w+)\s*\(', clean):
|
||||
if method not in allowed_live[receiver]: errors.append('unlisted live method: '+receiver+'.'+method)
|
||||
for method in re.findall(r'\.(\w+)\s*\(', clean):
|
||||
if method in ('set_paused', 'restore_snapshot', 'advance_minutes', 'add_child', 'instantiate'):
|
||||
required = 'step' if method == 'advance_minutes' else 'begin'
|
||||
if function != required and not (method == 'restore_snapshot' and function in ('run_e3', 'run_e4')) and not (method == 'advance_minutes' and function in ('run_e4', 'run_e5')): errors.append('state-changing call outside preparation/stepping: ' + method)
|
||||
if method in ('load_from_path', 'save_to_path', 'save_snapshot', 'load_snapshot', 'validate', 'enqueue', 'submit_command', 'enable_production_operations', 'initialize', 'reset', 'publish', 'publish_batch', '_set_speed', '_toggle_pause'):
|
||||
if not ((method in ('load_from_path', 'validate') and function == 'run_e3') or (method == 'save_snapshot' and function == 'e3_prepare_package') or (method in ('load_from_path', 'save_snapshot', 'submit_command') and function == 'run_e4')):
|
||||
errors.append('S3/unlisted state-changing call: ' + method)
|
||||
if '.set_paused(' in clean and not re.search(r'\.set_paused\(true\)', clean): errors.append('only pause true allowed')
|
||||
if '.advance_minutes(' in clean and not re.search(r'\.advance_minutes\(1\)', clean): errors.append('only one-minute stepping allowed')
|
||||
# A digest alone, stub proof, or truncated checkpoint producer is not admitted.
|
||||
required = {
|
||||
'transport': ('var_to_bytes(value)', 'var_to_bytes(decode(tree))', 'raw == rebuilt', 'encode(value)', 'hashed(json_text(tree).to_utf8_buffer())'),
|
||||
'checkpoint': ('layers()', 'transport(runtime.create_snapshot())', 'transport(latest_value)', 'before.s_bytes == after.s_bytes', 'before.k_bytes == after.k_bytes', 'before.c_bytes == after.c_bytes', 'diff_record(', 'write_evidence('),
|
||||
'bind_profile': ('ProjectSettings.globalize_path("user://").simplify_path()', 'receipt.get("actual_user_data_dir")', 'actual == live_root'),
|
||||
'observe_event': ('event.to_dictionary()', 'transport(value)', 'typeof(event.event_id)', 'typed_info(event.payload)', 'report.events.append('),
|
||||
'begin': ('runtime.domain_events.subscribe(&"*"', 'report.event_start = event_counts()', 'await step()', 'checkpoint()'),
|
||||
'finish': ('root.close_requested.emit()', 'runtime.domain_events.unsubscribe(', 'write_evidence("events.json"', 'write_evidence("lifecycle.json"'),
|
||||
}
|
||||
for name, snippets in required.items():
|
||||
body = '\n'.join(functions.get(name, []))
|
||||
# Comments cannot supply a required proof operation.
|
||||
body = '\n'.join(line for line in body.splitlines() if not line.lstrip().startswith('#'))
|
||||
for snippet in snippets:
|
||||
if snippet not in body: errors.append('missing full-state/proof operation: ' + name + ': ' + snippet)
|
||||
begin = '\n'.join(functions.get('begin', []))
|
||||
preparation, separator, rest = begin.partition('initial_inventory = inventory()')
|
||||
if not separator or re.search(r'\.(?:restore_snapshot|set_paused|instantiate|add_child)\(', _code(rest)):
|
||||
errors.append('preparation mutation after B0 boundary')
|
||||
if code.count('.advance_minutes(') != 7 or code.count('.restore_snapshot(') != 3 or code.count('.set_paused(') != 2:
|
||||
errors.append('unexpected mutation call count')
|
||||
for name, snippets in {
|
||||
'run_e3': ('scenario_active = true', 'scenario_active = false', 'e3_observation()', 'runtime.restore_snapshot(input)', 'SimulationSnapshot.validate(input)', 'runtime.load_from_path(path)'),
|
||||
'e3_prepare_package': ('demand(scenario_active,', 'SaveService.save_snapshot(path, input, {})'),
|
||||
}.items():
|
||||
body = '\n'.join(functions.get(name, []))
|
||||
for snippet in snippets:
|
||||
if snippet not in body: errors.append('missing E3 boundary/call: '+name+': '+snippet)
|
||||
if code.count('run_e3()') != 2 or code.count('e3_prepare_package(') != 2:
|
||||
errors.append('unexpected scenario dispatch')
|
||||
scenario_body = '\n'.join(functions.get('run_e3', []))
|
||||
prefix, opened, remaining = scenario_body.partition('scenario_active = true')
|
||||
active, closed, suffix = remaining.partition('scenario_active = false')
|
||||
if not opened or not closed or re.search(r'(?:restore_snapshot|load_from_path|validate|e3_prepare_package)\(', _code(prefix + suffix)):
|
||||
errors.append('E3 operation outside active interval')
|
||||
if text.count('print("P28_02_EQ_REPORT="') != 1: errors.append('single report emission required')
|
||||
for name in ('run_e4', 'run_e5'):
|
||||
body = '\n'.join(functions.get(name, []))
|
||||
prefix, opened, rest = body.partition('scenario_active = true')
|
||||
active, closed, suffix = rest.partition('scenario_active = false')
|
||||
if not opened or not closed or re.search(r'(?:advance_minutes|submit_command|restore_snapshot|load_from_path|save_snapshot|e4_candidates)\(|\breturned\s*\[', _code(prefix + suffix)):
|
||||
errors.append('E4/E5 operation outside active interval')
|
||||
if code.count(name+'()') != 2: errors.append('unexpected E4/E5 dispatch')
|
||||
for name, body in functions.items():
|
||||
clean = _code('\n'.join(body))
|
||||
if name != 'run_e5' and re.search(r'\breturned\s*\[|__p28_eq_probe', '\n'.join(body)):
|
||||
errors.append('ownership mutation outside E5')
|
||||
if name in ('observe_snapshot', 'observe_state') and re.search(r'\[[^\n]*\]\s*=|\.(?:append|erase|clear|merge)\(', clean):
|
||||
errors.append('signal handler mutation')
|
||||
if name != 'run_e4' and 'e4_candidates()' in clean and name != 'e4_candidates': errors.append('candidate dispatch outside E4')
|
||||
if code.count('e4_candidates()') != 2 or code.count('.submit_command(') != 2: errors.append('unexpected E4 command/search dispatch')
|
||||
candidate_body = '\n'.join(functions.get('e4_candidates', []))
|
||||
for snippet in ('runtime.definition_registry.get_facility_ids()', 'runtime.world_service.get_bounds()', 'runtime.preview_build_facility(definition_id, origin, 0)', 'demand(scenario_active,', 'selection.trials.append('):
|
||||
if snippet not in candidate_body: errors.append('missing E4 selection proof: '+snippet)
|
||||
if re.search(r'report\.events\.(?:resize|pop_front|pop_back|erase|clear)', code): errors.append('event cap/removal forbidden')
|
||||
return {'ok': not errors, 'stage': 'S3a', 'errors': errors}
|
||||
|
||||
|
||||
# S3a source-backed E3 table; E4/E5 admission remains S3b.
|
||||
E3_KINDS = ('missing_key', 'wrong_type', 'out_of_range', 'duplicate_published_ids', 'duplicate_facility', 'tampered_world')
|
||||
E3_APIS = ('restore_snapshot', 'validate', 'load_from_path')
|
||||
|
||||
|
||||
def node_at(tree, *names):
|
||||
for name in names:
|
||||
tree = fields(tree)[name]
|
||||
return tree
|
||||
|
||||
|
||||
def e3_expected_input(b1, kind):
|
||||
value = copy.deepcopy(b1)
|
||||
if kind == 'missing_key':
|
||||
value[1] = [pair for pair in value[1] if pair[0][1] != 'clock']
|
||||
elif kind in ('wrong_type', 'out_of_range'):
|
||||
node_at(value, 'clock', 'absolute_minute' if kind == 'wrong_type' else 'speed')[:] = (
|
||||
[4, 'x'] if kind == 'wrong_type' else [2, 9])
|
||||
elif kind in ('duplicate_published_ids', 'duplicate_facility'):
|
||||
nodes = (node_at(value, 'systems', 'runtime', 'domain_events', 'published_ids') if kind == 'duplicate_published_ids'
|
||||
else node_at(value, 'systems', 'runtime', 'facilities', 'instances'))
|
||||
if nodes[1]:
|
||||
nodes[1].append(copy.deepcopy(nodes[1][0]))
|
||||
else:
|
||||
eq.require(kind == 'duplicate_facility', 'no B1 published ID to duplicate')
|
||||
return value
|
||||
|
||||
|
||||
def e3_x(before, event):
|
||||
value = copy.deepcopy(before)
|
||||
counter = node_at(value, 'systems', 'runtime', 'id_generator', 'counters', 'domain_event')
|
||||
counter[1] += 1
|
||||
domain = node_at(value, 'systems', 'runtime', 'domain_events')
|
||||
ids = fields(domain)['published_ids']
|
||||
ids[1].append(copy.deepcopy(fields(event)['event_id']))
|
||||
ids[1].sort(key=lambda n: n[1])
|
||||
recent = fields(domain)['recent_events']
|
||||
dropped = copy.deepcopy(recent[1][0]) if len(recent[1]) == 256 else None
|
||||
recent[1].append(copy.deepcopy(event))
|
||||
if len(recent[1]) > 256:
|
||||
del recent[1][0]
|
||||
return value, dropped
|
||||
|
||||
|
||||
def e3_raw_observation(row):
|
||||
cp = row['checkpoint']
|
||||
check_observation(cp, row['raw'])
|
||||
s = eq._transport(cp['S'], None)
|
||||
eq.require(cp['S']['raw_bytes_sha'] == row['raw']['before']['sha']['S'], 'E3 S transport/raw')
|
||||
for layer in ('K', 'C'):
|
||||
proof = row[layer+'_tree']
|
||||
eq._transport(proof, None)
|
||||
eq.require(proof['raw_bytes_sha'] == row['raw']['before']['sha'][layer], 'E3 layer transport/raw')
|
||||
return s
|
||||
|
||||
|
||||
def e3_package_check(package, kind):
|
||||
def files(rows):
|
||||
eq.require(set(rows) == {'manifest.json', 'world.bin', 'thumbnail.png', 'journal.log'}, 'package inventory')
|
||||
out = {}
|
||||
for name, item in rows.items():
|
||||
if item is None:
|
||||
out[name] = None
|
||||
continue
|
||||
eq.require(set(item) == {'bytes', 'sha256'}, 'package file fields')
|
||||
content = base64.b64decode(item['bytes'], validate=True)
|
||||
eq.require(sha(content) == item['sha256'], 'package file SHA')
|
||||
out[name] = content
|
||||
return out
|
||||
saved = fields(eq._transport(package['save_return'], None))
|
||||
eq.require('ok' in saved and 'code' in saved, 'save preparation return')
|
||||
original, modified = files(package['original']), files(package['modified'])
|
||||
files(package['after_operation'])
|
||||
if saved['ok'] == [1, 0]:
|
||||
eq.require(kind.startswith('duplicate_'), 'required package save refused')
|
||||
return False
|
||||
eq.require(saved['ok'] == [1, 1], 'save preparation bool')
|
||||
eq.require(all(original[n] == modified[n] for n in ('thumbnail.png', 'journal.log')), 'unlisted package mutation')
|
||||
if kind == 'tampered_world':
|
||||
expected = bytearray(original['world.bin'])
|
||||
eq.require(len(expected) > 0, 'empty tamper world')
|
||||
offset = len(expected)//2
|
||||
old = expected[offset]
|
||||
expected[offset] ^= 1
|
||||
eq.require(modified['world.bin'] == bytes(expected) and original['manifest.json'] == modified['manifest.json'], 'D3 tamper rule')
|
||||
eq.require(package['tamper'] == {'offset': offset, 'before': old, 'after': old ^ 1}, 'tamper evidence')
|
||||
elif kind in ('missing_key', 'wrong_type', 'out_of_range'):
|
||||
before, after = json.loads(original['manifest.json']), json.loads(modified['manifest.json'])
|
||||
expected = copy.deepcopy(before)
|
||||
if kind == 'missing_key': del expected['checksum_world']
|
||||
else: expected['format_version'] = 'x' if kind == 'wrong_type' else 2147483647
|
||||
eq.require(eq.exact(after, expected) and original['world.bin'] == modified['world.bin'], 'manifest mutation rule')
|
||||
else:
|
||||
eq.require(original == modified, 'duplicate package changed after save')
|
||||
return True
|
||||
|
||||
|
||||
def check_e3(raw, evidence, b1_record):
|
||||
"""Separate malformed evidence from observed existing-defect candidates.
|
||||
|
||||
Returns all actual typed differences. Never promote NA or a defect to PASS.
|
||||
"""
|
||||
b1 = eq._transport(b1_record, None)
|
||||
first = eq.reconstruct_checkpoints(raw['checkpoints'])[0][0]
|
||||
eq.require(eq.exact(b1, first), 'E3 input is not measured B1')
|
||||
facilities = node_at(b1, 'systems', 'runtime', 'facilities', 'instances')
|
||||
count = len(facilities[1])
|
||||
eq.require(raw['role'] != 'R' or count > 0, 'R B1 has no facility')
|
||||
expected_ids = ['E3/'+api+'/'+kind for api in E3_APIS for kind in E3_KINDS]
|
||||
eq.require([s['id'] for s in raw['scenarios']] == expected_ids, 'complete ordered E3 applied/NA table')
|
||||
eq.require([e['id'] for e in evidence] == expected_ids, 'E3 raw evidence coverage')
|
||||
results = []
|
||||
previous_sha = raw['checkpoints'][-1]['observation']['after']
|
||||
for scenario, ev in zip(raw['scenarios'], evidence):
|
||||
api, kind = scenario['operation'], scenario['result']['category']
|
||||
result = scenario['result']
|
||||
eq.require(set(result) == {'category', 'applicability', 'reason', 'invoked', 'facility_count', 'ok', 'errors', 'code',
|
||||
'code_reason', 'migration_attempted', 'event_count', 'path'}, 'E3 result fields')
|
||||
eq.require(scenario['id'] == 'E3/'+api+'/'+kind, 'E3 API/category binding')
|
||||
eq.require(result['facility_count'] == count, 'B1 facility count')
|
||||
eq.require(ev['boundaries'] == ['begin', 'operation', 'end'], 'E3 interval boundaries')
|
||||
expected_input = e3_expected_input(b1, kind)
|
||||
eq.require(eq.exact(eq._transport(ev['input'], None), expected_input), 'fixed B1 mutation rule')
|
||||
before, after = e3_raw_observation(ev['begin']), e3_raw_observation(ev['end'])
|
||||
eq.require(eq.exact(previous_sha, ev['begin']['raw']['before']['sha']), 'unrecorded change between E3 intervals')
|
||||
previous_sha = ev['end']['raw']['after']['sha']
|
||||
e3_raw_observation(ev['invocation_before'])
|
||||
eq.require(eq.exact(scenario['checkpoints'], [ev['begin']['checkpoint'], ev['end']['checkpoint']]), 'E3 boundary binding')
|
||||
events = [eq._transport(item, None) for item in ev['events']]
|
||||
eq.require(eq.exact(events, scenario['events']) and type(result['event_count']) is int and result['event_count'] == len(events), 'E3 event count/evidence binding')
|
||||
applied, reason, invoked = True, None, True
|
||||
if kind == 'tampered_world' and api != 'load_from_path':
|
||||
applied, reason, invoked = False, 'Dictionary API does not read packages', False
|
||||
elif kind == 'duplicate_facility' and count == 0:
|
||||
eq.require(raw['role'] == 'O', 'facility NA only for O')
|
||||
applied, reason, invoked = False, 'B1 has zero facilities', False
|
||||
elif kind.startswith('duplicate_') and api == 'validate':
|
||||
applied, reason = False, 'Envelope validation does not inspect runtime internals'
|
||||
if api == 'load_from_path':
|
||||
eq.require(result['path'] == 'user://p28_eq/'+raw['role'].lower()+'/'+('duplicate_id' if kind.startswith('duplicate_') else kind), 'fixed scenario path')
|
||||
if applied:
|
||||
package_input = expected_input if kind.startswith('duplicate_') else b1
|
||||
eq.require(eq.exact(eq._transport(ev['package']['input'], None), package_input), 'package save input not fixed B1 copy')
|
||||
if not e3_package_check(ev['package'], kind):
|
||||
applied, reason, invoked = False, 'SaveService.save_snapshot refused duplicate input', False
|
||||
else:
|
||||
eq.require(ev['package'] is None, 'NA package unexpectedly prepared')
|
||||
else:
|
||||
eq.require(result['path'] is None and ev['package'] is None, 'Dictionary API package')
|
||||
eq.require(result['applicability'] == ('applied' if applied else 'NA') and result['reason'] == reason and result['invoked'] is invoked, 'E3 applied/NA table contradiction')
|
||||
actual = eq._transport(ev['return'], None)
|
||||
eq.require(type(result['migration_attempted']) is bool, 'migration flag type')
|
||||
if api != 'validate':
|
||||
eq.require(result['errors'] is None, 'invented validation errors')
|
||||
if api == 'restore_snapshot':
|
||||
eq.require(result['code'] is None and result['code_reason'] == 'API returns bool only', 'restore invented code')
|
||||
eq.require(actual == ([1, int(result['ok'])] if invoked and type(result['ok']) is bool else [0]), 'restore actual bool')
|
||||
eq.require(not invoked or type(result['ok']) is bool, 'restore bool missing')
|
||||
elif api == 'validate':
|
||||
eq.require(result['code'] is None and result['code_reason'] == 'API returns ok/errors only', 'validate invented code')
|
||||
if invoked:
|
||||
data = fields(actual)
|
||||
eq.require(set(data) == {'ok', 'errors'} and data['ok'] == [1, int(result['ok'])] and type(result['ok']) is bool, 'validate full return')
|
||||
eq.require(data['errors'][0] == 28 and [v[1] for v in data['errors'][1]] == result['errors'] and all(v[0] == 4 for v in data['errors'][1]), 'validate errors full list')
|
||||
elif invoked:
|
||||
data = fields(actual)
|
||||
eq.require('code' in data and data['code'][0] in (4, 21) and bool(data['code'][1]), 'load code missing')
|
||||
eq.require(result['code'] == data['code'][1] and result['code_reason'] is None, 'load code binding')
|
||||
eq.require(type(result['ok']) is bool and data['ok'] == [1, int(result['ok'])], 'load actual ok')
|
||||
eq.require(result['migration_attempted'] is (data.get('migration_attempted', [1, 0]) == [1, 1]), 'migration fact')
|
||||
if not invoked:
|
||||
eq.require(actual == [0] and result['ok'] is None and result['code'] is None, 'NA has invented outcome')
|
||||
defects = []
|
||||
expected_code, expected_error = None, None
|
||||
if applied:
|
||||
if result['ok'] is not False: defects.append({'kind': 'invalid_input_accepted', 'actual': actual})
|
||||
if api == 'validate':
|
||||
expected_error = {'missing_key': 'missing_clock', 'wrong_type': 'invalid_absolute_minute', 'out_of_range': 'invalid_speed'}[kind]
|
||||
if expected_error not in result['errors']: defects.append({'kind': 'expected_error_missing', 'expected': expected_error, 'actual': actual})
|
||||
if api == 'load_from_path':
|
||||
expected_code = {'missing_key': 'INVALID_MANIFEST', 'wrong_type': 'INVALID_MANIFEST', 'out_of_range': 'UNSUPPORTED_FORMAT',
|
||||
'duplicate_published_ids': 'RESTORE_FAILED', 'duplicate_facility': 'RESTORE_FAILED', 'tampered_world': 'CHECKSUM_MISMATCH'}[kind]
|
||||
if result['code'] != expected_code and not (kind == 'out_of_range' and result['migration_attempted']):
|
||||
defects.append({'kind': 'unexpected_code', 'expected': expected_code, 'actual': result['code']})
|
||||
expected_count = 1 if api == 'load_from_path' and invoked else 0
|
||||
if len(events) != expected_count:
|
||||
defects.append({'kind': 'event_count', 'expected': expected_count, 'actual': len(events)})
|
||||
expected_state, dropped = before, None
|
||||
if expected_count == 1 and len(events) == 1:
|
||||
event_data = fields(events[0])
|
||||
if event_data['event_type'] != [4, 'SAVE_LOAD_FAILED'] or event_data['source_service'] != [4, 'save_service'] or event_data['entity_ids'][1] != []:
|
||||
defects.append({'kind': 'failure_event_shape', 'actual': events[0]})
|
||||
latest = eq._transport(ev['latest_save_operation_result'], None)
|
||||
if not eq.exact(latest, event_data['payload']):
|
||||
defects.append({'kind': 'failure_payload_latest_mismatch', 'latest': latest, 'payload': event_data['payload']})
|
||||
data = fields(actual)
|
||||
payload = fields(event_data['payload'])
|
||||
for name in ('ok', 'code'):
|
||||
if not eq.exact(data[name], payload[name]):
|
||||
defects.append({'kind': 'return_payload_mismatch', 'field': name, 'return': data[name], 'payload': payload[name]})
|
||||
for name in ('duration_us', 'runtime_duration_us', 'message', 'save_path'):
|
||||
if name in data and not eq.exact(data[name], payload[name]):
|
||||
defects.append({'kind': 'return_payload_mismatch', 'field': name, 'return': data[name], 'payload': payload[name]})
|
||||
if data.get('preload_pause_restored') != [1, 1] or data.get('loaded_clock_paused') != [1, int(ev['begin']['checkpoint']['K']['paused'])]:
|
||||
defects.append({'kind': 'load_pause_outcome', 'actual': actual})
|
||||
if 'recovery_report' in data and fields(data['recovery_report']).get('restore_committed') != [1, 0]:
|
||||
defects.append({'kind': 'load_restore_committed', 'actual': data['recovery_report']})
|
||||
expected_state, dropped = e3_x(before, events[0])
|
||||
normalized_expected, expected_side = eq.normalize_tree(expected_state, raw['profile_root'])
|
||||
normalized_after, actual_side = eq.normalize_tree(after, raw['profile_root'])
|
||||
delta = eq.compare_trees(normalized_expected, normalized_after)
|
||||
if not delta['equal']: defects.append({'kind': 'S_changes', 'comparison': delta})
|
||||
for layer in ('K', 'C'):
|
||||
left, right = ev['begin']['raw']['before'], ev['end']['raw']['after']
|
||||
if left[layer] != right[layer]:
|
||||
defects.append({'kind': layer+'_changes', 'before': left[layer], 'after': right[layer],
|
||||
'comparison': eq.compare_trees(ev['begin'][layer+'_tree']['tree'], ev['end'][layer+'_tree']['tree'])})
|
||||
# Dictionary APIs require byte identity, not normalization/order fallback.
|
||||
if expected_count == 0 and ev['begin']['raw']['before']['S'] != ev['end']['raw']['after']['S']:
|
||||
defects.append({'kind': 'S_bytes_changed', 'before': ev['begin']['raw']['before']['S'], 'after': ev['end']['raw']['after']['S']})
|
||||
results.append({'id': scenario['id'], 'applicability': result['applicability'], 'reason': reason,
|
||||
'expected': {'ok': False if applied else None, 'code': expected_code, 'error': expected_error, 'event_count': expected_count},
|
||||
'actual': copy.deepcopy(result),
|
||||
'status': 'existing-defect-candidate' if defects else ('recorded' if applied else 'NA'),
|
||||
'defects': defects, 'dropped_recent_event': dropped, 'expected_state': expected_state,
|
||||
'state_comparison': delta, 'expected_sidecar': expected_side, 'actual_sidecar': actual_side})
|
||||
results[-1]['exclusions'] = [{'reason': 'SaveService static diagnostic budget outside S/K/C; wall time',
|
||||
'before': eq._transport(ev['save_budget_before'], None), 'after': eq._transport(ev['save_budget_after'], None)},
|
||||
{'reason': 'Package manifest/file evidence outside S/E2; includes real timestamps', 'actual': ev['package']}]
|
||||
return results
|
||||
|
||||
|
||||
|
||||
# S3b additions. Raw evidence is authoritative; outcome labels are derived.
|
||||
E4_PATHS = ('build_facility', 'tick', 'restore_snapshot', 'load_from_path', 'rejected_command')
|
||||
E5_TARGETS = ('create_snapshot', 'latest_snapshot', 'snapshot_published', 'state_updated')
|
||||
SORT_RULE = 'String(id) ascending Unicode code point'
|
||||
CELL_RULE = 'inclusive x/y public bounds; z FRONT=0 through BACK=1; x,y,z lexical; ID outer; rotation=0'
|
||||
|
||||
|
||||
def join_facts(value, profile_root):
|
||||
"""Normalize only snapshot transports; retain all raw facts in raw report."""
|
||||
proofs = []
|
||||
def walk(item, path):
|
||||
if isinstance(item, dict) and {'tree', 'tree_sha', 'raw_bytes_sha', 'roundtrip_ok'} == set(item):
|
||||
tree = eq._transport(item, None)
|
||||
if path and path[-1] in ('held_before', 'held_after', 'input'):
|
||||
normal, side = eq.normalize_tree(tree, profile_root)
|
||||
eq.require(eq.exact(eq.restore_tree(normal, side, profile_root), tree), 'fact normalization roundtrip')
|
||||
proofs.append({'path': path, 'sidecar': side, 'raw': item})
|
||||
return normal
|
||||
return tree
|
||||
if isinstance(item, dict):
|
||||
return {k: walk(v, path+[k]) for k, v in item.items()}
|
||||
if isinstance(item, list):
|
||||
return [walk(v, path+[i]) for i, v in enumerate(item)]
|
||||
return item
|
||||
return walk(value, []), proofs
|
||||
|
||||
|
||||
def e45_facts(detail):
|
||||
facts = copy.deepcopy(detail)
|
||||
for key in ('package_before', 'package_after', 'save_return', 'return', 'save_budget_before', 'save_budget_after', 'latest_save_operation_result', 'observation_before', 'observation_after'):
|
||||
facts.pop(key, None)
|
||||
if 'return' in detail:
|
||||
actual = eq._transport(detail['return'], None)
|
||||
facts['return_fact'] = ({k: fields(actual)[k][1] if fields(actual)[k][0] != 1 else bool(fields(actual)[k][1])
|
||||
for k in ('ok', 'code')} if actual[0] == 27 else bool(actual[1]))
|
||||
for trial in facts.get('trials', []):
|
||||
trial.pop('before', None); trial.pop('after', None)
|
||||
return facts
|
||||
|
||||
|
||||
def check_selection(detail, begin):
|
||||
for key in ('observation_before', 'observation_after'):
|
||||
eq.require(eq.exact(e3_raw_observation(detail[key]), begin), 'preview search S baseline')
|
||||
eq.require(eq.exact(detail['observation_before']['raw'], detail['observation_after']['raw']), 'preview search changed full S/K/C')
|
||||
eq.require(detail['source'] == 'definition_registry.get_facility_ids()', 'E4 registry source')
|
||||
raw = eq._transport(detail['raw_ids'], None)
|
||||
ordered = eq._transport(detail['sorted_ids'], None)
|
||||
eq.require(raw[0] == ordered[0] == 28 and all(n[0] == 21 for n in raw[1]), 'facility ID types')
|
||||
ids = [n[1] for n in raw[1]]
|
||||
eq.require(type(detail['count']) is int and detail['count'] == len(ids) and len(ids) > 0 and len(set(ids)) == len(ids), 'empty/invalid facility registry')
|
||||
eq.require(ordered[2] == raw[2] and ordered[1] == sorted(raw[1], key=lambda n: n[1]) and detail['sort_rule'] == SORT_RULE, 'facility sort rule')
|
||||
eq.require(detail['cell_rule'] == CELL_RULE, 'cell scan rule')
|
||||
bounds = eq._transport(detail['bounds'], None)
|
||||
eq.require(eq.exact(bounds, node_at(begin, 'systems', 'runtime', 'world', 'bounds')), 'public bounds/state binding')
|
||||
b = fields(bounds)
|
||||
eq.require(set(b) == {'min_x', 'max_x', 'min_y', 'max_y'} and all(n[0] == 2 for n in b.values()), 'bounds shape')
|
||||
eq.require(b['min_x'][1] <= b['max_x'][1] and b['min_y'][1] <= b['max_y'][1], 'empty scan bounds')
|
||||
def candidates():
|
||||
for ident in sorted(ids):
|
||||
for x in range(b['min_x'][1], b['max_x'][1]+1):
|
||||
for y in range(b['min_y'][1], b['max_y'][1]+1):
|
||||
for z in (0, 1):
|
||||
yield ident, x, y, z
|
||||
expected = candidates()
|
||||
chosen = None
|
||||
for trial in detail['trials']:
|
||||
eq.require(chosen is None, 'trials after first placeable candidate')
|
||||
wanted = next(expected, None)
|
||||
eq.require(wanted is not None, 'extra candidate trial')
|
||||
c = fields(eq._transport(trial['candidate'], None))
|
||||
eq.require(set(c) == {'definition_id', 'origin', 'rotation'} and c['definition_id'] == [21, wanted[0]]
|
||||
and c['origin'] == [10, [[2, v] for v in wanted[1:]]] and c['rotation'] == [2, 0], 'missing/reordered candidate trial')
|
||||
preview = fields(eq._transport(trial['preview'], None))
|
||||
eq.require(preview.get('can_build') in ([1, 0], [1, 1]), 'full preview result required')
|
||||
eq.require(set(trial) == {'candidate', 'preview'}, 'preview trial fields')
|
||||
if preview['can_build'] == [1, 1]: chosen = trial['candidate']
|
||||
if chosen is None:
|
||||
eq.require(next(expected, None) is None, 'missing candidate trials')
|
||||
eq.require(detail['chosen'] is None and detail['applicability'] == 'NA' and detail['reason'] == 'all registry/cell pairs rejected by public preview', 'false NA/reason')
|
||||
eq.require('submit' not in detail and 'command_result' not in detail, 'NA executed command')
|
||||
else:
|
||||
eq.require(eq.exact(detail['chosen'], chosen) and detail['applicability'] == 'applied' and detail['reason'] is None, 'chosen without matching preview')
|
||||
check_command(detail)
|
||||
return chosen is not None
|
||||
|
||||
|
||||
def check_command(detail):
|
||||
submitted = fields(eq._transport(detail['submit'], None))
|
||||
completed = fields(eq._transport(detail['command_result'], None))
|
||||
eq.require(all(k in submitted and k in completed for k in ('command_id', 'code')), 'command result absent')
|
||||
eq.require(submitted['command_id'] == completed['command_id'] and submitted['command_id'][0] == 2, 'command ID binding')
|
||||
eq.require(submitted['code'][0] == completed['code'][0] == 4, 'actual command code required')
|
||||
return completed
|
||||
|
||||
|
||||
def check_e45(raw, evidence, previous):
|
||||
ids = ['E4/'+p for p in E4_PATHS] + ['E5/'+t+'/'+l+'/'+d for t in E5_TARGETS
|
||||
for l in ('dict', 'array') for d in ('outside_in', 'inside_out')]
|
||||
scenarios = raw['scenarios'][18:]
|
||||
eq.require([s['id'] for s in scenarios] == ids and [e['id'] for e in evidence] == ids, 'complete ordered E4/E5 coverage')
|
||||
outcomes = []
|
||||
previous_sha = previous['raw']['after']['sha']
|
||||
for scenario, ev in zip(scenarios, evidence):
|
||||
eq.require(set(ev) == {'id', 'boundaries', 'observations', 'events', 'signals', 'detail'}, 'E4/E5 evidence fields')
|
||||
eq.require(ev['boundaries'] == ['begin', 'operation', 'end'], 'E4/E5 boundaries')
|
||||
obs, detail = ev['observations'], ev['detail']
|
||||
eq.require(eq.exact(detail['signals'], ev['signals']), 'scenario signals/facts binding')
|
||||
if scenario['id'].startswith('E5/'):
|
||||
eq.require(set(detail) == {'target', 'location', 'direction', 'digest_materialized_before', 'held_before', 'held_after', 'signals'}, 'E5 detail fields')
|
||||
else:
|
||||
common = {'save_budget_before', 'save_budget_after', 'signals'}
|
||||
specific = {
|
||||
'build_facility': {'source', 'raw_ids', 'count', 'sorted_ids', 'sort_rule', 'bounds', 'cell_rule', 'trials', 'chosen', 'applicability', 'reason', 'observation_before', 'observation_after'},
|
||||
'tick': set(), 'restore_snapshot': {'input', 'return'},
|
||||
'load_from_path': {'input', 'path', 'save_return', 'package_before', 'package_after', 'return', 'latest_save_operation_result'},
|
||||
'rejected_command': {'submit', 'command_result'},
|
||||
}[scenario['operation']]
|
||||
if scenario['operation'] == 'build_facility' and detail.get('chosen') is not None: specific |= {'submit', 'command_result'}
|
||||
eq.require(set(detail) == common | specific, 'E4 detail fields; no invented staleness verdict')
|
||||
eq.require(len(obs) >= 2, 'E4/E5 missing observations')
|
||||
trees = [e3_raw_observation(o) for o in obs]
|
||||
eq.require(eq.exact(previous_sha, obs[0]['raw']['before']['sha']), 'E4/E5 interval gap')
|
||||
previous_sha = obs[-1]['raw']['after']['sha']
|
||||
eq.require(eq.exact(scenario['checkpoints'], [o['checkpoint'] for o in obs]), 'E4/E5 observation binding')
|
||||
events = [eq._transport(e, None) for e in ev['events']]
|
||||
result = scenario['result']
|
||||
eq.require(set(result) == {'event_count', 'applicability', 'reason', 'facts'}, 'E4/E5 result fields; caller PASS forbidden')
|
||||
eq.require(type(result['event_count']) is int and result['event_count'] == len(events)
|
||||
and eq.exact(events, scenario['events']), 'E4/E5 event count binding')
|
||||
eq.require(result['applicability'] == detail.get('applicability', 'applied') and result['reason'] == detail.get('reason'), 'E4/E5 applicability binding')
|
||||
eq.require(eq.exact(result['facts'], e45_facts(detail)), 'E4/E5 facts binding/aliasing record missing')
|
||||
for signal in ev['signals']:
|
||||
eq.require(set(signal) == {'signal', 'minute'} and signal['signal'] in ('snapshot_published', 'state_updated')
|
||||
and obs[0]['checkpoint']['minute'] <= signal['minute'] <= obs[-1]['checkpoint']['minute'], 'scenario signal interval')
|
||||
eq.require(len(ev['signals']) % 2 == 0, 'scenario signal pair missing')
|
||||
for i in range(0, len(ev['signals']), 2):
|
||||
a, b = ev['signals'][i:i+2]
|
||||
eq.require(a['signal'] == 'snapshot_published' and b == {'signal': 'state_updated', 'minute': a['minute']}, 'scenario signal order')
|
||||
defects = []
|
||||
differences = {}
|
||||
for name in ('S', 'latest'):
|
||||
a, b = [eq._transport(o['checkpoint'][name], None) for o in (obs[0], obs[-1])]
|
||||
differences[name] = eq.compare_trees(a, b)
|
||||
for name in ('K', 'C'):
|
||||
differences[name] = eq.compare_trees(obs[0][name+'_tree']['tree'], obs[-1][name+'_tree']['tree'])
|
||||
op = scenario['operation']
|
||||
begin_count, begin_ids = counts(trees[0])
|
||||
end_count, end_ids = counts(trees[-1])
|
||||
event_ids = [fields(event)['event_id'][1] for event in events]
|
||||
eq.require(len(set(event_ids)) == len(event_ids) and not set(event_ids).intersection(begin_ids)
|
||||
and set(end_ids) == set(begin_ids) | set(event_ids)
|
||||
and end_count['counter'] - begin_count['counter'] == len(events), 'E4/E5 full event coverage')
|
||||
if scenario['id'].startswith('E4/'):
|
||||
eq.require(scenario['id'] == 'E4/'+op, 'E4 operation')
|
||||
for key in ('save_budget_before', 'save_budget_after'):
|
||||
eq.require(set(fields(eq._transport(detail[key], None))) == {'_samples', '_totals', '_sample_counts'}, 'save diagnostic budget missing')
|
||||
applied = True
|
||||
if op == 'build_facility': applied = check_selection(detail, trees[0])
|
||||
else: eq.require(result['applicability'] == 'applied' and result['reason'] is None, 'unlisted E4 NA')
|
||||
count = 3 if op == 'rejected_command' or (op == 'build_facility' and applied) else 2
|
||||
eq.require(len(obs) == count, 'submit/immediate E4 checkpoint missing')
|
||||
tick = op in ('tick', 'rejected_command') or (op == 'build_facility' and applied)
|
||||
eq.require(obs[-1]['checkpoint']['minute'] == obs[0]['checkpoint']['minute'] + int(tick), 'E4 tick count')
|
||||
if len(obs) == 3: eq.require(obs[1]['checkpoint']['minute'] == obs[0]['checkpoint']['minute'], 'submit checkpoint delayed')
|
||||
if op in ('restore_snapshot', 'load_from_path'):
|
||||
p = eq._transport(detail['input'], None)
|
||||
eq.require(eq.exact(p, trees[0]), 'E4 input not current deep copy')
|
||||
actual = eq._transport(detail['return'], None)
|
||||
expected = p
|
||||
if op == 'restore_snapshot':
|
||||
eq.require(actual == [1, 1], 'E4 restore did not succeed')
|
||||
eq.require(len(events) == 0, 'restore must emit zero events')
|
||||
else:
|
||||
eq.require(fields(actual).get('ok') == [1, 1] and 'code' in fields(actual), 'E4 load did not succeed')
|
||||
eq.require(detail['path'] == 'user://p28_eq/'+raw['role'].lower()+'/good', 'fixed E4 path')
|
||||
eq.require(len(events) == 1 and fields(events[0])['event_type'] == [4, 'SAVE_LOADED'], 'load must emit one SAVE_LOADED')
|
||||
eq.require(fields(events[0])['source_service'] == [4, 'save_service'], 'load event source')
|
||||
eq.require(eq.exact(eq._transport(detail['latest_save_operation_result'], None), fields(events[0])['payload']), 'load payload/latest result mismatch')
|
||||
expected, dropped = e3_x(p, events[0])
|
||||
package = {'save_return': detail['save_return'], 'original': detail['package_before'],
|
||||
'modified': detail['package_before'], 'after_operation': detail['package_after']}
|
||||
e3_package_check(package, 'good')
|
||||
left, left_side = eq.normalize_tree(expected, raw['profile_root'])
|
||||
right, right_side = eq.normalize_tree(trees[-1], raw['profile_root'])
|
||||
delta = eq.compare_trees(left, right)
|
||||
eq.require(delta['equal'], 'E4 restore/load X(P,event) mismatch')
|
||||
differences['expected_state'] = {'comparison': delta, 'expected': expected, 'sidecars': [left_side, right_side]}
|
||||
if op == 'rejected_command':
|
||||
command = check_command(detail)
|
||||
eq.require(command['code'] != [4, 'OK'], 'nonchanging command not rejected')
|
||||
# All paths retained, including tick effects; do not assert equivalence from digest.
|
||||
differences['submit'] = eq.compare_trees(trees[0], trees[1])
|
||||
differences['tick'] = eq.compare_trees(trees[1], trees[2])
|
||||
else:
|
||||
_, target, location, direction = scenario['id'].split('/')
|
||||
eq.require(op == direction and all(detail[k] == v for k, v in [('target', target), ('location', location), ('direction', direction)]), 'E5 target/direction')
|
||||
eq.require(result['applicability'] == 'applied' and result['reason'] is None and len(obs) == 4, 'E5 coverage/NA')
|
||||
eq.require(detail['digest_materialized_before'] is True, 'E5 digest not materialized')
|
||||
minutes = [o['checkpoint']['minute'] for o in obs]
|
||||
eq.require(minutes == [minutes[0], minutes[0]+1, minutes[0]+1+int(direction == 'inside_out'), minutes[0]+2+int(direction == 'inside_out')], 'E5 preparation/operation/reset tick sequence')
|
||||
held = eq._transport(detail['held_before'], None)
|
||||
after_held = eq._transport(detail['held_after'], None)
|
||||
baseline = obs[1]['checkpoint']
|
||||
expected_held = eq._transport(baseline['S' if target == 'create_snapshot' else 'latest'], None)
|
||||
eq.require(eq.exact(held, expected_held), 'E5 returned target binding')
|
||||
if direction == 'outside_in':
|
||||
expected = copy.deepcopy(held)
|
||||
if location == 'dict':
|
||||
n = node_at(expected, 'systems', 'runtime', 'id_generator', 'counters')
|
||||
eq.require('__p28_eq_probe' not in fields(n), 'E5 marker already present')
|
||||
n[1].append([[4, '__p28_eq_probe'], [2, 1]])
|
||||
else:
|
||||
node_at(expected, 'systems', 'runtime', 'domain_events', 'published_ids')[1].append([4, '__p28_eq_probe'])
|
||||
eq.require(eq.exact(expected, after_held), 'E5 fixed nested mutation absent/extra')
|
||||
for layer in ('S', 'latest'):
|
||||
delta = eq.compare_trees(eq._transport(obs[1]['checkpoint'][layer], None), eq._transport(obs[2]['checkpoint'][layer], None))
|
||||
differences['ownership_'+layer] = delta
|
||||
if not delta['equal']: defects.append({'kind': 'external_mutation_'+layer, 'comparison': delta})
|
||||
old, new = obs[1]['checkpoint'], obs[2]['checkpoint']
|
||||
for field in ('latest_digest', 'computed_latest_digest'):
|
||||
differences[field] = {'before': old[field], 'after': new[field]}
|
||||
if old[field] != new[field]: defects.append({'kind': field+'_changed', 'before': old[field], 'after': new[field]})
|
||||
if new['latest_digest'] != new['computed_latest_digest']:
|
||||
defects.append({'kind': 'cached_digest_aliasing', 'actual': new['latest_digest'], 'computed': new['computed_latest_digest']})
|
||||
else:
|
||||
delta = eq.compare_trees(held, after_held)
|
||||
differences['held'] = delta
|
||||
if not delta['equal']: defects.append({'kind': 'internal_mutation_of_returned_value', 'comparison': delta})
|
||||
for layer in ('K', 'C'):
|
||||
differences['ownership_'+layer] = eq.compare_trees(obs[1][layer+'_tree']['tree'], obs[2][layer+'_tree']['tree'])
|
||||
eq.require(len(events) == counts(trees[-1])[0]['counter']-counts(trees[0])[0]['counter'], 'E5 uncapped event counter delta')
|
||||
outcomes.append({'id': scenario['id'], 'status': 'existing-defect' if defects else ('NA' if result['applicability'] == 'NA' else 'recorded'),
|
||||
'defects': defects, 'differences': differences, 'signals': ev['signals'],
|
||||
'latest_policy': 'record actual value; publication timing is not cache staleness',
|
||||
'exclusions': [{'reason': 'Save package wall time and raw API timing; state/event normalization remains closed F1-F3',
|
||||
'actual': {k: detail[k] for k in ('save_return', 'return', 'package_before', 'package_after', 'save_budget_before', 'save_budget_after', 'latest_save_operation_result') if k in detail}}]})
|
||||
return outcomes
|
||||
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--report', type=Path, required=True)
|
||||
parser.add_argument('--lifecycle', type=Path, required=True)
|
||||
parser.add_argument('--probe', type=Path, default=Path(__file__).with_name('eq_probe.gd'))
|
||||
args = parser.parse_args()
|
||||
life = strict_json(args.lifecycle.read_text())
|
||||
result = {'format': check_report(strict_json(args.report.read_text()), life['measurement'], life['e3'], life['e3_b1'], life.get('e45')), 'static': check_probe(args.probe.read_text())}
|
||||
print(json.dumps(result, ensure_ascii=False))
|
||||
return 0 if all(item['ok'] for item in result.values()) else 1
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,651 @@
|
||||
"""S1 pure-Python typed transport/comparison. No engine or product imports.
|
||||
|
||||
Paths are lists of ['key', key_node] / ['index', integer] segments.
|
||||
Transport validation is distinct from product acceptance (see IMPLEMENTATION.md).
|
||||
"""
|
||||
import base64
|
||||
import copy
|
||||
import hashlib
|
||||
import json
|
||||
import re
|
||||
|
||||
|
||||
class EvidenceError(ValueError):
|
||||
"""Malformed, incomplete, or unauthorized evidence transformation."""
|
||||
|
||||
|
||||
SAVE_EVENTS = frozenset('SAVE_CHECKPOINT_SUCCEEDED SAVE_CHECKPOINT_FAILED SAVE_LOADED '
|
||||
'SAVE_LOAD_FAILED SAVE_MIGRATION_SUCCEEDED SAVE_MIGRATION_FAILED SAVE_RECOVERY_LOADED '
|
||||
'SAVE_RECOVERY_CANDIDATE_LOADED SAVE_RECOVERY_FAILED'.split())
|
||||
OPT_PATHS = frozenset(('autoload/simulation_runtime.gd', 'scripts/core/simulation_snapshot.gd',
|
||||
'scripts/world/world_service.gd', 'scripts/world/route_subslot_path_adapter.gd',
|
||||
'scripts/world/path_service.gd', 'scripts/core/command_queue.gd'))
|
||||
SOURCE_SHA = '651f703621c8ed06a724709f75d8bc05b1eef2988c3b3d5d3466096a3f759bf0'
|
||||
TOKEN = '{PRIVATE_USER_ROOT}/'
|
||||
|
||||
|
||||
def require(ok, message):
|
||||
if not ok:
|
||||
raise EvidenceError(message)
|
||||
|
||||
|
||||
def json_bytes(value):
|
||||
return json.dumps(value, ensure_ascii=False, separators=(',', ':'), allow_nan=False).encode('utf-8')
|
||||
|
||||
|
||||
def exact(a, b):
|
||||
return json_bytes(a) == json_bytes(b)
|
||||
|
||||
|
||||
def validate_tree(node):
|
||||
"""Validate all nodes; no application depth cutoff or value coercion."""
|
||||
pending = [node]
|
||||
while pending:
|
||||
n = pending.pop()
|
||||
require(type(n) is list and n and type(n[0]) is int, 'invalid typed node')
|
||||
t = n[0]
|
||||
require(t not in (23, 24, 25, 26) and 0 <= t <= 38, 'unsupported Variant type')
|
||||
require(len(n) == (1 if t == 0 else 3 if t in (27, 28) else 2), 'node arity')
|
||||
if t == 0:
|
||||
continue
|
||||
p = n[1]
|
||||
if t in (1, 2):
|
||||
require(type(p) is int and (p in (0, 1) if t == 1 else -(2**63) <= p < 2**63), 'integer payload')
|
||||
elif t == 3:
|
||||
require(type(p) is str and re.fullmatch('[0-9a-f]{16}', p), 'float must be f64 LE hex')
|
||||
elif t in (4, 21, 22):
|
||||
require(type(p) is str, 'string payload')
|
||||
elif t == 29:
|
||||
require(type(p) is str, 'byte array payload')
|
||||
try:
|
||||
require(base64.b64encode(base64.b64decode(p, validate=True)).decode() == p, 'noncanonical base64')
|
||||
except (ValueError, TypeError) as exc:
|
||||
raise EvidenceError('invalid base64') from exc
|
||||
elif t == 27:
|
||||
require(type(p) is list, 'dictionary entries')
|
||||
seen = set()
|
||||
for pair in p:
|
||||
require(type(pair) is list and len(pair) == 2, 'dictionary pair')
|
||||
key = json_bytes(pair[0])
|
||||
require(key not in seen, 'duplicate dictionary key')
|
||||
seen.add(key)
|
||||
pending.extend(pair)
|
||||
_typed_info(n[2], dictionary=True)
|
||||
elif t == 28:
|
||||
require(type(p) is list, 'array elements')
|
||||
_typed_info(n[2], dictionary=False)
|
||||
pending.extend(p)
|
||||
else:
|
||||
require(type(p) is list, 'component nodes')
|
||||
sizes = {5: 2, 6: 2, 7: 4, 8: 4, 9: 3, 10: 3, 11: 6,
|
||||
12: 4, 13: 4, 14: 4, 15: 4, 16: 6, 17: 9, 18: 12, 19: 16, 20: 4}
|
||||
if t in sizes:
|
||||
require(len(p) == sizes[t], 'component count')
|
||||
integer = t in (6, 8, 10, 13)
|
||||
require(all(x and x[0] == (2 if integer else 3) for x in p), 'component type')
|
||||
elif t in (30, 31, 32, 33, 34):
|
||||
expected = {30: 2, 31: 2, 32: 3, 33: 3, 34: 4}[t]
|
||||
require(all(x and x[0] == expected for x in p), 'packed element type')
|
||||
else:
|
||||
require(all(x and x[0] == {35: 5, 36: 9, 37: 20, 38: 12}[t] for x in p), 'packed vector type')
|
||||
pending.extend(p)
|
||||
return node
|
||||
|
||||
|
||||
def _typed_info(info, dictionary):
|
||||
# Metadata uses nodes too: builtin int, class StringName, script null.
|
||||
if info is None:
|
||||
return
|
||||
require(type(info) is list and len(info) == (2 if dictionary else 3), 'typed metadata')
|
||||
rows = info if dictionary else [info]
|
||||
for row in rows:
|
||||
require(type(row) is list and len(row) == 3, 'typed metadata row')
|
||||
for n in row:
|
||||
validate_tree(n)
|
||||
require(row[0][0] == 2 and row[1][0] == 21 and row[2] == [0], 'unsupported typed script metadata')
|
||||
|
||||
|
||||
def tree_sha(tree):
|
||||
validate_tree(tree)
|
||||
return hashlib.sha256(json_bytes(tree)).hexdigest()
|
||||
|
||||
|
||||
def _key_segment(key):
|
||||
return ['key', copy.deepcopy(key)]
|
||||
|
||||
|
||||
def _field(node, name):
|
||||
if node[0] != 27:
|
||||
return None
|
||||
found = [v for k, v in node[1] if k[0] in (4, 21) and k[1] == name]
|
||||
require(len(found) <= 1, 'ambiguous textual key: ' + name)
|
||||
return found[0] if found else None
|
||||
|
||||
|
||||
def _text(node):
|
||||
return node[1] if node and node[0] in (4, 21) else None
|
||||
|
||||
|
||||
def _at(tree, path):
|
||||
n = tree
|
||||
for segment in path:
|
||||
require(type(segment) is list and len(segment) == 2, 'path segment')
|
||||
kind, value = segment
|
||||
if kind == 'key':
|
||||
require(n[0] == 27, 'key path through non-dictionary')
|
||||
matches = [v for k, v in n[1] if exact(k, value)]
|
||||
require(len(matches) == 1, 'missing/ambiguous key path')
|
||||
n = matches[0]
|
||||
else:
|
||||
require(kind == 'index' and n[0] == 28 and type(value) is int and 0 <= value < len(n[1]), 'array path')
|
||||
n = n[1][value]
|
||||
return n
|
||||
|
||||
|
||||
def _put(tree, path, value):
|
||||
target = _at(tree, path)
|
||||
target[:] = copy.deepcopy(value)
|
||||
|
||||
|
||||
def apply_diff(tree, operations):
|
||||
result = copy.deepcopy(validate_tree(tree))
|
||||
require(type(operations) is list, 'diff operations')
|
||||
for op in operations:
|
||||
require(type(op) is dict and 'op' in op and type(op.get('path')) is list, 'diff operation')
|
||||
target = _at(result, op['path'])
|
||||
kind = op['op']
|
||||
if kind == 'set':
|
||||
require(set(op) == {'op', 'path', 'node'}, 'set fields')
|
||||
_put(result, op['path'], validate_tree(op['node']))
|
||||
elif kind == 'dict_insert':
|
||||
require(set(op) == {'op', 'path', 'index', 'key_node', 'value_node'}, 'insert fields')
|
||||
require(target[0] == 27 and type(op['index']) is int and 0 <= op['index'] <= len(target[1]), 'insert index')
|
||||
validate_tree(op['key_node']); validate_tree(op['value_node'])
|
||||
require(not any(exact(k, op['key_node']) for k, _ in target[1]), 'insert duplicate')
|
||||
target[1].insert(op['index'], copy.deepcopy([op['key_node'], op['value_node']]))
|
||||
elif kind == 'dict_remove':
|
||||
require(set(op) == {'op', 'path', 'key_node'} and target[0] == 27, 'remove fields')
|
||||
indexes = [i for i, (k, _) in enumerate(target[1]) if exact(k, op['key_node'])]
|
||||
require(len(indexes) == 1, 'remove missing key')
|
||||
target[1].pop(indexes[0])
|
||||
elif kind == 'array_splice':
|
||||
require(set(op) == {'op', 'path', 'start', 'delete_count', 'nodes'} and target[0] == 28, 'splice fields')
|
||||
start, count = op['start'], op['delete_count']
|
||||
require(type(start) is int and type(count) is int and 0 <= start <= len(target[1]) and 0 <= count <= len(target[1])-start, 'splice bounds')
|
||||
require(type(op['nodes']) is list, 'splice nodes')
|
||||
for n in op['nodes']:
|
||||
validate_tree(n)
|
||||
target[1][start:start+count] = copy.deepcopy(op['nodes'])
|
||||
else:
|
||||
raise EvidenceError('unknown diff operation')
|
||||
validate_tree(result)
|
||||
return result
|
||||
|
||||
|
||||
def reconstruct_checkpoints(checkpoints):
|
||||
"""Each checkpoint has S and latest transport records; verify before use."""
|
||||
require(type(checkpoints) is list and checkpoints, 'missing checkpoints')
|
||||
result, previous = [], None
|
||||
for cp in checkpoints:
|
||||
s = _transport(cp['S'], previous)
|
||||
latest = cp['latest']
|
||||
if latest.get('same_as_S') is True:
|
||||
require(set(latest) == {'same_as_S', 'tree_sha', 'raw_bytes_sha', 'roundtrip_ok'}, 'same_as_S fields')
|
||||
_proof(latest, s)
|
||||
require(latest['raw_bytes_sha'] == cp['S']['raw_bytes_sha'], 'same_as_S byte mismatch')
|
||||
l = copy.deepcopy(s)
|
||||
else:
|
||||
l = _transport(latest, s)
|
||||
result.append((s, l))
|
||||
previous = s
|
||||
return result
|
||||
|
||||
|
||||
def _proof(record, tree):
|
||||
require(record.get('roundtrip_ok') is True, 'Godot roundtrip missing/failed')
|
||||
require(type(record.get('raw_bytes_sha')) is str and re.fullmatch('[0-9a-f]{64}', record['raw_bytes_sha']), 'raw bytes SHA')
|
||||
require(record.get('tree_sha') == tree_sha(tree), 'tree SHA mismatch')
|
||||
|
||||
|
||||
def _transport(record, baseline):
|
||||
require(('tree' in record) != ('diff' in record), 'tree/diff exclusive')
|
||||
require(set(record) == {'tree' if 'tree' in record else 'diff', 'tree_sha', 'raw_bytes_sha', 'roundtrip_ok'}, 'transport fields')
|
||||
if 'tree' in record:
|
||||
tree = copy.deepcopy(record['tree'])
|
||||
else:
|
||||
require(baseline is not None, 'diff without baseline')
|
||||
tree = apply_diff(baseline, record['diff'])
|
||||
_proof(record, tree)
|
||||
return tree
|
||||
|
||||
|
||||
def compare_trees(a, b):
|
||||
validate_tree(a); validate_tree(b)
|
||||
differences, orders = [], []
|
||||
def diff(path, x, y):
|
||||
differences.append({'path': copy.deepcopy(path), 'a': copy.deepcopy(x), 'b': copy.deepcopy(y)})
|
||||
def walk(x, y, path):
|
||||
if exact(x, y):
|
||||
return
|
||||
if x[0] != y[0] or len(x) != len(y):
|
||||
diff(path, x, y); return
|
||||
t = x[0]
|
||||
if t in (27, 28) and not exact(x[2], y[2]):
|
||||
diff(path + [['metadata', 0]], x[2], y[2])
|
||||
if t == 27:
|
||||
def keyed(n):
|
||||
d = {}
|
||||
for k, v in n[1]:
|
||||
text = _key_text(k)
|
||||
require(text not in d, 'duplicate textual dictionary key')
|
||||
d[text] = (k, v)
|
||||
return d
|
||||
dx, dy = keyed(x), keyed(y)
|
||||
if set(dx) == set(dy) and [_key_text(k) for k, _ in x[1]] != [_key_text(k) for k, _ in y[1]]:
|
||||
orders.append(copy.deepcopy(path))
|
||||
for key in sorted(set(dx) | set(dy)):
|
||||
if key not in dx or key not in dy:
|
||||
diff(path + [['key', [4, key]]], dx.get(key), dy.get(key)); continue
|
||||
kx, vx = dx[key]; ky, vy = dy[key]
|
||||
p = path + [_key_segment(kx)]
|
||||
if not exact(kx, ky):
|
||||
diff(p + [['key_type', 0]], kx, ky)
|
||||
walk(vx, vy, p)
|
||||
elif t == 28 or t in range(5, 21) or t in range(30, 39):
|
||||
for i in range(max(len(x[1]), len(y[1]))):
|
||||
if i >= len(x[1]) or i >= len(y[1]):
|
||||
diff(path + [['index', i]], x[1][i] if i < len(x[1]) else None, y[1][i] if i < len(y[1]) else None)
|
||||
else:
|
||||
walk(x[1][i], y[1][i], path + [['index', i]])
|
||||
else:
|
||||
diff(path, x, y)
|
||||
walk(a, b, [])
|
||||
return {'equal': not differences, 'exact': exact(a, b), 'differences': differences, 'dict_order_paths': orders}
|
||||
|
||||
|
||||
def _key_text(key):
|
||||
"""Textual ordering never erases the original key node/type.
|
||||
|
||||
Non-string keys use a lossless textual transport spelling, avoiding any
|
||||
conversion of float bits or compound values to approximate decimal text.
|
||||
"""
|
||||
if key[0] in (4, 21, 22):
|
||||
return key[1]
|
||||
if key[0] == 2:
|
||||
return str(key[1])
|
||||
if key[0] == 1:
|
||||
return 'true' if key[1] else 'false'
|
||||
if key[0] == 0:
|
||||
return '<null>'
|
||||
return json_bytes(key).decode('utf-8')
|
||||
|
||||
|
||||
def _profile(profile_root):
|
||||
require(type(profile_root) is dict and set(profile_root) == {'root', 'actual_user_data_dir'}, 'guard-bound profile required')
|
||||
root = profile_root['root']
|
||||
require(type(root) is str and root.startswith('/') and root != '/' and not root.endswith('/') and '/..' not in root and '/./' not in root, 'profile root must be simplified absolute path')
|
||||
require(root == profile_root['actual_user_data_dir'], 'profile root/guard mismatch')
|
||||
return root
|
||||
|
||||
|
||||
def _marker(key, node):
|
||||
require(node[0] == 2 and node[1] >= 0, 'timing must be nonnegative int')
|
||||
return [27, [[[4, 'redacted_timing'], [4, key]], [[4, 'typeof'], [2, node[0]]]], None]
|
||||
|
||||
|
||||
def _normalize(trees, profile_root, events):
|
||||
root = _profile(profile_root)
|
||||
result = copy.deepcopy(trees)
|
||||
side = {'entries': [], 'violations': [], 'profile_root': {**profile_root, 'matches_guard': True}}
|
||||
def visit(n, path, event_index, permitted_payload=False, event_root=False):
|
||||
if n[0] == 27:
|
||||
if permitted_payload:
|
||||
require(_field(n, 'duration_us') is not None and _field(n, 'runtime_duration_us') is not None, 'save payload requires both timing fields')
|
||||
event_ok = (event_root and _text(_field(n, 'source_service')) == 'save_service' and _text(_field(n, 'event_type')) in SAVE_EVENTS)
|
||||
for k, v in n[1]:
|
||||
name = _text(k)
|
||||
p = path + [_key_segment(k)]
|
||||
if permitted_payload and name in ('duration_us', 'runtime_duration_us'):
|
||||
old = copy.deepcopy(v)
|
||||
v[:] = _marker(name, v)
|
||||
side['entries'].append({'event_index': event_index, 'path': p, 'key': name, 'original_node': old})
|
||||
elif permitted_payload and name == 'message' and v[0] == 4 and root + '/' in v[1]:
|
||||
require(TOKEN not in v[1], 'ambiguous preexisting root token')
|
||||
old = copy.deepcopy(v)
|
||||
v[1] = v[1].replace(root + '/', TOKEN)
|
||||
side['entries'].append({'event_index': event_index, 'path': p, 'key': name, 'original_node': old, 'root': root})
|
||||
else:
|
||||
if name and (name.endswith('_us') or name.endswith('_ms')):
|
||||
side['violations'].append({'event_index': event_index, 'path': p, 'kind': 'outside_timing', 'node': copy.deepcopy(v)})
|
||||
visit(v, p, event_index, event_ok and name == 'payload')
|
||||
# Keys are values too; they are never eligible for F1-F3.
|
||||
if k[0] in (4, 21) and root in k[1]:
|
||||
side['violations'].append({'event_index': event_index, 'path': p, 'kind': 'profile_in_key', 'node': copy.deepcopy(k)})
|
||||
elif n[0] == 28:
|
||||
for i, child in enumerate(n[1]):
|
||||
visit(child, path + [['index', i]], event_index)
|
||||
elif n[0] in (4, 21) and root in n[1]:
|
||||
side['violations'].append({'event_index': event_index, 'path': path, 'kind': 'outside_profile', 'node': copy.deepcopy(n)})
|
||||
for i, t in enumerate(result):
|
||||
validate_tree(t)
|
||||
pending = [t]
|
||||
while pending:
|
||||
node = pending.pop()
|
||||
if node[0] in (4, 21, 22):
|
||||
require(TOKEN not in node[1], 'reserved normalization token in raw/restored tree')
|
||||
elif node[0] == 27:
|
||||
for pair in node[1]:
|
||||
pending.extend(pair)
|
||||
elif node[0] == 28 or 5 <= node[0] <= 20 or 30 <= node[0] <= 38:
|
||||
pending.extend(node[1])
|
||||
if events:
|
||||
require(t[0] == 27, 'event dictionary required')
|
||||
visit(t, [], i, event_root=True)
|
||||
else:
|
||||
# Only the product recent_events location is eligible in snapshots.
|
||||
# Traverse everything for violations, enabling events solely there.
|
||||
_visit_snapshot(t, root, side, visit)
|
||||
return result, side
|
||||
|
||||
|
||||
def _visit_snapshot(tree, root, side, visit):
|
||||
permitted = ['systems', 'runtime', 'domain_events', 'recent_events']
|
||||
def walk(n, path, names):
|
||||
if names == permitted:
|
||||
require(n[0] == 28, 'recent_events array required')
|
||||
for i, event in enumerate(n[1]):
|
||||
visit(event, path + [['index', i]], None, event_root=True)
|
||||
return
|
||||
if n[0] == 27:
|
||||
for k, v in n[1]:
|
||||
name = _text(k)
|
||||
p = path + [_key_segment(k)]
|
||||
if name and (name.endswith('_us') or name.endswith('_ms')):
|
||||
side['violations'].append({'event_index': None, 'path': p, 'kind': 'outside_timing', 'node': copy.deepcopy(v)})
|
||||
walk(v, p, names + [name])
|
||||
elif n[0] == 28:
|
||||
for i, child in enumerate(n[1]):
|
||||
walk(child, path + [['index', i]], names + [i])
|
||||
elif n[0] in (4, 21) and root in n[1]:
|
||||
side['violations'].append({'event_index': None, 'path': path, 'kind': 'outside_profile', 'node': copy.deepcopy(n)})
|
||||
walk(tree, [], [])
|
||||
|
||||
|
||||
def normalize_events(events, profile_root):
|
||||
require(type(events) is list, 'event list required')
|
||||
return _normalize(events, profile_root, True)
|
||||
|
||||
|
||||
def normalize_tree(tree, profile_root):
|
||||
normalized, side = _normalize([tree], profile_root, False)
|
||||
return normalized[0], side
|
||||
|
||||
|
||||
def _restore(normalized, sidecar, profile_root, events):
|
||||
root = _profile(profile_root)
|
||||
require(type(sidecar) is dict and set(sidecar) == {'entries', 'violations', 'profile_root'}, 'sidecar fields')
|
||||
require(sidecar['profile_root'] == {**profile_root, 'matches_guard': True}, 'sidecar profile')
|
||||
require(type(sidecar['entries']) is list and type(sidecar['violations']) is list, 'sidecar lists')
|
||||
result = copy.deepcopy(normalized)
|
||||
seen = set()
|
||||
for entry in sidecar['entries']:
|
||||
require(set(entry) == {'event_index', 'path', 'key', 'original_node'} | ({'root'} if entry.get('key') == 'message' else set()), 'entry fields')
|
||||
index = entry['event_index']
|
||||
require((type(index) is int and 0 <= index < len(result)) if events else index is None, 'entry event index')
|
||||
identity = json_bytes([index, entry['path']])
|
||||
require(identity not in seen, 'duplicate sidecar entry')
|
||||
seen.add(identity)
|
||||
target = result[index] if events else result
|
||||
original = validate_tree(entry['original_node'])
|
||||
if entry['key'] == 'message':
|
||||
require(entry['root'] == root and original[0] == 4 and root+'/' in original[1] and TOKEN not in original[1], 'message sidecar')
|
||||
expected = [4, original[1].replace(root+'/', TOKEN)]
|
||||
else:
|
||||
require(entry['key'] in ('duration_us', 'runtime_duration_us'), 'outside closed list')
|
||||
expected = _marker(entry['key'], original)
|
||||
require(exact(_at(target, entry['path']), expected), 'sidecar does not match normalized node')
|
||||
_put(target, entry['path'], original)
|
||||
# Re-running the closed policy rejects missing entries and forged paths,
|
||||
# including attempts to normalize a violation. Raw tree SHA is also checked
|
||||
# by the caller against the independently retained transport proof.
|
||||
normal2, side2 = normalize_events(result, profile_root) if events else normalize_tree(result, profile_root)
|
||||
require(exact(normal2, normalized) and exact(side2, sidecar), 'non-reversible/unauthorized sidecar')
|
||||
return result
|
||||
|
||||
|
||||
def restore_events(normalized, sidecar, profile_root):
|
||||
return _restore(normalized, sidecar, profile_root, True)
|
||||
|
||||
|
||||
def restore_tree(normalized, sidecar, profile_root):
|
||||
return _restore(normalized, sidecar, profile_root, False)
|
||||
|
||||
|
||||
def check_source_closure(before_map, after_map, allowed_changed):
|
||||
require(type(before_map) is dict and type(after_map) is dict, 'source maps required')
|
||||
require(type(allowed_changed) in (list, set, frozenset, tuple), 'registered change set required')
|
||||
allowed = set(allowed_changed)
|
||||
errors = []
|
||||
for mapping in (before_map, after_map):
|
||||
for name, row in mapping.items():
|
||||
require(type(name) is str and type(row) is dict and set(row) == {'bytes', 'sha256'}, 'source row fields')
|
||||
require(type(row['bytes']) is int and row['bytes'] >= 0 and type(row['sha256']) is str and re.fullmatch('[0-9a-f]{64}', row['sha256']), 'source row values')
|
||||
digest = hashlib.sha256(json.dumps(before_map, sort_keys=True, separators=(',', ':')).encode()).hexdigest()
|
||||
if len(before_map) != 1407 or digest != SOURCE_SHA:
|
||||
errors.append('before map is not the frozen 1407-source map')
|
||||
if len(allowed) != len(allowed_changed) or not allowed <= OPT_PATHS:
|
||||
errors.append('unregistered allowed change set')
|
||||
added, missing = sorted(after_map.keys()-before_map.keys()), sorted(before_map.keys()-after_map.keys())
|
||||
changed = sorted(k for k in before_map.keys() & after_map.keys() if not exact(before_map[k], after_map[k]))
|
||||
if added or missing or set(changed) != allowed:
|
||||
errors.append('source closure mismatch')
|
||||
return {'ok': not errors, 'errors': errors, 'before_sha256': digest, 'added': added, 'missing': missing, 'changed': changed, 'allowed_changed': sorted(allowed)}
|
||||
|
||||
|
||||
K_COMPARE = frozenset(('absolute_minute', 'speed', 'paused', 'snapshot_version',
|
||||
'_accumulator', '_skip_next_process', '_pause_request_serial',
|
||||
'_abort_current_tick_requested', '_last_tick_advanced', '_phase_handlers'))
|
||||
C_COMPARE = frozenset(('_mvp_manifest_cache_generation', 'catalog_is_current', '_mvp_manifest_cache_bytes'))
|
||||
|
||||
|
||||
def compare_reports(a, b):
|
||||
"""Compare joined reports. Missing evidence fails, never defaults to zero.
|
||||
|
||||
Native admission/source closure is a separate mandatory S4 gate. This
|
||||
function compares report content, including all scenario outcomes, without
|
||||
converting an existing product failure into a harness failure or a PASS.
|
||||
"""
|
||||
out = {'ok': False, 'differences': [], 'dict_order_paths': [], 'excluded': [],
|
||||
'violations': [], 'digest_modes': [], 'errors': []}
|
||||
|
||||
def record(path, x, y):
|
||||
if not exact(x, y):
|
||||
out['differences'].append({'path': path, 'a': copy.deepcopy(x), 'b': copy.deepcopy(y)})
|
||||
|
||||
def excluded(path, reason, x, y):
|
||||
out['excluded'].append({'path': path, 'reason': reason, 'a': copy.deepcopy(x), 'b': copy.deepcopy(y)})
|
||||
|
||||
def trees(path, x, y, profiles):
|
||||
nx, sx = normalize_tree(x, profiles[0]); ny, sy = normalize_tree(y, profiles[1])
|
||||
require(tree_sha(restore_tree(nx, sx, profiles[0])) == tree_sha(x), 'a restore SHA')
|
||||
require(tree_sha(restore_tree(ny, sy, profiles[1])) == tree_sha(y), 'b restore SHA')
|
||||
sidecars(path, sx, sy)
|
||||
comparison(path, nx, ny)
|
||||
return sx, sy
|
||||
|
||||
def comparison(path, x, y):
|
||||
c = compare_trees(x, y)
|
||||
for row in c['differences']:
|
||||
out['differences'].append({**row, 'path': path + row['path']})
|
||||
out['dict_order_paths'].extend(path + p for p in c['dict_order_paths'])
|
||||
|
||||
def sidecars(path, x, y):
|
||||
# Compare semantic paths, not insertion indexes, including event IDs
|
||||
# in the separately compared event tree. Entry values are never metrics.
|
||||
identity = lambda e: json_bytes([e['event_index'], e['path'], e['key']])
|
||||
mx, my = {identity(e): e for e in x['entries']}, {identity(e): e for e in y['entries']}
|
||||
record(path + ['normalized_paths'], sorted(k.decode() for k in mx), sorted(k.decode() for k in my))
|
||||
for key in sorted(mx.keys() | my.keys()):
|
||||
ex, ey = mx.get(key), my.get(key)
|
||||
name = (ex or ey)['key']
|
||||
excluded(path + ['sidecar', key.decode()], 'private profile root' if name == 'message' else 'wall-clock timing', ex, ey)
|
||||
out['violations'].append({'path': path, 'a': x['violations'], 'b': y['violations']})
|
||||
|
||||
def layers(path, x, y):
|
||||
for n in (x['K'], y['K']):
|
||||
require(set(n) == K_COMPARE | {'performance_budget'}, 'K fields missing/unknown')
|
||||
require(set(n['performance_budget']) == {'_samples', '_totals', '_sample_counts'}, 'budget fields')
|
||||
require(type(n['_accumulator']) is str and re.fullmatch('[0-9a-f]{16}', n['_accumulator']), 'accumulator f64')
|
||||
counts = n['performance_budget']['_sample_counts']
|
||||
require(type(counts) is dict and all(type(v) is int and v >= 0 for v in counts.values()), 'metric sample counts')
|
||||
for field in sorted(K_COMPARE):
|
||||
vx, vy = x['K'][field], y['K'][field]
|
||||
if field == '_phase_handlers':
|
||||
require(type(vx) is dict and type(vy) is dict, 'phase handlers')
|
||||
def handlers(value):
|
||||
for ids in value.values():
|
||||
require(type(ids) is list and all(type(i) is str for i in ids) and len(set(ids)) == len(ids), 'handler IDs')
|
||||
return {p: sorted(ids) for p, ids in value.items()}
|
||||
vx, vy = handlers(vx), handlers(vy)
|
||||
# JSON object order is not semantic; typed state retains its order.
|
||||
if field == '_phase_handlers':
|
||||
vx, vy = sorted(vx.items()), sorted(vy.items())
|
||||
record(path + ['K', field], vx, vy)
|
||||
bx, by = x['K']['performance_budget'], y['K']['performance_budget']
|
||||
record(path + ['K', 'performance_budget', '_sample_counts'], sorted(bx['_sample_counts'].items()), sorted(by['_sample_counts'].items()))
|
||||
for field in ('_samples', '_totals'):
|
||||
excluded(path + ['K', 'performance_budget', field], 'wall-clock telemetry', bx[field], by[field])
|
||||
for n in (x['C'], y['C']):
|
||||
require(set(n) == C_COMPARE | {'catalog_instance_id', 'current_catalog_instance_id'}, 'C fields missing/unknown')
|
||||
require(type(n['catalog_is_current']) is bool, 'catalog identity flag')
|
||||
for field in sorted(C_COMPARE):
|
||||
record(path + ['C', field], x['C'][field], y['C'][field])
|
||||
for field in ('catalog_instance_id', 'current_catalog_instance_id'):
|
||||
excluded(path + ['C', field], 'process-local instance ID', x['C'][field], y['C'][field])
|
||||
|
||||
def scenario_facts(path, x, y):
|
||||
# Joined S3b facts carry lossless typed trees as well as JSON metadata.
|
||||
# Apply the same dictionary-order-only fallback to returned values.
|
||||
if isinstance(x, list) and isinstance(y, list) and x and y and type(x[0]) is int and type(y[0]) is int:
|
||||
validate_tree(x); validate_tree(y)
|
||||
comparison(path, x, y)
|
||||
elif isinstance(x, dict) and isinstance(y, dict):
|
||||
record(path + ['keys'], sorted(x), sorted(y))
|
||||
for key in sorted(set(x) & set(y)):
|
||||
scenario_facts(path + [key], x[key], y[key])
|
||||
elif isinstance(x, list) and isinstance(y, list):
|
||||
record(path + ['count'], len(x), len(y))
|
||||
for i, (left, right) in enumerate(zip(x, y)):
|
||||
scenario_facts(path + [i], left, right)
|
||||
else:
|
||||
record(path, x, y)
|
||||
|
||||
def checkpoints(path, xs, ys, profiles, main=False, ownership=False):
|
||||
if main:
|
||||
require(len(xs) == len(ys) == 31, 'B1 plus 30 ticks required')
|
||||
record(path + ['count'], len(xs), len(ys))
|
||||
tx, ty = reconstruct_checkpoints(xs), reconstruct_checkpoints(ys)
|
||||
for i, (x, y) in enumerate(zip(xs, ys)):
|
||||
p = path + [i]
|
||||
expected = {'minute', 'S', 'latest', 'latest_digest', 'computed_latest_digest', 'harness_normalized_digest', 'K', 'C', 'observation'}
|
||||
require(set(x) == expected and set(y) == expected, 'checkpoint fields')
|
||||
for cp in (x, y):
|
||||
require(type(cp['latest_digest']) is str and type(cp['computed_latest_digest']) is str, 'product digest type')
|
||||
# Only the immediately observed, intentional external E5 mutation
|
||||
# may expose cached-digest aliasing. Preserve it as a product fact.
|
||||
if not (ownership and i == 2):
|
||||
require(cp['latest_digest'] == cp['computed_latest_digest'], 'product digest self-consistency')
|
||||
obs = cp['observation']
|
||||
require(set(obs) == {'before', 'after'} and set(obs['before']) == set(obs['after']) == {'S', 'K', 'C'}, 'complete observation proof')
|
||||
require(all(type(v) is str and re.fullmatch('[0-9a-f]{64}', v) for v in list(obs['before'].values())+list(obs['after'].values())), 'observation bytes SHA')
|
||||
require(exact(obs['before'], obs['after']), 'observation mutated S/K/C')
|
||||
record(p + ['minute'], x['minute'], y['minute'])
|
||||
if main:
|
||||
require(x['minute'] == xs[0]['minute']+i and y['minute'] == ys[0]['minute']+i, 'checkpoint cadence')
|
||||
trees(p + ['S'], tx[i][0], ty[i][0], profiles)
|
||||
sx, sy = trees(p + ['latest'], tx[i][1], ty[i][1], profiles)
|
||||
if ownership and i == 2:
|
||||
record(p + ['digest_self_consistent'], x['latest_digest'] == x['computed_latest_digest'], y['latest_digest'] == y['computed_latest_digest'])
|
||||
if sx['entries'] or sy['entries']:
|
||||
excluded(p + ['computed_latest_digest'], 'E5 latest contains F1-F3; full normalized latest is compared', x['computed_latest_digest'], y['computed_latest_digest'])
|
||||
else:
|
||||
record(p + ['computed_latest_digest'], x['computed_latest_digest'], y['computed_latest_digest'])
|
||||
if sx['entries'] or sy['entries']:
|
||||
require(type(x['harness_normalized_digest']) is str and type(y['harness_normalized_digest']) is str, 'missing harness normalized digest')
|
||||
record(p + ['harness_normalized_digest'], x['harness_normalized_digest'], y['harness_normalized_digest'])
|
||||
excluded(p + ['latest_digest'], 'latest snapshot contains F1-F3 environment values', x['latest_digest'], y['latest_digest'])
|
||||
out['digest_modes'].append({'path': p, 'mode': 'harness normalized digest'})
|
||||
else:
|
||||
record(p + ['latest_digest'], x['latest_digest'], y['latest_digest'])
|
||||
out['digest_modes'].append({'path': p, 'mode': 'product latest_digest'})
|
||||
layers(p, x, y)
|
||||
|
||||
try:
|
||||
fields = {'schema', 'role', 'profile_root', 'checkpoints', 'events', 'event_start', 'event_end', 'signal_order', 'scenarios'}
|
||||
require(type(a) is dict and type(b) is dict and set(a) == fields and set(b) == fields, 'report fields missing/unknown')
|
||||
require(a['schema'] == b['schema'] == 'p28-02-eq/typed-v1', 'report schema')
|
||||
require(a['role'] in ('R', 'O') and b['role'] in ('R', 'O'), 'report role')
|
||||
record(['role'], a['role'], b['role'])
|
||||
profiles = (a['profile_root'], b['profile_root'])
|
||||
for profile in profiles:
|
||||
_profile(profile)
|
||||
for r in (a, b):
|
||||
require(set(r['event_start']) == {'counter', 'published_ids_count'}, 'event start fields')
|
||||
require(all(type(n) is int and n >= 0 for n in r['event_start'].values()), 'event counters')
|
||||
require(exact(a['event_start'], b['event_start']), 'event start counter/published_ids mismatch: correspondence invalid')
|
||||
record(['event_end'], a['event_end'], b['event_end'])
|
||||
record(['signal_order'], a['signal_order'], b['signal_order'])
|
||||
checkpoints(['checkpoints'], a['checkpoints'], b['checkpoints'], profiles, main=True)
|
||||
event_trees = []
|
||||
for r in (a, b):
|
||||
ts = []
|
||||
for i, e in enumerate(r['events']):
|
||||
require(set(e) == {'sequence', 'transport', 'original_field_types'} and e['sequence'] == i, 'event sequence/fields')
|
||||
ts.append(_transport(e['transport'], None))
|
||||
event_trees.append(ts)
|
||||
na, sa = normalize_events(event_trees[0], profiles[0]); nb, sb = normalize_events(event_trees[1], profiles[1])
|
||||
require(exact(restore_events(na, sa, profiles[0]), event_trees[0]) and exact(restore_events(nb, sb, profiles[1]), event_trees[1]), 'event restore proof')
|
||||
sidecars(['events'], sa, sb)
|
||||
record(['events', 'count'], len(na), len(nb))
|
||||
for i, (x, y) in enumerate(zip(na, nb)):
|
||||
comparison(['events', i], x, y)
|
||||
record(['events', i, 'original_field_types'], a['events'][i]['original_field_types'], b['events'][i]['original_field_types'])
|
||||
record(['scenarios', 'count'], len(a['scenarios']), len(b['scenarios']))
|
||||
for i, (x, y) in enumerate(zip(a['scenarios'], b['scenarios'])):
|
||||
require(set(x) == set(y) == {'id', 'operation', 'result', 'checkpoints', 'events'}, 'scenario fields')
|
||||
for key in ('id', 'operation', 'result', 'events'):
|
||||
# result preserves failures/path/value/ownership outcomes.
|
||||
# Scenario events use the same typed normalization below.
|
||||
if key != 'events':
|
||||
if key == 'result' and x['id'].startswith(('E4/', 'E5/')) and y['id'].startswith(('E4/', 'E5/')):
|
||||
scenario_facts(['scenarios', i, key], x[key], y[key])
|
||||
else:
|
||||
record(['scenarios', i, key], x[key], y[key])
|
||||
ownership_ids = {'E5/'+t+'/'+loc+'/outside_in' for t in ('create_snapshot', 'latest_snapshot', 'snapshot_published', 'state_updated') for loc in ('dict', 'array')}
|
||||
ownership = x['id'] == y['id'] and x['id'] in ownership_ids and x['operation'] == y['operation'] == 'outside_in' and len(x['checkpoints']) == len(y['checkpoints']) == 4
|
||||
checkpoints(['scenarios', i, 'checkpoints'], x['checkpoints'], y['checkpoints'], profiles, ownership=ownership)
|
||||
ex, sx = normalize_events(x['events'], profiles[0]); ey, sy = normalize_events(y['events'], profiles[1])
|
||||
sidecars(['scenarios', i, 'events'], sx, sy)
|
||||
record(['scenarios', i, 'events', 'count'], len(ex), len(ey))
|
||||
for j, (vx, vy) in enumerate(zip(ex, ey)):
|
||||
comparison(['scenarios', i, 'events', j], vx, vy)
|
||||
out['ok'] = not out['differences']
|
||||
except (EvidenceError, KeyError, TypeError, IndexError, ValueError) as exc:
|
||||
out['errors'].append(str(exc))
|
||||
return out
|
||||
|
||||
|
||||
def classify_improvement(before, after):
|
||||
"""SPEC §4: three actual run/PID values, no substituted markers."""
|
||||
import math
|
||||
require(len(before) == len(after) == 3, 'three values per version required')
|
||||
require(all(type(v) in (int, float) and math.isfinite(v) and v >= 0 for v in before+after), 'invalid measurement')
|
||||
return '改善' if max(after) < min(before) else '悪化' if min(after) > max(before) else '差は確認できない'
|
||||
|
||||
|
||||
def validate_scenario_paths(paths):
|
||||
"""D1: exact fixed relative names; no UUID/PID/time-generated paths."""
|
||||
allowed = {'user://p28_eq/'+role+'/'+name for role in ('r', 'o')
|
||||
for name in ('good', 'tampered_world', 'missing_key', 'wrong_type', 'out_of_range', 'duplicate_id')}
|
||||
require(type(paths) is list and all(type(p) is str and p in allowed for p in paths), 'non-fixed scenario path')
|
||||
return True
|
||||
@@ -0,0 +1,808 @@
|
||||
extends SceneTree
|
||||
## S3b external guarded probe. Native admission remains S4/Root.
|
||||
const FIXTURE_SHA: String = "eb4f770071eb07cd7e136fe54c3f78768cc8de7a4264e62a9af1f06a8f90f9bd"
|
||||
const K_FIELDS: Array = ["absolute_minute", "speed", "paused", "snapshot_version", "_skip_next_process", "_pause_request_serial", "_abort_current_tick_requested", "_last_tick_advanced"]
|
||||
var clock: Variant
|
||||
var runtime: Variant
|
||||
var main: Variant
|
||||
var role: String
|
||||
var report: Dictionary = {}
|
||||
var lifecycle: Dictionary = {"stage": "S3b", "errors": [], "preparation": [], "files": []}
|
||||
var previous_tree: Array = []
|
||||
var finished: bool = false
|
||||
var bound: bool = false
|
||||
var recording: bool = false
|
||||
var connected: bool = false
|
||||
var initial_inventory: Dictionary = {}
|
||||
var warm_signals: Array = []
|
||||
var scenario_active: bool = false
|
||||
var scenario_events: Array = []
|
||||
var scenario_signals: Array = []
|
||||
var b1_snapshot: Dictionary = {}
|
||||
var snapshot_reference: Dictionary = {}
|
||||
var state_reference: Dictionary = {}
|
||||
|
||||
func _initialize() -> void:
|
||||
call_deferred("begin")
|
||||
|
||||
func demand(ok: bool, message: String) -> bool:
|
||||
if not ok: lifecycle.errors.append(message)
|
||||
return ok
|
||||
|
||||
func hashed(bytes: PackedByteArray) -> String:
|
||||
var context: HashingContext = HashingContext.new()
|
||||
context.start(HashingContext.HASH_SHA256)
|
||||
context.update(bytes)
|
||||
return context.finish().hex_encode()
|
||||
|
||||
func json_text(value: Variant) -> String:
|
||||
return JSON.stringify(value, "", false, true)
|
||||
|
||||
func f64(value: float) -> String:
|
||||
var bytes: PackedByteArray = PackedByteArray()
|
||||
bytes.resize(8)
|
||||
bytes.encode_double(0, value)
|
||||
return bytes.hex_encode()
|
||||
|
||||
func typed_info(value: Variant) -> Variant:
|
||||
if typeof(value) == TYPE_ARRAY and value.is_typed():
|
||||
return [encode(value.get_typed_builtin()), encode(value.get_typed_class_name()), encode(value.get_typed_script())]
|
||||
if typeof(value) == TYPE_DICTIONARY and value.is_typed():
|
||||
return [[encode(value.get_typed_key_builtin()), encode(value.get_typed_key_class_name()), encode(value.get_typed_key_script())], [encode(value.get_typed_value_builtin()), encode(value.get_typed_value_class_name()), encode(value.get_typed_value_script())]]
|
||||
return null
|
||||
|
||||
func encode(value: Variant) -> Array:
|
||||
var t: int = typeof(value)
|
||||
match t:
|
||||
TYPE_NIL: return [0]
|
||||
TYPE_BOOL: return [1, 1 if value else 0]
|
||||
TYPE_INT: return [2, value]
|
||||
TYPE_FLOAT: return [3, f64(value)]
|
||||
TYPE_STRING, TYPE_STRING_NAME, TYPE_NODE_PATH: return [t, str(value)]
|
||||
TYPE_RID, TYPE_OBJECT, TYPE_CALLABLE, TYPE_SIGNAL:
|
||||
demand(false, "unsupported Variant in transport: " + str(t))
|
||||
return []
|
||||
TYPE_DICTIONARY:
|
||||
var pairs: Array = []
|
||||
for key: Variant in value: pairs.append([encode(key), encode(value[key])])
|
||||
return [27, pairs, typed_info(value)]
|
||||
TYPE_ARRAY:
|
||||
var children: Array = []
|
||||
for child: Variant in value: children.append(encode(child))
|
||||
return [28, children, typed_info(value)]
|
||||
TYPE_PACKED_BYTE_ARRAY: return [29, Marshalls.raw_to_base64(value)]
|
||||
var parts: Array = []
|
||||
match t:
|
||||
TYPE_VECTOR2, TYPE_VECTOR2I: parts = [value.x, value.y]
|
||||
TYPE_RECT2, TYPE_RECT2I: parts = [value.position.x, value.position.y, value.size.x, value.size.y]
|
||||
TYPE_VECTOR3, TYPE_VECTOR3I: parts = [value.x, value.y, value.z]
|
||||
TYPE_TRANSFORM2D: parts = [value.x.x, value.x.y, value.y.x, value.y.y, value.origin.x, value.origin.y]
|
||||
TYPE_VECTOR4, TYPE_VECTOR4I: parts = [value.x, value.y, value.z, value.w]
|
||||
TYPE_PLANE: parts = [value.normal.x, value.normal.y, value.normal.z, value.d]
|
||||
TYPE_QUATERNION: parts = [value.x, value.y, value.z, value.w]
|
||||
TYPE_AABB: parts = [value.position.x, value.position.y, value.position.z, value.size.x, value.size.y, value.size.z]
|
||||
TYPE_BASIS: parts = basis_parts(value)
|
||||
TYPE_TRANSFORM3D: parts = basis_parts(value.basis) + [value.origin.x, value.origin.y, value.origin.z]
|
||||
TYPE_PROJECTION:
|
||||
for column: int in range(4):
|
||||
for row: int in range(4): parts.append(value[column][row])
|
||||
TYPE_COLOR: parts = [value.r, value.g, value.b, value.a]
|
||||
_:
|
||||
if t >= TYPE_PACKED_INT32_ARRAY and t <= TYPE_PACKED_VECTOR4_ARRAY:
|
||||
for child: Variant in value: parts.append(child)
|
||||
else: demand(false, "unknown Variant type: " + str(t))
|
||||
var nodes: Array = []
|
||||
for part: Variant in parts: nodes.append(encode(part))
|
||||
return [t, nodes]
|
||||
|
||||
func basis_parts(value: Basis) -> Array:
|
||||
return [value.x.x, value.x.y, value.x.z, value.y.x, value.y.y, value.y.z, value.z.x, value.z.y, value.z.z]
|
||||
|
||||
func decode(node: Array) -> Variant:
|
||||
if node.is_empty():
|
||||
demand(false, "empty typed node")
|
||||
return null
|
||||
var t: int = node[0]
|
||||
if t == TYPE_NIL: return null
|
||||
var p: Variant = node[1]
|
||||
match t:
|
||||
TYPE_BOOL: return p == 1
|
||||
TYPE_INT: return int(p)
|
||||
TYPE_FLOAT: return String(p).hex_decode().decode_double(0)
|
||||
TYPE_STRING: return String(p)
|
||||
TYPE_STRING_NAME: return StringName(p)
|
||||
TYPE_NODE_PATH: return NodePath(p)
|
||||
TYPE_PACKED_BYTE_ARRAY: return Marshalls.base64_to_raw(p)
|
||||
TYPE_DICTIONARY:
|
||||
var result: Dictionary = {}
|
||||
if node[2] != null:
|
||||
var ki: Array = node[2][0]
|
||||
var vi: Array = node[2][1]
|
||||
result = Dictionary({}, decode(ki[0]), decode(ki[1]), decode(ki[2]), decode(vi[0]), decode(vi[1]), decode(vi[2]))
|
||||
for pair: Array in p: result[decode(pair[0])] = decode(pair[1])
|
||||
return result
|
||||
var values: Array = []
|
||||
for child: Array in p: values.append(decode(child))
|
||||
if t == TYPE_ARRAY:
|
||||
if node[2] != null:
|
||||
var info: Array = node[2]
|
||||
return Array(values, decode(info[0]), decode(info[1]), decode(info[2]))
|
||||
return values
|
||||
match t:
|
||||
TYPE_VECTOR2: return Vector2(values[0], values[1])
|
||||
TYPE_VECTOR2I: return Vector2i(values[0], values[1])
|
||||
TYPE_RECT2: return Rect2(values[0], values[1], values[2], values[3])
|
||||
TYPE_RECT2I: return Rect2i(values[0], values[1], values[2], values[3])
|
||||
TYPE_VECTOR3: return Vector3(values[0], values[1], values[2])
|
||||
TYPE_VECTOR3I: return Vector3i(values[0], values[1], values[2])
|
||||
TYPE_TRANSFORM2D: return Transform2D(Vector2(values[0], values[1]), Vector2(values[2], values[3]), Vector2(values[4], values[5]))
|
||||
TYPE_VECTOR4: return Vector4(values[0], values[1], values[2], values[3])
|
||||
TYPE_VECTOR4I: return Vector4i(values[0], values[1], values[2], values[3])
|
||||
TYPE_PLANE: return Plane(Vector3(values[0], values[1], values[2]), values[3])
|
||||
TYPE_QUATERNION: return Quaternion(values[0], values[1], values[2], values[3])
|
||||
TYPE_AABB: return AABB(Vector3(values[0], values[1], values[2]), Vector3(values[3], values[4], values[5]))
|
||||
TYPE_BASIS: return decoded_basis(values)
|
||||
TYPE_TRANSFORM3D: return Transform3D(decoded_basis(values), Vector3(values[9], values[10], values[11]))
|
||||
TYPE_PROJECTION: return Projection(Vector4(values[0], values[1], values[2], values[3]), Vector4(values[4], values[5], values[6], values[7]), Vector4(values[8], values[9], values[10], values[11]), Vector4(values[12], values[13], values[14], values[15]))
|
||||
TYPE_COLOR: return Color(values[0], values[1], values[2], values[3])
|
||||
TYPE_PACKED_INT32_ARRAY: return PackedInt32Array(values)
|
||||
TYPE_PACKED_INT64_ARRAY: return PackedInt64Array(values)
|
||||
TYPE_PACKED_FLOAT32_ARRAY: return PackedFloat32Array(values)
|
||||
TYPE_PACKED_FLOAT64_ARRAY: return PackedFloat64Array(values)
|
||||
TYPE_PACKED_STRING_ARRAY: return PackedStringArray(values)
|
||||
TYPE_PACKED_VECTOR2_ARRAY: return PackedVector2Array(values)
|
||||
TYPE_PACKED_VECTOR3_ARRAY: return PackedVector3Array(values)
|
||||
TYPE_PACKED_COLOR_ARRAY: return PackedColorArray(values)
|
||||
TYPE_PACKED_VECTOR4_ARRAY: return PackedVector4Array(values)
|
||||
demand(false, "unsupported decode type: " + str(t))
|
||||
return null
|
||||
|
||||
func decoded_basis(v: Array) -> Basis:
|
||||
return Basis(Vector3(v[0], v[1], v[2]), Vector3(v[3], v[4], v[5]), Vector3(v[6], v[7], v[8]))
|
||||
|
||||
func transport(value: Variant) -> Dictionary:
|
||||
var tree: Array = encode(value)
|
||||
var raw: PackedByteArray = var_to_bytes(value)
|
||||
var rebuilt: PackedByteArray = var_to_bytes(decode(tree))
|
||||
var ok: bool = raw == rebuilt
|
||||
demand(ok, "Godot typed tree byte roundtrip failed")
|
||||
return {"tree": tree, "tree_sha": hashed(json_text(tree).to_utf8_buffer()), "raw_bytes_sha": hashed(raw), "roundtrip_ok": ok}
|
||||
|
||||
func tree_diff(before: Array, after: Array, path: Array = []) -> Array:
|
||||
if json_text(before) == json_text(after): return []
|
||||
# Exact subtree replacement also preserves changes of insertion order and metadata.
|
||||
if before[0] != after[0] or before[0] not in [TYPE_DICTIONARY, TYPE_ARRAY] or json_text(before[2]) != json_text(after[2]):
|
||||
return [{"op": "set", "path": path, "node": after}]
|
||||
var changes: Array = []
|
||||
if before[0] == TYPE_DICTIONARY:
|
||||
var old_keys: Array = []
|
||||
var new_keys: Array = []
|
||||
for pair: Array in before[1]: old_keys.append(pair[0])
|
||||
for pair: Array in after[1]: new_keys.append(pair[0])
|
||||
if json_text(old_keys) != json_text(new_keys): return [{"op": "set", "path": path, "node": after}]
|
||||
for i: int in range(before[1].size()):
|
||||
changes.append_array(tree_diff(before[1][i][1], after[1][i][1], path + [["key", after[1][i][0]]]))
|
||||
else:
|
||||
if before[1].size() != after[1].size():
|
||||
return [{"op": "array_splice", "path": path, "start": 0, "delete_count": before[1].size(), "nodes": after[1]}]
|
||||
for i: int in range(before[1].size()): changes.append_array(tree_diff(before[1][i], after[1][i], path + [["index", i]]))
|
||||
return changes
|
||||
|
||||
func tree_at(tree: Array, path: Array) -> Array:
|
||||
var node: Array = tree
|
||||
for segment: Array in path:
|
||||
if segment[0] == "index": node = node[1][segment[1]]
|
||||
else:
|
||||
var found: bool = false
|
||||
for pair: Array in node[1]:
|
||||
if json_text(pair[0]) == json_text(segment[1]):
|
||||
node = pair[1]
|
||||
found = true
|
||||
break
|
||||
demand(found, "diff path missing")
|
||||
return node
|
||||
|
||||
func diff_record(record: Dictionary, baseline: Array) -> Dictionary:
|
||||
var operations: Array = tree_diff(baseline, record.tree)
|
||||
var replay: Array = baseline.duplicate(true)
|
||||
for op: Dictionary in operations:
|
||||
var target: Array = tree_at(replay, op.path)
|
||||
if op.op == "set":
|
||||
target.clear()
|
||||
target.append_array(op.node.duplicate(true))
|
||||
elif op.op == "array_splice":
|
||||
for unused: int in range(op.delete_count): target[1].remove_at(op.start)
|
||||
for i: int in range(op.nodes.size()): target[1].insert(op.start + i, op.nodes[i].duplicate(true))
|
||||
demand(json_text(replay) == json_text(record.tree), "diff roundtrip mismatch")
|
||||
return {"diff": operations, "tree_sha": record.tree_sha, "raw_bytes_sha": record.raw_bytes_sha, "roundtrip_ok": record.roundtrip_ok}
|
||||
|
||||
func kernel_state() -> Dictionary:
|
||||
var result: Dictionary = {}
|
||||
for key: String in K_FIELDS: result[key] = clock.get(key)
|
||||
result["_accumulator"] = f64(clock.get("_accumulator"))
|
||||
var ids: Dictionary = {}
|
||||
var handlers: Dictionary = clock.get("_phase_handlers")
|
||||
for phase: Variant in handlers:
|
||||
var names: Array = []
|
||||
for key: Variant in handlers[phase]: names.append(str(key))
|
||||
names.sort_custom(func(a: Variant, b: Variant) -> bool: return str(a) < str(b))
|
||||
ids[str(phase)] = names
|
||||
result["_phase_handlers"] = ids
|
||||
var budget: Variant = clock.get("performance_budget")
|
||||
var metrics: Dictionary = {}
|
||||
for key: String in ["_samples", "_totals", "_sample_counts"]: metrics[key] = budget.get(key).duplicate(true)
|
||||
result["performance_budget"] = metrics
|
||||
return result
|
||||
|
||||
func cache_state() -> Dictionary:
|
||||
var catalog: Variant = runtime.get("_mvp_manifest_cache_catalog")
|
||||
var current: Variant = runtime.get("mvp_content_catalog")
|
||||
return {"_mvp_manifest_cache_generation": runtime.get("_mvp_manifest_cache_generation"), "catalog_is_current": catalog == current,
|
||||
"_mvp_manifest_cache_bytes": Marshalls.raw_to_base64(var_to_bytes(runtime.get("_mvp_manifest_cache"))),
|
||||
"catalog_instance_id": str(catalog.get_instance_id()) if catalog != null else null, "current_catalog_instance_id": str(current.get_instance_id())}
|
||||
|
||||
func cache_filled() -> bool:
|
||||
var current: Variant = runtime.get("mvp_content_catalog")
|
||||
return runtime.get("_mvp_manifest_cache_catalog") == current and runtime.get("_mvp_manifest_cache_generation") == current.get_manifest_generation()
|
||||
|
||||
func prepare_cache(label: String) -> void:
|
||||
var before: Dictionary = cache_state()
|
||||
var filled: bool = cache_filled()
|
||||
if not filled: runtime.create_snapshot()
|
||||
lifecycle.preparation.append({"operation": "cache", "label": label, "before": before, "after": cache_state(), "filled_outside_observation": not filled})
|
||||
demand(cache_filled(), "cache preparation failed")
|
||||
|
||||
func layers() -> Dictionary:
|
||||
var k: Dictionary = kernel_state()
|
||||
var c: Dictionary = cache_state()
|
||||
var s: Dictionary = runtime.create_snapshot()
|
||||
var kb: PackedByteArray = var_to_bytes(k)
|
||||
var cb: PackedByteArray = var_to_bytes(c)
|
||||
demand(kb == var_to_bytes(kernel_state()), "state witness changed full K")
|
||||
demand(cb == var_to_bytes(cache_state()), "state witness changed full C")
|
||||
return {"snapshot": s, "K": k, "C": c, "s_bytes": var_to_bytes(s), "k_bytes": kb, "c_bytes": cb}
|
||||
|
||||
func witness(value: Dictionary) -> Dictionary:
|
||||
return {"S": hashed(value.s_bytes), "K": hashed(value.k_bytes), "C": hashed(value.c_bytes)}
|
||||
|
||||
func raw_layers(value: Dictionary) -> Dictionary:
|
||||
return {"sha": witness(value), "S": Marshalls.raw_to_base64(value.s_bytes), "K": Marshalls.raw_to_base64(value.k_bytes), "C": Marshalls.raw_to_base64(value.c_bytes), "kernel": value.K, "cache": value.C}
|
||||
|
||||
func checkpoint() -> void:
|
||||
var before: Dictionary = layers()
|
||||
var s: Dictionary = transport(runtime.create_snapshot())
|
||||
var latest_value: Dictionary = runtime.get("latest_snapshot")
|
||||
var latest: Dictionary = transport(latest_value)
|
||||
var latest_bytes: PackedByteArray = var_to_bytes(latest_value)
|
||||
var digest: String = runtime.get("latest_digest")
|
||||
var computed: String = SimulationDigest.compute(latest_value)
|
||||
var current_tree: Array = s.tree
|
||||
if not previous_tree.is_empty(): s = diff_record(s, previous_tree)
|
||||
if latest_bytes == before.s_bytes:
|
||||
latest = {"same_as_S": true, "tree_sha": latest.tree_sha, "raw_bytes_sha": latest.raw_bytes_sha, "roundtrip_ok": latest.roundtrip_ok}
|
||||
else: latest = diff_record(latest, current_tree)
|
||||
var after: Dictionary = layers()
|
||||
demand(before.s_bytes == after.s_bytes and before.k_bytes == after.k_bytes and before.c_bytes == after.c_bytes, "observation changed full S/K/C")
|
||||
demand(digest == computed, "latest digest self-consistency")
|
||||
var cp: Dictionary = {"minute": clock.absolute_minute, "S": s, "latest": latest, "latest_digest": digest, "computed_latest_digest": computed,
|
||||
"harness_normalized_digest": null, "K": before.K, "C": before.C, "observation": {"before": witness(before), "after": witness(after)}}
|
||||
# Python joins F1-F3 and the labelled normalized tree digest, retaining this raw record.
|
||||
var index: int = report.checkpoints.size()
|
||||
write_evidence("checkpoint-%02d.json" % index, cp)
|
||||
write_evidence("observation-%02d.json" % index, {"before": raw_layers(before), "after": raw_layers(after)})
|
||||
report.checkpoints.append(cp)
|
||||
previous_tree = current_tree
|
||||
|
||||
func event_counts() -> Dictionary:
|
||||
return {"counter": runtime.id_generator.get_counter(&"domain_event"), "published_ids_count": runtime.domain_events.get("_published_ids").size()}
|
||||
|
||||
func observe_event(event: Variant) -> void:
|
||||
if scenario_active:
|
||||
scenario_events.append(transport(event.to_dictionary()))
|
||||
return
|
||||
if not recording: return
|
||||
var value: Dictionary = event.to_dictionary()
|
||||
report.events.append({"sequence": report.events.size(), "transport": transport(value), "original_field_types": {
|
||||
"event_id": typeof(event.event_id), "event_type": typeof(event.event_type), "absolute_minute": typeof(event.absolute_minute), "source_service": typeof(event.source_service),
|
||||
"entity_ids": {"type": typeof(event.entity_ids), "typed_info": typed_info(event.entity_ids)},
|
||||
"payload": {"type": typeof(event.payload), "typed_info": typed_info(event.payload)}, "causation_command_id": typeof(event.causation_command_id)}})
|
||||
|
||||
func observe_snapshot(_snapshot: Dictionary, _digest: String) -> void:
|
||||
snapshot_reference = _snapshot
|
||||
record_signal("snapshot_published")
|
||||
|
||||
func observe_state(_snapshot: Dictionary) -> void:
|
||||
state_reference = _snapshot
|
||||
record_signal("state_updated")
|
||||
|
||||
func record_signal(name: String) -> void:
|
||||
var row: Dictionary = {"signal": name, "minute": clock.absolute_minute}
|
||||
if scenario_active: scenario_signals.append(row)
|
||||
elif recording: report.signal_order.append(row)
|
||||
else: warm_signals.append(row)
|
||||
|
||||
func inventory() -> Dictionary:
|
||||
var result: Dictionary = {}
|
||||
for sig: Signal in [runtime.snapshot_published, runtime.state_updated]:
|
||||
var rows: Array = []
|
||||
for connection: Dictionary in sig.get_connections():
|
||||
var callback: Callable = connection.callable
|
||||
rows.append({"object": str(callback.get_object_id()), "method": str(callback.get_method()), "flags": connection.flags})
|
||||
rows.sort_custom(func(a: Dictionary, b: Dictionary) -> bool: return json_text(a) < json_text(b))
|
||||
result[str(sig.get_name())] = rows
|
||||
var subscribers: Array = []
|
||||
var all_subscribers: Dictionary = runtime.domain_events.get("_subscribers")
|
||||
for event_type: Variant in all_subscribers:
|
||||
for id: Variant in all_subscribers[event_type]:
|
||||
var callback: Callable = all_subscribers[event_type][id]
|
||||
subscribers.append({"event_type": str(event_type), "id": str(id), "object": str(callback.get_object_id()), "method": str(callback.get_method())})
|
||||
subscribers.sort_custom(func(a: Dictionary, b: Dictionary) -> bool: return json_text(a) < json_text(b))
|
||||
result["subscribers"] = subscribers
|
||||
return result
|
||||
|
||||
func step() -> void:
|
||||
var before: int = clock.absolute_minute
|
||||
demand(clock.paused, "clock resumed")
|
||||
clock.advance_minutes(1)
|
||||
demand(clock.absolute_minute == before + 1 and clock.paused, "manual step failed")
|
||||
await process_frame
|
||||
demand(clock.absolute_minute == before + 1 and clock.paused, "inter-tick frame advanced clock")
|
||||
|
||||
func bind_profile() -> bool:
|
||||
var path: String = OS.get_environment("THE_TREE_PACK_PROFILE_REPORT")
|
||||
var file: FileAccess = FileAccess.open(path, FileAccess.READ)
|
||||
if not demand(file != null, "guard receipt missing"): return false
|
||||
var receipt: Variant = JSON.parse_string(file.get_as_text())
|
||||
file.close()
|
||||
if not demand(receipt is Dictionary and receipt.get("verified") == true, "guard receipt unverified"): return false
|
||||
var actual: Variant = receipt.get("actual_user_data_dir")
|
||||
var live_root: String = ProjectSettings.globalize_path("user://").simplify_path()
|
||||
if not demand(actual is String and actual == live_root and OS.get_user_data_dir() == actual, "live profile differs from guard actual_user_data_dir"): return false
|
||||
report["profile_root"] = {"root": live_root, "actual_user_data_dir": actual}
|
||||
lifecycle["guard"] = {"path": path, "sha256": FileAccess.get_sha256(path), "receipt": receipt, "live_root": live_root}
|
||||
bound = true
|
||||
return true
|
||||
|
||||
func write_evidence(name: String, value: Variant) -> void:
|
||||
if not demand(bound, "evidence write before guard binding"): return
|
||||
var directory: String = "user://evidence"
|
||||
var mkdir: int = DirAccess.make_dir_recursive_absolute(directory)
|
||||
if not demand(mkdir == OK, "evidence mkdir failed"): return
|
||||
var path: String = directory.path_join(name)
|
||||
if not demand(not FileAccess.file_exists(path), "refuse evidence overwrite: " + name): return
|
||||
var file: FileAccess = FileAccess.open(path, FileAccess.WRITE)
|
||||
if not demand(file != null, "evidence open failed: " + name): return
|
||||
var bytes: PackedByteArray = json_text(value).to_utf8_buffer()
|
||||
file.store_buffer(bytes)
|
||||
file.flush()
|
||||
var error: int = file.get_error()
|
||||
file.close()
|
||||
demand(error == OK, "evidence write failed: " + name)
|
||||
lifecycle.files.append({"path": "evidence/" + name, "bytes": bytes.size(), "sha256": hashed(bytes)})
|
||||
|
||||
func begin() -> void:
|
||||
clock = root.get_node("GameClock")
|
||||
runtime = root.get_node("SimulationRuntime")
|
||||
role = OS.get_environment("THE_TREE_EQ_ROLE")
|
||||
report = {"schema": "p28-02-eq/typed-v1", "role": role, "profile_root": null, "checkpoints": [], "events": [], "event_start": null, "event_end": null, "signal_order": [], "scenarios": []}
|
||||
if not demand(role in ["R", "O"], "unknown EQ role") or not bind_profile():
|
||||
finish()
|
||||
return
|
||||
# Stage 1: public preparation only. O retains the fresh 360-minute state.
|
||||
var k0: Dictionary = kernel_state()
|
||||
clock.set_paused(true)
|
||||
lifecycle.preparation.append({"operation": "initial_pause", "before": k0, "after": kernel_state()})
|
||||
if role == "R":
|
||||
var path: String = OS.get_environment("THE_TREE_P28_FIXTURE")
|
||||
if not demand(FileAccess.get_sha256(path) == FIXTURE_SHA, "fixture SHA mismatch"):
|
||||
finish()
|
||||
return
|
||||
var file: FileAccess = FileAccess.open(path, FileAccess.READ)
|
||||
if not demand(file != null, "fixture open failed"):
|
||||
finish()
|
||||
return
|
||||
var fixture: Variant = file.get_var(false)
|
||||
file.close()
|
||||
if not demand(fixture is Dictionary, "fixture is not Dictionary"):
|
||||
finish()
|
||||
return
|
||||
var restored: bool = runtime.restore_snapshot(fixture)
|
||||
lifecycle.preparation.append({"operation": "fixture_restore", "ok": restored, "input_sha256": FIXTURE_SHA, "K": kernel_state(), "C": cache_state()})
|
||||
demand(restored, "fixture restore failed")
|
||||
prepare_cache("restored")
|
||||
lifecycle["restored"] = raw_layers(layers())
|
||||
k0 = kernel_state()
|
||||
clock.set_paused(true)
|
||||
lifecycle.preparation.append({"operation": "restored_pause", "before": k0, "after": kernel_state()})
|
||||
prepare_cache("before_main")
|
||||
# Stage 2: same main and two deferred frames as DIAG, without controls/hooks.
|
||||
lifecycle["before_main"] = raw_layers(layers())
|
||||
main = load("res://scenes/main/main.tscn").instantiate()
|
||||
root.add_child(main)
|
||||
lifecycle["after_main"] = raw_layers(layers())
|
||||
await process_frame
|
||||
lifecycle["frame1"] = raw_layers(layers())
|
||||
await process_frame
|
||||
lifecycle["frame2"] = raw_layers(layers())
|
||||
var ops: Dictionary = main.get("_operations_start_report").duplicate(true)
|
||||
lifecycle["ops"] = ops
|
||||
lifecycle["save_policy"] = runtime.get_save_policy()
|
||||
demand(ops.get("code") == "INVALID_START_TIME" if role == "R" else ops.get("ok") == true, "unexpected main Ops result")
|
||||
demand(clock.paused and clock.absolute_minute == (602 if role == "R" else 360), "B0 clock")
|
||||
lifecycle["B0"] = raw_layers(layers())
|
||||
initial_inventory = inventory()
|
||||
runtime.snapshot_published.connect(observe_snapshot)
|
||||
runtime.state_updated.connect(observe_state)
|
||||
demand(runtime.domain_events.subscribe(&"*", &"p28_eq_observer", observe_event), "wildcard subscription failed")
|
||||
connected = true
|
||||
lifecycle["observer_before"] = initial_inventory
|
||||
lifecycle["observer_connected"] = inventory()
|
||||
# Stage 3: warm, excluded from E2; warm signal order is retained separately.
|
||||
for unused: int in range(30):
|
||||
if not lifecycle.errors.is_empty(): break
|
||||
await step()
|
||||
prepare_cache("B1")
|
||||
lifecycle["B1"] = raw_layers(layers())
|
||||
demand(clock.absolute_minute == (632 if role == "R" else 390), "B1 clock")
|
||||
lifecycle["measurement"] = {"probe_object": str(get_instance_id()), "connections": inventory(), "start_minute": clock.absolute_minute}
|
||||
report.event_start = event_counts()
|
||||
recording = true
|
||||
checkpoint()
|
||||
b1_snapshot = decode(report.checkpoints[0].S.tree).duplicate(true)
|
||||
# Stage 4: B1 and 30 exact checkpoints, uncapped events through the last frame.
|
||||
for unused: int in range(30):
|
||||
if not lifecycle.errors.is_empty(): break
|
||||
await step()
|
||||
checkpoint()
|
||||
report.event_end = event_counts()
|
||||
recording = false
|
||||
# Stage 5: E3 dedicated intervals, after measured event/signal closure.
|
||||
lifecycle["outside"] = raw_layers(layers())
|
||||
run_e3()
|
||||
run_e4()
|
||||
run_e5()
|
||||
finish()
|
||||
|
||||
func finish() -> void:
|
||||
if finished: return
|
||||
finished = true
|
||||
# Stage 6: restore observers, preserve every error.
|
||||
if connected:
|
||||
runtime.snapshot_published.disconnect(observe_snapshot)
|
||||
runtime.state_updated.disconnect(observe_state)
|
||||
runtime.domain_events.unsubscribe(&"*", &"p28_eq_observer")
|
||||
lifecycle["observer_disconnected"] = inventory()
|
||||
demand(json_text(initial_inventory) == json_text(lifecycle.observer_disconnected), "observer inventory not restored")
|
||||
lifecycle["warm_signals"] = warm_signals
|
||||
lifecycle["stop_reason"] = "S3b_complete_S4_pending" if lifecycle.errors.is_empty() else "failed"
|
||||
if bound:
|
||||
write_evidence("events.json", report.events)
|
||||
write_evidence("report.json", report)
|
||||
write_evidence("lifecycle.json", lifecycle.duplicate(true))
|
||||
print("P28_02_EQ_REPORT=" + json_text(report))
|
||||
if is_instance_valid(main): main.ui_audio_window_close_drained.connect(audio_close, CONNECT_ONE_SHOT)
|
||||
root.close_requested.emit()
|
||||
|
||||
func audio_close(result: Dictionary) -> void:
|
||||
write_evidence("audio-close.json", result)
|
||||
|
||||
func e3_observation() -> Dictionary:
|
||||
var before: Dictionary = layers()
|
||||
var s: Dictionary = transport(runtime.create_snapshot())
|
||||
var latest_value: Dictionary = runtime.get("latest_snapshot")
|
||||
var latest: Dictionary = transport(latest_value)
|
||||
var digest: String = runtime.get("latest_digest")
|
||||
var computed: String = SimulationDigest.compute(latest_value)
|
||||
var after: Dictionary = layers()
|
||||
demand(before.s_bytes == after.s_bytes and before.k_bytes == after.k_bytes and before.c_bytes == after.c_bytes, "E3 observation changed full S/K/C")
|
||||
var cp: Dictionary = {"minute": clock.absolute_minute, "S": s, "latest": latest, "latest_digest": digest, "computed_latest_digest": computed,
|
||||
"harness_normalized_digest": null, "K": before.K, "C": before.C, "observation": {"before": witness(before), "after": witness(after)}}
|
||||
return {"checkpoint": cp, "raw": {"before": raw_layers(before), "after": raw_layers(after)},
|
||||
"K_tree": transport(before.K), "C_tree": transport(before.C)}
|
||||
|
||||
func e3_input(kind: String) -> Dictionary:
|
||||
var value: Dictionary = b1_snapshot.duplicate(true)
|
||||
match kind:
|
||||
"missing_key": value.erase(&"clock")
|
||||
"wrong_type": value[&"clock"][&"absolute_minute"] = "x"
|
||||
"out_of_range": value[&"clock"][&"speed"] = 9
|
||||
"duplicate_published_ids":
|
||||
var ids: Array = value[&"systems"][&"runtime"][&"domain_events"]["published_ids"]
|
||||
if demand(not ids.is_empty(), "B1 has no published ID to duplicate"): ids.append(ids[0])
|
||||
"duplicate_facility":
|
||||
var instances: Array = value[&"systems"][&"runtime"][&"facilities"][&"instances"]
|
||||
if not instances.is_empty(): instances.append(instances[0].duplicate(true))
|
||||
return value
|
||||
|
||||
func e3_package(path: String) -> Dictionary:
|
||||
var files: Dictionary = {}
|
||||
for name: String in ["manifest.json", "world.bin", "thumbnail.png", "journal.log"]:
|
||||
var target: String = path.path_join(name)
|
||||
if not FileAccess.file_exists(target):
|
||||
files[name] = null
|
||||
continue
|
||||
var file: FileAccess = FileAccess.open(target, FileAccess.READ)
|
||||
if not demand(file != null, "package evidence open"): continue
|
||||
var bytes: PackedByteArray = file.get_buffer(file.get_length())
|
||||
file.close()
|
||||
files[name] = {"bytes": Marshalls.raw_to_base64(bytes), "sha256": hashed(bytes)}
|
||||
return files
|
||||
|
||||
func e3_prepare_package(path: String, input: Dictionary, kind: String) -> Dictionary:
|
||||
# This helper is called only within run_e3's explicitly opened interval.
|
||||
demand(scenario_active, "package preparation outside E3")
|
||||
var budget_before: Dictionary = {}
|
||||
for key: String in ["_samples", "_totals", "_sample_counts"]:
|
||||
budget_before[key] = SaveService._performance_budget.get(key).duplicate(true)
|
||||
var saved: Dictionary = SaveService.save_snapshot(path, input, {})
|
||||
var info: Dictionary = {"input": transport(input), "save_return": transport(saved), "original": e3_package(path), "budget_before": transport(budget_before)}
|
||||
if saved.get(&"ok") == true:
|
||||
if kind in ["missing_key", "wrong_type", "out_of_range"]:
|
||||
var manifest_path: String = path.path_join("manifest.json")
|
||||
var file: FileAccess = FileAccess.open(manifest_path, FileAccess.READ)
|
||||
if not demand(file != null, "manifest read"): return info
|
||||
var manifest: Dictionary = JSON.parse_string(file.get_as_text())
|
||||
file.close()
|
||||
match kind:
|
||||
"missing_key": manifest.erase("checksum_world")
|
||||
"wrong_type": manifest["format_version"] = "x"
|
||||
"out_of_range": manifest["format_version"] = 2147483647
|
||||
file = FileAccess.open(manifest_path, FileAccess.WRITE)
|
||||
if not demand(file != null, "manifest write"): return info
|
||||
file.store_string(json_text(manifest))
|
||||
file.close()
|
||||
elif kind == "tampered_world":
|
||||
var world_path: String = path.path_join("world.bin")
|
||||
var file: FileAccess = FileAccess.open(world_path, FileAccess.READ_WRITE)
|
||||
if not demand(file != null and file.get_length() > 0, "world tamper input"): return info
|
||||
var offset: int = file.get_length() / 2
|
||||
file.seek(offset)
|
||||
var old: int = file.get_8()
|
||||
file.seek(offset)
|
||||
file.store_8(old ^ 0x01)
|
||||
file.close()
|
||||
info["tamper"] = {"offset": offset, "before": old, "after": old ^ 0x01}
|
||||
info["modified"] = e3_package(path)
|
||||
return info
|
||||
|
||||
func run_e3() -> void:
|
||||
var facility_count: int = b1_snapshot[&"systems"][&"runtime"][&"facilities"][&"instances"].size()
|
||||
var kinds: Array = ["missing_key", "wrong_type", "out_of_range", "duplicate_published_ids", "duplicate_facility", "tampered_world"]
|
||||
lifecycle["e3"] = []
|
||||
lifecycle["e3_b1"] = transport(b1_snapshot)
|
||||
for api: String in ["restore_snapshot", "validate", "load_from_path"]:
|
||||
for kind: String in kinds:
|
||||
var id: String = "E3/" + api + "/" + kind
|
||||
var input: Dictionary = e3_input(kind)
|
||||
var applicable: bool = true
|
||||
var reason: Variant = null
|
||||
if kind == "tampered_world" and api != "load_from_path":
|
||||
applicable = false
|
||||
reason = "Dictionary API does not read packages"
|
||||
elif kind == "duplicate_facility" and facility_count == 0:
|
||||
demand(role == "O", "R B1 must contain a facility")
|
||||
applicable = false
|
||||
reason = "B1 has zero facilities"
|
||||
elif kind in ["duplicate_published_ids", "duplicate_facility"] and api == "validate":
|
||||
applicable = false
|
||||
reason = "Envelope validation does not inspect runtime internals"
|
||||
var relative: String = "duplicate_id" if kind.begins_with("duplicate_") else kind
|
||||
var path: String = "user://p28_eq/" + role.to_lower() + "/" + relative
|
||||
var before: Dictionary = e3_observation()
|
||||
var budget_before: Dictionary = {}
|
||||
for key: String in ["_samples", "_totals", "_sample_counts"]:
|
||||
budget_before[key] = SaveService._performance_budget.get(key).duplicate(true)
|
||||
scenario_events = []
|
||||
scenario_signals = []
|
||||
scenario_active = true
|
||||
var package: Variant = null
|
||||
var actual: Variant = null
|
||||
var invoked: bool = applicable or (api == "validate" and reason == "Envelope validation does not inspect runtime internals")
|
||||
var invocation_before: Dictionary = before
|
||||
if api == "load_from_path" and applicable:
|
||||
var package_input: Dictionary = input if kind.begins_with("duplicate_") else b1_snapshot.duplicate(true)
|
||||
package = e3_prepare_package(path, package_input, kind)
|
||||
var saved: Dictionary = decode(package.save_return.tree)
|
||||
if saved.get(&"ok") != true:
|
||||
demand(kind.begins_with("duplicate_"), "required package preparation refused")
|
||||
applicable = false
|
||||
invoked = false
|
||||
reason = "SaveService.save_snapshot refused duplicate input"
|
||||
invocation_before = e3_observation()
|
||||
# These are the only live E3 calls. No reset/repair of product state.
|
||||
if invoked:
|
||||
match api:
|
||||
"restore_snapshot": actual = runtime.restore_snapshot(input)
|
||||
"validate": actual = SimulationSnapshot.validate(input)
|
||||
"load_from_path": actual = runtime.load_from_path(path)
|
||||
if package != null: package["after_operation"] = e3_package(path)
|
||||
var after: Dictionary = e3_observation()
|
||||
scenario_active = false
|
||||
var code: Variant = null
|
||||
var code_reason: Variant = null
|
||||
var actual_ok: Variant = null
|
||||
var errors: Variant = null
|
||||
var migration: bool = false
|
||||
if api == "restore_snapshot":
|
||||
code_reason = "API returns bool only"
|
||||
actual_ok = actual
|
||||
elif api == "validate":
|
||||
code_reason = "API returns ok/errors only"
|
||||
if invoked:
|
||||
actual_ok = actual.get(&"ok")
|
||||
errors = actual.get(&"errors")
|
||||
elif invoked:
|
||||
code = actual.get(&"code")
|
||||
actual_ok = actual.get(&"ok")
|
||||
migration = actual.get(&"migration_attempted", false)
|
||||
demand(code != null, "load_from_path missing code")
|
||||
var event_trees: Array = []
|
||||
for event_record: Dictionary in scenario_events: event_trees.append(event_record.tree)
|
||||
var result: Dictionary = {"category": kind, "applicability": "applied" if applicable else "NA",
|
||||
"reason": reason, "invoked": invoked, "facility_count": facility_count, "ok": actual_ok, "errors": errors,
|
||||
"code": str(code) if code != null else null, "code_reason": code_reason, "migration_attempted": migration,
|
||||
"event_count": scenario_events.size(), "path": path if api == "load_from_path" else null}
|
||||
var scenario: Dictionary = {"id": id, "operation": api, "result": result,
|
||||
"checkpoints": [before.checkpoint, after.checkpoint], "events": event_trees}
|
||||
var budget_after: Dictionary = {}
|
||||
for key: String in ["_samples", "_totals", "_sample_counts"]:
|
||||
budget_after[key] = SaveService._performance_budget.get(key).duplicate(true)
|
||||
var evidence: Dictionary = {"id": id, "begin": before, "invocation_before": invocation_before, "end": after,
|
||||
"input": transport(input), "return": transport(actual), "package": package, "events": scenario_events,
|
||||
"signals": scenario_signals.duplicate(true), "latest_save_operation_result": transport(runtime.get("latest_save_operation_result")),
|
||||
"save_budget_before": transport(budget_before), "save_budget_after": transport(budget_after), "boundaries": ["begin", "operation", "end"]}
|
||||
report.scenarios.append(scenario)
|
||||
lifecycle.e3.append(evidence)
|
||||
write_evidence("e3-%02d.json" % (report.scenarios.size() - 1), evidence)
|
||||
|
||||
# S3b shares S3a's complete observation and transport; no state repair.
|
||||
func e45_emit(id: String, operation: String, observations: Array, detail: Dictionary) -> void:
|
||||
detail["signals"] = scenario_signals.duplicate(true)
|
||||
var cps: Array = []
|
||||
for observation: Dictionary in observations: cps.append(observation.checkpoint)
|
||||
var events: Array = []
|
||||
for event: Dictionary in scenario_events: events.append(event.tree)
|
||||
var result: Dictionary = {"event_count": events.size(), "applicability": detail.get("applicability", "applied"), "reason": detail.get("reason")}
|
||||
var facts: Dictionary = detail.duplicate(true)
|
||||
for key: String in ["package_before", "package_after", "save_return", "return", "save_budget_before", "save_budget_after", "latest_save_operation_result", "observation_before", "observation_after"]: facts.erase(key)
|
||||
if detail.has("return"):
|
||||
var actual: Variant = decode(detail["return"].tree)
|
||||
facts["return_fact"] = {"ok": actual.get(&"ok"), "code": actual.get(&"code")} if actual is Dictionary else actual
|
||||
if facts.has("trials"):
|
||||
for trial: Dictionary in facts.trials:
|
||||
trial.erase("before")
|
||||
trial.erase("after")
|
||||
result["facts"] = facts
|
||||
var evidence: Dictionary = {"id": id, "boundaries": ["begin", "operation", "end"], "observations": observations,
|
||||
"events": scenario_events.duplicate(true), "signals": scenario_signals.duplicate(true), "detail": detail}
|
||||
report.scenarios.append({"id": id, "operation": operation, "result": result, "checkpoints": cps, "events": events})
|
||||
lifecycle.e45.append(evidence)
|
||||
write_evidence("e45-%02d.json" % (lifecycle.e45.size() - 1), evidence)
|
||||
|
||||
func e4_candidates() -> Dictionary:
|
||||
demand(scenario_active, "candidate search outside E4")
|
||||
var before: Dictionary = e3_observation()
|
||||
var raw_ids: Array = runtime.definition_registry.get_facility_ids()
|
||||
var ids: Array = raw_ids.duplicate()
|
||||
ids.sort_custom(func(a: Variant, b: Variant) -> bool: return str(a) < str(b))
|
||||
var bounds: Dictionary = runtime.world_service.get_bounds()
|
||||
var selection: Dictionary = {"source": "definition_registry.get_facility_ids()", "raw_ids": transport(raw_ids), "count": raw_ids.size(),
|
||||
"sorted_ids": transport(ids), "sort_rule": "String(id) ascending Unicode code point", "bounds": transport(bounds),
|
||||
"cell_rule": "inclusive x/y public bounds; z FRONT=0 through BACK=1; x,y,z lexical; ID outer; rotation=0",
|
||||
"trials": [], "chosen": null, "applicability": "applied", "reason": null, "observation_before": before}
|
||||
if not demand(not ids.is_empty(), "empty facility registry"):
|
||||
selection.applicability = "failure"
|
||||
selection.reason = "empty facility registry"
|
||||
selection["observation_after"] = e3_observation()
|
||||
return selection
|
||||
for definition_id: StringName in ids:
|
||||
for x: int in range(bounds[&"min_x"], bounds[&"max_x"] + 1):
|
||||
for y: int in range(bounds[&"min_y"], bounds[&"max_y"] + 1):
|
||||
for z: int in range(0, 2):
|
||||
var origin: Vector3i = Vector3i(x, y, z)
|
||||
var preview: Dictionary = runtime.preview_build_facility(definition_id, origin, 0)
|
||||
var candidate: Dictionary = {"definition_id": definition_id, "origin": origin, "rotation": 0}
|
||||
selection.trials.append({"candidate": transport(candidate), "preview": transport(preview)})
|
||||
if preview.get(&"can_build") == true:
|
||||
selection.chosen = transport(candidate)
|
||||
selection["observation_after"] = e3_observation()
|
||||
demand(json_text(before.raw) == json_text(selection.observation_after.raw), "preview search mutated S/K/C")
|
||||
return selection
|
||||
selection.applicability = "NA"
|
||||
selection.reason = "all registry/cell pairs rejected by public preview"
|
||||
selection["observation_after"] = e3_observation()
|
||||
demand(json_text(before.raw) == json_text(selection.observation_after.raw), "preview search mutated S/K/C")
|
||||
return selection
|
||||
|
||||
func run_e4() -> void:
|
||||
lifecycle["e45"] = []
|
||||
for operation: String in ["build_facility", "tick", "restore_snapshot", "load_from_path", "rejected_command"]:
|
||||
var observations: Array = [e3_observation()]
|
||||
var detail: Dictionary = {}
|
||||
var save_budget_before: Dictionary = e45_save_budget()
|
||||
scenario_events = []
|
||||
scenario_signals = []
|
||||
scenario_active = true
|
||||
if operation == "build_facility":
|
||||
detail = e4_candidates()
|
||||
if detail.chosen != null:
|
||||
var payload: Dictionary = decode(detail.chosen.tree)
|
||||
var submitted: Variant = runtime.submit_command(&"build_facility", payload)
|
||||
detail["submit"] = transport(submitted.to_dictionary())
|
||||
observations.append(e3_observation())
|
||||
clock.advance_minutes(1)
|
||||
var completed: Variant = runtime.command_queue.get_processed_result(submitted.command_id)
|
||||
detail["command_result"] = transport(completed.to_dictionary() if completed != null else null)
|
||||
elif operation == "tick":
|
||||
clock.advance_minutes(1)
|
||||
elif operation == "restore_snapshot":
|
||||
var input: Dictionary = runtime.create_snapshot().duplicate(true)
|
||||
detail["input"] = transport(input)
|
||||
detail["return"] = transport(runtime.restore_snapshot(input))
|
||||
elif operation == "load_from_path":
|
||||
var input: Dictionary = runtime.create_snapshot().duplicate(true)
|
||||
var path: String = "user://p28_eq/" + role.to_lower() + "/good"
|
||||
detail["input"] = transport(input)
|
||||
detail["path"] = path
|
||||
var saved: Dictionary = SaveService.save_snapshot(path, input, {})
|
||||
detail["save_return"] = transport(saved)
|
||||
detail["package_before"] = e3_package(path)
|
||||
demand(saved.get(&"ok") == true, "E4 good package save failed")
|
||||
detail["return"] = transport(runtime.load_from_path(path))
|
||||
detail["latest_save_operation_result"] = transport(runtime.get("latest_save_operation_result"))
|
||||
detail["package_after"] = e3_package(path)
|
||||
elif operation == "rejected_command":
|
||||
var submitted: Variant = runtime.submit_command(&"build_facility", {&"definition_id": ""})
|
||||
detail["submit"] = transport(submitted.to_dictionary())
|
||||
observations.append(e3_observation())
|
||||
clock.advance_minutes(1)
|
||||
var completed: Variant = runtime.command_queue.get_processed_result(submitted.command_id)
|
||||
detail["command_result"] = transport(completed.to_dictionary() if completed != null else null)
|
||||
detail["save_budget_before"] = save_budget_before
|
||||
detail["save_budget_after"] = e45_save_budget()
|
||||
observations.append(e3_observation())
|
||||
scenario_active = false
|
||||
e45_emit("E4/" + operation, operation, observations, detail)
|
||||
|
||||
func e45_save_budget() -> Dictionary:
|
||||
var budget: Dictionary = {}
|
||||
for key: String in ["_samples", "_totals", "_sample_counts"]:
|
||||
budget[key] = SaveService._performance_budget.get(key).duplicate(true)
|
||||
return transport(budget)
|
||||
|
||||
func run_e5() -> void:
|
||||
for target: String in ["create_snapshot", "latest_snapshot", "snapshot_published", "state_updated"]:
|
||||
for location: String in ["dict", "array"]:
|
||||
for direction: String in ["outside_in", "inside_out"]:
|
||||
var observations: Array = [e3_observation()]
|
||||
scenario_events = []
|
||||
scenario_signals = []
|
||||
scenario_active = true
|
||||
# Explicit preparation tick refreshes signal references and starts a new baseline.
|
||||
clock.advance_minutes(1)
|
||||
var baseline: Dictionary = e3_observation()
|
||||
observations.append(baseline)
|
||||
var returned: Dictionary = {}
|
||||
match target:
|
||||
"create_snapshot": returned = runtime.create_snapshot()
|
||||
"latest_snapshot": returned = runtime.get("latest_snapshot")
|
||||
"snapshot_published": returned = snapshot_reference
|
||||
"state_updated": returned = state_reference
|
||||
var held_copy: Dictionary = returned.duplicate(true)
|
||||
var detail: Dictionary = {"target": target, "location": location, "direction": direction,
|
||||
"digest_materialized_before": true, "held_before": transport(held_copy)}
|
||||
if direction == "outside_in":
|
||||
if location == "dict":
|
||||
returned[&"systems"][&"runtime"][&"id_generator"][&"counters"]["__p28_eq_probe"] = 1
|
||||
else:
|
||||
returned[&"systems"][&"runtime"][&"domain_events"]["published_ids"].append("__p28_eq_probe")
|
||||
else:
|
||||
clock.advance_minutes(1)
|
||||
observations.append(e3_observation())
|
||||
detail["held_after"] = transport(returned)
|
||||
# Reset only through the authorized next tick, retaining the post-mutation state.
|
||||
clock.advance_minutes(1)
|
||||
observations.append(e3_observation())
|
||||
scenario_active = false
|
||||
e45_emit("E5/" + target + "/" + location + "/" + direction, direction, observations, detail)
|
||||
|
||||
@@ -0,0 +1,273 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Root-only EQ driver. --check neither writes nor starts processes other than read-only host/Git queries."""
|
||||
import argparse
|
||||
import importlib.util
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import uuid
|
||||
|
||||
sys.dont_write_bytecode = True
|
||||
import check_eq as check
|
||||
import compare_versions as eq
|
||||
import verify_eq as verify
|
||||
|
||||
HERE, ROOT = verify.HERE, verify.ROOT
|
||||
BASE = 'docs/plans/original-completion-2026-10-02/execution/'
|
||||
COLLECTOR = BASE + 'p28-01/collector/collect_p28_01.py'
|
||||
DEPENDENCIES = {
|
||||
'tools/run_all_tests.py': '320ca668732b4ff72fc4449998af2327d4e5c527b06896740806aaf0487282b4',
|
||||
'tools/regression/owned_outer.py': 'c2e3483b76db1a3ff940f23f88ea0083fc78736e874ebcdb385d766dde8866e7',
|
||||
'tools/regression/owned_diagnostic_process.py': 'e31e93c6e2c5ea46a7d954ef8bc0b4caec1c08b86b8aef19e93b52ef24993087',
|
||||
'tools/regression/p09_owned_engine_process.py': 'c007e712c281573254faa1233c2ac92e100ab87393256a6dc096b35283e43037',
|
||||
COLLECTOR: 'a43e1f963ef8505ddd5acf8bf747d9bfac22a028cbb805c0b964ee11b9b40a14',
|
||||
BASE + 'p28-01/collector/check_p28_01_report.py': '6c0851d498ca80bdc120fad047b072255f48713f63114521f3d4dfc902b2512b',
|
||||
BASE + 'p28-02/diag/diag_probe.gd': '4124067d4b193693f696d2b1a1e6eb56731948cfefd5a6e420b5c9a14fb2b11e',
|
||||
BASE + 'p28-02/diag/verify_diag.py': '829354804f0ebb152a8092486ccadbc6b36143a5c9187dac75c15f90b70d1fb9',
|
||||
BASE + 'p28-02/diag/test_diag.py': '744b779f4b2452e0c1660c6fd1aa009d26e7315e8a0fddd669a2ac3e261c61b4',
|
||||
BASE + 'p28-02/diag/diag_p28_02.py': '6b47d08b490ba742ce00e8835a09011c5966d0a8fc7b578498bfc80bc03f14ed',
|
||||
BASE + 'p28-02/diag/check_diag.py': '96dd9bef220339d6a973215d8db9a73c1bfa44f9e151bcf897641882e831b5ba',
|
||||
}
|
||||
FROZEN = {
|
||||
'SPEC.md': '3791ccdcb87e8d71fe9205e1e692ebca9e0f974ea3b5fbc4fbb3943882131f1c',
|
||||
'TASK_INSTRUCTIONS.md': 'f9937c3c7dff5a25ada453365d26c87fecf009d29518724f0c1e67d2b18afff3',
|
||||
'references/OPT_CONTRACT_T1.md': 'ad9f3d76f3500b39263fb898d7c64588b4b47c9e11b456f938195261fd054d16',
|
||||
'references/OPUS_D2_SCOPE_CLARIFICATION.txt': '5775e7b512d9e90dbcfbcb181f5b64dc0fa8207e0947c0a4a6a5c9195565f9bd',
|
||||
'references/OPUS_STARTUP_LIFECYCLE_CLARIFICATION.txt': '967aebf27ff412f7a16ce771ef7d68abf8cfde0bb76ed19cf6dbf2817ca7acc6',
|
||||
'registration/ACCEPTANCE_BASELINE.json': '84628bc21205387f8a7143031bdc50c9f68a767d350e6c34b32e0ba1c7059337',
|
||||
'registration/CONFIG_PROPOSAL.json': '775fbbb97cda8b4d4991defdf7871b0fc79f489f4dea34c1733d4830426cf1df',
|
||||
'registration/REGISTRATION_PROPOSAL.json': '9590fc853a4df8d50cc0d269d23bd9c844dc6931590ff6f24ebf95bb54a8d135',
|
||||
'registration/ROOT_PROPOSAL_BYTE_TRANSFER.json': '63197f650849084f769e487a76458361886a37090042f1e351851c75b0384da2',
|
||||
}
|
||||
require, sha, pin, write = verify.require, verify.sha, verify.pin, verify.write
|
||||
|
||||
|
||||
def load_dependencies(root=ROOT):
|
||||
root = Path(root).resolve()
|
||||
for name, expected in DEPENDENCIES.items():
|
||||
require(sha(root / name) == expected, 'dependency pin: ' + name)
|
||||
local = root / HERE.relative_to(ROOT)
|
||||
for name in verify.LOCAL_NAMES - {'eq_probe.gd'}:
|
||||
check.check_python_imports((local / name).read_text())
|
||||
def load(relative, module_name):
|
||||
require(relative in DEPENDENCIES and relative.endswith('.py'), 'import outside closure')
|
||||
spec = importlib.util.spec_from_file_location(module_name, root / relative)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
sys.modules[module_name] = module
|
||||
spec.loader.exec_module(module)
|
||||
return module
|
||||
# Import sibling dependencies under their real names before the collector.
|
||||
load(BASE + 'p28-01/collector/check_p28_01_report.py', 'check_p28_01_report')
|
||||
collector = load(COLLECTOR, 'eq_collector')
|
||||
diag = load(BASE + 'p28-02/diag/check_diag.py', 'eq_diag_check')
|
||||
for name in diag.DEPENDENCIES:
|
||||
diag.check_imports((root / name).read_text(), external=name)
|
||||
standard = collector.load_tool(collector.EXTERNAL_IMPORTS[0])
|
||||
outer = collector.load_tool(collector.EXTERNAL_IMPORTS[1])
|
||||
require(Path(outer.native.helper['__file__']).resolve() == root / 'tools/regression/p09_owned_engine_process.py', 'helper closure')
|
||||
for module in [collector, standard, outer, outer.native, *list(sys.modules.values())]:
|
||||
name = getattr(module, '__file__', None)
|
||||
if name:
|
||||
path = Path(name).resolve()
|
||||
if path.is_relative_to(root):
|
||||
require(path.relative_to(root).as_posix() in DEPENDENCIES or path.is_relative_to(local), 'loaded module outside closure')
|
||||
return collector, standard, outer, diag
|
||||
|
||||
|
||||
def actual_pins(root, readonly, fixture, engine, collector, standard):
|
||||
local = root / HERE.relative_to(ROOT)
|
||||
dependencies = {n: sha(root / n) for n in DEPENDENCIES}
|
||||
require(dependencies == DEPENDENCIES, 'dependencies changed')
|
||||
frozen = {n: sha(local / n) for n in FROZEN}
|
||||
require(frozen == FROZEN, 'frozen specification changed')
|
||||
source = collector.source_map(standard, root)
|
||||
require(len(source) == 1407 and collector.digest(source) == eq.SOURCE_SHA, 'full 1407 source pin')
|
||||
require(sha(fixture) == collector.FIXTURE_SHA and sha(engine) == collector.ENGINE_SHA, 'fixture/engine pin')
|
||||
inputs = collector.inputs(readonly)
|
||||
require(len(inputs['files']) == 9, 'nine original destinations required')
|
||||
manifest = verify.read(readonly / 'ROOT_INPUT_MANIFEST.json')
|
||||
require(len(manifest['files']) == 9 and len({r['destination'] for r in manifest['files']}) == 9, 'nine unique destinations')
|
||||
require(sys.platform == 'darwin', 'native platform')
|
||||
machine = subprocess.check_output(['sysctl', '-n', 'hw.model'], text=True).strip()
|
||||
require(machine == 'Mac16,10', 'machine pin')
|
||||
return {'source': source, 'source_sha256': collector.digest(source), 'dependencies': dependencies,
|
||||
'frozen': frozen, 'worker': {n: sha(local / n) for n in sorted(verify.LOCAL_NAMES)},
|
||||
'fixture': pin(fixture), 'engine': pin(engine), 'engine_version': collector.VERSION,
|
||||
'project': source['project.godot'], 'readonly': inputs, 'original_manifest': manifest,
|
||||
'machine': machine, 'platform': sys.platform}
|
||||
|
||||
|
||||
def frozen_commit(source):
|
||||
commit = subprocess.check_output(['git', '-C', str(ROOT), 'rev-parse', 'HEAD'], text=True).strip()
|
||||
for name in list(source) + [str((HERE / n).relative_to(ROOT)) for n in verify.LOCAL_NAMES]:
|
||||
data = subprocess.check_output(['git', '-C', str(ROOT), 'show', commit + ':' + name])
|
||||
require(data == (ROOT / name).read_bytes(), 'not frozen S: ' + name)
|
||||
return commit
|
||||
|
||||
|
||||
def wrapper_text(out):
|
||||
return ('extends ' + json.dumps(str(out / 'eq_probe.gd')) + '\nconst Guard = preload(' +
|
||||
json.dumps(str(out / 'profile_guard.gd')) + ')\nfunc _initialize() -> void:\n'
|
||||
'\tif not Guard.activate():\n\t\tquit(97)\n\t\treturn\n\tsuper._initialize()\n')
|
||||
|
||||
|
||||
def plan(collector, standard, engine, fixture, out):
|
||||
stage, wrapper = out / 'stage', out / 'guarded.gd'
|
||||
commands = [collector.argv_for(engine, stage, wrapper, importing=True),
|
||||
collector.parse_argv(engine, stage, out / 'eq_probe.gd'),
|
||||
collector.parse_argv(engine, stage, wrapper)] + [
|
||||
[str(engine), '--headless', '--path', str(stage), '--script', str(wrapper)] for _ in range(4)]
|
||||
rows = []
|
||||
for phase, command in zip(verify.PHASES, commands):
|
||||
startup_name = 'TheTree-PCK-tests-' + uuid.uuid4().hex + '-eq-startup'
|
||||
runtime_name = 'TheTree-PCK-tests-' + uuid.uuid4().hex + '-eq-runtime'
|
||||
startup, runtime = standard.profile_path(startup_name), standard.profile_path(runtime_name)
|
||||
require(not startup.exists() and not runtime.exists(), 'fresh profiles required')
|
||||
role = verify.ROLES.get(phase)
|
||||
env = {'THE_TREE_PACK_PROFILE_NAME': runtime_name, 'THE_TREE_PACK_PROFILE_EXPECTED': str(runtime),
|
||||
'THE_TREE_PACK_PROFILE_REPORT': str(out / (phase + '-guard.json')),
|
||||
'THE_TREE_EQ_ROLE': role or '', 'THE_TREE_P28_FIXTURE': str(fixture),
|
||||
'THE_TREE_P28_FIXTURE_SHA': collector.FIXTURE_SHA}
|
||||
rows.append({'phase': phase, 'role': role, 'argv': command, 'environment': env,
|
||||
'startup_name': startup_name, 'startup_profile': str(startup),
|
||||
'runtime_name': runtime_name, 'runtime_profile': str(runtime), 'folder': str(out / phase)})
|
||||
return rows
|
||||
|
||||
|
||||
def copy_evidence(runtime, destination):
|
||||
source = runtime / 'evidence'
|
||||
before = verify.inventory(source, seals=True)
|
||||
require(set(before) == verify.NAMES, 'private evidence missing/extra')
|
||||
destination.mkdir()
|
||||
for name in sorted(before):
|
||||
shutil.copyfile(source / name, destination / name)
|
||||
require(verify.inventory(source, seals=True) == before == verify.inventory(destination, seals=True), 'evidence changed during copy')
|
||||
return before
|
||||
|
||||
|
||||
def copy_profile(source, destination, collector):
|
||||
"""Keep complete private package/log/config bytes, including non-evidence files."""
|
||||
exists = source.is_dir()
|
||||
before = collector.profile_files(source)
|
||||
if exists:
|
||||
destination.mkdir()
|
||||
for name in before:
|
||||
target = destination / name
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
shutil.copyfile(source / name, target)
|
||||
require(verify.inventory(destination, seals=True) == before, 'profile copy mismatch')
|
||||
require(collector.profile_files(source) == before, 'profile changed during copy')
|
||||
return {'exists': exists, 'files': before}
|
||||
|
||||
|
||||
def run(admission, out, collector, standard, outer, diag):
|
||||
require(not out.exists(), 'new output required')
|
||||
collector.no_live_engine()
|
||||
out.mkdir(parents=True)
|
||||
write(out / 'admission.json', admission)
|
||||
rows, profiles, error = [], [], None
|
||||
source = admission['source_map']
|
||||
player = standard.default_player(ROOT)
|
||||
public = (ROOT / 'project.godot').read_bytes()
|
||||
stage = out / 'stage'
|
||||
try:
|
||||
stage.mkdir()
|
||||
for name in source:
|
||||
target = stage / name
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
standard.copy_source(ROOT / name, target)
|
||||
expected = standard.inventory(stage, stage=True)
|
||||
require(expected == source, 'stage source differs')
|
||||
(out / 'eq_probe.gd').write_bytes((HERE / 'eq_probe.gd').read_bytes())
|
||||
(out / 'profile_guard.gd').write_bytes((Path(admission['readonly_path']) / 'run-r02/profile_guard.gd').read_bytes())
|
||||
(out / 'guarded.gd').write_text(wrapper_text(out))
|
||||
(out / 'root-input-manifest.json').write_bytes((Path(admission['readonly_path']) / 'ROOT_INPUT_MANIFEST.json').read_bytes())
|
||||
for item in admission['plan']:
|
||||
phase = item['phase']
|
||||
require(standard.inventory(stage, stage=True) == expected, 'stage changed before phase')
|
||||
require(collector.source_map(standard, ROOT) == source and standard.default_player(ROOT) == player, 'source/player changed')
|
||||
for name, expected_sha in admission['pins']['worker'].items():
|
||||
require(sha(HERE / name) == expected_sha, 'EQ changed during execution')
|
||||
profiles.extend([Path(item['startup_profile']), Path(item['runtime_profile'])])
|
||||
require(all(not p.exists() for p in profiles[-2:]), 'profile reuse')
|
||||
row = collector.run_private_engine(standard, outer, item['argv'], out / phase,
|
||||
item['environment'], stage, public, item['startup_name'])
|
||||
row.update(phase=phase, role=item['role'], environment=item['environment'], pid=row['process']['pid'])
|
||||
rows.append(row)
|
||||
require(row['passed'] is True, 'owned phase failure: ' + phase)
|
||||
after = standard.inventory(stage, stage=True)
|
||||
collector.stage_gate(expected, after, importing=phase == 'import')
|
||||
expected = after
|
||||
row.update(stage_inventory=after, source_preserved=collector.source_map(standard, ROOT) == source,
|
||||
player_preserved=standard.default_player(ROOT) == player)
|
||||
if phase in verify.ROLES:
|
||||
guard_path = out / (phase + '-guard.json')
|
||||
guard = verify.read(guard_path)
|
||||
collector.guard_gate(guard, Path(item['runtime_profile']), item['runtime_name'])
|
||||
row.update(runtime_profile=item['runtime_profile'], runtime_name=item['runtime_name'],
|
||||
guard=guard, guard_sha256=sha(guard_path))
|
||||
row['evidence_files'] = copy_evidence(Path(item['runtime_profile']), out / phase / 'evidence')
|
||||
verify.phase_evidence(out, row)
|
||||
row['profile_copies'] = {
|
||||
'startup': copy_profile(Path(item['startup_profile']), out / phase / 'startup-profile', collector),
|
||||
'runtime': copy_profile(Path(item['runtime_profile']), out / phase / 'runtime-profile', collector)}
|
||||
diag.bound_raw(out / phase, row)
|
||||
except BaseException as caught:
|
||||
error = repr(caught)
|
||||
finally:
|
||||
cleanup, cleanup_errors = outer.finish_captured(outer.OWNED)
|
||||
execution = {'admission': admission, 'phases': rows, 'passed': error is None, 'error': error,
|
||||
'cleanup': cleanup, 'cleanup_errors': cleanup_errors, 'source_after': collector.source_map(standard, ROOT),
|
||||
'player_before': player, 'player_after': standard.default_player(ROOT),
|
||||
'profiles_retained': {str(p): collector.profile_files(p) for p in profiles}}
|
||||
try:
|
||||
execution['pins_after'] = actual_pins(ROOT, Path(admission['readonly_path']), Path(admission['fixture']),
|
||||
Path(admission['engine']), collector, standard)
|
||||
require((ROOT / 'project.godot').read_bytes() == public and (stage / 'project.godot').read_bytes() == public, 'project restoration')
|
||||
if error is None:
|
||||
result = verify.recompute(out, execution, collector, standard, diag)
|
||||
write(out / 'results.json', result)
|
||||
for phase, values in result['phases'].items():
|
||||
for name, value in values.items():
|
||||
write(out / phase / (name + '.json'), value)
|
||||
except BaseException as caught:
|
||||
execution.update(passed=False, error=repr(caught))
|
||||
write(out / 'execution.json', execution)
|
||||
if execution['passed']:
|
||||
verify.seal(out)
|
||||
return 0 if execution['passed'] else 1
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
mode = parser.add_mutually_exclusive_group(required=True)
|
||||
mode.add_argument('--check', action='store_true')
|
||||
mode.add_argument('--run', action='store_true')
|
||||
for name in ('readonly', 'fixture', 'engine', 'output'):
|
||||
parser.add_argument('--' + name, type=Path, required=True)
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
readonly, fixture, engine, out = [p.resolve() for p in (args.readonly, args.fixture, args.engine, args.output)]
|
||||
require(not out.exists(), 'new output required')
|
||||
collector, standard, outer, diag = load_dependencies()
|
||||
pins = actual_pins(ROOT, readonly, fixture, engine, collector, standard)
|
||||
static = check.check_probe((HERE / 'eq_probe.gd').read_text())
|
||||
require(static['ok'], 'probe checker: ' + repr(static['errors']))
|
||||
admission = {'measured_source': 'S_eq-native-not-Q', 'candidate_Q_measured': False,
|
||||
'commit': frozen_commit(pins['source']), 'source_map': pins['source'], 'pins': pins,
|
||||
'readonly_path': str(readonly), 'fixture': str(fixture), 'engine': str(engine),
|
||||
'phases': verify.PHASES, 'plan': plan(collector, standard, engine, fixture, out)}
|
||||
if args.check:
|
||||
print(json.dumps(admission, ensure_ascii=False, indent=2))
|
||||
return 0
|
||||
return run(admission, out, collector, standard, outer, diag)
|
||||
except (ValueError, OSError, KeyError, TypeError, subprocess.CalledProcessError) as error:
|
||||
print(json.dumps({'status': 'failed', 'error': str(error)}))
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
raise SystemExit(main())
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,254 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Read-only verification of the exact S_eq native evidence; never launches Godot."""
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
sys.dont_write_bytecode = True
|
||||
import check_eq as check
|
||||
import compare_versions as eq
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
ROOT = HERE.parents[5]
|
||||
PHASES = ['import', 'parse-base', 'parse-wrapper', 'R-A', 'R-B', 'O-A', 'O-B']
|
||||
ROLES = {'R-A': 'R', 'R-B': 'R', 'O-A': 'O', 'O-B': 'O'}
|
||||
NAMES = {f'{prefix}-{i:02d}.json' for prefix, count in
|
||||
[('checkpoint', 31), ('observation', 31), ('e3', 18), ('e45', 21)] for i in range(count)} | {
|
||||
'events.json', 'report.json', 'lifecycle.json', 'audio-close.json'}
|
||||
LOCAL_NAMES = {'run_eq.py', 'verify_eq.py', 'check_eq.py', 'compare_versions.py', 'eq_probe.gd', 'test_eq.py'}
|
||||
require = eq.require
|
||||
|
||||
|
||||
def sha(path):
|
||||
return hashlib.sha256(Path(path).read_bytes()).hexdigest()
|
||||
|
||||
|
||||
def pin(path):
|
||||
path = Path(path)
|
||||
require(path.is_file() and not path.is_symlink(), 'missing/symlink: ' + str(path))
|
||||
return {'bytes': path.stat().st_size, 'sha256': sha(path)}
|
||||
|
||||
|
||||
def read(path):
|
||||
return check.strict_json(Path(path).read_text(encoding='utf-8'))
|
||||
|
||||
|
||||
def write(path, value):
|
||||
with Path(path).open('x', encoding='utf-8') as stream:
|
||||
json.dump(value, stream, ensure_ascii=False, allow_nan=False, indent=2)
|
||||
stream.write('\n')
|
||||
|
||||
|
||||
def wire(value):
|
||||
"""Checker diagnostics may contain tuples; bind their exact JSON representation."""
|
||||
return check.strict_json(json.dumps(value, ensure_ascii=False, allow_nan=False))
|
||||
|
||||
|
||||
def inventory(directory, seals=False):
|
||||
directory = Path(directory)
|
||||
require(directory.is_dir() and not directory.is_symlink(), 'evidence directory missing/symlink')
|
||||
result = {}
|
||||
for path in sorted(directory.rglob('*')):
|
||||
require(not path.is_symlink(), 'evidence symlink')
|
||||
name = path.relative_to(directory).as_posix()
|
||||
if path.is_file() and (seals or name not in ('bundle.json', 'seal.json')):
|
||||
result[name] = pin(path)
|
||||
return result
|
||||
|
||||
|
||||
def seal(directory):
|
||||
directory = Path(directory)
|
||||
require(not (directory / 'bundle.json').exists() and not (directory / 'seal.json').exists(), 'already sealed')
|
||||
write(directory / 'bundle.json', {'schema': 'p28-02-eq-bundle-v1', 'files': inventory(directory)})
|
||||
write(directory / 'seal.json', {'bundle': pin(directory / 'bundle.json')})
|
||||
|
||||
|
||||
def check_seal(directory):
|
||||
directory = Path(directory)
|
||||
manifest, sealed = read(directory / 'bundle.json'), read(directory / 'seal.json')
|
||||
require(sealed == {'bundle': pin(directory / 'bundle.json')}, 'seal mismatch')
|
||||
require(manifest == {'schema': 'p28-02-eq-bundle-v1', 'files': inventory(directory)}, 'manifest/file mismatch')
|
||||
|
||||
|
||||
def check_audio(audio, pid):
|
||||
expected = {'coordinator': True, 'passed': True, 'owned_engine_pid': pid,
|
||||
'all_owned_targets_released': True, 'deadline_reached': False,
|
||||
'clock_process_held_stopped': True, 'window_input_held_disabled': True,
|
||||
'restored_before_quit': False, 'shared_bus_deleted': False, 'settings_mutated': False}
|
||||
require(all(type(audio.get(k)) is type(v) and audio[k] == v for k, v in expected.items()), 'audio close/PID')
|
||||
|
||||
|
||||
def phase_evidence(directory, row):
|
||||
"""Recompute all S1-S3b checks from copied native bytes, with no cached verdicts."""
|
||||
directory = Path(directory)
|
||||
phase, role = row['phase'], row['role']
|
||||
require(ROLES.get(phase) == role, 'phase/role binding')
|
||||
folder = directory / phase
|
||||
evidence = folder / 'evidence'
|
||||
files = inventory(evidence, seals=True)
|
||||
require(set(files) == NAMES and files == row['evidence_files'], 'exact private evidence inventory')
|
||||
raw = check.read_report_stdout((folder / 'stdout.log').read_text())
|
||||
require(raw == read(evidence / 'report.json') and raw['role'] == role, 'raw report/role copy')
|
||||
require(len(raw['scenarios']) == 39, '39 scenarios required')
|
||||
life = read(evidence / 'lifecycle.json')
|
||||
require(life['stage'] == 'S3b', 'S3b lifecycle required')
|
||||
require(len(life['e3']) == 18 and len(life['e45']) == 21, 'scenario evidence coverage')
|
||||
declared = {r['path']: {'bytes': r['bytes'], 'sha256': r['sha256']} for r in life['files']}
|
||||
require(len(declared) == len(life['files']), 'duplicate lifecycle inventory')
|
||||
expected = {'evidence/' + n: v for n, v in files.items() if n not in ('lifecycle.json', 'audio-close.json')}
|
||||
require(declared == expected, 'lifecycle inventory differs')
|
||||
guard_path = directory / (phase + '-guard.json')
|
||||
guard = read(guard_path)
|
||||
require(guard == row['guard'] and sha(guard_path) == row['guard_sha256'] == life['guard']['sha256'], 'guard SHA')
|
||||
require(life['guard']['path'] == row['environment']['THE_TREE_PACK_PROFILE_REPORT'], 'guard path binding')
|
||||
require(raw['profile_root']['root'] == row['runtime_profile'], 'report profile binding')
|
||||
check.check_lifecycle(raw, life, guard)
|
||||
check_audio(read(evidence / 'audio-close.json'), row['pid'])
|
||||
require(read(evidence / 'events.json') == raw['events'], 'events copy')
|
||||
for i, cp in enumerate(raw['checkpoints']):
|
||||
require(read(evidence / f'checkpoint-{i:02d}.json') == cp, 'checkpoint copy')
|
||||
check.check_observation(cp, read(evidence / f'observation-{i:02d}.json'))
|
||||
for prefix in ('e3', 'e45'):
|
||||
for i, value in enumerate(life[prefix]):
|
||||
require(read(evidence / f'{prefix}-{i:02d}.json') == value, 'scenario copy')
|
||||
checked = check.check_report(raw, life['measurement'], life['e3'], life['e3_b1'], life['e45'])
|
||||
require(checked['ok'], 'report checker: ' + repr(checked['errors']))
|
||||
joined, proofs = check.join_report(raw)
|
||||
return wire({'raw': raw, 'joined': joined, 'proofs': proofs, 'checker': checked})
|
||||
|
||||
|
||||
def recompute(directory, execution, collector, standard, diag):
|
||||
"""Validate owned receipts and recompute every comparison from raw evidence."""
|
||||
directory = Path(directory)
|
||||
require(execution['passed'] is True and execution['error'] is None and execution['cleanup_errors'] == [], 'execution failed')
|
||||
admission = execution['admission']
|
||||
require(read(directory / 'admission.json') == admission, 'admission copy')
|
||||
require(admission['measured_source'] == 'S_eq-native-not-Q' and admission['candidate_Q_measured'] is False, 'Q measurement forbidden')
|
||||
require(admission['phases'] == PHASES, 'phase plan')
|
||||
from run_eq import wrapper_text
|
||||
original_out = Path(admission['plan'][0]['folder']).parent
|
||||
engine = Path(admission['engine'])
|
||||
expected_commands = [collector.argv_for(engine, original_out / 'stage', original_out / 'guarded.gd', importing=True),
|
||||
collector.parse_argv(engine, original_out / 'stage', original_out / 'eq_probe.gd'),
|
||||
collector.parse_argv(engine, original_out / 'stage', original_out / 'guarded.gd')] + [
|
||||
[str(engine), '--headless', '--path', str(original_out / 'stage'), '--script', str(original_out / 'guarded.gd')]
|
||||
for _ in range(4)]
|
||||
require([p['argv'] for p in admission['plan']] == expected_commands, 'actual seven-phase command plan')
|
||||
require((directory / 'guarded.gd').read_text() == wrapper_text(original_out), 'guard before parent wrapper')
|
||||
require(sha(directory / 'eq_probe.gd') == admission['pins']['worker']['eq_probe.gd'], 'frozen probe')
|
||||
require(sha(directory / 'profile_guard.gd') == admission['pins']['readonly']['files']['run-r02/profile_guard.gd'], 'guard pin')
|
||||
require(sha(directory / 'root-input-manifest.json') == admission['pins']['readonly']['manifest_sha256'], 'original manifest copy')
|
||||
static = check.check_probe((directory / 'eq_probe.gd').read_text())
|
||||
require(static['ok'], 'probe checker: ' + repr(static['errors']))
|
||||
source = admission['source_map']
|
||||
require(len(source) == 1407 and collector.digest(source) == eq.SOURCE_SHA, 'full source map pin')
|
||||
require(execution['source_after'] == source and execution['player_before'] == execution['player_after'], 'source/player preservation')
|
||||
require(execution['pins_after'] == admission['pins'], 'pin preservation')
|
||||
rows = execution['phases']
|
||||
require([r['phase'] for r in rows] == PHASES, 'seven phases in order')
|
||||
pids, profiles, joined, results = [], [], {}, {}
|
||||
previous = source
|
||||
for i, row in enumerate(rows):
|
||||
phase = row['phase']
|
||||
# DIAG's shared owned/raw checks return before its DIAG-specific report branch
|
||||
# for the EQ phase names. Its dependency is frozen; no function is replaced.
|
||||
diag.bound_raw(directory / phase, row)
|
||||
for name in row['raw']:
|
||||
require(not collector.diagnostics((directory / phase / name).read_text()), 'strict diagnostic')
|
||||
for name in row['owned_files']:
|
||||
read(directory / phase / name) # reject duplicate JSON keys before any admission
|
||||
pid = row['process']['pid']
|
||||
require(type(pid) is int and pid > 0 and row['pid'] == pid, 'phase PID binding')
|
||||
pids.append(pid)
|
||||
start, end = row['process']['actual_start_binding'], row['process']['actual_end_binding']
|
||||
require(type(start['monotonic_ns']) is int and end['monotonic_ns'] >= start['monotonic_ns'], 'PID start/end time')
|
||||
command = admission['plan'][i]
|
||||
require(command['phase'] == phase and command['role'] == ROLES.get(phase), 'planned role')
|
||||
environment = {'THE_TREE_PACK_PROFILE_NAME': command['runtime_name'],
|
||||
'THE_TREE_PACK_PROFILE_EXPECTED': command['runtime_profile'],
|
||||
'THE_TREE_PACK_PROFILE_REPORT': str(original_out / (phase + '-guard.json')),
|
||||
'THE_TREE_EQ_ROLE': ROLES.get(phase, ''), 'THE_TREE_P28_FIXTURE': admission['fixture'],
|
||||
'THE_TREE_P28_FIXTURE_SHA': collector.FIXTURE_SHA}
|
||||
require(command['environment'] == environment, 'guard/role/fixture environment')
|
||||
require(command['startup_profile'] == str(standard.profile_path(command['startup_name'])) and
|
||||
command['runtime_profile'] == str(standard.profile_path(command['runtime_name'])), 'profile name/path')
|
||||
require(row['argv'][:-3] == command['argv'] and row['argv'][-3] == '--log-file' and
|
||||
row['argv'][-1] == '--verbose' and '--headless' in row['argv'], 'phase argv')
|
||||
require(row['environment'] == command['environment'], 'phase environment')
|
||||
collector.stage_gate(previous, row['stage_inventory'], importing=phase == 'import')
|
||||
previous = row['stage_inventory']
|
||||
require(row['source_preserved'] is True and row['player_preserved'] is True, 'phase preservation')
|
||||
startup = row['startup_project']
|
||||
require(startup['name'] == command['startup_name'] and startup['profile'] == command['startup_profile'] and
|
||||
startup['fresh_before'] is True and startup['restored_sha256'] == source['project.godot']['sha256'], 'startup profile')
|
||||
require(sha(directory / (phase + '-startup-project.godot')) == startup['sha256'], 'startup project bytes')
|
||||
require((directory / (phase + '-startup-project.godot')).read_bytes() ==
|
||||
standard.private_project((ROOT / 'project.godot').read_bytes(), command['startup_name']), 'private project policy')
|
||||
profiles.extend([startup['profile'], command['runtime_profile']])
|
||||
for kind in ('startup', 'runtime'):
|
||||
copied = row['profile_copies'][kind]
|
||||
target = directory / phase / (kind + '-profile')
|
||||
require(type(copied['exists']) is bool and copied['exists'] == target.is_dir(), 'profile existence/copy')
|
||||
require((inventory(target, seals=True) if target.is_dir() else {}) == copied['files'], 'complete profile copy')
|
||||
require(execution['profiles_retained'][command[kind + '_profile']] == copied['files'], 'retained profile changed')
|
||||
if phase in ROLES:
|
||||
require(row['profile_copies']['runtime']['exists'] is True, 'missing runtime profile')
|
||||
require({n[len('evidence/'):]: p for n, p in row['profile_copies']['runtime']['files'].items()
|
||||
if n.startswith('evidence/')} == row['evidence_files'], 'profile/evidence copy binding')
|
||||
require(row['role'] == ROLES[phase] and row['runtime_profile'] == command['runtime_profile'] and
|
||||
row['runtime_name'] == command['runtime_name'], 'runtime/role binding')
|
||||
collector.guard_gate(row['guard'], Path(row['runtime_profile']), row['runtime_name'])
|
||||
results[phase] = phase_evidence(directory, row)
|
||||
joined[phase] = results[phase]['joined']
|
||||
else:
|
||||
require(row['role'] is None, 'parse/import role')
|
||||
require('P28_02_EQ_REPORT=' not in (directory / phase / 'stdout.log').read_text(), 'parse/import report')
|
||||
require(len(set(pids)) == 7 and len(set(profiles)) == 14, 'PID/profile reuse')
|
||||
require({r['pid'] for r in execution['cleanup']} == set(pids) and all(
|
||||
r['engine_ended'] is True and r['outer_cleanup_errors'] == [] and
|
||||
r['foreign_process_or_group_signals'] == 0 for r in execution['cleanup']), 'cleanup incomplete')
|
||||
comparisons = {}
|
||||
for role in ('R', 'O'):
|
||||
result = eq.compare_reports(joined[role + '-A'], joined[role + '-B'])
|
||||
require(result['ok'] and result['differences'] == [], 'same-role determinism failed: ' + role)
|
||||
comparisons[role] = result
|
||||
return wire({'phases': results, 'comparisons': comparisons, 'measured_source': 'S_eq-native-not-Q',
|
||||
'candidate_Q_measured': False, 'original_credit': 0, 'formal_acceptance': False})
|
||||
|
||||
|
||||
def verify(project_root, directory):
|
||||
from run_eq import load_dependencies, actual_pins
|
||||
project_root, directory = Path(project_root).resolve(), Path(directory).resolve()
|
||||
check_seal(directory)
|
||||
execution = read(directory / 'execution.json')
|
||||
collector, standard, outer, diag = load_dependencies(project_root)
|
||||
admission = execution['admission']
|
||||
require(actual_pins(project_root, Path(admission['readonly_path']), Path(admission['fixture']),
|
||||
Path(admission['engine']), collector, standard) == admission['pins'], 'actual input/source/EQ pins differ')
|
||||
result = recompute(directory, execution, collector, standard, diag)
|
||||
require(result == read(directory / 'results.json'), 'recomputed results differ')
|
||||
for phase, values in result['phases'].items():
|
||||
for name, value in values.items():
|
||||
require(read(directory / phase / (name + '.json')) == value, 'raw/joined/proof/checker copy differs')
|
||||
return result
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--project-root', type=Path, required=True)
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
require(os.environ.get('BUILD_OUTPUT_DIR'), 'BUILD_OUTPUT_DIR required')
|
||||
result = verify(args.project_root, Path(os.environ['BUILD_OUTPUT_DIR']) / 'p28-02-eq-evidence')
|
||||
print(json.dumps({'status': 'verified', 'result': result}, ensure_ascii=False, allow_nan=False))
|
||||
return 0
|
||||
except (ValueError, OSError, KeyError, TypeError, IndexError) as error:
|
||||
print(json.dumps({'status': 'failed', 'error': str(error), 'formal_acceptance': False}))
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user