Repository navigation
Conversation
f565344 to
a69b54a
Compare
|
Verdict: PASS at a69b54a Ran:
What I checked:
Non-blocking notes:
|
Written-by: Dev3
`plugins/workflow/index.js`'s `dispatch` returned the host's
`{ action: 'deny' | 'hold' }` records untouched. They carry no `ok` key, so
`handOff()`'s `answer?.ok === false` guard missed them: the node was written
to `run.handed`, no warn line was logged, and `settle()` skips a handed node,
so the step never ran and the run sat at Running while the graph showed work
in flight.
Normalise the two refusals inside `dispatch` — the one place that reads
`fb.bot.send`'s answer — into `{ ok: false, code, reason }`. `handOff` and its
call sites are unchanged, and an `allow` answer is returned exactly as before.
Docs-not-needed: plugin-internal fix; no architecture, subsystem or contract
change, because `dispatch` keeps answering in the vocabulary `handOff`
already reads.
a69b54a to
f149b26
Compare
|
Verdict: PASS at f149b26 Ran:
Checked:
Not run:
Non-blocking:
The tip moved since the earlier PASS only because the branch was rebased onto |
|
Written-by: Rework Not replaying this branch: on current main ( Checks run at
Recommendation: close PR #1416 and issue #1407 as fixed by #1412 (or re-scope #1407 if a different gap remains). No commit, label or body change made here. |
Written-by: Dev3
Owner: Dev3
Reviewer: Reviewer2
Fixes #1407
Tip SHA:
f149b26a5cd749c1c02ee4853d05883cd6ba6fb5Reproduce
On
26657c8a(current main),dispatchinplugins/workflow/index.js:60-65answers{ ok: false, code: 'no-sender' }when it cannot send, and otherwise hands back exactly whatfb.bot.sendreturned. That success shape is{ action: 'allow' | 'deny' | 'hold', … }and never carriesok—core/src/host/hooks.jsbuilds all three (:291a middleware that threw,:294an unknown action,:309-310the verdict,:618/:620owner policy and chain denies,:621-627holdwithapprovalId).So
handOff()'sanswer?.ok === falseguard (plugins/workflow/src/service.js, merged by#1399) never fires for the two refusals: it writesrun.handed[nodeId], logs nothing, and becausesettle()skips a node that is already handed, no later pass tries again. The run staysRunning, the graph shows work in flight, and the step never runs — the#1389stall reached through a different return value.The new cases build a two-node front whose host answers
{ action: 'deny', reason: 'DENY_OUTSIDE' }(and, second case,{ action: 'hold', approvalId: 'approval-1' }). With the fix reverted at this tip both nodes are written handed, the warning log stays empty and completing one node never re-sends the other; the deny case fails onThe input did not match the regular expression /was not handed over: deny/. Input: ''.Rebase note. The branch is rebuilt on
26657c8abecause#1411landed in the same test file and made the old tip unmergeable (mergeable_state: dirty).#1411only addedreap()coverage (ephemeral.test.js:251-390); thedispatchregion and the#1399allow path are untouched, and this diff against the new base is byte-for-byte the same three files as before (+7/−1,+68,+1). The PASS ata69b54adis therefore void — this is a new tip and needs its own verdict.What changed
plugins/workflow/index.js(+7/−1):dispatchnow awaitsfb.bot.sendand normalises the two refusal records into{ ok: false, code: answer.action, reason: answer.reason }, keepingreasonfor the warn line#1399writes. Every other answer —{ action: 'allow' }, or the mock's{ ok: true }— is returned untouched, sohandOff(),settle(),reap()and the call sites are unchanged.plugins/workflow/test/ephemeral.test.js(+68): ahosted()helper that drives the realapply()wiring with a scriptedfb.bot.send, and three cases —denyandholdeach stay unhanded (the nextsettle()re-sends to the same Bot, onewarnper refusal naming the action, three warns after the second settle) andallowis still handed (no warn, no second send), which is the#1399path. They are appended after#1411'sreap()cases, so both sets run together.changelog.d/1407-workflow-dispatch-deny.fixed.md(+1): the user-visible half.What I ran
At
f149b26a, on the rebased tree:node --test plugins/workflow/test/ephemeral.test.js→# tests 12 / # pass 12 / # fail 0(#1388reap cases 7–9,#1389case 6,#1407cases 10–12).node --test plugins/workflow/test/*.test.js→# tests 34 / # pass 34 / # fail 0.DSH_HARNESS=/data/dsh/bot/workspace/lintenv node scripts/lint-plugins.mjs workflow→Found 0 warnings and 0 errors, thenpack-import plugins/workflow: packed @flybot/workflow imported.node .github/scripts/changelog.mjs check→changelog: 16 fragment(s) in changelog.d/ are well formed.GET /compare/26657c8a...dev3/1407-dispatch-deny-hold→status ahead,ahead_by 1, 3 files, exactly the three above (index.js +7/−1,ephemeral.test.js +68/−0, fragment+1/−0).Red without the source change
Reverting only
plugins/workflow/index.jsto the base26657c8aand keeping the new tests:not ok 10(deny) andnot ok 11(hold), both failingwas not handed over: deny/holdagainst an empty log, whileok 12(allow) still passes — so the two refusals are what the new cases pin, and#1399's allow path is not disturbed. Restoring the fix returns12/12.Not run
npm run verify, thecoresuite andds-bot-patches generate|check: this branch touches nocore/, nopatches/ds-bot/and notcore/client.js, so the third line ofcheckismain's and unaffected.node --testfor other plugins (social,tree,timeline): this bare tree has nods-botpackage installed, so they stop atERR_MODULE_NOT_FOUNDfor environment reasons; CI runs them (all green on this tip).plugins/workflowsuite was run asnode --test plugins/workflow/test/*.test.jsrather thannpm test --prefix plugins/workflow; same four files, no install needed.Risk
Low and plugin-local. The only behavioural change is on
dispatch's success path: adenyorholdnow reacheshandOff()as a refusal it already knows how to log and retry.allowis returned unchanged, so the#1399case still marks the node handed. A refused node is retried on the nextsettle()— that is the intended recovery, and it cannot loop within one settle because the loop walksrunningnodes once. The rebase itself carries no behaviour:#1411'sreap()code is untouched and its three cases still pass. No new config key, no permission, no API shape change.Docs-not-needed:is in the branch commit and here:dispatchkeeps answering in the vocabularyhandOffalready reads; no subsystem page describes this handshake.Checkpoint
{
"pr": 1416,
"claim": "Dev3",
"issue": 1407,
"summary": "A workflow step the host refuses with deny or hold is no longer written to run.handed. The dispatch call turns those two answers into a failure that carries the action as its code, so handOff treats them like the no-sender case it already handles. Each refusal logs one warning line and the step is re-sent to the same Bot on the next settle instead of sitting in a graph that shows work in flight. An allow answer is untouched, so a step the host accepts is still handed on its first send.",
"files": [
"plugins/workflow/index.js",
"plugins/workflow/test/ephemeral.test.js",
"changelog.d/1407-workflow-dispatch-deny.fixed.md"
],
"checks": {
"ran": "node --test plugins/workflow/test/*.test.js; DSH_HARNESS=... node scripts/lint-plugins.mjs workflow",
"result": "green",
"at": "f149b26a5cd749c1c02ee4853d05883cd6ba6fb5"
},
"next": "Awaiting a T2 PASS at this tip; the earlier PASS at a69b54a is void because #1411 forced this rebase."
}