Skip to content

fix(#249): broadcast on reflects committed membership (CONTRACT §14.1, §13)#367

Merged
voidfreud merged 1 commit intomainfrom
fix/config-bugs-group-d
Apr 13, 2026
Merged

fix(#249): broadcast on reflects committed membership (CONTRACT §14.1, §13)#367
voidfreud merged 1 commit intomainfrom
fix/config-bugs-group-d

Conversation

@voidfreud
Copy link
Copy Markdown
Owner

Summary

One atomic commit. #287 out of scope (already closed under PR #338 per triage sweep).

Real root cause found: iTerm2 silently drops broadcast domains with fewer than 2 sessions. So `ita broadcast on -s ONE` passed the in-connection verify but vanished before `broadcast list` ran on the next API call. Classic time-of-check-to-time-of-use.

Fix: reject singleton writes up-front with `ItaError("bad-args")` and actionable guidance — suggest `broadcast add` / `broadcast set` / `--window` with ≥2 panes. Same guard on the `--window` branch. Post-write verify upgraded from `ClickException` → `ItaError` for structured rc=6.

Fast-lane: 557 pass / 14 fail → 583 pass / 12 fail (+2 new regression tests, -1 stale `known_broken` marker cleared on an existing test now passing; no regressions).

Flagged (not in scope):

  • Pre-existing integration failures in `tests/test_broadcast.py` / `test_broadcast_redesign.py` — suggest iTerm2 has a deeper cross-window broadcast limitation. Was failing before this PR; worth its own issue.
  • Latent fixture bug in `tests/fixtures/sessions.py::broadcast_domain` — calls `ita_ok('broadcast', 'on', *sids)` positionally but the command takes `-s`.

Closes #249.

Test plan

  • Fast-lane: 583/12
  • Smoke `ita broadcast on -s single-sid` → rc=6 bad-args with guidance about ≥2 sessions
  • Smoke `ita broadcast on -s s1 -s s2 && ita broadcast list` → list reflects the new domain

🤖 Generated with Claude Code

…, §13)

Root cause: iTerm2 silently drops broadcast domains with <2 sessions
(broadcast is mirror-input — nothing to mirror to a single target).
`broadcast on -s ONE` with no existing domain would succeed in-connection
(verify block saw the domain), then state vanished when the connection
closed, so `broadcast list` correctly showed empty — a §14.1 lie from
the writer.

Fix: reject invalid writes up front instead of racing iTerm2's silent
drop.
- `broadcast on -s SID` with no existing domain → ItaError("bad-args")
  pointing at `broadcast add` / `broadcast set` / `broadcast on --window`
  with ≥2 panes.
- `broadcast on --window WIN` with <2 panes → ItaError("bad-args").
- Post-write verify upgraded from ClickException to ItaError (belt+braces
  for any future iTerm2 rejection path — structured rc=6 per §6).
- De-duplicate the merge branch: skip re-adding an already-present
  session rather than creating a no-op write the API might reject.

Tests:
- test_issue_249_broadcast_on_single_session_rejected: rc!=0 with
  actionable error, state stays empty.
- test_issue_249_broadcast_list_reflects_reality_after_rejection: §14.1
  proof that a rejected write leaves no residue.
- Drop stale `known_broken` marker on
  test_trust_05_broadcast_on_missing_session (it already passed via
  resolve_session's not-found path).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@voidfreud voidfreud merged commit f847f0a into main Apr 13, 2026
0 of 2 checks passed
@voidfreud voidfreud deleted the fix/config-bugs-group-d branch April 13, 2026 23:58
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.

bug: broadcast on reports success but broadcast list shows empty

1 participant