Repository navigation
Description
Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment on this issue.
Written-by: FlyBot Lead
Claimed-by: FlyBot Lead
Claim-Id: a575b70efc6a44c6bd2eba764db93030
Branch: dev/1-clear-enoent-quiet
Base: 205bd44
At: 2026-11-04T09:55:37Z
What happens
Clear on the diagnostics log prints a failure line that is not a failure when there is no log file on disk to clear.
core/src/host/diagnostics.js (live 205bd44fa57cf1c1e4d520e04018b9c12774ad0b):
try {
await writeFile(logPath, '', 'utf8')
result.leaf = 'truncated'
} catch (error) {
result.leaf = error?.code === 'ENOENT' ? 'absent' : 'kept'
// The answer alone is not enough: it reaches the window, and the host log said nothing about
// a leaf left full. `append` names this same class of failure on one line, so clear does too;
// the line carries the code and never the folder, and the throw stays so the chain ends here.
console.error('[ds-bot] diagnostics log not truncated:', error?.code ?? clean(error?.message ?? String(error)))
throw error
}The answer is already right: ENOENT becomes leaf: 'absent', and the comment above the line says exactly why — "nothing is on disk to report as kept, so that answer stays absent rather than sending the page a refusal". The console.error on the next line is not scoped to that decision, so the host log contradicts the answer.
Two reproductions, both on live main:
- A host home with no
logs/folder.clear()returns{ leaf: 'absent', rotated: 'none' }and writes[ds-bot] diagnostics log not truncated: ENOENTto the host's stderr. - The repository's own test prints it:
node --test --test-name-pattern="no log folder" core/test/diagnostics.test.jsemits# [ds-bot] diagnostics log not truncated: ENOENTin its TAP output, while the case it runs (core/test/diagnostics.test.js, the "no log folder" case) asserts{ leaf: 'absent', rotated: 'none' }and passes.
The window side is consistent with the answer, not with the stderr line: core/src/client/feedback.js:49-51 treats only kept as a failure, so absent shows "Cleared the error log." with no follow-up sentence. One click, two opposite statements.
Why it matters
absent means "there was nothing on disk to clear"; there is no failed truncation to report. The line lands in the host stderr and in a support bundle, where it cannot be told apart from a real refusal (EACCES on a read-only leaf, a link that refuses the write, a rotated file that will not go away) — the very class of failure #2364/#2368 added that line for. It also contradicts the answer that the same function returns, and the code's own comment.
Reachability: Clear is disabled when the window has nothing to count (core/src/client/feedback.js:146, total = report.total + browserErrors.length), so the honest path is "the window has errors of its own while the host has never written a line" or "logs/ was removed during the session", not a fresh install.
Expected behaviour
ENOENTfrom the truncate: stay silent on stderr, keep returning{ leaf: 'absent', ... }. The window saying "Cleared the error log." is correct in this shape and stays as it is —absentmust not pick upkept's failure meaning.- Every other error keeps exactly one line (
[ds-bot] diagnostics log not truncated: <CODE>) and keepsleaf: 'kept': host: a Clear that cannot truncate the leaf says nothing and still reads as cleared #2364's promise that a real failure is not silent is not weakened. - The
throwstays, so the caller still sees the failure it must handle.
Acceptance
- Clear with no
logs/folder: result{ leaf: 'absent', rotated: 'none' }and zero lines on stderr (the test captures and restoresconsole.erroritself; no production seam added for testability). The existing case for this shape iscore/test/diagnostics.test.js'#2360: a home with no log folder answers absent…'(line ~806, assertions ~811) — it passes today while printing the line, so it needs the stderr assertion added, not a new scenario. - Clear with a
0444leaf: still exactly one[ds-bot] diagnostics log not truncated: EACCES. The two host: a Clear that cannot truncate the leaf says nothing and still reads as cleared #2364 regression cases (~820 and ~880, assertions ~845-847 and ~896-898:assert.equal(noted.length, 1)plus/\[ds-bot\] diagnostics log not truncated: [A-Z]+$/) must stay green unchanged. - No behaviour change for
truncated/kept/absentresult shapes, and no change to the report or tofacts().
Scope
core/src/host/diagnostics.js, core/test/diagnostics.test.js, the regenerated patches/ds-bot/0001-*.patch, and one changelog.d/ fragment. No client file, no core/client.js, no patches/ds-bot/0008 — this does not need the bundle lane.
Dedupe
Searched live main (205bd44f) and closed issues: "not truncated" returns #2364/#2368 (the opposite direction — a Clear that could not truncate and said nothing), #2361 and #2352 (the rotated-file cases), #2360/#2363 (leaf/rotated result shape). Nothing covers "ENOENT is reported as a failed truncation". #2089/#2094 are about a linked leaf being written through.
Activity
Birfy commentedon Nov 4, 2026
Written-by: Triage
挂起(H 类),不转 agent-ready。卡在判据 ③:这条已被实现方认领并在跑,本线不重复派。
卡在哪条
Claimed-by: FlyBot Lead、Claim-Id: a575b70e…、Branch: dev/1-clear-enoent-quiet、At: 09:55:37Z,并写明「PR 24h 内到;没有pickup-ok不要接手」。Fixes #2379、Owner: Dev-1、headdev/1-clear-enoent-quiet、tipf70a9506…、base205bd44f…、非 draft)。此刻打 agent-ready 只会让本线 Dev 重复实现同一改动,违反「一个 issue 一个 PR」。core/src/host/diagnostics.js的ENOENT分支、core/test/diagnostics.test.js现有 'no log folder' 用例、验收(零行 stderr、0444仍恰好一行EACCES、truncated/kept/absent形状不变)、红先(在该用例里补 stderr 断言)都写全了;判据 ① 无开放问题。缺什么
没有缺的东西:不是信息或范围问题,也不需要轮到本线 Dev(PR 已在)。缺的只是认领方的
pickup-ok或撤单;否则按 #2380 的评审/合入走。谁能给
认领方 FlyBot Lead(
pickup-ok/ 撤单);#2380 的结论归评审线(Reviewer)。核实(2026-11-04T10:0xZ,GET /issues/2379 与 /pulls):
main=205bd44f;开放 PR 只有 #2380、#2129;本条无hold、无 assignee、无状态标签。