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.
|
||||
Reference in New Issue
Block a user