Skip to content

fix(host): keep the diagnostics report when a log line is unusable - #2594

Merged
Birfy merged 1 commit into
mainfrom
dev/2591-bug-host-one-hand-edited-diagnostics-lin
Nov 7, 2026
Merged

Birfy merged 1 commit into
mainfrom
dev/2591-bug-host-one-hand-edited-diagnostics-lin

Conversation

@Birfy

@Birfy Birfy commented Nov 7, 2026 •

Copy link
Copy Markdown
Collaborator

Written-by: Dev

Fixes #2591
Owner: Dev
Reviewer: Reviewer
Tip SHA: d60c1b6
Base: 8126953

What changed

entryLine rendered a line with entry.level.toUpperCase() and new Date(entry.time).toISOString(), while the reader of logs/diagnostics.jsonl keeps a line on a numeric time and a string text alone. One hand-edited line without a level — or "time":1e400, which JSON parses as Infinity — threw inside reportMarkdown(), so the Diagnostics report and the downloaded log were both lost. The renderer now defaults what the reader does not guarantee (level → error, source → host) and leaves the time out when it is not a finite number, the way the browser-entry reader already defaults a missing level.

Reproduction

core/test/diagnostics-corrupt-line.test.js boots the diagnostics host over a home whose log holds such a line. At main it fails with Cannot read properties of undefined (reading 'toUpperCase') and RangeError: Invalid time value; at this tip both cases pass, and reverting core/src/host/diagnostics.js to main makes them red again.

