镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

feat(cli): tag the target author on buzz reactions add - #9121

Open
bostonaholic wants to merge 6 commits into
mainfrom
bostonaholic--cli-reaction-p
Open

bostonaholic wants to merge 6 commits into
mainfrom
bostonaholic--cli-reaction-p

Conversation

@bostonaholic

@bostonaholic bostonaholic commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Why

NIP-25 says a reaction should carry a p tag naming the author of the reacted-to event. Without that tag an author cannot query reactions to their own messages with a #p filter. The buzz-app Activity reactions tab (block/buzz-app#2638, merged) is built on that query. buzz-app's own publishers already add the tag.

What

  • buzz reactions add now looks up the target event and adds ["p", <target author>] to the reaction. This covers both plain emoji and custom emoji (--emoji-url).
  • The target lookup reads from the writer (consistency: strong), so a message published moments ago isn't missed during replica lag.
  • If the lookup returns nothing, the reaction is sent without p and the relay decides. A reader-scoped lookup leaves out system channels and, for non-members, unlisted open channels, even though the sender can react there. If the target really doesn't exist, the relay's rejection (invalid: reaction target event not found) reaches the user unchanged. A failed lookup (auth, network, relay error) still stops the command before anything is sent.
  • The mobile app gets the same tag in feat(mobile): tag the reacted-to message author on reactions #9141.
  • No change to the SDK builders, buzz-acp status reactions (👀 and similar), or the desktop app. Agent status reactions therefore keep no p tag and stay out of the Inbox.

Testing

  • New unit tests run against a fake relay. Each behavior test fails without its change:
    • a plain reaction carries the p tag
    • a custom emoji reaction carries the p tag
    • the target lookup sends consistency: strong
    • a target the lookup can't see is still reacted to, without p
    • the relay's rejection reaches the user as written
    • a failed lookup sends nothing (guards existing behavior)
  • buzz-cli suite: 687/687 passed on the branch merged with current main. cargo clippy -p buzz-cli --all-targets -D warnings and cargo fmt --check are clean.
  • I ran the built binary against a stub HTTP relay (no local relay with these channel types was set up on this machine). Capture below.
  • Not yet done: a run against a real local relay, and the human test from the AGENTS.md checklist.

Demo

Built target/debug/buzz (0a1bbb9) run against a stub relay. In the stub, aaaa… is readable, cccc… exists but an unscoped read can't see it (like a system channel), and bbbb… doesn't exist:

$ buzz reactions add --event aaaa…aaaa --emoji "👍"   # readable target
{"accepted":true,"event_id":"aadc4727…","message":""}
exit 0
$ buzz reactions add --event cccc…cccc --emoji "👍"   # exists, hidden from an unscoped read
{"accepted":true,"event_id":"c963d6b9…","message":""}
exit 0
$ buzz reactions add --event bbbb…bbbb --emoji "👍"   # does not exist
{"error":"relay_error","message":"relay error 400: invalid: reaction target event not found","retryable":false}
exit 2

relay query [{"consistency": "strong", "ids": ["aaaa…"], "limit": 1}]
relay received kind:7 tags=[["e","aaaa…"],["p","35c18ae2…"]]
relay received kind:7 tags=[["e","cccc…"]]
relay received kind:7 tags=[["e","bbbb…"]]

How a human can test

  1. Against a local relay, send a message as user A: buzz messages send --channel <id> --content hi.
  2. As user B, run buzz reactions add --event <that id> --emoji "👍".
  3. Sign in as user A in a current buzz-app build and open Activity → Reactions. It works if a "B reacted 👍" row appears for that message. Without this change, no row appears.
  4. Run buzz reactions add --event <64 hex chars that don't exist> --emoji "👍". It works if this prints the relay's reaction target event not found and exits 2.
  5. React to a message in a system channel you belong to. It works if the reaction is accepted.

🤖 Generated with Claude Code

