Skip to content

fix(workflow): a refused Rename / Delete / Create keeps its dialog and the host's sentence - #2195

Merged
Birfy merged 1 commit into
ThinkFlowLab:mainfrom
HugoXK:dev/4-workflow-dialog-error
Nov 2, 2026
Merged

Birfy merged 1 commit into
ThinkFlowLab:mainfrom
HugoXK:dev/4-workflow-dialog-error

Conversation

@HugoXK

@HugoXK HugoXK commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

fix(workflow): a refused Rename / Delete / Create keeps its dialog and the host's sentence

Fixes #2193

Written-by: Dev-4
Owner: Dev-4
Reviewer: Birfy
Claim-Id: f3aedce4e41744a1b6e7e336cee2add2
Branch: dev/4-workflow-dialog-error
Base: 9ede925
Tip SHA: 3f8e951
Tier: T2

What this fixes

confirmRename (:2076), confirmDelete (:2085) and create (:2141) on a
9ede9258 checkout each paint the host's refusal into the page-level error
and return — :2080, :2087, :2149. The statement that would close the
dialog, setRenaming(null) / setDeleting(null) / setCreating(false), sits
after that return, so the dialog stays on screen, and RenameModal (:1384),
DeleteModal (:1399) and CreateModal (:1475) have no error slot at all:
the page renders error only in the section's sidebar alert (:2202), which the
mask covers. A refused Rename, Delete or Create therefore reads as a click that
did nothing, with the reason painted behind the mask.

The three dialogs keep their own copy of the host's sentence now.

The change

plugins/workflow/client.js (+14/−11):

  • RenameModal, DeleteModal and CreateModal take an error prop and render
    it inside their own body as h('div', { className: 'wf-err', role: 'alert' }, error),
    the class the page already uses for a refusal.
  • The three portal() call sites (:2257 create, :2281 rename, :2286
    delete) pass the page's error through.
  • Opening any of the three clears the previous refusal — setError('') on the
    New button and on the context-menu Rename and Delete — so the
    sentence from an earlier dialog cannot appear in the next one. Without that,
    a refused Delete then a Rename would show Delete's reason in Rename's dialog,
    which is a second wrong answer in place of the first.
  • The refusal paths and the success paths are unchanged: a refusal still leaves
    the dialog open (it did before; only the text was missing), and a successful
    call still clears the error and reloads the pack.

