Skip to content

fix(attention): asks and waiting sessions name the exact tmux target - #388

Merged
ZacxDev merged 10 commits into
mainfrom
fix/asks-name-tmux-window
Nov 1, 2026
Merged

ZacxDev merged 10 commits into
mainfrom
fix/asks-name-tmux-window

Conversation

@ZacxDev

@ZacxDev ZacxDev commented Nov 1, 2026 •

Copy link
Copy Markdown
Owner

What

Every attention text that names a mirrored tmux window now gives its exact tmux target, <session>:<index> on its host, led by the host's codename when it has one:

  • Fix CI (tmux build:4 @ laptop) stopped and is waiting on you: …
  • Fix CI (mango:1 · tmux scratch3:5 @ laptop) stopped and is waiting on you: …

One helper, mirror.Where(host, session, window, index, label) (and SessionView.Where()), in internal/mirror/order.go, built on the same <session>:<index> rule as SessionView.Address (now tmuxAddress, shared by Address and Title).

Why

The operator could not find the window an ask was about. The ask text used c.Label, the host's codename (mango:1), which is not a tmux name: one ask said mango:1 while the window was tmux session scratch…, a different index. With no codename it fell back to the tmux session alone, with no window (build @ ws for window build:4). Neither one is a target you can type into tmux.

How

  • chiefnudge.Session carries Index (filled in stallInputs from w.Index).
  • nudgeAskQuestion: only the mirror/agent branch changed. It now calls nudgeAskPlace(c), which returns " (" + mirror.Where(...) + ")" or " (agent <name>)". The function's signature, its first lines and its generic branch are untouched, so it merges cleanly with fix(chief-nudges): the generic ask shows the chief's read #384 (since merged; see below).
  • A mirrored session's ask (attention.Asker{MirrorHost, MirrorSession}) resolves the window running its Claude session now (claudeSessionEntry, which is the rule claudeSessionWindow already used and is now built on) to get its source. If no window runs it, the source is its stored name plus (not shown in any mirrored window now). It never invents a target.
  • askItem(a, hosts...) takes the owner's windows variadically. Every production caller passes them: askItemNow, the queue, the asker block. askItem(a) still compiles, so feat(attention): GET /api/attention/summary + summary-only token scope #385's test keeps building.

The index is a snapshot. tmux renumbers windows, so the text says where the window was when it was written. View in session (from #383) resolves by Claude session id at click time and stays the source of truth. The docs say this. I did not add "as of when it was asked" to every ask, because it would be noise on every line.

Site ledger

From a git grep for Label, TmuxSession, MirrorSession, " @ ", DisplayTitle() + and askItem( over non-test Go:

site surface changed?
chief_nudge.go nudgeAskQuestion / new nudgeAskPlace chief nudge ask text, both the specific and the generic ask yes: mirror.Where
chief_nudge.go:344 stallInputs fills chiefnudge.Session yes: carries Index
attention.go waitingSessions Source waiting session, held question (AskUserQuestion), Hermes waiting item; queue card and push title/body yes: e.Where() (was DisplayTitle() + " @ " + host)
attention.go askItem → new askSource a mirrored session's ask: queue source, push title yes: resolved through the hub
attention_ask_page.go renderAskPage ask page header " asks" yes: askItemNow
attention_asker.go askerAsks the in-session asks block yes: passes hostViews()
attention_push_target.go openTarget tap target item yes: askItemNow
attention_suggest.go askFiled, repushAsk the ask's push and its suggestions re-push yes: askItemNow
cards_attention.go claudeSessionWindow the resolver yes: built on the new claudeSessionEntry (the same rule, now with Index/Label)
attention.go answeredAsksHTML / answerDeliveryText (Answered card source; "Queued for X…", "Delivering to X", "Waiting for X to read it…"), attention_ask_page.go answered ask's delivery line answered asks: they send the operator to the session changed (round 1): askSource (answeredAsksNow reads the windows once when an answer is a mirrored session's); window gone → "(not shown …)". askerLabel is now only askSource's fallback
attention.go askerName log lines left: ids by design ("never its label")
mirror_mcp.go:274 Asker.Label stored name of a session's ask left: still the name and host; the target is resolved at render time (above)
chief_ask_tool.go renderChiefQuestion a session question put to the chief changed (round 1): new fenced line where: <askSource>; the preface (host, Claude session id) is unchanged
focus_tools.go fleet_list chief changed (round 1): new where field
sessions_overview.go sessions_overview rows + liveSessions chief changed (round 1): new where field
sessions_overview.go → internal/plugins/hints.go session hints chief (plugin messages) changed (round 1): — where: … on each hint's head line
pr_routes.go → hints.go renderAuthor chief (offline/unrouted PR author) changed (round 1): window: online, where: … when a window shows it
fleet_report.go chief's door changed (round 1): new where on listed windows. Mail door: never (it names no host; its goldens are unchanged)
plugin_message_route_tools.go:290 route candidates a mirrored session's own plugin_message_route refusal changed (round 1): new where field
internal/agentspec/instructions.go chiefLiveReads (shared by both chief runtimes) supervisor prompt changed (round 1): one paragraph: when pointing the owner at a session, give its where exactly. Digest re-recorded after reading the diff; worded without tool names (the two runtimes name tools differently) and without "tmux" (an existing prose test bans it)
agent_destroy_tool.go, chief_restart_tool.go, connector_decide_tools.go, route_reply_tool.go, plugin_message_route_tools.go (MirrorHost + "/" + MirrorSession) logs and audit from left: ids
nudge decisions page (docs/chief-nudges.md "focus title and host") decision log left: not an ask; out of scope
internal/ui/send_queue.go / composer.go "Already answered X's question" notes on the session's OWN page about its queued message left: the operator is already in that session

Before this change, an unlabelled mirrored session's ask was already near-exact: its stored label was DisplayTitle() @ host = build:7 @ ws. It was a snapshot with no tmux marker and no codename handling. It now resolves live.

Test matrix

Whole normalised strings are pinned (internal/api/attention_where_test.go, internal/mirror/where_test.go). The fixture's fields are pairwise distinct: session scratch3, id @37, index 5, codename mango:1 (the codename's index is not the tmux index), plus an unlabelled build/@4/7.

