unrip/scripts/workflow/close_turn.py
philipp 54dc05a94c Archive first live trade loop and open funding visibility turn
Proof: Preserve the completed first live BTC/EURe trade loop and establish the next approved implementation proof around pre-credit funding visibility and operator alerts.
Assumptions: The live-trade loop is sufficiently proven by the recorded deposits, withdrawals, durable command/result chain, and successful mainnet quote responses; the next highest-value slice is operational visibility rather than new execution breadth.
Still fake: The newly opened funding-visibility and alert turn is planning only; no pre-credit watcher or durable alert evaluator is implemented yet.
2026-04-03 01:07:02 +02:00

150 lines
4.5 KiB
Python
Executable file

#!/usr/bin/env python3
from __future__ import annotations
import argparse
import re
import shutil
from pathlib import Path
from common import (
ARCHIVE_PATH,
IMPLEMENTATION_ARCHIVE_DIR,
IMPLEMENTATION_PATH,
PROOF_PATH,
RESEARCH_ACTIVE_PATH,
RESEARCH_ARCHIVE_DIR,
append_archive_line,
git_commit,
load_text,
save_text,
slugify,
timestamp_slug,
today_iso,
)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Archive and close the current implementation or research turn.")
parser.add_argument("--lane", required=True, choices=("implementation", "research"))
parser.add_argument(
"--status",
required=True,
choices=("passed", "failed", "paused", "abandoned"),
help="Outcome of the turn.",
)
parser.add_argument("--summary", required=True, help="One-line closure summary.")
parser.add_argument(
"--commit",
action="store_true",
help="Commit the archive change automatically.",
)
return parser.parse_args()
def title_from_content(content: str, prefix: str) -> str:
match = re.search(rf"^# {re.escape(prefix)}: (.+)$", content, flags=re.MULTILINE)
if not match:
raise SystemExit(f"could not find title for {prefix.lower()}")
return match.group(1).strip()
def close_implementation_turn(status: str, summary: str) -> tuple[str, list[Path]]:
proof_content = load_text(PROOF_PATH)
implementation_content = load_text(IMPLEMENTATION_PATH)
title = title_from_content(proof_content, "Implementation Proof")
slug = slugify(title)
stamp = timestamp_slug()
IMPLEMENTATION_ARCHIVE_DIR.mkdir(parents=True, exist_ok=True)
proof_archive = IMPLEMENTATION_ARCHIVE_DIR / f"{stamp}-{slug}-proof.md"
implementation_archive = IMPLEMENTATION_ARCHIVE_DIR / f"{stamp}-{slug}-implementation.md"
shutil.copyfile(PROOF_PATH, proof_archive)
shutil.copyfile(IMPLEMENTATION_PATH, implementation_archive)
save_text(
PROOF_PATH,
"""# Implementation Proof
Status: idle
No approved implementation proof is active yet.
""",
)
save_text(
IMPLEMENTATION_PATH,
"""# Implementation Turn
Status: idle
No approved implementation turn is active yet.
""",
)
append_archive_line(
"implementation",
f"- {today_iso()}: `{slug}` closed with status `{status}`. {summary}",
)
return title, [proof_archive, implementation_archive]
def close_research_turn(status: str, summary: str) -> tuple[str, list[Path]]:
research_content = load_text(RESEARCH_ACTIVE_PATH)
title = title_from_content(research_content, "Research Turn")
slug = slugify(title)
stamp = timestamp_slug()
RESEARCH_ARCHIVE_DIR.mkdir(parents=True, exist_ok=True)
research_archive = RESEARCH_ARCHIVE_DIR / f"{stamp}-{slug}.md"
shutil.copyfile(RESEARCH_ACTIVE_PATH, research_archive)
save_text(
RESEARCH_ACTIVE_PATH,
"""# Research Turn
Status: idle
No approved research turn is active yet.
""",
)
append_archive_line(
"research",
f"- {today_iso()}: `{slug}` closed with status `{status}`. {summary}",
)
return title, [research_archive]
def main() -> None:
args = parse_args()
if args.lane == "implementation" and "Status: idle" in load_text(PROOF_PATH):
raise SystemExit("no active implementation turn to close")
if args.lane == "research" and "Status: idle" in load_text(RESEARCH_ACTIVE_PATH):
raise SystemExit("no active research turn to close")
if args.lane == "implementation":
title, archived_paths = close_implementation_turn(args.status, args.summary)
else:
title, archived_paths = close_research_turn(args.status, args.summary)
if args.commit:
paths = [ARCHIVE_PATH]
if args.lane == "implementation":
paths.extend([PROOF_PATH, IMPLEMENTATION_PATH])
else:
paths.append(RESEARCH_ACTIVE_PATH)
paths.extend(archived_paths)
git_commit(
f"""Archive {args.lane} turn: {title}
Proof: Preserve the completed {args.lane} turn and record its outcome in the tracked archive.
Assumptions: The archived files capture the relevant planning state for the completed turn.
Still fake: Archiving does not validate the work by itself; external evidence still governs whether the result is trustworthy.""",
paths=paths,
)
for archived_path in archived_paths:
print(archived_path.relative_to(RESEARCH_ACTIVE_PATH.parent.parent))
if __name__ == "__main__":
main()