| name | tfactory-watch |
| description | Poll a running TFactory task to completion, then pick up its triage report and verify the generated tests cover the acceptance criteria. One check per invocation — drive it with /loop for a hands-off round-trip. Reads task_status over MCP and the triage report file directly (no backend dependency on the bugged report_get). |
| when_to_use | After /handover-to-tfactory returns a task_id and you want to wait for the autonomous pipeline (Planner → Gen-Functional → Executor → Evaluator → Triager) to finish, then automatically review the result. Common triggers — "watch the tfactory task", "/tfactory-watch <task_id>", "is the tfactory task done yet", "pick up the tfactory report when ready", "/loop 30s /tfactory-watch <task_id>". |
| allowed-tools | ["mcp__tfactory__task_status","mcp__tfactory__task_list","mcp__tfactory__task_rerun","Read","Bash"] |
/tfactory-watch
Poll one TFactory task, and when it finishes, pick it up and verify that
the autonomously-generated tests actually cover the acceptance criteria you
handed off. This skill does one status check per invocation — to make it a
hands-off loop, run it under /loop:
/loop 30s /tfactory-watch <task_id>
/loop re-fires it on the interval; the skill tells the loop to stop as
soon as the task reaches a terminal state.
Arguments
task_id (required) — the id returned by /handover-to-tfactory
(task_id == spec_id). If omitted, call mcp__tfactory__task_list and ask
the user which task to watch.
Procedure (one pass)
Step 1 — poll status
Call mcp__tfactory__task_status(task_id=<task_id>). Read two fields:
status — the lifecycle state
phase — fine-grained sub-state (for a friendly progress line)
Also note project_id and spec_id from the response — you need them to
locate the report in Step 3.
Step 2 — classify the state
| Bucket | status values | Action |
|---|
| ✅ Done | triaged, triaged_empty | go to Step 3 (pick up + verify), then STOP the loop |
| ❌ Failed | anything ending in _failed, or stuck | report the failure + remediation (Step 4), then STOP the loop |
| ⏳ Running | everything else (pending, planning, planned, generating, generated, evaluating, evaluated, triaging, and the transient *_empty intermediates) | print a one-line progress update (status / phase) and let the loop re-fire — do NOT read the report yet |
Important: planned_empty / generated_empty / evaluated_empty are
not terminal — they auto-advance to the next stage. Only triaged* and
*_failed / stuck stop the loop.
To stop the loop, finish your turn without scheduling another iteration (state
plainly that the task is terminal so /loop does not re-fire).
Step 3 — pick up the report + VERIFY
The Triager writes the report to the workspace, not via report_get
(which is currently wired to the wrong path). Read it directly:
WS="${TFACTORY_WORKSPACE_ROOT:-$HOME/.tfactory/workspaces}"
SPEC_DIR="$WS/<project_id>/specs/<spec_id>"
# Read $SPEC_DIR/findings/triage_report.md (and findings/triage_report.json)
Use the Read tool on $SPEC_DIR/findings/triage_report.md. Then verify:
- List the acceptance criteria you handed off (from the task's goals / the
context/aifactory_spec.md the pipeline planned against).
- For each accepted/flagged test in the triage report, note which
AC#N its
rationale covers.
- Flag any acceptance criterion with no covering accepted test — that's a
coverage gap, not a pass.
- Summarise for the user: ✅ covered ACs, ⚠️ flagged tests (and why), ❌ ACs
with no test, plus the verdict counts (committed / flagged / rejected).
- If
status == triaged_empty (no tests survived triage), say so explicitly —
the pipeline ran but nothing passed the 5-signal verdict; recommend a
task_rerun or revisiting the acceptance criteria.
Step 4 — on failure / stuck
*_failed — report which stage failed (the status names it:
planner_failed / gen_functional_failed / evaluator_failed /
triager_failed) and surface status.json error fields + the relevant
logs/<agent>.log line if present.
stuck — the Planner hit replan_count >= 2; the acceptance criteria are
likely ambiguous or untestable. Surface the latest context/replan_request.json
reason and ask the user to refine the criteria.
- Offer
mcp__tfactory__task_rerun(task_id, lane=<lane>) as the retry path.
Notes
- Pure read-only round-trip —
task_status is cheap + safe to poll; the
report is read from disk. No backend changes, no writes (except an optional
user-approved task_rerun).
- Cadence:
30s is a good default; the pipeline typically runs minutes.
For long browser-lane runs, /loop 60s is fine.
- Pairs with
/handover-to-tfactory — that skill hands off and returns the
task_id; this one watches it home and verifies the result.