fix(goals): wake agent panes on inbox mail, canonicalize pane ids, make impl workers visible - #29
Merged
Conversation
…ke impl workers visible Three failures found driving a live goals org (canora-sync gp6/gp7): 1. Reports reached the orchestrator's inbox (88 unread) but it never acted: the bus is pull-only and an interactive `claude` blocks on stdin once its turn ends. New control/nudge.rs + arm_inbox_nudge: when mail lands for an opted-in pane (meta.role goals-orch|spec, or hp.nudge=on) wait for it to leave Busy, then type ONE coalesced, rate-limited line naming the read cursor. HYPERPANES_MSG_NUDGE=0 disables. 2. Replies to a spec agent 404'd: app-created panes are `pane-<uuid>`, control-created ones bare `<uuid>`, and an agent handed one spelling reconstructed the other. ReadModel::resolve_pane_id canonicalizes either form (and a session uid); find_pane_scoped returns the canonical id so post and read hit the same inbox. 3. Impl-agent work was invisible: spawn_workers put N agents in one pane, `claude -p` prints nothing until it exits, and the runner's exit on drain auto-closed the pane with its scrollback. `hyperpanes worker` gains --stream (render Claude stream-json as progress), --log-dir (per-task raw transcript that outlives the pane) and --linger; personas pass --output-format stream-json --verbose and spawn one pane per worker. All new flags default off = frozen behaviour. Verified live: alias-addressed post lands in the canonical inbox, the nudge line types into a quiet pane, and a streamed worker run renders + logs per task. Co-Authored-By: Claude Opus 5 (1M context) <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.
Three failures found driving a live goals org (canora-sync, goals
gp6/gp7) — all in the plumbing around the org, not the org itself.1. Reports reach the parent's inbox but it never acts on them
The message bus is pull-only:
POST /panes/:id/messagesstores the message and pings WS clients, but nothing writes to the pane. An interactiveclaudeorchestrator blocks on stdin the moment its turn ends, so mail sat unread (88 messages, latest seq 121) until a human typed into the pane.New
control/nudge.rs+arm_inbox_nudgeinroutes.rs: when mail lands for an opted-in pane (meta.roleingoals-orch/spec, orhp.nudge=on), wait for the pane to leaveBusy, then type ONE line naming the read cursor, using the same cadence as goal/resume delivery.compute_activity() != Busy.hp.nudge=offmeta, orHYPERPANES_MSG_NUDGE=0.The inbox stays the source of truth; this is only the wake-up.
2. Replies to a spec agent 404'd (
no such pane)Two pane-id spellings coexist: app-created panes are
pane-<uuid>, control-created ones bare<uuid>. An agent handed one form and reconstructing the other addressed a queue nobody reads — the reverse direction of the bus (orchestrator to spec answers, impl advisor consults) was silently dead.ReadModel::resolve_pane_idcanonicalizes either spelling (and a session uid);find_pane_scopedreturns the canonical id, so post and read land on the same inbox.3. Impl-agent work is invisible
spawn_workersput N agents in one pane (interleaved output),claude -pprints nothing until it exits, and the runner exits on drain ->pane_exited-> the pane auto-closes with its scrollback.hyperpanes workergains three flags, all default off = frozen behaviour:--stream— renders Claude--output-format stream-jsonevents as progress; non-JSON output passes through unchanged.--log-dir <dir>— tees each child's raw output to<dir>/<queue>-<taskId>.log, which outlives the pane.--linger <secs>— holds the process open after the drain so the pane stays readable.Personas now pass
--output-format stream-json --verbose+stream:true, lingerSecs:120. The matching MCP change (spawn_workersdefaults to one pane per worker, exposesstream/logDir/lingerSecs) is in Eyalm321/hyperpanes-mcp.Verification
cargo test -p hyperpanes-core— 600 pass (new: nudge policy unit tests,resolve_pane_id, alias route roundtrip).cargo testincrates/app— 150 pass (new: flag parsing, stream rendering, log paths).cargo clippy --all-targetsclean on both crates.🤖 Generated with Claude Code