Auto-clear a hera role's self-reported blocked status, not just the PTY flag - #904
Merged
Conversation
…TY flag The rail's "(?)" glyph ORs two independent signals: the auto-clearing PTY-content needs-input flag (RoleView.NeedsInput) and a role's self-reported hera_status=="blocked" (RoleView.needsInputOwn), set only via an explicit hera_status tool call or a manual s/S step. Every prior needs-input fix governs only the first signal, so a role that marked itself blocked and was then answered directly in its pane -- with the agent replying conversationally rather than re-invoking hera_status -- showed a stale "(?)" that nothing but a manual step could clear. agent.ClearBlockedRoleStatus mirrors NeedsInputClear's two-tier design: a direct reply after the block clears immediately (no threshold, since a brief acknowledgment may never sustain the resumed-activity ticks), or sustained resumed activity clears it for a coordinator-relayed answer. Wired into both the TUI and the daemon for frontend parity, backed by two new DB primitives (ListBlockedHeraRoleBindings, ClearBlockedRoleStatus) scoped to the (usually empty) live-blocked set. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Merging this branch changes the coverage (2 decrease, 1 increase)
Coverage by fileChanged files (no unit tests)
Please note that the "Total", "Covered", and "Missed" counts above refer to code statements instead of lines of code. The value in brackets refers to the test coverage of that file in the old version of the code. Changed unit test files
|
Merged
5 tasks
anutron
added a commit
that referenced
this pull request
Jul 22, 2026
…nct AskUserQuestion prompts (BUG-067) (#905) BUG-063's cleared-marker guard could only compare (taskID, timestamp), so it couldn't distinguish "the same already-answered content re-detected" from "a second, textually distinct, still-unanswered prompt that happens to arrive with lastInputOf(id) unchanged" -- an accepted trade-off at the time. Claude Code's /brainstorm AskUserQuestion flow hits this constantly: answer question 1 directly in the pane, question 2 (a different prompt) appears before any further keystroke, and the rail's "(?)" never comes back even though the agent is genuinely blocked on it. agent.NeedsInputClear now threads a content fingerprint alongside the cleared-marker timestamp (ClearedMarker{At, FP, HasFP}) so a stale re-candidacy is only suppressed when the content also matches; a fingerprint that provably differs re-arms instead. Both callers already computed the needed fingerprint each tick for the BUG-032 content- stability pass, so no new render pass was added. Investigated first as a possible regression from #904 (which reuses the same shared ScreenRenderer) -- ruled out via the live DB (neither role had a hera_role_status row) and a test proving the two passes don't cross-contaminate when sharing a renderer in the same tick. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Root cause
The hera rail's "(?)" glyph is
RoleView.needsInputOwn() = r.NeedsInput || (r.HasStatus && r.Status == db.HeraStatusBlocked)— an OR of two independent signals. Every prior needs-input fix (BUG-029 through BUG-065, seecontext/knowledge/gotchas/events.md) governs only the first signal: the auto-detected PTY-content needs-input flag. The second signal — a role's self-reportedhera_status, set only via an explicithera_statustool call or a manual rail s/S step — had no auto-clear at all.Confirmed via a direct read-only query against the live dogfood DB: the reported role's
hera_role_statuswasblocked, set before the screenshot's direct-reply exchange. The deployed dogfood binary was only one unrelated commit behind master, ruling out binary skew.Live repro: a worker set itself
hera_status="blocked"(e.g. awaiting a check-in), the human replied DIRECTLY in the pane (a real keystroke), and the worker replied conversationally without re-invokinghera_status— plain conversation has no tool call to trigger it. The rail kept showing "(?)" indefinitely.Fix
agent.ClearBlockedRoleStatus(blockedAt, lastUserInput, resumed) bool— mirrorsNeedsInputClear's two-tier design. A direct reply after the block clears immediately (no threshold — a brief acknowledgment reply may never sustain the resumed-activity ticks BUG-065's condition requires). Sustained resumed activity (reusing BUG-065'sagent.ResumeActivityTick) clears it for the symmetric coordinator-relayed-answer case.db.ListBlockedHeraRoleBindings()/db.ClearBlockedRoleStatus(roleID)— new read/write DB primitives, one indexed join, scoped to the (usually empty) live+blocked set.internal/tui/app.go(App.autoClearBlockedHeraRoles) andinternal/api/push.go(Server.autoClearBlockedHeraRoles) for frontend parity — REST/web/macOS all read the samehera_role_statusrow.context/knowledge/gotchas/events.md+ index bump.Testing
New tests at all layers:
internal/db(read/write DB primitives),internal/agent(pure predicate),internal/tui,internal/api(end-to-end through the real callers, including the exact live-repro shape: direct reply → brief ack → clears with no resumed-activity threshold needed).Verification
make pre-pr: build/vet/fmt-check/lint-pr all pass clean (0 lint issues).vulnfails on pre-existing stdlib CVEs unrelated to this diff (confirmed non-blocking perci-gates.md, CI runs itcontinue-on-error).test-cover-gatehit repeated timeouts in unrelated pre-existing tests under sustained-raceload on the dev machine — confirmed via agit stash+ rerun on the unmodified base commit, which reproduced the identical failure/timing, proving it's environmental and not caused by this diff. All new + touched-package tests pass individually.🤖 Generated with Claude Code