3.5 KiB
3.5 KiB
T10.9 — CLI: runs list/episode/transcript
| Field | Value |
|---|---|
| Phase | P10 — Orchestration |
| Size | S — under 1 day |
| Status | Not started |
| Flags | — |
| Spec | inlined below |
| Blocks | — |
Goal
Three thin CLI wrappers over the HTTP API — poimen runs list --goal <id>,
poimen runs episode <run_id>, poimen runs transcript <run_id> <step> <attempt> — the whole troubleshooting UX, no dashboard.
Facts (inlined — no spec read needed)
- Thin HTTP clients, not a second implementation of the query logic already in T10.1/T1.7/T1.6 — the CLI calls the same routes T10.4 exposes.
- Rides the eventual shared
poimenbinary (T9.3); workable as a standalone binary if T9.3 hasn't landed yet — soft dependency, not a hard block. episodeoutput must include failed attempts by default — T1.7's own rule. A CLI that hides them defeats the purpose of the command.transcriptdereferences theBlobRefserver-side, via the HTTP route (T10.4) — the CLI never talks toBlobStoredirectly.
Steps
poimen runs list [--goal <id>] [--status <state>]→GET /v1/runs, table output (run_id,status,goal_id, age).poimen runs episode <run_id>→GET /v1/runs/{id}/episode, human-readable rendering ofEpisodeViewincluding failed attempts, clearly marked.poimen runs transcript <run_id> <step> <attempt>→GET .../transcript, prints prompt/output text, dereferenced server-side.- Exit codes: non-zero on API error, distinct code for "run not found" vs "transport error" — operator scripting depends on this distinction.
- Test against a live embedded API instance (T10.4's test harness) with a run that has a retry and a rewind.
Acceptance
episodeon a run with two failed attempts and one success shows all three, visually distinguishable.transcriptreturns the same text content as reading theBlobRefdirectly throughBlobStorein a test assertion.
Verify
Harness: T10.4's axum test instance, one run with a retry (two
attempts, one failed) and a rewind.
Integration test — tests/it_cli_runs_ux.rs:
runs list --goal G; assert output contains exactly the runs tagged G, none untagged.runs episode <id>; assert both the failed and successful attempt appear — count them explicitly, not just non-empty output.runs transcript <id> <step> 1(the failed attempt) and... 2(the retry); assert distinct content for each, matching their respectiveBlobRefs byte-for-byte.- Run-not-found case; assert a distinct exit code from a transport-down case.
Command: cargo test -p cli runs_ux
False pass:
- Step 2 checking only that output is non-empty — a CLI silently filtering to the winning attempt (T1.7's own named trap) passes a non-empty check while hiding exactly the debugging signal requested.
Traps
- Filtering episode output to "just the successful attempt for clarity" — T1.7's trap restated at the CLI layer; the failed attempts are the reason this command exists.
- Fetching transcripts client-side by resolving
BlobRefdirectly instead of through the HTTP route. Bypasses the tenant auth checks the API enforces.
Background (not required to do this task): T10.4-http-api-surface.md · T1.7-episode-query-surface.md · T1.6-prompt-and-output-blob-capture.md · T8.2-metrics.md