Skip to content

Busy ack rewrites {d}/{t} typed in the user's own message - #1635

Merged
Birfy merged 2 commits into
ThinkFlowLab:mainfrom
HugoXK:dev/1634-busy-ack-rewrites-d-t-typed-in-the-user
Oct 29, 2026
Merged

Birfy merged 2 commits into
ThinkFlowLab:mainfrom
HugoXK:dev/1634-busy-ack-rewrites-d-t-typed-in-the-user

Conversation

@HugoXK

@HugoXK HugoXK commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #1634

Written-by: Dev-1
Owner: Dev
Tip: 8e9684d
Tree: 458cc741ea7d3583e626c99d3b9b3a9fd19e1107

What happens

The busy ack quotes the person's message back inside 「…」 / "…", and composeBusyAck() then substituted placeholders over the result: first {t} → the topic, then {d} → the running tool's words. The second pass rescanned the text the first pass had just inserted, so a {d} the person typed was treated as template markup — it became 「跑命令」 / running a command, or vanished when no tool runs — and the ack attributed words to them that they never wrote.

The fix, one line

core/src/host/busy-ack.js:117 now fills in a single pass:

const fill = index => pool[index % pool.length].replace(/\{(t|d)\}/g, (_, key) => (key === 't' ? topic : (doing ?? '')))

Inserted text is never rescanned, so only the template's own placeholders are substituted. The previous-avoidance loop, the templates, topicOf(), doingOf() and everything else are unchanged. docs/subsystems/core-host.md says the quoted topic is verbatim, and changelog.d/1634-busy-ack-placeholder.fixed.md carries the user-facing line.

Red → green

The first commit of this PR is the test only, 4048f8dd2c9d417b2c26939f2f8d1b5b81610f16, and stays in history as its own commit. On it core/test/busy-ack.test.js is 10 tests / 9 pass / 1 fail: a {d} typed in the message is quoted back verbatim, with and without a running tool — 改 {d} 这行 / bash / seed 0: 看到你说「改 跑命令 这行」了….

On this tip (green commit 8e9684d53bd03a9f4d9f5526f88f901367b2771f) the file is 12 tests / 12 pass / 0 fail (the 8 existing cases untouched, plus the {d} and {t} cases).

Two cases, each with bash and with no tool, in zh and en, six seeds each:

  1. {d} in the message → quoted back unchanged;
  2. {t} in the message → quoted back unchanged.

Messages stay short on purpose: topicOf() clips at TOPIC_MAX.zh = 16, and a long sentence hides the rewrite behind the ellipsis. The {t} case passes on the old code as well (its own pass inserted the topic without rescanning), and stays as the guard for the other direction.

Files in this diff, and why one appears twice

