Skip to content

Tree: a reachable Archived group in the sidebar, and one group for a concurrent burst #810

Closed
Birfy/FlyBot
#34

Description

@Birfy

Where this comes from

Split out of #450 by the owner's call. #450 keeps items 1, 3, 5 and 7, each of which needs a core API for plugins or the owner raising a limit. These two are ordinary tree behaviour with no product decision left open: they were already decided when #450 was written.

A. An archived Bot becomes unreachable

plugins/tree/client.js:339 adds every archived Bot — fields['flybot-tree'].archived, or a leftover 归档-* / Archive-* name (ARCHIVE_NAME_RE at :279) — to the hidden set, and core/src/client/sidebar.js:366 drops hidden ids from the Bot list entirely. Keeping them out of the tree is #452's decision and stays; but the only way back to an archived Bot's chat is its right-click menu, and a Bot archived by a merge is invisible unless its name is remembered.

Expected behaviour — keep the list exactly as it is, and add one section of the tree's own through the slot that already exists (core/src/client/flybot-slots.js, used at client.js:466):

  • A flybot.sidebar.section entry with id flybot-tree-archived, rendered below the Bot list: collapsed by default, header Archived (N), N = the number of archived Bots.
  • Renders nothing at all when N is 0 — no header, no border, no empty group.
  • Expanded, one row per archived Bot, carrying the same tag statusOf() already produces (:442): archived, or archived · merged into <name> for a merge.
  • A row opens that Bot's chat through the same action every other row uses. No new endpoint, no new call.
  • Expanded/collapsed is local state and survives the 10 s roster refresh (REFRESH_MS): the section re-renders, it does not reset.
  • Archived Bots stay out of the default list and out of the tree: include() keeps returning false for them, so ds-bot's botTree() never sees them.

Done when plugins/tree/test/web-entry.test.js (or a new client test beside it) covers: zero archived → nothing rendered; one archived → header Archived (1), collapsed, and the row present after a click; one merged archived → archived · merged into X; a 归档- named Bot with no field counted the same way; and the default list excluding all of them in the same fixture.

B. A concurrent burst is placed one Bot at a time

planChild() (allocate.js:92) plans each create_child_bot against a fresh snapshot, so two related Bots created at the same moment independently pick a home from homesFor(...). Both can land in a broader existing group — the #450 example is a Dev Lead that already has a Programmer — and only the daily tidy regroups them. create_team already owns the allocation this needs: planTeam (:158) under a per-parent lock (:173), one lead per key through createLead (:244).

Expected behaviour, and this is the whole definition:

  • A burst is two or more create_child_bot calls from the same caller in flight at the same time — the second started before the first returned. No timer and no settle window: a call that starts after the previous one returned keeps today's path untouched.
  • Members of a burst whose profiles share the first domain key (keysOf(profileFor(name, role))[0] — the key create_team already uses at :158) are placed as one group: one lead for that key, reused when leadIn() finds one, created once otherwise, with every burst member under it. The second member must not resolve to a broader pre-existing group.
  • A burst whose members fall into different domain keys is not forced together: each call keeps today's placement.
  • Grouping is deterministic. classify-model is not consulted and no model call is added.
  • Limits are unchanged: every create is still gated by checkCreate / limits; a member that cannot fit is refused with the existing message, never silently dropped, and one member failing does not undo the others.
  • Observable in the results: every placed member of the burst names the same lead path.

Done when plugins/tree/test/tree.test.js covers, against a fake fb that holds both createUnder promises until both calls have started: two concurrent creates in one domain produce exactly one lead and two children, both results naming that lead, and at most one createLead action for the batch. Negative control in the same file: with the burst path disabled the same fixture places them under two different parents, so the case fails for the right reason. Plus a serial fixture (the second call awaited after the first returns) whose tree is identical to today's.

Verification

  • node --test plugins/tree/test/*.test.js: the new cases pass; the negative controls fail without the change.
  • plugins/tree/client.js is hand-written and loaded as a classic script, so build-client --check has nothing new to compare; ds-bot-patches check still reports three ok lines.
  • node scripts/testing-layers.mjs --check still classifies every file; a changelog.d/ fragment is added.

Kill conditions

  • Delaying a tool result to wait for more creates (a timer or a settle window). The burst is defined by overlap in flight, never by clock time.
  • A and B may land in one pull request, but neither may hide the other's evidence, and B must not change the sidebar.
  • Reversing Tree reorg must MOVE/reparent bots; never rename to 归档- and recreate #452: archived Bots must not come back into the Bot list or into botTree().
  • A new endpoint, a new stored field, or a model call used to decide grouping.
  • Editing plugins/tree/cordis.patch.yml permissions or limits.json so a fixture fits.

Out of scope

#450 items 1, 3, 5 and 7 (memory handoff on merge, a notice in the Main Bot's chat, richer activity, the maxChildren limit); create_team's behaviour; the daily tidy's own regrouping in organize.js; how a Bot is archived or unarchived.

Activity

  1. added
    enhancementNew feature or request
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    area:uiWeb/desktop UI and copy
    area:automationScheduled tasks and automation
    on Oct 23, 2026
  2. self-assigned this
    on Oct 23, 2026
  3. added
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 23, 2026
  4. Birfy commented on Oct 23, 2026

    @Birfy
    CollaboratorAuthor

    Written-by: Dev

    Claiming. Branch feat/810-archived-section-and-burst in Birfy/FlyBot, cut from main 6f9b60c7.

    Plan: A and B in one pull request, each with its own fixtures and evidence. A renders an archived section through the existing flybot.sidebar.section slot and leaves include() returning false, so #452 is untouched. B groups a concurrent burst through the allocation create_team already uses, keyed by keysOf(profileFor(name, role))[0], with no timer and no settle window.

  5. added
    agent-prPull request opened by an agent
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    and removed
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 23, 2026
  6. added a commit that references this issue on Oct 23, 2026
    f20cfa3
  7. removed
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    agent-prPull request opened by an agent
    on Oct 23, 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 automationarea:uiWeb/desktop UI and copyenhancementNew feature or request

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions