Assemble Remote speech before reader delivery

This commit is contained in:
ak47 committed 2026-11-04 14:33:54 -05:00
1 parent f23e89ed93
commit 205cb27483
9 files changed
+492 -33

No files matched your search

@@ -25,6 +25,7 @@ import (
"git.stormux.org/storm/cthulhu/internal/input"
"git.stormux.org/storm/cthulhu/internal/interaction"
"git.stormux.org/storm/cthulhu/internal/tentacle"
"git.stormux.org/storm/cthulhu/internal/tentaclewire"
)
// This uses the source-built external executable and real host/SDK IPC. Only
@@ -223,6 +224,7 @@ func TestRemoteConnectionCommandCancelsInspectionOnHandoff(t *testing.T) {
func TestRemoteConnectionCommandPrivateRelay(t *testing.T) {
for _, role := range []string{"controller", "controlled"} {
t.Run(role, func(t *testing.T) {
remoteText := " " + strings.Repeat("é\x00世界 ", 1500) + " "
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
t.Fatal(err)
@@ -274,12 +276,39 @@ func TestRemoteConnectionCommandPrivateRelay(t *testing.T) {
t.Error("invalid relay join or wrong selected role")
return
}
io.WriteString(connection, `{"type":"channel_joined","channel":"synthetic-fixture","clients":[]}`+"\n")
peerRole := "master"
if role == "controller" {
peerRole = "slave"
}
io.WriteString(connection, `{"type":"channel_joined","channel":"synthetic-fixture","clients":[{"id":7,"connection_type":"`+peerRole+`"}]}`+"\n")
if role == "controller" {
json.NewEncoder(connection).Encode(map[string]any{"type": "speak", "origin": 7, "priority": 2, "sequence": []any{
[]any{"CharacterModeCommand", map[string]any{"state": true}},
[]any{"LangChangeCommand", map[string]any{"lang": "fr"}}, remoteText,
[]any{"EndUtteranceCommand", map[string]any{}},
}})
}
close(joined)
io.Copy(io.Discard, reader)
close(closed)
}()
runtime, forms, _ := remote_command_fixture(t)
// Only this fixture supplies a reader owner. Production remains
// disabled until output arbitration/security policy is implemented.
var deliveries <-chan tentacle.RemoteSpeechDelivery
if role == "controller" {
runtime.mutex.Lock()
for _, command := range runtime.commands {
if command.id == "remote" {
deliveries = command.session.EnableRemoteSpeech()
break
}
}
runtime.mutex.Unlock()
if deliveries == nil {
t.Fatal("Remote fixture session unavailable")
}
}
consent := select_remote_relay(t, forms, listener.Addr().String(), role)
credentials := approve_remote_form(t, forms, consent, role)
credentials.reply <- internalUIResult{Activated: "inspect-certificate"}
@@ -305,6 +334,40 @@ func TestRemoteConnectionCommandPrivateRelay(t *testing.T) {
if status.form.Title != "Remote relay status" {
t.Fatal("missing connection status")
}
var delivery tentacle.RemoteSpeechDelivery
if role == "controller" {
select {
case delivery = <-deliveries:
case <-time.After(5 * time.Second):
t.Fatal("split relay speech did not reach the reader owner")
}
var text strings.Builder
ends := 0
for _, speech := range delivery.Speeches {
if !tentaclewire.ValidRemoteSpeech(speech) || speech.Priority != 2 {
t.Fatal("invalid speech fragment or changed priority")
}
for _, part := range speech.Parts {
if part.End {
ends++
} else {
if !part.Characters || part.Language != "fr" {
t.Fatal("split speech lost character/language state")
}
text.WriteString(part.Text)
}
}
}
if len(delivery.Speeches) < 2 || text.String() != remoteText || ends != 1 {
t.Fatal("reader owner received partial or altered utterance")
}
select {
case <-deliveries:
t.Fatal("one relay utterance became multiple deliveries")
default:
}
delivery.Release()
}
status.reply <- internalUIResult{Activated: "cancel"}
select {
case <-closed:
@@ -312,6 +375,9 @@ func TestRemoteConnectionCommandPrivateRelay(t *testing.T) {
t.Fatal("Disconnect and close retained the relay")
}
waitTentacle(t, func() bool { return len(runtime.resultSlots) == 0 })
if role == "controller" && delivery.Context.Err() == nil {
t.Fatal("Disconnect retained remote delivery authority")
}
})
}
}