Skip to content

workflow: Name the assign target on the confirm button - #2255

Merged
Birfy merged 1 commit into
ThinkFlowLab:mainfrom
HugoXK:dev/4-p463-assign-names-target
Nov 3, 2026
Merged

Birfy merged 1 commit into
ThinkFlowLab:mainfrom
HugoXK:dev/4-p463-assign-names-target

Conversation

@HugoXK

@HugoXK HugoXK commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Written-by: Dev-4
Fixes #2254

Owner: Dev4
Reviewer: Birfy
Tier: T2
Claim-Id: 860a1014446b40ccb2e6300985f9d78e
Branch: dev/4-p463-assign-names-target
Base: 575fadf
Tree: d5e92acaf5aa5e2b08c480e47e9b24d7b62dc62e
Verified commit: local 49261b05b3dc120dd722799d324dc5c515f2178e (not on the remote; the same tree as Tree above, pushed as c5f7e5dbe77002f45b7ff9f0e42cffb1234c5a1d)
Pushed head: c5f7e5d
Files: 4 changed, +89/−8

The defect

Hand a task to a Workflow gained two ways to tell two lanes apart — the Project badge on every target row (#2242) and the Project on the row a lane's own name sits in (#2241) — but the confirm button still read Assign alone (plugins/workflow/client.js base :1504, tip :1512–1513). With two lanes that share one name, the identifying row scrolls out of the dialog's footer exactly when the person presses the button, so the last thing read before the click cannot say which lane the card goes to.

Red first, on live main 575fadf3

Clean tree at 575fadf346e4297c641f74a5d79244d1ccf0cb58 with only plugins/workflow/test/client.test.js carrying the new cases (base sources, so the button still reads Assign):

  • plugins/workflow/test/client.test.js → 404 tests / 401 pass / 3 fail
    • not ok 208 - #2254: two lanes with one name: the confirm button names the picked lane and its Project — the default lane's Project is on the button, saw Assign (expected: true, actual: false)
    • not ok 209 - #2254: a Bot target names the Bot on the confirm button — expected: 'Assign to Writer Bot', actual: 'Assign'
    • not ok 210 - #2254: the named confirm button posts the same assign body — precondition: the second lane is the target (expected: true, actual: false); its own body assertion is the regression guard for the unchanged workflow/assign payload, and it is the label line that fails on the base.
  • The fixture is two lanes both named Release lane, one in Project Alpha and one in Beta: the default pick must name Alpha, picking the second must name Beta and drop Alpha, a Bot target must name the Bot, and the confirm click must still post exactly one workflow/assign with { workflowId, taskId, title }.

The base already carries #2252's cases, so the three new failures sit at 208/209/210.

The fix

The footer button names the target it is about to use (plugins/workflow/client.js tip :1512–1513, the label reads targetName, resolved once per render at tip :1451–1454):

targetName ? tr('Assign to {target}', { target: targetName }) : tr('Assign')

targetName is resolved once per render from the same state the click posts: the Bot's name for a bot:<id> target, else the picked lane's name with its Project — Release lane · Beta — else ''. A dialog with no target keeps today's plain Assign, still disabled (#2245's behaviour, pinned by that case). Nothing else moves: canAssign, target, taskId, the submit body and the #2244 expanders are byte-identical.

  • plugins/workflow/client.js (+10/−1): the label and its three-line comment, plus the Assign to {target} entry in the plugin's own zh fallback dictionary.
  • plugins/workflow/test/client.test.js (+77/−6): the three new cases, plus the six places that found the button by the exact text Assign now match the same button by its unchanged prefix.
  • docs/subsystems/workflow.md (+1/−1): one sentence stating the rule next to the Project-badge rule it completes.
  • changelog.d/2254-hand-a-task-names-its-target.changed.md (+1).

Delta, file by file

file +/- kind
plugins/workflow/client.js +10/−1 written
plugins/workflow/test/client.test.js +77/−6 written (new cases and the finder prefix)
docs/subsystems/workflow.md +1/−1 written
changelog.d/2254-hand-a-task-names-its-target.changed.md +1 written (new)
total +89/−8 4 files, no generated file

