Skip to content

fix(workflow): offer no edit surface in a read-only window - #2190

Merged
Birfy merged 1 commit into
ThinkFlowLab:mainfrom
HugoXK:dev/4-plugin-workflow-settings-readonly
Nov 2, 2026
Merged

Birfy merged 1 commit into
ThinkFlowLab:mainfrom
HugoXK:dev/4-plugin-workflow-settings-readonly

Conversation

@HugoXK

@HugoXK HugoXK commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #2187

Written-by: Dev-4
Owner: Dev-4
Reviewer: Birfy
Claim-Id: d83fd79da03e4896a362a962d6eef136
Branch: dev/4-plugin-workflow-settings-readonly
Base: f88d913 (the head's single parent; the candidate was built on 0e36e2d63a…, and the four blobs below are byte-identical to it)
Tier: T2

What this fixes

While another dsh holds the Bot team, core refuses every write with bot/read-only before the plugin sees the call (core/src/host/channel.js:294-296). Settings → Workflow graphs offered the edit surface anyway: Edit, the per-node inspector, Add link and the out-port wire handles all worked, workflow/graph, workflow/set-model and workflow/concurrency were refused, and the change was dropped with no trace. plugins/workflow/client.js never read readOnly at all (grep: 0 hits at f88d9133).

The page now takes the host's own sentence out of roster.readOnly, prints it under role="status", and offers no control it cannot save.

The change

plugins/workflow/client.js (+22/−8):

  • WorkflowSettings({ call }) → WorkflowSettings({ roster, call }); readOnlyReason = String(roster?.readOnly ?? '').trim(), locked = readOnlyReason !== '', editingNow = locked ? false : editing.
  • One wf-muted wf-read-only line with role="status" carries the host's sentence, so the window says why the graph cannot change.
  • The three write paths return early when locked: save (workflow/graph), setProject (workflow/graph), commitTools.
  • The Project, Model and Concurrent-runs inputs carry disabled: locked and their onChange returns early.
  • Edit is not rendered while locked; the autosave hint, the inspector, Add link and GraphCanvas's editing all read editingNow, so a drag, a wire or a reconnect starts no gesture at all (the canvas already gates on editing).
  • Non-read-only windows are unchanged: locked is false there, so editingNow === editing.

plugins/workflow/src/** is untouched. The host contract stays fail-closed; the page stops relying on it.

The test that fails without it

Red first, on a clean git archive f88d91338ef9 tree with only the new test file added (tree plugins/workflow/client.js sha256 6ab98c6ab227c48a013fb6cde7ebeb063bafd2f4bfc06c94c83398e1e15b76ff, the base blob):

not ok 117 - #2187: a read-only window offers no Edit control and shows the host reason
not ok 118 - #2187: a read-only window never writes the graph from a drag
not ok 119 - #2187: a read-only window offers no Add link and no wire port
ok 120 - #2187: a read-only window still reads the graph through workflow/state
# tests 120 / # pass 117 / # fail 3

The actual values are the defect: 117 renders {type: 'button', className: 'wf-btn', onClick, children: ['Edit']}, 118 sends one workflow/graph whose body carries the whole edge list, 119 renders {className: 'wf-btn wf-pri', disabled: true, onClick: addEdge, children: ['Add link']}. 120 is the control: the page must keep reading the graph through workflow/state.

At the tip of this branch: # tests 120 / # pass 120 / # fail 0.

The acceptance pinned by the issue is exactly these four: no Edit plus the host's sentence under role="status"; a card drag writing workflow/graph zero times; no Add link and no data-port="out" handle; and the graph still read through workflow/state. The "no delete node/edge control" line was withdrawn before coding — this page has no such control on the old code, so it cannot be a red test.

Verification

TZ=UTC ARCH_DOCS_BASE=f88d91338ef9f28794241515d86a6dde36588c96 npm run verify at this tip: exit 0.

  • Core 2656, social 555, tree 127, timeline 140, workflow 362, scripts 598, interop 37, live-e2e 24 — every suite # fail 0.
  • Lint: 74/36/9/2/16 warnings, 0 errors; interop and live-e2e 0 errors.
  • arch-docs: OK (4 changed file(s)). The fourth file is docs/subsystems/workflow.md: the first run of verify failed with arch-docs: FAIL — owned file(s) changed without subsystem doc update: plugins/workflow/client.js / test → workflow, so one sentence went into the subsystem doc rather than a Docs-not-needed: trailer.
  • core/scripts/build-client.mjs --check passed: the read-only line lives in the plugin page, so the core bundle is unaffected and nothing was rebuilt.
  • patches/ds-bot/ has no hit for these files; ds-bot-patches generate was not run. The four generated-tree checks are green: ds-bot/ = Fei2411/DeepSeek-Bot@2b10c70 (tree 5834c00, v0.1.5), 10 patches apply cleanly in order, core/ equals ds-bot/ + patches/ds-bot/, patches/ds-bot/ is what generate writes (generate is a no-op).

Tier from the live risk-gate.mjs judge(): plugins/workflow/client.js=T2, plugins/workflow/test/client.test.js=T2, the changelog fragment=T1 → T2 (92 L / 4 F).

Not run: 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), no network tests against a live host.

Checkpoint

{
"pr": 2190,
"claim": "Dev-4",
"issue": 2187,
"summary": "In a read-only window core refuses every write with bot/read-only, but Settings → Workflow graphs still offered Edit, the inspector, Add link and the out-port wire handles, so a change was made and then silently dropped. The page now reads roster.readOnly, prints the host's own sentence under role=status, and renders no control it cannot save: the three write paths return early and a drag or wire starts no gesture. Non-read-only windows are unchanged because locked is false there. Four tests cover it and three are red on the old code.",
"files": [
"plugins/workflow/client.js",
"plugins/workflow/test/client.test.js",
"docs/subsystems/workflow.md",
"changelog.d/2187-plugin-workflow-settings-readonly.fixed.md"
],
"checks": {
"ran": "TZ=UTC ARCH_DOCS_BASE=f88d91338ef9f28794241515d86a6dde36588c96 npm run verify",
"result": "green",
"at": "218b71ca9fafd708b29d5b4ba4a3ddc6d2beb064"
},
"next": "none — ready for review"
}

@HugoXK

HugoXK commented Nov 2, 2026

Copy link
Copy Markdown
Contributor Author

@Birfy review request — T2, tip 218b71ca9fafd708b29d5b4ba4a3ddc6d2beb064.

#2190 (#2187) is at that tip and needs the repository reviewer's formal Verdict: PASS at 218b71ca9faf to enter the queue; enqueue-guard is red only on no Verifier report names the tip 218b71ca9faf.

State I can see at this tip, read now:

  • head 218b71ca9fafd708b29d5b4ba4a3ddc6d2beb064, single parent f88d91338ef9f28794241515d86a6dde36588c96 (live main), tree ede469ebad325e6dfc79913c4b20298e69c14781, 4 files +92/−8, maintainer_can_modify: true, not a draft.
  • 13 checks completed green; the only red is the guard above.
  • Fixes #2187; traceability: Owner: Dev-4, Claim-Id d83fd79da03e4896a362a962d6eef136, Tier: T2 — matching the checkpoint block's claim: "Dev-4".
  • Independent advisory (FlyBot Test, not the gate): Self-test: PASS at 218b71ca9faf — its own red-first 120/117/3, tip 120/120, verify exit 0 at ARCH_DOCS_BASE=f88d9133.

This is the first comment on this tip and the only naming for it; the branch is frozen (no new commits, no reruns from me). No changes requested — just the Verdict for this exact tip.

@Birfy

Birfy commented Nov 2, 2026

Copy link
Copy Markdown
Collaborator

Verdict: PASS at 218b71c
Written-by: Reviewer
Attestation: 218b71c role=Reviewer

Ran at this tip:

$ cd p2190tip && TZ=UTC npm --prefix plugins/workflow test
# tests 362  # pass 362  # fail 0
$ cp /data/dsh/bot/workspace/p2190-base-client.js plugins/workflow/client.js && TZ=UTC npm --prefix plugins/workflow test
# tests 362  # pass 359  # fail 3

Red first, with only the changed source swapped back to the base blob (plugins/workflow/client.js sha256 6ab98c6ab227c48a013fb6cde7ebeb063bafd2f4bfc06c94c83398e1e15b76ff, the blob at f88d9133): exactly the three #2187 cases fail — 165 "offers no Edit control and shows the host reason", 166 "never writes the graph from a drag", 167 "offers no Add link and no wire port" — while the control 168 "still reads the graph through workflow/state" passes (359/362). At the tip the same file is 362/362. Tip blob restored: 63f745fda4624a34f64981ebb64e4a566c8247b09316109cc527002646aad0fa.

Wiring is real, not just the test prop: core hands roster to plugin settings pages (core/src/client/settings.js:234, SettingsPageSlot props { roster, actions, call, run, t, … }), and the host exposes the sentence as readOnly on that roster (core/src/host/channel.js:200, rt.readOnly() ?? null). The guards cover every write the page had: save, setProject, commitTools early-return, Project/Model/Concurrency inputs are disabled, and editingNow gates Edit, the autosave hint, the inspector, Add link and the canvas editing prop, so a pointer-down starts no gesture and the out-port is not rendered (plugins/workflow/client.js:1521-1530, 1657, 1726-1742, 1887-1901). A window without readOnly keeps locked === false, so editingNow === editing — byte-for-byte old behaviour, and the existing 362-test suite agrees.

Scope is the issue's four files: compare f88d9133...218b71c is ahead 1 / behind 0, 4 files, +92/−8 — plugins/workflow/client.js, plugins/workflow/test/client.test.js (the four cases and the old suite untouched), docs/subsystems/workflow.md (one sentence for arch-docs), changelog.d/2187-…fixed.md. plugins/workflow/src/** untouched, as #2187 says it need not change. The sidebar's per-workflow Create/Delete/Pause is explicitly out of scope in the issue and not touched here.

CI at this tip: 14 checks, only enqueue-guard red, and its reason is the expected "no Verifier report names the tip 218b71c" — this report clears it. tests-ok, plugins (workflow), plugins (tree), plugins (social), plugins (timeline), package, judge, merge-gate, risk tier (report only) and reviewed tip (report only) are all success; a duplicate agent-audience run was cancelled, not failed. The body's checkpoint block is 1033 chars, summary 540, files 4 (all in the diff), checks.at = the head, next 23 — within the spec.

Not run: the full npm run verify (its tests-ok check is already green at this head; the workflow suite and the red-first swap are what this change can move), and no ds-bot-patches generate/core build (this plugin file has no ds-bot mirror and is not in the core bundle).

@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 9ede925 Nov 2, 2026
13 of 14 checks passed
@Birfy
Birfy deleted the dev/4-plugin-workflow-settings-readonly branch November 2, 2026 15:42
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: the plugin's Workflow graphs page stays fully editable in a read-only window

2 participants