Brain-5D-Space / tests /_restore_worker.py
github-actions[bot]
Sync: publish Space API fix
5e0b58b
Raw History Blame Contribute Delete
5.69 kB
"""Restore worker subprocess for Path C (Alpha.5).
This is C2: a fresh Python process that receives only filesystem paths
and scalar arguments. It calls the production restore_full() and
computes digests using the canonical production digest.
No in-memory network/engine/state object crosses the subprocess boundary.
"""
from __future__ import annotations
import argparse
import json
import os
import sys
from pathlib import Path
from typing import Any, cast
def main() -> None:
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
parser = argparse.ArgumentParser()
parser.add_argument("--phase", choices=("c1", "c2"), default="c2")
parser.add_argument("--snapshot")
parser.add_argument("--journal")
parser.add_argument("--checkpoint")
parser.add_argument("--config", required=True)
parser.add_argument("--schedule", required=True)
parser.add_argument("--output", required=True)
parser.add_argument("--end-tick", type=int, required=True)
parser.add_argument(
"--digest-k",
required=True,
help="Path to write digest at K (before continuation)",
)
args = parser.parse_args()
if args.phase == "c1":
from src.homeostasis.engine import HomeostasisEngine
from src.learning.learning_engine import LearningEngine
from src.storage.checkpoint import (
CheckpointNetworkLike,
capture_runtime_checkpoint,
write_runtime_checkpoint,
)
from src.storage.runtime import (
RuntimeNetworkLike,
StorageRuntimeConfig,
StorageSession,
)
from tests._restore_helpers import K, create_network, run_absolute_schedule
config = json.loads(Path(args.config).read_text(encoding="utf-8"))
schedule = json.loads(Path(args.schedule).read_text(encoding="utf-8"))
network = create_network(config)
homeo = HomeostasisEngine(network, config)
homeo.attach()
learn = LearningEngine(network, config)
learn.attach()
run_absolute_schedule(network, schedule, K)
artifact_dir = Path(args.output).parent
runtime = StorageRuntimeConfig(
snapshot_path=artifact_dir / "base.b5d",
journal_path=artifact_dir / "base.b5d.journal",
commit_interval_ticks=1,
)
with StorageSession(cast("RuntimeNetworkLike", network), runtime):
pass
from tests._restore_helpers import capture_learning_state
checkpoint = capture_runtime_checkpoint(
cast("CheckpointNetworkLike", network),
homeostasis_rates=cast(Any, homeo)._rates_hz,
learning_states=capture_learning_state(learn)["states"],
pending_rewards=capture_learning_state(learn)["pending_rewards"],
)
checkpoint_path = artifact_dir / "runtime.json"
write_runtime_checkpoint(checkpoint_path, checkpoint)
manifest = {
"snapshot": str(runtime.snapshot_path),
"journal": str(runtime.journal_path),
"checkpoint": str(checkpoint_path),
"pid": os.getpid(),
}
(artifact_dir / "pid_C1.txt").write_text(str(os.getpid()), encoding="utf-8")
Path(args.output).write_text(json.dumps(manifest, indent=2), encoding="utf-8")
print(f"C1 worker done: pid={os.getpid()}")
return
from src.storage.core_restore import restore_full
# ── Restore from filesystem artifacts only ───────────────────────────
bundle = restore_full(
snapshot_path=Path(args.snapshot),
journal_path=Path(args.journal),
checkpoint_path=Path(args.checkpoint),
config=json.loads(Path(args.config).read_text()),
recovered_path=Path(args.output).parent / "recovered.b5d",
create_homeostasis_engine=True,
create_learning_engine=True,
)
# ── Compute digest at K (before continuing) ──────────────────────────
from tests._restore_helpers import (
compute_digest,
config_sha256,
make_config,
run_absolute_schedule,
)
config = make_config()
digest_K = compute_digest(
bundle.network,
bundle.homeostasis_engine,
bundle.learning_engine,
config_sha256_str=config_sha256(config),
)
digest_K_path = Path(args.digest_k)
digest_K_path.write_text(
json.dumps({"digest_K": digest_K, "pid": os.getpid()}), encoding="utf-8"
)
# ── Continue K -> N ──────────────────────────────────────────────────
schedule = json.loads(Path(args.schedule).read_text())
run_absolute_schedule(bundle.network, schedule, args.end_tick)
# ── Compute digest at N ──────────────────────────────────────────────
digest_N = compute_digest(
bundle.network,
bundle.homeostasis_engine,
bundle.learning_engine,
config_sha256_str=config_sha256(config),
)
result = {
"digest": digest_N,
"digest_K": digest_K,
"pid": os.getpid(),
"start_tick": 0,
"end_tick": args.end_tick,
"restore_full_used": True,
}
Path(args.output).write_text(json.dumps(result, indent=2), encoding="utf-8")
print(
f"C2 worker done: digest_K={digest_K}, digest_N={digest_N}, pid={os.getpid()}"
)
if __name__ == "__main__":
main()