You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(workflow): offer no edit surface in a read-only window - #2190
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.
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.mjsjudge(): 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"
}
@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.
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.
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).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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-onlybefore 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-modelandworkflow/concurrencywere refused, and the change was dropped with no trace.plugins/workflow/client.jsnever readreadOnlyat all (grep: 0 hits atf88d9133).The page now takes the host's own sentence out of
roster.readOnly, prints it underrole="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.wf-muted wf-read-onlyline withrole="status"carries the host's sentence, so the window says why the graph cannot change.save(workflow/graph),setProject(workflow/graph),commitTools.disabled: lockedand theironChangereturns early.GraphCanvas'seditingall readeditingNow, so a drag, a wire or a reconnect starts no gesture at all (the canvas already gates onediting).lockedis false there, soeditingNow === 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 f88d91338ef9tree with only the new test file added (treeplugins/workflow/client.jssha2566ab98c6ab227c48a013fb6cde7ebeb063bafd2f4bfc06c94c83398e1e15b76ff, the base blob):The
actualvalues are the defect: 117 renders{type: 'button', className: 'wf-btn', onClick, children: ['Edit']}, 118 sends oneworkflow/graphwhose 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 throughworkflow/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 writingworkflow/graphzero times; no Add link and nodata-port="out"handle; and the graph still read throughworkflow/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 verifyat this tip: exit 0.# fail 0.arch-docs: OK (4 changed file(s)). The fourth file isdocs/subsystems/workflow.md: the first run of verify failed witharch-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 aDocs-not-needed:trailer.core/scripts/build-client.mjs --checkpassed: 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 generatewas 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.mjsjudge():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 corebuild(bundle unaffected), no smoke test (noindex.jsorsrc/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"
}