Files
pulse/internal/ai/tools/executor_clone_test.go
T
rcourtman 5d53fa7a3d Remove the Assistant mutation handlers nothing calls
pulse_control only plans typed resource actions into Pulse Actions
(executeControlResource -> typedActionPlanner). The handlers that sat
behind the retired model-authored command, file and container paths
stayed in the tree with no production caller: run command, guest
control, app-container control, Docker control and container update,
Kubernetes scale/restart/delete-pod/exec, and file append/write.
registerFileTools was never called either, so pulse_file_edit is not
registered at all; calls to it are denied by the mutation registry
before any tool lookup.

A whole-program reachability run over cmd/... lists each of them as
unreachable, and so is everything only they used: approval-record and
preflight authoring, the command and native-action audit lanes with
their remediation-lock gate and plan-hash helpers, the Docker host
resolvers, and the file write verification. The executor's autonomous
flag, whose only readers were those handlers, goes with them (the
executor's SetAutonomousMode and the flag argument of SetContext).

Delete them with their tests and the constants, types and test helpers
they stranded. The contract prose that described the removed broker now
says that plan freshness and the operator remediation lock are enforced
by internal/actionlifecycle. Two source pins that named deleted code go
(the publishActionCompleted dispatch sites and the pulse_file_edit
declaration), the standards tests drop their expectations of an
ActionPlan construction in action_audit.go and of the legacy app_container
rejection in the deleted file-edit test, and the RA35 evidence entry for
the deleted run-command test goes with them.

Left alone on purpose: the saved autonomous control level and its
entitlement and approval-admission checks, which stay as legacy
compatibility, Service.SetAutonomousMode and the chat clamp,
SetOnActionCompleted and its router wiring (no dispatcher is left, the
contract prose says so), and the protected-guests plumbing.

Rebuilt on current main: the first version had 213 commits of drift.
Two conflicts, both on code this change deletes. tools_control.go takes
the deletion over the Protected guests cleanup that landed inside
executeRunCommand. action_audit_remediation_lock_test.go goes with the
audit lanes, including the test added for the dispatch gate's read
through a succession; that gate is deleted here, and
TestLockMovedBySuccessionStillRefusesTheIDThePreviousGenerationLists in
internal/actionlifecycle covers the same refusal on the live path.
2026-10-11 12:35:28 +01:00

62 lines
2.0 KiB
Go

package tools
import "testing"
func TestPulseToolExecutorCloneIsolatesSessionState(t *testing.T) {
creator := &mockPatrolFindingCreator{}
proposer := &mockPatrolObserverProposer{}
resolved := &mockResolvedContext{}
original := NewPulseToolExecutor(ExecutorConfig{})
original.SetContext("node", "node-1")
original.SetOrgID("tenant-a")
original.SetResolvedContext(resolved)
original.SetPatrolFindingCreator(creator)
original.SetPatrolObserverProposer(proposer)
clone := original.Clone()
if clone == nil {
t.Fatal("Clone() returned nil")
}
if clone == original {
t.Fatal("Clone() returned the original executor")
}
if clone.GetResolvedContext() != nil {
t.Fatal("Clone() should start without a session-scoped resolved context")
}
if clone.GetPatrolFindingCreator() != creator {
t.Fatal("Clone() should retain patrol creator availability for the new run")
}
if clone.GetPatrolObserverProposer() != proposer {
t.Fatal("Clone() should retain patrol observer proposer availability for the new run")
}
if clone.targetType != original.targetType || clone.targetID != original.targetID {
t.Fatalf("Clone() lost base execution context: got %q/%q", clone.targetType, clone.targetID)
}
if clone.orgID != original.orgID {
t.Fatalf("Clone() orgID = %q, want %q", clone.orgID, original.orgID)
}
clone.SetContext("vm", "vm-201")
if original.targetType != "node" || original.targetID != "node-1" {
t.Fatalf("original context mutated after clone update: got %q/%q", original.targetType, original.targetID)
}
}
func TestPulseToolExecutorCloneDoesNotSharePatrolCreatorSlot(t *testing.T) {
creator := &mockPatrolFindingCreator{}
original := NewPulseToolExecutor(ExecutorConfig{})
original.SetPatrolFindingCreator(creator)
clone := original.Clone()
clone.SetPatrolFindingCreator(nil)
if original.GetPatrolFindingCreator() != creator {
t.Fatal("clearing patrol creator on clone mutated the original executor")
}
if clone.GetPatrolFindingCreator() != nil {
t.Fatal("clone patrol creator should be independently mutable")
}
}