Files
cthulhu/internal/app/tentacle_remote_connection_test.go

703 lines
26 KiB
Go

// Copyright (c) 2026 Storm Dragon
// SPDX-License-Identifier: GPL-3.0-or-later
package app
import (
"bufio"
"context"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/tls"
"crypto/x509"
"encoding/json"
"io"
"log/slog"
"math/big"
"net"
"os"
"path/filepath"
"strings"
"testing"
"time"
"git.stormux.org/storm/cthulhu/internal/atspi"
"git.stormux.org/storm/cthulhu/internal/config"
"git.stormux.org/storm/cthulhu/internal/input"
"git.stormux.org/storm/cthulhu/internal/interaction"
"git.stormux.org/storm/cthulhu/internal/review"
"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
// OpenLocal submissions are synthetic; it cannot prove physical-source input.
func remote_command_fixture(t *testing.T, setup ...func(*tentacleRuntime)) (*tentacleRuntime, *consentTestForms, input.Command) {
t.Helper()
program := os.Getenv("CTHULHU_REMOTE_BINARY")
if program == "" {
t.Skip("requires the separately built Remote executable")
}
directory := t.TempDir()
spec := tentacle.Spec{ID: "remote", Program: []string{program, "--data-dir", filepath.Join(directory, "state")}, Presentation: true, Interaction: true, SessionEvents: true, RemoteGrants: []string{"output-observe", "remote-present"}}
data, _ := json.Marshal([]tentacle.Spec{spec})
launchPath := filepath.Join(directory, "launch.json")
if err := os.WriteFile(launchPath, data, 0600); err != nil {
t.Fatal(err)
}
bindings := &tentacleBindingRecorder{}
runtime := newTentacleRuntime(slog.New(slog.DiscardHandler), bindings, launchPath, "")
runtime.output = tentacleOutputFixture(t)
runtime.remotePolicy = tentacle.NewRemotePolicy()
runtime.output.gate.remotePolicy = runtime.remotePolicy
runtime.newManager = func() (*tentacle.Manager, error) { return tentacle.NewManager(tentacle.DefaultLimits(), nil) }
forms := &consentTestForms{requests: make(chan consentFormRequest, 1)}
runtime.forms = forms
for _, configure := range setup {
configure(runtime)
}
ctx, cancel := context.WithCancel(t.Context())
t.Cleanup(func() {
cancel()
stopCtx, stopCancel := context.WithTimeout(context.Background(), 5*time.Second)
defer stopCancel()
if err := runtime.Stop(stopCtx); err != nil {
t.Error(err)
}
})
if err := runtime.Start(ctx); err != nil {
t.Fatal(err)
}
var command input.Command
waitTentacle(t, func() bool {
runtime.mutex.Lock()
defer runtime.mutex.Unlock()
for id, registered := range runtime.commands {
if registered.id == "remote" {
command = id
return true
}
}
return false
})
runtime.Invoke(ctx, command)
return runtime, forms, command
}
func next_remote_form(t *testing.T, forms *consentTestForms) consentFormRequest {
t.Helper()
select {
case request := <-forms.requests:
if request.ctx.Err() != nil {
t.Fatal("form already cancelled")
}
if _, err := interaction.NewSession(request.form); err != nil {
t.Fatal("invalid form", err)
}
return request
case <-time.After(5 * time.Second):
t.Fatal("Remote did not present its next local form")
return consentFormRequest{}
}
}
func select_remote_relay(t *testing.T, forms *consentTestForms, address, role string) consentFormRequest {
t.Helper()
selection := next_remote_form(t, forms)
if !strings.Contains(selection.form.Title, "Remote relay and role") || selection.form.Elements[0].ID != "cancel" {
t.Fatal("missing safe endpoint/role selection")
}
// Required entry validation applies to every button in native forms. An
// empty relay must not prevent the initially focused Cancel from working.
selectionSession, _ := interaction.NewSession(selection.form)
if effect := selectionSession.Handle(interaction.Event{Key: interaction.Enter}); effect.Activated != "cancel" {
t.Fatal("empty relay entries blocked the Cancel button")
}
host, port, err := net.SplitHostPort(address)
if err != nil {
t.Fatal(err)
}
selection.reply <- internalUIResult{Activated: "review-access", Values: map[string]interaction.Value{"host": {Text: host}, "port": {Text: port}, "role": {Selected: role}}}
consent := next_remote_form(t, forms)
if !strings.Contains(consent.form.Title, "Remote access for remote") || consent.form.Elements[0].ID != "cancel" {
t.Fatal("connection skipped reader-owned consent")
}
for _, element := range consent.form.Elements {
if element.Checked {
t.Fatal("permission preselected")
}
}
return consent
}
func approve_remote_form(t *testing.T, forms *consentTestForms, consent consentFormRequest, role string) consentFormRequest {
t.Helper()
grant := "remote-present"
if role == "controlled" {
grant = "output-observe"
}
consent.reply <- internalUIResult{Activated: "approve", Values: map[string]interaction.Value{grant: {Checked: true}}}
credentials := next_remote_form(t, forms)
if credentials.form.Title != "Connect Remote relay" {
t.Fatal("approval did not reach connection controls", credentials.form.Title)
}
for _, element := range credentials.form.Elements {
if element.ID == "channel-key" && (!element.Secret || element.Text != "") {
t.Fatal("unmasked or prefilled channel key")
}
}
return credentials
}
func TestRemoteConnectionCommandConsentDenialAndPolicyCancellation(t *testing.T) {
for _, mode := range []string{"deny", "empty", "lock", "handoff"} {
t.Run(mode, func(t *testing.T) {
runtime, forms, command := remote_command_fixture(t)
consent := select_remote_relay(t, forms, "127.0.0.1:6837", "controller")
switch mode {
case "deny":
consent.reply <- internalUIResult{Cancelled: true}
case "empty":
consent.reply <- internalUIResult{Activated: "approve"}
case "lock", "handoff":
runtime.remotePolicy.SetAvailable(false)
runtime.remotePolicy.SetAvailable(true)
}
waitTentacle(t, func() bool { return len(runtime.resultSlots) == 0 })
select {
case form := <-forms.requests:
t.Fatal("denied consent opened connection controls", form.form.Title)
default:
}
// The command must recover after a denied/cancelled review, without
// keeping an awaiting flag or reviving the previous approval.
runtime.Invoke(t.Context(), command)
form := next_remote_form(t, forms)
if !strings.Contains(form.form.Title, "Remote relay and role") {
t.Fatal("stale setup survived cancellation")
}
form.reply <- internalUIResult{Cancelled: true}
waitTentacle(t, func() bool { return len(runtime.resultSlots) == 0 })
})
}
}
func TestRemoteConnectionCommandCancelsInspectionOnHandoff(t *testing.T) {
listener, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
t.Fatal(err)
}
defer listener.Close()
accepted := make(chan struct{})
closed := make(chan struct{})
go func() {
connection, err := listener.Accept()
if err != nil {
return
}
defer connection.Close()
connection.SetDeadline(time.Now().Add(5 * time.Second))
close(accepted)
io.Copy(io.Discard, connection)
close(closed)
}()
runtime, forms, _ := remote_command_fixture(t)
consent := select_remote_relay(t, forms, listener.Addr().String(), "controller")
credentials := approve_remote_form(t, forms, consent, "controller")
credentials.reply <- internalUIResult{Activated: "inspect-certificate"}
inspection := next_remote_form(t, forms)
select {
case <-accepted:
case <-time.After(5 * time.Second):
t.Fatal("inspection did not open its socket")
}
runtime.remotePolicy.SetAvailable(false)
runtime.remotePolicy.SetAvailable(true)
select {
case <-inspection.ctx.Done():
case <-time.After(time.Second):
t.Fatal("handoff retained the inspection form")
}
select {
case <-closed:
case <-time.After(time.Second):
t.Fatal("handoff retained a pre-lease inspection socket")
}
waitTentacle(t, func() bool { return len(runtime.resultSlots) == 0 })
}
func TestRemoteConnectionCommandPrivateRelay(t *testing.T) {
for _, test := range []struct {
role, ending string
playback bool
}{
{"controller", "disconnect", false}, {"controlled", "disconnect", false},
{"controller", "lock", false}, {"controlled", "lock", false},
{"controller", "handoff", false}, {"controlled", "handoff", false},
{"controller", "disable", false}, {"controlled", "disable", false},
{"controller", "disconnect", true}, {"controller", "lock", true},
{"controller", "handoff", true}, {"controller", "disable", true},
{"controller", "backend-failure", true},
} {
role, ending := test.role, test.ending
name := role + "/" + ending
if test.playback {
name += "/production-speech"
}
t.Run(name, func(t *testing.T) {
remoteText := " " + strings.Repeat("é\t世界 ", 1500) + " "
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
t.Fatal(err)
}
template := &x509.Certificate{SerialNumber: big.NewInt(1), NotBefore: time.Now().Add(-time.Hour), NotAfter: time.Now().Add(time.Hour), KeyUsage: x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}}
der, err := x509.CreateCertificate(rand.Reader, template, template, &key.PublicKey, key)
if err != nil {
t.Fatal(err)
}
listener, err := tls.Listen("tcp", "127.0.0.1:0", &tls.Config{Certificates: []tls.Certificate{{Certificate: [][]byte{der}, PrivateKey: key}}, MinVersion: tls.VersionTLS12})
if err != nil {
t.Fatal(err)
}
defer listener.Close()
probed, joined, closed := make(chan struct{}), make(chan struct{}), make(chan struct{})
speechReady := make(chan struct{})
relayOutput := make(chan []byte, 64)
go func() {
probe, err := listener.Accept()
if err != nil {
return
}
probe.SetDeadline(time.Now().Add(5 * time.Second))
data, _ := io.ReadAll(probe)
probe.Close()
if len(data) != 0 {
t.Error("certificate inspection sent application data")
}
close(probed)
connection, err := listener.Accept()
if err != nil {
return
}
defer connection.Close()
connection.SetDeadline(time.Now().Add(10 * time.Second))
reader := bufio.NewReader(connection)
if _, err := reader.ReadBytes('\n'); err != nil {
return
}
line, err := reader.ReadBytes('\n')
var join struct {
Type string `json:"type"`
Channel string `json:"channel"`
ConnectionType string `json:"connection_type"`
}
wantRole := "master"
if role == "controlled" {
wantRole = "slave"
}
if err != nil || json.Unmarshal(line, &join) != nil || join.Type != "join" || join.Channel != "synthetic-fixture" || join.ConnectionType != wantRole {
t.Error("invalid relay join or wrong selected role")
return
}
peerRole := "master"
if role == "controller" {
peerRole = "slave"
}
io.WriteString(connection, `{"type":"channel_joined","channel":"synthetic-fixture","clients":[{"id":7,"connection_type":"`+peerRole+`"}]}`+"\n")
close(joined)
if role == "controller" {
select {
case <-speechReady:
case <-t.Context().Done():
return
}
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{}},
}})
}
for {
frame, err := reader.ReadBytes('\n')
if err != nil {
break
}
relayOutput <- frame
}
close(closed)
}()
var server *isolatedVoiceServer
var voice *remoteSpeechVoice
var rendered isolatedVoiceUtterance
var configure []func(*tentacleRuntime)
if test.playback {
speaker, fixture := isolated_voice_fixture(t)
server = fixture
configure = append(configure, func(runtime *tentacleRuntime) {
worker := runtime.output.speech
worker.speaker = speaker
if err := worker.Start(t.Context()); err != nil {
t.Fatal(err)
}
t.Cleanup(func() {
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
if err := worker.Stop(ctx); err != nil {
t.Error(err)
}
})
})
}
runtime, forms, shortcut := remote_command_fixture(t, configure...)
if role == "controlled" {
worker := runtime.output.speech
worker.speaker = &observationSpeaker{fakeSpeaker{spoken: make(chan string, 64)}}
worker.textTransform = func(text string) string { return strings.ReplaceAll(text, "colour", "color") }
worker.reading = func() config.ReadingSettings { return runtime.output.live.Load().Reading }
if err := worker.Start(t.Context()); err != nil {
t.Fatal(err)
}
t.Cleanup(func() {
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
if err := worker.Stop(ctx); err != nil {
t.Error(err)
}
})
}
// Keep the explicit mailbox assembly fixture alongside production
// playback, which is attached by the actual runtime startup path.
var deliveries <-chan tentacle.RemoteSpeechDelivery
if role == "controller" && !test.playback {
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"}
inspection := next_remote_form(t, forms)
select {
case <-probed:
case <-time.After(5 * time.Second):
t.Fatal("certificate probe did not finish")
}
for inspection.form.Title != "Review Remote relay certificate" {
inspection.reply <- internalUIResult{Activated: "refresh"}
inspection = next_remote_form(t, forms)
}
inspection.reply <- internalUIResult{Activated: "trust-once"}
credentials = next_remote_form(t, forms)
credentials.reply <- internalUIResult{Activated: "connect", Values: map[string]interaction.Value{"channel-key": {Text: "synthetic-fixture"}}}
status := next_remote_form(t, forms)
select {
case <-joined:
case <-time.After(5 * time.Second):
t.Fatal("Remote did not join the private relay")
}
if status.form.Title != "Remote relay status" {
t.Fatal("missing connection status")
}
// Open has already succeeded before the relay can join. Return to
// ordinary desktop work without holding either runtime slot or form.
status.reply <- internalUIResult{Activated: "desktop"}
waitTentacle(t, func() bool { return len(runtime.resultSlots) == 0 && len(runtime.interactionSlots) == 0 })
if status.ctx.Err() == nil {
t.Fatal("background connection retained its form context")
}
if test.playback {
waitTentacle(t, func() bool {
worker := runtime.output.speech
worker.mutex.Lock()
defer worker.mutex.Unlock()
return worker.activeDone == nil && len(worker.pending) == 0
})
if ending == "backend-failure" {
server.mutex.Lock()
server.queryReplies = map[string]string{"GET LANGUAGE": "400 Rejected\r\n"}
server.mutex.Unlock()
}
}
close(speechReady)
if ending == "backend-failure" {
remote_stream_wait(t, closed)
// Backend failure retires the lease, while the process and
// mailbox owner remain usable for an explicit new connection.
runtime.Invoke(t.Context(), shortcut)
selection := next_remote_form(t, forms)
if selection.form.Title == "Remote relay status" {
// An ended attempt remains inspectable until explicitly
// closed, as with ordinary transport failure.
selection.reply <- internalUIResult{Activated: "cancel"}
waitTentacle(t, func() bool { return len(runtime.resultSlots) == 0 })
runtime.Invoke(t.Context(), shortcut)
selection = next_remote_form(t, forms)
}
if !strings.Contains(selection.form.Title, "Remote relay and role") {
t.Fatal("backend failure retained a connected workflow")
}
selection.reply <- internalUIResult{Cancelled: true}
waitTentacle(t, func() bool { return len(runtime.resultSlots) == 0 })
server.mutex.Lock()
for _, connection := range server.connections {
if connection.priority == "TEXT" && connection.pending != "" {
t.Error("failed rendering exposed a speech prefix")
}
}
server.mutex.Unlock()
return
}
select {
case <-closed:
t.Fatal("return to desktop disconnected the relay")
default:
}
var delivery tentacle.RemoteSpeechDelivery
if test.playback {
utterance := server.next_utterance(t)
for utterance.priority == "MESSAGE" {
// Returning to desktop produces local status on its ordinary
// client. The production Remote voice must stay separate.
utterance = server.next_utterance(t)
}
rendered = utterance
if utterance.text != remoteText || utterance.language != "fr" || utterance.spelling != "on" ||
utterance.ssml != "off" || utterance.priority != "TEXT" {
t.Fatal("production owner lost literal speech, metadata or local priority")
}
speaker := runtime.output.speech.speaker.(*configuredSpeaker)
speaker.mu.RLock()
voice = speaker.remote
speaker.mu.RUnlock()
if voice == nil {
t.Fatal("production owner did not acquire isolated synthesis")
}
} else 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()
} else {
// Joining at the relay is earlier than the Tentacle admitting the
// peer. Poll status before testing actual output rather than
// depending on a scheduling delay or replaying pre-peer output.
runtime.Invoke(t.Context(), shortcut)
status = next_remote_form(t, forms)
deadline := time.Now().Add(5 * time.Second)
for {
encoded, _ := json.Marshal(status.form)
if strings.Contains(string(encoded), "One opposite-role peer has joined") {
break
}
if time.Now().After(deadline) {
t.Fatal("peer did not become ready")
}
status.reply <- internalUIResult{Activated: "refresh"}
status = next_remote_form(t, forms)
}
status.reply <- internalUIResult{Activated: "desktop"}
waitTentacle(t, func() bool { return len(runtime.resultSlots) == 0 })
worker := runtime.output.speech
for _, request := range []speechRequest{
{Text: "private form", Cause: "internal-ui"},
{Text: "password", Role: "password text", origin: speechOriginLocal},
{Text: "local status", origin: speechOriginStatus},
{Text: "colour " + remoteText, origin: speechOriginLocal},
} {
if err := worker.EnqueueAndWait(t.Context(), request); err != nil {
t.Fatal(err)
}
}
request := document_observation_request(t, "read-all", review.Result{
ReadAllContext: t.Context(), ReadAllLines: []atspi.DocumentLine{{Contents: []atspi.DocumentContent{{
Snapshot: atspi.Snapshot{Role: "text"}, Text: "First colour. Second colour.",
}}}},
})
if err := worker.EnqueueAndWait(t.Context(), request); err != nil {
t.Fatal(err)
}
request = current_line_observation_request(t, review.Result{CurrentLineBrowse: true,
DocumentCaretText: "Current colour.", DocumentPosition: review.DocumentPosition{Snapshot: atspi.Snapshot{Role: "static"}},
DocumentCaretContext: []atspi.Snapshot{{Role: "static"}, {Role: "paragraph"}, {Role: "document web"}}})
if err := worker.EnqueueAndWait(t.Context(), request); err != nil {
t.Fatal(err)
}
// A joined line can contain a private neighboring fragment even
// when its caret source and the line's presentation are ordinary.
caret := atspi.Snapshot{Role: "static"}
privateLine := atspi.DocumentLine{Contents: []atspi.DocumentContent{{Snapshot: caret, Text: "private joined text"}},
SourceContexts: [][]atspi.Snapshot{{caret}, {{Role: "static"}, {Role: "password text"}}}}
for _, kind := range []string{"caret", "read-all", "current-line"} {
request := document_observation_request(t, kind, review.Result{
Moved: true, DocumentCaretCommand: review.CaretNextLine,
DocumentPosition: review.DocumentPosition{Snapshot: caret}, DocumentCaretText: "private joined text",
DocumentCaretContext: []atspi.Snapshot{caret, {Role: "document web"}},
DocumentCaretLine: &privateLine, ReadAllContext: t.Context(), ReadAllLines: []atspi.DocumentLine{privateLine},
})
if err := worker.EnqueueAndWait(t.Context(), request); err != nil {
t.Fatal(err)
}
}
for _, private := range []bool{false, true} {
result := native_current_line_result()
if private {
result.DocumentCaretText = "private native text"
result.DocumentCaretContext[1].Role = "password text"
}
if err := worker.EnqueueAndWait(t.Context(), current_line_observation_request(t, result)); err != nil {
t.Fatal(err)
}
}
for _, kind := range []string{"object", "line"} {
for _, privacy := range []string{"ordinary", "snapshot-ancestor", "stale"} {
request := review_observation_request(t, kind, review_observation_result(t, kind, privacy))
if err := worker.EnqueueAndWait(t.Context(), request); err != nil {
t.Fatal(err)
}
}
}
for _, privacy := range []string{"ordinary", "snapshot-ancestor", "missing", "stale"} {
if err := worker.EnqueueAndWait(t.Context(), where_am_i_observation_request(t, privacy)); err != nil {
t.Fatal(err)
}
}
for _, privacy := range []string{"ordinary", "ancestor", "changed-text", "failure"} {
if err := worker.EnqueueAndWait(t.Context(), native_where_am_i_request(t, privacy)); err != nil {
t.Fatal(err)
}
}
list := atspi.Snapshot{BusName: ":1.42", Path: "/relay-list", Role: "list", Name: "Relay items"}
privateList := list
privateList.Path, privateList.Name = "/private-list", "Private relay label"
for _, request := range []speechRequest{
{origin: speechOriginLocal, Text: "Relay inside", Context: []atspi.Snapshot{list}},
{origin: speechOriginLocal, Text: "Relay outside", Context: []atspi.Snapshot{}},
{origin: speechOriginSecret, Text: "Private relay content", Context: []atspi.Snapshot{privateList}},
{origin: speechOriginLocal, Text: "Relay resumed", Context: []atspi.Snapshot{}},
} {
if err := worker.EnqueueAndWait(t.Context(), request); err != nil {
t.Fatal(err)
}
}
worker.InterruptForUser()
var received strings.Builder
ends, frames := 0, 0
readOutput:
for {
select {
case frame := <-relayOutput:
var message struct {
Type string `json:"type"`
Sequence []json.RawMessage `json:"sequence"`
}
if err := json.Unmarshal(frame, &message); err != nil {
t.Fatal(err)
}
if message.Type == "cancel" {
break readOutput
}
if message.Type != "speak" {
t.Fatal("unexpected observed relay message", message.Type)
}
frames++
for _, raw := range message.Sequence {
var text string
if json.Unmarshal(raw, &text) == nil {
received.WriteString(text)
} else if strings.Contains(string(raw), "EndUtteranceCommand") {
ends++
} else {
t.Fatal("unexpected observed speech command", string(raw))
}
}
case <-time.After(5 * time.Second):
t.Fatal("reader output did not reach the relay in order")
}
}
if received.String() != "color "+remoteText+"First color.Second color.Current color.Native color.Review color.staticFlat color. Review color.Review color.staticNative color.textRelay items listRelay insideLeaving Relay items list.Relay outsideRelay resumed" || frames < 18 || ends != 17 {
t.Fatalf("observation leaked private text or lost resolved output/boundaries: frames=%d ends=%d suffix=%q", frames, ends, received.String()[max(0, received.Len()-160):])
}
}
// Reopening returns to this attempt, with no second consent or
// saved-key read. Lifecycle retirement must work with no form open.
switch ending {
case "disconnect":
runtime.Invoke(t.Context(), shortcut)
status = next_remote_form(t, forms)
if status.form.Title != "Remote relay status" {
t.Fatal("reopening lost the approved connection")
}
status.reply <- internalUIResult{Activated: "cancel"}
case "lock":
runtime.output.gate.SetLocked(true, nil, nil, nil, nil, &brailleWorker{})
runtime.output.gate.SetLocked(false, nil, nil, nil, nil, &brailleWorker{})
case "handoff":
runtime.output.gate.SetSuspended(true)
runtime.output.gate.SetSuspended(false)
case "disable":
runtime.Disable()
}
select {
case <-closed:
case <-time.After(5 * time.Second):
t.Fatal("background connection retained the relay after " + ending)
}
waitTentacle(t, func() bool { return len(runtime.resultSlots) == 0 })
if test.playback {
remote_stream_wait(t, voice.closed)
server.mutex.Lock()
pending := server.connections[rendered.id].pending
server.mutex.Unlock()
if pending != "" {
t.Fatal("revoked production speech survived backend cleanup")
}
} else if role == "controller" {
// Socket cancellation precedes the final sequenced lease close.
// A reopened status interaction did not issue the original consent,
// so its result-slot completion is not the lease-close barrier.
select {
case <-delivery.Context.Done():
case <-time.After(3 * time.Second):
t.Fatal("Disconnect retained remote delivery authority")
}
}
})
}
}