Skip to content

feat(cards): let the human unblock a card, with a guarded re-block - #112

Merged
Robbertvermeulen merged 1 commit into
mainfrom
feat/human-unblock
Oct 15, 2026
Merged

Robbertvermeulen merged 1 commit into
mainfrom
feat/human-unblock

Conversation

@Robbertvermeulen

Copy link
Copy Markdown
Owner

A ready card with an open blocker never reaches next. When the human sees another route (e.g. task_5ae3: point 1 via a mu-plugin instead of a theme PR, which made the GH-token blocker ops_11b1 irrelevant), there was no way to hand the card back: the UI could not remove a blocker, and card edit --blocked-by changed it without any timeline trace.

What changed

  • Unblock: removeBlocker() in core, agentboard card unblock <id> <blocker> --reason ..., POST /api/cards/:id/unblock (pokes the runner like move/comment), and an × next to each open blocker chip on the card page that asks for a reason (suggestions: "Different route, see my comment", "No longer needed"). The blocker card itself is untouched; it may still matter for other work.
  • No silent blocker changes: new event kind blocker_removed (the existing event-table migration rebuilds the CHECK on init). card edit --blocked-by now writes blocker_added/blocker_removed for every change, with an optional --reason. The timeline renders both with their reason.
  • Guarded re-block: an agent re-adding a blocker that a human removed from that card must pass --reason, and core moves the card from ready/doing to needs_input in the same transaction (stamped with the session id). So the agent can disagree, but the card lands with the human instead of silently dropping out of next again.
  • AGENT.md rule 15: after a human blocker_removed, read the comments after it and try that route first; re-block only with a new reason.

askReason gained optional suggestions and okLabel; existing callers are unchanged.

Testing

npm run build passes. Against an isolated data dir:

  • DB created by the current main build, then init with this build → "event table rebuilt (event kinds brought up to date)".
  • Blocked ready card is absent from gate; after card unblock ... --as human it is in gate.
  • Agent card edit --blocked-by <same> --as agent without --reason → refused with an explanatory error; with --reason → blocker_added + ready → needs_input events, card in needs_input.
  • Human re-adding the same blocker is not guarded; unblocking a non-blocker errors.
  • UI (local serve, Playwright): × on the chip opens the reason dialog, suggestion fills it, Unblock removes the chip and the timeline shows blocker_removed by human ... (Different route, see my comment).

🤖 Generated with Claude Code

A ready card with an open blocker never reaches next, so a human who sees
another route could not hand it back to the agent: the UI had no way to
remove a blocker and `card edit --blocked-by` changed it silently.

- removeBlocker + `card unblock <id> <blocker> --reason` + POST
  /api/cards/:id/unblock (pokes the runner like move/comment), and an x on
  each open blocker chip in the card view that asks for a reason.
- New event kind blocker_removed; blocker changes via `card edit` now write
  blocker_added/blocker_removed too, never silently.
- Guard: an agent re-adding a blocker the human removed must pass --reason,
  and core moves the card to needs_input in the same transaction, so the
  human decides instead of the card silently dropping out of next again.
- AGENT.md rule 15: try the human's route first after a blocker_removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Robbertvermeulen
Robbertvermeulen merged commit bd0a953 into main Oct 15, 2026
2 checks passed
@Robbertvermeulen
Robbertvermeulen deleted the feat/human-unblock branch October 15, 2026 10:56
github-actions Bot pushed a commit that referenced this pull request Oct 15, 2026
# [0.23.0](v0.22.2...v0.23.0) (2026-10-15)

### Features

* **cards:** let the human unblock a card, with a guarded re-block ([#112](#112)) ([bd0a953](bd0a953)), closes [#token](https://github.com/Robbertvermeulen/agentboard/issues/token)
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 0.23.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

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.

1 participant