refactor(harness): route workflow persistence through repositories
This commit is contained in:
@@ -8,7 +8,6 @@ commands. All read workflow facts from load_workflow() (no mirrored constants).
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
import typer
|
||||
|
||||
@@ -22,16 +21,12 @@ from tht.workflow import load_workflow
|
||||
phase_app = typer.Typer(help="Fase del workflow HITL (gate di avanzamento/ritorno)")
|
||||
|
||||
|
||||
def session_dir(cfg, session_id: str) -> Path:
|
||||
"""Where a session's artifacts live. Mirror of session_cmd.session_dir (kept
|
||||
here to avoid a circular import: session_cmd imports phase helpers too)."""
|
||||
return cfg.paths.sessions / session_id
|
||||
|
||||
|
||||
def require_phase_or_exit(cfg, session: str, min_phase: int) -> None:
|
||||
"""Refuse with exit 1 if the session hasn't reached min_phase yet. The phase
|
||||
name in the message comes from workflow.yaml (load_workflow), not a constant."""
|
||||
cur = current_phase(session_dir(cfg, session))
|
||||
from tht.cli.session_cmd import load_snapshot_or_exit
|
||||
|
||||
cur = current_phase(load_snapshot_or_exit(cfg, session))
|
||||
if cur < min_phase:
|
||||
wf = load_workflow()
|
||||
nome = wf.phase_name(min_phase)
|
||||
@@ -89,21 +84,24 @@ def advance_cmd(
|
||||
),
|
||||
) -> None:
|
||||
"""Approva la fase corrente e passa alla successiva (persiste phase_approved)."""
|
||||
from tht.decisions import append_decision
|
||||
from tht.cli.session_cmd import load_snapshot_or_exit, session_repository
|
||||
|
||||
sdir = session_dir(_cfg(), session)
|
||||
cur = current_phase(sdir)
|
||||
cfg = _cfg()
|
||||
snapshot = load_snapshot_or_exit(cfg, session)
|
||||
cur = current_phase(snapshot)
|
||||
wf = load_workflow()
|
||||
if cur > wf.max_phase:
|
||||
typer.secho("Sessione già alla fase terminale.", fg=typer.colors.YELLOW)
|
||||
raise typer.Exit(0)
|
||||
if auto:
|
||||
if not auto_advance_eligible(sdir):
|
||||
problems = advance_problems(sdir, cur)
|
||||
if not auto_advance_eligible(snapshot):
|
||||
problems = advance_problems(snapshot, cur)
|
||||
for p in problems:
|
||||
typer.echo(p)
|
||||
raise typer.Exit(6) # needs human confirmation (gate contract)
|
||||
append_decision(sdir, type="phase_approved", subject=f"phase:{cur}")
|
||||
session_repository(cfg).append_decisions(
|
||||
session, [{"type": "phase_approved", "subject": f"phase:{cur}"}]
|
||||
)
|
||||
typer.echo(f"Fase {cur} ({wf.phase_name(cur)}) approvata → Fase {cur + 1}.")
|
||||
|
||||
|
||||
@@ -113,16 +111,21 @@ def reopen_cmd(
|
||||
phase: int = typer.Option(..., "--phase", help="Fase a cui tornare (1..fase corrente -1)."),
|
||||
) -> None:
|
||||
"""Torna a una fase precedente (persiste phase_reopened + teardown artefatti)."""
|
||||
from tht.decisions import append_decision
|
||||
from tht.teardown import teardown_to_phase
|
||||
from tht.cli.session_cmd import load_snapshot_or_exit, session_repository
|
||||
|
||||
sdir = session_dir(_cfg(), session)
|
||||
cur = current_phase(sdir)
|
||||
cfg = _cfg()
|
||||
snapshot = load_snapshot_or_exit(cfg, session)
|
||||
cur = current_phase(snapshot)
|
||||
if phase < 1 or phase >= cur:
|
||||
typer.secho(f"Target non valido (fase corrente {cur}).", fg=typer.colors.RED, err=True)
|
||||
raise typer.Exit(1)
|
||||
report = teardown_to_phase(sdir, target_phase=phase)
|
||||
append_decision(sdir, type="phase_reopened", subject=f"phase:{phase}")
|
||||
from tht.teardown import teardown_snapshot
|
||||
|
||||
repository = session_repository(cfg)
|
||||
report = teardown_snapshot(repository, snapshot, phase)
|
||||
repository.append_decisions(
|
||||
session, [{"type": "phase_reopened", "subject": f"phase:{phase}"}]
|
||||
)
|
||||
for f in report.deleted_files:
|
||||
typer.echo(f" eliminato artefatto: {f}")
|
||||
typer.echo(f"Tornati alla Fase {phase} ({load_workflow().phase_name(phase)}).")
|
||||
@@ -133,13 +136,13 @@ def show_cmd(
|
||||
session: str = typer.Option(..., "--session"),
|
||||
) -> None:
|
||||
"""Mostra stato, fase corrente e ultime decisioni della sessione."""
|
||||
from tht.decisions import list_decisions
|
||||
from tht.cli.session_cmd import load_snapshot_or_exit
|
||||
|
||||
sdir = session_dir(_cfg(), session)
|
||||
cur = current_phase(sdir)
|
||||
snapshot = load_snapshot_or_exit(_cfg(), session)
|
||||
cur = current_phase(snapshot)
|
||||
wf = load_workflow()
|
||||
typer.echo(f"Fase corrente: {cur}/{wf.max_phase} ({wf.phase_name(min(cur, wf.max_phase))})")
|
||||
decisions = list_decisions(sdir)
|
||||
decisions = snapshot.decisions
|
||||
if decisions:
|
||||
typer.echo(f"Decisioni registrate: {len(decisions)}")
|
||||
for d in decisions[-5:]:
|
||||
|
||||
Reference in New Issue
Block a user