P04-01: 同時発生の更新規約

This commit is contained in:
Agent Control Runner
2026-10-18 20:16:38 +09:00
parent 2cd734062a
commit 13aefdd3dd
22 changed files with 1392 additions and 35 deletions
@@ -1,6 +1,26 @@
## REPAIR49 current correction
Source-ready only; original 30/88, formal 16, P04=0, no partial credit.
REPAIR48's specification-mismatch blocker below is historical and corrected:
the immutable 7000-byte original has SHA256
d28aadb044633f7d804de5a92c8d4c4a7438dfbf44c3243dca978951f4def25f;
removing its single EOF LF gives
9ec722e7dfb0bee178d291624a026420c08412574e238bba1fde012c7a6f7881.
This is the existing Git/Runner strip/checker one-EOF-LF pin contract.
No specification, approval or normalization change. Older contradictory wording
below is superseded history, including blanket full-reuse prohibitions and
all-controls-unexecuted wording. Q47 admission/index failures remain failures.
See REPAIR49_STATUS.md for closure audit and verbatim complete_B FileNotFoundError.
Root handoff reports payload(B), all53, series/join/power PASS; order-typed remains
UNDETERMINED. Worker did not rerun them. Corrected complete_B remains unexecuted.
Old native/full successes confer no new-S acceptance or credit.
REPAIR48 current source status: see [REPAIR48_STATUS.md](REPAIR48_STATUS.md). Earlier run directions and successes below are historical; they grant no P04 credit.
RUN47 current harness status: see REPAIR47_STATUS.md, REPAIR47_PLAN.json and REPAIR47_VALIDATION.json. Original unit remains unaccepted; earlier status below is historical.
# P04-01 current status — repair31
# Historical P04-01 status — repair31
**BLOCKED: partial implementation; do not start the once-only native/full run.**
Formal completed status is **16/88**, with **zero P04 credit**.
@@ -1,3 +1,72 @@
## REPAIR49 normal-gate handoff
Required materials: exact B/native-first-current and fresh-run registry; each
runner-input/ended/source/UID/formal/raw/lifecycle receipt; original recorded Q
and engine context; B/p04-evidence/runner-materials and RELOCATION.json; matching
collection/MANIFEST and separate dependency invocation; original full run and
full_suite binding/raw receipts; final index and invocation receipt; immutable
authorities in frozen checkout. No raw or historical receipt is rewritten.
Two-placement identity requires the explicit closure in repair48_identity_controls.py,
missing-file rejection, and original/A/B complete path/bytes/SHA tables and tree
hash equality before and after positive execution. See REPAIR49_STATUS.md.
Submission is followed by new Q freeze, affected pure controls (complete_B included),
clean exact-Q check-only, capacity/PID checks, one fresh native lease for
S1/S2a/S2b/S3/S4 and all ten S5 cases, readers/adapters, 15EV collector, full
verification/binding under the conditions below (or one final full184 if any
condition fails), index generation, p04-acceptance once, separate Opus whole-unit
review, normal prepare/C/integration/final/Root DB join/ledger/main push.
If order-typed fails, preserve its result and stop before heavy execution.
Only whole-unit acceptance grants credit.
## REPAIR49 full184 conditional reuse candidate — all conditions UNVERIFIED
Native reuse is forbidden: all six series require fresh M/S/Q_tree provenance
(p04_native_series.py:1287; checker:370). Full uses the existing separate binding
(checker:1175-1186); no adopter or checker change is authorized.
The following are requirements, not results or approval:
1. New S5 source_before must equal old full selected_source_map: all 1369 keys
and SHA values, not counts alone.
2. Old project_root must remain unchanged: source-start == current source_refs
== post-verification source_refs (full_suite_verifier.py:115).
3. selected_source_map, roster184, parse329, settings, runner/marker module,
marker contract, suite-policy and UID plan/stage must all match (116-152,225).
4. inputs.engine must match current engine_pin (124-125).
5. Revalidate every phase PID, cleanup, marker and diagnostics (154-228).
6. Current s5/run_s5_native.py and full_suite_verifier.py SHA must equal the
Root rehearsal versions.
7. Never relabel old S/oldQ/project_root/PIDs/time. Describe reuse only as
revalidating the exact-source-identical old full through the existing
full_suite route; never claim full ran on new S.
8. A separate Opus whole-unit review must independently confirm applicability.
Conditions 1–6 require actual checks after final freeze. If any predicate is
unproved or differs, reject reuse and execute full184 once on the final version.
SourceRefs (tools/run_all_tests.py:40-45) excludes docs/private package, but that
fact is no substitute for complete source equality. No reuse is approved here.
## REPAIR49 current correction
Source-ready only; original 30/88, formal 16, P04=0, no partial credit.
REPAIR48's specification-mismatch blocker below is historical and corrected:
the immutable 7000-byte original has SHA256
d28aadb044633f7d804de5a92c8d4c4a7438dfbf44c3243dca978951f4def25f;
removing its single EOF LF gives
9ec722e7dfb0bee178d291624a026420c08412574e238bba1fde012c7a6f7881.
This is the existing Git/Runner strip/checker one-EOF-LF pin contract.
No specification, approval or normalization change. Older contradictory wording
below is superseded history, including blanket full-reuse prohibitions and
all-controls-unexecuted wording. Q47 admission/index failures remain failures.
See REPAIR49_STATUS.md for closure audit and verbatim complete_B FileNotFoundError.
Root handoff reports payload(B), all53, series/join/power PASS; order-typed remains
UNDETERMINED. Worker did not rerun them. Corrected complete_B remains unexecuted.
Old native/full successes confer no new-S acceptance or credit.
REPAIR48 current source status: see [REPAIR48_STATUS.md](REPAIR48_STATUS.md). Earlier run directions and successes below are historical; they grant no P04 credit.
## RUN47 harness repair; original unit remains unaccepted
Q46 S4 failed before engine startup: `AssertionError: complete 316-script parse roster`.
@@ -11,7 +80,7 @@ reuse instructions. Immutable spec, REQUIRED/REACH_REFS, product, caps, denomina
permissions and historical raw are unchanged. Option B: Root freezes new final Q,
then fresh all-series runs once; no receipt rewriting or reuse adopter.
# P04-01 order audit — repair31
# Historical P04-01 order audit — repair31
Formal status is **16/88, P04 credit 0**. Policy approvals are recorded; implementation and exact-Q evidence remain incomplete. No original-unit completion is claimed.
@@ -0,0 +1,14 @@
Traceback (most recent call last):
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement/docs/plans/original-completion-2026-10-02/execution/p04-01/build_p04_index.py", line 159, in <module>
main()
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement/docs/plans/original-completion-2026-10-02/execution/p04-01/build_p04_index.py", line 141, in main
index = payload(args.build, gate)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement/docs/plans/original-completion-2026-10-02/execution/p04-01/build_p04_index.py", line 37, in payload
raw = gate.combine_native_series(build, c)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement/tools/check_p04_order_evidence.py", line 1150, in combine_native_series
require({k: v for k, v in recorded.items() if k != 'verifier_sha256'} == actual, 'fresh raw recomputation drift')
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement/tools/check_p04_order_evidence.py", line 97, in require
raise ValueError(message)
ValueError: fresh raw recomputation drift
@@ -0,0 +1,53 @@
{
"S": "2cd734062a2226b5006bbecf96e6024a26982665",
"checker_sha256": "3bb0cde776bc295f6f18e74f1e23bf3d832d8e4f71aed260601c82d287c655fd",
"actual_function": "supplied_file",
"source_call_site": "build_p04_index.payload lines 50-55 calls descriptor of actual runner fixed paths then supplied_file on all those paths",
"scope": "narrow pure actual material admission only; NOT complete checker/index or engine execution",
"rows": [
{
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/audit-support/p04-fresh-context-r47/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/p04_s4_power_probe.gd",
"admitted": false,
"error": "unsupplied external material: /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/audit-support/p04-fresh-context-r47/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/p04_s4_power_probe.gd"
},
{
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/audit-support/p04-fresh-context-r47/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/run_s4_native.py",
"admitted": false,
"error": "unsupplied external material: /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/audit-support/p04-fresh-context-r47/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/run_s4_native.py"
},
{
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/audit-support/p04-fresh-context-r47/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/S4_ROOT_RUN.md",
"admitted": false,
"error": "unsupplied external material: /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/audit-support/p04-fresh-context-r47/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/S4_ROOT_RUN.md"
},
{
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-root-q-r47-2cd73406/tests/transport/test_runtime_transport.gd",
"admitted": false,
"error": "unsupplied external material: /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-root-q-r47-2cd73406/tests/transport/test_runtime_transport.gd"
},
{
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-root-q-r47-2cd73406/tests/staff/test_rescue_elevator.gd",
"admitted": false,
"error": "unsupplied external material: /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-root-q-r47-2cd73406/tests/staff/test_rescue_elevator.gd"
},
{
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-root-q-r47-2cd73406/docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json",
"admitted": false,
"error": "unsupplied external material: /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-root-q-r47-2cd73406/docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json"
},
{
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/audit-support/p04-fresh-context-r47/docs/plans/original-completion-2026-10-02/execution/p04-01/s5/run_s5_native.py",
"admitted": false,
"error": "unsupplied external material: /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/audit-support/p04-fresh-context-r47/docs/plans/original-completion-2026-10-02/execution/p04-01/s5/run_s5_native.py"
},
{
"path": "/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/audit-support/p04-fresh-context-r47/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/p04_s4_power_probe.gd",
"admitted": false,
"error": "unsupplied external material: /Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/.runtime/P04-01/build/audit-support/p04-fresh-context-r47/docs/plans/original-completion-2026-10-02/execution/p04-01/s4/p04_s4_power_probe.gd"
}
],
"rejected": 8,
"full184_status": "still running; retain without restarting",
"formal_acceptance": false,
"at_unix_ns": 1792318056557763000
}
@@ -0,0 +1,88 @@
{
"task_id": "P04-01",
"kind": "static inspection only; no tests executed",
"syntax": [
"build_p04_index.py",
"p04_native_series.py",
"full_suite_verifier.py",
"collect_p04_native.py",
"s5/s5_order_adapter.py",
"s5/s5_power_adapter.py",
"repair48_transport_controls.py",
"repair48_identity_controls.py"
],
"source_sha256": {
"build_p04_index.py": "35b1b35f94e64f0f8c93ad5de17b35a16c2a81ca802691ba77251ad4256ca515",
"p04_native_series.py": "c33f8abb7f4ad143f75a1b761447a84afddb2dd0ac67b782e4cf9a8a67b67e4a",
"full_suite_verifier.py": "779ab0c0b5be31dcee462f04cbd6b765d44f9bef95fb52b03d3b676ec9f80c9c",
"collect_p04_native.py": "70a12149c770ef4dca97d3d5aa0b59270cf1547efde79ee7346ba340e1bebca6",
"s5/s5_order_adapter.py": "91344410b3441049fbce316cef9c227c9355747ae56890b45fcf348dac401d7e",
"s5/s5_power_adapter.py": "41d33e8d6b4e986611bdf7a0eedbde3f0b92f724ea37d3b2502ba4965a298462",
"repair48_transport_controls.py": "b2df097bc20bde89a7a738d4c1fe855bfa0bd1ac82a12936aa2b106980685628",
"repair48_identity_controls.py": "1c4f81e13715a2ab4b73b633265d3279772a3a8a90115e78098f0ecbd895d9ef"
},
"engine_runs": 0,
"git_writes": 0,
"runner_actions": 0,
"immutable": [
{
"path": "tools/check_p04_order_evidence.py",
"sha256": "3bb0cde776bc295f6f18e74f1e23bf3d832d8e4f71aed260601c82d287c655fd",
"matches_repair47_record": true
},
{
"path": "docs/spec/acceptance/P04-01.json",
"sha256": "d28aadb044633f7d804de5a92c8d4c4a7438dfbf44c3243dca978951f4def25f",
"matches_repair47_record": true
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/s4/historical/run_s4_native_r28.py.reference",
"sha256": "2d3be39d2b310abac058e27336ac816c234043a0a1dd7b2c52d84994907dd31b",
"matches_repair47_record": true
}
],
"historical_failure_copies": [
{
"name": "ROOT_Q47_ACTUAL_INDEX_GENERATION.log",
"byte_identical": true,
"sha256": "0250e523aeeecde5d81d298e30cd7e4e18a5415ac4e762401697256be6d514f9"
},
{
"name": "ROOT_Q47_ACTUAL_MATERIAL_ADMISSION_FAILURE.json",
"byte_identical": true,
"sha256": "a86b93150c33620854938c040f57db49e5627171f8f0633b399c527b7c08ec55"
}
],
"status": "blocked",
"specification_version_gap": {
"contract_sha256": "9ec722e7dfb0bee178d291624a026420c08412574e238bba1fde012c7a6f7881",
"actual_sha256": "d28aadb044633f7d804de5a92c8d4c4a7438dfbf44c3243dca978951f4def25f",
"specification_modified": false
},
"tests_executed": [],
"historical_test_results_reused": [],
"changed_source_files": [
"build_p04_index.py",
"p04_native_series.py",
"full_suite_verifier.py",
"collect_p04_native.py",
"s5/s5_order_adapter.py",
"s5/s5_power_adapter.py",
"repair48_transport_controls.py",
"repair48_identity_controls.py"
],
"changed_documentation": [
"REPAIR48_STATUS.md",
"REPAIR48_STATIC_INSPECTION.json",
"REPAIR48_HISTORICAL_ROOT_Q47_ACTUAL_INDEX_GENERATION.log",
"REPAIR48_HISTORICAL_ROOT_Q47_ACTUAL_MATERIAL_ADMISSION_FAILURE.json",
"ORDER_AUDIT.md",
"CURRENT_STATUS.md",
"s1/S1_ROOT_RUN.md",
"s2/S2_ROOT_RUN.md",
"s2b/S2B_ROOT_RUN.md",
"s3/S3_ROOT_RUN.md",
"s4/S4_ROOT_RUN.md",
"s5/S5_ROOT_RUN.md"
]
}
@@ -0,0 +1,160 @@
## REPAIR49 current correction
Source-ready only; original 30/88, formal 16, P04=0, no partial credit.
REPAIR48's specification-mismatch blocker below is historical and corrected:
the immutable 7000-byte original has SHA256
d28aadb044633f7d804de5a92c8d4c4a7438dfbf44c3243dca978951f4def25f;
removing its single EOF LF gives
9ec722e7dfb0bee178d291624a026420c08412574e238bba1fde012c7a6f7881.
This is the existing Git/Runner strip/checker one-EOF-LF pin contract.
No specification, approval or normalization change. Older contradictory wording
below is superseded history, including blanket full-reuse prohibitions and
all-controls-unexecuted wording. Q47 admission/index failures remain failures.
See REPAIR49_STATUS.md for closure audit and verbatim complete_B FileNotFoundError.
Root handoff reports payload(B), all53, series/join/power PASS; order-typed remains
UNDETERMINED. Worker did not rerun them. Corrected complete_B remains unexecuted.
Old native/full successes confer no new-S acceptance or credit.
# REPAIR48 implementation status
BLOCKED on exact specification-version context; source changes are retained for
review. No acceptance or new credit is claimed.
Original scope remains 30/88; formal credit is 16; P04 credit is 0.
Engine runs, Git writes, Runner actions and delegation are prohibited.
The supplied task contract declares spec_sha256
`9ec722e7dfb0bee178d291624a026420c08412574e238bba1fde012c7a6f7881`.
The actual immutable docs/spec/acceptance/P04-01.json hashes to
`d28aadb044633f7d804de5a92c8d4c4a7438dfbf44c3243dca978951f4def25f`.
That local hash agrees with REPAIR47_STATIC_CHECKS.json. This worker has not
changed the specification or selected a replacement authority. Root must resolve
which exact specification bytes govern the retained repair before gate use.
This is an exact-version context gap, not a proposed acceptance change.
## Current changes
`build_p04_index.py` separates exclusive generation (`relocate_materials`) from
read-only `payload`. The exact output is resolved B/p04-evidence, with no existing
output, traversal or parent symlinks. Fixed pins plus QA are checked for exact
duplicates and conflicting identities, including across series. Copies are
content-addressed under the first referencing series, created exclusively, and
rehashed. Exact (original path, bytes, SHA) identities share one copy across all
series; different original paths are never silently merged. RELOCATION.json
keeps original pin paths as keys. Raw inputs are never rewritten. Every payload
call checks map membership, declared relative form, hashes, unmapped files and
exactly one wrapper candidate. Materials and wrapper descriptors are relative;
the relocation-map SHA is included in the index. The obsolete absolute material
admission pre-check is removed. Main relocates, derives, checks refs and roles,
then writes index and the separate invocation receipt. Failure leaves a failed
output attempt without a usable index; an existing output cannot be resumed.
S5 dependency identity uses the package-relative power, series and guard module
paths. Each module is read once and those same bytes are compiled and executed,
without cached bytecode. Symlinks, outside dependencies and mismatched mappings
are rejected. The roster is checked against the modules loaded. Dependency maps
are checked against the executed roster before deriving facts. Absolute observed
paths and checkout are retained in collection/dependency-invocation.json, outside
the compared s5.json and the collection manifest's series mapping. The adapter's
own observed path and executed-byte SHA are also retained there.
## Static path audit
| Value | Result and required context |
| --- | --- |
| fixed pins and QA | Source placement is free-form. Generation reads original pinned paths; verification admits relocated relative copies under B/p04-evidence. |
| wrapper | Exactly one distinct original pin path must match wrapper_sha256; descriptor uses that relocated copy. |
| runner-input row | Absolute path is constructed from the current B and the registered series run. supplied_file admits each registered run root. No earlier Root B is embedded by the builder. |
| C references | Constructed under current B/audit-support/native-first-current, one of supplied_file's fixed roots. |
| native_bundle | Same fixed native-first-current root under the supplied B. |
| authorities | ROOT-relative source paths, resolved against the invocation's gate.ROOT. |
| native and full raw references | Relative to each retained run/B, with original provenance retained. No analysis checkout is used as a payload identity. |
| S1–S4 / verify_fresh_* | Shared implementations in p04_native_series.py; no separate checkout-keyed dependency maps. Current metadata modules are found via __file__; that path is not returned as a fresh fact. Fresh wrapper loading now executes source bytes directly. |
| S5 adapters | Checkout-keyed dependency map corrected. Raw hash keys refer to the immutable raw input, not the analysis checkout. Explicit raw root is resolved before writer/reader references are formed. |
| readers | Independent Reader data is validated from raw run-relative references and recorded original provenance. bulk_reader_equivalence.py is a fixture using explicit scratch checkouts, not a production payload producer. |
| full_suite_verifier | Explicit Q root and retained run are inputs. Its reference map uses run-relative names. Metadata module loading now executes source bytes directly. |
| scratch_fixture_adapter | Explicit scratch routing only; no production compared payload. |
Transport does not make the entire B portable by itself. FreshSeries still
requires original Q source paths/project_root, the retained stage/formal copies,
and the exact engine file for identity reads (no engine launch). full-suite
verification also reads its recorded actual Q. If a later invocation changes B,
the registry/run hierarchy and these original-source contexts must still be
supplied. Missing context is a blocker; do not rewrite raw pins or the checker
to conceal it. Static supplied_file inspection found no additional absolute
descriptor admission gap in the builder's rows above. Runtime admission has
not been claimed.
## Historical failures and successes
The Q47 material admission failure is preserved verbatim in
REPAIR48_HISTORICAL_ROOT_Q47_ACTUAL_MATERIAL_ADMISSION_FAILURE.json.
All eight recorded attempts failed with their original `unsupplied external
material: ...` messages. The index generation traceback is preserved verbatim
in REPAIR48_HISTORICAL_ROOT_Q47_ACTUAL_INDEX_GENERATION.log, ending:
```text
ValueError: fresh raw recomputation drift
```
These are failures, not passing receipts. Original raw and historical receipts
remain unchanged. Their retained source is
build/owner-handoff/p04-after-p26-closure-r01/repair48-final-index-transport.
Root actually staged the S47 context under p04-fresh-context-r47, deviating from
the fixed p04-fresh-context name in the pre-REPAIR48 S5_ROOT_RUN.md line 167.
The old direction is retained as history. Material placement is now free-form
for builder relocation; no historical receipt is renamed or adopted.
Q47 native successes and the historical full 184 result (21903 checks, zero
reported failures, 329 parse paths, 186 ended PIDs, no guard/cleanup failures)
remain historical only. They are not C and cannot be reused under the new S.
The immutable checker still binds M/S/Q_tree; no adopter is introduced.
## Verification handoff
The worker performed syntax parsing and static source/path inspection only.
Per the final worker instruction that tests are formally executed by Runner,
no pure control, check-only plan, registered checker or engine was executed.
No result is inferred from a historical test count. No unaffected pure result
is reused without a complete code/dependency SHA proof; none is claimed here.
Runner controls added:
- repair48_transport_controls.py --retained <retained repair48-final-index-transport>
checks the real immutable S47 inputs/copies, r47 context and out-of-B Q pins,
relocation repeatability, duplicate/conflict rules, material adversaries,
wrapper failures, and the actual checker's old-S/new-S binding rejection
using simulated Git observations without Git writes.
- repair48_identity_controls.py --raw <retained S5 raw> --writer-sha <pin>
--reader-sha <pin> --build <complete retained relocated B> checks independent
same-byte complete analysis directories (S5 results and builder payload),
dependency mutations and mappings, symlinks,
outside paths, two read-only payload calls and unchanged B tree, index drift,
and external absolute descriptor rejection. The optional B section must be
supplied for the complete control, not omitted as an implicit pass.
All these controls remain UNEXECUTED. Required affected existing controls and
fresh check-only S1/S2a/S2b/S3/S4/S5 plans also remain Runner work. A dirty-only
failure has not been observed and is not invented. Source-ready is not a gate
pass. Runner must verify full negative coverage, including exclusive output,
pin-SHA mismatch and ambiguous wrapper bindings, before the native lease.
## Normal-gate material roster and Root order
Supply the exact B with native-first-current, historical relocation inputs,
fresh-run registry, every fresh run's runner-input/ended/source/UID/formal/raw
and lifecycle receipts, the exact recorded Q source and engine identity context;
B/p04-evidence/runner-materials with all pin copies and RELOCATION.json;
the matching fresh collection including MANIFEST and separate dependency
invocation record; and the matching full 184 run and its binding/raw receipts.
The final index and generation-invocation receipt belong to this same attempt.
Required original authorities and sources must exist in the frozen checkout.
Root's next order is unchanged: freeze new Q; affected pure controls; clean
exact-Q check-only; capacity/PID-end checks; one heavy native lease for
S1/S2a/S2b/S3/S4 and all ten S5 cases; readers/adapters; collect 15 EV and all
subclauses; full 184 once; index generation with relocation; registered
p04-acceptance once (no duplicate Root --verify-only); separate Opus whole-unit
review; normal prepare/C/integration/final/Root DB join/ledger/main push.
Only whole-unit acceptance can grant credit.
@@ -0,0 +1,41 @@
{
"before": {
"build_p04_index.py": "35b1b35f94e64f0f8c93ad5de17b35a16c2a81ca802691ba77251ad4256ca515",
"p04_native_series.py": "c33f8abb7f4ad143f75a1b761447a84afddb2dd0ac67b782e4cf9a8a67b67e4a",
"full_suite_verifier.py": "779ab0c0b5be31dcee462f04cbd6b765d44f9bef95fb52b03d3b676ec9f80c9c",
"collect_p04_native.py": "70a12149c770ef4dca97d3d5aa0b59270cf1547efde79ee7346ba340e1bebca6",
"s5/s5_order_adapter.py": "91344410b3441049fbce316cef9c227c9355747ae56890b45fcf348dac401d7e",
"s5/s5_power_adapter.py": "41d33e8d6b4e986611bdf7a0eedbde3f0b92f724ea37d3b2502ba4965a298462",
"s5/s5_guard_oracle.py": "b58ee46f5c8a82de796bffd88ff8cab89f1f9e7e5c9417414310a1b649dc6c1c",
"s5/s5_order_adapter_controls.py": "f1f90b9847830c6505a176bf78442e619b1d297c818ec561c92c498a4db74b53",
"s5/s5_power_adapter_controls.py": "32d71db80994052b905829e6a2da38448ae789825c44570a901e67fe2d07fd33"
},
"root_expected": {
"build_p04_index.py": "35b1b35f94e64f0f8c93ad5de17b35a16c2a81ca802691ba77251ad4256ca515",
"p04_native_series.py": "c33f8abb7f4ad143f75a1b761447a84afddb2dd0ac67b782e4cf9a8a67b67e4a",
"full_suite_verifier.py": "779ab0c0b5be31dcee462f04cbd6b765d44f9bef95fb52b03d3b676ec9f80c9c",
"collect_p04_native.py": "70a12149c770ef4dca97d3d5aa0b59270cf1547efde79ee7346ba340e1bebca6",
"s5/s5_order_adapter.py": "91344410b3441049fbce316cef9c227c9355747ae56890b45fcf348dac401d7e",
"s5/s5_power_adapter.py": "41d33e8d6b4e986611bdf7a0eedbde3f0b92f724ea37d3b2502ba4965a298462",
"s5/s5_guard_oracle.py": "b58ee46f5c8a82de796bffd88ff8cab89f1f9e7e5c9417414310a1b649dc6c1c",
"s5/s5_order_adapter_controls.py": "f1f90b9847830c6505a176bf78442e619b1d297c818ec561c92c498a4db74b53",
"s5/s5_power_adapter_controls.py": "32d71db80994052b905829e6a2da38448ae789825c44570a901e67fe2d07fd33"
},
"after": {
"build_p04_index.py": "35b1b35f94e64f0f8c93ad5de17b35a16c2a81ca802691ba77251ad4256ca515",
"p04_native_series.py": "c33f8abb7f4ad143f75a1b761447a84afddb2dd0ac67b782e4cf9a8a67b67e4a",
"full_suite_verifier.py": "779ab0c0b5be31dcee462f04cbd6b765d44f9bef95fb52b03d3b676ec9f80c9c",
"collect_p04_native.py": "70a12149c770ef4dca97d3d5aa0b59270cf1547efde79ee7346ba340e1bebca6",
"s5/s5_order_adapter.py": "91344410b3441049fbce316cef9c227c9355747ae56890b45fcf348dac401d7e",
"s5/s5_power_adapter.py": "41d33e8d6b4e986611bdf7a0eedbde3f0b92f724ea37d3b2502ba4965a298462",
"s5/s5_guard_oracle.py": "b58ee46f5c8a82de796bffd88ff8cab89f1f9e7e5c9417414310a1b649dc6c1c",
"s5/s5_order_adapter_controls.py": "f1f90b9847830c6505a176bf78442e619b1d297c818ec561c92c498a4db74b53",
"s5/s5_power_adapter_controls.py": "32d71db80994052b905829e6a2da38448ae789825c44570a901e67fe2d07fd33"
},
"unchanged": true,
"parse": "pass",
"tests_run": false,
"additional_protected": {
"s5/run_s5_native.py": "28d54f061a9a07ee7ab12e043170ae43760bb686354b1c682166e82d04ec35b3"
}
}
@@ -0,0 +1,225 @@
## REPAIR49 current correction
Source-ready only; original 30/88, formal 16, P04=0, no partial credit.
REPAIR48's specification-mismatch blocker below is historical and corrected:
the immutable 7000-byte original has SHA256
d28aadb044633f7d804de5a92c8d4c4a7438dfbf44c3243dca978951f4def25f;
removing its single EOF LF gives
9ec722e7dfb0bee178d291624a026420c08412574e238bba1fde012c7a6f7881.
This is the existing Git/Runner strip/checker one-EOF-LF pin contract.
No specification, approval or normalization change. Older contradictory wording
below is superseded history, including blanket full-reuse prohibitions and
all-controls-unexecuted wording. Q47 admission/index failures remain failures.
See REPAIR49_STATUS.md for closure audit and verbatim complete_B FileNotFoundError.
Root handoff reports payload(B), all53, series/join/power PASS; order-typed remains
UNDETERMINED. Worker did not rerun them. Corrected complete_B remains unexecuted.
Old native/full successes confer no new-S acceptance or credit.
## REPAIR49 full184 conditional reuse candidate — all conditions UNVERIFIED
Native reuse is forbidden: all six series require fresh M/S/Q_tree provenance
(p04_native_series.py:1287; checker:370). Full uses the existing separate binding
(checker:1175-1186); no adopter or checker change is authorized.
The following are requirements, not results or approval:
1. New S5 source_before must equal old full selected_source_map: all 1369 keys
and SHA values, not counts alone.
2. Old project_root must remain unchanged: source-start == current source_refs
== post-verification source_refs (full_suite_verifier.py:115).
3. selected_source_map, roster184, parse329, settings, runner/marker module,
marker contract, suite-policy and UID plan/stage must all match (116-152,225).
4. inputs.engine must match current engine_pin (124-125).
5. Revalidate every phase PID, cleanup, marker and diagnostics (154-228).
6. Current s5/run_s5_native.py and full_suite_verifier.py SHA must equal the
Root rehearsal versions.
7. Never relabel old S/oldQ/project_root/PIDs/time. Describe reuse only as
revalidating the exact-source-identical old full through the existing
full_suite route; never claim full ran on new S.
8. A separate Opus whole-unit review must independently confirm applicability.
Conditions 1–6 require actual checks after final freeze. If any predicate is
unproved or differs, reject reuse and execute full184 once on the final version.
SourceRefs (tools/run_all_tests.py:40-45) excludes docs/private package, but that
fact is no substitute for complete source equality. No reuse is approved here.
# REPAIR49 source-ready status
Original 30/88, formal 16, P04=0; no partial credit or whole-unit acceptance.
Worker static audit/parse only; all new controls remain Runner work.
## Explicit closure audit
All .py files are explicitly enumerated in CLOSURE, plus the six probe .gd files
and six ROOT_RUN documents used by package-local runner material references.
The list is fixed in source; a missing member cannot vanish through globbing.
No package-local JSON is read by the identity execution path: JSON inputs are
supplied B/raw/recorded Q. These external contexts remain required, not rewritten.
The original checker is loaded from the original checkout and supplied to both builders.
- `build_p04_index.py:46`: `path = Path(__file__).with_name('p04_native_series.py')`
- `build_p04_index.py:184`: `series_spec = importlib.util.spec_from_file_location('p04_index_series', Path(__file__).with_name('p04_native_series.py'))`
- `checker_join_fixtures.py:111`: `current_wrapper = series.digest((series.HERE / 's4/run_s4_native.py').read_bytes())`
- `full_suite_verifier.py:111`: `wrapper = module('p04_full_uid', Path(__file__).parent / 's5/run_s5_native.py')`
- `normal_c_join_fixtures.py:12`: `spec = importlib.util.spec_from_file_location("normal_c_join", HERE / "normal_c_join.py")`
- `p04_native_series.py:1001`: `S4_HISTORICAL_WRAPPER = HERE / 's4/historical/run_s4_native_r28.py.reference'`
- `p04_native_series.py:1013`: `require(receipt_sha256 == digest((HERE / 's4/run_s4_native.py').read_bytes()),`
- `p04_native_series.py:1035`: `qa = HERE / 's4/p04_s4_power_probe.gd'`
- `p04_native_series.py:1332`: `wrapper_path = Path(__file__).parent / 's5/run_s5_native.py'`
- `p04_native_series.py:1340`: `admission = wrapper.module('fresh_s4_admission', HERE / 's4/run_s4_native.py')`
- `p04_native_series.py:1432`: `path = Path(__file__).parent / 's5/s5_order_adapter.py'`
- `repair48_identity_controls.py:38`: `CLOSURE = ('build_p04_index.py', 'bulk_reader_equivalence.py', 'checker_applicability_fixtures.py', 'checker_approval_fixtures.py', 'checker_candidate_fixtures.py', 'checker_encoder_fixtures.py', 'checker_join_fixtures.py', 'checker_native_fixtures.py', 'checker_negative_fixtures.py', 'checker_role_fixtures.py', 'checker_series_fixtures.py', 'collect_p04_native.py', 'full_suite_verifier.py', 'normal_c_join.py', 'normal_c_join_fixtures.py', 'p04_native_series.py', 'repair48_identity_controls.py', 'repair48_transport_controls.py', 's1/S1_ROOT_RUN.md', 's1/p04_s1_ev_power_probe.gd', 's1/run_s1_native.py', 's2/S2_ROOT_RUN.md', 's2/p04_s2a_midnight_probe.gd', 's2/run_s2a_native.py', 's2b/S2B_ROOT_RUN.md', 's2b/p04_s2b_shift_probe.gd', 's2b/run_s2b_native.py', 's3/S3_ROOT_RUN.md', 's3/p04_s3_closure_probe.gd', 's3/run_s3_native.py', 's4/S4_ROOT_RUN.md', 's4/admission_controls.py', 's4/engine_identity_negative_fixtures.py', 's4/p04_s4_power_probe.gd', 's4/phase_cut_regression.py', 's4/receipt_lifecycle_fixtures.py', 's4/run_s4_native.py', 's5/S5_ROOT_RUN.md', 's5/p04_s5_power_probe.gd', 's5/repair44_controls.py', 's5/run_s5_native.py', 's5/s5_guard_oracle.py', 's5/s5_order_adapter.py', 's5/s5_order_adapter_controls.py', 's5/s5_power_adapter.py', 's5/s5_power_adapter_controls.py', 's5/s5_uid_controls.py', 's5/s5_wrapper_fixtures.py', 'scratch_fixture_adapter.py')`
- `repair48_identity_controls.py:71`: `shutil.copyfile(HERE / relative, target)`
- `repair48_identity_controls.py:86`: `original_builder = load(HERE / 'build_p04_index.py', 'original_builder')`
- `repair48_identity_controls.py:125`: `rejects(lambda: a.module('outside_identity', HERE / 's5/s5_guard_oracle.py'))`
- `repair48_identity_controls.py:128`: `builder = load(HERE / 'build_p04_index.py', 'identity_builder')`
- `repair48_transport_controls.py:14`: `spec = importlib.util.spec_from_file_location('transport', Path(__file__).with_name('build_p04_index.py'))`
- `s1/run_s1_native.py:20`: `QA = HERE / "p04_s1_ev_power_probe.gd"`
- `s1/run_s1_native.py:61`: `shared = module("fresh_q_shared", HERE.parent / "s5/run_s5_native.py")`
- `s1/run_s1_native.py:89`: `QA, Path(__file__), HERE / "S1_ROOT_RUN.md",`
- `s1/run_s1_native.py:119`: `fixed.append(pin(HERE.parent / "s5/run_s5_native.py"))`
- `s2/run_s2a_native.py:20`: `QA = HERE / "p04_s2a_midnight_probe.gd"`
- `s2/run_s2a_native.py:33`: `]] + [HERE.parent / "s1" / n for n in ["run_s1_native.py", "p04_s1_ev_power_probe.gd", "S1_ROOT_RUN.md"]]`
- `s2/run_s2a_native.py:82`: `shared = module("fresh_q_shared", HERE.parent / "s5/run_s5_native.py")`
- `s2/run_s2a_native.py:111`: `QA, Path(__file__), HERE / "S2_ROOT_RUN.md",`
- `s2/run_s2a_native.py:141`: `fixed.append(pin(HERE.parent / "s5/run_s5_native.py"))`
- `s2b/run_s2b_native.py:20`: `QA = HERE / "p04_s2b_shift_probe.gd"`
- `s2b/run_s2b_native.py:25`: `HERE.parent / folder / name for folder, name in [`
- `s2b/run_s2b_native.py:26`: `("s1", "run_s1_native.py"), ("s1", "S1_ROOT_RUN.md"),`
- `s2b/run_s2b_native.py:28`: `("s2", "S2_ROOT_RUN.md"),`
- `s2b/run_s2b_native.py:71`: `shared = module("fresh_q_shared", HERE.parent / "s5/run_s5_native.py")`
- `s2b/run_s2b_native.py:102`: `QA, Path(__file__), HERE / "S2B_ROOT_RUN.md",`
- `s2b/run_s2b_native.py:132`: `fixed.append(pin(HERE.parent / "s5/run_s5_native.py"))`
- `s3/run_s3_native.py:20`: `QA = HERE / "p04_s3_closure_probe.gd"`
- `s3/run_s3_native.py:31`: `MATERIALS = [MANIFEST, AUDIT, HERE.parent / "s2b/run_s2b_native.py",`
- `s3/run_s3_native.py:32`: `HERE.parent / "s2b/p04_s2b_shift_probe.gd", HERE.parent / "s2b/S2B_ROOT_RUN.md"]`
- `s3/run_s3_native.py:90`: `shared = module("fresh_q_shared", HERE.parent / "s5/run_s5_native.py")`
- `s3/run_s3_native.py:121`: `QA, Path(__file__), HERE / "S3_ROOT_RUN.md",`
- `s3/run_s3_native.py:151`: `fixed.append(pin(HERE.parent / "s5/run_s5_native.py"))`
- `s4/admission_controls.py:99`: `series = s4.module('admission_series', s4.HERE.parent / 'p04_native_series.py')`
- `s4/admission_controls.py:100`: `series_tree = ast.parse((s4.HERE.parent / 'p04_native_series.py').read_text())`
- `s4/admission_controls.py:105`: `wrapper = s4.module('admission_fresh_wrapper', s4.HERE.parent / 's5/run_s5_native.py')`
- `s4/admission_controls.py:124`: `historical = s4.HERE / 'historical/run_s4_native_r28.py.reference'`
- `s4/admission_controls.py:134`: `uid_plan, snapshot, _ = s4.module('admission_uid', s4.HERE.parent / 's5/run_s5_native.py').load_uid_helper(root, r, selected)`
- `s4/engine_identity_negative_fixtures.py:12`: `spec = importlib.util.spec_from_file_location("series", HERE.parent / "p04_native_series.py")`
- `s4/engine_identity_negative_fixtures.py:15`: `spec = importlib.util.spec_from_file_location("s4", HERE / "run_s4_native.py")`
- `s4/receipt_lifecycle_fixtures.py:36`: `s4 = load('receipt_s4_historical', HERE / 'historical/run_s4_native_r28.py.reference')`
- `s4/receipt_lifecycle_fixtures.py:38`: `series = load('receipt_series', HERE.parent / 'p04_native_series.py')`
- `s4/receipt_lifecycle_fixtures.py:42`: `tree = ast.parse((HERE.parent / 'p04_native_series.py').read_text())`
- `s4/receipt_lifecycle_fixtures.py:97`: `put(staged / 'run_s4_native.py', (HERE / 'historical/run_s4_native_r28.py.reference').read_bytes())`
- `s4/receipt_lifecycle_fixtures.py:98`: `put(staged / 'S4_ROOT_RUN.md', b'synthetic fixture material\n')`
- `s4/run_s4_native.py:21`: `QA = HERE / "p04_s4_power_probe.gd"`
- `s4/run_s4_native.py:136`: `shared = module("fresh_q_shared", HERE.parent / "s5/run_s5_native.py")`
- `s4/run_s4_native.py:177`: `QA, Path(__file__), HERE / "S4_ROOT_RUN.md",`
- `s4/run_s4_native.py:214`: `fixed.append(pin(HERE.parent / "s5/run_s5_native.py"))`
- `s4/run_s4_native.py:365`: `# The shared runner log is not write-once; see S4_ROOT_RUN.md.`
- `s5/repair44_controls.py:148`: `for name in ('S5_ROOT_RUN.md', 'PENDING.md'):`
- `s5/run_s5_native.py:26`: `QA = HERE / "p04_s5_power_probe.gd"`
- `s5/run_s5_native.py:33`: `matches = re.findall(r"^const CASE_TABLE: Dictionary = (\{.*?^\})", Path(path).read_text(), re.M | re.S)`
- `s5/run_s5_native.py:45`: `CASE_TABLE = case_table(QA)`
- `s5/run_s5_native.py:77`: `if len(seeds) != 1 or sorted(json.loads(seeds[0])) != CASES or sorted(case_table(QA)) != CASES:`
- `s5/run_s5_native.py:334`: `QA, Path(__file__), HERE / "S5_ROOT_RUN.md",`
- `s5/run_s5_native.py:527`: `# The shared runner log is not write-once; see S5_ROOT_RUN.md.`
- `s5/s5_order_adapter.py:46`: `POWER_PATH = Path(__file__).with_name('s5_power_adapter.py')`
- `s5/s5_order_adapter.py:50`: `GUARD_PATH = Path(__file__).with_name('s5_guard_oracle.py')`
- `s5/s5_order_adapter_controls.py:12`: `mutation = a.module('order_typed_mutation', Path(__file__).with_name('s5_power_adapter_controls.py'))`
- `s5/s5_power_adapter_controls.py:12`: `spec = importlib.util.spec_from_file_location("s5_power_adapter", Path(__file__).with_name("s5_power_adapter.py"))`
- `s5/s5_uid_controls.py:28`: `w = module('s5_uid_wrapper', Path(__file__).with_name('run_s5_native.py'))`
- `s5/s5_wrapper_fixtures.py:13`: `path = Path(__file__).parent / "run_s5_native.py"`
- `scratch_fixture_adapter.py:43`: `source = HERE / (args.fixture + ".py")`
Explicit closure membership:
- `build_p04_index.py`
- `bulk_reader_equivalence.py`
- `checker_applicability_fixtures.py`
- `checker_approval_fixtures.py`
- `checker_candidate_fixtures.py`
- `checker_encoder_fixtures.py`
- `checker_join_fixtures.py`
- `checker_native_fixtures.py`
- `checker_negative_fixtures.py`
- `checker_role_fixtures.py`
- `checker_series_fixtures.py`
- `collect_p04_native.py`
- `full_suite_verifier.py`
- `normal_c_join.py`
- `normal_c_join_fixtures.py`
- `p04_native_series.py`
- `repair48_identity_controls.py`
- `repair48_transport_controls.py`
- `s1/S1_ROOT_RUN.md`
- `s1/p04_s1_ev_power_probe.gd`
- `s1/run_s1_native.py`
- `s2/S2_ROOT_RUN.md`
- `s2/p04_s2a_midnight_probe.gd`
- `s2/run_s2a_native.py`
- `s2b/S2B_ROOT_RUN.md`
- `s2b/p04_s2b_shift_probe.gd`
- `s2b/run_s2b_native.py`
- `s3/S3_ROOT_RUN.md`
- `s3/p04_s3_closure_probe.gd`
- `s3/run_s3_native.py`
- `s4/S4_ROOT_RUN.md`
- `s4/admission_controls.py`
- `s4/engine_identity_negative_fixtures.py`
- `s4/p04_s4_power_probe.gd`
- `s4/phase_cut_regression.py`
- `s4/receipt_lifecycle_fixtures.py`
- `s4/run_s4_native.py`
- `s5/S5_ROOT_RUN.md`
- `s5/p04_s5_power_probe.gd`
- `s5/repair44_controls.py`
- `s5/run_s5_native.py`
- `s5/s5_guard_oracle.py`
- `s5/s5_order_adapter.py`
- `s5/s5_order_adapter_controls.py`
- `s5/s5_power_adapter.py`
- `s5/s5_power_adapter_controls.py`
- `s5/s5_uid_controls.py`
- `s5/s5_wrapper_fixtures.py`
- `scratch_fixture_adapter.py`
The fixture compares complete relative-path/bytes/SHA tables and canonical table
tree hashes for original/A/B before execution and after positive identity work.
Missing, traversal, outside paths and symlinks reject. Negative mutation phase is
separate; existing byte/missing/extra/mapping/symlink/outside cases remain.
A missing S5 .gd negative is added. complete_B_controls=true requires both
placements' S5 facts and entire payload equality. No raw or compared fields are
excluded or normalized. Actual three-placement proof is UNEXECUTED by worker;
Runner must retain the emitted before/after tables.
## Root handoff
Read ROOT_REPAIR49_CURRENT_EVIDENCE_AND_INDEPENDENT_SCOPE.json directly:
payload(B), all53, series/join/power PASS per Root report, engine0, no acceptance.
order-typed is UNDETERMINED and is not pass. Transport/raw-only/synthetic and
q4801 six-series collection are historical S47 successes, not new-S evidence.
Only the observed complete_B closure failure is repaired.
## Historical complete_B failure (verbatim)
```text
Traceback (most recent call last):
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement/docs/plans/original-completion-2026-10-02/execution/p04-01/repair48_identity_controls.py", line 115, in <module>
run(parser.parse_args())
File "/Users/korizatou114/Projects/TheTree-managed-worktrees/p04-01/P04-01-implement/docs/plans/original-completion-2026-10-02/execution/p04-01/repair48_identity_controls.py", line 60, in run
assert native[0].verify_fresh_s5(build) == native[1].verify_fresh_s5(build)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/private/var/folders/41/j8fq6vqj2993cmyprl6p76pw0000gn/T/p04-r48-identity-8veppaza/first/docs/plans/original-completion-2026-10-02/execution/p04-01/p04_native_series.py", line 1430, in verify_fresh_s5
s = FreshSeries(build, 's5')
^^^^^^^^^^^^^^^^^^^^^^^^
File "/private/var/folders/41/j8fq6vqj2993cmyprl6p76pw0000gn/T/p04-r48-identity-8veppaza/first/docs/plans/original-completion-2026-10-02/execution/p04-01/p04_native_series.py", line 1338, in __init__
exec(compile(wrapper_path.read_bytes(), str(wrapper_path), 'exec'), wrapper.__dict__)
File "/private/var/folders/41/j8fq6vqj2993cmyprl6p76pw0000gn/T/p04-r48-identity-8veppaza/first/docs/plans/original-completion-2026-10-02/execution/p04-01/s5/run_s5_native.py", line 45, in <module>
File "/private/var/folders/41/j8fq6vqj2993cmyprl6p76pw0000gn/T/p04-r48-identity-8veppaza/first/docs/plans/original-completion-2026-10-02/execution/p04-01/s5/run_s5_native.py", line 33, in case_table
File "/opt/homebrew/Cellar/python@3.12/3.12.13_2/Frameworks/Python.framework/Versions/3.12/lib/python3.12/pathlib.py", line 1027, in read_text
with self.open(mode='r', encoding=encoding, errors=errors) as f:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/python@3.12/3.12.13_2/Frameworks/Python.framework/Versions/3.12/lib/python3.12/pathlib.py", line 1013, in open
return io.open(self, mode, buffering, encoding, errors, newline)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '/private/var/folders/41/j8fq6vqj2993cmyprl6p76pw0000gn/T/p04-r48-identity-8veppaza/first/docs/plans/original-completion-2026-10-02/execution/p04-01/s5/p04_s5_power_probe.gd'
```
@@ -29,9 +29,155 @@ def descriptor(path):
return {'path': str(path.absolute()), 'bytes': len(data), 'sha256': hashlib.sha256(data).hexdigest()}
def require(value, message):
if not value:
raise ValueError(message)
def ordinary(path):
path = Path(path)
require('..' not in path.parts, 'parent traversal')
require(not any(p.is_symlink() for p in (path, *path.parents)), 'symlink path')
return path
def series_inputs(build):
registry = json.loads(ordinary(build / 'audit-support/p04-fresh-runs.json').read_bytes())
path = Path(__file__).with_name('p04_native_series.py')
spec = importlib.util.spec_from_file_location('transport_series', path)
module = importlib.util.module_from_spec(spec)
exec(compile(path.read_bytes(), str(path), 'exec'), module.__dict__)
require(set(registry['series']) == set(module.FRESH_RUNS), 'fresh series roster')
result = {}
for name in module.FRESH_RUNS:
run = Path(registry['series'][name]['run'])
require(not run.is_absolute() and '..' not in run.parts, 'fresh run path')
result[name] = json.loads(ordinary(build / run / 'runner-input.json').read_bytes())
return result
def pin_roster(inputs):
result = {}
for pin in inputs['fixed_input_pins'] + [inputs['QA']]:
path = pin['path']
ordinary(path)
require(Path(path).is_absolute(), 'pin source must be absolute')
require(type(pin['bytes']) is int and pin['bytes'] >= 0, 'pin bytes')
digest = pin['sha256']
require(isinstance(digest, str) and len(digest) == 64
and all(c in '0123456789abcdef' for c in digest), 'pin SHA')
identity = {'bytes': pin['bytes'], 'sha256': digest}
require(path not in result or result[path] == identity, 'conflicting duplicate pin')
result[path] = identity
return result
def relative_material(series, original, pin):
return f"runner-materials/{series}/{pin['sha256']}/{Path(original).name}"
def all_rosters(inputs):
rosters, seen = {}, {}
for name, raw in inputs.items():
rosters[name] = pin_roster(raw)
for original, pin in rosters[name].items():
require(original not in seen or seen[original] == pin, 'conflicting duplicate pin across series')
seen[original] = pin
return rosters
def material_layout(inputs):
rosters = all_rosters(inputs)
layout, seen, destinations = {}, {}, {}
for name, roster in rosters.items():
layout[name] = {}
for original, pin in roster.items():
identity = (original, pin['bytes'], pin['sha256'])
relative = seen.setdefault(identity, relative_material(name, original, pin))
require(relative not in destinations or destinations[relative] == identity,
'distinct pins collide at material destination')
destinations[relative] = identity
layout[name][original] = relative
return rosters, layout
def checked_material(path, pin):
data = ordinary(path).read_bytes()
require(len(data) == pin['bytes'] and hashlib.sha256(data).hexdigest() == pin['sha256'],
'material pin mismatch')
return data
def relocate_materials(build, output):
build = ordinary(Path(build).absolute()).resolve(strict=True)
output = ordinary(Path(output).absolute())
require(output == build / 'p04-evidence', 'output must be B/p04-evidence')
output.mkdir()
mapping = {}
inputs = series_inputs(build)
rosters, layout = material_layout(inputs)
written = set()
for name, roster in rosters.items():
mapping[name] = {}
for original, pin in roster.items():
relative = layout[name][original]
target = output / relative
if relative not in written:
data = checked_material(original, pin)
target.parent.mkdir(parents=True, exist_ok=True)
with target.open('xb') as stream:
stream.write(data)
written.add(relative)
checked_material(target, pin)
mapping[name][original] = {'relative': relative, **pin}
with (output / 'runner-materials/RELOCATION.json').open('x') as stream:
json.dump(mapping, stream, sort_keys=True, indent=2)
stream.write('\n')
return mapping
def relocated_materials(build):
output = ordinary(build / 'p04-evidence')
map_path = ordinary(output / 'runner-materials/RELOCATION.json')
def unique(pairs):
result = {}
for key, value in pairs:
require(key not in result, 'duplicate relocation key')
result[key] = value
return result
mapping = json.loads(map_path.read_bytes(), object_pairs_hook=unique)
inputs = series_inputs(build)
rosters, layout = material_layout(inputs)
require(set(mapping) == set(inputs), 'relocation series roster')
descriptors = {}
expected_files = {'runner-materials/RELOCATION.json'}
for name, raw in inputs.items():
roster = rosters[name]
require(set(mapping[name]) == set(roster), 'relocation material roster')
descriptors[name] = {}
for original, pin in roster.items():
relative = layout[name][original]
require(mapping[name][original] == {'relative': relative, **pin}, 'relocation mapping mismatch')
checked_material(output / relative, pin)
expected_files.add(relative)
descriptors[name][original] = {'path': relative, **pin}
wrappers = [path for path, pin in roster.items() if pin['sha256'] == raw['wrapper_sha256']]
require(len(wrappers) == 1, 'exactly one wrapper pin required')
actual_files = set()
for path in (output / 'runner-materials').rglob('*'):
ordinary(path)
if path.is_file():
actual_files.add(path.relative_to(output).as_posix())
require(actual_files == expected_files, 'unmapped material')
return inputs, descriptors, {'path': 'runner-materials/RELOCATION.json',
'bytes': map_path.stat().st_size,
'sha256': hashlib.sha256(map_path.read_bytes()).hexdigest()}
def payload(build, gate=None):
gate = gate or checker()
build = Path(build).resolve(strict=True)
build = ordinary(Path(build).absolute()).resolve(strict=True)
inputs_by_series, materials_by_series, relocation_descriptor = relocated_materials(build)
native = build / 'audit-support/native-first-current'
c = gate.verify_native(native)
raw = gate.combine_native_series(build, c)
@@ -48,16 +194,12 @@ def payload(build, gate=None):
path = gate.safe(build, run_binding['run'] + '/runner-input.json')
inputs = gate.load(path)
row = descriptor(path)
row['materials'] = {}
for pin in inputs.get('fixed_input_pins', []) + [inputs['QA']]:
material = descriptor(Path(pin['path']))
gate.require(material['bytes'] == pin['bytes'] and material['sha256'] == pin['sha256'],
'fresh material changed')
gate.supplied_file(build, material)
row['materials'][pin['path']] = material
wrapper = next(p for p in inputs['fixed_input_pins']
if p['sha256'] == inputs['wrapper_sha256'])
row['wrapper'] = descriptor(Path(wrapper['path']))
require(inputs == inputs_by_series[name], 'runner input changed during payload')
row['materials'] = materials_by_series[name]
wrappers = [p for p in row['materials']
if row['materials'][p]['sha256'] == inputs['wrapper_sha256']]
require(len(wrappers) == 1, 'exactly one wrapper pin required')
row['wrapper'] = row['materials'][wrappers[0]]
runners.append(row)
# C references retain every lifecycle, raw phase, source, environment and
# formal member mapping; Stage R retains its complete original->relocated map.
@@ -102,7 +244,8 @@ def payload(build, gate=None):
reachability[name] = {'reach': name == 'EV', 'case_id': 'EV' if name == 'EV' else None, 'source_refs': refs,
'raw_verified': 'EV' in raw['verified_conditions'] if name == 'EV' else None}
delta = gate.source_delta(gate.REGISTERED_COMMIT, tested)
index = {'schema_version': 2, 'task_id': 'P04-01', 'formal_acceptance': False,
index = {'runner_material_relocation': relocation_descriptor,
'schema_version': 2, 'task_id': 'P04-01', 'formal_acceptance': False,
'versions': {'registered': gate.REGISTERED_COMMIT, 'execution_origin': gate.EXECUTION_ORIGIN,
'tested': tested},
'product_binding': {'tested_product': tested, 'runner_inputs': runners},
@@ -127,17 +270,16 @@ def payload(build, gate=None):
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--build', required=True, type=Path)
parser.add_argument('--output', required=True, type=Path, help='fresh directory; exclusive creation')
parser.add_argument('--output', type=Path, help='exact B/p04-evidence; exclusive creation')
parser.add_argument('--invocation', required=True, choices=('validate', 'prepare-integration', 'final'))
parser.add_argument('--registered-ref', required=True)
parser.add_argument('--tested-ref', required=True)
args = parser.parse_args()
gate = checker()
os.environ['BUILD_OUTPUT_DIR'] = str(args.build.resolve(strict=True))
output = args.output.absolute()
gate.require(not output.exists() and not output.is_symlink(), 'output must be fresh')
for path in output.parents:
gate.require(not path.is_symlink(), 'output parent symlink')
output = args.output or Path(os.environ.get('P04_EVIDENCE_DIR', str(args.build.resolve() / 'p04-evidence')))
output = output.absolute()
relocate_materials(args.build, output)
index = payload(args.build, gate)
gate.require(args.registered_ref == gate.REGISTERED_COMMIT and
args.tested_ref == index['versions']['tested'],
@@ -147,11 +289,15 @@ def main():
# The historical invocation is separate from the reusable evidence index.
receipt = {'invocation': args.invocation, 'actual_head': role['actual_head'],
'actual_tree': role['actual_tree'], 'role': role['role'], 'formal_acceptance': False}
output.mkdir(parents=False)
try:
for name, value in (('index.json', index), ('generation-invocation.json', receipt)):
with (output / name).open('x', encoding='utf-8') as stream:
json.dump(value, stream, ensure_ascii=False, sort_keys=True, indent=2)
stream.write('\n')
except BaseException:
# The exclusively created directory is a failed attempt, never evidence.
(output / 'index.json').unlink(missing_ok=True)
raise
print(json.dumps({'evidence_directory': str(output), **receipt}))
@@ -45,6 +45,9 @@ def collect(build, fresh=None):
'collector_sha256': series.digest(Path(__file__).read_bytes()),
'historical_merged': False, 'large_payloads_copied': 0}
payloads['MANIFEST.json'] = encoded(manifest)
if fresh:
# This is an invocation/transport record, never compared as S5 facts.
payloads['dependency-invocation.json'] = encoded(series.S5_DEPENDENCY_INVOCATION)
estimate = sum(len(v) for v in payloads.values())
# The estimate precedes all writes. Reserve extra directory/allocation space.
print(json.dumps({'estimated_payload_bytes': estimate, 'files': len(payloads),
@@ -12,9 +12,13 @@ def require(value, message):
def module(name, path):
path = Path(path).absolute()
require('..' not in path.parts and all(not p.is_symlink() for p in (path, *path.parents)),
'module ordinary path')
data = path.read_bytes()
spec = importlib.util.spec_from_file_location(name, path)
result = importlib.util.module_from_spec(spec)
spec.loader.exec_module(result)
exec(compile(data, str(path), 'exec'), result.__dict__)
return result
@@ -1333,7 +1333,9 @@ class FreshSeries(Series):
import importlib.util
spec = importlib.util.spec_from_file_location('fresh_series_wrapper', wrapper_path)
wrapper = importlib.util.module_from_spec(spec)
spec.loader.exec_module(wrapper)
require(all(not p.is_symlink() for p in (wrapper_path, *wrapper_path.parents)),
'fresh wrapper ordinary path')
exec(compile(wrapper_path.read_bytes(), str(wrapper_path), 'exec'), wrapper.__dict__)
if self.name == 's4':
admission = wrapper.module('fresh_s4_admission', HERE / 's4/run_s4_native.py')
product = {n: p for n, p in selected.items() if n != admission.CHECKER}
@@ -1430,7 +1432,18 @@ def verify_fresh_s5(build):
path = Path(__file__).parent / 's5/s5_order_adapter.py'
spec = importlib.util.spec_from_file_location('fresh_order_adapter', path)
adapter = importlib.util.module_from_spec(spec)
spec.loader.exec_module(adapter)
require('..' not in path.parts and all(not p.is_symlink() for p in (path, *path.parents)),
'S5 adapter ordinary package path')
adapter_bytes = path.read_bytes()
exec(compile(adapter_bytes, str(path), 'exec'), adapter.__dict__)
# Transport-only observations are retained by collect(), outside s5.json.
global S5_DEPENDENCY_INVOCATION
S5_DEPENDENCY_INVOCATION = {
'checkout': str(HERE.parents[4]),
'adapter': {'path': str(path.absolute()), 'sha256': digest(adapter_bytes)},
'dependencies': dict(adapter.DEPENDENCY_OBSERVATIONS),
'dependency_sha256': dict(adapter.DEPENDENCIES),
}
arguments = (s.base / 'raw', s.inventory['writer.json']['sha256'], s.inventory['reader.json']['sha256'])
power = adapter.power.derive(*arguments)
order = adapter.derive(*arguments)
@@ -0,0 +1,153 @@
#!/usr/bin/env python3
"""Runner-only retained-raw identity controls; no engine or acceptance run."""
import argparse
import copy
import hashlib
import importlib.util
import json
from pathlib import Path
import shutil
import sys
import tempfile
sys.dont_write_bytecode = True
HERE = Path(__file__).resolve().parent
def load(path, name):
spec = importlib.util.spec_from_file_location(name, path)
value = importlib.util.module_from_spec(spec)
exec(compile(path.read_bytes(), str(path), 'exec'), value.__dict__)
return value
def rejects(call):
try:
call()
except (ValueError, OSError, KeyError, TypeError):
return
raise AssertionError('negative admitted')
def tree(root):
return {p.relative_to(root).as_posix(): hashlib.sha256(p.read_bytes()).hexdigest()
for p in root.rglob('*') if p.is_file()}
# Explicit audited package-local closure; see REPAIR49_STATUS.md.
CLOSURE = ('build_p04_index.py', 'bulk_reader_equivalence.py', 'checker_applicability_fixtures.py', 'checker_approval_fixtures.py', 'checker_candidate_fixtures.py', 'checker_encoder_fixtures.py', 'checker_join_fixtures.py', 'checker_native_fixtures.py', 'checker_negative_fixtures.py', 'checker_role_fixtures.py', 'checker_series_fixtures.py', 'collect_p04_native.py', 'full_suite_verifier.py', 'normal_c_join.py', 'normal_c_join_fixtures.py', 'p04_native_series.py', 'repair48_identity_controls.py', 'repair48_transport_controls.py', 's1/S1_ROOT_RUN.md', 's1/p04_s1_ev_power_probe.gd', 's1/run_s1_native.py', 's2/S2_ROOT_RUN.md', 's2/p04_s2a_midnight_probe.gd', 's2/run_s2a_native.py', 's2b/S2B_ROOT_RUN.md', 's2b/p04_s2b_shift_probe.gd', 's2b/run_s2b_native.py', 's3/S3_ROOT_RUN.md', 's3/p04_s3_closure_probe.gd', 's3/run_s3_native.py', 's4/S4_ROOT_RUN.md', 's4/admission_controls.py', 's4/engine_identity_negative_fixtures.py', 's4/p04_s4_power_probe.gd', 's4/phase_cut_regression.py', 's4/receipt_lifecycle_fixtures.py', 's4/run_s4_native.py', 's5/S5_ROOT_RUN.md', 's5/p04_s5_power_probe.gd', 's5/repair44_controls.py', 's5/run_s5_native.py', 's5/s5_guard_oracle.py', 's5/s5_order_adapter.py', 's5/s5_order_adapter_controls.py', 's5/s5_power_adapter.py', 's5/s5_power_adapter_controls.py', 's5/s5_uid_controls.py', 's5/s5_wrapper_fixtures.py', 'scratch_fixture_adapter.py')
def package_snapshot(root):
root = Path(root).absolute()
rows = {}
for name in CLOSURE:
relative = Path(name)
if relative.is_absolute() or '..' in relative.parts:
raise ValueError('closure traversal/outside')
path = root / relative
if (any(p.is_symlink() for p in (path, *path.parents))
or not path.resolve(strict=True).is_relative_to(root.resolve(strict=True))
or not path.is_file()):
raise ValueError('closure missing/symlink/outside: ' + name)
data = path.read_bytes()
rows[name] = {'bytes': len(data), 'sha256': hashlib.sha256(data).hexdigest()}
encoded = json.dumps(rows, sort_keys=True, separators=(',', ':')).encode()
return {'files': rows, 'tree_sha256': hashlib.sha256(encoded).hexdigest()}
def run(args):
raw = args.raw.resolve(strict=True)
with tempfile.TemporaryDirectory(prefix='p04-r48-identity-') as directory:
base = Path(directory).resolve()
suffix = Path('docs/plans/original-completion-2026-10-02/execution/p04-01')
packages = [base / name / suffix for name in ('first', 'second')]
original_package = package_snapshot(HERE)
names = [Path(name) for name in CLOSURE]
for package in packages:
for relative in names:
target = package / relative
target.parent.mkdir(parents=True, exist_ok=True)
shutil.copyfile(HERE / relative, target)
snapshots_before = [package_snapshot(root) for root in (HERE, *packages)]
assert all(row == original_package for row in snapshots_before)
a, b = [load(p / 's5/s5_order_adapter.py', 'identity_' + str(i))
for i, p in enumerate(packages)]
first = a.derive(raw, args.writer_sha, args.reader_sha)
assert b.derive(raw, args.writer_sha, args.reader_sha) == first
assert a.DEPENDENCY_OBSERVATIONS != b.DEPENDENCY_OBSERVATIONS
if args.build:
build = args.build.resolve(strict=True)
before = tree(build)
# These independent packages execute the same complete analysis bytes.
native = [load(p / 'p04_native_series.py', 'native_' + str(i))
for i, p in enumerate(packages)]
assert native[0].verify_fresh_s5(build) == native[1].verify_fresh_s5(build)
original_builder = load(HERE / 'build_p04_index.py', 'original_builder')
gate = original_builder.checker()
builders = [load(p / 'build_p04_index.py', 'builder_' + str(i))
for i, p in enumerate(packages)]
assert builders[0].payload(build, gate) == builders[1].payload(build, gate)
assert tree(build) == before
snapshots_after = [package_snapshot(root) for root in (HERE, *packages)]
assert snapshots_after == snapshots_before
missing = packages[1] / 's5/p04_s5_power_probe.gd'
saved = missing.read_bytes()
missing.unlink()
rejects(lambda: package_snapshot(packages[1]))
missing.write_bytes(saved)
assert package_snapshot(packages[1]) == original_package
for kind in ('byte', 'missing', 'extra', 'mapping'):
original = copy.deepcopy(a.DEPENDENCIES)
key = next(iter(original))
if kind == 'byte':
a.DEPENDENCIES[key] = '0' * 64
elif kind == 'missing':
del a.DEPENDENCIES[key]
elif kind == 'extra':
a.DEPENDENCIES['extra.py'] = '0' * 64
else:
a.DEPENDENCY_OBSERVATIONS[key] = '/outside-package.py'
rejects(lambda: a.derive(raw, args.writer_sha, args.reader_sha))
a.DEPENDENCIES.clear()
a.DEPENDENCIES.update(original)
a.DEPENDENCY_OBSERVATIONS.update(a._EXECUTED_OBSERVATIONS)
target = packages[1] / 's5/s5_guard_oracle.py'
target.write_bytes(target.read_bytes() + b'\n')
changed = load(packages[1] / 's5/s5_order_adapter.py', 'changed_identity')
assert changed.DEPENDENCIES != a.DEPENDENCIES
# Reject the changed payload at the same equality boundary used for recomputation.
rejects(lambda: a.require(changed.derive(raw, args.writer_sha, args.reader_sha) == first,
'fresh raw recomputation drift'))
target.unlink()
target.symlink_to(packages[0] / 's5/s5_guard_oracle.py')
rejects(lambda: load(packages[1] / 's5/s5_order_adapter.py', 'symlink_identity'))
rejects(lambda: a.module('outside_identity', HERE / 's5/s5_guard_oracle.py'))
target.unlink()
target.write_bytes((HERE / 's5/s5_guard_oracle.py').read_bytes())
assert [package_snapshot(root) for root in (HERE, *packages)] == snapshots_before
if args.build:
# A retained complete B is required. Never call the registered checker main().
builder = load(HERE / 'build_p04_index.py', 'identity_builder')
build = args.build.resolve(strict=True)
before = tree(build)
first = builder.payload(build)
assert builder.payload(build) == first and tree(build) == before
changed = copy.deepcopy(first)
changed['runner_material_relocation']['sha256'] = '0' * 64
rejects(lambda: builder.require(changed == builder.payload(build), 'index recomputation mismatch'))
rejects(lambda: builder.checker().supplied_file(build, {
'path': '/outside-B/material', 'bytes': 0, 'sha256': '0' * 64}))
assert package_snapshot(HERE) == original_package
print(json.dumps({'identity_controls': 'pass', 'complete_B_controls': bool(args.build),
'formal_acceptance': False,
'closure_before': snapshots_before, 'closure_after': snapshots_after}))
if __name__ == '__main__':
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--raw', type=Path, required=True)
parser.add_argument('--writer-sha', required=True)
parser.add_argument('--reader-sha', required=True)
parser.add_argument('--build', type=Path)
run(parser.parse_args())
@@ -0,0 +1,159 @@
#!/usr/bin/env python3
"""Runner-only, engine-free retained-copy transport controls. No acceptance."""
import argparse
import copy
import hashlib
import importlib.util
import json
from pathlib import Path
import tempfile
from unittest.mock import patch
import sys
sys.dont_write_bytecode = True
spec = importlib.util.spec_from_file_location('transport', Path(__file__).with_name('build_p04_index.py'))
builder = importlib.util.module_from_spec(spec)
spec.loader.exec_module(builder)
def sha(data):
return hashlib.sha256(data).hexdigest()
def tree(root):
return {p.relative_to(root).as_posix(): sha(p.read_bytes())
for p in root.rglob('*') if p.is_file()}
def rejects(call):
try:
call()
except (ValueError, OSError, KeyError, TypeError):
return
raise AssertionError('negative admitted')
def run(retained):
manifest = json.loads((retained / 'REAL_S47_PINNED_MATERIAL_COPIES.json').read_bytes())
inputs, sources = {}, {}
for name, row in manifest['series'].items():
data = (retained / row['raw_input']).read_bytes()
assert len(data) == row['bytes'] and sha(data) == row['sha256']
inputs[name] = json.loads(data)
for original, row in manifest['materials'].items():
data = (retained / row['retained_copy']).read_bytes()
assert len(data) == row['bytes'] and sha(data) == row['sha256']
sources[original] = data
assert any('p04-fresh-context-r47' in p for p in sources)
assert any('P04-01-root-q-r47' in p for p in sources)
original_checked = builder.checked_material
def retained_checked(path, pin):
if str(path) in sources:
data = sources[str(path)]
builder.require(len(data) == pin['bytes'] and sha(data) == pin['sha256'], 'retained pin')
return data
return original_checked(path, pin)
with tempfile.TemporaryDirectory(prefix='p04-repair48-') as directory:
build = Path(directory).resolve()
with patch.object(builder, 'series_inputs', return_value=inputs), \
patch.object(builder, 'checked_material', side_effect=retained_checked):
output = build / 'p04-evidence'
rejects(lambda: builder.relocate_materials(build, build / 'wrong'))
assert not output.exists()
builder.relocate_materials(build, output)
rejects(lambda: builder.relocate_materials(build, output))
before = tree(build)
first = builder.relocated_materials(build)
assert builder.relocated_materials(build) == first and tree(build) == before
map_path = output / 'runner-materials/RELOCATION.json'
map_bytes = map_path.read_bytes()
mapping = json.loads(map_bytes)
identities = {(pin['path'], pin['bytes'], pin['sha256'])
for raw in inputs.values() for pin in raw['fixed_input_pins'] + [raw['QA']]}
assert len({row['relative'] for rows in mapping.values() for row in rows.values()}) == len(identities)
series = next(iter(inputs))
original = next(iter(mapping[series]))
target = output / mapping[series][original]['relative']
data = target.read_bytes()
target.write_bytes(data + b'x')
rejects(lambda: builder.relocated_materials(build))
target.write_bytes(data)
target.unlink()
target.symlink_to(map_path)
rejects(lambda: builder.relocated_materials(build))
target.unlink()
target.write_bytes(data)
for kind in ('missing', 'extra', 'mapping', 'traversal', 'external'):
changed = copy.deepcopy(mapping)
if kind == 'missing':
del changed[series][original]
elif kind == 'extra':
changed[series]['/extra'] = changed[series][original]
else:
changed[series][original]['relative'] = {
'mapping': 'runner-materials/wrong', 'traversal': '../outside',
'external': '/outside-B'}[kind]
map_path.write_text(json.dumps(changed))
rejects(lambda: builder.relocated_materials(build))
map_path.write_bytes(map_bytes)
extra = output / 'runner-materials/unmapped'
extra.write_bytes(b'extra')
rejects(lambda: builder.relocated_materials(build))
extra.unlink()
for digest in ('0' * 64, None):
altered = copy.deepcopy(inputs)
altered[series]['wrapper_sha256'] = digest
with patch.object(builder, 'series_inputs', return_value=altered):
rejects(lambda: builder.relocated_materials(build))
# A second distinct pin carrying wrapper bytes is ambiguous.
altered = copy.deepcopy(inputs)
wrapper = next(p for p in altered[series]['fixed_input_pins']
if p['sha256'] == altered[series]['wrapper_sha256'])
altered[series]['fixed_input_pins'].append(dict(wrapper, path='/different-wrapper'))
with patch.object(builder, 'series_inputs', return_value=altered):
rejects(lambda: builder.relocated_materials(build))
assert tree(build) == before
raw = copy.deepcopy(next(iter(inputs.values())))
pin = copy.deepcopy(raw['QA'])
raw['fixed_input_pins'].append(pin)
assert len(builder.pin_roster(raw)) == len({p['path'] for p in raw['fixed_input_pins'] + [raw['QA']]})
with tempfile.TemporaryDirectory(prefix='p04-r48-dedup-') as directory:
build = Path(directory).resolve()
with patch.object(builder, 'series_inputs', return_value={'s1': raw}), \
patch.object(builder, 'checked_material', side_effect=retained_checked):
mapping = builder.relocate_materials(build, build / 'p04-evidence')
assert len(mapping['s1']) == len(builder.pin_roster(raw))
builder.relocated_materials(build)
raw['fixed_input_pins'].append(dict(pin, bytes=pin['bytes'] + 1))
rejects(lambda: builder.pin_roster(raw))
rejects(lambda: builder.ordinary('/a/../b'))
changed = copy.deepcopy(inputs)
series = next(iter(changed))
changed[series]['QA']['sha256'] = '0' * 64
rejects(lambda: builder.all_rosters(changed))
# Exercise the actual immutable checker's role binding predicate, with
# simulated Git observations only. No objects, refs or checkouts are written.
gate = builder.checker()
old = next(iter(inputs.values()))['provenance']
new_submission, composed = 'f' * 40, 'e' * 40
assert old['S'] != new_submission
with patch.object(gate, 'actual_checkout', return_value=(new_submission, composed, {})), \
patch.object(gate, '_GIT_ENV', {}), \
patch.object(gate, 'ancestor', return_value=False), \
patch.object(gate, 'submission_role'), \
patch.object(gate, 'git_bytes', return_value=composed.encode()):
try:
gate.verify_roles({'fresh_run_bindings': old}, Path('/retained-B'))
except ValueError as error:
assert str(error) == 'fresh evidence does not bind recomputed Q'
else:
raise AssertionError('old S47 bindings admitted under new S')
print(json.dumps({'retained_S47_transport_controls': 'pass', 'formal_acceptance': False}))
if __name__ == '__main__':
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--retained', type=Path, required=True)
run(parser.parse_args().retained.resolve(strict=True))
@@ -1,3 +1,26 @@
## REPAIR49 normal-gate handoff
Required materials: exact B/native-first-current and fresh-run registry; each
runner-input/ended/source/UID/formal/raw/lifecycle receipt; original recorded Q
and engine context; B/p04-evidence/runner-materials and RELOCATION.json; matching
collection/MANIFEST and separate dependency invocation; original full run and
full_suite binding/raw receipts; final index and invocation receipt; immutable
authorities in frozen checkout. No raw or historical receipt is rewritten.
Two-placement identity requires the explicit closure in repair48_identity_controls.py,
missing-file rejection, and original/A/B complete path/bytes/SHA tables and tree
hash equality before and after positive execution. See REPAIR49_STATUS.md.
Submission is followed by new Q freeze, affected pure controls (complete_B included),
clean exact-Q check-only, capacity/PID checks, one fresh native lease for
S1/S2a/S2b/S3/S4 and all ten S5 cases, readers/adapters, 15EV collector, full
verification/binding under the conditions below (or one final full184 if any
condition fails), index generation, p04-acceptance once, separate Opus whole-unit
review, normal prepare/C/integration/final/Root DB join/ledger/main push.
If order-typed fails, preserve its result and stop before heavy execution.
Only whole-unit acceptance grants credit.
REPAIR48 current source status: see [REPAIR48_STATUS.md](../REPAIR48_STATUS.md). Earlier run directions and successes below are historical; they grant no P04 credit.
# S1 Root run(コード準備のみ)
S1コード準備完了・未実測・原P04 whole未達。D05 pending、A未検証。
@@ -1,3 +1,26 @@
## REPAIR49 normal-gate handoff
Required materials: exact B/native-first-current and fresh-run registry; each
runner-input/ended/source/UID/formal/raw/lifecycle receipt; original recorded Q
and engine context; B/p04-evidence/runner-materials and RELOCATION.json; matching
collection/MANIFEST and separate dependency invocation; original full run and
full_suite binding/raw receipts; final index and invocation receipt; immutable
authorities in frozen checkout. No raw or historical receipt is rewritten.
Two-placement identity requires the explicit closure in repair48_identity_controls.py,
missing-file rejection, and original/A/B complete path/bytes/SHA tables and tree
hash equality before and after positive execution. See REPAIR49_STATUS.md.
Submission is followed by new Q freeze, affected pure controls (complete_B included),
clean exact-Q check-only, capacity/PID checks, one fresh native lease for
S1/S2a/S2b/S3/S4 and all ten S5 cases, readers/adapters, 15EV collector, full
verification/binding under the conditions below (or one final full184 if any
condition fails), index generation, p04-acceptance once, separate Opus whole-unit
review, normal prepare/C/integration/final/Root DB join/ledger/main push.
If order-typed fails, preserve its result and stop before heavy execution.
Only whole-unit acceptance grants credit.
REPAIR48 current source status: see [REPAIR48_STATUS.md](../REPAIR48_STATUS.md). Earlier run directions and successes below are historical; they grant no P04 credit.
# P04-01 S2a Root run(code-ready提出用・実測未実施)
repair12確認: worktreeのoperations_coordinator.gd SHA256は
@@ -1,3 +1,26 @@
## REPAIR49 normal-gate handoff
Required materials: exact B/native-first-current and fresh-run registry; each
runner-input/ended/source/UID/formal/raw/lifecycle receipt; original recorded Q
and engine context; B/p04-evidence/runner-materials and RELOCATION.json; matching
collection/MANIFEST and separate dependency invocation; original full run and
full_suite binding/raw receipts; final index and invocation receipt; immutable
authorities in frozen checkout. No raw or historical receipt is rewritten.
Two-placement identity requires the explicit closure in repair48_identity_controls.py,
missing-file rejection, and original/A/B complete path/bytes/SHA tables and tree
hash equality before and after positive execution. See REPAIR49_STATUS.md.
Submission is followed by new Q freeze, affected pure controls (complete_B included),
clean exact-Q check-only, capacity/PID checks, one fresh native lease for
S1/S2a/S2b/S3/S4 and all ten S5 cases, readers/adapters, 15EV collector, full
verification/binding under the conditions below (or one final full184 if any
condition fails), index generation, p04-acceptance once, separate Opus whole-unit
review, normal prepare/C/integration/final/Root DB join/ledger/main push.
If order-typed fails, preserve its result and stop before heavy execution.
Only whole-unit acceptance grants credit.
REPAIR48 current source status: see [REPAIR48_STATUS.md](../REPAIR48_STATUS.md). Earlier run directions and successes below are historical; they grant no P04 credit.
RUN47 note: Earlier 1338-source native instructions below describe the historical relocation. Current fresh-Q selection uses exact source/manifest equality, never a literal file count. See ../REPAIR47_PLAN.json.
# P04-01 S2b code preparation
@@ -1,3 +1,26 @@
## REPAIR49 normal-gate handoff
Required materials: exact B/native-first-current and fresh-run registry; each
runner-input/ended/source/UID/formal/raw/lifecycle receipt; original recorded Q
and engine context; B/p04-evidence/runner-materials and RELOCATION.json; matching
collection/MANIFEST and separate dependency invocation; original full run and
full_suite binding/raw receipts; final index and invocation receipt; immutable
authorities in frozen checkout. No raw or historical receipt is rewritten.
Two-placement identity requires the explicit closure in repair48_identity_controls.py,
missing-file rejection, and original/A/B complete path/bytes/SHA tables and tree
hash equality before and after positive execution. See REPAIR49_STATUS.md.
Submission is followed by new Q freeze, affected pure controls (complete_B included),
clean exact-Q check-only, capacity/PID checks, one fresh native lease for
S1/S2a/S2b/S3/S4 and all ten S5 cases, readers/adapters, 15EV collector, full
verification/binding under the conditions below (or one final full184 if any
condition fails), index generation, p04-acceptance once, separate Opus whole-unit
review, normal prepare/C/integration/final/Root DB join/ledger/main push.
If order-typed fails, preserve its result and stop before heavy execution.
Only whole-unit acceptance grants credit.
REPAIR48 current source status: see [REPAIR48_STATUS.md](../REPAIR48_STATUS.md). Earlier run directions and successes below are historical; they grant no P04 credit.
RUN47 note: Earlier 1338-source native instructions below describe the historical relocation. Current fresh-Q selection uses exact source/manifest equality, never a literal file count. See ../REPAIR47_PLAN.json.
# P04-01 S3 code-ready preparation
@@ -1,3 +1,26 @@
## REPAIR49 normal-gate handoff
Required materials: exact B/native-first-current and fresh-run registry; each
runner-input/ended/source/UID/formal/raw/lifecycle receipt; original recorded Q
and engine context; B/p04-evidence/runner-materials and RELOCATION.json; matching
collection/MANIFEST and separate dependency invocation; original full run and
full_suite binding/raw receipts; final index and invocation receipt; immutable
authorities in frozen checkout. No raw or historical receipt is rewritten.
Two-placement identity requires the explicit closure in repair48_identity_controls.py,
missing-file rejection, and original/A/B complete path/bytes/SHA tables and tree
hash equality before and after positive execution. See REPAIR49_STATUS.md.
Submission is followed by new Q freeze, affected pure controls (complete_B included),
clean exact-Q check-only, capacity/PID checks, one fresh native lease for
S1/S2a/S2b/S3/S4 and all ten S5 cases, readers/adapters, 15EV collector, full
verification/binding under the conditions below (or one final full184 if any
condition fails), index generation, p04-acceptance once, separate Opus whole-unit
review, normal prepare/C/integration/final/Root DB join/ledger/main push.
If order-typed fails, preserve its result and stop before heavy execution.
Only whole-unit acceptance grants credit.
REPAIR48 current source status: see [REPAIR48_STATUS.md](../REPAIR48_STATUS.md). Earlier run directions and successes below are historical; they grant no P04 credit.
## RUN47 current admission (supersedes earlier execution instructions)
Current S4 check-only and native call the same engine-free `admission` function.
@@ -1,3 +1,54 @@
## REPAIR49 normal-gate handoff
Required materials: exact B/native-first-current and fresh-run registry; each
runner-input/ended/source/UID/formal/raw/lifecycle receipt; original recorded Q
and engine context; B/p04-evidence/runner-materials and RELOCATION.json; matching
collection/MANIFEST and separate dependency invocation; original full run and
full_suite binding/raw receipts; final index and invocation receipt; immutable
authorities in frozen checkout. No raw or historical receipt is rewritten.
Two-placement identity requires the explicit closure in repair48_identity_controls.py,
missing-file rejection, and original/A/B complete path/bytes/SHA tables and tree
hash equality before and after positive execution. See REPAIR49_STATUS.md.
Submission is followed by new Q freeze, affected pure controls (complete_B included),
clean exact-Q check-only, capacity/PID checks, one fresh native lease for
S1/S2a/S2b/S3/S4 and all ten S5 cases, readers/adapters, 15EV collector, full
verification/binding under the conditions below (or one final full184 if any
condition fails), index generation, p04-acceptance once, separate Opus whole-unit
review, normal prepare/C/integration/final/Root DB join/ledger/main push.
If order-typed fails, preserve its result and stop before heavy execution.
Only whole-unit acceptance grants credit.
## REPAIR49 full184 conditional reuse candidate — all conditions UNVERIFIED
Native reuse is forbidden: all six series require fresh M/S/Q_tree provenance
(p04_native_series.py:1287; checker:370). Full uses the existing separate binding
(checker:1175-1186); no adopter or checker change is authorized.
The following are requirements, not results or approval:
1. New S5 source_before must equal old full selected_source_map: all 1369 keys
and SHA values, not counts alone.
2. Old project_root must remain unchanged: source-start == current source_refs
== post-verification source_refs (full_suite_verifier.py:115).
3. selected_source_map, roster184, parse329, settings, runner/marker module,
marker contract, suite-policy and UID plan/stage must all match (116-152,225).
4. inputs.engine must match current engine_pin (124-125).
5. Revalidate every phase PID, cleanup, marker and diagnostics (154-228).
6. Current s5/run_s5_native.py and full_suite_verifier.py SHA must equal the
Root rehearsal versions.
7. Never relabel old S/oldQ/project_root/PIDs/time. Describe reuse only as
revalidating the exact-source-identical old full through the existing
full_suite route; never claim full ran on new S.
8. A separate Opus whole-unit review must independently confirm applicability.
Conditions 1–6 require actual checks after final freeze. If any predicate is
unproved or differs, reject reuse and execute full184 once on the final version.
SourceRefs (tools/run_all_tests.py:40-45) excludes docs/private package, but that
fact is no substitute for complete source equality. No reuse is approved here.
REPAIR48 current source status: see [REPAIR48_STATUS.md](../REPAIR48_STATUS.md). Earlier run directions and successes below are historical; they grant no P04 credit.
# REPAIR45 handoff
## REPAIR45 — implementation ready for submission
@@ -5,11 +5,41 @@ import importlib.util
import json
from pathlib import Path
PACKAGE_ROOT = Path(__file__).absolute().parents[1]
DEPENDENCIES = {}
DEPENDENCY_OBSERVATIONS = {}
_EXECUTED_DEPENDENCIES = {}
_EXECUTED_OBSERVATIONS = {}
def module(name, path):
path = Path(path).absolute()
if '..' in path.parts or any(p.is_symlink() for p in (path, *path.parents)):
raise ValueError('dependency traversal/symlink')
if not path.resolve(strict=True).is_relative_to(PACKAGE_ROOT.resolve(strict=True)):
raise ValueError('dependency outside package')
relative = path.relative_to(PACKAGE_ROOT).as_posix()
data = path.read_bytes()
spec = importlib.util.spec_from_file_location(name, path)
value = importlib.util.module_from_spec(spec)
spec.loader.exec_module(value)
exec(compile(data, str(path), 'exec'), value.__dict__)
DEPENDENCIES[relative] = hashlib.sha256(data).hexdigest()
DEPENDENCY_OBSERVATIONS[relative] = str(path)
for key, digest in getattr(value, 'DEPENDENCIES', {}).items():
dependency = Path(key)
if dependency.is_absolute() or '..' in dependency.parts:
raise ValueError('dependency key must be package relative')
observed = Path(value.DEPENDENCY_OBSERVATIONS[key])
if (observed != PACKAGE_ROOT / dependency
or any(p.is_symlink() for p in (observed, *observed.parents))
or not observed.resolve(strict=True).is_relative_to(PACKAGE_ROOT.resolve(strict=True))):
raise ValueError('dependency mapping outside package/symlink')
if key in DEPENDENCIES and DEPENDENCIES[key] != digest:
raise ValueError('dependency mapping conflict')
DEPENDENCIES[key] = digest
DEPENDENCY_OBSERVATIONS[key] = value.DEPENDENCY_OBSERVATIONS[key]
_EXECUTED_DEPENDENCIES.update(DEPENDENCIES)
_EXECUTED_OBSERVATIONS.update(DEPENDENCY_OBSERVATIONS)
return value
@@ -17,11 +47,11 @@ POWER_PATH = Path(__file__).with_name('s5_power_adapter.py')
power = module('s5_order_power', POWER_PATH)
Raw, staff_check, duplicate_check = power.Raw, power.staff_check, power.duplicate_check
series, require = power.series, power.require
DEPENDENCIES = {str(p): hashlib.sha256(p.read_bytes()).hexdigest()
for p in (POWER_PATH, power.SERIES_PATH)}
GUARD_PATH = Path(__file__).with_name('s5_guard_oracle.py')
guard_oracle = module('s5_guard_oracle', GUARD_PATH)
DEPENDENCIES[str(GUARD_PATH)] = hashlib.sha256(GUARD_PATH.read_bytes()).hexdigest()
if (set(DEPENDENCIES) != {'s5/s5_power_adapter.py', 'p04_native_series.py', 's5/s5_guard_oracle.py'}
or power.DEPENDENCIES != {'p04_native_series.py': power.SERIES_SHA256}):
raise ValueError('loaded dependency roster mismatch')
GUEST, REQUEST = power.GUEST, power.REQUEST
SECOND, SECOND_REQUEST = 'p04.s5.guest.b', 'p04.s5.request.b'
@@ -415,7 +445,10 @@ DERIVERS = {'S5C_DESTRUCTION_COMMAND': destruction_command, 'S5D_DESTRUCTION_RAI
def derive(root, writer_sha, reader_sha):
root = Path(root)
require(DEPENDENCIES == _EXECUTED_DEPENDENCIES
and DEPENDENCY_OBSERVATIONS == _EXECUTED_OBSERVATIONS,
'dependency identity differs from executed module roster')
root = Path(root).resolve(strict=True)
raw = Raw(root)
writer = json.loads(raw.pin(root / 'writer.json', writer_sha), object_pairs_hook=power.unique)
reader = json.loads(raw.pin(root / 'reader.json', reader_sha), object_pairs_hook=power.unique)
@@ -11,11 +11,20 @@ import struct
import json
from pathlib import Path
SERIES_PATH = Path(__file__).resolve().parents[1] / 'p04_native_series.py'
SERIES_SHA256 = hashlib.sha256(SERIES_PATH.read_bytes()).hexdigest()
PACKAGE_ROOT = Path(__file__).absolute().parents[1]
SERIES_PATH = PACKAGE_ROOT / 'p04_native_series.py'
for _path in (SERIES_PATH, *SERIES_PATH.parents):
if _path.is_symlink():
raise ValueError('dependency symlink')
if not SERIES_PATH.resolve(strict=True).is_relative_to(PACKAGE_ROOT.resolve(strict=True)):
raise ValueError('dependency outside package')
_series_bytes = SERIES_PATH.read_bytes()
SERIES_SHA256 = hashlib.sha256(_series_bytes).hexdigest()
_spec = importlib.util.spec_from_file_location('s5_power_series', SERIES_PATH)
series = importlib.util.module_from_spec(_spec)
_spec.loader.exec_module(series)
exec(compile(_series_bytes, str(SERIES_PATH), 'exec'), series.__dict__)
DEPENDENCIES = {'p04_native_series.py': SERIES_SHA256}
DEPENDENCY_OBSERVATIONS = {'p04_native_series.py': str(SERIES_PATH)}
CASES = ("S5A_PURE", "S5B_DEPENDENCY")
GUEST = "p04.s5.guest.a"
@@ -96,6 +105,7 @@ def duplicate_check(replay_node, recorded):
def derive(root, writer_sha, reader_sha):
root = Path(root).resolve(strict=True)
raw = Raw(root)
writer = json.loads(raw.pin(root / "writer.json", writer_sha), object_pairs_hook=unique)
reader = json.loads(raw.pin(root / "reader.json", reader_sha), object_pairs_hook=unique)