+// Reserve keeps a child name out of future subagent draws. An existing subagent
+// directory or a reserved name is refused.
+func (s *Subagents) Reserve(name string) error {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+
+ if s.reserved[name] {
+ return fmt.Errorf("name %q is already used", name)
+ }
+
+ _, err := os.Lstat(filepath.Join(s.dir, name))
+ if err == nil {
+ return fmt.Errorf("name %q is already used by a subagent", name)
+ }
+
+ if !errors.Is(err, os.ErrNotExist) {
+ return fmt.Errorf("check subagent name: %w", err)
+ }
+
+ s.reserved[name] = true
+
+ return nil
+}
+
+// Release frees a reservation after a child fails to publish. It does not
+// remove a subagent directory or change an open log.
+func (s *Subagents) Release(name string) {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+
+ delete(s.reserved, name)
+}
+