52 lines
1.5 KiB
Go
52 lines
1.5 KiB
Go
// 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
|
|
}
|