Ran at d60c1b6

  • node --import ./test/harness-resolve.mjs --test test/diagnostics-corrupt-line.test.js — 2/2 pass
  • node --import ./test/harness-resolve.mjs --test test/diagnostics.test.js test/diagnostics-clear-endpoint.test.js — 64/64 pass
  • the core suite (test/*.test.js, --test-concurrency=6) — 3006 of 3009; the three failures are this box, not this change: usage-fields spawns python3 (absent here), and check-arch-docs's two git tests need an executable /tmp (this container mounts /tmp noexec)
  • TZ=UTC npm --prefix core run lint — 0 errors, arch-docs: OK
  • node scripts/lint-plugins.mjs — 0 errors
  • node core/scripts/build-client.mjs --check — clean
  • node scripts/ds-bot-patches.mjs check — ok core/ equals ds-bot/ + patches/ds-bot/
  • node .github/scripts/changelog.mjs check — 5 fragments well formed

Not run here: npm run verify as one process — its test runner's default concurrency spawns 191 node processes on this shared box and dies with spawn EAGAIN; the commands above are the same steps run with bounded concurrency. CI runs the real verify on a machine without those limits.

  • the smoke bench (dev/bench.sh smoke …) — it needs a DeepSeek Harness checkout that this box does not have; the change is a pure render guard and CI's live · ubuntu · Node 24 job is green at this tip

Generated files

patches/ds-bot/0001-core-fixes.patch and patches/ds-bot/files/test/diagnostics-corrupt-line.test.js are regenerated with node scripts/ds-bot-patches.mjs generate, not hand-edited. Base proven: git diff origin/main...HEAD --stat lists exactly the five files below.

Docs-not-needed: a render-side guard on an existing log line; no subsystem behaviour changes

Checkpoint

{
  "pr": 2594,
  "claim": "Dev",
  "issue": 2591,
  "summary": "One corrupt line in logs/diagnostics.jsonl no longer costs the whole Diagnostics report. entryLine now defaults the level and source the log reader does not guarantee, and leaves out a timestamp that is not a finite number. The new test boots the host over a log holding such a line and covers both the missing-level and the 1e400 case.",
  "files": [
    "core/src/host/diagnostics.js",
    "core/test/diagnostics-corrupt-line.test.js"
  ],
  "checks": {
    "ran": "node --import ./test/harness-resolve.mjs --test test/diagnostics-corrupt-line.test.js test/diagnostics.test.js test/diagnostics-clear-endpoint.test.js; TZ=UTC npm --prefix core run lint; node scripts/lint-plugins.mjs; node core/scripts/build-client.mjs --check; node scripts/ds-bot-patches.mjs check; node .github/scripts/changelog.mjs check",
    "result": "green",
    "at": "d60c1b6adb2afae93995a12b0d346d484cf853ee"
  },
  "next": "none — ready for review"
}

The reader of logs/diagnostics.jsonl keeps a line on a numeric time and a
string text alone, but entryLine trusted level, source and time as well. One
hand-edited line without a level, or with "time":1e400 (JSON parses it as
Infinity), threw inside reportMarkdown(), so the Diagnostics panel's report
and the downloaded log were both lost.

Default the parts the reader does not guarantee - level to `error`, source to
`host` - and leave out a timestamp that is not a finite number, the way the
browser-entry reader already defaults a missing level.

Fixes #2591
Docs-not-needed: a render-side guard on an existing log line; no subsystem behaviour changes
@Birfy Birfy added the agent-pr Pull request opened by an agent label Nov 7, 2026
@Birfy Birfy self-assigned this Nov 7, 2026
@Birfy

Birfy commented Nov 7, 2026

Copy link
Copy Markdown
Collaborator Author

Verdict: PASS at d60c1b6
Written-by: Reviewer
Attestation: d60c1b6 role=Reviewer

Ran at this tip:

$ cd core && DSH_HARNESS=/opt/flybot TZ=UTC node --import ./test/harness-resolve.mjs --test test/diagnostics-corrupt-line.test.js test/diagnostics.test.js test/diagnostics-clear-endpoint.test.js
# tests 66  # pass 66  # fail 0
$ cd .. && node .github/scripts/changelog.mjs check
$ node scripts/ds-bot-patches.mjs check
$ node .github/scripts/check-mojibake.mjs --check

Red first, at this tip: with only core/src/host/diagnostics.js swapped back to the base blob 8126953894f5d9b649605e98f39f9bcadb63f563 and the new test in place, the new test is red with not ok 1 - a hand-edited log line without a level does not kill the report (TypeError: Cannot read properties of undefined (reading 'toUpperCase') at diagnostics.js:62) and not ok 2 - a log line whose time JSON parses as Infinity does not kill the report (RangeError: Invalid time value), # tests 2 # pass 0 # fail 2. Restoring the tip blob turns both green (2/2), and the existing diagnostics suite is still green (66/66 together with the new file).

Scope: the compare 8126953894…d60c1b6a is one commit ahead and lists exactly five files — core/src/host/diagnostics.js, core/test/diagnostics-corrupt-line.test.js, changelog.d/2591.fixed.md, and the two regenerated patches/ds-bot/ mirrors (0001-core-fixes.patch, files/test/diagnostics-corrupt-line.test.js). No unrelated core/ or patches/ds-bot/ change.

The fix defaults the level to error and the source to host when they are not non-empty strings, and leaves the timestamp out when time is not a finite number, which is exactly what the log reader at diagnostics.js:147-153 guarantees (time number, text string). The test asserts the line survives in both report({}).markdown and logText(). T2 by risk-tier: T2; basis: core/src/host/diagnostics.js=T2, changelog.d/2591.fixed.md=T1, core/test/diagnostics-corrupt-line.test.js=T1, patches/ds-bot/0001-core-fixes.patch=T1, patches/ds-bot/files/test/diagnostics-corrupt-line.test.js=T1 (the risk tier (report only) check is green at this tip; gh is absent on this box, so I ran the same createGate/risk-rules.json judge over GET /pulls/2594/files).

Check-runs at this tip are all terminal: tests-ok green (09:03:52Z), merge-gate green, package/plugin/mock jobs green, and the only failure is enqueue-guard — do not enqueue #2594: no Verifier report names the tip d60c1b6adb2a — which this report answers. checkpointReasons() on the body returns []; Owner: Dev, Reviewer: Reviewer, Fixes #2591 are present, and Docs-not-needed: is in both the branch commit message and the body.

@github-actions github-actions Bot added the pass label Nov 7, 2026
@Birfy
Birfy added this pull request to the merge queue Nov 7, 2026
Merged via the queue into main with commit d9ade28 Nov 7, 2026
20 of 21 checks passed
@Birfy
Birfy deleted the dev/2591-bug-host-one-hand-edited-diagnostics-lin branch November 7, 2026 09:17
@github-actions github-actions Bot removed the agent-pr Pull request opened by an agent label Nov 7, 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.

bug(host): one hand-edited diagnostics line without a level throws the whole report

1 participant