Route a call key naming its machine after '@', and refuse a malformed key before publishing

The lease write asked seat:node-service-manager.stop@novox-be through Conn.Call, which published
the '@' inside the subject: nobody served it and the call timed out after 30 s with nothing said
(issue 774 notes 84-87). Every key now parses in one place, calladdress: Call routes '@node' as
CallOn does, and stdio Ask refuses a key the runtime could not route, before anything is sent.

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
This commit is contained in:
2026-11-02 11:22:50 +01:00
parent 8295207077
commit 49b307a46d
7 changed files with 219 additions and 27 deletions
+5 -1
View File
@@ -237,7 +237,8 @@ func TestReleaseAcceptanceAProcessDoesExactlyItsBusDeclaration(t *testing.T) {
}
// 1470/AC4: two answerers of the same verb on the subjects of nodes ace and g14; CallOn naming g14 gets g14's
// answer, and ace's answerer hears nothing.
// answer, and ace's answerer hears nothing. Issue 774 notes 84-87: Call with the key `<verb>@g14` is published on the
// same subject, never on one holding the '@' that nobody serves.
func TestCallOnReachesTheNamedNodeAlone(t *testing.T) {
url, account := grantedSendProcess(t)
adminNC, _ := adminJS(t, url)
@@ -271,6 +272,9 @@ func TestCallOnReachesTheNamedNodeAlone(t *testing.T) {
if string(result) != `{"node":"g14"}` {
t.Fatalf("result: %s, want g14's answer", result)
}
if result, err = conn.Call("seat:operator-channel.tell@g14", map[string]any{}); err != nil || string(result) != `{"node":"g14"}` {
t.Fatalf("Call with @g14: %s, %v, want g14's answer", result, err)
}
select {
case <-aceHeard:
t.Error("ace's answerer heard a call named for g14")