Skip to content

A finished blocked verdict reads as finished and its reason opens from work review - #246

Merged
vjovanov merged 2 commits into
mainfrom
fix/issue-243
Oct 22, 2026
Merged

vjovanov merged 2 commits into
mainfrom
fix/issue-243

Conversation

@vjovanov

@vjovanov vjovanov commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #243

When a fix-gate ticket finishes with a blocked verdict, work list now says the ticket is finished blocked and prints the path of its verdict. work review lists the verdict and result files, so the reason can be opened from the review. Before this change, the list showed only the verdict's imperative sentence, which read like a gate still waiting on someone. The review then said there was no gate and had nothing to open.

Before, with the reproducer from the issue (plan and both tickets in the final done state, verdict blocked, the reason in the verdict file):

$ ephor work list
demo  ✓ fix-gate · blocked — a person has to decide or do something first  Gate cannot be collected
      <root>/panta/gdev-graal-24550-e13a1739.rhei.md
$ ephor work review --item gdev:graal
No work is waiting at a human gate for this matter.
$ ephor work review --item gdev:graal --json
{ "gates": [], "files": [] }

After, on 4ff7ce3:

$ ephor work list
demo  ✓ fix-gate · finished blocked  Gate cannot be collected
      <root>/panta/runtime/ephor/gdev-graal-24550-e13a1739.fix-gate-2.verdict.md  (why it is blocked)
      <root>/panta/gdev-graal-24550-e13a1739.rhei.md
$ ephor work review --item gdev:graal
No work is waiting at a human gate for this matter.
  file 1: gdev-graal-24550-e13a1739.fix-gate-1 · finished blocked · verdict — <root>/panta/runtime/ephor/gdev-graal-24550-e13a1739.fix-gate-1.verdict.md
  file 2: gdev-graal-24550-e13a1739.fix-gate-1 · finished blocked · result — <root>/panta/runtime/results/gdev-graal-24550-e13a1739.fix-gate-1.md
  file 3: gdev-graal-24550-e13a1739.fix-gate-2 · finished blocked · verdict — <root>/panta/runtime/ephor/gdev-graal-24550-e13a1739.fix-gate-2.verdict.md
  file 4: gdev-graal-24550-e13a1739.fix-gate-2 · finished blocked · result — <root>/panta/runtime/results/gdev-graal-24550-e13a1739.fix-gate-2.md

Opening file 3 (--file 3, or Enter in the TUI) shows VERDICT: blocked — … followed by Collection could not run because the VPN was down; a person must restore the VPN and re-run collect. work review --json still has "gates": [], and files now holds the same four entries.

What changed

A finished blocked verdict is an outcome, not a gate. A ticket counts as finished blocked when it is in a final state, is not cancelled, and has a readable verdict artifact whose verdict is explicitly blocked. For each such ticket, review lists two files: its verdict (runtime/ephor/<plan>.<ticket>.verdict.md), then its runtime result (runtime/results/<plan>.<ticket>.md). They are labelled <ticket> · finished blocked · verdict|result, come in plan order after every live gate's materials, and are listed once each. If either file is missing or unreadable, it is still listed, with its problem. Review reads only these two known locations. It does not sweep directories or follow links. The files add no gate, destination or transition. They count toward no parked work and start no run. They open through the same bounded, read-only viewer as a gate's files (§FS-005-dispatch.9.2).

Gates still come from current state alone. A ticket is a gate only because the state it is in now is a gating state, never because of a verdict it wrote earlier (§FS-005-dispatch.9.1). In a mixed matter, live gates keep their destinations and transition selection, and the finished-blocked files follow them.

List and review describe the same matter. In work list, work offers and the TUI work screen, a finished blocked ticket reads ✓ fix-gate · finished blocked instead of the verdict's own sentence. When the matter has no open ticket, work list prints the first readable outcome file of the last ticket under the row, preferring the verdict over the result. List JSON carries the same files on the ticket as outcome_files: [{name, path, problem}], and the field is absent when there are none. state, finished, the raw verdict and a review's gates keep their existing meanings (§FS-005-dispatch.23, §REQ-002-parity.3). assets/ephor-views.schema.json adds the optional ticket.outcome_files, and its work-review description now covers the finished-blocked files.

