fix(remote-crew): allow same major.minor peers and surface create failures - #8543
Conversation
Design Review (Fable 5) — 🟡 CONCERNSDesign-level review of Design review complete. The stable-channel problem is real and the fix is sound; one compatibility-contract gap is worth surfacing. Design-Verdict: CONCERNS Series parity is right for stable releases but silently waves through prerelease skew, exactly where the frame vocabulary moves fastest. Watch
Suggestions
[DESIGN-REVIEWED] fe6decb |
GPT 5.6 Review — ✅ no blocking findingsGPT 5.6 completed its review of This comment is updated in place on each push. Review detailsFINDING -- src/kiro_crew/dashboard/remote_relay.py:151 -- [GPT-REVIEWED] fe6decb False positive or not applicable? A repository writer can comment: |
UX Review (Fable 5) — ✅ PASSUX-level review of The diff checks out against the frontend patterns — UX-Verdict: PASS Silent no-op becomes an inline, announced, actionable error at the point of click — the fix lands where the user's attention already is. Suggestions
[UX-REVIEWED] fe6decb |
Opus 4.8 Review — ✅ no blocking findingsReviewed Verdict parsed from the review's SHA-scoped output markers for commit False positive or not applicable? A repository writer can comment: |
First Principles Review (Fable 5) — 🟡 CONCERNSPremise-level review of All checks complete. Here is the review. First-Principles-Verdict: CONCERNS Both fixes sit at cause level and reuse existing mechanisms — but the swallowed-rejection cause has five counted, unfixed siblings in the same file. What this change shipsIntent: make "New chat on crew" stop failing silently on routine version skew — a FIX (two causes).
Watch
[FIRST-PRINCIPLES-REVIEWED] fe6decb |
ace71dc to
db9ee68
Compare
|
The hand-written
|
Per website/AGENTS.md ("Never a hand-written
|
db9ee68 to
aafe8f5
Compare
aafe8f5 to
fe6decb
Compare
Problem / Motivation
Creating a session on a connected crew (New chat menu → New chat on crew → pick a crew) failed silently: no session appeared in the local sidebar list, none was created on the remote crew, and no error was shown — the click read as a no-op.
Two independent causes:
ensure_version_parity) required the peer'skiro_crew.__version__to match the local build byte-for-byte, so any build skew refused the create before the peer was ever asked to open a session.createRemoteChatMutationhadonSuccessbut noonError, so react-query swallowed the resulting 502 and nothing surfaced.Why it matters
The create opens the peer session before the local slot and, by design, leaves nothing behind on failure. So a version skew — the common case right after an update lands on one end but not the other — made "New chat on crew" look broken with no diagnosis, and users had no way to tell it was a version issue rather than a bug.
What changed (motivation → approach → change)
ensure_version_paritynow compares themajor.minorseries, not the full string.0.6.0and0.6.3interoperate;0.6.xvs0.7.xis still refused — a feature release moves the unversioned frame vocabulary the two ends exchange, and on a 0.x line that axis is the minor (the major stays 0). Added_version_series()to parse the leading semver. When either side is not semver-shaped (a packaging build id replaces__version__at build time), compatibility cannot be proven by series, so it falls back to strict full-string equality. The refusal message now says "same major.minor version".createRemoteChatMutationgains anonErrorthat surfaces the backend reason inline in the submenu (newremoteCrewErrorstate + a truthiness-gated error line). The reason is read off the rejected value's.message: RTK's.unwrap()rejects with a SerializedError plain object, not anError, so aninstanceof Errorguard would have dropped the message. Crew rows useonSelect+preventDefaultso a failed create keeps the menu open long enough to read the error, while a successful create moves focus to the composer (which closes the menu).Tests
test/test_remote_crew_execution.py:test_a_patch_skew_in_the_same_series_passes— samemajor.minor, different patch is allowed.test_a_different_minor_is_refused— a minor bump is refused and the message namesmajor.minor.test_a_non_semver_build_id_falls_back_to_strict_equality— a build id compares by full-string equality.catalogParity(77) and the ChatSidebar suites pass;tsc -bandeslintclean. No new user-facing string was added — the failure text comes from the backend, already localized byapiFailure.Manual verification
N/A — unit coverage is sufficient for the version gate. The frontend change is a conditional error line whose steady state is unchanged; reproducing the live surface needs a connected peer at a mismatched
major.minor, which a unit test cannot stage.Screenshots / video
Why no screenshot: the only rendered change is a conditionally-shown error line in the "New chat on crew" submenu that appears solely when a remote create fails, and it requires a live version-mismatched or unreachable peer to trigger. The steady-state (no-error) sidebar is pixel-identical.
Related Issues
no linked issue: field-reported behaviour after #7693 landed; no tracking issue was filed.
Pattern harvest
Rule candidate: review-prompt
Pattern: a react-query
useMutationwhosemutationFndispatches a thunk.unwrap()but declares noonErrorsilently swallows the rejection — a user-visible action that "leaves nothing behind" on failure must surface the reason. Corollary for the extraction:.unwrap()rejects with a SerializedError plain object, soerr instanceof Erroris false; read.messageoff the object.Checklist
feat|fix|docs|refactor|perf|test|chore|ci|build|revert: ...)