link sync store: fence when identify gives no capability list
Follow-up 1 of #35652, from the Codex review that gave SHIP on #34604.
What it fixes
When a machine's identify answer succeeds but its capabilities are missing or not a list, fetch_served read it as Some(false): "this machine serves no blob fetch". The push then skipped the fence, so an older blob.fetch job still running there could commit files over what this push writes. A missing list says nothing about what the machine serves, so it is now None, and the push takes fence_unknown (the path already used when identify does not answer at all). A machine whose list is present and lacks blob-fetch-v2 is still Some(false), unchanged.
The decision is pulled out of fetch_served into serves_fetch(&Value) so it can be tested without a socket.
Test
cargo test -p cmux-tui --lib an_identify_answer_without_capabilities (hosted, ./scripts/verify-cmux-tui-hosted.sh --filter):
- Red on the test-only commit b2e3c83 (run 41878360641):
left: Some(false),right: None. - Green on the head: the hosted run for
link::sync_cli::store(result in a comment below).
Observed / Not run
- Observed: the red above, from the hosted run's log.
- Not run: the
link_sync_storeend-to-end test, which has no fixture for an identify answer without capabilities. This change only affects that case.
risk: low (one branch of a capability check, toward the cautious path).
Changelog
none
Agent session: agent session
🤖 Generated with Claude Code
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Fences a push when a machine's identify succeeds but its capabilities are missing or not a list, closing a window where an older blob.fetch job could still commit files over the push's writes.
Previously a missing or non-list capabilities field was read as Some(false) ("serves no blob fetch") and the push skipped the fence. It now reads as None and the push takes fence_unknown, the same path used when identify does not answer at all. A present list that lacks blob-fetch-v2 is still Some(false), unchanged.
The capability check is pulled out of fetch_served into serves_fetch(&Value) so it can be tested without a socket, with a new unit test covering the missing, malformed, and present-list cases.