feat(e2e): relay-backed add_reaction so a headless click publishes a real kind-7 - #146
Merged
Merged
Conversation
Author
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
This was referenced Aug 11, 2026
devin-ai-integration
Bot
force-pushed
the
devin/issue-133-relay-add-reaction
branch
3 times, most recently
from
August 11, 2026 02:52
413afe3 to
697ca6c
Compare
This was referenced Aug 11, 2026
devin-ai-integration
Bot
force-pushed
the
devin/issue-133-relay-add-reaction
branch
11 times, most recently
from
August 11, 2026 14:44
8689f03 to
306f7ca
Compare
Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com> Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com> Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com> Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com> Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com> Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…an main Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com>
devin-ai-integration
Bot
force-pushed
the
devin/issue-133-relay-add-reaction
branch
from
August 11, 2026 15:05
306f7ca to
b13eb59
Compare
This was referenced Aug 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The desktop e2e bridge's
add_reactionwas mock-only, so relay mode could not make a headless click publish anything:handleAddReactionlooked the target up in the mock store and synthesized a kind-7. Only the transports (plugin:websocket|*) branched on relay mode. That is why #121's owner Accept/Reject had to be proven in two halves (desktop click on the mock bridge, kind-7 on the relay via thebuzzCLI) with no single run covering click → relay.Mutating handlers now follow the convention the message/channel handlers already use — branch on
getIdentity(config)(non-null only in relay mode), publish viasubmitSignedEvent, and skip mock-store bookkeeping because the real WebSocket subscription supplies the echo:Each relay branch mirrors its Rust command exactly —
add_reaction→ kind 7 with only the targetetag (events.rs::build_reaction),remove_reaction→ relay-query the caller's own kind-7 then kind 5 on the reaction id (build_remove_reaction),delete_message→ kind 5 withh+e(build_delete_compat),set_canvas→ kind 40100 withh(build_set_canvas). No reaction semantics, kinds, or evidence tags change — D-036 stands.The audit is the real payload.
docs/crew/verification/0011-e2e-bridge-relay-mutation-audit.mdclassifies every mutating bridge command: (a) already relay-aware, (b) mock-only in relay mode — the trap, where a spec passes while never reaching the relay, (c) legitimately local-only. The four cheap (b) cases above are fixed here; the four that need real design (send_managed_agent_channel_messageneeds an agent signing identity,send_channel_user_input_answer,update_persona_and_publish,archive_identity/unarchive_identity) are filed as #144 with evidence. Class-(c) rows inferred only from the bridge side (workflows, save subscriptions/archive_events) are marked unconfirmed from the Rust side rather than asserted, and #144 tracks confirming them.New decision D-042 (slot assigned by the orchestrator; D-028…D-039 are taken by in-flight PRs) records the rule: a mutating bridge command with a real Nostr event behind it publishes in relay mode, and one that cannot must be listed in 0011 with its reason.
Basing: branched off
devin/1786360062-evidence-thread-log(PR #128, issue #121) because the evidence cards and verification record 0010 live there and are not onmainyet. Targetsmain, so this diff carries #128's commits until #128 lands.Related issue
Closes #133. Depends on #128 (#121). Files #144 for the remaining mock-only mutations. Verification record for the gap this closes:
docs/crew/verification/0010-evidence-on-thread-log-probes.md(its split-probe limitation now points at the closing evidence).Testing
New headless spec
desktop/tests/e2e/evidence-reactions-relay.spec.ts(integration project — the relay-backed lane; smoke has no relay). In one run it publishes an evidence-tagged kind-9 to a real local relay, clicksevidence-accept, then pollsPOST /queryfor the resulting event and asserts kind 7 / owner pubkey /✅content /etag on the evidence id — then the same forevidence-rejectwith❌, plus the reply composer still opening.Mock-path regression set (
evidence-reactions,evidence-cards,reaction-order,reaction-names,inbox-reactions,custom-emoji,empty-edit-delete,--project=smoke): 28 passed, 1 failed —inbox-reactions.spec.ts:36("Toggle ❤️ reaction" not visible). Verified preexisting: it fails identically in a clean worktree at the base commitdf2a9995e, output in record 0011.pnpm --filter buzz checkandtypecheckclean.Known limit, stated in 0011 rather than papered over: the agent-ownership metadata for the card is still injected via bridge config (
mock.searchProfiles) — publishing an owner-authenticated kind-0 for the test identities needs plumbing the headless harness lacks. The evidence message and the entire reaction path are real relay state, so the claim supported is "a headless click publishes a real kind-7 to a real relay", not agent-profile provenance.No computer-use anywhere in the verification path (per #121).
Where this evidence stops — no CI lane, deliberately: the
integrationproject (all 17 relay-backed specs, of which this is the only Crew-specific one) runs only in the inheritedci.yml, which Crew disabled on purpose as part of the CI minimisation (docs/crew/CI.md: "Upstream Sync does not run the inherited integration or cross-platform matrices"). The lane is upstream-owned (block/buzza1c28f487d, still active upstream) and costs 2ubuntu-latestshards at ~6m45s/~6m17s (run 30533242569) needing Postgres + Redis + MinIO, a builtbuzz-relay, schema + community seed,setup-desktop-test-data.shand a Playwright install. The active workflow'sProject Relayjob provisions its own stack inside its script and jobs don't share services, so a Crew lane means duplicating all of that — not a small addition, so it stays with #147 (which also owns the required-vs-advisory call; D-032's posture argues advisory). Record 0011 carries the numbers and exact local-run commands so the spec is runnable without rediscovering any of it.remove_reaction's relay branch throwscould not find your reaction event for this emojion no match, matching the Rust command rather than diverging silently; the mock path's preexisting silent no-op is untouched.Desktop Smoke E2Eshards 1/3 red: six of the failures reproduce on clean-main(run 31362178966, shard 1),inbox-reactions.spec.ts:36reproduces on the base commit, andchannels.spec.ts:1951/:2108reproduce on PR #128's parentdf2a9995e— inherited from the base branch, not from this diff. Per-test baseline with job URLs is in 0011. The requiredNuncioCrew Gateis green.Link to Devin session: https://app.devin.ai/sessions/bae615c82bdc4b5bb116dcf221f47d4c
Requested by: @oscarlehuu