Red runs at origin/main f73c492f. Green runs at HEAD. The counts are the runner's own --- PASS/FAIL lines.

test main HEAD
TestANudgeAskNamesItsWindowsExactTmuxTarget (codename / no codename subtests) FAIL (2/2 subtests) PASS
TestAnAgentNudgeAskKeepsItsAgentName PASS (invariant guard) PASS
TestAWaitingSessionAndItsPushNameTheExactTmuxTarget (session item and push body) FAIL PASS
TestAMirroredSessionsAskNamesTheWindowRunningItNow (queue source and push title, incl. window gone → "(not shown …)") FAIL PASS
TestTheAskPageHeaderNamesTheExactTmuxTarget (incl. window gone) FAIL PASS
TestASessionPagesAsksBlockNamesTheExactTmuxTarget FAIL PASS
TestAFiledAsksNotificationNamesTheExactTmuxTarget (stored name stale main:9, push says main:2) FAIL PASS
TestChiefNudgeLiveAskIsAnsweredAndRelayedVerbatim (PG; now pins the whole ask question through actAsk) FAIL PASS
TestAWaitingSessionShowsWhatItWaitsOn (PG; existing, expectation updated) FAIL PASS
TestChiefNudgeTheGenericAsk* ×3 (PG; #384's, genericAskHead updated) FAIL PASS
TestWhereIsTheExactTmuxTarget (helper unit test) n/a (new symbol) PASS

To run the two nudge tests at main, which has no nudgeAskPlace, I used a test-only shim that read main's own place out of main's own nudgeAskQuestion. It was never committed.

Mutation battery (one exact edit per mutant, tree checksum restored): 10/10 killed.

mutant result
drop the index (addr := session) KILLED (9)
Label instead of Session KILLED (9)
drop the codename lead KILLED (7)
nudge candidate drops Index KILLED (3)
nudge place back to Label @ host KILLED (3)
ask source not resolved KILLED (4)
unresolved ask drops "not shown" KILLED (2)
claudeSessionEntry drops Index KILLED (4)
waiting session back to old source KILLED (1)
askFiled without hosts KILLED (1)

go build ./... and go vet ./... are clean. go test -race passes on internal/api, internal/mirror, internal/chiefnudge and internal/ui under scripts/with-test-pg.sh. Full go test ./... with PG: 77 packages ok, rc 0 (run before the last two refactor commits; the -race set above was re-run at HEAD).

Round 1 (answered lines + the chief's reads)

The tests pin whole strings: attention_where_delivery_test.go, attention_where_chief_test.go, internal/plugins/hints_where_test.go, plus a whole-line pin in chief_ask_pg_test.go. Red runs at the previous head 4ed52f11, green at 2311ca58. Counts are the runner's own result lines.

test 4ed52f11 HEAD
TestAnAnswersDeliveryLineNamesTheExactTmuxTarget (Answered list: card source and delivery line whole, for Queued+detail with a codename, Queued with window gone, Pull, Unconfirmed) FAIL PASS
TestAnAnsweredAskPagesDeliveryLineNamesTheExactTmuxTarget (the same lines on the ask's own page) FAIL PASS
TestTheChiefsFleetListCarriesEachWindowsWhere (where, with name/host kept) FAIL PASS
TestChiefAskPutsTheQuestionToTheChiefWithItsSessionAndRoute (PG; pins \n| where: tmux main:1 @ ws\n in the chief's real turn) FAIL PASS
TestASessionQuestionToTheChiefSaysWhereTheWindowIs (incl. window gone) n/a (new signature) PASS
TestTheOverviewAndTheRouteCandidatesCarryEachWindowsWhere n/a (new field) PASS
TestASessionHintAndAnOnlineAuthorCarryTheirWhere n/a (new field) PASS
TestFleetReportGolden (PG; 3 *.tool.json goldens regenerated; all mail goldens unchanged) — PASS

Mutation battery, round 1: 11 of 11 mutants killed, with the round-0 "drop the index" mutant as a positive control (also killed).

mutant result
delivery line back to askerLabel KILLED
ask page delivery back to askerLabel KILLED
Answered list without hosts KILLED
fleet_list drops where KILLED
liveSessions drops where KILLED
overview row drops where KILLED
route candidate drops where KILLED
chief question drops its where line KILLED (unit + PG)
fleet report drops where KILLED (goldens)
hint drops where KILLED
author drops where KILLED

go build ./... and go vet ./... are clean. -race with PG passes on internal/api, internal/mirror, internal/chiefnudge, internal/ui, internal/plugins, internal/agentspec, internal/agentprovision and cmd/muster-server.

Round 1 has two things a reviewer should know:

  • The fleet report's withheld counter now counts a hidden character in a window's label twice, once for name and once for where: the rich golden's gap reads "2 field(s) withheld", where it used to read 1. Both fields really are withheld.
  • The pr_routes.go wiring (a.Where = e.Where()) has no test of its own. Only the renderer is pinned.

Round 2 (final): the target is shown verbatim

🟡 Markdown stripping. Every display surface plains a title's markdown with textplain.Title. That stripped the target's own characters, so tmux session _scratch_ showed as scratch, *dev* as dev, and a`b`c as abc.

  • One rule: textplain.TitleKeeping(s, keep). It plains s except keep, which it keeps verbatim. keep is the window's target, a new mirror.WhereTarget (tmux <session>:<index> @ <host>, the machine part of Where). attentionItem carries that target.
  • Where it applies: the push body and the push title sink (goNotify, through a new RouterNotification.TitleKeep), the queue card, the summary title/why, the ask page header and its delivery line, and the Answered list.
  • What is still plained: the codename around the target (*mango*:1 shows as mango:1). Surface escaping is unchanged: HTML-escaped on pages, one line on pushes.
  • Ledger (internal/textplain/sinks_test.go): it records the exemption and counts TitleKeeping as the title rule. It now also tracks Where, askSource and askSourceParts reads. A new subtest, where kept verbatim, fails on any textplain.Title over a value that can name a window (a Source, a Where, an ask's source). It has a positive control requiring at least 6 TitleKeeping sites.

🟢 Offline host. A where from a host that has just dropped (the hub keeps listing its windows for a grace period) now ends in (host offline). This applies to an ask's source and to the chief's fleet_report. The clash saved output for the fleet report was regenerated.

🟢 Asks block comment. The asks block (attention_asker.go) now reads hosts only for a mirrored ask, so its comment is true again.

Docs: attention.md's summary table now shows Waiting: <tool> · <where>. "How a window is named" now says the target is verbatim and describes (host offline).

Tests, red at 3427d6d4 and green at HEAD:

test 3427d6d4 HEAD
TestAWindowsTargetIsShownVerbatimOnThePushTheSummaryAndTheCard (sessions _scratch_ with codename *mango*:1, *dev*, a`b`c; push body, summary title and why, card, all whole) FAIL (tmux scratch:2, tmux dev:3, tmux abc:4) PASS
TestAnAsksPushTitleKeepsItsTargetVerbatim (through goNotify) FAIL (tmux dev:3 @ ws is asking) PASS
TestAWhereOnAnOfflineHostSaysSo FAIL PASS
TestTitleKeepingKeepsOnlyItsPartVerbatim (textplain) n/a (new function) PASS

Full go test -race ./... with Postgres on the merged final tree (c73ddd4e, which includes main's #386 and #389): 77 ok, 0 FAIL, 20 with no test files, 0 timeouts, 0 skips, rc 0. go build ./... and go vet ./... are clean.

This round has two rows that did not change after the offline marker, recorded here:

  • The chief's fleet_list and sessions_overview list only online windows, so they never show an offline where.
  • The waiting-session card already shows its own offline marker.

Mutations: 8 of 8 killed, plus a positive control (also killed).

  • Push body, summary or card back to Title: killed by both the behavioural test and the ledger's where kept verbatim.
  • The sink ignoring TitleKeep, a waiting item with no target, an ask item with no target, TitleKeeping keeping nothing, no offline marker: each killed.

Merge notes (test-merged)

  • fix(chief-nudges): the generic ask shows the chief's read #384 is now on main. It is merged into this branch with no textual conflict. Its new chief_nudge_generic_read_pg_test.go pinned "A session (Gold:1 @ ws)", and this branch updates it to "(Gold:1 · tmux main:1 @ ws)".
  • feat(attention): GET /api/attention/summary + summary-only token scope #385 (the attention summary API) is now on main and merged into this branch with no textual conflict. What changed after that merge:
    • One semantic fix. feat(attention): GET /api/attention/summary + summary-only token scope #385 made attentionItemsIn take the summary's ONE hub read (hs). This branch's ask loop had made a second, lazy read for mirrored asks. It now names asks from hs, so a summary reads the hub once even when a mirrored session's ask is open. New seam test TestTheSummaryNamesAMirroredAsksWindowFromItsOneHubRead: it passes at HEAD. With the second read put back, it fails with "read the hub 2 times; want 1".

    • feat(attention): GET /api/attention/summary + summary-only token scope #385's expectations updated. attention_summary_pg_test.go: the mirrored ask's title is now tmux main:1 @ ws, the session's title is tmux main:1 @ ws and its why is Waiting: tmux main:1 @ ws. The member-leak list also checks for tmux main:1, with a control that the operator's own summary contains tmux main:1 @ ws. attention_summary_test.go: the mirrored ask is built with its fixture's window (Gold:1, tmux main:4), so its title is pinned as Gold:1 · tmux main:4 @ ws, not the "not shown" fallback.

    • One more fix, after the full suite on the merged tree. The internal/textplain title-sink ledger went red, because the round-1 commit read the answered ask page's it.Source raw into its delivery line. It now goes through textplain.Title. That commit's own -race run did not include internal/textplain. Only the full ./... run caught it.

    • Full go test -race ./... with Postgres at 3427d6d4: 77 ok, 0 FAIL, 20 packages with no test files, 0 timeouts, 0 skips, rc 0. go build ./... and go vet ./... are clean.

What the summary (and so the bar) shows now

GET /api/attention/summary builds each item's title from the item's source and its why from the first line of its push body. Both now carry the window's exact target:

  • A waiting session or held question: title is tmux build:4 @ laptop, or mango:1 · tmux scratch3:5 @ laptop when the window has a codename. why is Waiting: <tool> · <the same>, or Waiting: <the same> when no tool is named.
  • A mirrored session's ask: title is the window running it now. When no window runs it, the title is its stored name followed by (not shown in any mirrored window now). why is the question.
  • An agent's ask, a chief nudge's ask (your chief), a reply draft: unchanged. A nudge ask's why is the first line of its question, which opens with <focus title> (<where>) ….

Not verified

  • No live check against a real host, the operator's phone or Attention view, or a live chief's behaviour with the new prompt paragraph.
  • The e2e Playwright specs were not run. attention.spec.ts asserts toContainText('@ ' + host), which the new format still contains.

🤖 Generated with Claude Code

ZacxDev and others added 5 commits October 31, 2026 23:32
An ask, a waiting session and their notifications named a mirrored window
by its host's codename ("mango:1 @ ws", which is no tmux name) or by its tmux
session alone with no window ("build @ ws"), so the operator could not find
it. Every attention surface that names a mirrored window now takes its words
from one helper, mirror.Where: "tmux <session>:<index> @ <host>", led by the
codename when the host has one ("mango:1 · tmux scratch3:5 @ ws").

- chiefnudge.Session carries the window's Index (filled by stallInputs), and
  nudgeAskQuestion builds its "where" from mirror.Where; agents keep
  "(agent <name>)".
- A waiting session / held question / Hermes item's source is e.Where().
- A mirrored session's ask resolves the window running its Claude session
  NOW (claudeSessionEntry, the rule claudeSessionWindow already used) for its
  source on the queue, its page header, its session page's asks block and
  its notification; when no window runs it, its stored name is followed by
  "(not shown in any mirrored window now)" instead of an invented target.
- Docs: attention.md "How a window is named", chief-nudges.md ask text.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… for the in-flight PRs

Test-merged with the two open PRs that touch these functions: one changes
nudgeAskQuestion's parameters, the other's test calls askItem(a). So:

- askItem takes its hosts variadically: askItem(a) still compiles (a mirrored
  session's ask is then named as no window showing it); every production
  caller passes the owner's windows. The test call sites go back to main's.
- The nudge ask's "where" is its own function, nudgeAskWhere, placed away
  from nudgeAskQuestion; nudgeAskQuestion's only change is calling it. The
  unit tests pin nudgeAskWhere whole; the live-ask PG test now pins the whole
  question built through the real path.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…geAskQuestion's head untouched

Test-merged with the open PR that changes nudgeAskQuestion's parameters: a
helper replacing the function's first lines conflicted with it textually.
Only the mirror/agent branch now changes (it calls nudgeAskPlace), as in the
first commit, which merged cleanly.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…x target

#384 (now on main) pinned the generic ask's head as "A session (Gold:1 @ ws)";
with this branch the place is mirror.Where's "(Gold:1 · tmux main:1 @ ws)".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@ZacxDev

ZacxDev commented Nov 1, 2026

Copy link
Copy Markdown
Owner Author

Audit round 0 (requirements & deletion) at 4ed52f11.

Verdict: requirement questioned. The operator asked for the exact tmux target always, and the PR applies that more narrowly than asked.

What already works: both cases that were observed now render as full tmux targets. The pane index is not needed, because the mirror tracks each window's active pane.

D1 — the answered-list/"Queued for X" exclusion (askerLabel at attention.go:1414,1464): drop it and use askSource(a, hosts) so Pull/Queued/Unconfirmed lines carry the tmux target
D2 — the "chief/tools are machine-facing" exclusion: drop it for sessions_overview/fleet list/renderChiefQuestion, because the chief passes asks on to the operator using only codename @ host
Q1 — Does "always include the exact pane" cover asks the CHIEF writes about a session (its own attention_ask), so chief-facing session listings must carry the tmux target too? · forcing: user

@ZacxDev

ZacxDev commented Nov 1, 2026

Copy link
Copy Markdown
Owner Author

The operator answered the round-0 premise. Relayed word for word:

Q1=answered: Yes, in this PR — chief-facing session listings (fleet list, sessions overview, chief questions) carry the same tmux target, and the chief's prompt says to use it when pointing the operator at a session
D1=deleted
D2=deleted

ZacxDev and others added 5 commits November 1, 2026 00:31
… exact tmux target

The operator's "always" is wider than the open-ask surfaces: an answered
ask's card and its delivery line ("Queued for X …", "Waiting for X to read
it …") send them to the session too, and the chief only ever saw a session
as its codename and host, so an ask the chief wrote could not name the
window.

D1, delivery: answerDeliveryText takes its asker's name, and every caller
passes askSource's — the Answered list (answeredAsksNow reads the owner's
windows once, when an answer is a mirrored session's) and an answered ask's
own page (its item's Source). A window no longer shown reads "(not shown in
any mirrored window now)", never an invented target.

D2, the chief: every session listing it reads carries the same text, as
`where` (additive; every existing field kept):
- fleet_list rows, sessions_overview rows (and the session hints built from
  the same live sessions), fleet_report rows on the chief's door only (the
  mail door names no host, so it never carries it);
- a session question's block: "where: <askSource>" inside the fence;
- route candidates and an online PR author's window line.
The supervisor prompt's shared live-reads paragraph says to give that
`where` exactly when pointing the owner at a session (its digest
re-recorded after reading the diff).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…mary's one hub read

- attentionItemsIn (#385) takes the caller's ONE read of the hub; the ask
  loop had a second, lazy read of its own for mirrored sessions' asks. It
  now names them from that same read, so a summary reads the hub once with
  a mirrored ask open too (new seam test; a second read is caught as
  "read the hub 2 times; want 1").
- #385's summary tests pin the new titles and whys: "tmux main:1 @ ws",
  "Waiting: tmux main:1 @ ws"; the unit fixture's ask is built with its
  window, "Gold:1 · tmux main:4 @ ws"; the member-leak list also refuses
  the operator's "tmux main:1", with a control that the operator's own
  summary carries it.
- An answered ask's page passes its source through textplain.Title before
  it reaches the delivery line (internal/textplain's title-sink ledger
  caught the raw read, introduced in the previous commit).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…own-stripped

The title rule (textplain.Title) plains markdown out of every page and
notification title; on a where it also plained the tmux target itself, so a
session named "_scratch_" read "scratch", "*dev*" read "dev" and "a`b`c"
read "abc" — places the operator cannot find.

- textplain.TitleKeeping(s, keep): Title over s, keep kept verbatim. keep is
  mirror.WhereTarget ("tmux <session>:<index> @ <host>", Where's machine
  part), carried on attentionItem (target) and RouterNotification
  (TitleKeep). Every surface that plains a Source uses it: the push body and
  the push title sink (goNotify), the queue card, the summary title/why, the
  ask page header and delivery line, the Answered list. The codename around
  the target is still plained; per-surface escaping is unchanged.
- The title-sink ledger records the exemption, counts TitleKeeping as the
  rule, tracks Where / askSource / askSourceParts reads, and refuses a plain
  Title over any value that can name a window ("where kept verbatim", with a
  positive control).
- A where from a host the hub still lists but has dropped ends
  " (host offline)" (an ask's source, the chief's fleet_report).
- The session page's asks block reads the hub only for a mirrored ask (its
  comment said so; the code did not).
- docs/attention.md: the summary's why is "Waiting: <tool> · <where>"; the
  target is verbatim; "(host offline)".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@ZacxDev

ZacxDev commented Nov 1, 2026

Copy link
Copy Markdown
Owner Author

Audit round 1 (full, at 3427d6d4): 0 🔴, so the ladder ends here. It found 1 🟡 and 3 🟢. They are fixed in 7e5c2bd9, which is not re-audited. Main was merged in afterwards as c73ddd4e.

  • 🟡 The exact tmux target went through the markdown stripper, so session _scratch_ showed as scratch. It is now kept verbatim on every surface via textplain.TitleKeeping + mirror.WhereTarget. Only the codename is stripped. The sink ledger now watches Where/askSource.
  • 🟢 A host that recently disconnected now shows (host offline) in an ask's source and in fleet_report.
  • 🟢 The asks block reads the hub only when a mirrored ask is present.
  • 🟢 Docs line fixed.

The round also checked that where never reaches the mail door, plugin replies or another owner's summary.

1. The tmux target is kept verbatim (not markdown-stripped) on the push body, push title, queue card, summary title/why, ask page header, delivery line and Answered list.
2. The title-sink ledger records the exemption and fails on a plain Title over a window-naming value.
3. A recently-disconnected host's window carries " (host offline)" in ask sources and fleet_report.
4. The asks block reads the hub only when a mirrored ask is present.

@ZacxDev
ZacxDev marked this pull request as ready for review November 1, 2026 06:54
@ZacxDev
ZacxDev merged commit 8f48db2 into main Nov 1, 2026
19 checks passed
@ZacxDev
ZacxDev deleted the fix/asks-name-tmux-window branch November 1, 2026 06:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant