P18-REG-KITCHEN-LEGACY14: P18承認済み保存移行と厨房旧14回帰の整合(原88件に加算しない補助)

This commit is contained in:
Agent Control Runner
2026-10-16 07:16:55 +09:00
parent 9b1a18c1eb
commit 52ce2f125c
6 changed files with 699 additions and 5 deletions
@@ -78,7 +78,7 @@
"template": "Required kitchen: <checks> checks, <failures> failures", "template": "Required kitchen: <checks> checks, <failures> failures",
"required": true, "required": true,
"fixed_check_count_used": false, "fixed_check_count_used": false,
"source_sha256_at_schema_audit": "90e7639f5aa76e34b9ee14769f4ec1ae1317a647900b27877075dbf21ef1dfcf", "source_sha256_at_schema_audit": "3a9c92f80c24064ef0858fba10bd7caab63203932942837f7e142349578f6b2f",
"authority": { "authority": {
"path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p09-kitchen-single-link-candidate-r09/candidates/tests/business/test_required_kitchen.gd", "path": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p09-kitchen-single-link-candidate-r09/candidates/tests/business/test_required_kitchen.gd",
"sha256": "90e7639f5aa76e34b9ee14769f4ec1ae1317a647900b27877075dbf21ef1dfcf", "sha256": "90e7639f5aa76e34b9ee14769f4ec1ae1317a647900b27877075dbf21ef1dfcf",
@@ -86,7 +86,7 @@
}, },
"source_marker_lines": [ "source_marker_lines": [
{ {
"line": 281, "line": 481,
"text": "\tprint(\"Required kitchen: %d checks, %d failures\" % [checks, failures])" "text": "\tprint(\"Required kitchen: %d checks, %d failures\" % [checks, failures])"
} }
] ]
@@ -0,0 +1,65 @@
{
"task_id": "P18-REG-KITCHEN-LEGACY14",
"base_commit": "9b1a18c1eb25ca1300dcd59da78423c0dda2f498",
"state": "code-ready; tests NOT RUN; Root native proof pending",
"canonical_source_delta": {
"authority_file": "MAIN9B_COMPLETE_SOURCE_REFS.json",
"authority_bytes": 376039,
"authority_sha256": "dc43e665be3f02d14513f0b8c4248d410175dcfb118171d8cbe0e62ef764a2e4",
"canonical_count": 1338,
"docs_in_canonical_map": false,
"path": "tests/business/test_required_kitchen.gd",
"old": {"bytes": 31533, "sha256": "5dcc86d66bdc47003472d6c30d6889eb514e016003265965bdd8496d123d5ca5"},
"new": {"bytes": 38276, "sha256": "3a9c92f80c24064ef0858fba10bd7caab63203932942837f7e142349578f6b2f"},
"other_entries_same_keys_and_hashes": 1337,
"added_keys": [],
"dropped_keys": []
},
"marker_delta": {
"path": "docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json",
"separate_fixed_authority": true,
"old": {"bytes": 188089, "sha256": "6ce6b28c5985e8a4f13b78bfeb1f1e09f6216d874fb01e0656ec1633bfa01cd7"},
"new": {"bytes": 188089, "sha256": "9c095df16eb6848e5b3b34cd78aef1c57a7724e875eb8371d3ff4c2c8cc349a1"},
"changed_rows": [{
"test": "tests/business/test_required_kitchen.gd",
"source_sha256_at_schema_audit": {
"old": "90e7639f5aa76e34b9ee14769f4ec1ae1317a647900b27877075dbf21ef1dfcf",
"new": "3a9c92f80c24064ef0858fba10bd7caab63203932942837f7e142349578f6b2f"
},
"source_marker_lines": {
"old": [{"line": 281, "text": "\tprint(\"Required kitchen: %d checks, %d failures\" % [checks, failures])"}],
"new": [{"line": 481, "text": "\tprint(\"Required kitchen: %d checks, %d failures\" % [checks, failures])"}]
}
}],
"authority_records_changed": false,
"other_rows_changed": false,
"fixed_check_count_used": false,
"predicted_native_checks": 163,
"actual_native_checks": null
},
"new_support_path_group": {
"path": "docs/plans/original-completion-2026-10-02/execution/p18-kitchen-legacy-support/",
"files": ["plan.md", "delta-manifest.json", "verify_support.py", "root_diagnostic.py"]
},
"full_selected_map": {
"required_count": 1339,
"composition": "current canonical 1338 plus exactly the fixed reviewed P04 extra",
"extra_path": "tools/check_p04_order_evidence.py",
"extra_bytes": 78235,
"extra_sha256": "f5b44827958f2ae352fe5c4bc3a1ffd4211ec7a41fc4c0759c8b954891662324"
},
"zero_changes": ["autoload", "scripts", "scenes", "resources", "project.godot", "export", "policy", "engine", "legacy_fixture"],
"grep": {
"pattern": "test_required_kitchen\\.gd",
"canonical_source_reference_search_exit": 1,
"canonical_source_reference_matches": [],
"repository_reference_matches": "docs only (including archived manifests); edited definition is the kitchen test itself",
"source_consumers_outside_the_test": 0
},
"existing_source_manifest_rewritten": false,
"generic_exclusions_added": false,
"tests_run": false,
"independent_review": "pending",
"integration": "pending",
"native_Windows": "not claimed"
}
@@ -0,0 +1,120 @@
# P18-REG-KITCHEN-LEGACY14 source submission
Requirement: `legacy_preservation`. Base remains
`9b1a18c1eb25ca1300dcd59da78423c0dda2f498`. This is uncounted support;
original30/88 and the acceptance denominator do not change. Product code, P04,
settings, thresholds, suite policy, fixture bytes and fixture authority are unchanged.
## Diagnosis and exact migration
The old14 writer is v1, while the approved P18 relationship service saves a v2
container. The five typed differences are all below
`/systems/runtime/relationships`: version 1 becomes 2, `legacy` is added,
`original_relationships` is added, and `threshold_candidates` and
`next_candidate_sequence` move into `legacy`. The retained full native typed
inputs are 159552 and 159680 bytes, an increase of 128 bytes. Their SHA-256 values
are respectively `a2f8992853ba9497539cdfcb74d22c83c76011f2acf73f9e8e3e7241620ddca0`
and `a2f3e75181071f94946369df6f3a6256998dd7d776441766bccc9b9c3ccf5d8d`.
They diagnose the earlier failure; they are never substituted into a new run.
The genuine local `write-checkpoint.var` contains the old v1 dictionary at byte
offsets [143668,143816): **148 bytes**, SHA-256
`ed2cafb629f4d08249f8cd147c7ff9fc715ff641c24809a93e66a1229d4105c4`.
This was obtained by reading the original fixture bytes, including its dictionary
header, StringName keys, typed empty Dictionary arrays, and int values. The new
native proof independently hashes `var_to_bytes(old)` and the whole fixture file.
The pure validator requires the exact old field set/key encoding, int version 1,
byte-identical nested legacy, int version 2, exact v2 field set, unchanged sequence,
byte-identical compatibility projection and typed empty original records. It builds
the container in the service's insertion order with StringName keys and typed
`Array[Dictionary]`. Original values stay unconfigured: no conversion from old
five-axis values and no guessed original initialization.
After the existing identity/saveID-bound IO1 replacement, a reader copy with just
relationships reversed to v1 must equal the entire expected writer byte stream.
Only that subtree is then replaced. Whole typed bytes, Dictionary equality,
SimulationDigest, IO validity, envelope, replaced==1 and published IDs remain
required. Only legacy14 opts in. new14 has the same behavior and proof shape.
Seventeen in-memory controls cover an outside change, each legacy field deleted
and changed, sequence +1, nonempty originals, actual versions 0/3/string, equal
reordered/reencoded dictionaries, and a byte-identical deep-copy positive control.
Every attempt checks both caller inputs and both attempted copies for mutation.
There are 17 new assertions plus one fresh proof-file assertion, so the native
success path is expected to report 163 checks (the existing 145 remain). This
arithmetic is a gate expectation, not an observed native result. The final print
wording and schema are unchanged; the marker contract continues to derive counts
from raw output (`fixed_check_count_used: false`).
## Source map and authority
`MAIN9B_COMPLETE_SOURCE_REFS.json` was read locally after its 376039-byte SHA-256
`dc43e665be3f02d14513f0b8c4248d410175dcfb118171d8cbe0e62ef764a2e4`
was checked. Its canonical 1338 keys exclude docs. The only changed selected entry
is `tests/business/test_required_kitchen.gd`; all other 1337 keys and hashes match.
The selected map hash before this change is
`533a4177918a9da4d4982aa9862cb7420c25d30c2458e36aab9c071c4d3a7139`.
Absolute production paths in those records are provenance, never input paths.
The completion-marker contract is a separately pinned, second changed existing
file. Its pre-change bytes were 188089 with SHA-256
`6ce6b28c5985e8a4f13b78bfeb1f1e09f6216d874fb01e0656ec1633bfa01cd7`.
Only the kitchen source SHA and actual marker line position change; authority,
template, count policy and other entries remain byte-for-byte unchanged.
The newly added support directory is the third allowed path group. The tree as a
whole is not described as exactly two paths. See `delta-manifest.json`.
Root's selected full-run map must be exactly these current 1338 files plus
`tools/check_p04_order_evidence.py`, 78235 bytes, SHA-256
`f5b44827958f2ae352fe5c4bc3a1ffd4211ec7a41fc4c0759c8b954891662324`.
This is the fixed supplied reviewed P04 QA source, not permission to edit P04 or
read its build. The verifier compares local relative keys and full file pins,
rejecting additions, drops and stale sources. It introduces no selector exclusions.
Static reference search:
```sh
rg -l 'test_required_kitchen\.gd' autoload scripts scenes data tests assets tools project.godot export_presets.cfg Makefile AGENTS.md
rg -l 'test_required_kitchen\.gd' docs
```
The first command returned no matches (exit 1). The second finds documentation
and archived manifests only; there are no other source consumers of the test.
The test itself is the edited definition. This search does not rewrite manifests.
## Root-only finite local diagnostic procedure
Worker has run **no tests, engine, Runner, Git or agents**. Python support files
were compiled in memory only. GDScript import/parse and native results are pending.
Root must use the existing `godot` guarded launcher supported by the current tools;
do not point any command directly at a player profile. Run from this checkout in
one shell, stop on the first nonzero exit, and do not retry into an existing output.
If an output already exists, retain it and obtain a newly registered build before
a new collection. The helper uses the existing `execute_phase`, Guard, owned outer
launcher and `run_p18_relationship_tests.py` roster/archive APIs. It changes no
production collector, policy or threshold. All source copying is private.
```sh
export BUILD_OUTPUT_DIR=/Users/korizatou114/Projects/TheTree-managed-worktrees/p18-kitchen-regression-r02/.runtime/P18-REG-KITCHEN-LEGACY14/build
set -e
python3 docs/plans/original-completion-2026-10-02/execution/p18-kitchen-legacy-support/root_diagnostic.py --phase parse
python3 docs/plans/original-completion-2026-10-02/execution/p18-kitchen-legacy-support/root_diagnostic.py --phase kitchen
python3 docs/plans/original-completion-2026-10-02/execution/p18-kitchen-legacy-support/root_diagnostic.py --phase affected
python3 docs/plans/original-completion-2026-10-02/execution/p18-kitchen-legacy-support/root_diagnostic.py --phase full
python3 docs/plans/original-completion-2026-10-02/execution/p18-kitchen-legacy-support/verify_support.py --verify-only --marker-contracts docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json
```
Order is import/all-script parse, required_kitchen alone, all business plus all
s4 relationship tests/all s6/P18 affected set, then the new standard full178.
Every phase retains import/parse and exact-source receipts; the full phase invokes
the unchanged `run_all_tests.main` with the explicit 1339 source input and marker
contract. `archive_profiles` retains all actual private profiles under the build,
including the kitchen typed proofs, checked against native inventories. The
read-only verifier reads those receipts, raw stdout/stderr/native logger streams,
and PID lifecycle evidence; it launches nothing and emits no PASS of its own.
Missing future evidence correctly exits nonzero and does not block writing code.
Root will formally verify P04 separately in P04A repair. Independent Opus review,
integration and final verification remain required before any original-unit credit.
No native Windows behavior or whole-unit completion is claimed.
@@ -0,0 +1,126 @@
#!/usr/bin/env python3
"""Root-only finite diagnostics, using existing guarded native phase APIs.
This is an execution procedure, not worker evidence or an acceptance gate.
"""
import argparse
import hashlib
import json
import os
from pathlib import Path
import shutil
import sys
import uuid
sys.dont_write_bytecode = True
ROOT = Path(__file__).resolve().parents[5]
sys.path.insert(0, str(ROOT / 'tools'))
import run_p18_relationship_tests as p18
s = p18.shared
def main():
parser = argparse.ArgumentParser(allow_abbrev=False)
parser.add_argument('--phase', required=True, choices=['parse', 'kitchen', 'affected', 'full'])
args = parser.parse_args()
build = Path(os.environ['BUILD_OUTPUT_DIR']).resolve(strict=True)
out = build / {'parse': 'native-parse', 'kitchen': 'native-kitchen',
'affected': 'native-affected', 'full': 'native-full178'}[args.phase]
s.require(not out.exists(), 'fresh output; no automatic retry or evidence splice')
prior = {'kitchen': 'native-parse', 'affected': 'native-kitchen', 'full': 'native-affected'}
if args.phase in prior:
previous = s.read(build / prior[args.phase] / 'runner-ended.json')
s.require(previous['error'] is None and previous['cleanup_errors'] == []
and previous['guard_errors'] == [], 'preceding diagnostic must finish successfully')
refs = s.source_refs(ROOT)
checker = build / 'audit-support/root-input-r01/P04_REVIEWED_CANDIDATE_CHECKER.py'
s.require(checker.stat().st_size == 78235 and s.sha(checker)
== 'f5b44827958f2ae352fe5c4bc3a1ffd4211ec7a41fc4c0759c8b954891662324', 'fixed local P04 extra')
extra = {'path': str(checker), 'bytes': 78235, 'sha256': s.sha(checker)}
s.require('tools/check_p04_order_evidence.py' not in refs
or {k: refs['tools/check_p04_order_evidence.py'][k] for k in ('bytes', 'sha256')}
== {k: extra[k] for k in ('bytes', 'sha256')}, 'no replacement of a different P04 source')
refs['tools/check_p04_order_evidence.py'] = extra
s.require(len(refs) == 1339, 'prospective full source set')
marker_path = ROOT / 'docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json'
if args.phase == 'full':
selected = build / 'kitchen-selected-1339.json'
s.write(selected, refs)
code = s.main(['--project-root', str(ROOT), '--output', str(out), '--marker-contracts', str(marker_path),
'--source-input-refs', str(selected)])
# Retain the actual profiles under BUILD_OUTPUT_DIR while they still
# exist. Archive helper checks every byte against native phase inventory.
for row in s.read(out / 'runner-ended.json')['phases']:
p18.archive_profiles(out, row)
return code
root_before = s.source_refs(ROOT)
roster = [] if args.phase == 'parse' else ['tests/business/test_required_kitchen.gd']
if args.phase == 'affected':
roster = sorted(set(n for n in refs if n.startswith('tests/business/test') and n.endswith('.gd'))
| set(p18.ROSTER)
| set(n for n in refs if n.startswith('tests/s6/test') and n.endswith('.gd'))
| set(n for n in refs if n.startswith('tests/s4/test') and n.endswith('.gd') and 'relationship' in n))
markers = s.module('kitchen_diagnostic_markers', ROOT / 'tools/strict_test_markers.py')
contracts = markers.load_contracts(marker_path)
policy = s.read(s.SUPPORT / 'suite-policy.json')
s.policy_coverage(roster, refs, policy)
engine = shutil.which('godot')
s.require(engine, 'existing guarded native launcher required')
engine = str(Path(engine).resolve())
outer = s.module('kitchen_diagnostic_outer', s.SUPPORT / 'owned_outer.py')
s.require(not outer.native.helper['live_engines'](), 'one owned engine; no concurrent run')
s.require(shutil.disk_usage(build).free >= sum(p['bytes'] for p in refs.values()) + s.MIN_SPACE, 'unchanged disk admission')
out.mkdir()
stage = out / 'stage'; stage.mkdir()
(out / 'starters').mkdir(); (out / 'bootstrap').mkdir()
for name, entry in s.read(s.SUPPORT / 'bootstrap-scripts.json').items():
data = entry['text'].encode()
s.require(hashlib.sha256(data).hexdigest() == entry['sha256'], 'exact existing bootstrap')
(out / 'bootstrap' / name).write_bytes(data)
for name, entry in refs.items():
target = stage / name; target.parent.mkdir(parents=True, exist_ok=True)
s.copy_source(Path(entry['path']), target)
expected = {n: {k: p[k] for k in ('bytes', 'sha256')} for n, p in refs.items()}
s.require(s.inventory(stage, stage=True) == expected, 'whole private source copy')
public = (ROOT / 'project.godot').read_bytes()
protected = s.default_player(ROOT)
paths = ['res://' + n for n in sorted(refs) if n.endswith('.gd')]
s.write(out / 'parse-paths.json', paths)
selected = {'root_before': root_before, 'map': {n: p['sha256'] for n, p in refs.items()}, 'timeout': 1200}
run_id = uuid.uuid4().hex
s.write(out / 'runner-input.json', {'protocol': 'kitchen-diagnostic-v1', 'run_id': run_id,
'roster': roster, 'selected_source_map': selected['map'], 'default_player_before': protected})
s.write(out / 'source-start.json', root_before)
diagnostic = s.module('kitchen_diag_gate', s.SUPPORT / 'diagnostic_gate.py')
owners = s.module('kitchen_diag_owners', s.SUPPORT / 'ordinary_proof_gate.py')
audio = s.module('kitchen_diag_audio', s.SUPPORT / 'audio_evidence_gate.py')
phases = []; rows = []; generated = {}; error = None; guard_errors = []
try:
for phase, test in [('import', None), ('parse', None)] + [(f'{i:03}', n) for i, n in enumerate(roster)]:
row = s.execute_phase(engine, stage, out, phase, test, selected, expected, generated,
policy, contracts, paths, public, protected, ROOT, outer, markers, diagnostic, owners, audio)
p18.archive_profiles(out, row)
phases.append(row)
if test:
row.update(sequence=len(rows), godot=engine); rows.append(row)
(out / 'all-tests.json').write_text(json.dumps(rows, ensure_ascii=False, indent=2) + '\n')
s.require(row['passed'], 'first strict native failure stops: ' + phase)
except BaseException as caught:
error = type(caught).__name__ + ': ' + str(caught)
finally:
cleanup, cleanup_errors = outer.finish_captured(outer.OWNED)
try:
s.require(s.source_refs(ROOT) == root_before and s.default_player(ROOT) == protected, 'whole source/default unchanged')
s.require(s.inventory(stage, stage=True) == dict(expected, **generated), 'whole stage unchanged')
s.require(all(r['engine_ended'] for r in cleanup), 'all native PIDs ended')
except BaseException as caught:
guard_errors.append(str(caught))
s.write(out / 'runner-ended.json', {'protocol': 'kitchen-diagnostic-v1', 'run_id': run_id, 'error': error,
'cleanup_errors': cleanup_errors, 'guard_errors': guard_errors, 'final_owned_cleanup': cleanup,
'phases': phases, 'default_player_after': s.default_player(ROOT)})
return int(error is not None or bool(cleanup_errors) or bool(guard_errors))
if __name__ == '__main__':
raise SystemExit(main())
@@ -0,0 +1,284 @@
#!/usr/bin/env python3
"""Read-only Root evidence gate. No collection, engine launch, or PASS emission."""
import argparse
import hashlib
import importlib.util
import json
import os
from pathlib import Path
import sys
sys.dont_write_bytecode = True
ROOT = Path(__file__).resolve().parents[5]
KITCHEN = 'tests/business/test_required_kitchen.gd'
MARKER = 'docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json'
EXTRA = 'tools/check_p04_order_evidence.py'
EXTRA_PIN = {'bytes': 78235, 'sha256': 'f5b44827958f2ae352fe5c4bc3a1ffd4211ec7a41fc4c0759c8b954891662324'}
BASE_PIN = {'bytes': 376039, 'sha256': 'dc43e665be3f02d14513f0b8c4248d410175dcfb118171d8cbe0e62ef764a2e4'}
MARKER_PIN = {'bytes': 188089, 'sha256': '6ce6b28c5985e8a4f13b78bfeb1f1e09f6216d874fb01e0656ec1633bfa01cd7'}
def require(ok, reason):
if not ok:
raise ValueError(reason)
def pin(path):
data = path.read_bytes()
return {'bytes': len(data), 'sha256': hashlib.sha256(data).hexdigest()}
def unique(pairs):
result = {}
for key, value in pairs:
require(key not in result, 'duplicate JSON key: ' + key)
result[key] = value
return result
def read(path):
return json.loads(path.read_bytes(), object_pairs_hook=unique)
def local(base, name):
name = Path(name)
require(not name.is_absolute() and '..' not in name.parts, 'relative evidence key required')
path = base / name
require(path.resolve().is_relative_to(base.resolve()), 'evidence escapes build directory')
require(not any(p.is_symlink() for p in [path, *path.parents] if p != base.parent), 'evidence alias')
return path
def load(name, path):
spec = importlib.util.spec_from_file_location(name, path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
def pins(refs):
# Absolute production paths are provenance only. Never open them.
return {name: {key: value[key] for key in ('bytes', 'sha256')} for name, value in refs.items()}
def exited(pid):
require(type(pid) is int and pid > 0, 'native PID invalid')
try:
os.kill(pid, 0)
except ProcessLookupError:
return
raise ValueError('native PID still exists or cannot be confirmed exited: ' + str(pid))
def cleanup(rows, expected):
require([r['pid'] for r in rows] == expected, 'captured cleanup PID set/order')
for row in rows:
require(row['engine_ended'] is True and row['outer_cleanup_errors'] == []
and row['foreign_process_or_group_signals'] == 0
and row['cleanup']['engine_ended'] is True and row['cleanup']['errors'] == [],
'owned native cleanup incomplete')
exited(row['pid'])
def verify(args):
build = Path(os.environ['BUILD_OUTPUT_DIR']).resolve(strict=True)
out = local(build, args.full_output)
authority = local(build, 'audit-support/root-input-r01')
base_path = local(authority, 'MAIN9B_COMPLETE_SOURCE_REFS.json')
marker_base = local(authority, 'MAIN9B_COMPLETION_MARKER_CONTRACTS.json')
require(pin(base_path) == BASE_PIN and pin(marker_base) == MARKER_PIN, 'fixed Root authority bytes')
baseline = pins(read(base_path))
require(len(baseline) == 1338, 'canonical map size')
require(hashlib.sha256(json.dumps({n: p['sha256'] for n, p in baseline.items()}, sort_keys=True).encode()).hexdigest()
== '533a4177918a9da4d4982aa9862cb7420c25d30c2458e36aab9c071c4d3a7139', 'canonical selected map hash')
delta = read(Path(__file__).with_name('delta-manifest.json'))
require(pin(ROOT / KITCHEN) == delta['canonical_source_delta']['new'], 'submitted kitchen source stale')
require(baseline[KITCHEN] == delta['canonical_source_delta']['old'], 'old kitchen pin')
expected = dict(baseline)
expected[KITCHEN] = pin(ROOT / KITCHEN)
expected[EXTRA] = EXTRA_PIN
require(len(expected) == 1339, 'exact fixed additional P04 QA source')
shared = load('kitchen_shared', ROOT / 'tools/run_all_tests.py')
submitted = pins(shared.source_refs(ROOT))
require(set(submitted) in (set(baseline), set(expected)), 'submitted additions/drops')
require(all(p == expected[n] for n, p in submitted.items()), 'submitted source byte drift')
marker_path = Path(args.marker_contracts).resolve(strict=True)
require(pin(marker_path) == pin(ROOT / MARKER) == delta['marker_delta']['new'], 'explicit marker input stale')
old_contract = read(marker_base)
new_contract = read(marker_path)
require(set(old_contract) == set(new_contract), 'marker structure changed')
changes = []
for old, new in zip(old_contract['rows'], new_contract['rows']):
if old != new:
require(old['test'] == new['test'] == KITCHEN, 'other marker row changed')
require({k for k in set(old) | set(new) if old.get(k) != new.get(k)}
== {'source_sha256_at_schema_audit', 'source_marker_lines'}, 'marker authority/count changed')
changes.append(new)
require(len(changes) == 1 and len(old_contract['rows']) == len(new_contract['rows'])
and all(old_contract[k] == new_contract[k] for k in old_contract if k != 'rows'), 'marker contract delta')
text = (ROOT / KITCHEN).read_text().splitlines()
require(changes[0]['source_sha256_at_schema_audit'] == expected[KITCHEN]['sha256'], 'marker source SHA')
require(changes[0]['source_marker_lines'] == [{'line': i, 'text': line} for i, line in enumerate(text, 1)
if 'print("Required kitchen:' in line], 'actual source marker line/text')
markers = load('kitchen_markers', ROOT / 'tools/strict_test_markers.py')
contracts = markers.load_contracts(marker_path)
start = read(local(out, 'runner-input.json'))
end = read(local(out, 'runner-ended.json'))
require(start['protocol'] == end['protocol'] == 'guarded-standard-v1'
and start['run_id'] == end['run_id'] and start['owner_runner_pid'] == end['owner_runner_pid'], 'native standard run identity')
require(Path(start['stage']) == out / 'stage', 'native build output identity')
require(end['passed'] is True and end['engine_ended'] is True and end['failed_suites'] == 0, 'native full run did not pass')
require(start['selected_source_map'] == {n: p['sha256'] for n, p in expected.items()}, 'exact 1339 selected map')
require(pins(read(local(out, 'source-start.json'))) == {n: p for n, p in expected.items() if n != EXTRA}
or pins(read(local(out, 'source-start.json'))) == expected, 'native submitted map stale')
require(start['marker_contract_sha256'] == pin(marker_path)['sha256']
and start['runner_sha256'] == expected['tools/run_all_tests.py']['sha256']
and start['marker_module_sha256'] == expected['tools/strict_test_markers.py']['sha256'], 'native authority pins')
roster = ['tests/run_tests.gd'] + sorted(n for n in expected if n.startswith('tests/') and n.endswith('.gd')
and Path(n).name.startswith('test') and 'export' not in Path(n).parts and n != 'tests/s0/test_kernel_and_save.gd')
require(len(roster) == 178 and start['roster'] == roster, 'new standard full 178 required')
rows = read(local(out, 'all-tests.json'))
require(markers.review_roster(roster, rows)['passed'], 'full exact ordered native roster')
require(pin(local(out, 'all-tests.json'))['sha256'] == end['all_tests_sha256'], 'full rows receipt hash')
phases = end['phases']
require(len(phases) == 180 and [p['phase'] for p in phases] == ['import', 'parse'] + [f'{i:03}' for i in range(178)], 'import/parse/full finite phases')
paths = ['res://' + n for n in sorted(expected) if n.endswith('.gd')]
require(read(local(out, 'parse-paths.json')) == paths, 'all submitted scripts parsed')
diagnostics = load('kitchen_diagnostics', ROOT / 'tools/regression/diagnostic_gate.py')
native = load('kitchen_native', ROOT / 'tools/regression/owned_diagnostic_process.py')
policy = read(ROOT / 'tools/regression/suite-policy.json')
pids = []
kitchen_raw = None
generated = {}
for source, source_pin in expected.items():
require(pin(local(out, 'stage/' + source)) == source_pin, 'native selected bytes stale: ' + source)
owners = load('kitchen_owners', ROOT / 'tools/regression/ordinary_proof_gate.py')
audio = load('kitchen_audio', ROOT / 'tools/regression/audio_evidence_gate.py')
bootstraps = read(ROOT / 'tools/regression/bootstrap-scripts.json')
for name, entry in bootstraps.items():
require(local(out, 'bootstrap/' + name).read_bytes() == entry['text'].encode()
and pin(local(out, 'bootstrap/' + name))['sha256'] == entry['sha256'], 'existing Guard/bootstrap bytes')
for index, phase in enumerate(phases):
name = phase['phase']
recorded = read(local(out, name + '-receipt.json'))
# all-tests adds only sequence and godot after the immutable phase receipt.
require(all(phase[k] == v for k, v in recorded.items()), 'phase receipt binding')
test = roster[index - 2] if index >= 2 else None
if test:
require(phase == rows[index - 2] and phase['test'] == test, 'full row/phase identity')
require(phase['validation_error'] is None and phase['passed'] is True and phase['failed'] is False, 'native phase failed')
command = [start['engine'], '--headless', '--path', str(out / 'stage')]
if name == 'import':
command += ['--editor', '--import', '--quit', '--verbose']
else:
script = out / ('bootstrap/parse_full_dependencies.gd' if name == 'parse' else 'starters/' + name + '.gd')
command += ['--script', str(script), '--verbose']
require(pin(script)['sha256'] == phase['starter_sha256'], 'actual guarded starter pin')
if test:
expected_starter = ('extends ' + json.dumps('res://' + test)
+ '\nconst Guard := preload(' + json.dumps(str(out / 'bootstrap/profile_guard.gd'))
+ ')\nfunc _initialize() -> void:\n\tif not Guard.activate():\n\t\tquit(97)\n\t\treturn\n\tsuper._initialize()\n')
require(script.read_text() == expected_starter, 'unchanged actual guarded suite entry')
command += ['--log-file', str(out / name / 'engine-native.log')]
require(phase['command'] == command, 'actual guarded launcher command')
stdout = local(out, name + '/stdout.log').read_text()
stderr = local(out, name + '/stderr.log').read_text()
raw = stdout + stderr
require(local(out, phase['log']).read_text() == raw and pin(local(out, phase['log']))['sha256'] == phase['log_sha256'], 'literal raw native transports')
logger = local(out, name + '/engine-native.log')
require(pin(logger) == {k: phase['raw_native_log'][k] for k in ('bytes', 'sha256')}, 'native logger hash')
review = diagnostics.review_streams(native, {'stdout': stdout, 'stderr': stderr, 'native_file': logger.read_text()}, test,
local(out, 'stage/' + test) if test else None)
process = read(local(out, name + '/process.json'))
require(process == phase['native_process'] and shared.process_gate(process, review['allowed_e31_error_lines'])
and diagnostics.diagnostic_result_gate(process, review), 'native process/strict diagnostics')
began = read(local(out, name + '/started.json'))
ended = read(local(out, name + '/ended.json'))
pid = phase['actual_pid']; pids.append(pid)
require(began['actual_pid'] == ended['actual_pid'] == process['pid'] == pid
and began['command'] == ended['command'] == phase['command']
and began['owner_pid'] == ended['owner_pid'] == start['owner_runner_pid']
and ended['engine_ended'] is True and ended['exit_code'] == 0, 'native START/END PID/command binding')
require(began['live_identity_exact'] is True or began['tracked_child_ended_before_initial_probe'] is True, 'owned native identity')
require(began == process['actual_start_binding'] and ended == process['actual_end_binding']
and began['event'] == 'ENGINE_STARTED' and ended['event'] == 'ENGINE_ENDED'
and ended['monotonic_ns'] >= began['monotonic_ns']
and ended['actual_process_exit_code'] == 0 and ended['timed_out'] is False
and ended['lifecycle_error'] is None, 'raw complete lifecycle binding')
require(read(local(out, name + '/adapter-owned-cleanup.json')) == process['adapter_owned_cleanup'], 'raw adapter cleanup binding')
capture = phase['outer_actual_capture']
outer = read(local(out, name + '/outer-owned-finally.json'))
require(all(capture[k] == v for k, v in outer.items()) and capture['all_captured_ended'] is True
and capture['outer_receipt_written'] is True and capture['outer_receipt_error'] is None
and capture['adapter_exception'] is None and capture['outer_cleanup_errors'] == []
and capture['foreign_process_or_group_signals'] == 0 and capture['actual_captured_pids'] == [pid], 'outer native ownership')
cleanup(capture['cleanup'], [pid])
require(phase.get('guard_error') is None and phase['default_player_entire_profile_unchanged'] is True
and phase['private_project_fields'] == 2, 'unchanged guards/default profile')
public = (ROOT / 'project.godot').read_bytes()
require(hashlib.sha256(shared.private_project(public, phase['profile_startup_name'])).hexdigest()
== phase['private_project_sha256'], 'only the two existing private profile settings')
require(read(local(out, name + '-startup-profile-before.json'))['existed'] is False, 'fresh startup profile')
for kind in ('startup', 'runtime') if index else ('startup',):
whole = phase['whole_' + kind + '_profile_after']
archive = local(out, 'profiles/' + name + '/' + kind)
require(archive.is_dir() and shared.inventory(archive) == whole['files'], 'retained actual whole private profile')
if index:
report = read(local(out, name + '-profile.json'))
require(report == phase['actual_private_profile']['report'] and report['verified'] is True
and report['conditions'] == [True] * 5 and report['conditions_checked'] == 5
and report['fresh_before_parent_initialize'] is True and report['profile_writes_before_guard'] == 0
and report['project_settings_persisted'] is False
and report['actual_user_data_dir'] == report['expected_user_data_dir'], 'unchanged five Guard conditions')
require(pin(local(out, name + '-profile.json'))['sha256'] == phase['actual_private_profile']['report_sha256']
and phase['actual_private_profile']['whole_files'] == phase['whole_runtime_profile_after']['files']
and report['globalized_probe'] == report['actual_user_data_dir'] + '/guard-probe'
and Path(report['actual_user_data_dir']).name == report['custom_user_dir_name'], 'whole actual profile/Guard binding')
if test:
require(phase['source_sha256'] == phase['source_sha256_end'] == expected[test]['sha256'], 'suite source stale')
parsed = markers.parse_raw(test, raw, contracts, expected[test]['sha256'])
require(parsed['passed'] and parsed['checks'] == phase['reported_checks']
and parsed['marker'] == phase['completion_marker'], 'strict actual marker/count')
if test in policy['suite_policies']:
require(phase['policy'] == shared.phase_policy(test, local(out, 'stage/' + test), policy['suite_policies']), 'unchanged suite cleanup/threshold policy')
proof_policy = phase['policy']
if proof_policy['ordinary_cleanup_prepared']:
require(owners.ordinary_gate(local(out, name + '-teardown'), pid, out,
proof_policy['ordinary_control_labels']) == phase['ordinary_owner_pairs'], 'actual ordinary cleanup proof')
if proof_policy['old_bounded_teardown'] or test == 'tests/ui/test_ui_audio_feedback.gd':
require(audio.teardown_gate(local(out, name + '-teardown'), pid, out) == phase['old_bounded_proof'], 'actual bounded cleanup proof')
if test == KITCHEN:
kitchen_raw = raw
require(parsed['checks'] == 163, '145 existing checks plus 17 controls and one fresh proof')
elif name == 'parse':
require(raw.count('FULL_DEPENDENCY_PARSE checks=%d failures=0\n' % len(paths)) == 1, 'strict all-script parse')
generated.update({n: {k: p[k] for k in ('bytes', 'sha256')} for n, p in phase['generated_reports'].items()})
require(len(set(pids)) == 180 and end['actual_captured_PIDs'] == pids, 'all native PID bindings')
cleanup(end['final_owned_cleanup'], pids)
require(end['error'] is None and end['cleanup_errors'] == [] and end['guard_errors'] == [], 'full cleanup/guards')
require(start['default_player_before'] == end['default_player_after']
and start['default_player_before']['logs_and_locks_included'] is True, 'whole default profile including locks/logs preserved')
require(shared.inventory(local(out, 'stage'), stage=True) == dict(expected, **generated), 'whole stage/source/report set preserved')
labels = ['outside'] + [verb + ' ' + field for field in ['version', 'relationships', 'threshold_candidates', 'next_candidate_sequence']
for verb in ['delete', 'change']] + ['sequence +1', 'nonempty originals', 'version 0', 'version 3', 'version 2',
'equal reordered keys', 'equal String reencoding', 'byte-identical deep copy']
lines = kitchen_raw.splitlines()
for label in labels:
require(lines.count(' ✓ legacy migration control immutable ' + label) == 1, 'native negative/positive control missing: ' + label)
# Successful return is deliberately silent. This gate never produces its own PASS.
def main():
parser = argparse.ArgumentParser(allow_abbrev=False, description=__doc__)
parser.add_argument('--verify-only', required=True, action='store_true')
parser.add_argument('--marker-contracts', required=True)
parser.add_argument('--full-output', default='native-full178', help='relative to BUILD_OUTPUT_DIR')
verify(parser.parse_args())
if __name__ == '__main__':
try:
main()
except (OSError, ValueError, KeyError, TypeError, AssertionError) as error:
print(str(error), file=sys.stderr)
raise SystemExit(1)
+102 -3
View File
@@ -188,7 +188,93 @@ func _io_valid(event: Dictionary, kind: String, operation: StringName, path: Str
var payload: Dictionary = event.get("payload", {}) var payload: Dictionary = event.get("payload", {})
return event.get("event_type") == kind and event.get("source_service") == "save_service" and event.get("causation_command_id") == 0 and event.get("entity_ids") == [] and not String(event.get("event_id", "")).is_empty() and payload.get(&"operation") == operation and typeof(payload.get(&"ok")) == TYPE_BOOL and payload[&"ok"] and payload.get(&"code") == &"OK" and payload.get(&"save_path") == path and payload.get(&"checkpoint_absolute_minute") == checkpoint_minute and payload.get(&"saved_absolute_minute") == checkpoint_minute and event.get("absolute_minute") == checkpoint_minute and not String(payload.get(&"save_id", "")).is_empty() and payload.get(&"request_id") == 0 and payload.get(&"reason") == (&"manual" if operation == &"save" else &"") and (operation != &"load" or typeof(payload.get(&"duration_us")) == TYPE_INT and payload[&"duration_us"] >= 0 and typeof(payload.get(&"runtime_duration_us")) == TYPE_INT and payload[&"runtime_duration_us"] >= 0) return event.get("event_type") == kind and event.get("source_service") == "save_service" and event.get("causation_command_id") == 0 and event.get("entity_ids") == [] and not String(event.get("event_id", "")).is_empty() and payload.get(&"operation") == operation and typeof(payload.get(&"ok")) == TYPE_BOOL and payload[&"ok"] and payload.get(&"code") == &"OK" and payload.get(&"save_path") == path and payload.get(&"checkpoint_absolute_minute") == checkpoint_minute and payload.get(&"saved_absolute_minute") == checkpoint_minute and event.get("absolute_minute") == checkpoint_minute and not String(payload.get(&"save_id", "")).is_empty() and payload.get(&"request_id") == 0 and payload.get(&"reason") == (&"manual" if operation == &"save" else &"") and (operation != &"load" or typeof(payload.get(&"duration_us")) == TYPE_INT and payload[&"duration_us"] >= 0 and typeof(payload.get(&"runtime_duration_us")) == TYPE_INT and payload[&"runtime_duration_us"] >= 0)
func _compare_loaded(writer: Dictionary, write_path: String, read_path: String, label: String) -> void: func _typed_sha(value: Variant) -> String:
var context := HashingContext.new()
context.start(HashingContext.HASH_SHA256)
context.update(var_to_bytes(value))
return context.finish().hex_encode()
func _legacy_relationship_v1_to_v2(expected_subtree: Variant, actual_subtree: Variant) -> Dictionary:
var rejected := {"ok": false, "expected": null, "proof": {}}
if not expected_subtree is Dictionary or not actual_subtree is Dictionary: return rejected
var old: Dictionary = expected_subtree
var actual: Dictionary = actual_subtree
# The genuine fixture uses StringName keys, in this exact serialization order.
if var_to_bytes(old.keys()) != var_to_bytes([&"version", &"relationships", &"threshold_candidates", &"next_candidate_sequence"]): return rejected
if typeof(old[&"version"]) != TYPE_INT or old[&"version"] != 1: return rejected
if not old[&"relationships"] is Array or not old[&"threshold_candidates"] is Array or typeof(old[&"next_candidate_sequence"]) != TYPE_INT: return rejected
if var_to_bytes(actual.keys()) != var_to_bytes([&"version", &"legacy", &"relationships", &"original_relationships"]): return rejected
if typeof(actual[&"version"]) != TYPE_INT or actual[&"version"] != 2: return rejected
if not actual[&"legacy"] is Dictionary or var_to_bytes(actual[&"legacy"]) != var_to_bytes(old): return rejected
if var_to_bytes(actual[&"legacy"].get(&"next_candidate_sequence")) != var_to_bytes(old[&"next_candidate_sequence"]): return rejected
if not actual[&"original_relationships"] is Array or not actual[&"original_relationships"].is_empty(): return rejected
# create_snapshot uses a typed compatibility collection even for empty v1 input.
var projection: Array[Dictionary] = []
for entry: Variant in old[&"relationships"]:
if not entry is Dictionary: return rejected
projection.append(entry.duplicate(true))
if var_to_bytes(actual[&"relationships"]) != var_to_bytes(projection): return rejected
var originals: Array[Dictionary] = []
var migrated := {&"version": 2, &"legacy": old.duplicate(true), &"relationships": projection.duplicate(true), &"original_relationships": originals}
if var_to_bytes(migrated) != var_to_bytes(actual): return rejected
return {"ok": true, "expected": migrated, "proof": {"old_v1_bytes": var_to_bytes(old).size(), "old_v1_sha256": _typed_sha(old), "replaced_subtree_sha256": _typed_sha(migrated)}}
func _legacy_checkpoint(expected: Dictionary, reader: Dictionary) -> Dictionary:
var migration := _legacy_relationship_v1_to_v2(expected[&"systems"][&"runtime"][&"relationships"], reader[&"systems"][&"runtime"][&"relationships"])
if not migration["ok"]: return migration
# Reverse just this subtree in a copy of the reader: every other byte must
# already match the writer after the separately validated IO1 replacement.
var outside := reader.duplicate(true)
outside[&"systems"][&"runtime"][&"relationships"] = expected[&"systems"][&"runtime"][&"relationships"].duplicate(true)
if var_to_bytes(outside) != var_to_bytes(expected): return {"ok": false}
var result := expected.duplicate(true)
result[&"systems"][&"runtime"][&"relationships"] = migration["expected"].duplicate(true)
if var_to_bytes(result) != var_to_bytes(reader) or result != reader or SimulationDigest.compute(result) != SimulationDigest.compute(reader): return {"ok": false}
return {"ok": true, "expected": result, "proof": migration["proof"]}
func _legacy_control(writer: Dictionary, reader: Dictionary, label: String, kind: String, field: StringName = &"", value: Variant = null) -> void:
var writer_bytes := var_to_bytes(writer); var reader_bytes := var_to_bytes(reader)
var candidate := writer.duplicate(true); var observed := reader.duplicate(true)
var old: Dictionary = candidate[&"systems"][&"runtime"][&"relationships"]
var actual: Dictionary = observed[&"systems"][&"runtime"][&"relationships"]
match kind:
"outside": candidate[&"legacy_control_outside"] = true
"delete": old.erase(field)
"change": old[field] = value
"sequence": actual[&"legacy"][&"next_candidate_sequence"] += 1
"originals": actual[&"original_relationships"].append({&"unapproved": true})
"version": actual[&"version"] = value
"reorder":
var reordered := {}
var keys := old.keys(); keys.reverse()
for key: Variant in keys: reordered[key] = old[key]
candidate[&"systems"][&"runtime"][&"relationships"] = reordered
"reencode":
var reencoded := {}
for key: Variant in old: reencoded[String(key)] = old[key]
candidate[&"systems"][&"runtime"][&"relationships"] = reencoded
var before_candidate := var_to_bytes(candidate); var before_observed := var_to_bytes(observed)
var encoding_control := true
if kind in ["reorder", "reencode"]:
encoding_control = candidate == writer and before_candidate != writer_bytes
var result := _legacy_checkpoint(candidate, observed)
expect(encoding_control and result["ok"] == (kind == "copy") and var_to_bytes(writer) == writer_bytes and var_to_bytes(reader) == reader_bytes and var_to_bytes(candidate) == before_candidate and var_to_bytes(observed) == before_observed, "legacy migration control immutable " + label)
func _legacy_controls(writer: Dictionary, reader: Dictionary) -> void:
_legacy_control(writer, reader, "outside", "outside")
for field: StringName in [&"version", &"relationships", &"threshold_candidates", &"next_candidate_sequence"]:
_legacy_control(writer, reader, "delete " + String(field), "delete", field)
_legacy_control(writer, reader, "change " + String(field), "change", field, null)
_legacy_control(writer, reader, "sequence +1", "sequence")
_legacy_control(writer, reader, "nonempty originals", "originals")
for version: Variant in [0, 3, "2"]:
_legacy_control(writer, reader, "version " + str(version), "version", &"", version)
_legacy_control(writer, reader, "equal reordered keys", "reorder")
_legacy_control(writer, reader, "equal String reencoding", "reencode")
_legacy_control(writer, reader, "byte-identical deep copy", "copy")
_proof("legacy14-migration-controls", {"attempts": 17, "writer_sha256": _typed_sha(writer), "reader_sha256": _typed_sha(reader), "failures": failures})
func _compare_loaded(writer: Dictionary, write_path: String, read_path: String, label: String, migrate_relationships_v1: bool = false) -> void:
var reader: Dictionary = runtime.create_snapshot() var reader: Dictionary = runtime.create_snapshot()
var old: Dictionary = writer[&"systems"][&"runtime"][&"domain_events"]["recent_events"].back().duplicate(true) var old: Dictionary = writer[&"systems"][&"runtime"][&"domain_events"]["recent_events"].back().duplicate(true)
var actual: Dictionary = reader[&"systems"][&"runtime"][&"domain_events"]["recent_events"].back().duplicate(true) var actual: Dictionary = reader[&"systems"][&"runtime"][&"domain_events"]["recent_events"].back().duplicate(true)
@@ -199,9 +285,22 @@ func _compare_loaded(writer: Dictionary, write_path: String, read_path: String,
if event.get("event_id") == old.get("event_id"): if event.get("event_id") == old.get("event_id"):
valid = valid and var_to_bytes(event) == var_to_bytes(old) valid = valid and var_to_bytes(event) == var_to_bytes(old)
event["event_type"] = actual["event_type"]; event["payload"] = actual["payload"].duplicate(true); replaced += 1 event["event_type"] = actual["event_type"]; event["payload"] = actual["payload"].duplicate(true); replaced += 1
var migration_proof := {}
if migrate_relationships_v1:
_legacy_controls(expected, reader)
var migration := _legacy_checkpoint(expected, reader)
valid = valid and migration["ok"]
if migration["ok"]:
expected = migration["expected"]
migration_proof = migration["proof"]
migration_proof["write_checkpoint_sha256"] = FileAccess.get_sha256(LEGACY.path_join("write-checkpoint.var"))
valid = valid and replaced == 1 and expected[&"systems"][&"runtime"][&"domain_events"]["published_ids"].has(actual.get("event_id")) and var_to_bytes(expected) == var_to_bytes(reader) and expected == reader and SimulationDigest.compute(expected) == SimulationDigest.compute(reader) valid = valid and replaced == 1 and expected[&"systems"][&"runtime"][&"domain_events"]["published_ids"].has(actual.get("event_id")) and var_to_bytes(expected) == var_to_bytes(reader) and expected == reader and SimulationDigest.compute(expected) == SimulationDigest.compute(reader)
_proof(label + "-expected-io1", expected); _proof(label + "-actual", reader) _proof(label + "-expected-io1", expected); _proof(label + "-actual", reader)
_proof(label + "-io1-binding", {"whole_typed_bytes_equal": valid, "writer_io": old, "reader_io": actual, "mapped_fields": ["event_type", "payload"], "event_deletion_count": 0, "write_path": write_path, "read_path": read_path, "copied_legacy_package": write_path != read_path}) var binding := {"whole_typed_bytes_equal": valid, "writer_io": old, "reader_io": actual, "mapped_fields": ["event_type", "payload"], "event_deletion_count": 0, "write_path": write_path, "read_path": read_path, "copied_legacy_package": write_path != read_path}
if migrate_relationships_v1:
binding["mapped_fields"].append("relationships_v1_to_v2")
binding["relationships_v1_to_v2"] = migration_proof
_proof(label + "-io1-binding", binding)
expect(valid, "whole typed loaded state unchanged except complete identity/saveID-bound IO1: " + label) expect(valid, "whole typed loaded state unchanged except complete identity/saveID-bound IO1: " + label)
func _new_saved_boundary() -> void: func _new_saved_boundary() -> void:
@@ -340,7 +439,7 @@ func _legacy_saved_boundary() -> void:
expect(persisted is Dictionary and inspected.get(&"ok", false) and inspected.get(&"read_only", false) and var_to_bytes(inspected.get(&"snapshot", {})) == var_to_bytes(persisted) and var_to_bytes(live) == var_to_bytes(runtime.create_snapshot()) and _package(path) == hashes, "old14 inspection exact complete typed persisted state and read-only for every live byte/package") expect(persisted is Dictionary and inspected.get(&"ok", false) and inspected.get(&"read_only", false) and var_to_bytes(inspected.get(&"snapshot", {})) == var_to_bytes(persisted) and var_to_bytes(live) == var_to_bytes(runtime.create_snapshot()) and _package(path) == hashes, "old14 inspection exact complete typed persisted state and read-only for every live byte/package")
expect(runtime.load_from_path(path).get(&"ok", false), "ordinary strict old14 formal Load, schema stays14") expect(runtime.load_from_path(path).get(&"ok", false), "ordinary strict old14 formal Load, schema stays14")
_listen(true) _listen(true)
_compare_loaded(expected, contract["slot"], path, "legacy14-load") _compare_loaded(expected, contract["slot"], path, "legacy14-load", true)
var cafe: FacilityInstance = runtime.facility_service.get_instance(ids["cafe"]) var cafe: FacilityInstance = runtime.facility_service.get_instance(ids["cafe"])
var service: ServiceInstance = runtime.facility_service.get_service(ids["service"]) var service: ServiceInstance = runtime.facility_service.get_service(ids["service"])
expect(cafe.related_facility_id.is_empty() and service.state == ServiceInstance.State.ACTIVE and service.elapsed_minutes == 5 and cafe.state == FacilityInstance.State.OPEN and not cafe.related_facility_operating and cafe.operation_state == FacilityInstance.OperationState.INACTIVE, "old raw OPEN/ACTIVE5 remains serialized immediately; derived missing kitchen false") expect(cafe.related_facility_id.is_empty() and service.state == ServiceInstance.State.ACTIVE and service.elapsed_minutes == 5 and cafe.state == FacilityInstance.State.OPEN and not cafe.related_facility_operating and cafe.operation_state == FacilityInstance.OperationState.INACTIVE, "old raw OPEN/ACTIVE5 remains serialized immediately; derived missing kitchen false")