From e3b813f4dadb4f506af29efde0bb2c5d6dd8550b Mon Sep 17 00:00:00 2001 From: Danyang Chen Date: Mon, 9 Nov 2026 02:03:34 +0800 Subject: [PATCH] Release v0.2.27 Written-by: Release Mechanical release v0.2.27: version bump and 35 changelog fragments folded into CHANGELOG.md. Changelog fragments consumed: - changelog.d/2624.fixed.md (#2624) - changelog.d/2629.fixed.md (#2629) - changelog.d/2631.fixed.md (#2631) - changelog.d/2633.fixed.md (#2633) - changelog.d/2634.fixed.md (#2634) - changelog.d/2637.fixed.md (#2637) - changelog.d/2638.fixed.md (#2638) - changelog.d/2641.fixed.md (#2641) - changelog.d/2643.fixed.md (#2643) - changelog.d/2645.fixed.md (#2645) - changelog.d/2646.fixed.md (#2646) - changelog.d/2649.fixed.md (#2649) - changelog.d/2650.fixed.md (#2650) - changelog.d/2652.security.md (#2652) - changelog.d/2654.fixed.md (#2654) - changelog.d/2656.fixed.md (#2656) - changelog.d/2658-step-artifacts-output.fixed.md (#2658) - changelog.d/2662-run-name-id.fixed.md (#2662) - changelog.d/2663-parallel-node-id.fixed.md (#2663) - changelog.d/2667-task-handoff-terminal.fixed.md (#2667) - changelog.d/2669-edge-outputs.fixed.md (#2669) - changelog.d/2673-readonly-reap.fixed.md (#2673) - changelog.d/2675-readonly-onboard.fixed.md (#2675) - changelog.d/2677-quoted-failure.fixed.md (#2677) - changelog.d/2679-output-limit-turn.fixed.md (#2679) - changelog.d/2681-newer-version-store.fixed.md (#2681) - changelog.d/2685-output-evidence.fixed.md (#2685) - changelog.d/2687-otlp-redirect.fixed.md (#2687) - changelog.d/2689-external-long-answer.fixed.md (#2689) - changelog.d/2691-name-identity.fixed.md (#2691) - changelog.d/2692-identity-sites.fixed.md (#2692) - changelog.d/2693-social-name-cut.fixed.md (#2693) - changelog.d/2697-private-files.fixed.md (#2697) - changelog.d/2699-room-line-leak.fixed.md (#2699) - changelog.d/notify-webhook-duplicate.fixed.md (#2660) --- CHANGELOG.md | 46 ++++++++++++++++++- changelog.d/2624.fixed.md | 1 - changelog.d/2629.fixed.md | 1 - changelog.d/2631.fixed.md | 1 - changelog.d/2633.fixed.md | 1 - changelog.d/2634.fixed.md | 1 - changelog.d/2637.fixed.md | 1 - changelog.d/2638.fixed.md | 1 - changelog.d/2641.fixed.md | 1 - changelog.d/2643.fixed.md | 1 - changelog.d/2645.fixed.md | 1 - changelog.d/2646.fixed.md | 1 - changelog.d/2649.fixed.md | 1 - changelog.d/2650.fixed.md | 1 - changelog.d/2652.security.md | 1 - changelog.d/2654.fixed.md | 1 - changelog.d/2656.fixed.md | 1 - .../2658-step-artifacts-output.fixed.md | 1 - changelog.d/2662-run-name-id.fixed.md | 1 - changelog.d/2663-parallel-node-id.fixed.md | 1 - .../2667-task-handoff-terminal.fixed.md | 1 - changelog.d/2669-edge-outputs.fixed.md | 1 - changelog.d/2673-readonly-reap.fixed.md | 1 - changelog.d/2675-readonly-onboard.fixed.md | 1 - changelog.d/2677-quoted-failure.fixed.md | 1 - changelog.d/2679-output-limit-turn.fixed.md | 1 - changelog.d/2681-newer-version-store.fixed.md | 1 - changelog.d/2685-output-evidence.fixed.md | 1 - changelog.d/2687-otlp-redirect.fixed.md | 1 - .../2689-external-long-answer.fixed.md | 1 - changelog.d/2691-name-identity.fixed.md | 1 - changelog.d/2692-identity-sites.fixed.md | 1 - changelog.d/2693-social-name-cut.fixed.md | 1 - changelog.d/2697-private-files.fixed.md | 1 - changelog.d/2699-room-line-leak.fixed.md | 1 - changelog.d/notify-webhook-duplicate.fixed.md | 1 - core/package-lock.json | 4 +- core/package.json | 2 +- patches/ds-bot/0007-version-and-tooling.patch | 6 +-- 39 files changed, 51 insertions(+), 42 deletions(-) delete mode 100644 changelog.d/2624.fixed.md delete mode 100644 changelog.d/2629.fixed.md delete mode 100644 changelog.d/2631.fixed.md delete mode 100644 changelog.d/2633.fixed.md delete mode 100644 changelog.d/2634.fixed.md delete mode 100644 changelog.d/2637.fixed.md delete mode 100644 changelog.d/2638.fixed.md delete mode 100644 changelog.d/2641.fixed.md delete mode 100644 changelog.d/2643.fixed.md delete mode 100644 changelog.d/2645.fixed.md delete mode 100644 changelog.d/2646.fixed.md delete mode 100644 changelog.d/2649.fixed.md delete mode 100644 changelog.d/2650.fixed.md delete mode 100644 changelog.d/2652.security.md delete mode 100644 changelog.d/2654.fixed.md delete mode 100644 changelog.d/2656.fixed.md delete mode 100644 changelog.d/2658-step-artifacts-output.fixed.md delete mode 100644 changelog.d/2662-run-name-id.fixed.md delete mode 100644 changelog.d/2663-parallel-node-id.fixed.md delete mode 100644 changelog.d/2667-task-handoff-terminal.fixed.md delete mode 100644 changelog.d/2669-edge-outputs.fixed.md delete mode 100644 changelog.d/2673-readonly-reap.fixed.md delete mode 100644 changelog.d/2675-readonly-onboard.fixed.md delete mode 100644 changelog.d/2677-quoted-failure.fixed.md delete mode 100644 changelog.d/2679-output-limit-turn.fixed.md delete mode 100644 changelog.d/2681-newer-version-store.fixed.md delete mode 100644 changelog.d/2685-output-evidence.fixed.md delete mode 100644 changelog.d/2687-otlp-redirect.fixed.md delete mode 100644 changelog.d/2689-external-long-answer.fixed.md delete mode 100644 changelog.d/2691-name-identity.fixed.md delete mode 100644 changelog.d/2692-identity-sites.fixed.md delete mode 100644 changelog.d/2693-social-name-cut.fixed.md delete mode 100644 changelog.d/2697-private-files.fixed.md delete mode 100644 changelog.d/2699-room-line-leak.fixed.md delete mode 100644 changelog.d/notify-webhook-duplicate.fixed.md diff --git a/CHANGELOG.md b/CHANGELOG.md index ff5fea959..4e0756e35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,49 @@ New entries are written as one fragment file per change in [changelog.d/](change ## [Unreleased] +## [0.2.27] - 2026-11-09 + +### Fixed + +- A trace rotation whose flush is refused no longer prunes the oldest segment, so the last durable trace file stays on disk instead of being deleted while the newer records exist only in memory ([#2624](https://github.com/ThinkFlowLab/FlyBot/issues/2624)). +- A timeline trace whose open is refused — a directory that cannot be listed, one removed underneath, or an I/O error — now gives its writer lock back instead of keeping it for the life of the process, so the next open in the same process and every later process succeeds once the problem is gone, and one transient read failure no longer leaves the on-disk trace switched off until a restart ([#2629](https://github.com/ThinkFlowLab/FlyBot/issues/2629)). +- A Bot Social credentials, backup or settings file that exists but no longer parses is now refused with a message naming it instead of being read as "not configured", so a torn file no longer makes a restart register a new home identity and overwrite the old one. Writes land through a temp file and a rename, so a failed write leaves the previous file whole ([#2631](https://github.com/ThinkFlowLab/FlyBot/issues/2631)). +- A grant or profile change that falls back to Bot Social's REST routes now gives up at the client's deadline instead of waiting forever, so a Bot Social server that accepts the connection and never answers shows a timeout error rather than a hung action ([#2633](https://github.com/ThinkFlowLab/FlyBot/issues/2633)). +- An external participant whose room turn times out is now stopped instead of being left running, so a late answer to the timed-out turn can no longer become the next turn's answer — a slow process no longer replies one turn behind ([#2634](https://github.com/ThinkFlowLab/FlyBot/issues/2634)). +- The group board (`track_tasks`) now matches a Bot name and a group name the way every other door does — trimmed, case-insensitive, a leading `@` dropped from a Bot name and surrounding quotes from a group name — so `assignee: "dev"` and `group: "delivery group"` resolve the Bot and the room they name instead of being refused while the same state resolves them everywhere else. A name that matches no member or more than one still gets the same refusal ([#2637](https://github.com/ThinkFlowLab/FlyBot/issues/2637)). +- A Project name, repository, default branch, owner id, working folder or status that ends in an emoji at its length bound is now cut on a character boundary, so `state.json` stores a whole character instead of half a surrogate pair that every UTF-8 write showed as a replacement character ([#2638](https://github.com/ThinkFlowLab/FlyBot/issues/2638)). +- A person's own line in a face-to-face room is now capped at 18 000 code points instead of UTF-16 units, so an emoji at the bound is kept whole rather than stored as half a surrogate pair that every later UTF-8 write shows as a replacement character ([#2641](https://github.com/ThinkFlowLab/FlyBot/issues/2641)). +- The `social`, `timeline` and `workflow` plugins now resolve `$DSH_HOME` the way the core does — a blank or whitespace value counts as unset, `~` expands, and the root is always absolute — so `bot/flybot-social.json`, `bot/flybot-timeline` and `bot/flybot-workflow` no longer move with the process's working directory ([#2643](https://github.com/ThinkFlowLab/FlyBot/issues/2643)). +- A copied line no longer loses the front of a word that only starts with a Bot's name: `Development plan is ready`, `Devices are offline`, `Released v0.2.26`, `Reviewers disagree` and `Chief concern about the tip` copy exactly as the preview reads them, while a real `Dev → Reviewer` delegation trace is still removed ([#2645](https://github.com/ThinkFlowLab/FlyBot/issues/2645)). +- A friend's Bot can no longer put its own CSS on your page: the image URL in its published look is checked where it enters and again in the page-wide mention stylesheet, so a value carrying a quote, a parenthesis, a backslash or a control character is dropped and the Bot is drawn with its colour and mask instead of its photo ([#2646](https://github.com/ThinkFlowLab/FlyBot/issues/2646)). +- A Bot's stored GIF avatar now reaches friends as the picture itself instead of a generated shape, and a look Bot Social refuses is no longer recorded as synced: saving the same picture again retries it instead of being silently skipped ([#2649](https://github.com/ThinkFlowLab/FlyBot/issues/2649)). +- The Project board reads every page of its GitHub pull-request and issue lists instead of the first hundred rows, so its seven-day merge and close medians and its day counts now cover the whole window rather than roughly the newest three days ([#2650](https://github.com/ThinkFlowLab/FlyBot/issues/2650)). +- A `define_workflow` call that replaces a saved graph now stores its `stepTimeoutMinutes` instead of returning success while keeping the old value, and refuses a value outside 1..120 the way the create branch does; the `workflow/graph` save applies the same rule, while a save that omits the field still keeps what is stored ([#2654](https://github.com/ThinkFlowLab/FlyBot/issues/2654)). +- The Inbox lists failed workflow runs again: the shell now reads the workflow pack through the plugin's `flybot/workflow/state` endpoint instead of the bare `workflow/state` the host refuses, so a failed run reaches the Needs list and its badge ([#2656](https://github.com/ThinkFlowLab/FlyBot/issues/2656)). +- An issue fast-line run no longer ends `failed` after its pull request was already opened: a Triage step that prints its delivery as its own `OUTPUT pr: 2657 (verified)` — or as `OUTPUT merged: <40-character sha>` — now counts as work done, so the run continues to `gate`/`enqueue`/`attest` and its record keeps the pull request number instead of dying on a missing `state` line ([#2658](https://github.com/ThinkFlowLab/FlyBot/issues/2658)). +- Two `run_workflow` calls that land in the same millisecond now start two runs instead of sharing a generated task id, so the second call is no longer silently dropped and no longer overwrites the first run's brief; a repeated dispatch that passes the same `task` explicitly is still de-duplicated ([#2662](https://github.com/ThinkFlowLab/FlyBot/issues/2662)). +- Adding three or more Bots to one Parallel step in the New workflow dialog no longer gives two of them the same node id, so Create succeeds instead of failing with `Node n2 is listed twice` ([#2663](https://github.com/ThinkFlowLab/FlyBot/issues/2663)). +- A card that has already finished — `accepted`, `cancelled` or `failed` — now refuses a late `handoff` with `A finished task cannot be handed on` instead of reopening itself as `open`, `not-started` and 0% under the next role, so a card that shows 100% can no longer slide back to the start of the board; the refusal is written the way the same card's "waiting on a question" write already is, and the refused write lands nothing at all, with `claimedBy` and the card's terminal state kept. A `result-ready` card still hands on, because that column is allowed to go back to working ([#2667](https://github.com/ThinkFlowLab/FlyBot/issues/2667)). +- A workflow node is now told which `OUTPUT` lines it owes from its own declared outputs **and** from the outputs its outgoing edges read, with the accepted values spelled out (`OUTPUT state: `), so a node that declares no outputs no longer runs every step into `Missing OUTPUT state` and fails ([#2669](https://github.com/ThinkFlowLab/FlyBot/issues/2669)). +- A second, read-only DSH window on the same home no longer reaps or disposes the writer's live workflow: loading the plugin and closing that window both leave the run, its step Bots and the stored progress alone, and the writing host's own load-time reap decides ([#2673](https://github.com/ThinkFlowLab/FlyBot/issues/2673)). +- A second, read-only DSH window on the same home no longer onboards a Bot Social home or writes the shared credentials file: it starts the social layer from the credentials the writable window already saved, so friends and messages stay visible, while the window that holds the team is the only one that can create a home or change that file ([#2675](https://github.com/ThinkFlowLab/FlyBot/issues/2675)). +- A workflow step no longer fails because its own answer quotes `could not answer your message` while auditing that sentence: the host marks its real failure notice structurally, and an old host without the marker is read only from the notice shape at the start of the reply ([#2677](https://github.com/ThinkFlowLab/FlyBot/issues/2677)). +- A turn that DSH ended at the model's output limit is no longer reported as a normal finish or as a member that chose silence: the activity feed marks `turn.end` with `limited: true`, the ended-turn view keeps the turn (with `silent` and the streak when it wrote nothing, and its own sentence in the chat instead of "could not run"), and a group member cut off before it answered is recorded as "no answer" instead of a pass ([#2679](https://github.com/ThinkFlowLab/FlyBot/issues/2679)). +- A workflow file written by a newer FlyBot is no longer rewritten by an older one: the workspace store refuses to save over a definition whose `version` is higher than the one it writes and leaves it byte-identical, and lists it as a newer file instead of showing a definition that has lost fields it could not read. The workflow plugin does the same for `workflows.json` — `workflow/state` now answers `store-newer-version` with the version that wrote it, and every write is refused, so the owner's workflows, runs, claims and `seq` can no longer be replaced by the factory fixture ([#2681](https://github.com/ThinkFlowLab/FlyBot/issues/2681)). +- A declared `pr`/`pull` OUTPUT now counts as delivery evidence only when its value is the pull number itself — a positive integer, an optional leading `#`, an optional trailing parenthetical such as `2657 (verified)` — so a step that says it has no pull request is no longer read as one, and a loop's `until` output reaches the step body the same way a `when` condition does, so a looping node is told the line it must print instead of failing for silence ([#2685](https://github.com/ThinkFlowLab/FlyBot/issues/2685)). +- The timeline's OTLP exporter no longer follows a redirect from the collector: a `307` reply that points at another origin is an export failure (warned, not counted as delivered, retried on the next flush) instead of a replay of `otlpHeaders` and the span payload at a host the operator never named. A normal `200` still counts as delivered ([#2687](https://github.com/ThinkFlowLab/FlyBot/issues/2687)). +- An external room participant whose answer line grows past the 4 KB stdout buffer is now reported to the room as `answer exceeded 4096 bytes` and keeps its process for later turns, instead of the answer being dropped as if the process had never spoken ([#2689](https://github.com/ThinkFlowLab/FlyBot/issues/2689)). +- A Bot or group-chat name written in either Unicode canonical form, or carrying an invisible format character such as a zero-width space, is now one identity: the duplicate guard refuses the twin, `@Name` and every lookup reach the same record, and a stored name keeps only the characters that show on screen ([#2691](https://github.com/ThinkFlowLab/FlyBot/issues/2691)). +- A sibling Bot name, a member's role label and a memory topic written in either Unicode canonical form are now one identity each: `create_child_bot` refuses a child whose name only spells the sibling's name the other way, a queued task card reaches the member whose role label is the same role, and one topic is one file — a file written under an older spelling is still the topic's file, so nothing already saved is lost ([#2692](https://github.com/ThinkFlowLab/FlyBot/issues/2692)). +- A friend's Bot or owner display name is now cut on code points at its 60-character bound, so a name whose bound falls inside an emoji keeps the emoji whole instead of being stored as half a surrogate pair that every later UTF-8 write shows as a replacement character; the file names, outbound drafts and error lines the plugin also caps follow the same rule. A name already stored with a lone surrogate keeps that value: this change fixes new values and does not rewrite stored ones ([#2693](https://github.com/ThinkFlowLab/FlyBot/issues/2693)). +- The host now creates its own files private: a Bot's memory and its snapshot, `state.json`, the chat index, the decision log, the OCR cache and `inflight.json` are `0600` in a `0700` folder whatever `umask` the process inherited, and a rewrite keeps the mode the file already has, so a `chmod 0600` the owner made by hand is no longer undone by the next `remember` ([#2697](https://github.com/ThinkFlowLab/FlyBot/issues/2697)). +- A room line no longer tells the other homes in the room about this machine: a picture that could not be read is named by its file name and size instead of its absolute path (a Bot's own chat still names the path for itself), and a crashed external Bot's line reports only how it ended (`exit 1`, `signal SIGKILL`) while the child's last `stderr` words stay in this host's log. Every stored room line also passes this host's secret redaction before it is kept or sent, so a pasted key cannot ride a line to a friend's Bot ([#2699](https://github.com/ThinkFlowLab/FlyBot/issues/2699)). +- A Feishu webhook message whose answer was lost is no longer posted a second time: a timed-out or aborted send gets one attempt and says the message may already be in the chat, instead of claiming Feishu refused it ([#2660](https://github.com/ThinkFlowLab/FlyBot/issues/2660)). + +### Security + +- A room request naming one room in `id` and another in `roomId` no longer mints, reads or withdraws the other member's link, nor returns another member's live round: on the invite and round-read endpoints the permission gate and the handler resolve the room the same way, and such a request is refused ([#2652](https://github.com/ThinkFlowLab/FlyBot/issues/2652)). + ## [0.2.26] - 2026-11-08 ### Added @@ -1289,7 +1332,8 @@ If you used the legacy `dsh-bot` package, remove it before you install `ds-bot`. - Only one DSH can change a team at a time; a second DSH on the same DSH home opens it read-only ([Data and backups](ds-bot/README.md#data-and-backups)). - Group chats use many tokens: each member reads the group and answers in turn. -[Unreleased]: https://github.com/ThinkFlowLab/FlyBot/compare/v0.2.26...HEAD +[Unreleased]: https://github.com/ThinkFlowLab/FlyBot/compare/v0.2.27...HEAD +[0.2.27]: https://github.com/ThinkFlowLab/FlyBot/compare/v0.2.26...v0.2.27 [0.2.26]: https://github.com/ThinkFlowLab/FlyBot/compare/v0.2.25...v0.2.26 [0.2.25]: https://github.com/ThinkFlowLab/FlyBot/compare/v0.2.24...v0.2.25 [0.2.24]: https://github.com/ThinkFlowLab/FlyBot/compare/v0.2.23...v0.2.24 diff --git a/changelog.d/2624.fixed.md b/changelog.d/2624.fixed.md deleted file mode 100644 index be3f5e6c8..000000000 --- a/changelog.d/2624.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A trace rotation whose flush is refused no longer prunes the oldest segment, so the last durable trace file stays on disk instead of being deleted while the newer records exist only in memory ([#2624](https://github.com/ThinkFlowLab/FlyBot/issues/2624)). diff --git a/changelog.d/2629.fixed.md b/changelog.d/2629.fixed.md deleted file mode 100644 index b82640ea2..000000000 --- a/changelog.d/2629.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A timeline trace whose open is refused — a directory that cannot be listed, one removed underneath, or an I/O error — now gives its writer lock back instead of keeping it for the life of the process, so the next open in the same process and every later process succeeds once the problem is gone, and one transient read failure no longer leaves the on-disk trace switched off until a restart ([#2629](https://github.com/ThinkFlowLab/FlyBot/issues/2629)). diff --git a/changelog.d/2631.fixed.md b/changelog.d/2631.fixed.md deleted file mode 100644 index 9ee061e6f..000000000 --- a/changelog.d/2631.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A Bot Social credentials, backup or settings file that exists but no longer parses is now refused with a message naming it instead of being read as "not configured", so a torn file no longer makes a restart register a new home identity and overwrite the old one. Writes land through a temp file and a rename, so a failed write leaves the previous file whole ([#2631](https://github.com/ThinkFlowLab/FlyBot/issues/2631)). diff --git a/changelog.d/2633.fixed.md b/changelog.d/2633.fixed.md deleted file mode 100644 index 8b8248fc3..000000000 --- a/changelog.d/2633.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A grant or profile change that falls back to Bot Social's REST routes now gives up at the client's deadline instead of waiting forever, so a Bot Social server that accepts the connection and never answers shows a timeout error rather than a hung action ([#2633](https://github.com/ThinkFlowLab/FlyBot/issues/2633)). diff --git a/changelog.d/2634.fixed.md b/changelog.d/2634.fixed.md deleted file mode 100644 index 24d1b4c73..000000000 --- a/changelog.d/2634.fixed.md +++ /dev/null @@ -1 +0,0 @@ -An external participant whose room turn times out is now stopped instead of being left running, so a late answer to the timed-out turn can no longer become the next turn's answer — a slow process no longer replies one turn behind ([#2634](https://github.com/ThinkFlowLab/FlyBot/issues/2634)). diff --git a/changelog.d/2637.fixed.md b/changelog.d/2637.fixed.md deleted file mode 100644 index d3ec3a0dd..000000000 --- a/changelog.d/2637.fixed.md +++ /dev/null @@ -1 +0,0 @@ -The group board (`track_tasks`) now matches a Bot name and a group name the way every other door does — trimmed, case-insensitive, a leading `@` dropped from a Bot name and surrounding quotes from a group name — so `assignee: "dev"` and `group: "delivery group"` resolve the Bot and the room they name instead of being refused while the same state resolves them everywhere else. A name that matches no member or more than one still gets the same refusal ([#2637](https://github.com/ThinkFlowLab/FlyBot/issues/2637)). diff --git a/changelog.d/2638.fixed.md b/changelog.d/2638.fixed.md deleted file mode 100644 index 7c3f5d881..000000000 --- a/changelog.d/2638.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A Project name, repository, default branch, owner id, working folder or status that ends in an emoji at its length bound is now cut on a character boundary, so `state.json` stores a whole character instead of half a surrogate pair that every UTF-8 write showed as a replacement character ([#2638](https://github.com/ThinkFlowLab/FlyBot/issues/2638)). diff --git a/changelog.d/2641.fixed.md b/changelog.d/2641.fixed.md deleted file mode 100644 index 244566c1a..000000000 --- a/changelog.d/2641.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A person's own line in a face-to-face room is now capped at 18 000 code points instead of UTF-16 units, so an emoji at the bound is kept whole rather than stored as half a surrogate pair that every later UTF-8 write shows as a replacement character ([#2641](https://github.com/ThinkFlowLab/FlyBot/issues/2641)). diff --git a/changelog.d/2643.fixed.md b/changelog.d/2643.fixed.md deleted file mode 100644 index 99ab43c27..000000000 --- a/changelog.d/2643.fixed.md +++ /dev/null @@ -1 +0,0 @@ -The `social`, `timeline` and `workflow` plugins now resolve `$DSH_HOME` the way the core does — a blank or whitespace value counts as unset, `~` expands, and the root is always absolute — so `bot/flybot-social.json`, `bot/flybot-timeline` and `bot/flybot-workflow` no longer move with the process's working directory ([#2643](https://github.com/ThinkFlowLab/FlyBot/issues/2643)). diff --git a/changelog.d/2645.fixed.md b/changelog.d/2645.fixed.md deleted file mode 100644 index 41b1269c1..000000000 --- a/changelog.d/2645.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A copied line no longer loses the front of a word that only starts with a Bot's name: `Development plan is ready`, `Devices are offline`, `Released v0.2.26`, `Reviewers disagree` and `Chief concern about the tip` copy exactly as the preview reads them, while a real `Dev → Reviewer` delegation trace is still removed ([#2645](https://github.com/ThinkFlowLab/FlyBot/issues/2645)). diff --git a/changelog.d/2646.fixed.md b/changelog.d/2646.fixed.md deleted file mode 100644 index 49ddb6a9f..000000000 --- a/changelog.d/2646.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A friend's Bot can no longer put its own CSS on your page: the image URL in its published look is checked where it enters and again in the page-wide mention stylesheet, so a value carrying a quote, a parenthesis, a backslash or a control character is dropped and the Bot is drawn with its colour and mask instead of its photo ([#2646](https://github.com/ThinkFlowLab/FlyBot/issues/2646)). diff --git a/changelog.d/2649.fixed.md b/changelog.d/2649.fixed.md deleted file mode 100644 index d2b40dd88..000000000 --- a/changelog.d/2649.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A Bot's stored GIF avatar now reaches friends as the picture itself instead of a generated shape, and a look Bot Social refuses is no longer recorded as synced: saving the same picture again retries it instead of being silently skipped ([#2649](https://github.com/ThinkFlowLab/FlyBot/issues/2649)). diff --git a/changelog.d/2650.fixed.md b/changelog.d/2650.fixed.md deleted file mode 100644 index f6f5472a3..000000000 --- a/changelog.d/2650.fixed.md +++ /dev/null @@ -1 +0,0 @@ -The Project board reads every page of its GitHub pull-request and issue lists instead of the first hundred rows, so its seven-day merge and close medians and its day counts now cover the whole window rather than roughly the newest three days ([#2650](https://github.com/ThinkFlowLab/FlyBot/issues/2650)). diff --git a/changelog.d/2652.security.md b/changelog.d/2652.security.md deleted file mode 100644 index 337921612..000000000 --- a/changelog.d/2652.security.md +++ /dev/null @@ -1 +0,0 @@ -A room request naming one room in `id` and another in `roomId` no longer mints, reads or withdraws the other member's link, nor returns another member's live round: on the invite and round-read endpoints the permission gate and the handler resolve the room the same way, and such a request is refused ([#2652](https://github.com/ThinkFlowLab/FlyBot/issues/2652)). diff --git a/changelog.d/2654.fixed.md b/changelog.d/2654.fixed.md deleted file mode 100644 index 4cfadcb6c..000000000 --- a/changelog.d/2654.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A `define_workflow` call that replaces a saved graph now stores its `stepTimeoutMinutes` instead of returning success while keeping the old value, and refuses a value outside 1..120 the way the create branch does; the `workflow/graph` save applies the same rule, while a save that omits the field still keeps what is stored ([#2654](https://github.com/ThinkFlowLab/FlyBot/issues/2654)). diff --git a/changelog.d/2656.fixed.md b/changelog.d/2656.fixed.md deleted file mode 100644 index 11d45033c..000000000 --- a/changelog.d/2656.fixed.md +++ /dev/null @@ -1 +0,0 @@ -The Inbox lists failed workflow runs again: the shell now reads the workflow pack through the plugin's `flybot/workflow/state` endpoint instead of the bare `workflow/state` the host refuses, so a failed run reaches the Needs list and its badge ([#2656](https://github.com/ThinkFlowLab/FlyBot/issues/2656)). diff --git a/changelog.d/2658-step-artifacts-output.fixed.md b/changelog.d/2658-step-artifacts-output.fixed.md deleted file mode 100644 index c8f115686..000000000 --- a/changelog.d/2658-step-artifacts-output.fixed.md +++ /dev/null @@ -1 +0,0 @@ -An issue fast-line run no longer ends `failed` after its pull request was already opened: a Triage step that prints its delivery as its own `OUTPUT pr: 2657 (verified)` — or as `OUTPUT merged: <40-character sha>` — now counts as work done, so the run continues to `gate`/`enqueue`/`attest` and its record keeps the pull request number instead of dying on a missing `state` line ([#2658](https://github.com/ThinkFlowLab/FlyBot/issues/2658)). diff --git a/changelog.d/2662-run-name-id.fixed.md b/changelog.d/2662-run-name-id.fixed.md deleted file mode 100644 index a7476a106..000000000 --- a/changelog.d/2662-run-name-id.fixed.md +++ /dev/null @@ -1 +0,0 @@ -Two `run_workflow` calls that land in the same millisecond now start two runs instead of sharing a generated task id, so the second call is no longer silently dropped and no longer overwrites the first run's brief; a repeated dispatch that passes the same `task` explicitly is still de-duplicated ([#2662](https://github.com/ThinkFlowLab/FlyBot/issues/2662)). diff --git a/changelog.d/2663-parallel-node-id.fixed.md b/changelog.d/2663-parallel-node-id.fixed.md deleted file mode 100644 index 6331140e4..000000000 --- a/changelog.d/2663-parallel-node-id.fixed.md +++ /dev/null @@ -1 +0,0 @@ -Adding three or more Bots to one Parallel step in the New workflow dialog no longer gives two of them the same node id, so Create succeeds instead of failing with `Node n2 is listed twice` ([#2663](https://github.com/ThinkFlowLab/FlyBot/issues/2663)). diff --git a/changelog.d/2667-task-handoff-terminal.fixed.md b/changelog.d/2667-task-handoff-terminal.fixed.md deleted file mode 100644 index 0b2ffdd75..000000000 --- a/changelog.d/2667-task-handoff-terminal.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A card that has already finished — `accepted`, `cancelled` or `failed` — now refuses a late `handoff` with `A finished task cannot be handed on` instead of reopening itself as `open`, `not-started` and 0% under the next role, so a card that shows 100% can no longer slide back to the start of the board; the refusal is written the way the same card's "waiting on a question" write already is, and the refused write lands nothing at all, with `claimedBy` and the card's terminal state kept. A `result-ready` card still hands on, because that column is allowed to go back to working ([#2667](https://github.com/ThinkFlowLab/FlyBot/issues/2667)). diff --git a/changelog.d/2669-edge-outputs.fixed.md b/changelog.d/2669-edge-outputs.fixed.md deleted file mode 100644 index 023557335..000000000 --- a/changelog.d/2669-edge-outputs.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A workflow node is now told which `OUTPUT` lines it owes from its own declared outputs **and** from the outputs its outgoing edges read, with the accepted values spelled out (`OUTPUT state: `), so a node that declares no outputs no longer runs every step into `Missing OUTPUT state` and fails ([#2669](https://github.com/ThinkFlowLab/FlyBot/issues/2669)). diff --git a/changelog.d/2673-readonly-reap.fixed.md b/changelog.d/2673-readonly-reap.fixed.md deleted file mode 100644 index e1cd6a47f..000000000 --- a/changelog.d/2673-readonly-reap.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A second, read-only DSH window on the same home no longer reaps or disposes the writer's live workflow: loading the plugin and closing that window both leave the run, its step Bots and the stored progress alone, and the writing host's own load-time reap decides ([#2673](https://github.com/ThinkFlowLab/FlyBot/issues/2673)). diff --git a/changelog.d/2675-readonly-onboard.fixed.md b/changelog.d/2675-readonly-onboard.fixed.md deleted file mode 100644 index 907b9cfe1..000000000 --- a/changelog.d/2675-readonly-onboard.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A second, read-only DSH window on the same home no longer onboards a Bot Social home or writes the shared credentials file: it starts the social layer from the credentials the writable window already saved, so friends and messages stay visible, while the window that holds the team is the only one that can create a home or change that file ([#2675](https://github.com/ThinkFlowLab/FlyBot/issues/2675)). diff --git a/changelog.d/2677-quoted-failure.fixed.md b/changelog.d/2677-quoted-failure.fixed.md deleted file mode 100644 index 5428cb2b2..000000000 --- a/changelog.d/2677-quoted-failure.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A workflow step no longer fails because its own answer quotes `could not answer your message` while auditing that sentence: the host marks its real failure notice structurally, and an old host without the marker is read only from the notice shape at the start of the reply ([#2677](https://github.com/ThinkFlowLab/FlyBot/issues/2677)). diff --git a/changelog.d/2679-output-limit-turn.fixed.md b/changelog.d/2679-output-limit-turn.fixed.md deleted file mode 100644 index 8342a2fb3..000000000 --- a/changelog.d/2679-output-limit-turn.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A turn that DSH ended at the model's output limit is no longer reported as a normal finish or as a member that chose silence: the activity feed marks `turn.end` with `limited: true`, the ended-turn view keeps the turn (with `silent` and the streak when it wrote nothing, and its own sentence in the chat instead of "could not run"), and a group member cut off before it answered is recorded as "no answer" instead of a pass ([#2679](https://github.com/ThinkFlowLab/FlyBot/issues/2679)). diff --git a/changelog.d/2681-newer-version-store.fixed.md b/changelog.d/2681-newer-version-store.fixed.md deleted file mode 100644 index b643671e6..000000000 --- a/changelog.d/2681-newer-version-store.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A workflow file written by a newer FlyBot is no longer rewritten by an older one: the workspace store refuses to save over a definition whose `version` is higher than the one it writes and leaves it byte-identical, and lists it as a newer file instead of showing a definition that has lost fields it could not read. The workflow plugin does the same for `workflows.json` — `workflow/state` now answers `store-newer-version` with the version that wrote it, and every write is refused, so the owner's workflows, runs, claims and `seq` can no longer be replaced by the factory fixture ([#2681](https://github.com/ThinkFlowLab/FlyBot/issues/2681)). diff --git a/changelog.d/2685-output-evidence.fixed.md b/changelog.d/2685-output-evidence.fixed.md deleted file mode 100644 index 2f1bdfcb5..000000000 --- a/changelog.d/2685-output-evidence.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A declared `pr`/`pull` OUTPUT now counts as delivery evidence only when its value is the pull number itself — a positive integer, an optional leading `#`, an optional trailing parenthetical such as `2657 (verified)` — so a step that says it has no pull request is no longer read as one, and a loop's `until` output reaches the step body the same way a `when` condition does, so a looping node is told the line it must print instead of failing for silence ([#2685](https://github.com/ThinkFlowLab/FlyBot/issues/2685)). diff --git a/changelog.d/2687-otlp-redirect.fixed.md b/changelog.d/2687-otlp-redirect.fixed.md deleted file mode 100644 index ac45a5208..000000000 --- a/changelog.d/2687-otlp-redirect.fixed.md +++ /dev/null @@ -1 +0,0 @@ -The timeline's OTLP exporter no longer follows a redirect from the collector: a `307` reply that points at another origin is an export failure (warned, not counted as delivered, retried on the next flush) instead of a replay of `otlpHeaders` and the span payload at a host the operator never named. A normal `200` still counts as delivered ([#2687](https://github.com/ThinkFlowLab/FlyBot/issues/2687)). diff --git a/changelog.d/2689-external-long-answer.fixed.md b/changelog.d/2689-external-long-answer.fixed.md deleted file mode 100644 index 9638cc1b7..000000000 --- a/changelog.d/2689-external-long-answer.fixed.md +++ /dev/null @@ -1 +0,0 @@ -An external room participant whose answer line grows past the 4 KB stdout buffer is now reported to the room as `answer exceeded 4096 bytes` and keeps its process for later turns, instead of the answer being dropped as if the process had never spoken ([#2689](https://github.com/ThinkFlowLab/FlyBot/issues/2689)). diff --git a/changelog.d/2691-name-identity.fixed.md b/changelog.d/2691-name-identity.fixed.md deleted file mode 100644 index 0c4297b82..000000000 --- a/changelog.d/2691-name-identity.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A Bot or group-chat name written in either Unicode canonical form, or carrying an invisible format character such as a zero-width space, is now one identity: the duplicate guard refuses the twin, `@Name` and every lookup reach the same record, and a stored name keeps only the characters that show on screen ([#2691](https://github.com/ThinkFlowLab/FlyBot/issues/2691)). diff --git a/changelog.d/2692-identity-sites.fixed.md b/changelog.d/2692-identity-sites.fixed.md deleted file mode 100644 index 8de090f5c..000000000 --- a/changelog.d/2692-identity-sites.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A sibling Bot name, a member's role label and a memory topic written in either Unicode canonical form are now one identity each: `create_child_bot` refuses a child whose name only spells the sibling's name the other way, a queued task card reaches the member whose role label is the same role, and one topic is one file — a file written under an older spelling is still the topic's file, so nothing already saved is lost ([#2692](https://github.com/ThinkFlowLab/FlyBot/issues/2692)). diff --git a/changelog.d/2693-social-name-cut.fixed.md b/changelog.d/2693-social-name-cut.fixed.md deleted file mode 100644 index 835764ed8..000000000 --- a/changelog.d/2693-social-name-cut.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A friend's Bot or owner display name is now cut on code points at its 60-character bound, so a name whose bound falls inside an emoji keeps the emoji whole instead of being stored as half a surrogate pair that every later UTF-8 write shows as a replacement character; the file names, outbound drafts and error lines the plugin also caps follow the same rule. A name already stored with a lone surrogate keeps that value: this change fixes new values and does not rewrite stored ones ([#2693](https://github.com/ThinkFlowLab/FlyBot/issues/2693)). diff --git a/changelog.d/2697-private-files.fixed.md b/changelog.d/2697-private-files.fixed.md deleted file mode 100644 index b85248e28..000000000 --- a/changelog.d/2697-private-files.fixed.md +++ /dev/null @@ -1 +0,0 @@ -The host now creates its own files private: a Bot's memory and its snapshot, `state.json`, the chat index, the decision log, the OCR cache and `inflight.json` are `0600` in a `0700` folder whatever `umask` the process inherited, and a rewrite keeps the mode the file already has, so a `chmod 0600` the owner made by hand is no longer undone by the next `remember` ([#2697](https://github.com/ThinkFlowLab/FlyBot/issues/2697)). diff --git a/changelog.d/2699-room-line-leak.fixed.md b/changelog.d/2699-room-line-leak.fixed.md deleted file mode 100644 index 374b106a0..000000000 --- a/changelog.d/2699-room-line-leak.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A room line no longer tells the other homes in the room about this machine: a picture that could not be read is named by its file name and size instead of its absolute path (a Bot's own chat still names the path for itself), and a crashed external Bot's line reports only how it ended (`exit 1`, `signal SIGKILL`) while the child's last `stderr` words stay in this host's log. Every stored room line also passes this host's secret redaction before it is kept or sent, so a pasted key cannot ride a line to a friend's Bot ([#2699](https://github.com/ThinkFlowLab/FlyBot/issues/2699)). diff --git a/changelog.d/notify-webhook-duplicate.fixed.md b/changelog.d/notify-webhook-duplicate.fixed.md deleted file mode 100644 index c83ca7136..000000000 --- a/changelog.d/notify-webhook-duplicate.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A Feishu webhook message whose answer was lost is no longer posted a second time: a timed-out or aborted send gets one attempt and says the message may already be in the chat, instead of claiming Feishu refused it ([#2660](https://github.com/ThinkFlowLab/FlyBot/issues/2660)). diff --git a/core/package-lock.json b/core/package-lock.json index ab2af5ff7..fb966686d 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -1,12 +1,12 @@ { "name": "ds-bot", - "version": "0.2.26", + "version": "0.2.27", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ds-bot", - "version": "0.2.26", + "version": "0.2.27", "license": "Apache-2.0", "dependencies": { "@larksuiteoapi/node-sdk": "1.76.0" diff --git a/core/package.json b/core/package.json index cbecf5847..e1bc451ca 100644 --- a/core/package.json +++ b/core/package.json @@ -1,6 +1,6 @@ { "name": "ds-bot", - "version": "0.2.26", + "version": "0.2.27", "description": "DS Bot: a team of long-lived Bots for DeepSeek Harness, with Main Bots, Bot-to-Bot messages and group chats", "keywords": [ "dsh-plugin", diff --git a/patches/ds-bot/0007-version-and-tooling.patch b/patches/ds-bot/0007-version-and-tooling.patch index e87809664..23ec8e5c8 100644 --- a/patches/ds-bot/0007-version-and-tooling.patch +++ b/patches/ds-bot/0007-version-and-tooling.patch @@ -95,14 +95,14 @@ diff --git a/package-lock.json b/package-lock.json { "name": "ds-bot", - "version": "0.1.5", -+ "version": "0.2.26", ++ "version": "0.2.27", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ds-bot", - "version": "0.1.5", -+ "version": "0.2.26", ++ "version": "0.2.27", "license": "Apache-2.0", + "dependencies": { + "@larksuiteoapi/node-sdk": "1.76.0" @@ -733,7 +733,7 @@ diff --git a/package.json b/package.json { "name": "ds-bot", - "version": "0.1.5", -+ "version": "0.2.26", ++ "version": "0.2.27", "description": "DS Bot: a team of long-lived Bots for DeepSeek Harness, with Main Bots, Bot-to-Bot messages and group chats", "keywords": [ "dsh-plugin",