Skip to content

[compass] Fix: seat_job can answer finished: true without the end of the command's output - #31

Merged
skulitom merged 1 commit into
mainfrom
compass/anode-fix-2026-10-09-job-finished-tail
Oct 10, 2026
Merged

skulitom merged 1 commit into
mainfrom
compass/anode-fix-2026-10-09-job-finished-tail

Conversation

@skulitom

@skulitom skulitom commented Oct 9, 2026 •

Copy link
Copy Markdown
Owner

Report

From Compass's ANODE-BUGS.md inbox (not in this repo), entry B-025 (filed 2026-10-07 by compass-anode-fixer, from the second review of #25): seat_job can answer finished: true without the end of the command's output. An agent that stops reading at finished: true loses the tail of a build or test log, often its summary, with nothing in the reply to say so.

Root cause

ExecutionJobs.ReadAsync read the output page (job.Output.Read) first, and the job's state, finished and exitCode under the job's gate second. A job's supervisor sets Done only after both output streams are drained. When the last output arrived and Done was set between those two reads, the reply said finished: true and hasMoreOutput: false, but its page stopped short of the end. It needs a reply's wait to run out, or a no-wait read to arrive, in that gap, so it is rare.

Fix

ReadAsync now takes the status (state, finished, worker, exit code, error, elapsed time) under the gate before it reads the output page. Since a job is marked finished only after its output is drained, a page read after a finished status holds everything to the end. The reply's fields and their order are unchanged.

An internal seam, ExecutionJobs.BetweenStatusAndOutput, runs between the two reads; only the quick check sets it.

Unchanged: if a job's output streams are still open 3 s after its worker exits and the job object ended its descendants (something outside the job holding them), the supervisor stops waiting and the job ends failed with a timeout error, as before; output that arrives after that can still follow a finished reply.

docs/DEVELOPMENT-TESTING.md now says that a finished: true reply holds the output to its end, with hasMoreOutput meaning only that maxChars cut the page. One CHANGELOG entry.

How it was tested

  • New quick check, execution job tail: a real Windows PowerShell job writes head, waits 200 ms and writes tail. The check reads it once, and the seam lets the job finish, output and all, while that read is between the status and the output. It then requires: the two pages together are headtail; and a reply that says finished: true has hasMoreOutput: false and nothing after its cursor.
  • Mutation: putting the old order back (output page, seam, status) fails the check with the reported shape: a reply said finished: true without the end of the output: it had '', and 'headtail' followed. The file was restored byte for byte afterwards.
  • dotnet build -c Debug and selftest --quick: 98/98.
  • The FOCUS test command, scripts\build.ps1 -QuickTest -OutputDirectory artifacts\pkg-build: 98/98, and documentation links, anchors and tool names consistent.
  • No seat, lease, input, browser, Android or gamepad command ran, and the installed Anode's anode-control pipe was not touched.
  • Second review: read-only Codex (gpt-6-astra through bin/codex-review.sh, sandbox: read-only) on c13ff48: "No actionable regressions were identified. The status-before-output ordering addresses the completion race, and the added regression check exercises that interleaving."

Needs a manual check in a seat

Nothing specific: the change is in the seat host's job bookkeeping, and the check runs it with real processes. Whoever next runs test-development.ps1 in a seat covers seat_exec/seat_job end to end.

Merge note

It merges cleanly with main and with #30 (the 0.11.2 candidate). If #30 merges first, git puts this CHANGELOG entry at the top of the 0.11.2 section, which ships without this fix: move it under a new ## Unreleased heading above ## 0.11.2 when merging main in.

🤖 Generated with Claude Code

ExecutionJobs.ReadAsync read the output page first and the job's status
second. A job whose last output was drained and whose Done was set between
the two was reported finished, with hasMoreOutput false, while the page
stopped short of its end. An agent that stops reading at finished: true lost
the tail of the log.