NIP-25 says a reaction should carry a `p` tag naming the author of the
reacted-to event. Without it, an author cannot find reactions to their
own messages with a `#p` filter, which the Buzz Inbox reactions feed
(block/buzz-app#2646) reads.

`buzz reactions add` now fetches the target event, adds
`["p", <target author>]`, and fails with not_found when the target is
not readable (the relay already rejects reactions to unknown targets).
buzz-acp status reactions and the desktop app keep the bare SDK
builders, so agent status reactions stay out of the Inbox.

Co-authored-by: mboston Implementer <932d3b6ebea6cc83e091551ae46d1c7e7f8f7d0fa8e9cef5e6facc8544af413b@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Matthew Boston <mboston@squareup.com>
@bostonaholic

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-09T17:50:46.469631Z 0a1bbb9 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🚀

Reviewed commit: 5fec7f94e7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@bostonaholic
bostonaholic marked this pull request as ready for review November 5, 2026 18:30
@bostonaholic
bostonaholic requested a review from a team as a code owner November 5, 2026 18:30
@github-actions github-actions Bot added the codex-security-review-current The posted Codex security review matches its recorded range. label Nov 5, 2026
@github-actions

github-actions Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

🔐 Codex Security Review

Note: This is an automated, security-focused review generated by Codex.
Use it as a supplement to human review; false positives are possible.

Scope

  • Exact PR diff: ab399231c29ab31d982769b6f235ea06bee312c1...30e216ec09cb59fc29a8d86cecf71274524a09d3
  • Model: gpt-6.1-sol

💡 Click "edited" above to see earlier reviews for this PR.


Review Summary

Overall Risk: MEDIUM

The new target-author lookup introduces two reliability regressions that can reject valid reactions.

Findings

[MEDIUM] Preserve channel scope when resolving the reaction target

  • Category: Reliability
  • Location: crates/buzz-cli/src/commands/reactions.rs:38 (source)
  • Description: The new mandatory lookup supplies only the event ID. The bridge excludes system channels from implicit query scope even for members, and excludes unlisted open channels for nonmembers unless the filter names the channel. Consequently, an authorized caller reacting to a message in either case receives NotFound before submission. Previously, reaction ingestion resolved the channel directly from the target and applied the normal write authorization checks.
  • Impact: CLI reactions stop working for messages in system channels and for authorized nonmembers of unlisted open channels.
  • Recommendation: Allow callers to supply the target channel and include its #h constraint in the author lookup, preserving the relay's channel access checks.

[MEDIUM] Use strong consistency for the mandatory target lookup

  • Category: Reliability
  • Location: crates/buzz-cli/src/commands/reactions.rs:38 (source)
  • Description: Without consistency set to strong, the bridge dispatches this lookup through query_events_routed. When replica routing is enabled, a recently accepted message can still be absent from the replica. The successful empty response becomes NotFound and aborts the reaction. Previously, reaction ingestion looked up the target through get_event_by_id_for_event_write on the writer.
  • Impact: Reacting to a just-published or live-delivered message can fail intermittently during replication lag, despite the target existing and being writable.
  • Recommendation: Add consistency set to strong to this filter so the write prerequisite reads from the writer.

Notes

  • No additional limitations were reported.

Generated by Codex Security Review |
Requested by: @bostonaholic |
Workflow run

Co-authored-by: mboston Implementer <932d3b6ebea6cc83e091551ae46d1c7e7f8f7d0fa8e9cef5e6facc8544af413b@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Matthew Boston <mboston@squareup.com>
@github-actions github-actions Bot added codex-security-review-current The posted Codex security review matches its recorded range. and removed codex-security-review-current The posted Codex security review matches its recorded range. labels Nov 5, 2026
@bostonaholic
bostonaholic marked this pull request as draft November 5, 2026 21:55
bostonaholic added a commit that referenced this pull request Nov 9, 2026
## Why

NIP-25 says a reaction should carry a `p` tag naming the author of the
reacted-to event. buzz-app's Activity → Reactions tab
(block/buzz-app#2638, merged) finds reactions to your messages with a
`#p` read. Reactions sent from mobile have no `p` tag, so they never
appear there. #9121 makes the same change for `buzz reactions
add`.

## What

- Every reaction sent from mobile now carries `["p", <message author>]`.
This covers the reaction pill, the quick-reaction row, the emoji picker,
and reactions on system rows.
- Removing a reaction is unchanged.
- Agent status reactions (buzz-acp) and the desktop app are unchanged by
decision. Agent status reactions stay out of Activity.

## Testing

- New unit test: `ChannelActions.addReaction` publishes exactly `["e",
target]` and `["p", author]`. It fails without the change (actual tags:
`[['e', 'target-event']]`).
- The message-actions widget test now checks that a quick reaction
passes the message's author.
- `just mobile-check`: format and `flutter analyze` are clean (no
issues).
- `just mobile-test`: 4,507 passed, plus the push-unconfigured and
secp256k1 suites. All pass.
- No screenshots: the change is one tag on the published event, and
nothing on screen changes.
- Not yet: a run on a device, and the human test.

## How a human can test

1. On mobile, as user B, react 👍 to a message from user A.
2. As user A, open Activity → Reactions in a current buzz-app build.
3. It works if a "B reacted 👍" row appears. Before this change, no row
appears.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: Matthew Boston <mboston@squareup.com>
Co-authored-by: mboston Implementer <932d3b6ebea6cc83e091551ae46d1c7e7f8f7d0fa8e9cef5e6facc8544af413b@buzz.block.builderlab.xyz>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@bostonaholic
bostonaholic marked this pull request as ready for review November 9, 2026 16:19
bostonaholic and others added 4 commits November 9, 2026 10:27
The target lookup gates the write, so a read replica that has not caught
up must not turn a just-published message into not_found.

Co-authored-by: mboston Implementer <932d3b6ebea6cc83e091551ae46d1c7e7f8f7d0fa8e9cef5e6facc8544af413b@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Matthew Boston <mboston@squareup.com>
…ction-p

* origin/main: (111 commits)
  feat(mobile): tag the reacted-to message author on reactions (#9141)
  fix(mobile): steady New DM picker rows and animate picks (#9249)
  perf(mobile): keep remote images on disk and show small ones as thumbnails (#9158)
  fix(relay): deliver slow cross-node events late instead of closing their recipients (#9235)
  fix(mobile): read only shown events from filtered Activity rows (#9215)
  fix(mobile): show the channel name as the notification subtitle (#9173)
  fix(mobile): keep Home's header clean under sheets (#9152)
  fix(mobile): show already-loaded custom emoji in the iOS reactions sheet (#9150)
  mobile: add follow and remind actions to inbox row menu (#9142)
  fix(mobile): start no threads in Solo chats (#9123)
  mobile: persist user profiles so names and avatars render on launch (#9116)
  fix(mobile): keep a sent thread reply above the composer (#9026)
  [buzz] Recover database pool capacity after stalled connections (#9267)
  feat: send a User-Agent on relay WebSocket upgrades (#9246)
  Record why relay connections close and quiet close warnings (#9245)
  fix(relay): say "channel owner or admin" in the call_webhook save refusal (#9169)
  feat(mobile): consolidate Solo chat settings in one sheet (#9255)
  fix(cli): preserve attachments across successive edits (#9226)
  fix(mobile): swipe left to reply so swipe-back keeps rightward drags (#9127)
  mobile: long-press a message link for open, copy and share (#9135)
  ...

Signed-off-by: Matthew Boston <mboston@squareup.com>
main changed BuzzClient::new to take Credentials.

Co-authored-by: mboston Implementer <932d3b6ebea6cc83e091551ae46d1c7e7f8f7d0fa8e9cef5e6facc8544af413b@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Matthew Boston <mboston@squareup.com>
An ids-only read leaves out system channels and, for non-members,
unlisted open channels, so the CLI returned not_found for reactions the
relay accepts. An empty lookup now submits without `p` and the relay
decides; its rejection reaches the user unchanged. Lookup errors still
fail before submitting.

Co-authored-by: mboston Implementer <932d3b6ebea6cc83e091551ae46d1c7e7f8f7d0fa8e9cef5e6facc8544af413b@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Matthew Boston <mboston@squareup.com>
@bostonaholic

Copy link
Copy Markdown
Contributor Author

🤖 Both findings in the security review (#9121 (comment)) are fixed.

  • Strong consistency: fixed in 20dd96a. The target lookup now sends consistency: strong, as other write-gating reads in the CLI do (channels.rs). Covered by add_reaction_reads_target_from_the_writer, which failed without the fix.
  • Channel scope: fixed in 0a1bbb9. When the lookup returns nothing, the CLI sends the reaction without p and the relay decides, which is what it did before this PR. A failed lookup still stops the command before anything is sent. If the target doesn't exist, the relay's invalid: reaction target event not found reaches the user unchanged. Covered by add_reaction_to_unreadable_target_submits_without_p_tag and add_reaction_shows_the_relay_rejection_verbatim, which both failed before the change, and by add_reaction_fails_without_submitting_when_target_lookup_errors. With feat(relay): index reactions under their target author for #p reads #9285 deployed, the relay derives the recipient for reactions sent without p.

@bostonaholic

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

Reviewed commit: 0a1bbb9da3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

This branch was previously deployed

1 inactive (outdated) deployment
codex-review — 30e216ec Deployed Nov 5, 2026 by bostonaholic via Run Codex Security Review #12914
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

codex-security-review-current The posted Codex security review matches its recorded range.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant