Draw an ended run's worker as building again, and a CI head the run will replace as superseded - #86
Merged
Merged
Conversation
…ill replace as superseded The fleet pipeline view drew two frames the captain read wrong on 2026-09-15. A worker whose run had ended `failed` (daemon shutting down) and who had been building again for 27 minutes drew `building 1h29m` finished beside `review FAIL`, with no band and no reason. The collector marked building completed the moment any run existed, whatever its status, and never put the run's error on the wire; the renderer never read run status at all. Now the building box measures the current phase only: Run #1 from dispatch, Run #N from Run #N-1's end, and after a failed or cancelled run it runs again from that run's last write while the worker's endpoint still resolves, with the running band. The run's end reason is stated on the head line in the daemon's own words. A row on Run #5 with review 31 minutes in drew the CI cell amber `4/4 your word` for PR 50's checks on head 4a22cbba, pushed by a cancelled earlier run, and the header counted it ready to merge. Now the collector reads GitHub's head beside the rollup and the run's own head from the daemon, and when a live run past its rebase has a different head it compares the two in the run's own worktree: merge-base against the default branch for "main moved", patch-ids for "new branch commit". The cell draws yellow with those sentences wrapped whole, the checked commit rides the facts line, and the header does not count it. The daemon's base_sha is the previous run's head, not a main base, so it is not consulted. Colour now encodes the verdict alone: every finished box and a CI cell whose checks passed on the head that will land are the runner band's centre green from one named token; "your word" moves to the pre-merge box; Run #N is dim rather than red. The pipeline block gains a fifth detail row because the two sentences wrap to five fifteen-column rows and widening the cell by one column leaves them at five. Tests reproduce both frames from the collector output captured that day and build the superseded fixture with real git so merge-base and patch-id are the tool's own answers.
The merge gate re-runs main's own copy of each test file against the branch. Main's collector test builds its fixture database from a schema trimmed to the columns the collector read at the time, which has no worktree_dir; the run index now names that column, so against that fixture SQLite refused the whole statement, no run resolved for any task, and every run-dependent assertion in the file failed or was never reached. With only the column added to the fixture, all 61 of main's assertions pass, so the collector now reads the table's columns once and selects worktree_dir only where it exists. The daemon trails its current release by several minor versions, so a column one version records is not one every database carries. The run counter goes back to red, main's behaviour. Painting it dim came from the scout report's own recommendation, not from a captain ruling, and the captain asked for it back. Main's counter test is restored byte for byte. The three main assertions that expect "your word" inside the GITHUB CI cell remain superseded under the captain's ruling that the cell's colour is its verdict alone; their replacements on this branch assert the ruled behaviour.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two frames the captain read wrong on 2026-09-15, diagnosed in the scout report
data/fm-pipeline-view-stale-run-r4/report.md(private, not in this repo) and fixed here under the captain's rulings.What was wrong
A run that ended under a live worker.
eln-live-body-coedit-b2's run endedfailed(daemon shutting down) and the worker had been building again for 27 minutes, but the row drewbuilding 1h29mfinished besidereview FAIL, with no band and no reason. The collector markedbuildingcompleted the moment any run existed for the branch, whatever its status, and never put the run's error on the wire; the renderer never readrun.statusat all.A CI head the run will replace.
eln-location-no-project-l3was 31 minutes into Run #5's review on an unpushed head while the CI cell drew amber4/4 your wordfor PR 50's checks on4a22cbba, pushed by a cancelled earlier run, and the header counted1 ready to merge. The wire carried no head of any kind, and amber meant both "parked on the captain" and "not green".What changes
Collector,
bin/fm-flow-snapshot.sh:buildingbox measures the current phase only: Run chore(treehouse): add worktree pool config; commit the reset-accounts skill #1 from dispatch, Run #N from Run #N-1's last write, and after afailedorcancelledrun it runs again from that run's last write while the worker's endpoint still resolves. A gone worker keeps the finished interval.run.errorandrun.headreach the wire from the daemon's record;ci.headis read in the samegh pr viewcall as the rollup.ci.supersededstates, when a live run past its rebase has a different head from the checked one, whether main moved (git merge-baseagainst the default branch) and whether the branch's content changed (git patch-id), read in the run's own worktree. The daemon'sbase_shais the previous run's head, not a main base, so it is not consulted.Renderer,
bin/fm-flow-tui.mjs:run failed: daemon shutting down.N/N passedon the head that will land, red failed, white running, yellow for a superseded head with the captain's sentencesmain moved, must retestandnew branch commit, must retestwrapped whole over the detail rows. The checked commit rides the facts line.your wordmoves to the pre-merge box.Run #Nis dim.Doc,
docs/flow-tui.md: the amendedbuildingcontract, the new wire fields, and a section on the CI verdict colours with the measurements behind them.Tests
tests/fm-flow-tui.test.shreproduces both frames from the collector output captured that day, pinned, and asserts each cell's word and paint through the renderer's own layout arithmetic: the rebuild with its band and reason, the gone-worker twin, the cancelled note, the three superseded captions plus the unreadable-reason fallback, the green cell with the word on pre-merge, green finished boxes, and the dim counter.tests/fm-flow-snapshot.test.shbuilds the superseded fixture with real git so merge-base and patch-id are the tool's own answers, and asserts the rebuild's elapsed, the per-run phase of a second run, the two heads, all three comparison outcomes, the missing-worktree fallback, and that the question is not asked for the run's own head, before rebase, or under--no-ci.bin/fm-lint.shclean;tests/fm-flow-tui.test.sh,tests/fm-flow-snapshot.test.sh, andtests/fm-flow.test.shpass.