A review with no gate still has something to open. With zero gates, the CLI review still prints No work is waiting at a human gate for this matter. and lists the finished files under it. The TUI review used to return early when there were no gates. It now draws the same sentence (shared as one constant, replacing the TUI's old No task is currently waiting at a human gate.) and the file list, and selecting a file opens the bounded viewer.

Every other finished ticket is unchanged. A finished ticket with no readable verdict, a verdict other than blocked, or a cancellation looks exactly as it did before, in the list and in the review. Plans that workflows lay write their verdicts elsewhere (§FS-005-dispatch.35). A row pointing at a file nobody was meant to write would only be noise.

The design follows the approved plan, with the author's three notes applied:

  1. There are no "outcome unavailable" rows.
  2. The finished-outcome reading is a new point, §9.2, rather than a widening of §9.1. §9.1 gains only the sentence about gates.
  3. The no-gate sentence stays, and the files are listed under it.

docs/manual.md §6.2, §8.7 and §8.7.2 describe the new row and the review.

The implementation is split as follows:

  • results::finished_blocked and results::is_blocked in the adapter find the files.
  • review_plan reads final from the runtime machine.
  • Review::settled() appends the finished files after every plan's gates.
  • TicketStatus::outcome and outcome_file are the one formatter that the badge, rows, TUI and work offers all use.

Known limitation, not fixed here

Review round 1 found one nit (R1-01), which is deferred. The blocked rule looks at the first word of the verdict line. That means a decorated VERDICT: **blocked** — … is not classified as blocked. In the other direction, a non-conforming artifact with no VERDICT: line whose first line begins with "Blocked" is classified as blocked. The rule was left as it is because the machine ephor ships (assets/ephor-work.states.yaml) writes the plain line the rule matches. Review found no adjacent issues.

Verified

The spec, the schema and E2E-063 were committed first (eabe60f), with the three behavioural cases ignored and failing for the reported reason. The implementation commit (4ff7ce3) removed the ignore markers.

  • E2E-063 (tests/e2e/cases/E2E-063-a-finished-blocked-verdict-is-read-not-gated.rs):
    • the reported all-final, no-gate case reads as finished and its reason is one open away;
    • a live gate stays actionable beside finished-blocked files;
    • a missing result beside a blocked verdict carries its problem;
    • a guard checks that a finished ticket without a blocked verdict is presented as before.
  • Unit tests:
    • only an explicit blocked verdict counts, and verdict then result are offered;
    • finished-blocked files follow the gates and are never gated;
    • the badge and rows say finished blocked.
  • TUI tests:
    • a zero-gate review draws its finished files;
    • a finished file opens and returns without a move;
    • a mixed review keeps transition selection for its live gate.
  • Triage reproducer: exited 1 on main (2156be0) and exits 0 (REPRO: no) on 4ff7ce3.
  • Green run on 4ff7ce3, under CI's pinned grund 0.18.0, all exit 0:
    • pre-commit run --all-files;
    • Python integration (113 tests);
    • scripts/check_boundary.py;
    • scripts/check_parity.py (28 abilities, 25 presentation keys, 56 bindings);
    • the full cargo test with TMPDIR pointed at a symlinked directory.

The workflow summary below was generated before shipping, so it does not include the ship step.

AI workflow: `rhei`, 14 agent invocations across 2 models; 8 tasks completed, 8 in progress.
  1. github-issues-agent-grounds-ephor-243-implement-428da888.ticket supervising (visit 1) — cdx, openai/gpt-6.1-sol — 2m15s — 587.7k in / 3.7k out
  2. github-issues-agent-grounds-ephor-243-implement-428da888.ticket.triage assessing (visit 1) — cdx, openai/gpt-6.1-sol — 1m25s — 318.2k in / 2.7k out
  3. github-issues-agent-grounds-ephor-243-implement-428da888.ticket.triage reproducing (visit 1) — cdx, openai/gpt-6.1-sol — 7m46s — 1.5M in / 15.4k out
  4. github-issues-agent-grounds-ephor-243-implement-428da888.ticket supervising (visit 2) — cdx, openai/gpt-6.1-sol — 3m42s — 734.0k in / 6.3k out
  5. github-issues-agent-grounds-ephor-243-implement-428da888.ticket.plan planning — cdx, openai/gpt-6.1-sol — 6m29s — 1.8M in / 9.8k out
  6. github-issues-agent-grounds-ephor-243-implement-428da888.ticket supervising (visit 3) — cld, anthropic/claude-opus-5-5 — 24.0s — 270.6k in / 2.6k out
  7. github-issues-agent-grounds-ephor-243-implement-428da888.ticket supervising (visit 4) — cld, anthropic/claude-opus-5-5 — 34.0s — 276.4k in / 3.1k out
  8. github-issues-agent-grounds-ephor-243-implement-428da888.ticket.specify specify — cld, anthropic/claude-opus-5-5 — 10m35s — 4.6M in / 25.3k out
  9. github-issues-agent-grounds-ephor-243-implement-428da888.ticket supervising (visit 5) — cld, anthropic/claude-opus-5-5 — 30.0s — 282.5k in / 3.0k out
  10. github-issues-agent-grounds-ephor-243-implement-428da888.ticket.implement implement — cld, anthropic/claude-opus-5-5 — 13m26s — 6.3M in / 31.8k out
  11. github-issues-agent-grounds-ephor-243-implement-428da888.ticket supervising (visit 6) — cld, anthropic/claude-opus-5-5 — 53.0s — 696.3k in / 3.6k out
  12. github-issues-agent-grounds-ephor-243-implement-428da888.ticket.review-1 review — cld, anthropic/claude-opus-5-5 — 2m26s — 1.8M in / 10.6k out
  13. github-issues-agent-grounds-ephor-243-implement-428da888.ticket supervising (visit 7) — cld, anthropic/claude-opus-5-5 — 34.0s — 500.2k in / 2.3k out
  14. github-issues-agent-grounds-ephor-243-implement-428da888.ticket supervising (visit 8) — cld, anthropic/claude-opus-5-5 — 38.0s — 303.9k in / 2.4k out
Accounting Value
cost $10.57
total tokens 20.1M
input tokens (incl. cache) 20.0M
input cache read 18.7M
input cache write 876.0k
output tokens (incl. cache) 122.6k
output cache read -
output cache write -
coverage Complete

work list printed a finished ticket's blocked verdict as its bare
imperative sentence, so a plan that was over read as a person being
waited on now, while work review said no work waits at a human gate and
offered nothing to open; the reason the ticket wrote stayed in the
plan's runtime directory (#243).

FS-005-dispatch.9.2 says a final, non-cancelled ticket whose readable
verdict is blocked contributes its verdict and result to the review as
read-only files labelled finished blocked, after every live gate's
materials and with no destination; 9.1 says gates come from current
state alone; 23 says the list calls the outcome finished and prints its
verdict path, and the ticket JSON carries the same files as
outcome_files. The schema declares outcome_files.

E2E-063 pins the reported site, a mixed matter with a live gate, and a
missing result. Those three are ignored until the change exists; the
guard that a finished ticket without a blocked verdict is presented as
before runs now.
…s from the review

A ticket that finished with the verdict blocked was printed by work list
as the verdict's own imperative sentence, so a plan that was over read as
a person being waited on now, while work review said no work waits at a
human gate and offered nothing to open (#243).

The runtime adapter now reads a final, non-cancelled ticket whose verdict
artifact says blocked as an outcome with two files, its verdict and its
runtime result (FS-005-dispatch.9.2). Ticket status carries them, so the
badge, the navigator rows, the work screen and work offers say finished
blocked, work list prints the verdict path under the row, and the list
and work readings carry them as outcome_files (FS-005-dispatch.23). The
review appends them after every live gate's materials, in plan order,
with no gate, destination or transition; with no gate the CLI keeps its
no-gate sentence above them and the TUI review draws and opens them
instead of returning early. Gates still come from current state alone
(FS-005-dispatch.9.1). Any other finished ticket is presented as before.

The manual describes the wording, the finished files in a review, and a
mixed review.
@vjovanov vjovanov changed the title spec: a finished blocked verdict is read beside the gates, never as one A finished blocked verdict reads as finished and its reason opens from work review Oct 22, 2026
@vjovanov
vjovanov marked this pull request as ready for review October 22, 2026 14:42
@vjovanov
vjovanov requested a review from kimeta October 22, 2026 14:42
@vjovanov
vjovanov merged commit 31e0fb8 into main Oct 22, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

work list presents a finished blocked verdict as a human gate while work review reports no gate

1 participant