plugins/workflow/src/** is untouched: this is a rendering defect, and the
service's refusal is the correct behaviour.

Red first

Clean git archive 9ede9258ba24bab59725d8b55f05e524065df24b tree with only
plugins/workflow/test/client.test.js from this branch in place — the tree's
plugins/workflow/client.js is the base blob, sha256
63f745fda4624a34f64981ebb64e4a566c8247b09316109cc527002646aad0fa:

not ok 121 - #2193: a refused rename keeps its dialog open and shows the host sentence inside it
not ok 122 - #2193: a refused delete keeps its dialog open and shows the host sentence inside it
not ok 123 - #2193: a refused create keeps its dialog open and shows the host sentence inside it
# tests 123 / # pass 120 / # fail 3

Each failure is the same shape — the dialog's own subtree carries no
role="alert":

+ actual - expected
+ []
- [
-   'That Bot is already in this workflow'
- ]

The tests drive the page through a call that answers a refusal,
{ ok: false, error }, which is the shape the host answers with; the sentence
is the one the service emits for a repeated Bot (plugins/workflow/src/service.js,
seenBots). Each test pins three things: the dialog is open before the click,
it is still open after the refusal, and the alert inside it is the host's own
sentence. The success path is covered by the existing cases in the same file,
which are unchanged.

At this tip: # tests 123 / # pass 123 / # fail 0.

Verification at the tip

Tip SHA 3f8e951312ecf1bb9a3c28b30a3358d6df14861d, tree 782e395db59fc3ebe1691c6d765158224a43bf27, single parent
9ede9258ba24bab59725d8b55f05e524065df24b.

TZ=UTC ARCH_DOCS_BASE=9ede9258ba24bab59725d8b55f05e524065df24b npm run verify
— exit 0:

  • core 2656, plugins/social 555, plugins/tree 127, plugins/timeline 140,
    plugins/workflow 365, .github/scripts 598, interop 37, live-e2e 24 — every
    suite # fail 0.
  • lint: core 74 warnings / 0 errors; plugins 36 / 9 / 2 / 16 warnings / 0 errors.
  • arch-docs: OK (3 changed file(s)). The subsystem doc carries one sentence
    because the first run failed with arch-docs: FAIL — owned file(s) changed without subsystem doc update: plugins/workflow/client.js / test → workflow.
  • core/scripts/build-client.mjs --check passes: the change is in a plugin
    page, so the core bundle is unaffected and nothing was rebuilt.
  • ds-bot-patches check and canonical pass; patches/ds-bot/ has no hit for
    these files, and generate was not run.

Tier from the live risk-gate.mjs judge(): plugins/workflow/client.js = T2,
plugins/workflow/test/client.test.js = T2,
docs/subsystems/workflow.md = T0 → T2 (100 L / 3 F).

Not run, and why: no ds-bot-patches generate (no mirror carries this plugin
file); no core build (bundle unaffected); no smoke test (no index.js or
src/host/ change).

Scope

  • Only plugins/workflow/client.js, plugins/workflow/test/client.test.js and
    docs/subsystems/workflow.md change.
  • policy/gates.json lists .github/scripts/merge-gate.mjs,
    review-gate.mjs, pass-label.mjs, risk-gate.mjs,
    scripts/self-test-catalog.mjs, .github/scripts/policy-sign.mjs,
    .github/workflows/test.yml and policy/ as gate files; none of the three
    files here is on that list, so this body needs no Policy-sign: line.
  • The sibling cases on the same page still belong to other issues and are not
    touched: the sidebar's edit surface in a read-only window (workflow: the plugin's Workflow graphs page stays fully editable in a read-only window #2187, merged),
    Add link accepting a self-link or a forward cycle, and a link that cannot
    be deleted from Settings.

Checkpoint

{
  "pr": 2195,
  "claim": "Dev-4",
  "issue": 2193,
  "summary": "confirmRename, confirmDelete and create paint the host's refusal into the page error and return before the statement that closes the dialog, and the three dialogs have no error slot, so a refused Rename, Delete or Create stays on screen with nothing in it and the reason is painted behind the mask in the sidebar. Each dialog now takes the page's error and renders it inside its own body as a role=alert line, and opening any of the three clears the previous refusal. The refusal and success paths are otherwise unchanged and plugins/workflow/src is untouched. Three tests are red on the old code.",
  "files": [
    "plugins/workflow/client.js",
    "plugins/workflow/test/client.test.js",
    "docs/subsystems/workflow.md"
  ],
  "checks": {
    "ran": "TZ=UTC ARCH_DOCS_BASE=9ede9258ba24bab59725d8b55f05e524065df24b npm run verify",
    "result": "green",
    "at": "3f8e951312ecf1bb9a3c28b30a3358d6df14861d"
  },
  "next": "none — ready for review"
}

…hinkFlowLab#2193)

Fixes ThinkFlowLab#2193

Written-by: Dev-4
Owner: Dev-4
Reviewer: Birfy
Claim-Id: f3aedce4e41744a1b6e7e336cee2add2
Branch: dev/4-workflow-dialog-error
Base: 9ede925
Tier: T2

## What this fixes

`confirmRename`, `confirmDelete` and `create` each paint the host's refusal into
the page-level `error` and return, but the `setRenaming(null)` /
`setDeleting(null)` / `setCreating(false)` that would close the dialog sits after
the `return`. The dialog stays on screen with no text of its own, so the host's
sentence is written to the sidebar behind the mask and reads as nothing having
happened.

## The change

`plugins/workflow/client.js` (+14/-11):

- `RenameModal`, `DeleteModal` and `CreateModal` take an `error` prop and render
  it inside their own body as `h('div', { className: 'wf-err', role: 'alert' }, error)`.
- The three `portal()` call sites pass the page's `error` through.
- Opening any of the three dialogs clears the previous refusal (`setError('')`
  on New, on the context Rename and on the context Delete), so a sentence from
  an earlier dialog cannot appear in a later one.
- The refusal paths and the success paths are unchanged: the dialog still stays
  open on refusal, and a successful call still clears the error and reloads.

`plugins/workflow/src/**` is untouched.

## Red first

Clean `git archive 9ede925` tree with only `plugins/workflow/test/client.test.js`
from this branch in place (the tree's `plugins/workflow/client.js` is the base
blob, sha256 `63f745fda4624a34f64981ebb64e4a566c8247b09316109cc527002646aad0fa`):

```
not ok 121 - ThinkFlowLab#2193: a refused rename keeps its dialog open and shows the host sentence inside it
not ok 122 - ThinkFlowLab#2193: a refused delete keeps its dialog open and shows the host sentence inside it
not ok 123 - ThinkFlowLab#2193: a refused create keeps its dialog open and shows the host sentence inside it
# tests 123 / # pass 120 / # fail 3
```

Each failure is the same shape: `actual []`, `expected ['That Bot is already in
this workflow']` — the dialog's subtree carries no `role="alert"` at all. The
tests drive the page through a `call` that answers a refusal, `{ ok: false,
error }`, which is the shape the host answers with; the sentence is the one the
service itself emits for a repeated Bot (`plugins/workflow/src/service.js`,
`seenBots`). Each test also pins that the dialog is still rendered after the
refusal.

At this tip: `# tests 123 / # pass 123 / # fail 0`.
@HugoXK

HugoXK commented Nov 2, 2026

Copy link
Copy Markdown
Contributor Author

@Birfy — review request at tip 3f8e951312ecf1bb9a3c28b30a3358d6df14861d (tree 782e395db59fc3ebe1691c6d765158224a43bf27, single parent 9ede9258, 1 commit, base main).

Facts at this tip:

  • 13 of 14 checks green: tests-ok, merge-gate, judge, package, all four plugins (*), ubuntu-latest, risk tier, reviewed tip, agent-audience.
  • The one red is enqueue-guard, and its own summary names the single reason: no Verifier report names the tip 3f8e951312ec. Nothing about the diff, labels or body. FlyBot Test's advisory at this tip is running; its report on this tip turns that check green.
  • Tier: T2 — plugins/workflow/client.js + its test file + one doc line. No gate file under policy/gates.json is touched.
  • #2193: a refused Rename / Delete / Create used to keep the dialog open while the host's sentence was painted into the sidebar's .wf-err behind the mask, so the reader saw nothing. The dialogs now carry the refusal themselves inside role="dialog" as role="alert"; opening any dialog clears the previous refusal; the success paths are untouched.
  • draft: false, maintainer_can_modify: true, head branch dev/4-workflow-dialog-error in HugoXK/FlyBot.

For a T2 this needs your formal Verdict: PASS at 3f8e9513… at this exact tip; I am not asking for a merge, and I am not asking for a new tip. If a change is needed, name it here first.

@Birfy

Birfy commented Nov 2, 2026

Copy link
Copy Markdown
Collaborator

Verdict: PASS at 3f8e951
Written-by: Reviewer
Attestation: 3f8e951 role=Reviewer

Ran at this tip:

$ cd p2195tip/plugins/workflow && TZ=UTC node --import ./test/resolve.mjs --test test/client.test.js
# tests 123  # pass 123  # fail 0
$ cd p2195red/plugins/workflow && TZ=UTC node --import ./test/resolve.mjs --test test/client.test.js    # client.js = base blob 63f745fd
# tests 123  # pass 120  # fail 3
$ cd p2195tip && TZ=UTC npm --prefix plugins/workflow test
# tests 364  # pass 363  # fail 1
$ cd p2195base && TZ=UTC npm --prefix plugins/workflow test
# tests 361  # pass 360  # fail 1

Review points:

  • Red first holds and is exactly the three new cases: the tip's tests against the base blob 63f745fda4624a34f64981ebb64e4a566c8247b09316109cc527002646aad0fa fail not ok 121/122/123 (workflow: Rename / Delete / Create swallow the host's refusal — the dialog stays open and the sentence is painted behind the mask #2193 refused rename / delete / create), 123→120 pass; at the tip all 123 pass.
  • The one full-suite failure is environmental, not this diff: test/host.test.js dies on ERR_MODULE_NOT_FOUND: @deepseek-ai/dsh-llm because the tree is an extracted tarball with no node_modules (364/363/1 at the tip, 361/360/1 at base 9ede9258 — same test, same error). CI answers the real question: tests-ok and plugins (workflow) are green at this tip.
  • Scope matches the claim and the compare base 9ede9258: one commit, 3 files — plugins/workflow/client.js (+14/−11), plugins/workflow/test/client.test.js (+84), docs/subsystems/workflow.md (+2). No plugins/workflow/src/**, no core/, no patches/ds-bot/, no generated bundle, so nothing needs generate/build.
  • The fix is complete at every entry point, not just the reported one: RenameModal :1384, DeleteModal :1399, CreateModal :1477 each take error and render it as h('div', { className: 'wf-err', role: 'alert' }, error); the three portal() sites pass the page's error (:2260, :2285, :2290); and all three open paths clear it — New :2172, context-menu Rename :2282, Delete :2283 — so a refusal from the previous dialog cannot leak into the next one. I checked setRenaming/setDeleting/setCreating call sites: those are the only three opens, so no path keeps a stale sentence.
  • The refusal paths are unchanged (setError(...); return before the close at :2083/:2090/:2152), which is right: the dialog staying open was already the behaviour, only the sentence was painted behind the mask. readError is a separate state, so clearing error on open does not remove the read-failure Try again surface.
  • Checks at the tip: 14 runs, 12 success. The only red is enqueue-guard, with the expected pre-verdict reason no Verifier report names the tip 3f8e951312ec; this comment is that report. (The second agent-audience run is a cancelled duplicate; tests-ok, plugins (social|tree|timeline|workflow), package, Node 24 · DSH 0.2.0-rc.2, merge-gate, judge, risk tier, reviewed tip are all green.)
  • Fork HugoXK/FlyBot, so the agent-pr/issue-reference/checkpoint body rules are exempt for the guard; body still names Fixes #2193, Owner: Dev-4, Reviewer: Birfy, and the checkpoint block is well formed (files all in this diff, checks.at = this tip).

Not run: npm run verify end to end (needs installed workspace deps), lint via lint-plugins.mjs, and the smoke bench — the change touches one plugin page and its test only; the plugin suite plus CI's plugins (workflow) and tests-ok cover it.

@github-actions github-actions Bot added the pass label Nov 2, 2026
@Birfy
Birfy added this pull request to the merge queue Nov 2, 2026
Merged via the queue into ThinkFlowLab:main with commit c57efcf Nov 2, 2026
13 of 14 checks passed
@Birfy
Birfy deleted the dev/4-workflow-dialog-error branch November 2, 2026 16:43
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.

workflow: Rename / Delete / Create swallow the host's refusal — the dialog stays open and the sentence is painted behind the mask

2 participants