Files
mesh-catalog/modules/claude-code/cmd/claude-code/registrations.go
T
jschoubben 657cb2b6c8 A section registered before the controller's terminal took over, or set there, is replaced or removed by a proposal the operator approves
It could not be changed at all: propose refused a name set there and never replaced one. The ask now says plainly that
it replaces or removes the registered section and binds its text's digest; on Approve every node renders the new text
in the place of the old (a removal leaves it out); a replacement keeps the section's own heading form (issue 340 note 14).

Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
2026-11-05 22:14:55 +01:00

125 lines
3.9 KiB
Go

package main
// What a Claude Code session on the mesh runs or obeys, and where each came from (novox/hq issue 340): for the
// operator to review what is registered today, read-only.
import (
"encoding/json"
"sort"
"strings"
)
// ByIs says what a registration's `by` is: the node whose tool runner served the call, never the caller, whom the
// runner is not told.
const ByIs = "the node whose tool runner served the registering call; who called it was never recorded, because the runner is not told"
// Registrations is every registration on the mesh that reaches a session, read from the state, and what the
// operator set at the controller's terminal for this node: the tool servers (`servers`), the agent's
// configuration (`config`) with whether each is still rendered and, when not, why; and the `managed_settings`
// and `mcp_servers` this node's layers compose to.
func Registrations(p Paths, servers ServerState, config ConfigState) (map[string]any, error) {
serverKeys, err := servers.Keys()
if err != nil {
return nil, err
}
sort.Strings(serverKeys)
registered := map[string]any{}
for _, key := range serverKeys {
raw, found, err := servers.Get(key)
if err != nil || !found {
continue
}
var entry map[string]any
if json.Unmarshal(raw, &entry) != nil {
continue
}
row := map[string]any{"entry": entry, "by": "not recorded: a tool server's registration kept only its entry"}
if _, name, ok := strings.Cut(key, "."); ok {
if problem := EntryProblem(name, entry); problem != "" {
row["rendered"] = "no: " + problem
} else {
row["rendered"] = "yes, on the nodes its key names"
}
}
registered[key] = row
}
configKeys, err := config.Keys()
if err != nil {
return nil, err
}
sort.Strings(configKeys)
items := map[string]any{}
for _, key := range configKeys {
raw, found, err := config.Get(key)
if err != nil || !found {
continue
}
var it Item
if json.Unmarshal(raw, &it) != nil {
continue
}
_, node, _, _, ok := ParseKey(key)
if !ok {
continue
}
row := map[string]any{"kind": it.Kind, "scope": it.Scope, "by": it.By, "at": it.At}
files := make([]string, 0, len(it.Files))
for f := range it.Files {
files = append(files, f)
}
sort.Strings(files)
if len(files) > 0 {
row["files"] = files
}
switch it.Kind {
case KindHook:
row["event"], row["matcher"], row["command"] = it.Event, it.Matcher, it.Command
case KindSettings:
row["settings"] = it.Settings
}
switch problem := it.Problem(); {
case it.Key(node) != key:
row["rendered"] = "no: its key does not say what the item is"
case problem != "":
row["rendered"] = "no: " + problem
default:
row["rendered"] = "yes, as " + it.Scope + " " + it.Kind
}
items[key] = row
}
var settings Settings
_ = readJSON(p.Settings, &settings)
text, leftOut := terminalText(p)
shared := []string{}
for _, it := range text {
shared = append(shared, it.Kind+" "+it.Name)
}
// The registered text an approved proposal replaced or removed on this node: what renders instead, or nothing.
replaced := []map[string]any{}
if approved, err := ReadApproved(p); err == nil {
for _, s := range ApprovedHere(approved, p.Node) {
if s.Over == "" {
continue
}
did := "replaced"
if s.Removes {
did = "removed"
}
replaced = append(replaced, map[string]any{"name": s.Name, "scope": s.Scope, "did": did,
"registered text": fingerprintOf(s.Over), "proposal": s.Proposal, "approved": s.Approved.Format("2006-01-02T15:04:05Z07:00"),
"by": s.By})
}
}
return map[string]any{
"registered text replaced by an approved proposal, or removed by one": replaced,
"set at the controller's terminal, as this node composes it": map[string]any{
"managed_settings": settings.ManagedSettings, "mcp_servers": settings.MCPServers,
"shared text": shared, "shared text left out": leftOut},
"tool servers registered through this module": registered,
"configuration registered through this module": items,
"by": ByIs,
}, nil
}