9p: remove all peer code

Peers were removed from core but lingered in the 9P layer.
Deleted: PeerAdd, PeerRemove, PeerList, PeerSubmit (D-Bus + manager),
peer directory listing, peer file handling, peer stat, peer
creation/removal, HasPeer, peers field on Session.
This commit is contained in:
Levi Neely 2026-07-29 22:17:39 +02:00
parent aeef7ff718
commit 82a7f585f2
4 changed files with 3 additions and 209 deletions

34
dbus.go
View File

@ -476,36 +476,6 @@ func (a *DBusAdapter) ListAgents() ([]string, *dbus.Error) {
return result, nil
}
// --- Peers ---
func (a *DBusAdapter) PeerAdd(sessionID, peerID string) (bool, *dbus.Error) {
if err := a.mgr.PeerAdd(sessionID, peerID); err != nil {
return false, nil
}
return true, nil
}
func (a *DBusAdapter) PeerRemove(sessionID, peerID string) (bool, *dbus.Error) {
if err := a.mgr.PeerRemove(sessionID, peerID); err != nil {
return false, nil
}
return true, nil
}
func (a *DBusAdapter) PeerList(sessionID string) ([]string, *dbus.Error) {
peers, err := a.mgr.PeerList(sessionID)
if err != nil {
return nil, nil
}
return peers, nil
}
func (a *DBusAdapter) PeerSubmit(sessionID, peerID, prompt string) (bool, *dbus.Error) {
if err := a.mgr.PeerSubmit(sessionID, peerID, prompt); err != nil {
return false, nil
}
return true, nil
}
// --- Detached processes ---
@ -737,10 +707,6 @@ var introspectXML = `<node>
<method name="ListModelsByBackend"><arg direction="in" type="s" name="backend"/><arg direction="out" type="as"/></method>
<method name="ListModels"><arg direction="in" type="s" name="sessionID"/><arg direction="out" type="as"/></method>
<method name="ListAgents"><arg direction="out" type="as"/></method>
<method name="PeerAdd"><arg direction="in" type="s" name="sessionID"/><arg direction="in" type="s" name="peerID"/><arg direction="out" type="b"/></method>
<method name="PeerRemove"><arg direction="in" type="s" name="sessionID"/><arg direction="in" type="s" name="peerID"/><arg direction="out" type="b"/></method>
<method name="PeerList"><arg direction="in" type="s" name="sessionID"/><arg direction="out" type="as"/></method>
<method name="PeerSubmit"><arg direction="in" type="s" name="sessionID"/><arg direction="in" type="s" name="peerID"/><arg direction="in" type="s" name="prompt"/><arg direction="out" type="b"/></method>
<method name="DetachProcess"><arg direction="in" type="s" name="sessionID"/><arg direction="out" type="b"/></method>
<method name="ListDetached"><arg direction="in" type="s" name="sessionID"/><arg direction="out" type="as"/></method>
<method name="SignalDetached"><arg direction="in" type="s" name="sessionID"/><arg direction="in" type="i" name="pid"/><arg direction="in" type="s" name="signal"/><arg direction="out" type="b"/></method>

View File

@ -183,112 +183,9 @@ func (s *Manager) Readdir(name string) ([]os.DirEntry, error) {
return entries, nil
}
}
// {id}/peer — list peer session IDs
if len(parts) == 2 && parts[1] == "peer" {
peers, _ := s.PeerList(sessID)
entries := make([]os.DirEntry, len(peers))
for i, p := range peers {
entries[i] = fs.FileEntry(p, 0666)
}
return entries, nil
}
return nil, fmt.Errorf("%s: not a directory", name)
}
// --- Peer Management ---
// PeerAdd creates a bidirectional peer link between two sessions.
func (s *Manager) PeerAdd(sessID, peerID string) error {
s.mu.RLock()
sess, ok := s.sessions[sessID]
peer, peerOk := s.sessions[peerID]
s.mu.RUnlock()
if !ok {
return fmt.Errorf("session not found: %s", sessID)
}
if !peerOk {
return fmt.Errorf("peer session not found: %s", peerID)
}
if sessID == peerID {
return fmt.Errorf("cannot peer a session with itself")
}
sess.mu.Lock()
if sess.peers == nil {
sess.peers = make(map[string]bool)
}
sess.peers[peerID] = true
sess.mu.Unlock()
peer.mu.Lock()
if peer.peers == nil {
peer.peers = make(map[string]bool)
}
peer.peers[sessID] = true
peer.mu.Unlock()
return nil
}
// PeerRemove removes a bidirectional peer link between two sessions.
func (s *Manager) PeerRemove(sessID, peerID string) error {
s.mu.RLock()
sess, ok := s.sessions[sessID]
peer, peerOk := s.sessions[peerID]
s.mu.RUnlock()
if !ok {
return fmt.Errorf("session not found: %s", sessID)
}
sess.mu.Lock()
delete(sess.peers, peerID)
sess.mu.Unlock()
if peerOk {
peer.mu.Lock()
delete(peer.peers, sessID)
peer.mu.Unlock()
}
return nil
}
// PeerList returns the peer session IDs for a session.
func (s *Manager) PeerList(sessID string) ([]string, error) {
s.mu.RLock()
sess, ok := s.sessions[sessID]
s.mu.RUnlock()
if !ok {
return nil, fmt.Errorf("session not found: %s", sessID)
}
sess.mu.RLock()
result := make([]string, 0, len(sess.peers))
for id := range sess.peers {
result = append(result, id)
}
sess.mu.RUnlock()
return result, nil
}
// PeerSubmit sends a prompt to a peer session.
func (s *Manager) PeerSubmit(sessID, peerID, prompt string) error {
s.mu.RLock()
sess, ok := s.sessions[sessID]
peer, peerOk := s.sessions[peerID]
s.mu.RUnlock()
if !ok {
return fmt.Errorf("session not found: %s", sessID)
}
if !peerOk {
return fmt.Errorf("peer session not found: %s", peerID)
}
sess.mu.RLock()
isPeer := sess.peers[peerID]
sess.mu.RUnlock()
if !isPeer {
return fmt.Errorf("%s is not a peer of %s", peerID, sessID)
}
go peer.Core.Agent().Submit(peer.Ctx, prompt)
return nil
}
func (s *Manager) stat(name string) (os.FileInfo, error) {
// Top-level fixed files (new, idx, sh, etc.)
@ -326,21 +223,6 @@ func (s *Manager) stat(name string) (os.FileInfo, error) {
}
return afs.Stat(parts[3])
}
// Peer directory: {id}/peer
if parts[1] == "peer" {
if len(parts) == 2 {
return &fs.SyntheticFileInfo{Name_: "peer", Mode_: 0755, IsDir_: true}, nil
}
// Peer file: {id}/peer/{peer-id}
peerID := parts[2]
sess.mu.RLock()
isPeer := sess.peers[peerID]
sess.mu.RUnlock()
if !isPeer {
return nil, fmt.Errorf("%s: not found", name)
}
return &fs.SyntheticFileInfo{Name_: peerID, Mode_: 0666}, nil
}
// Session file: {id}/{file} (plan, env)
sfs, err := s.openSessionTree(sess)
if err != nil {
@ -353,8 +235,6 @@ func (s *Manager) openEntry(name string) (fs.File, error) {
notBlocking := func(context.Context, string) ([]byte, string, error) {
return nil, "", fmt.Errorf("blocking read not supported")
}
// Peer file: {id}/peer/{peer-id} — write submits prompt to peer
parts := strings.SplitN(name, "/", 3)
// Proc file: {id}/proc/{pid} — read returns ring buffer output
@ -385,28 +265,6 @@ func (s *Manager) openEntry(name string) (fs.File, error) {
}, nil
}
if len(parts) == 3 && parts[1] == "peer" {
sessID := parts[0]
peerID := parts[2]
return &fs.FileConfig{
StatFn: func() (os.FileInfo, error) {
return &fs.SyntheticFileInfo{Name_: peerID, Mode_: 0666}, nil
},
ReadFn: func() ([]byte, error) {
return nil, nil // empty read
},
WriteFn: func(data []byte) error {
prompt := strings.TrimSpace(string(data))
if prompt == "" {
return nil
}
return s.PeerSubmit(sessID, peerID, prompt)
},
BlockingReadFn: notBlocking,
}, nil
}
// Top-level fixed files.
switch name {
case "new":
return &fs.FileConfig{
@ -478,11 +336,6 @@ func (s *Manager) openEntry(name string) (fs.File, error) {
}
func (s *Manager) create(name string) error {
// Peer creation: {id}/peer/{peer-id}
parts := strings.SplitN(name, "/", 3)
if len(parts) == 3 && parts[1] == "peer" {
return s.PeerAdd(parts[0], parts[2])
}
return fmt.Errorf("create not supported: %s", name)
}
@ -500,10 +353,6 @@ func (s *Manager) del(name string) error {
}
return fmt.Errorf("session not found: %s", sessID)
}
// Peer removal: {id}/peer/{peer-id}
if len(parts) == 3 && parts[1] == "peer" {
return s.PeerRemove(sessID, parts[2])
}
// Proc dismiss: {id}/proc/{pid}
if len(parts) == 3 && parts[1] == "proc" {
sess := s.Session(sessID)

View File

@ -23,7 +23,6 @@ type Session struct {
ChatOffset int
plan []byte
prevPrompt []byte // last submitted prompt; overwritten on each new submission
peers map[string]bool // peer session IDs (bidirectional links)
remote string // SSH target for remote execution (empty = local)
// Cached model list (expensive API call; refreshed every 24h).
@ -71,12 +70,6 @@ func (sess *Session) InvalidateModelsCache() {
sess.modelsMu.Unlock()
}
// HasPeer reports whether peerID is a registered peer of this session.
func (sess *Session) HasPeer(peerID string) bool {
sess.mu.RLock()
defer sess.mu.RUnlock()
return sess.peers[peerID]
}
func (sess *Session) RunnableID() string { return sess.id }
func (sess *Session) Uname() string { return sess.uname }

View File

@ -192,12 +192,9 @@ func (s *Server) dirMode(path string) plan9.Perm {
func (s *Server) filePerm(path string) os.FileMode {
// Session files have per-file overrides.
if strings.HasPrefix(path, fs.PathSessions) {
// Peer/proc file permissions.
// Proc file permissions.
name := strings.TrimPrefix(path, fs.PathSessions)
parts := strings.SplitN(name, "/", 3)
if len(parts) == 3 && parts[1] == "peer" {
return 0666
}
if len(parts) == 3 && parts[1] == "proc" {
return 0444
}
@ -531,22 +528,11 @@ func (s *Server) pathType(path string) string {
}
return "dir"
}
// /session/{id}/peer or /session/{id}/proc — directory
// /session/{id}/proc — directory
parts := strings.SplitN(name, "/", 3)
if len(parts) == 2 && (parts[1] == "peer" || parts[1] == "proc") {
if len(parts) == 2 && parts[1] == "proc" {
return "dir"
}
// /session/{id}/peer/{peer-id} — verify peer exists
if len(parts) == 3 && parts[1] == "peer" {
sess := s.sessionMgr.Session(parts[0])
if sess == nil {
return ""
}
if sess.HasPeer(parts[2]) {
return "file"
}
return ""
}
// /session/{id}/proc/{pid} — verify PID exists in detached list
if len(parts) == 3 && parts[1] == "proc" {
sess := s.sessionMgr.Session(parts[0])