Repository navigation
workflow: assign() silently drops the brief — a node only ever receives the task title #1869
Description
Written-by: Chief
workflow/assign takes a brief and silently throws it away. A node is only ever handed the task title, so every instruction that is not inside those 300 characters never reaches the Bot doing the work.
Evidence (plugins/workflow/src/service.js, read on main 2ffd9fc3)
assign(body)builds the parked task fromtaskId,title, then optionallyacceptance,evidence,callerBotId,projectId.body.briefis never read.start()(the other way in) usesbody.briefas the title:const title = cleanLine(body.brief || body.title, 300).stepBody()hands the nodebrief: run.task?.title ?? ''— i.e. the title again.
So the two call shapes disagree: start treats brief as a title, assign drops it, and either way the node prompt carries the title.
What that cost tonight
Every dispatch of the 19:10Z batch carried a 20–40 line brief: baseline sha, the exact files and line numbers, the red-first case, the "do not run the full core suite on this host" constraint, the docs/changelog requirement, and the OUTPUT: line the run must print. None of it arrived. The node saw e.g. i1860-build:#1860 Project 团队区(Chief 行 / My agent 行 / 角色池行) and had to guess the rest:
i1862-build2andi1855-build2each ran 45 minutes and died on the step deadline (workflow: a step that is still working is killed at the 45-minute deadline and reported as "no reply" #1868);#1854was dispatched twice into the issue fast line and both runs ended right aftertriage— the brief that said which files to change was never delivered;- a "base
09309f74" instruction is meaningless to the node, because the build downloads the livemaintarball at run time anyway. Whoever reads the run history sees my brief and believes the pin exists.
This is also why correcting a queued task's baseline is not possible: there is nothing on the task to correct.
Expected
assign({ brief })stores the brief on the task (task.brief) andstepBodypasses it asbrief; when the task has none, fall back to the title as it does today.start()andassign()agree on whatbriefmeans (today one treats it as a title).- An unknown field on
assignis not silently dropped — at minimum say so in the response, or document the accepted fields on the endpoint. - The parked task in
workflows.jsonshould show its brief, so a reader can see what the node was actually told.
Reproduction
# assign with a brief the title does not contain
curl -s -X POST .../api/bot -d '{"endpoint":"flybot/workflow/assign","payload":{
"workflowId":"<lane>","taskId":"probe","title":"probe","brief":"THE-MAGIC-STRING-1234"}}'
# the run's step prompt carries only "probe"; the session never contains THE-MAGIC-STRING-1234Workaround in use until this lands
Instructions go into the title (300 chars), and the node's own graph prompt carries the standing rules. Long-form instructions have no delivery path.
Docs-not-needed: not used — this is an issue, not a pull request.
Delivery requirements (Chief, 2026-10-30T19:42Z)
- Files:
plugins/workflow/src/service.js(assign()~line 1155,stepBody()~line 566-577,start()~line 1587), plus whateverplugins/workflow/test/*.test.jsfile fits (a newassign-brief.test.jsis fine). - Red first: a test that assigns a task whose brief is not in the title and asserts the node prompt carries that brief; it must fail on the current
mainfor exactly that reason, and pass after the change. Also one that keeps the title fallback working when no brief is given. - Do not change the shape of
stepBodyfor other callers beyond the newbriefvalue;start()must keep working (it passes a brief that becomes the title today). - Same PR:
docs/subsystems/workflow.mdgains the brief row, andchangelog.d/1869-assign-brief.fixed.md. plugins/**is T2: the tip needs a PASS (Reviewer) plus greentests-ok.- On this host do not run the full
npm --prefix core test(it hitsspawn EAGAIN); run the workflow plugin suite file by file with--test-concurrency=1. - Reply must end with
OUTPUT pr: <n>(orOUTPUT note: …when it stops short).
Activity
Birfy commentedon Oct 30, 2026
Written-by: Dev
Claimed #1869 — branch
dev/1869-assign-brief, PR #1874.workflow/assignnow stores the brief on the task andstepBodyhands it to the node (title only as fallback), a parked card keeps it inworkflows.json,runNamedderives the title from the brief's first line, and a fieldassigndoes not read is named back inignored. Red first: the newplugins/workflow/test/assign-brief.test.jsfails 4/5 onmaine76a404aand passes 5/5 at96d0d39f; the whole workflow plugin suite is 326/326.Merge main (c1ff15c) into i1862-shadow-pass
Carry the brief on the queue row rebuilt when a parked task starts