// peer.go — Peer agent management. // // # Capability-Based Peer Access // // Peers implement the namespace-bounded capability model for inter-agent // communication. An agent can only message agents that exist in its peer // list—the peer/ directory is dynamically generated from this list. // // The enforcement point is in fs/spec.go: the peer/ directory is built via // virtfs.Each(a.Peers()), so only declared peers appear as writable files. // If agent A tries to write to peer/B but B is not in A's peer list, the // file simply doesn't exist. // // This is structural enforcement: the directory listing IS the capability // set. An agent cannot reference a peer that isn't in its namespace. // // Links are bidirectional: adding a peer on one agent adds the reverse link. // This ensures both sides explicitly consent to the communication channel. package agent import "slices" // AddPeer adds a peer agent by name. func (ag *Agent) AddPeer(name string) { ag.peerMu.Lock() if ag.peers == nil { ag.peers = make(map[string]struct{}) } ag.peers[name] = struct{}{} ag.peerMu.Unlock() } // RemovePeer removes a peer agent by name. func (ag *Agent) RemovePeer(name string) { ag.peerMu.Lock() delete(ag.peers, name) ag.peerMu.Unlock() } // Peers returns the sorted list of peer agent names. func (ag *Agent) Peers() []string { ag.peerMu.RLock() defer ag.peerMu.RUnlock() out := make([]string, 0, len(ag.peers)) for name := range ag.peers { out = append(out, name) } slices.Sort(out) return out }