Skip to content

fix(session): fail-fast (or warn loudly) when launcher dropped session key (#284.4)#302

Merged
laulpogan merged 1 commit into
mainfrom
fix/284-4-cli-wire-home-fail-fast
Jun 15, 2026
Merged

fix(session): fail-fast (or warn loudly) when launcher dropped session key (#284.4)#302
laulpogan merged 1 commit into
mainfrom
fix/284-4-cli-wire-home-fail-fast

Conversation

@laulpogan

Copy link
Copy Markdown
Collaborator

Part 4 of #284 (Willard's Windows report).

Summary

When the launcher spawns wire without inheriting `WIRE_HOME` or `WIRE_SESSION_ID` (and no host-adapter env like `CLAUDE_CODE_SESSION_ID` either), the session adapter silently falls through to:

  • `wire mcp` → mints a fresh per-process key (`SESSION_SOURCE = "minted"`).
  • `wire daemon` / `wire monitor` / `wire notify` → runs against the machine-default identity (`SESSION_SOURCE = "machine-default"`).

Both fallbacks are usually not what the launcher meant. The operator only finds out minutes later when they notice a sibling process serving the real session-key home racing the inbox cursor with this one's machine-default-or-minted one. Willard's repro: the spawned shell dropped `WIRE_HOME` on the floor, the child wrote to the cwd-default home, and the resulting cross-home contention contributed to the `relay.lock` pileup behind #284.5.

Fix

A new helper `crate::session::warn_if_unexpected_session_source(role)`:

  • Default: forces a clear stderr line naming the resolved source (`machine-default` / `minted`) and the operator-facing remediation ("pass an explicit `WIRE_SESSION_ID=` or `WIRE_HOME=`"). Force-rendered, not gated on TTY — these are spawn paths under Claude Code or scripts where stderr usually isn't a terminal.

  • `WIRE_STRICT_SESSION=1`: upgrades the warning to a hard exit (code 2) at startup so the launcher fails-fast instead of letting downstream `init` / `bind` / `daemon` calls block on a shared relay-state lock or quietly write to the wrong home.

Each of the four inbox-owning entry points now calls `warn_if_unexpected_session_source` BEFORE `warn_on_identity_collision`:

Entry point Call site
`wire mcp` `mcp.rs`
`wire daemon` `cli/relay.rs`
`wire monitor` `cli/comms.rs`
`wire notify` (long-running, `--once`-excluded) `cli/comms.rs`

The existing collision check stays in place; the session-source check is the earlier signal that catches the "launcher dropped the key" cases the collision check only fires for once a sibling process is also already running.

Pure-logic

`is_unexpected_session_source(&str) -> bool` is split out so the policy is exhaustively unit-testable across every adapter label.

Tests

3 new in `session::tests`, all green on `x86_64-pc-windows-msvc` (rustc 1.96.0):

  • `is_unexpected_session_source_flags_machine_default_and_minted`
  • `is_unexpected_session_source_passes_explicit_sources` — locks the policy against every existing adapter label (`env:WIRE_HOME`, `env:WIRE_HOME_FORCE`, `override`, `claude-code`, `claude-code-pidfile`, `codex-cli`, `copilot-cli`, `vscode-workspace`)
  • `is_unexpected_session_source_handles_unknown_conservatively` — `unknown` (adoption never ran) doesn't get flagged; new adapter labels default to "explicit" until a maintainer opts them in.

Full lib suite: 489 passed; 0 failed; 7 ignored.

Stack

Stacks on top of #294 (Windows test/clippy hygiene). Sibling Windows-cluster PRs already open: #296 (#284.5), #297 (#247.4), #298 (#284.1), #300 (#284.2), #301 (#284.3). This rounds out the Willard #284 cluster + #247.4 from saffron's hand-off.

Test plan

  • `cargo fmt --check` clean on Windows.
  • `cargo clippy --all-targets -- -D warnings` clean on Windows.
  • `cargo test --lib` 489/0/7 on Windows.
  • CI green.
  • Manual: run `wire daemon` from a shell with no `WIRE_HOME` / `WIRE_SESSION_ID` set, confirm the warning fires on stderr; re-run with `WIRE_STRICT_SESSION=1`, confirm exit code 2.

🤖 Generated with Claude Code

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 15, 2026

Copy link
Copy Markdown

Deploying wireup-landing with  Cloudflare Pages  Cloudflare Pages

Latest commit: 48da312
Status: ✅  Deploy successful!
Preview URL: https://8b8a03f3.wireup-landing.pages.dev
Branch Preview URL: https://fix-284-4-cli-wire-home-fail.wireup-landing.pages.dev

View logs

@laulpogan laulpogan force-pushed the fix/284-4-cli-wire-home-fail-fast branch 7 times, most recently from b753b50 to 24bd219 Compare June 15, 2026 02:12
…n key (#284.4)

Issue #284 part 4 (from Willard's Windows report). When the launcher
spawns wire without `WIRE_HOME` or `WIRE_SESSION_ID` (and no
host-adapter env like `CLAUDE_CODE_SESSION_ID` either), the session
adapter falls through to one of two silent-failure modes:

  - `wire mcp` mints a fresh per-process key (`SESSION_SOURCE = "minted"`)
    so the new server gets its own identity rather than colliding on
    the cwd-default.
  - `wire daemon` / `wire monitor` / `wire notify` run against the
    machine-default identity (`SESSION_SOURCE = "machine-default"`).

Both fallbacks are usually NOT what the launcher meant. The operator
only finds out minutes later, when they notice a sibling daemon
serving the real session-key home racing the inbox cursor with this
process's freshly-minted-or-default one.

New helper `crate::session::warn_if_unexpected_session_source(role)`:

  - Default: forces a clear stderr line naming the resolved source
    (`machine-default` / `minted`) and the operator-facing remediation
    ("pass an explicit `WIRE_SESSION_ID=<key>` or `WIRE_HOME=<path>`").
    Force-rendered, NOT gated on TTY — these are spawn paths under
    Claude Code / scripts where stderr may not look like a terminal.

  - `WIRE_STRICT_SESSION=1`: upgrades the warning to a hard exit
    (code 2) at startup, so the launcher fails-fast instead of
    letting downstream `init` / `bind` / `daemon` calls block on a
    shared relay-state lock or quietly write to the wrong home.

Each of the four inbox-owning entry points now calls
warn_if_unexpected_session_source BEFORE warn_on_identity_collision:

  - mcp.rs (`wire mcp`)
  - cli/relay.rs (`wire daemon`)
  - cli/comms.rs (`wire monitor`, `wire notify --once`-excluded)

The collision check itself stays in place; the session-source check is
the earlier signal that catches the "launcher dropped the key" cases
the collision check needs another sibling process to actually fire.

Pure-logic `is_unexpected_session_source(&str) -> bool` predicate is
extracted + unit-tested across every adapter label.

Tests: 3 new in session::tests, all green on `x86_64-pc-windows-msvc`
(rustc 1.96.0):

  - is_unexpected_session_source_flags_machine_default_and_minted
  - is_unexpected_session_source_passes_explicit_sources
  - is_unexpected_session_source_handles_unknown_conservatively

Full lib suite: 489 passed; 0 failed; 7 ignored.

Stacks on top of #294 (Windows test/clippy hygiene); rebase onto main
once #294 lands.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: laul.pogan <paul@zaibatsuheavy.industries>
@laulpogan laulpogan force-pushed the fix/284-4-cli-wire-home-fail-fast branch from 24bd219 to 48da312 Compare June 15, 2026 02:17
@laulpogan laulpogan merged commit 5327b68 into main Jun 15, 2026
12 checks passed
@laulpogan laulpogan deleted the fix/284-4-cli-wire-home-fail-fast branch June 15, 2026 02:22
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