Repository navigation
Description
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
- The value is in
plugins/tree/limits.json:{ "maxDepth": 5, "maxChildren": 8 }. Plugin config can override it (limits.js#L7-L10). checkCreaterefuses withlimit reached: <parent> already has N children (maxChildren=8). It runs only insidecreateChildNow, which means only the tree toolcreate_child_botchecks it. Creates are serialized per parent so parallel calls cannot overshoot (Tree: stop_bot blocked by tree policy, stale prompts after reparent, createChild race (PR #2 review) #15).adoptUnattachedalso reads the cap. Once the root is full, a bot that would be adopted is skipped and only a server-logwarnis written (N bot(s) left outside the tree because the root already has maxChildren=8 children).- Why the cap exists: it was kept as the guardrail on recursive spawning when every tree Bot was allowed to create children (Decision: should non-Main tree Bots be allowed to call create_child_bot? (PR #2 review) #16 Option B; tree.md "Child creation", team.md #8). [Team] Bound agent loops and resource consumption #56 lists it with the loop and resource bounds. The docs never call it advisory.
- The tree prompt tells the coordinator what to do when the cap is hit:
prompt.js#L29: "If creation is rejected by limits, use the closest child." It says nothing about asking the owner, and nothing aboutcreate_bot.
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:
bot.createdfires, and the tree plugin callsensureRoot()→adoptUnattached(chief)(index.js#L31).- 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. - The Bot ends up outside the tree and uncounted. It has no
parentortreeRoleand no tree prompt block. It does not appear in Chief'slist_childrenor in Chief's coordinator prompt. It cannot usecreate_child_bot. - 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. - 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. Thecreate_botBots 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
maxChildrenwithcreate_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-taskchildrenbudget charged increateChild([Team] Bound agent loops and resource consumption #56).) - The tree's own instruction was ignored. The prompt says "use the closest child", but
create_botwas 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
- 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 undermaxChildren/maxDepth; it is never left outside or drawn as an uncounted child of Chief. - 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.
- 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.
- 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.
- 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.
- Logged and undoable. Every move / merge / archive / new lead is logged; the tree view shows what the last reorganization did, with one-click undo.
- 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.
- Repair after deletion (kept from Tree organizes itself by role: groups under leads, merge, daily tidy, undo #448). A parent pushed over
maxChildrenby a deletion is reorganized by the same role rules. - Prompt guidance. The root prompt says the limits apply to every create path and
create_botdoes not get around them; automatic reorganization keeps the tree healthy.
Acceptance criteria
- With the tree plugin loaded, Chief cannot bypass
maxChildrenviacreate_bot; a test covers bothcreate_botandcreate_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.mddocuments 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
[-]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[/+]Birfy commentedon Oct 19, 2026
Owner decision (2026-10-19 ~19:45 Asia/Shanghai):否决此前「满了就问 / 标成树外」为主方案。新方向:
maxChildren或出现树外 Bot 时自动整理成合理结构,而不是停下抛 question card 当作主修复。create_bot不得绕过 tree 的maxChildren: 8;新创建必须走树规则。Issue body 的 Recommended approach / Acceptance 已按此改写。已加
agent-ready,去掉needs-human。Birfy commentedon Oct 19, 2026
Claimed for development (2026-10-19 20:00 Asia/Shanghai). Branch
fix/446-tree-auto-prune-mergeoff main753b7e9. Working in parallel this maintenance run.Birfy commentedon Oct 19, 2026
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.Birfy commentedon Oct 19, 2026
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:
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.Kept from #448: core
create_botno longer bypasses the tree (every new Bot is placed undermaxChildren/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.
Tree organizes itself by role: groups, leads, merge, daily tidy, undo
tree: add move_bot for reorganising an existing tree
tree: add move_bot for reorganising an existing tree
tree: add move_bot for reorganising an existing tree (ThinkFlowLab#636)
fix(tree): take a retired Bot out of the tree and re-attach its child…