unrip/scripts/workflow/open_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

176 lines
4.5 KiB
Python
Executable file

#!/usr/bin/env python3
from __future__ import annotations
import argparse
from common import (
BACKLOG_PATH,
ARCHIVE_PATH,
IMPLEMENTATION_PATH,
PROOF_PATH,
RESEARCH_ACTIVE_PATH,
append_archive_line,
backlog_entry_map,
git_commit,
remove_backlog_ids,
save_text,
slugify,
today_iso,
)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Open a new implementation or research turn.")
parser.add_argument("--lane", required=True, choices=("implementation", "research"))
parser.add_argument("--title", required=True, help="Turn title.")
parser.add_argument("--summary", required=True, help="One-line proof or charter summary.")
parser.add_argument(
"--pick",
action="append",
default=[],
help="Backlog ID to pull into the turn. Repeat as needed.",
)
parser.add_argument(
"--commit",
action="store_true",
help="Commit the planning change automatically.",
)
parser.add_argument(
"--force",
action="store_true",
help="Replace an already-open turn instead of refusing.",
)
return parser.parse_args()
def render_selected(ids: list[str], items: dict[str, str]) -> str:
if not ids:
return "- none selected"
return "\n".join(f"- [{item_id}] {items[item_id]}" for item_id in ids)
def open_implementation_turn(title: str, summary: str, selected: str) -> None:
opened = today_iso()
save_text(
PROOF_PATH,
f"""# Implementation Proof: {title}
Status: open
Opened: {opened}
## Hypothesis
{summary}
## Scope
{selected}
## Non-goals
- unchanged from `THESIS.md` unless the user approves otherwise
## Definition of done
- current turn implementation is validated with direct evidence
- remaining fakes are listed plainly
""",
)
save_text(
IMPLEMENTATION_PATH,
f"""# Implementation Turn: {title}
Status: open
Opened: {opened}
## Goal
{summary}
## Selected backlog items
{selected}
## Notes
- Fill in the concrete implementation plan before coding if the live plan no longer matches the turn.
""",
)
def open_research_turn(title: str, summary: str, selected: str) -> None:
opened = today_iso()
save_text(
RESEARCH_ACTIVE_PATH,
f"""# Research Turn: {title}
Status: open
Opened: {opened}
## Charter
{summary}
## Selected backlog items
{selected}
## Hypothesis
TBD by the approved research turn.
## Dataset or source of truth
TBD by the approved research turn.
## Metrics
TBD by the approved research turn.
## Assumptions
TBD by the approved research turn.
## Falsification condition
TBD by the approved research turn.
""",
)
def main() -> None:
args = parse_args()
if args.lane == "implementation":
if "Status: open" in PROOF_PATH.read_text(encoding="utf-8") and not args.force:
raise SystemExit("implementation turn already open; close it first or pass --force")
else:
if "Status: open" in RESEARCH_ACTIVE_PATH.read_text(encoding="utf-8") and not args.force:
raise SystemExit("research turn already open; close it first or pass --force")
entries = backlog_entry_map()
missing = [item_id for item_id in args.pick if item_id not in entries]
if missing:
raise SystemExit(f"unknown backlog IDs: {', '.join(missing)}")
selected = render_selected(args.pick, entries)
if args.lane == "implementation":
open_implementation_turn(args.title, args.summary, selected)
else:
open_research_turn(args.title, args.summary, selected)
if args.pick:
remove_backlog_ids(args.pick)
append_archive_line(
"planning",
(
f"- {today_iso()}: opened {args.lane} turn `{slugify(args.title)}` "
f"from backlog items {', '.join(args.pick) if args.pick else 'none'}."
),
)
if args.commit:
commit_paths = [BACKLOG_PATH, ARCHIVE_PATH]
if args.lane == "implementation":
commit_paths.extend([PROOF_PATH, IMPLEMENTATION_PATH])
else:
commit_paths.append(RESEARCH_ACTIVE_PATH)
git_commit(
f"""Open {args.lane} turn: {args.title}
Proof: Establish the approved {args.lane} turn and move selected backlog items into active scope.
Assumptions: The selected backlog items are the approved scope for this turn.
Still fake: Opening a turn changes planning state only; the work itself is not implemented yet.""",
paths=commit_paths,
)
if __name__ == "__main__":
main()