Skip to content

fix(kanban): add audited triage recovery - #69692

Open
onfire7777 wants to merge 2 commits into
NousResearch:mainfrom
onfire7777:codex/kanban-triage-recovery
Open

fix(kanban): add audited triage recovery#69692
onfire7777 wants to merge 2 commits into
NousResearch:mainfrom
onfire7777:codex/kanban-triage-recovery

Conversation

@onfire7777

Copy link
Copy Markdown

Summary

  • add an explicit promote --from-triage recovery path
  • require a human-readable audit reason
  • reject --force and any task whose parents are still open
  • preserve task, workspace, and lease evidence
  • emit triage_recovered_manual for auditability

Verification

  • TDD: 11 expected failures before implementation
  • 27 focused tests pass
  • Ruff, CLI help smoke, git diff --check, and secret scan pass

This does not bypass dependencies or automatically recover triage cards.

@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/cli CLI entry point, hermes_cli/, setup wizard comp/cron Cron scheduler and job management labels Jul 23, 2026
Require durable triage provenance and reject every active task or run
ownership signal before audited recovery. Keep the successful path
immediately claimable through the canonical claim transaction.
@onfire7777

Copy link
Copy Markdown
Author

Resolved the two independent review blockers in 35727edea:

  • --from-triage now applies only to tasks whose current status is exactly triage and requires durable prior specified or block_loop_detected event evidence.
  • Recovery fails closed on every task/run ownership signal. It does not clear or reclaim ownership as a side effect; an ownership invariant must be repaired through a separate audited operation.
  • A successful recovery remains atomic with the parent gate and is immediately claimable through canonical claim_task.
  • Nonblank reason and --force incompatibility remain enforced.

Verification:

  • RED: 9 targeted failures before the implementation change.
  • Focused: scripts/run_tests.sh tests/hermes_cli/test_kanban_promote.py -q — 42 passed.
  • Adjacent: specification, core lifecycle/claim/reclaim, and DB suites — 412 passed.
  • Ruff passed on the three Python files; git diff --check passed; secret/risky-file sweep was clean.

@onfire7777

Copy link
Copy Markdown
Author

Follow-up from GitHub/codebase attention package 20260723-100038:

  • Refreshed current PR state: branch onfire7777:codex/kanban-triage-recovery @ 35727edeace60516cdd537c03e8aa2056fca2580 remains mergeable against current upstream main.
  • scripts/run_tests.sh tests/hermes_cli/test_kanban_promote.py -q -> pass, 42 passed.
  • git diff --check origin/main...HEAD -> pass.
  • GitHub still reports no checks for this fork branch, and my permission on NousResearch/hermes-agent is READ, so merge/check authorization remains maintainer-gated.

@onfire7777

Copy link
Copy Markdown
Author

From 2026-07-24 GitHub/codebase attention report triage:

  • Still open, no CI checks reported on fork branch (expected for external fork PRs to NousResearch/hermes-agent).
  • Last local verification (per prior comment): tests/hermes_cli/test_kanban_promote.py 42 pass, adjacent suites 412 pass, ruff clean.
  • Per report: only unblocked P3 PR; others have needs-decision.
  • Current local main @ 951d606 synced with origin. No new changes.
  • Awaiting maintainer review / merge decision. (READ permission on upstream, cannot self-merge.)

No new action from this triage; re-confirming state.

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the focused recovery path. The premise is confirmed on current main: promote_task rejects triage at hermes_cli/kanban_db.py:5710-5714, while the loop breaker deliberately routes recurring blocks to triage at hermes_cli/kanban_db.py:5580-5618.

The PR's guarded --from-triage branch is consistent with the current lifecycle: it preserves the normal ready -> running claim transaction, whose parent invariant is enforced in hermes_cli/kanban_db.py:4094-4154. The linked maintainer cross-reference from issue #74012 confirms this is the intended audited CLI-recovery direction.

No substantive correctness defect was identified in static review. This is an automated hermes-sweeper review.

@teknium1 teknium1 added sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 30, 2026
@Shard

Shard commented Aug 9, 2026

Copy link
Copy Markdown

Confirming the premise on current main (3a915c46d): promote_task still refuses triage at hermes_cli/kanban_db.py:5859, and the loop breaker still routes recurring same-cause blocks there at hermes_cli/kanban_db.py:5726-5745. The guarded, fail-closed shape here looks right, and the ownership-invariant check is a good call. Three things I'd raise before this lands, all from trying the change against triage cards that didn't come from the loop breaker.

1. The event-proof precondition strands the never-specified card. --from-triage requires durable 'specified' or 'block_loop_detected' event proof covers the #74012 loop-breaker case exactly, but it excludes the other way a card sits in triage: created there and never processed. On an install with no auxiliary.triage_specifier configured (or offline, or a misconfigured slot — #21494, #30382, #61585), hermes kanban create "x" --triage yields a card where specify returns "auxiliary client unavailable" (hermes_cli/kanban_specify.py:168), decompose returns the same, and --from-triage refuses for lack of proof. archive becomes the only exit. #36814's assignee-bearing triage cards that never auto-decompose land in the same hole. Since the reason gate and the parent gate are already doing the "deliberate operator action" work, is the event proof carrying weight the audit reason doesn't?

2. Destination todo rather than ready. Both existing triage exits land in todo and let recompute_ready do the gating. specify_triage_task says so explicitly (kanban_db.py:5983): "todo (not ready) is the correct landing column: recompute_ready promotes parent-free / parent-done todos to ready on the next dispatcher tick, which keeps the normal parent-gating behaviour intact." The dashboard's non-LLM equivalent does the same — PATCH /tasks/:id {"status":"todo"}_set_status_direct (plugins/kanban/dashboard/plugin_api.py:904). A --to {todo,ready} defaulting to todo would match both surfaces, and the parent gate would fall out of recompute_ready for free instead of being re-implemented in promote_task. #74012's own suggested spelling is --to todo.

3. The recurrence counter (#74012 item 5). block_recurrences is captured into the triage_recovered_manual payload but not reset or overridable, and unblock_task deliberately preserves it too. So a card recovered out of a loop-breaker escalation re-escalates to triage on the very next same-cause block — the operator gets one attempt and the loop the issue reported isn't actually broken. An opt-in --reset-recurrences (audited in the same event) would close that, and it's the one item from #74012's expected-behaviour list still open.

Heads-up on merge order: #79615 is extracting the ready-promotion/triage logic out of kanban_db.py into mixins and touches promote_task directly — whichever lands first will force a rebase.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard comp/cron Cron scheduler and job management P3 Low — cosmetic, nice to have sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants