From f272bbd069d41b6b24564f03b675b9995f24d57d Mon Sep 17 00:00:00 2001 From: Day Dreamer <87640074+HugoXK@users.noreply.github.com> Date: Tue, 10 Nov 2026 17:32:42 +0800 Subject: [PATCH] fix(tree): pass jobTimeoutMs from the plugin config to the organizer The organizer already reads a job deadline and falls back to ten minutes, but the plugin never handed it the configured value: `apply()` did not read `config.jobTimeoutMs` and `createTree()` neither accepted nor forwarded it, so every queued job kept the default however the key was set. Wire it through and pin it with a plugin-level test that hangs the host's create on the create_team path, so a dropped value shows up as the 600000ms default in the abandonment warning. --- .../2800-tree-job-timeout-config.fixed.md | 1 + docs/subsystems/tree.md | 2 +- plugins/tree/index.js | 2 +- plugins/tree/src/tree.js | 4 +- plugins/tree/test/job-timeout-config.test.js | 75 +++++++++++++++++++ 5 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 changelog.d/2800-tree-job-timeout-config.fixed.md create mode 100644 plugins/tree/test/job-timeout-config.test.js diff --git a/changelog.d/2800-tree-job-timeout-config.fixed.md b/changelog.d/2800-tree-job-timeout-config.fixed.md new file mode 100644 index 000000000..a95c3c5e4 --- /dev/null +++ b/changelog.d/2800-tree-job-timeout-config.fixed.md @@ -0,0 +1 @@ +The tree plugin's `jobTimeoutMs` config key now bounds a queued reorganization job: the value was read by the organizer but never passed to it from the plugin config, so every job waited on the ten-minute default however the key was set. A value that is not a finite number above 0 still keeps that default. See [#2758](https://github.com/ThinkFlowLab/FlyBot/issues/2758). diff --git a/docs/subsystems/tree.md b/docs/subsystems/tree.md index a1970763c..b5cd6a883 100644 --- a/docs/subsystems/tree.md +++ b/docs/subsystems/tree.md @@ -76,7 +76,7 @@ The tree organizes itself by role instead of leaving Bots outside it or a parent - **Placement** of a Bot outside the tree: its namesake, else the tree Bot that leads a group it belongs to (most specific key first, then the shallower lead; an area only through a lead made for it, e.g. "Work Lead"), else the root. At the first of those with room it is placed. A full level is **regrouped**: the most specific group of two or more children (the newcomer counted) moves under a suitable existing member, or under a new lead. Inside a full lead of its own group with no finer group, the member closest to its role takes it (all members share the group). There is **no "least-loaded child" fallback**: a Bot that fits no group while every level it matches is full stays outside, a warning names it and the sidebar tags it "outside the tree"; the next attempt (any `bot.created`, startup) tries again. - **Leads.** A suitable existing lead is a member already marked as that group's lead, already coordinating that group (it has children and the key, project and domain only), or named for it ("Life", "FlyBot Lead") or as a lead ("Kitchen Manager", 负责人). It gets `lead { key, label }`. Only when none fits a new lead is created with a clear role (`