Skip to content

chore(kanban): tier-2 batch salvage — doctor, started_at, parent-guard, latest_summary, selects, linked-children (closes #18344 #20022 #19473 #19828 #19743 #20251 #20019)#20448

Merged
teknium1 merged 8 commits into
mainfrom
hermes/hermes-9ddf5187
May 6, 2026
Merged

chore(kanban): tier-2 batch salvage — doctor, started_at, parent-guard, latest_summary, selects, linked-children (closes #18344 #20022 #19473 #19828 #19743 #20251 #20019)#20448
teknium1 merged 8 commits into
mainfrom
hermes/hermes-9ddf5187

Conversation

@teknium1
Copy link
Copy Markdown
Contributor

@teknium1 teknium1 commented May 5, 2026

Tier-2 batch salvage of six kanban contributor PRs. All narrow, well-tested, and non-overlapping with each other after careful rebase.

What each commit does

#18344 (@suncokret12) — fix(doctor): report Kanban worker tools as runtime-gated

  • Teaches hermes doctor to treat the kanban_* worker tools as runtime-gated rather than missing, so users with kanban installed don't see spurious "tool not found" warnings.
  • 2 files, +66/-5. Clean cherry-pick.

#20022 (@LeonSGP43) — partial salvage: fix(kanban): accept created_cards linked as child of completing task

  • The original PR added a second implementation of the hallucination gate shipped in PR feat(kanban): hallucination gate + recovery UX for worker-created-card claims (closes #20017) #20232. Instead of wholesale adoption, salvaged the substantive improvement: widen _verify_created_cards to also accept cards explicitly linked as children of the completing task (not just cards where created_by matches). Matters for orchestrator flows where a specifier creates a card and the worker later adopts it via kanban_create(parents=[current]).
  • 2 files, +64/-11 (overlap-adjusted). Added new test_complete_accepts_cross_worker_card_when_linked_as_child regression test.

#19473 (@mioimotoai-lgtm) — fix(kanban): measure max runtime from current run

  • Bug: enforce_max_runtime read from tasks.started_at (lifetime timestamp), so a task that timed out once and got re-claimed would immediately re-timeout against its original start time instead of the new run's start time. Infinite-immediate-timeout loop.
  • Fix: JOIN on task_runs and read COALESCE(r.started_at, t.started_at) so per-attempt elapsed is measured from the active run. Preserves tasks.started_at semantics (first-ever-started).
  • Picked over competing [codex] Fix Kanban retry runtime clock #19828 which destructively overwrote tasks.started_at on every claim.
  • 3 files, +75/-9.

test-fix on top of #19473test(kanban): backdate task_runs.started_at alongside tasks.started_at

#19743 (@SimbaKingjoe / daixin1204) — fix(kanban): prevent child task dispatch when parent is not done

  • Dashboard's _set_status_direct (triggered by drag-to-Ready) didn't check parent dependencies. A user could drag a child task to ready with an incomplete parent; the dispatcher would then happily spawn it. The guard existed in recompute_ready but not on direct status writes.
  • Fix: parent-done check in _set_status_direct, returns 409 if any parent isn't done.
  • 2 files, +42/-8.

#20251 (@Brecht-H) — feat(kanban): surface task_runs.summary on dashboard cards + kanban show

#20019 (@LeonSGP43) — fix(kanban): wire dependency selects

  • Task drawer's add-parent / add-child dropdowns had inline onChange handlers that didn't thread through the shared selectChangeHandler helper used elsewhere. Selections didn't land on state, so the action buttons stayed disabled.
  • Fix: swap to selectChangeHandler(setNewParent/setNewChild) matching the rest of the codebase.
  • 2 files, +21/-6. Static bundle-inspection regression test preserves the fix.

Merge conflict resolutions

Validation

Result
Full kanban suite 438/438 pass
Attribution 6 contributors preserved via rebase-merge
AUTHOR_MAP entries added for suncokret12, mioimotoai-lgtm

Closures

Rebase-merge recommended to preserve per-commit contributor attribution.

Co-authored-by: suncokret12 suncokret@protonmail.com
Co-authored-by: LeonSGP43 cine.dreamer.one@gmail.com
Co-authored-by: 澪 / Mio mio.imoto.ai@gmail.com
Co-authored-by: daixin1204 daixin1204@gmail.com
Co-authored-by: Brecht-H 73849650+Brecht-H@users.noreply.github.com

suncokret12 and others added 8 commits May 5, 2026 15:14
Widens _verify_created_cards to also accept ids that are children of the
completing task in task_links. Previously we only accepted cards where
created_by matched the completing task's assignee, which was too strict
for legitimate orchestrator flows: a specifier creates a card (so
created_by=specifier, not worker), then a worker picks it up and passes
parents=[current_task] to kanban_create. The explicit link proves the
relationship and should be trusted.

Salvaged from #20022 @LeonSGP43 (full PR superseded by #20232 +
this patch; the linked-children relaxation was the portable
improvement).
After #19473 landed (enforce_max_runtime reads from task_runs.started_at
rather than tasks.started_at), a regression test added earlier still
only backdated the tasks column. Backdate both so the test is robust
regardless of which column the enforcer reads from.
Add parent dependency guard to _set_status_direct so dragging
a task to the ready column is rejected (409) when its parents
are not all done. Previously the guard only existed in
recompute_ready, allowing direct status writes via the
dashboard API to bypass the dependency engine.

Root cause: after reclaiming stale workers, both T3 and T4
were set to ready via dashboard status writes in quick
succession, causing the writer to be spawned while the analyst
was blocked — upstream work wasn't done yet.
… show``

The kanban-worker skill (built into the gateway dispatcher's spawn
prompt) instructs every worker to hand off via
``kanban_complete(summary=..., metadata=...)``. That writes the summary
onto the closing ``task_runs`` row, NOT onto ``tasks.result`` — the
latter is left NULL unless the caller passes ``result=`` explicitly.

Result: a glance at the dashboard or ``hermes kanban show <id>`` shows
a blank "Result:" section even when the worker did real work, which
on 2026-05-05 caused a Mac false-alarm ("Hermes did nothing") on a
task that had a 10-line completion summary on its run.

This patch surfaces the latest non-null run summary as
``latest_summary`` so the worker's actual handoff lands in front of
operators.

* New helpers ``kanban_db.latest_summary(conn, task_id)`` and
  ``kanban_db.latest_summaries(conn, task_ids)``. The batch variant
  uses a single window-function SELECT so the dashboard board endpoint
  doesn't pay an N+1 cost on multi-hundred-task boards.
* CLI ``hermes kanban show <id>`` prints a "Latest summary:" block
  when ``tasks.result`` is empty but a run has produced a summary
  (the existing "Result:" section still wins when populated, so the
  back-compat path for hand-edited results is untouched). JSON output
  gains a top-level ``latest_summary`` field.
* Dashboard ``/board`` and ``/tasks/{id}`` now include a
  ``latest_summary`` field on every task. Cards on /board carry a
  200-character preview (cheap to render, plenty for "what did this
  worker do?" at a glance); the drawer/detail endpoint returns the
  full summary.
* Five new tests cover: empty-runs case, post-complete surface,
  newest-of-multiple selection, empty-string skip, batch with
  missing tasks + empty input.

Smoke-tested locally against the live profile DB on the three
acceptance-criterion targets (t_f08fef91 cron-hygiene-audit,
t_007b7f1c EMA-analysis, t_05746fa4 self-assessment) — all three now
return their populated summaries via both ``latest_summary`` and
``latest_summaries``.

Test plan: 255/255 kanban tests pass + 91/91 dashboard plugin tests
pass. No regression on tasks where ``tasks.result`` is explicitly
populated (the existing "Result:" branch is preserved).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants