mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-06 11:48:24 +00:00
Pointing the live harness at oversized transfer found three bugs that no unit test could have found, because each one was a thing the fixture did that a real server does not. 1. We declared no CEP-35 surface at all. `initialize`'s capabilityTags defaulted to empty and nothing ever passed any, so a spec-correct ContextVM server learned nothing about us — and it only chunks a CEP-22 response, or opens a CEP-41 stream, for a client that declared it can take one. Both profiles were dead on every live session, which is also why msg_sub_many has never had a live proof. The surface now rides the session's first message whatever that message is, since a session that opens with a tool call rather than a handshake would otherwise still declare nothing. 2. A completed transfer could not end the call. `onNotification` returned Unit, so after reassembling the response the transport went back to waiting for a direct one — which a chunking server never sends, the chunked response being the response. It returns JsonRpcMessage? now; non-null completes the call. CEP-41 keeps returning null, because `close` is not an answer. The unit test missed this by having the fixture ALSO answer normally, so the call was ended by that answer and reassembly only had to win a tie-break. The fixture now sends frames and nothing else, and the test fails without the fix. 3. The deadline bounded the whole call. Both profiles deliver one response as a run of notifications, each its own signed, wrapped, published relay event, so a 100 KB transfer ran past the 20 s default and was killed mid-run with every frame arriving and parsing correctly. timeoutMs now bounds silence, which is what a caller actually wants bounded. Subscriptions keep the old meaning through an explicit TimeoutMode.TOTAL: their timeout is a budget the sync loop re-opens on, and a busy stream bounded by silence would never return. Harness: tier-b.sh gains the three tools the two-party lifecycle never reaches — join_request_store, join_request_take_many and kp_remove, via a third account who asks to join rather than being invited — plus a backlog big enough to trip the coordinator's 48000-byte threshold. `cordn fetch --json` reports oversized_transfers so the run can tell a server that chunked from one that never had to; without it a reassembled response is indistinguishable from a direct one, by design. Also corrects an assertion I had backwards: reading a join request does not consume it. Retirement rides the next call after an accept or decline, so a reader that lost its process between listing and accepting has to still find the request — two amy runs are exactly that case. Verified live against the reference coordinator: TIER B PASSED with oversized_transfers=1, and CLIENT INTEROP PASSED unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012BfD4txdnsaPRXmNXbup9n