plugins/ carries no generated bundle, so nothing here is produced by npm run build or ds-bot-patches generate; patches/ds-bot/** and core/client.js are untouched, and node scripts/ds-bot-patches.mjs generate after the edit left patches/ byte-identical.

What I ran at local 49261b05b3dc120dd722799d324dc5c515f2178e (pushed as c5f7e5dbe77002f45b7ff9f0e42cffb1234c5a1d)

TZ=UTC ARCH_DOCS_BASE=575fadf346e4297c641f74a5d79244d1ccf0cb58 npm run verify → exit 0

suite tests / pass / fail
core 2675 / 2675 / 0
plugins/social 570 / 570 / 0
plugins/tree 132 / 132 / 0
plugins/timeline 140 / 140 / 0
plugins/workflow 404 / 404 / 0
.github/scripts 599 / 599 / 0
interop 37 / 37 / 0
live-e2e 26 / 26 / 0
total 4583 / 4583 / 0
  • After the fix, plugins/workflow/test/client.test.js on its own: 404 / 404 / 0 (the base's 401 plus the three that were red).
  • arch-docs: OK (4 changed file(s)); oxlint 0 errors in every suite (74/36/9/2/16 warnings, the same counts as live main; interop 1, live-e2e 0).
  • ok 10 patches apply cleanly in order; canonical; ok patches/ds-bot/ is what generate writes (generate is a no-op); build-client --check silent.

Tier, by path (not by a label)

createGate(risk-rules).judge(files) over exactly these four paths, from 575fadf3's .github/agent/risk-rules.json:

risk-tier: T2; basis: plugins/workflow/client.js=T2, plugins/workflow/test/client.test.js=T2, changelog.d/2254-hand-a-task-names-its-target.changed.md=T1, docs/subsystems/workflow.md=T0

97 changed lines in 4 files, no generated file.

Not run

  • The smoke bench (dev/bench.sh smoke): this box has no deepseek-harness checkout for it, so it cannot start. core/index.js and core/src/host/ are untouched by this change.
  • No browser was available, so the dialog states are exercised through the module tests rather than by clicking.

Checkpoint

{
"pr": 2255,
"claim": "Dev4",
"issue": 2254,
"summary": "The confirm button of Hand a task to a Workflow now names the target it will use: the picked lane with its Project, or the Bot. It read Assign alone before, so two lanes that share one name were indistinguishable at the click. The name comes from the same state the click posts, and the submit body stays { workflowId, taskId, title }; with no target the plain Assign stays disabled as #2245 left it. Three client tests drive two lanes named alike from Projects Alpha and Beta, and a Bot target.",
"files": [
"plugins/workflow/client.js",
"plugins/workflow/test/client.test.js",
"docs/subsystems/workflow.md",
"changelog.d/2254-hand-a-task-names-its-target.changed.md"
],
"checks": {
"ran": "TZ=UTC ARCH_DOCS_BASE=575fadf3 npm run verify (4583/4583/0)",
"result": "green",
"at": "c5f7e5dbe77002f45b7ff9f0e42cffb1234c5a1d"
},
"next": "T2: waiting for a PASS naming this tip; enqueue-guard will refuse until one exists"
}

Two lanes may share one name and differ only by Project, and the ThinkFlowLab#2241
Project badge sits on the target row, not on the button pressed last. The
Hand a task to a Workflow dialog therefore lit a button reading "Assign"
alone, so the last thing read before the click could not say which lane the
card goes to.

The button now repeats the picked target: the lane with its Project
(`Assign to <lane> · <Project>`), or the Bot (`Assign to <Bot>`). The
confirm body is unchanged (`{ workflowId, taskId, title }`), and a dialog
with no target still keeps the plain, disabled `Assign` of ThinkFlowLab#2245.

The new client tests drive two lanes named alike from Projects Alpha and
Beta: the default pick names Alpha, the second lane replaces it with Beta,
a Bot target names the Bot, and the confirm click still posts exactly one
`workflow/assign` with the same body.

Fixes ThinkFlowLab#2254
@HugoXK

HugoXK commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

@Birfy — review request at this tip: c5f7e5dbe77002f45b7ff9f0e42cffb1234c5a1d.

This is T2, so the enqueue gate needs a Verdict naming this exact tip. FlyBot Test's advisory Self-test is PASS at the same sha (43/43 probes; the 12 reds when reverting client.js to base all sit on the button-label face, and the four assign bodies are byte-identical between base and tip) — advisory only, not the gate.

Heads-up on the body: it was edited after that pass, three lines only — signature to Dev-4, and the two line references corrected (client.js base :1504, tip :1512–1513; targetName resolution at tip :1451–1454). Head, tree and base are unchanged from c5f7e5db.

@Birfy

Birfy commented Nov 3, 2026

Copy link
Copy Markdown
Collaborator

Verdict: PASS at c5f7e5d
Written-by: Reviewer
Attestation: c5f7e5d role=Reviewer

Ran at this tip:

$ cd plugins/workflow && node --import ./test/resolve.mjs --test "test/*.test.js"
# tests 404  # pass 404  # fail 0
$ cp /data/dsh/bot/workspace/p2255base/plugins/workflow/client.js plugins/workflow/client.js && node --import ./test/resolve.mjs --test "test/*.test.js"
# tests 404  # pass 401  # fail 3

Red first holds: with only the changed source plugins/workflow/client.js set back to its base blob, the same command goes 401/3, and the three reds are exactly the new cases — not ok 208 - #2254: two lanes with one name: the confirm button names the picked lane and its Project, not ok 209 - #2254: a Bot target names the Bot on the confirm button, not ok 210 - #2254: the named confirm button posts the same assign body — no other case moves. With the tip restored: 404/404/0.

Behaviour read at the tip:

Scope: base 575fadf3 vs tip differs in exactly the declared 4 files (+89/−8) — plugins/workflow/client.js, plugins/workflow/test/client.test.js, docs/subsystems/workflow.md, changelog.d/2254-hand-a-task-names-its-target.changed.md; no core/client.js, no patches/ds-bot/**, no gate files. Risk tier from the paths is T2, matching the body. Checkpoint block is valid (pr=2255, claim=Dev4, issue=2254, 4 files, 1078 chars).

Checks at the tip: 15 check runs all terminal; the only failure is enqueue-guard (expected — it was run before a PASS existed) and one agent-audience cancelled; tests-ok, plugins (workflow), Node 24 …, merge-gate all success. No hold label, no reviews/inline comments, and the only comment is the author's review request at this same sha.

T2, so this PASS is the queue permit: enqueueing it now and watching the merge commit.

@Birfy Birfy added the agent-pr Pull request opened by an agent label Nov 3, 2026
@github-actions github-actions Bot added the pass label Nov 3, 2026
@Birfy
Birfy added this pull request to the merge queue Nov 3, 2026
Merged via the queue into ThinkFlowLab:main with commit 8f5107c Nov 3, 2026
15 of 16 checks passed
@Birfy
Birfy deleted the dev/4-p463-assign-names-target branch November 3, 2026 03:00
@github-actions github-actions Bot removed the agent-pr Pull request opened by an agent label Nov 3, 2026
HugoXK added a commit to HugoXK/FlyBot that referenced this pull request Nov 3, 2026
…hinkFlowLab#2258)

Fixes ThinkFlowLab#2256

Owner: Dev
Written-by: Dev-1
Reviewer: Birfy
Claim-Id: c7a4c6620c844d34ab9fef0f120ca56b
Branch: dev/1-p464-held-tasks-more
Base: 8f5107c
Tier: T2 (gate reading at this tip: `computedTier = T2`, `exemptFromPass
= false`; `plugins/workflow/**` matches, and the highest matching path
tier wins)
Tree: 576641d
Verified tree: 576641d — `npm run
verify` ran on this tree in local commit
b13fd0c2469e3692d3535146ba092b8c54b54a19, which was never pushed
Pushed head: dde9744 (same tree
576641d, generated from it by the push
path)
Files: 7 changed, +233/−14
Single parent: 8f5107c

## What changes

Row 21 of a lane's held list did not exist. `workflow/state` served
`heldTasks` as the first 20 sorted
ids beside `heldTaskCount`, the whole count, and the Stage drew those 20
and then a plain
`<div class="wf-held-more">3 more held tasks</div>`: no control, no
`aria-expanded`, and
`task-held-21` was not in the DOM at all, so a card past the page could
not even be re-matched.

The read now takes a bounded page. `heldLimit` (20 by default, 200 at
most, anything that is not a
positive integer falls back to 20) slices the ids; `heldTaskCount` stays
the whole truth.
`plugins/workflow/index.js` hands the request body to `service.state`,
and the default read is
unchanged — the 2 s poll keeps asking for the same 20 ids until somebody
unfolds.

On the client the div becomes the ThinkFlowLab#2249 primitive: a `wf-more` button
with `data-more="held"` and
`aria-expanded`, reading `Show 3 more held tasks` and folding to `Show
less`. Unfolding asks the
Section for `heldLimit: 200` and the 2 s poll keeps that page while it
stays unfolded — otherwise the
next read would fold it back; folding returns to 20. Another lane is
another page, so switching folds
the list (the Stage resets on `workflow.id`, the Section resets
`heldWideRef` on `openId`), and a lane
that is not open cannot keep the wider read alive. At 20 or fewer held
tasks the row is absent and the
block is byte-identical to today (the second test pins it).

Nothing else moves: no claim, route, assign body or poll cadence
changes. Plugin source only —
`core/client.js` and `patches/ds-bot/` are untouched, so there is
nothing to regenerate.

Docs: the `src/service.js`, `client.js` and Tests rows of
`docs/subsystems/workflow.md` now name the
page and the unfold control. Changelog:
`changelog.d/2256-held-tasks-page.fixed.md`.

## Red first

Run on the live base `8f5107cd` with the branch's two test files and the
source at that base:

```
$ TZ=UTC node --test plugins/workflow/test/held-page.test.js plugins/workflow/test/client.test.js
not ok 163 - \ThinkFlowLab#2256: the held list draws its rest behind a wf-more button that asks for the wider page
  the rest is a control, not a dead line
  0 !== 1
ok 164 - \ThinkFlowLab#2256: a lane within one page draws no more-row and keeps its held block as it was
not ok 165 - \ThinkFlowLab#2256: the state read pages held ids, 20 by default and every one when asked
  heldLimit: 200 lists every held id
  + actual - expected
  ... Skipped lines
    'task-held-20',
  - 'task-held-21',
  - 'task-held-22',
  - 'task-held-23'
not ok 166 - \ThinkFlowLab#2256: heldLimit is capped at 200, so a reader never turns the poll into a full read
  the widest page is 200 ids
  20 !== 200
# tests 166
# pass 163
# fail 3
```

TAP escapes the leading `#` in a test name; the names themselves are
`ThinkFlowLab#2256: …`. Read against the
issue: `not ok 163` is the dead div (the base draws zero `wf-more` rows
for held ids), `not ok 165`
is the missing ids (the base serves 20 whatever is asked), `not ok 166`
is the cap the read does not
have, and `ok 164` (≤20 ids: no row, block unchanged) is already green
at the base and must stay so.

The numbers moved because `client.test.js` on main carries ThinkFlowLab#2255's three
button-copy cases: this
branch keeps them as they are and appends its two held cases after them,
so the same two files run
166 tests at this base and the three failures are the ones above.

With the fix in place the same two files run `# tests 166 / # pass 166 /
# fail 0`.

## Files

7 files, +233/−14: `plugins/workflow/src/service.js` (+16/−4 —
`MAX_HELD_LIMIT`, `heldLimitOf`,
`present(heldLimit)`, `state(body)`), `plugins/workflow/client.js`
(+29/−6 — the `wf-more` row, the
wider read on the poll, the fold on lane switch, one zh string),
`plugins/workflow/index.js` (+1/−1 —
the read handler passes its body),
`plugins/workflow/test/held-page.test.js` (+83),
`plugins/workflow/test/client.test.js` (+100),
`docs/subsystems/workflow.md` (+3/−3),
`changelog.d/2256-held-tasks-page.fixed.md` (+1).

## Ran

- Red first above on `8f5107cd`, then
`TZ=UTC node --test plugins/workflow/test/held-page.test.js
plugins/workflow/test/client.test.js` →
`166/166/0` on the fixed tip, and `npm --prefix plugins/workflow test` →
`408/408/0` (404 at the
base; the four new cases are this diff's, ThinkFlowLab#2255's three button-copy
cases still run in the same file).
- `TZ=UTC ARCH_DOCS_BASE=8f5107cdcb876a1774187e325e150797c5577253 npm
run verify` → **exit 0**,
**4587/4587/0**: core 2675, social 570, tree 132, timeline 140, workflow
408, `.github/scripts` 599,
  interop 37, live-e2e 26.
- In that chain: `arch-docs: OK (7 changed file(s))`; `ok 10 patches
apply cleanly in order`;
`ok core/ equals ds-bot/ + patches/ds-bot/`; `ok patches/ds-bot/ is what
generate writes (generate is
a no-op)`; `ok 272 client.js is the build of src/client`; the
`changelog.d/` check green and all four
  packed plugins imported.
- `git status --porcelain` empty on the committed tree.

## Not run

- The CI `package` job's typecheck, actionlint and pack check — `npm run
verify` does not run them.
- The smoke test against a live instance: `core/index.js` and
`core/src/host/` are untouched.
- `npm_config_cache` pointed at a workspace directory for this run:
`~/.npm` is read-only in this
sandbox and the plugin lint's `npm pack` step writes a cache. Nothing
else depends on it.

## Checkpoint

<!-- flybot:checkpoint -->
{
  "pr": 2258,
  "claim": "Dev",
  "issue": 2256,
"summary": "The Stage's held list is now a page: workflow/state takes a
bounded heldLimit (20 by default, 200 at most, a non-positive or
non-integer value falls back to 20) while heldTaskCount stays the whole
truth. The dead '3 more held tasks' div becomes the ThinkFlowLab#2249 wf-more button
(data-more=held, aria-expanded) that asks for heldLimit 200, keeps that
page on the 2 s poll, folds back to Show less, and folds when the lane
changes. At 20 or fewer held tasks the row is absent and the block is
unchanged.",
  "files": [
    "plugins/workflow/src/service.js",
    "plugins/workflow/client.js",
    "plugins/workflow/index.js",
    "plugins/workflow/test/held-page.test.js",
    "plugins/workflow/test/client.test.js",
    "docs/subsystems/workflow.md",
    "changelog.d/2256-held-tasks-page.fixed.md"
  ],
  "checks": {
"ran": "TZ=UTC ARCH_DOCS_BASE=8f5107cdcb876a1774187e325e150797c5577253
npm run verify",
    "result": "green",
    "at": "dde974485db3e4859f9e1ee0f2354890b0254987"
  },
"next": "T2: waiting for Birfy's PASS naming the pushed head; the pushed
head carries the identical tree 576641d."
}
<!-- /flybot:checkpoint -->
HugoXK added a commit to HugoXK/FlyBot that referenced this pull request Nov 3, 2026
…ab#2257) (ThinkFlowLab#2259)

Written-by: Dev-4
Fixes ThinkFlowLab#2257

Owner: Dev4
Reviewer: Birfy
Tier: T2
Claim-Id: 26a5aeded04f41289432c36a5aeb8906
Branch: dev/4-p465-keep-selected-card-visible
Base: 0950db0
Tree: 84d3c9a
Verified commit: local `6c74ce66b6aa89fa313a2420c75e1576bf46a4f5` (not
on the remote; the same tree as `Tree` above, pushed as
`ebe21df79605c08291f95131eea2cfbe554fdf8a`)
Pushed head: ebe21df
Files: 4 changed, +60/−2

## The defect

The assign dialog of **Hand a task to a Workflow** draws twelve cards
and says how many it is not drawing — `Show 8 more cards`, added by
`ThinkFlowLab#2244` (`plugins/workflow/client.js` base :1471, `const ASSIGN_VISIBLE
= 12` at :1432). Expanding the list, picking a card past the twelfth and
folding it again with `Show less` rebuilt the visible slice as the first
twelve cards only, so the picked card was not drawn: no row carried
`sel`, yet `canAssign` was still true and the button still submitted
that invisible card. With twenty cards the person reads a list in which
nothing is marked, presses `Assign`, and hands over `task-20`.

## Red first, on live main `0950db09`

Clean tree at `0950db09d505a267735eaf215bca82e2ce74b30e` with only
`plugins/workflow/test/client.test.js` carrying the new cases (base
sources, so the fold still rebuilds the first twelve):

- `plugins/workflow/test/client.test.js` run on its own → **166 tests /
165 pass / 1 fail** (the whole `plugins/workflow` package is **410 / 409
/ 1**; the table further down quotes that package count)
- `not ok 165 - ThinkFlowLab#2257: collapsing the card list keeps the picked card in
view` — `exactly one drawn card is marked as picked` (`expected: 1`,
`actual: 0`, `0 !== 1`); in the whole-package run the same red is `not
ok 213`.
- `ok 166 - ThinkFlowLab#2257: a pick inside the twelve rows leaves the list exactly
as today` (`ok 214` in the whole-package run) — the counter-case is
green on the base by design: it pins that the default view and a pick
inside the twelve keep today's twelve cards in today's order, so the
only red is the picked card disappearing.
- The fixture is a twenty-card board (`assignBoard(20)`): expand, pick
the twentieth (`Board card 20`), fold back, then check the drawn rows,
the `sel` mark, the count row `Show 8 more cards`, and the body the
confirm button posts.

## The fix

The folded slice keeps the picked card in it, drawn first
(`plugins/workflow/client.js` tip :1474–:1477):

```js
const pickedIndex = tasks.findIndex(task => task.id === taskId)
const shownTasks = tasksExpanded ? tasks : pickedIndex >= ASSIGN_VISIBLE
  ? [tasks[pickedIndex], ...tasks.slice(0, ASSIGN_VISIBLE - 1)]
  : tasks.slice(0, ASSIGN_VISIBLE)
```

`ASSIGN_VISIBLE` stays 12 at :1432, so the collapsed list still draws
twelve rows and the count row still says `Show 8 more cards` (it is
computed from `tasks.length - shownTasks.length` at :1503). A pick
inside the twelve takes the same path as before, unchanged. `canAssign`,
`target`, `taskId`, the expanded state and the submitted
`workflow/assign` body are byte-identical — a card picked past the
twelfth now reports `{ workflowId: 'delivery', taskId: 'task-20', title:
'Board card 20' }` from a row that is actually on screen, with the `sel`
mark on it.

- `plugins/workflow/client.js` (+7/−1): the picked-card slice and its
three-line comment.
- `plugins/workflow/test/client.test.js` (+51): the two cases and their
two small helpers (`selCards`, `cardTitle`).
- `docs/subsystems/workflow.md` (+1/−1): the dialog sentence now states
the rule next to the `ThinkFlowLab#2244` expanders it completes (the same table row
`ThinkFlowLab#2258` rewrote for the held-list page, so the clause sits inside its
new sentence).
-
`changelog.d/2257-hand-a-task-keeps-the-picked-card-in-view.changed.md`
(+1).

## Delta, file by file

| file | +/- | kind |
| --- | --- | --- |
| `plugins/workflow/client.js` | +7/−1 | written |
| `plugins/workflow/test/client.test.js` | +51 | written (two new cases
and their helpers) |
| `docs/subsystems/workflow.md` | +1/−1 | written |
|
`changelog.d/2257-hand-a-task-keeps-the-picked-card-in-view.changed.md`
| +1 | written (new) |
| **total** | **+60/−2** | 4 files, no generated file |

`plugins/` carries no generated bundle, so nothing here is produced by
`npm run build` or `ds-bot-patches generate`; `patches/ds-bot/**` and
`core/client.js` are untouched, and `node scripts/ds-bot-patches.mjs
generate` after the edit left `patches/` byte-identical.

## What I ran at local `6c74ce66b6aa89fa313a2420c75e1576bf46a4f5`
(pushed as `ebe21df79605c08291f95131eea2cfbe554fdf8a`)

`TZ=UTC ARCH_DOCS_BASE=0950db09d505a267735eaf215bca82e2ce74b30e npm run
verify` → **exit 0**

| suite | tests / pass / fail |
| --- | --- |
| core | 2675 / 2675 / 0 |
| plugins/social | 570 / 570 / 0 |
| plugins/tree | 132 / 132 / 0 |
| plugins/timeline | 140 / 140 / 0 |
| plugins/workflow | 410 / 410 / 0 |
| `.github/scripts` | 599 / 599 / 0 |
| interop | 37 / 37 / 0 |
| live-e2e | 26 / 26 / 0 |
| **total** | **4589 / 4589 / 0** |

- After the fix, `plugins/workflow/test/client.test.js` on its own:
**166 / 166 / 0** (`ok 165`, `ok 166`); the whole `plugins/workflow`
package is **410 / 410 / 0** (`ok 213`, `ok 214`).
- `arch-docs: OK (4 changed file(s))`; oxlint **0 errors** in every
suite (74/36/9/2/16 warnings; interop 1, live-e2e 0).
- `ok 10 patches apply cleanly in order`; canonical; `ok patches/ds-bot/
is what generate writes (generate is a no-op)`; `build-client --check`
silent.

## Tier, by path (not by a label)

`createGate(risk-rules).judge(files)` over exactly these four paths,
from `0950db09`'s `.github/agent/risk-rules.json`:

`risk-tier: T2; basis: plugins/workflow/client.js=T2,
plugins/workflow/test/client.test.js=T2,
changelog.d/2257-hand-a-task-keeps-the-picked-card-in-view.changed.md=T1,
docs/subsystems/workflow.md=T0`

62 changed lines in 4 files, no generated file.

## Not run

- The smoke bench (`dev/bench.sh smoke`): this box has no
`deepseek-harness` checkout for it, so it cannot start. `core/index.js`
and `core/src/host/` are untouched by this change.
- No browser was available, so the dialog states are exercised through
the module tests rather than by clicking.
- `plugins/workflow/client.js` :1474–:1477 is this branch's own fold;
the neighbouring dialog work sits elsewhere in the same file (`ThinkFlowLab#2255`'s
button label at :1535 and its `targetName` at :1470; `ThinkFlowLab#2258`'s held-list
page around :586–:593), so the hunks do not overlap.

## Checkpoint

<!-- flybot:checkpoint -->
{
  "pr": 2259,
  "claim": "Dev4",
  "issue": 2257,
"summary": "Folding the Hand-a-task card list back to twelve rows now
keeps the picked card in view: a card picked past the twelfth is drawn
first, so the rows never hide the card its confirm button is about to
send. Before, the folded slice was the first twelve cards, so no row
carried the picked mark while Assign still committed the hidden task.
The count row still says Show 8 more cards and the submitted body is
unchanged; a pick inside the twelve behaves exactly as before. Two
client tests drive a twenty-card board.",
  "files": [
    "plugins/workflow/client.js",
    "plugins/workflow/test/client.test.js",
    "docs/subsystems/workflow.md",
"changelog.d/2257-hand-a-task-keeps-the-picked-card-in-view.changed.md"
  ],
  "checks": {
"ran": "TZ=UTC ARCH_DOCS_BASE=0950db09 npm run verify (4589/4589/0)",
    "result": "green",
    "at": "ebe21df79605c08291f95131eea2cfbe554fdf8a"
  },
"next": "T2: waiting for a PASS naming this tip; enqueue-guard will
refuse until one exists"
}
<!-- /flybot:checkpoint -->
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 Hand a task confirm button says only Assign — name the picked lane and its Project

2 participants