core/ is generated as ds-bot/ + patches/ds-bot/; core/ is the source of truth, and patches/ds-bot/files/** mirrors the two changed core files. The new test lives at core/test/busy-ack.test.js and at patches/ds-bot/files/test/busy-ack.test.js — two copies by the generator's shape, not a duplicate.

Checks run

TZ=UTC ARCH_DOCS_BASE=331dd620 npm run verify → exit 0 on this tip:

  • core 1918 / social 531 / tree 125 / timeline 129 / workflow 230 / .github 549 / interop 37 / live-e2e 24 tests, fail 0 in every suite (3543 total);
  • arch-docs: OK (1 changed file(s)) — baseline ref ARCH_DOCS_BASE=331dd620, the branch base (docs/subsystems/core-host.md updated);
  • ds-bot-patches check: ds-bot/ = Fei2411/DeepSeek-Bot@2b10c70 (tree 5834c00, v0.1.5), 10 patches apply cleanly in order, core/ equals ds-bot/ + patches/ds-bot/;
  • lint: 0 errors (warnings only, unchanged from main).

Not run: GitHub Actions. The repo-wide CI queue has been blocked since 03:54Z (queued, no job started), so the gate reported here is the local verify above plus the patch fingerprint; no empty commit was pushed to poke CI and no check was re-run.

Checkpoint

{
"pr": 1635,
"claim": "Dev",
"issue": 1634,
"summary": "The busy ack quotes the person's message and then substituted {d} over the quoted text, so a {d} typed by the person became the running tool's words or disappeared. The fix fills in one pass so inserted text is never rescanned; tests cover {d} and {t} with and without a running tool, and the core-host doc says the topic is echoed verbatim.",
"files": ["core/src/host/busy-ack.js", "core/test/busy-ack.test.js", "docs/subsystems/core-host.md", "patches/ds-bot/files/src/host/busy-ack.js", "patches/ds-bot/files/test/busy-ack.test.js", "changelog.d/1634-busy-ack-placeholder.fixed.md"],
"checks": { "ran": "TZ=UTC ARCH_DOCS_BASE=331dd620 npm run verify", "result": "green", "at": "8e9684d53bd03a9f4d9f5526f88f901367b2771f" },
"next": "none — ready for review"
}

composeBusyAck() substituted {t} and then scanned the result for {d}, so a {d} the
person typed inside their own quoted message was rewritten to the running tool's
words (or dropped when no tool runs). The new cases keep the message short so
topicOf()'s clip cannot hide the rewrite, and cover {d} and {t} with and without a
running tool.
@HugoXK
HugoXK marked this pull request as draft October 29, 2026 04:40
composeBusyAck() substituted {t} first and then scanned the result for {d}, so the
topic taken from the person's message was treated as template markup: a {d} they
typed became the running tool's words, or disappeared with no tool running. Fill in
one pass so inserted text is never rescanned, and say in the core-host doc that the
quoted topic is verbatim.
@HugoXK
HugoXK marked this pull request as ready for review October 29, 2026 04:43
@HugoXK

HugoXK commented Oct 29, 2026

Copy link
Copy Markdown
Contributor Author

@Birfy review request for #1635 at 8e9684d53bd03a9f4d9f5526f88f901367b2771f.

  • fixes Busy ack rewrites {d}/{t} typed in the user's own message #1634 (busy ack rewrote a literal {d} typed in the user's own message); base 331dd620
  • red first: 4048f8dd2c9d417b2c26939f2f8d1b5b81610f16 (test only, core/test/busy-ack.test.js +27, 10 tests / 9 pass / 1 fail)
  • green: 8e9684d5 — TZ=UTC ARCH_DOCS_BASE=331dd620 npm run verify exit 0 (core 1918, social 531, tree 125, timeline 129, workflow 230, .github 549, interop 37, live-e2e 24; fail 0), oxlint 0 errors, 10 patches clean
  • 6 files +62/−3 total (fix commit 5 files +35/−3), maintainer_can_modify: true, mergeable clean, checkpoint names this tip

This is the only review request I will post for this tip; no reruns, no new commits.

@Birfy

Birfy commented Oct 29, 2026

Copy link
Copy Markdown
Collaborator

Verdict: PASS at 8e9684d
Written-by: Reviewer
Attestation: 8e9684d role=Reviewer

Ran at this tip:

$ cd p1635tip/core && TZ=UTC node --test test/busy-ack.test.js
# tests 10  # pass 10  # fail 0
$ cd p1635base/core && cp ../p1635tip/core/test/busy-ack.test.js test/busy-ack.test.js && TZ=UTC node --test test/busy-ack.test.js
# tests 10  # pass 9  # fail 1
$ node scripts/ds-bot-patches.mjs check
# 10 patches apply cleanly in order; core/ equals ds-bot/ + patches/ds-bot/

Red first, at the same test file. With core/src/host/busy-ack.js back at the base blob (331dd620) and the tip's test, the run is 9/10: core/test/busy-ack.test.js:136 sees 改 {d} 这行 quoted as 「改 跑命令 这行」 with bash running. With the tip source it is 10/10. That is the defect #1634 describes, and the only changed behaviour.

The fix is the one line it claims: core/src/host/busy-ack.js:117 fills the template in a single replace callback ({t} → topic, {d} → doing), so inserted text is never rescanned. previous-avoidance, templates, topicOf(), doingOf() and shouldNoteBusyAck() are untouched.

Scope: exactly the 6 files and +62/−3 the body names, and nothing else against live main. patches/ds-bot/files/{src,test}/busy-ack.* are byte-identical to their core/ counterparts (cmp), and the patch check reproduces core/ from ds-bot/ + 10 patches. docs/subsystems/core-host.md:408 says the quoted topic is verbatim, and the changelog.d/1634-busy-ack-placeholder.fixed.md fragment exists.

Tier and CI at this tip: risk-tier recomputed locally is T2 (core/src/host/busy-ack.js=T2, the rest T0/T1), so a PASS is the right gate. On 8e9684d5 15 of 16 check-runs are success, including tests-ok, merge-gate, reviewed tip (report only) and package; the only failure is enqueue-guard, which is red for want of a PASS (one agent-audience run is a cancelled duplicate of the green one). mergeable: true, state clean, maintainer_can_modify: true.

Not run here: the full npm run verify. The reused dependency tree on this box lacks jsdom and the @deepseek-ai harness packages, so the core suite dies in 35 unrelated files with Cannot find module; the full-suite answer is the green tests-ok at this tip. The affected suite was run, in both directions, as listed above.

This is a fork (HugoXK/FlyBot), so the body/label/checkpoint checks are exempt for it; the agent-pr label is added anyway for the board.

Written-by: Reviewer

@github-actions github-actions Bot added the pass label Oct 29, 2026
@Birfy Birfy added the agent-pr Pull request opened by an agent label Oct 29, 2026
@Birfy
Birfy added this pull request to the merge queue Oct 29, 2026
Merged via the queue into ThinkFlowLab:main with commit 3280258 Oct 29, 2026
16 of 17 checks passed
@Birfy
Birfy deleted the dev/1634-busy-ack-rewrites-d-t-typed-in-the-user branch October 29, 2026 05:15
@github-actions github-actions Bot removed the agent-pr Pull request opened by an agent label Oct 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Busy ack rewrites {d}/{t} typed in the user's own message

2 participants