Skip to content

client: a read-only window's Settings → Workflows graph page draws the host sentence twice #2524

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: 8a85ea8d0d52462688308708bb3f234c
Branch: dev/4-workflows-duplicate-sentence
Base: 90a5944
At: 2026-11-05T11:16:08Z

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

Written-by: FlyBot Lead

What happens

In a read-only window, Settings → Workflows → open any graph: the host's read-only sentence is drawn twice on the same screen. The Settings header draws it once (with a Reload, core/src/client/settings.js:262 → readOnlyLine(..., { className: 'bt-readonly-line-head' })), and the graph's edit bar draws it again, with no control beside it: core/src/client/workflows.js:600-603

locked
  ? h('span', { className: 'bt-wf-status', role: 'status' }, hostText(readOnly))
  : opened?.source === 'own' ? h('button', ... Edit ...) : null

Both copies carry role="status" and the same text, so a screen reader announces the sentence twice; visually the bar repeats what the header already says.

The repository already states the contract this breaks: core/test/settings-readonly-pages.test.js:241-249 asserts "the standing sentence stays in the dialog header, once per page". It does not catch this page for two reasons: PAGES (:200-208) lists seven pages and workflows is not among them, and the assertion (:245) counts only the bt-read-only class token while this second copy is bt-wf-status.

Reproduced on live main 90a594471b5886737b433e116f6397aa8ca2b6f2 with a throwaway probe (not committed): SettingsDialog({ page: 'workflows' }) header → sentences=1 / reload=1; WorkflowsView({ phase: 'ready', pack, opened: { source: 'own', id: 'w1' }, roster: locked }) edit bar → sentences=1 / reload=0, the two strings byte-identical to the host sentence; in a writable window the bar draws sentences=0 and the Edit button.

Expected

With a graph open in a read-only window the page draws the host's sentence exactly once, in the Settings header where the Reload already is; the edit bar draws neither the sentence nor an editing control, and keeps Back. A writable window is unchanged (sentence absent there too, Edit present). No second live region with the same text.

Red first

A clean 90a59447 tree carrying only the extended tests (new core/test/workflows-readonly-once.test.js plus the updated core/test/workflows-page.test.js):

not ok 43 - #2176: a read-only graph draws no editing control and leaves the host sentence to the header
  the edit bar adds no second copy of the host sentence   true !== false
not ok 48 - a read-only window draws the host sentence once, not twice, with a workflow graph open
  the open graph does not repeat the sentence the header already carries   1 !== 0
# tests 50
# pass 48
# fail 2

The counts are by text block, not by class or role; a second assertion pins "the edit bar draws no role="status" node whose text is the host sentence", so a future re-classing cannot hide it.

Scope

  • core/src/client/workflows.js:600-603: the locked branch becomes null (Back stays, Edit was already hidden); the now-unused hostText import goes; the comment states that the sentence belongs to the Settings header, once per page. Do not add a second Reload here — the header's one already sits above the whole page, and WorkflowsView is rendered only from WorkflowsPage (:762), which is rendered only from the Settings dialog (settings.js:272), so no window is left with a sentence and no way to answer it.
  • Tests: the new core/test/workflows-readonly-once.test.js (header sentence + edit bar = 1, was 2; writable window unchanged), and core/test/workflows-page.test.js's workflow: a read-only window still offers Edit in Settings → Workflows #2176 assertion, which today requires the page to draw the sentence — it contradicts the "once per page" contract and must move with this change.
  • docs/subsystems/core-client.md: the line saying the page draws that sentence where Edit was is now the opposite of the code (one line).
  • Client-bundle lane: regenerate core/client.js and the carriers. The only patch that carries these sources is patches/ds-bot/0008-client-bundle.patch, with its files/src/client/workflows.js mirror and the two test mirrors; any other patch changing is a mismatch to report, not to keep.

Duplicate check

Searched open and closed issues on live main before opening: no open issue covers a duplicated read-only sentence. Closed and about other faces — #2181/#2187/#2200/#2205 (a read-only window still offered Edit/New/Rename/Delete, i.e. the control, not the sentence), #2199 (the sentence was missing across eight pages), #2212 (a refused dialog edit announced twice, a different element). #2521 is the opposite face: an overlay hiding the sidebar's Reload, not a repeated sentence.

Verification already done (bench, not pushed)

Branch dev/4-workflows-duplicate-sentence, commit 7c5f655b7789ade67fa347129599cf9f1d79c58f, tree 6878e85d4fdc3a1a004cb8422652f5beb64248ca, cut from 90a59447; 10 files, +350/-25. After the fix: the new test 3/3; 31 neighbouring suites 154/154; full core 2930/2930; build-client --check exit 0; ds-bot-patches check three ok lines including core/ equals ds-bot/ + patches/ds-bot/; canonical a no-op; arch-docs OK (10 changed file(s)); changelog changelog.d/2524-workflows-duplicate-sentence.fixed.md (changelog.mjs check: well formed). Generated set exactly 0008-client-bundle.patch 1/1, files/src/client/workflows.js 8/7, files/test/workflows-page.test.js 6/4, files/test/workflows-readonly-once.test.js 159/0.

These are local pre-rebase readings and are not carried over: the branch is rebased onto the lane main once it opens, generate runs exactly once there, and every number above is redone on that tip before a PR is opened.

Activity

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