docs(research): mock bridge has five dead handlers and one backend-less tested handler (#344) - #438
Conversation
…d but harmless (#344) Signed-off-by: tucktuck101 <jeffreytaylorrobertson@gmail.com>
serina-mcfall
left a comment
There was a problem hiding this comment.
Blocker — it is five dead handlers, not six, and "no test path reaches them" is false
complete_identity_recovery_pairing is driven by a registered, running spec:
$ git grep -n "complete_identity_recovery_pairing" -- 'desktop/tests/**' 'desktop/src/testing/**'
desktop/src/testing/e2eBridge.ts:13257: case "complete_identity_recovery_pairing":
desktop/tests/e2e/identity-lost.spec.ts:280: "complete_identity_recovery_pairing",
$ git grep -n "identity-lost" -- desktop/playwright.config.ts
desktop/playwright.config.ts:122: "**/identity-lost.spec.ts",
$ git grep -rn "fn complete_identity_recovery_pairing" -- desktop/src-tauri/
(no match — the handler is mock-only)
Three things break together:
- The count is wrong — in the PR title, the frontmatter description and the finding. Five, not six.
- "They cannot mislead a test, because no test path reaches them" is false, and it is the sole support for "the drift is currently harmless." A registered spec invokes this command and then asserts a UI transition. A green spec exercising a command with no backend implementation at all is very close to the exact failure mode the note declares is not present.
- Recommendation 2 — "I would delete the six dead handlers" — would break a registered spec if actioned as written.
On the harmlessness question specifically: it is measured for direction 2 and asserted for direction 1, and the direction-1 assertion is the one that does not hold. Your direction-2 argument is genuinely evidenced — an unmocked command throws with its own name in the message, so missing coverage cannot produce a false pass. That reasoning is good. It just does not transfer.
Medium — the single-grep generalisation is what produced the above
The note runs grep -rln "pick_team_directory" desktop/, gets one file back, and generalises "the only file in the repository that mentions them is e2eBridge.ts" to all six. Running the grep per name would have caught complete_identity_recovery_pairing. Worth naming in the note itself, because the method is reusable and the failure is the interesting part.
Medium — e2eBridgeCustomHarnesses.ts contributes nothing to the 259
259 commands are handled by
e2eBridge.tsande2eBridgeCustomHarnesses.ts, counted from theircase "…"labels.
$ git show 5d76799d:desktop/src/testing/e2eBridgeCustomHarnesses.ts | grep -c 'case '
0
All 259 come from e2eBridge.ts alone. The figure is right; the attribution to a second file that contributes zero will send whoever re-runs the count into the wrong place.
What is right — every quantitative figure reproduced exactly
This is the most mechanically accurate part of the note, and it is worth saying so plainly:
| Figure | Note | Recount |
|---|---|---|
#[tauri::command] attributes |
322 | 322 |
Registered at lib.rs:604 |
312 | 312 |
| Mock handlers | 259 | 259 |
| Direction 1 (mock-only) | 9 | 9 |
| Direction 2 (backend-only) | 62 | 62 |
e2eBridge.ts length |
13,450 | 13,450 |
| Playwright specs | 146 | 146 |
The throwing fallback at e2eBridge.ts:13424 is real, and all six named handlers genuinely have no fn <name> anywhere under desktop/src-tauri/.
That accuracy is exactly what makes the one error hard to spot — the nine mock-only handlers were found correctly; it is the step from "mock-only" to "dead" that skipped a check. Everything else here stands.
Reviewed at head 16c0cf72d. The spec invocation and its registration were verified by me directly.
🤖 Review drafted by Claude Code (claude-opus-5) for @serina-mcfall.
Signed-off-by: tucktuck101 <jeffreytaylorrobertson@gmail.com>
Review panel — two independent reviewers (Fable, gpt-5.6-sol xhigh), consolidatedSummary: The prior review's blocker (six→five, the falsified "no test path reaches them") is genuinely fixed and threaded through the whole note, and every figure the note derives by its own method reproduces exactly (Fable re-derived all of them: 322/312, 259 by the note's extraction, the 9 and 62 sets, 13,450 lines, 146 specs, High
Medium
What looks good
Panel: fable + gpt-5.6-sol (codex, xhigh), independent reviews consolidated by the lane; the consolidator re-verified the deciding findings (277-label count, pairing-event seam) directly against the repo. Author is tucktuck101, so this is a comment, not a formal review — needs an external reviewer once addressed. Posted under Jeff's standing authorization. |
serina-mcfall
left a comment
There was a problem hiding this comment.
Re-review — the blocker is addressed. Three Highs filed as issues; no blocker remains.
Agent-authored under @serina-mcfall's instruction. I do not approve; this records what I verified.
Blocker (six dead handlers is five, and "no test path reaches them" is false) — fixed, and threaded properly. The finding, the direction-1 analysis, the recommendation and the confidence section all carry the correction, and :68-69 documents the methodological error that produced it — checking one name and generalising to six. That candour is the most reusable part of the revision.
Medium (e2eBridgeCustomHarnesses.ts contributed zero labels) — fixed. :33 now says so explicitly.
Three Highs, filed rather than blocked
I verified each of these myself at origin/launchpad rather than adopting them from the panel comment above:
- #513 —
:20still says "Six handlers for commands that exist nowhere in the repository", which is the exact wording the note's own correction falsified.:54already has the accurate phrasing. - #514 — the 259 mock-handler count is a de-duplication artifact.
grep -o 'case "[^"]*"' | sort -ugives 277, of which 18 are colon-namespaced (plugin:websocket|connectand friends); 277 − 18 = 259 exactly. Four of the dropped labels are the websocket commands the note's own caveat calls unexpanded — that surface is mocked, and enumerable. - #515 —
complete_identity_recovery_pairingis a test seam, not drift. The mock ate2eBridge.ts:13259emitspairing-complete, the same event the real backend emits atpairing.rs:439/:546and thatIdentityRecoveryPairing.tsx:86listens for. The spec invokes it to stand in for an async native callback; production never calls it.
None of the three is a blocker under this repo's rubric: the note's central claim — nothing detects mock/backend mismatch — survives all of them, and the five genuinely dead handlers are correctly identified. #515 is the one I would most want fixed before this is cited, because it changes what the note says the risk is.
Nothing else new. Every figure the note derives by its own stated method reproduces: 322/312, the 9 and 62 difference sets, 13,450 lines, 146 specs, and identity-lost.spec.ts:280.
Reviewed at head b3f947592; counts run at origin/launchpad. The 277-label recount and the pairing-event wiring were both checked by me directly, not taken on report.
🤖 Review drafted by Claude Code (claude-opus-5) for @serina-mcfall.
Summary
Answers #344 by extracting both command sets and diffing them. The mock bridge has drifted — six handlers stand in for commands that exist nowhere in the repository — but the drift is currently harmless, because an unmocked command throws rather than returning a default. The real finding is that nothing detects drift at all.
Related issue
Closes #344
Issue type
Task
Agent provenance
Objective
Add
launchpad/Research/344-mock-bridge-drift.mdcomparing the commands the E2E mock bridge handles against the commands the Tauri backend registers, in both directions.Impacted components
launchpad/Research/344-mock-bridge-drift.md
Approach and rejected alternatives
Diffed the two sets mechanically with
comm, then chased each difference to a verdict rather than reporting the counts. That mattered: of the nine commands the mock handles without a backend counterpart, three are deliberate test-only helpers and six are dead residue, and a bare "9 mismatches" would have implied nine problems.Then checked the mock's
default:branch before drawing any conclusion about severity. That single line is what determines whether the 62-command gap is dangerous or benign, and it turns the answer from "the mock may be reporting false green" into "it cannot".Rejected treating the 62 unmocked commands as a coverage gap to close. The mock is deliberately partial and the throw makes partiality safe; mocking commands no spec exercises would add surface for no assurance. That reasoning is in the document's recommendations section, marked as opinion.
Verification
Command run:
Raw output:
Not verified
Return-shape fidelity was not examined at all, and it is the more dangerous question. This is a name-level comparison. A mocked command whose name matches but whose return value has drifted from the real Rust signature would pass every check here and could produce a false green. That applies to all ~250 commands the mock does handle and is unmeasured; establishing it means comparing each handler's returned shape against its Rust function's return type.
The second handler at
native_websocket.rs:325was not expanded. Its commands are not among the 312 counted fromlib.rs, so a few of the "unmocked" 62 may be registered there and the real total is above 312.The 259 figure comes from
case "…"labels. If the bridge dispatches some commands another way — a lookup table, a prefix match — those are uncounted.Whether the mock's partiality is documented anywhere was not established. No specs were run — #322 established this host cannot resolve pnpm.
That nothing detects drift is negative evidence — I found no such check, which is not the same as proving none exists.
Security implications
None added by the document. One observation: the six dead handlers name a removed team import/export flow (
pick_team_directory,install_team_from_directory,export_team_to_json), so the mock retains a description of filesystem-touching commands the application no longer has. Unreachable, but misleading to read.Escalations