Skip to content

Tree: close create_bot maxChildren bypass; auto-prune/merge when over capacity or orphans exist #446

Closed

Description

@Birfy

What happened

The owner asked Chief to build a dedicated sub-team for the FlyBot repo. Chief already had 8 direct children. It answered (translated from Chinese):

"The current tree's direct children are already at the limit (8/8), so I'm creating 4 FlyBot specialist members as team Bots instead, for the four roles you named: development, testing, maintenance, repo management. Creating them in parallel now."

So Chief knew it had hit the tree's per-parent cap. It did not ask the owner what to do. It switched on its own to a second creation tool that the cap does not cover.

How the cap is enforced

How Chief got around it

Chief is the Main Bot, so it can also use the core host tool create_bot ("Main Bot only. Create a new Bot on the user's team"). That is the "team Bot" path in Chief's message. The tool calls rt.createBot(...) with no tree fields and knows nothing about the tree or maxChildren.

Here is what happens to each of the 4 Bots:

  1. bot.created fires, and the tree plugin calls ensureRoot() → adoptUnattached(chief) (index.js#L31).
  2. Chief already has 8 children, so the Bot is skipped at tree.js#L96. The only trace is a server-log warning. The owner never sees it.
  3. The Bot ends up outside the tree and uncounted. It has no parent or treeRole and no tree prompt block. It does not appear in Chief's list_children or in Chief's coordinator prompt. It cannot use create_child_bot.
  4. In the sidebar it still looks like Chief's child. The client structure gives non-tree Bots no parent, "and ds-bot shows them directly under Chief" (client.js#L308-L311). The owner sees 12 Bots under Chief while the tree model says 8.
  5. Messaging still works one way. The root may message any local Bot, and a non-tree Bot may message only the root (middleware.js#L7-L9). So Chief can still delegate to them, which makes the bypass work in practice.

There is also a delayed effect. If one of Chief's 8 tree children is later deleted, the next bot.created runs adoptUnattached again and silently pulls one of these Bots into the tree, picked by list order. Structure then changes without anyone deciding it.

Why this is a problem

  • The structure is inconsistent. Two kinds of Bots look the same in the sidebar but follow different rules. Tree members get the parent/child send rules, the coordinator prompt, create_child_bot, and tree trace lines. The create_bot Bots get none of these, and the UI does not show the difference.
  • The limit means nothing for the root. Any Main Bot can go past maxChildren with create_bot. That undoes the guardrail Decision: should non-Main tree Bots be allowed to call create_child_bot? (PR #2 review) #16 and [Team] Bound agent loops and resource consumption #56 rely on. (It also slips past any future per-task children budget charged in createChild ([Team] Bound agent loops and resource consumption #56).)
  • The tree's own instruction was ignored. The prompt says "use the closest child", but create_bot was right there in the tool list, so that rule never had a chance to hold.
  • Orphans and overcapacity are left to rot. Skipping + log-warn (or asking the owner as the primary fix) does not restore a sensible tree. Outside-tree "team Bots" and over-full parents need automatic cleanup.

Owner decision (2026-10-19 ~19:45 Asia/Shanghai)

Rejected: primary fix = stop and ask with a question card / mark bots permanently "outside the tree".

New direction: prefer automatic prune and merge so the tree becomes more reasonable when the direct-child cap is hit or when bots were created outside the tree. Still close the create_bot bypass hole so new creates respect tree limits — but when over capacity or when orphan team Bots exist, the system should automatically prune / merge / reparent / consolidate rather than only blocking and asking.

Owner decision (2026-10-19 21:27 Asia/Shanghai)

Rejected: #448's last-resort rule "when Chief is full and nothing matches, put the new Bot under Chief's least-loaded child". The tree should organize itself by role (comment). This section and the ones below replace the 19:45 approach where they differ.

Recommended approach

  1. Close the create_bot hole (required, kept from Tree organizes itself by role: groups under leads, merge, daily tidy, undo #448). With the tree plugin loaded, every new Bot (core create_bot, the Bot list, an older install) is placed in the tree under maxChildren / maxDepth; it is never left outside or drawn as an uncounted child of Chief.
  2. Group by role. When a level is full, and in a daily reorganization pass, read each child's name, description (role label, tree role, own prompt text) and recent activity (e.g. the tools it used), and cluster children with similar roles (dev / test / repo maintenance → a FlyBot group; cooking / shopping → a life group). A new Bot goes into the group that matches its role. Clustering may use the Bot's model if the codebase has a pattern for that; otherwise a deterministic role / keyword similarity with a clear hook for a smarter classifier.
  3. Leads. If a group already has a suitable Bot (a lead-like role, already coordinating that group, or named for it), it becomes the lead and the others move under it. Only when none fits, create a new lead Bot with a clear role (e.g. "FlyBot Lead"), never an empty placeholder. Never fall back to "least-loaded child" for unrelated Bots.
  4. Merge duplicates. Two Bots with essentially the same role are merged into one: children and conversation / memory references move to the kept Bot, the old one is archived, never deleted.
  5. Daily tidy. Besides when a level is full, a reorganization runs once a day. Leaf Bots idle for a long time are marked "idle" and archived after 30 days. Deleting a Bot always needs the owner's explicit click; nothing is deleted automatically.
  6. Logged and undoable. Every move / merge / archive / new lead is logged; the tree view shows what the last reorganization did, with one-click undo.
  7. Big changes run directly (no plan card), and the owner is told afterwards: a summary notice in the Main Bot / tree view of what moved.
  8. Repair after deletion (kept from Tree organizes itself by role: groups under leads, merge, daily tidy, undo #448). A parent pushed over maxChildren by a deletion is reorganized by the same role rules.
  9. Prompt guidance. The root prompt says the limits apply to every create path and create_bot does not get around them; automatic reorganization keeps the tree healthy.

Acceptance criteria

  • With the tree plugin loaded, Chief cannot bypass maxChildren via create_bot; a test covers both create_bot and create_child_bot.
  • A full level is reorganized by role: related children are grouped under a suitable existing lead, or under a new lead with a clear role; a new Bot joins the group matching its role. No "least-loaded child" fallback; a test covers the FlyBot (dev / test / repo) and life (cooking / shopping) examples.
  • Duplicate-role Bots are merged; the old one is archived (still exists, out of the tree), never deleted.
  • A daily pass runs the same grouping and marks long-idle leaf Bots idle, archiving them after 30 days.
  • Every move / merge / archive is logged; the tree view shows the last reorganization with one-click undo, and undo restores the previous structure.
  • The owner is told after a reorganization (tree view / Main Bot), without a plan card first.
  • Freeing a slot under Chief does not silently move a Bot by list order; sidebar structure matches the tree model after reorganization.
  • docs/subsystems/tree.md documents all create paths, role grouping, leads, merge / archive, the daily tidy and undo; link to allocation (Tree: smarter sub-Bot allocation (lead+children, reuse, deeper placement) maintained by auto-prune/merge #447).

Related: #6 (tree), #16 (child creation decision), #15 (createChild race), #56 (bounded loops and resources). Placement and allocation follow-up: #447.
Verified against main at 753b7e9.
Owner decisions recorded 2026-10-19 ~19:45 and 21:27 Asia/Shanghai.

Activity

  1. self-assigned this
    on Oct 19, 2026
  2. added
    bugSomething isn't working
    needs-humanThe agent loop stopped; a person must decide (reason in the last comment)
    area:automationScheduled tasks and automation
    on Oct 19, 2026
  3. changed the title [-]Tree: Chief bypasses maxChildren via create_bot when its direct children are full (8/8) instead of asking the owner[/-] [+]Tree: close create_bot maxChildren bypass; auto-prune/merge when over capacity or orphans exist[/+] on Oct 19, 2026
  4. added
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    and removed
    needs-humanThe agent loop stopped; a person must decide (reason in the last comment)
    on Oct 19, 2026
  5. Birfy commented on Oct 19, 2026

    @Birfy
    CollaboratorAuthor

    Owner decision (2026-10-19 ~19:45 Asia/Shanghai):否决此前「满了就问 / 标成树外」为主方案。新方向:

    1. 优先自动 prune + merge,让树在触及 maxChildren 或出现树外 Bot 时自动整理成合理结构,而不是停下抛 question card 当作主修复。
    2. 仍要堵住根因:core create_bot 不得绕过 tree 的 maxChildren: 8;新创建必须走树规则。
    3. 过载 / 孤儿的处理:自动 prune、合并冗余或错位 Bot,reparent / consolidate,使树回到 cap 内且结构合理;不要只靠「阻断 + 问用户」。
    4. 与 Tree: smarter sub-Bot allocation (lead+children, reuse, deeper placement) maintained by auto-prune/merge #447 对齐:分配逻辑产出健康树;本 issue 的 auto-prune/merge 作为结构走偏时的安全网。

    Issue body 的 Recommended approach / Acceptance 已按此改写。已加 agent-ready,去掉 needs-human。

  6. added
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 19, 2026
  7. Birfy commented on Oct 19, 2026

    @Birfy
    CollaboratorAuthor

    Claimed for development (2026-10-19 20:00 Asia/Shanghai). Branch fix/446-tree-auto-prune-merge off main 753b7e9. Working in parallel this maintenance run.

  8. Birfy commented on Oct 19, 2026

    @Birfy
    CollaboratorAuthor

    Re-claimed (2026-10-19 20:57 Asia/Shanghai): the 20:00 run's worker stopped without changes; development restarts now on the same branch name off main 753b7e9.

  9. added
    agent-prPull request opened by an agent
    and removed
    agent-prPull request opened by an agent
    on Oct 19, 2026
  10. Birfy commented on Oct 19, 2026

    @Birfy
    CollaboratorAuthor

    Owner decision (2026-10-19 Asia/Shanghai): recorded 21:27. This replaces the 19:45 direction where it differs.

    The owner rejected #448's last-resort rule "when Chief is full and nothing matches, put the new Bot under Chief's least-loaded child". The Bot tree should organize itself by role:

    1. Group by role. When a level is full (maxChildren), and once a day, read each child's name, description and recent activity and cluster children with similar roles (e.g. dev / test / repo maintenance → a FlyBot group; cooking / shopping → a life group). A new Bot goes into the group that matches its role.
    2. Leads. If a group already has a suitable Bot, it becomes the lead and the others move under it. Only when none fits, create a new lead Bot with a clear role (e.g. "FlyBot Lead"), never an empty placeholder. Never fall back to "least-loaded child" for unrelated Bots.
    3. Merge duplicates. Two Bots with essentially the same role are merged into one (conversation / memory references move to the kept Bot); the old one is archived, never deleted.
    4. Daily tidy. Besides when a level is full, a reorganization runs once a day. Bots idle for a long time with no children are marked "idle" and archived after 30 days. Deleting a Bot always needs the owner's explicit click.
    5. Logged and undoable. Every move / merge / archive is logged; the tree view shows what the last reorganization did and offers one-click undo.
    6. Big changes run directly (no plan card); the owner is told afterwards (a summary notice in the Main Bot / tree view of what moved).

    Kept from #448: core create_bot no longer bypasses the tree (every new Bot is placed under maxChildren / maxDepth), repair after deletions, nothing is deleted automatically.

    The body's "Recommended approach" and acceptance criteria are updated to match. #448 is being reworked to this design; #447 builds on it.

  11. removed
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:automationScheduled tasks and automationbugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions