Показать cold-start артефакты в status stage-loop

This commit is contained in:
dctouch 2026-05-09 13:38:13 +03:00
parent 913745380f
commit 48c3b5340b
3 changed files with 40 additions and 1 deletions

View File

@ -143,7 +143,7 @@ It stores the GUI review under `artifacts/domain_runs/stage_agent_loops/<stage_i
`stage_loop_summary.json` also includes `next_step_guidance.command_templates`, so the next operator or agent pass can continue from machine-readable commands instead of re-inferring the workflow from prose.
Use `python scripts/stage_agent_loop.py status --manifest docs/orchestration/<stage_loop>.json` as the cheap read-only checkpoint before continuing a stage. It prints the current next action, closing gate, latest GUI run, latest repair coder status, and latest repair validation status without modifying artifacts.
Use `python scripts/stage_agent_loop.py status --manifest docs/orchestration/<stage_loop>.json` as the cheap read-only checkpoint before continuing a stage. It prints the current next action, closing gate, latest GUI run, latest repair coder status, latest repair validation status, and cold-start continuation artifacts such as `domain_pack_loop.command.txt` without modifying artifacts.
Use `python scripts/stage_agent_loop.py continue --manifest docs/orchestration/<stage_loop>.json` as the safe one-command continuation layer. From a cold start it materializes `domain_pack_loop.command.txt` without launching the long live loop; after a GUI review it can prepare a repair iteration and materialize `run-repair --dry-run` automatically; it will not run the real coder pass unless `--execute-repair` is passed, and it waits for a `--run-id assistant-stage1-<id>` when the next required step is post-repair rerun/ingest validation.

View File

@ -1128,6 +1128,13 @@ def handle_plan(args: argparse.Namespace) -> int:
def build_stage_status(stage_manifest: dict[str, Any], stage_dir: Path) -> dict[str, Any]:
summary_path = stage_dir / "stage_loop_summary.json"
summary = load_json_object(summary_path, "Existing stage summary") if summary_path.exists() else {}
continue_result_path = stage_dir / "stage_continue_result.json"
continue_result = (
load_json_object(continue_result_path, "Stage continue result")
if continue_result_path.exists()
else {}
)
domain_command_path = stage_dir / "domain_pack_loop.command.txt"
next_action = str(summary.get("next_action") or "run_stage_loop_or_ingest_gui_run")
latest_gui_review = summary.get("latest_gui_review") if isinstance(summary.get("latest_gui_review"), dict) else {}
latest_repair_execution = (
@ -1166,6 +1173,11 @@ def build_stage_status(stage_manifest: dict[str, Any], stage_dir: Path) -> dict[
"latest_validation_status": latest_repair_validation.get("validation_status"),
"accepted_after_repair": latest_repair_validation.get("accepted_after_repair"),
"summary_path": repo_relative(summary_path) if summary_path.exists() else None,
"domain_pack_loop_command_exists": domain_command_path.exists(),
"domain_pack_loop_command_path": repo_relative(domain_command_path) if domain_command_path.exists() else None,
"last_continue_action": continue_result.get("performed_action"),
"last_continue_next_action": continue_result.get("next_action"),
"last_continue_result_path": repo_relative(continue_result_path) if continue_result_path.exists() else None,
}

View File

@ -817,6 +817,33 @@ class StageAgentLoopTests(unittest.TestCase):
self.assertEqual(result["performed_action"], "materialize_stage_run_dry_run")
self.assertIn("run-pack-loop", command_text)
def test_build_stage_status_reports_cold_start_continue_artifacts(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
stage_dir = root / "stage_runs" / "agent_loop"
write_json(
stage_dir / "stage_continue_result.json",
{
"schema_version": "stage_agent_loop_continue_result_v1",
"performed_action": "materialize_stage_run_dry_run",
"next_action": "run_stage_loop_or_ingest_gui_run",
},
)
(stage_dir / "domain_pack_loop.command.txt").write_text("python run-pack-loop\n", encoding="utf-8")
status = stage_loop.build_stage_status(
{
"stage_id": "agent_loop",
"module_name": "Agent Loop",
"title": "Agent Loop",
},
stage_dir,
)
self.assertTrue(status["domain_pack_loop_command_exists"])
self.assertEqual(status["last_continue_action"], "materialize_stage_run_dry_run")
self.assertEqual(status["last_continue_next_action"], "run_stage_loop_or_ingest_gui_run")
def test_resolve_stage_repair_iteration_auto_prepares_from_handoff(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)