feat(update): session ids, per-node serialization, progress relay (VS-77) #95
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/VS-77-update-session-progress"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Server half of the VS-77 / VA-97 co-design. Together with vervain-agent VA-97 (PR #98) this fixes the confirmed root cause of the agent-side #VA-96 failure: the two proto crates had diverged, so
encode_agent_updateemitted a single 52-byte hash frame for both start and end. The agent decoded every start marker as an End (length-based discrimination), so no session opened and every block was dropped. This PR removes that frame and replaces it with an explicit, session-tagged protocol.Wire change (lockstep with vervain-agent VA-97; byte-identical)
AgentUpdate(13) is kind-discriminated: Begin =u16 cmd | u8 0 | u32 session_id | u64 total; End =u16 cmd | u8 1 | u32 session_id | 48-byte sha384. The legacy session-lessencode_agent_update/encode_agent_update_blockare removed.AgentUpdateBlock(14) gains au32 session_idheader.AgentUpdateProgress(32, agent -> server), decoded intoPostAuthFrame; a newvervain-agent-proto::updatemodule mirrors the agent crate.Server behaviour
build_agent_update_framesstamps a per-transfersession_id(Begin also carries the total binary length).AgentRegistrygains a per-node transfer guard (try_begin_update/end_update) plus a monotonic session-id source. The reactive AgentHash-mismatch path, the proactivepushAgentUpdate, and the scheduled auto-update sweep all reserve the slot before streaming, so concurrent producers coalesce instead of interleaving frames for one node (the interleave the agent could not associate with a session). The slot is released on a terminal progress event (restarting/failed) or on disconnect.dispatch_binaryhandlesAgentUpdateProgress: releases the guard on a terminal phase and publishes aProgressEventonto a new node-id-keyed broadcast bus (agent_progress, modeled onconnectivity).{"action":"event","event":{"action":"agentupdate",nodeid,session,phase,received,total,detail}}, gated by the samelookup_node_groupidvisibility check asnodeconnect. Best-effort (Lagged/Closed handled); never back-pressures the agent transfer.Tests
just check(compile + clippy -D warnings + fmt) and the full workspace test suite pass. New: guard coalesces a second in-flight push; progress bus publish/subscribe; proto round-trips; the two update-frame tests updated for the new Begin/End layout.Dependency
Co-designed with vervain-agent VA-97 (PR #98). The wire layout must match byte-for-byte; land them together.
WIRE CHANGE (lockstep with vervain-agent VA-97; the agent crate `vervain-agent-protocol` MUST match byte-for-byte): - AgentUpdate (opcode 13) is now an explicit kind-discriminated frame: Begin = `u16 cmd | u8 0 | u32 session_id | u64 total`, End = `u16 cmd | u8 1 | u32 session_id | 48-byte sha384`. The legacy session-less `encode_agent_update` / `encode_agent_update_block` are removed: they emitted the length-discriminated form the agent misread (every start marker decoded as an End), which is the root cause of the agent-side VA-96 failure. - AgentUpdateBlock (opcode 14) gains a `u32 session_id` header. - New AgentUpdateProgress (opcode 32, agent -> server) decoded into PostAuthFrame; mirrored in a new `vervain-agent-proto::update` module. Server behaviour: - build_agent_update_frames stamps a per-transfer session_id (Begin also carries the total binary length) via AgentUpdate::encode_begin/encode_end and AgentUpdateBlock::encode. - AgentRegistry gains a per-node transfer guard (try_begin_update / end_update) and a monotonic session_id source. The reactive AgentHash-mismatch path, the proactive pushAgentUpdate, and the scheduled auto-update sweep all reserve the slot before streaming, so concurrent producers coalesce instead of interleaving frames for one node. This eliminates the on-wire interleave the agent could not associate with a session. The slot is released on a terminal progress event (restarting/failed) or on disconnect. - dispatch_binary handles AgentUpdateProgress: it releases the per-node guard on a terminal phase and publishes a ProgressEvent onto a new node-id-keyed broadcast bus (agent_progress, modeled on connectivity). - The browser control-session loop subscribes to the progress bus and emits `{"action":"event","event":{"action":"agentupdate",nodeid,session,phase,received,total,detail}}`, gated by the same lookup_node_groupid visibility check as nodeconnect. The relay is best-effort (Lagged/Closed handled) and never back-pressures the agent transfer. This is the server half of the VS-77/VA-97 co-design that fixes the VA-96 root cause. #VS-77 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>