P04-01: 同時発生の更新規約
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user