Control: action.run lists created objects that show a publish late (cx-9ce.30)
Summary
action.run sometimes answered with an empty created list, for example cmux tab new under load (plans/cmux-next/cli.md Remaining 13). The reply looks up each created object in the snapshot that reflects the run's daemon sequence. But the app can build a new object a publish after the event that moved the sequence, so the lookup came up empty.
- A settled run now waits briefly for a snapshot that shows every object it created: at most 2 s, and always ending 100 ms before the request's own deadline. If an object never shows (say a tab that was opened and closed in the same run), it's left out, and the run still answers
ran: truerather than timing out. ControlSnapshotStorewaits can now take any condition (snapshot(where:deadline:)); the sequence barrier uses the same path. The created-object wait lives on the store (ControlSnapshotStore+Created.swift), soControlRouterdoesn't grow.- A store wait whose deadline had already passed could register after its timer had fired, and then nothing ever resumed it. It now answers nil at once. The review found this; I couldn't write a test that hits the race reliably, so it is untested.
- The bead's other half, item 8 (an unknown target reports
ran: true), was already done: the router refuses an unknown target once the topology is loaded (ActionRunTargetTests), andActionScoperefuses an unknown tab, pane or workspace in the handler.cli.mdnow marks items 8 and 13 done.
Testing
Behavior tests ActionRunCreatedTests (CmuxNextControl). Each runs action.run through ControlRouter with an executor that creates a tab the way a loaded app can.
- The snapshot reaches the command's sequence first, and the tab appears 200 ms later.
createdmust list it. - The tab never appears, under the default 2 s request deadline. The run must answer
ran: truewithcreated: [].
All runs are fleet run-swift-testing-suites.sh on the full package:
- Test 1, red (test only, 384a8010a12b):
createdwas[]. - Test 1, green (9df392c295d8): passes.
- Test 2, red (test only, 8a5607051ff4, on the first fix):
timeoutafter 1999 ms. The review predicted this: the first fix's wait ignored the request deadline. - Test 2, green (132b17e1fdd9, then 9d1559bf7863 with the race fix): both tests pass.
PasswordManagerRouteTests timed out in the four runs with the fix on the older base (73434cf13f4d). Its action succeeds and its 20 s wait for the Passwords tab expires. It never calls action.run or waits on the control snapshot store. #20103 documents the same fleet timeouts in it and in PinnedPageTests. On base it is skipped (no published same-tree cmux-tui), so base gives no comparison. On the merged head (1d96e462ec23, base merged with #20103), the full package run had no failing suite: PasswordManagerRouteTests ran (not skipped) and passed in 1 s, and both ActionRunCreatedTests pass.
Bead: cx-9ce.30
Changelog
- Fixed:
cmuxcommands that create something (for examplecmux tab new) no longer sometimes report an empty created list.
🤖 Generated with Claude Code