The status is now read first. A job is marked finished only after its
output is drained, so a page read after a finished status holds everything
to the end. A quick check ("execution job tail") finishes a real job while
a read is between the two, through an internal seam, and requires that a
finished reply has nothing left to read.

Reported in ANODE-BUGS.md as B-025.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@skulitom
skulitom merged commit 6edbff5 into main Oct 10, 2026
1 check passed
@skulitom
skulitom deleted the compass/anode-fix-2026-10-09-job-finished-tail branch October 10, 2026 00:23
@skulitom

Copy link
Copy Markdown
Owner Author

Compass review: ready to merge (merged by compass-merge, 2026-10-10)

ReadAsync now reads the status before the output page. That is safe because Done is set only after the output drains (ExecutionJobs.cs lines 118–121), so a finished status always comes with the whole output. The test hook is null outside the checks.

  • Tested with main and [compass] Anode after the launch: be where agents look, and show what it is for #27 merged in (616d16f): the build, 98/98 quick checks including execution job tail, and the docs check. CI is green. Squash merge 6edbff5 has the same tree as that test (1f81ef6).
  • Second review: read-only Codex (logs/codex/2026-10-10-0118-...-job-finished-tail.out.txt) found no actionable regression, matching the fixer's own review.
  • Undo: git revert 6edbff5.

skulitom added a commit that referenced this pull request Oct 10, 2026
#31 and #32

- scripts/test-chrome-form.ps1: the window's process went into $chrome, which in PowerShell is the
  same variable as the -Chrome parameter, so the session check always failed and the final report
  named a process instead of chrome.exe. It is now $chromeProcess.
- #31 (B-025) and #32 (B-023) merged before this candidate, so they ship in 0.11.2: the release
  notes list both, RELEASE-READINESS drops them from "Known and open", and the check count is 99.
- The changelog, readiness record and release-notes anchor date 0.11.2 to 10 October, when its
  contents were fixed again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
skulitom added a commit that referenced this pull request Oct 10, 2026
…e launch within days (#30)

* [compass] Anode 0.11.2 release candidate

- Version 0.11.2 in Anode.csproj, server.json, the MCPB manifest and the
  Claude Code plugin; CHANGELOG's Unreleased section becomes 0.11.2.
- .github/RELEASE_NOTES.md: what's new in 0.11.2, known issues, upgrade.
- docs/RELEASE-READINESS.md: a 0.11.2 section with what was checked
  without a seat, the owner's live check as exact commands (about 25
  minutes), what stays covered only by stand-ins, and the known open bugs.
- scripts/test-chrome-form.ps1: an opt-in live check for #28 and #29 on a
  local Chrome page (text field set_value read-back, <select> set_value
  failing instead of reporting success, the open list observed once).

Package manifests, INSTALL.md's pinned example and the README's known
issues change after the release, so main never points at a release that
doesn't exist yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* [compass] 0.11.2 candidate: review fixes

- test-chrome-form.ps1: count Find-Control's results through @(...), since
  Windows PowerShell 5.1 gives a single PSCustomObject no Count; start
  Chrome inside the try, and clean up every Chrome process it started.
- RELEASE_NOTES: link the validation record on main, where the results
  are added after the release.
- RELEASE-READINESS: say which PRs are in scope; stop if no File Explorer
  window appeared.
- README: the 0.11.1 known issues now say 0.11.2 fixes them, which stays
  true inside the 0.11.2 package.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: align pinned installer example with 0.11.2

* [compass] 0.11.2 candidate: fix test-chrome-form's Chrome variable; add #31 and #32

- scripts/test-chrome-form.ps1: the window's process went into $chrome, which in PowerShell is the
  same variable as the -Chrome parameter, so the session check always failed and the final report
  named a process instead of chrome.exe. It is now $chromeProcess.
- #31 (B-025) and #32 (B-023) merged before this candidate, so they ship in 0.11.2: the release
  notes list both, RELEASE-READINESS drops them from "Known and open", and the check count is 99.
- The changelog, readiness record and release-notes anchor date 0.11.2 to 10 October, when its
  contents were fixed again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant