[agent/codex:gpt-5.4-mini] Read docs/RFC.md fully. Find ONE feature described in the sp... #25

Merged
Virgil merged 1 commit from main into dev 2026-04-03 20:40:12 +00:00
2 changed files with 67 additions and 0 deletions

View file

@ -26,6 +26,13 @@ type ActionDefinition struct {
Invoke func(map[string]any) (any, bool, error)
}
// ActionRegistrar accepts named DNS action handlers from a service.
//
// service.RegisterActions(registrar)
type ActionRegistrar interface {
RegisterAction(name string, invoke func(map[string]any) (any, bool, error))
}
// ActionDefinitions returns the complete DNS action surface in registration order.
//
// service.ActionDefinitions()
@ -132,6 +139,18 @@ func (service *Service) ActionNames() []string {
return names
}
// RegisterActions publishes the DNS action surface to a registrar in definition order.
//
// service.RegisterActions(registrar)
func (service *Service) RegisterActions(registrar ActionRegistrar) {
if registrar == nil {
return
}
for _, definition := range service.ActionDefinitions() {
registrar.RegisterAction(definition.Name, definition.Invoke)
}
}
// HandleAction executes a DNS action by name.
//
// service.HandleAction("dns.resolve", map[string]any{"name": "gateway.charon.lthn"})

View file

@ -1063,6 +1063,41 @@ func TestServiceActionNamesExposeAllRFCActions(t *testing.T) {
}
}
func TestServiceRegisterActionsPublishesAllActionsInOrder(t *testing.T) {
service := NewService(ServiceOptions{
Records: map[string]NameRecords{
"gateway.charon.lthn": {
A: []string{"10.10.10.10"},
},
},
})
registrar := &actionRecorder{}
service.RegisterActions(registrar)
expected := service.ActionNames()
if len(registrar.names) != len(expected) {
t.Fatalf("expected %d registered actions, got %d: %#v", len(expected), len(registrar.names), registrar.names)
}
for index, name := range expected {
if registrar.names[index] != name {
t.Fatalf("unexpected registered action at %d: got %q want %q", index, registrar.names[index], name)
}
}
payload, ok, err := registrar.handlers[ActionResolve](map[string]any{"name": "gateway.charon.lthn"})
if err != nil {
t.Fatalf("unexpected registered handler error: %v", err)
}
if !ok {
t.Fatal("expected registered handler to resolve")
}
result, ok := payload.(ResolveAddressResult)
if !ok || len(result.Addresses) != 1 || result.Addresses[0] != "10.10.10.10" {
t.Fatalf("unexpected registered handler payload: %#v", payload)
}
}
func TestServiceActionDefinitionsHaveInvokers(t *testing.T) {
service := NewService(ServiceOptions{
Records: map[string]NameRecords{
@ -1226,3 +1261,16 @@ func TestServiceHandleActionReverseHealthServeAndDiscover(t *testing.T) {
t.Fatalf("expected discover to refresh tree root, got %#v", discoverHealth["tree_root"])
}
}
type actionRecorder struct {
names []string
handlers map[string]func(map[string]any) (any, bool, error)
}
func (recorder *actionRecorder) RegisterAction(name string, invoke func(map[string]any) (any, bool, error)) {
if recorder.handlers == nil {
recorder.handlers = map[string]func(map[string]any) (any, bool, error){}
}
recorder.names = append(recorder.names, name)
recorder.handlers[name] = invoke
}