Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ Primary commands write compact JSON to stdout by default. This does not require
genome accession ... --include genome --filename ...` commands, records
return codes and ZIP readiness for later inspection, and still does not
mutate manifests, install genomes, accept final genome usability, or create
strict scientific deliverables.
strict scientific deliverables. For blocked download-smoke outputs, summary
`blockers` are repeated in the top-level `blocking` array for AI routing.

AI-facing stdout must stay short. Long logs, reports, tables, diagnostics, and
evidence belong in the run directory.
Expand Down
9 changes: 9 additions & 0 deletions tests/test_cli_download_smoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,9 @@ def test_download_smoke_execute_blocks_mutated_command_manifest(capsys, tmp_path
assert payload["status"] == "blocked"
assert payload["downloads_triggered"] == 0
assert payload["network_access"] is False
assert payload["blocking"] == [
{"id": "command_manifest_invalid", "message": "command_manifest_invalid"}
]
assert summary["command_invalid_count"] == 1
assert summary["blockers"] == ["command_manifest_invalid"]
assert rows[0]["command_valid"] == "false"
Expand Down Expand Up @@ -1310,6 +1313,12 @@ def test_download_smoke_prepare_blocks_without_planned_rows(capsys, tmp_path):
payload = json.loads(capsys.readouterr().out)
summary = payload["bounded_download_smoke_summary"]
assert payload["status"] == "blocked"
assert payload["blocking"] == [
{
"id": "no_planned_ncbi_download_rows",
"message": "no_planned_ncbi_download_rows",
}
]
assert summary["ready"] is False
assert summary["blockers"] == ["no_planned_ncbi_download_rows"]

Expand Down
16 changes: 16 additions & 0 deletions typetreeflow/download_smoke_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,10 @@ def run_download_smoke_command(
),
outdir=str(args.outdir) if args.write else "",
)
if status != "pass":
summary_blocking = _blocking_from_summary(result["summary"])
if summary_blocking:
payload["blocking"] = summary_blocking
if args.action == "prepare":
payload["bounded_download_smoke_summary"] = result["summary"]
elif args.action == "inspect":
Expand Down Expand Up @@ -2361,6 +2365,18 @@ def _payload(
return payload


def _blocking_from_summary(summary: dict[str, object]) -> list[dict[str, str]]:
blockers = summary.get("blockers", [])
if not isinstance(blockers, list):
return []
result: list[dict[str, str]] = []
for blocker in blockers:
blocker_id = str(blocker).strip()
if blocker_id:
result.append({"id": blocker_id, "message": blocker_id})
return result


def _payload_schema_version(command: str) -> str:
if command == INSPECT_COMMAND:
return "download_smoke_inspect.v1"
Expand Down
Loading