Skip to content

host: a stopped state journal is invisible in the diagnostics report #2134

Closed

Description

@HugoXK

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: f7bf73d73df14046842000c37d308652
Branch: dev/4-390-journal-status
Base: e6dfffe
At: 2026-11-02T08:38:52Z

Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment.

Written-by: FlyBot Lead

What happens

With stateJournal: true, a journal that cannot record stops for the run and leaves one warning, and nothing else ever says so. The diagnostics report a user is asked to paste into an issue therefore looks like a healthy host while no state change has been journalled at all.

Base: e6dfffeeb1ea1a50ab4e0695db9404b65528140f.

  • core/src/host/journal.js:239 — the only trace is warn('ds-bot: state journal %s is not recording: %s', path, error). stop() keeps no state, and openJournal returns no way to ask.
  • core/src/host/store.js — the writer stays in a local journal; Object.assign(rt, …) does not expose it.
  • core/src/host/diagnostics.js:219 — facts() has no journal entry; reportMarkdown (:65-88) lists up to Read-only, so the report shows Read-only plus No host errors recorded. and never mentions the journal.

Reproduction

  1. stateJournal: true in the bot config.
  2. Before start, make <home>/journal/state.jsonl something that is not a plain file of its own (a symlink is the shape the existing tests use).
  3. Start the host and open Settings → Diagnostics (or call the report).

Actual: one warning line at start; the report says Read-only: … and No host errors recorded. — no line about the journal, so the person cannot tell that recording is off for this run.

Expected

  • openJournal(...) returns status() → { recording: true }, or { recording: false, because: "<path> is not recording: <error>" } after stop().
  • store.js puts that writer on rt (journal), and diagnostics.facts() gains stateJournal — recording, or stopped (… ) with the home rewritten to ~ by the existing clean(), so no absolute path reaches a public report.
  • reportMarkdown writes one line after the table: state journal: recording or state journal: stopped (…). A host that never opened a journal (stateJournal off) gets no extra line at all.
  • The warning text stays byte-identical in shape (ds-bot: state journal %s is not recording: %s becomes one string built once), so existing log-based expectations do not drift.

Acceptance

  • Red first, on the base above, with only the new tests added: state-journal.test.js + diagnostics.test.js → 37 tests / 35 pass / 2 fail, failing as stopped.status is not a function and by the report not matching ^state journal: stopped \(.*not a plain file.*\)$. After the fix: 37/37.
  • Mutations each kill their own assertion: status() always { recording: true } → both red; because without the path → only the journal case red; reportMarkdown without the new line → only the diagnostics case red.
  • TZ=UTC ARCH_DOCS_BASE=<base> npm run verify exit 0 at the tip, with arch-docs and ds-bot-patches check / canonical clean; core count grows by exactly the two new tests.
  • docs/subsystems/core-host.md "Fail closed" gains one sentence saying the report names the stopped journal; changelog.d/<issue>-journal-status.added.md says in one user-visible line that Diagnostics now says whether the state journal is recording.
  • smoke may be reported as not run with the reason (no deepseek-harness checkout on this box); the change touches src/host/ journal status and report assembly only.

Scope

core/src/host/journal.js, core/src/host/store.js, core/src/host/diagnostics.js, core/test/state-journal.test.js, core/test/diagnostics.test.js, docs/subsystems/core-host.md, changelog fragment, and the generated patches/ds-bot/** mirrors — 11 files plus the changelog. No gateFiles (.github/scripts/*, .github/workflows/test.yml, policy/) are touched, so no Policy-sign: is needed.

Out of scope: changing what stops the journal (that is #2131/#2133 and the folder checks of #2056/#2074), adding any new field to the report table, and exposing the journal path or its contents.

Dedupe

Live main grep: stateJournal appears in core/README.md, CHANGELOG.md, journal.js, store.js, docs/subsystems/core-host.md and the patches/ds-bot/** mirrors — none of them reports whether the journal is recording; diagnostics.js has no journal key.

Closed issues: repo:ThinkFlowLab/FlyBot journal → 52 hits, all about the journal refusing a path or being written through (#2056, #2074, #2131/#2133, #2079/#2083), none about reporting a stopped journal; diagnostics → 63 hits, none on this topic. No open issue or PR covers it.

Activity

  1. added a commit that references this issue on Nov 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions