from __future__ import annotations
import json
import os
from datetime import datetime, timezone
from pathlib import Path
from typing import Any
IMPLEMENT_DIRNAME = ".fermilink-implement"
STATE_FILENAME = "state.json"
RESULTS_FILENAME = "results.tsv"
MEMORY_FILENAME = "memory.md"
WORKER_MEMORY_FILENAME = "worker_memory.md"
PROGRAM_FILENAME = "program.md"
RUN_LOCK_FILENAME = "run.lock.json"
RUNS_DIRNAME = "runs"
AUTOGEN_DIRNAME = "autogen"
GOAL_COPY_FILENAME = "goal.md"
GOAL_ANALYSIS_FILENAME = "goal_analysis.json"
CONTRACT_FILENAME = "implementation_contract.yaml"
VALIDATION_RUNNER_FILENAME = "validation_runner.py"
PLAN_FILENAME = "implementation_plan.md"
RESULTS_HEADER = "iteration\tcommit\tstatus\tscore\tcomplete\tdescription\n"
[docs]
def utc_now_z() -> str:
return datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
[docs]
def implement_root(project_root: Path) -> Path:
return project_root / IMPLEMENT_DIRNAME
[docs]
def state_path(project_root: Path) -> Path:
return implement_root(project_root) / STATE_FILENAME
[docs]
def results_path(project_root: Path) -> Path:
return implement_root(project_root) / RESULTS_FILENAME
[docs]
def memory_path(project_root: Path) -> Path:
return implement_root(project_root) / MEMORY_FILENAME
[docs]
def worker_memory_path(project_root: Path) -> Path:
return implement_root(project_root) / WORKER_MEMORY_FILENAME
[docs]
def program_path(project_root: Path) -> Path:
return implement_root(project_root) / PROGRAM_FILENAME
[docs]
def run_lock_path(project_root: Path) -> Path:
return implement_root(project_root) / RUN_LOCK_FILENAME
[docs]
def clear_run_lock(path: Path) -> None:
try:
path.unlink(missing_ok=True)
except OSError:
return
[docs]
def runs_root(project_root: Path) -> Path:
return implement_root(project_root) / RUNS_DIRNAME
[docs]
def autogen_root(project_root: Path) -> Path:
return implement_root(project_root) / AUTOGEN_DIRNAME
[docs]
def goal_copy_path(project_root: Path) -> Path:
return autogen_root(project_root) / GOAL_COPY_FILENAME
[docs]
def goal_analysis_path(project_root: Path) -> Path:
return autogen_root(project_root) / GOAL_ANALYSIS_FILENAME
[docs]
def contract_path(project_root: Path) -> Path:
return autogen_root(project_root) / CONTRACT_FILENAME
[docs]
def validation_runner_path(project_root: Path) -> Path:
return autogen_root(project_root) / VALIDATION_RUNNER_FILENAME
[docs]
def plan_path(project_root: Path) -> Path:
return autogen_root(project_root) / PLAN_FILENAME
[docs]
def ensure_implement_root(project_root: Path) -> Path:
root = implement_root(project_root)
root.mkdir(parents=True, exist_ok=True)
runs_root(project_root).mkdir(parents=True, exist_ok=True)
return root
[docs]
def ensure_autogen_root(project_root: Path) -> Path:
root = autogen_root(project_root)
root.mkdir(parents=True, exist_ok=True)
return root
[docs]
def safe_relative(path: Path, root: Path) -> str:
try:
return str(path.resolve().relative_to(root.resolve())).replace("\\", "/")
except ValueError:
return str(path.resolve())
[docs]
def write_json_file(path: Path, payload: dict[str, Any]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
tmp = path.with_suffix(path.suffix + ".tmp")
tmp.write_text(
json.dumps(payload, indent=2, sort_keys=True) + "\n",
encoding="utf-8",
)
tmp.replace(path)
[docs]
def load_json_file(path: Path) -> dict[str, Any] | None:
if not path.is_file():
return None
try:
payload = json.loads(path.read_text(encoding="utf-8"))
except (OSError, json.JSONDecodeError):
return None
return payload if isinstance(payload, dict) else None
[docs]
def write_state(path: Path, payload: dict[str, Any]) -> None:
write_json_file(path, payload)
[docs]
def load_state(path: Path) -> dict[str, Any] | None:
return load_json_file(path)
[docs]
def ensure_results_file(path: Path) -> bool:
if path.exists():
return False
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(RESULTS_HEADER, encoding="utf-8")
return True
[docs]
def ensure_program_file(path: Path, *, content: str) -> bool:
if path.exists():
return False
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(content, encoding="utf-8")
return True
[docs]
def ensure_memory_file(
path: Path,
*,
package_id: str,
goal_rel: str,
contract_rel: str,
branch_name: str,
) -> bool:
if path.exists():
return False
started = utc_now_z()
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(
(
"# FermiLink Implement Memory\n"
"\n"
f"- package_id: {package_id}\n"
f"- goal_path: {goal_rel}\n"
f"- contract_path: {contract_rel}\n"
f"- implement_branch: {branch_name}\n"
f"- started_at_utc: {started}\n"
f"- last_updated_utc: {started}\n"
"\n"
"## Short-Term Memory (Operational)\n"
"### Current objective\n"
"- Implement the feature described by goal.md and the generated contract.\n"
"### Latest accepted implementation\n"
"- commit: pending\n"
"- score: pending\n"
"- complete: false\n"
"### Progress log\n"
"- Campaign initialized.\n"
"\n"
"## Long-Term Memory (Persistent)\n"
"### Accepted implementation steps\n"
"- none yet\n"
"### Rejected patterns\n"
"- none yet\n"
"### Open hypotheses\n"
"- Review goal, contract, validation, and prior results before each change.\n"
),
encoding="utf-8",
)
return True
[docs]
def reset_worker_memory_file(
path: Path,
*,
package_id: str,
goal_rel: str,
contract_rel: str,
controller_memory_rel: str,
results_rel: str,
worker_iteration: int,
) -> None:
now = utc_now_z()
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(
(
"# FermiLink Implement Worker Memory\n"
"\n"
f"- package_id: {package_id}\n"
f"- goal_path: {goal_rel}\n"
f"- contract_path: {contract_rel}\n"
f"- controller_memory_path: {controller_memory_rel}\n"
f"- results_path: {results_rel}\n"
f"- worker_iteration: {worker_iteration}\n"
f"- reset_at_utc: {now}\n"
"\n"
"This file is reset at the start of each outer implement iteration and "
"archived under `.fermilink-implement/runs/iter_XXXX/worker_memory.md`.\n"
"\n"
"## Short-Term Memory (Operational)\n"
"### Current objective\n"
"- Prepare exactly one focused implementation step for controller validation.\n"
"### Plan\n"
"- Read goal, contract, controller memory, results, and skills.\n"
"- Inspect current implementation state.\n"
"- Apply focused edits only within editable scope.\n"
"- Run cheap local checks when useful.\n"
"- Finish only when this step is ready for validation.\n"
"### Progress log\n"
"- Worker iteration initialized.\n"
"\n"
"## Tactical Notes\n"
"### Candidate summary\n"
"- pending\n"
"### Debug notes\n"
"- none yet\n"
),
encoding="utf-8",
)
[docs]
def archive_worker_memory(source_path: Path, run_dir: Path) -> Path | None:
if not source_path.is_file():
return None
run_dir.mkdir(parents=True, exist_ok=True)
target_path = run_dir / WORKER_MEMORY_FILENAME
target_path.write_text(source_path.read_text(encoding="utf-8"), encoding="utf-8")
return target_path
[docs]
def append_result(
path: Path,
*,
iteration: int,
commit: str,
status: str,
score: float | int | str,
complete: bool,
description: str,
) -> None:
rendered_score = (
f"{float(score):.12g}" if isinstance(score, (float, int)) else str(score)
)
safe_description = " ".join(str(description or "").replace("\t", " ").split())
row = (
f"{int(iteration)}\t{commit}\t{status}\t{rendered_score}\t"
f"{str(bool(complete)).lower()}\t{safe_description}\n"
)
with path.open("a", encoding="utf-8") as handle:
handle.write(row)
[docs]
def recent_results_text(path: Path, *, limit: int = 8) -> str:
try:
lines = path.read_text(encoding="utf-8").splitlines()
except OSError:
return ""
return "\n".join(lines[-limit:]) if lines else ""
[docs]
def pid_is_running(pid: int) -> bool:
if pid <= 0:
return False
try:
os.kill(pid, 0)
except OSError:
return False
return True
[docs]
def ensure_executable(path: Path) -> None:
try:
mode = path.stat().st_mode
except OSError:
return
if mode & 0o111:
return
try:
path.chmod(mode | 0o111)
except OSError:
return