upstream(sync): Tier 1 security — mention auth + relay skills guard + RUSTSEC-2026-0258 - #306
Conversation
🤖 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:
|
DONEAll five scoped upstream ports are implemented and locally verified.
Tests added: Gates (run individually; full
Evidence (on the session VM, also attached to the session): RED/GREEN logs IN PROGRESSNothing. The working tree is clean, the branch is pushed at TODO / NEXT
|
… (upstream block#5681) Ported from block/buzz bcf353c. Crew keeps its extracted useMentionSendComplete hook, explicit-empty imeta edit save, removed-mention diff and Project workspace resolution; upstream revalidation is layered on top. Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com>
…tream block#6224, block#6338) Ported from block/buzz 3fdf289 and the block#6338 follow-up. Crew keeps its inline list_relay_agents directory command and invoke.rs handler macro; the bounded send-time check lands as a new commands::mention_authorization module instead of upstream's relay_directory.rs rewrite. Cross-owner relay agents stay mentionable in owner-only builds when relay policy plus bot-role membership authorize them; Crew's RelayAgent has no ownerPubkey field, so admission is derived from respondTo/allowlist and channel membership rather than owner identity. Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com>
…ock#6394) Ported from block/buzz d274a6e. Adds the base-prompt restriction plus a regression test asserting the guard stays in the shared prompt. Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com>
) Ported from block/buzz cc8a8b0. Only the h2 entry is bumped; upstream's incidental windows-sys re-resolution churn is left out to keep the lockfile diff scoped. Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com>
…test The owner-only cross-owner case still surfaces the not-in-channel invite prompt before publication, so the test must accept it to observe the outgoing p tag. Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com>
Edit-save revalidation stripped denied agents from mentionPubkeys but the non-notifying reference tags were built before revalidation, so a revoked agent's pubkey was still published and rendered as an agent chip. Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com>
Main now requires ownerPubkey on RelayAgent. Restore the mapping that lived in the previous merge resolution so send-time revalidation stays type-correct after the rebase. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: oscarlehuu <oscarlehuu@users.noreply.github.com>
ca39305 to
98ed7b4
Compare
Main's #306 revalidation renamed the explicit-agent guard. The source-inspection test still required the old local name after rebase. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: oscarlehuu <oscarlehuu@users.noreply.github.com>
…303) * feat(desktop): bounded selection + visible-page agent context (#272) Port the upstream Projects agent-context payload builders (block#6368, block#6396) onto Crew's channel-first composer: an explicit-agent send now carries a bounded, injection-safe description of what the sender is looking at (channel, thread, repository/branch, PR) as a hidden reference line. Crew keeps its own chrome: the context is mounted by Crew-owned channel and thread composer providers, not by upstream Projects overview tabs, context pods, a Projects rail, or a Workbench. Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com> * fix(desktop): scope visible-page context to pages with workspace selection The channel dock and bare thread replies show nothing the agent cannot derive from the message it already receives, so attaching hidden context there changed the sent content of every agent mention (regressing the mentions E2E contract). Visible-page context now requires the thread chrome to contribute a repository/branch or PR selection. Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com> * fix(desktop): match view-context wiring test to mention-auth guard Main's #306 revalidation renamed the explicit-agent guard. The source-inspection test still required the old local name after rebase. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: oscarlehuu <oscarlehuu@users.noreply.github.com> --------- Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Oscar Le <oscar.lehuu@gmail.com> Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: oscarlehuu <oscarlehuu@users.noreply.github.com>
Summary
Ports the Tier 1 security slice of the Buzz 0.5.18 sync (upstream block#5681, block#6224, block#6338, block#6394, block#6222) onto Crew, keeping Crew's architecture where it diverges from upstream.
agentAutocompleteEligibilitynow answers a three-state admission (allow/deny/unknown) and unknown fails closed, so an agent pubkey that cannot be proven authorized never reaches aptag.agentMentionRevalidationre-checks the requested agent mentions immediately before publication, andsubmitMessageEditre-checks added mentions before an edit is saved — so an authorization revoked between compose and send (or between edit and save) drops the mention instead of pinging the agent. On the edit path the denied pubkey is also removed from the non-notifyingmentionreference tags, so a revoked agent is neither published nor rendered as an agent chip.revalidate_relay_agents(pubkeys, channel_id)indesktop/src-tauri/src/commands/mention_authorization.rsqueries the relay with exact author filters for only the requested pubkeys, plus a kind:39002 membership filter narrowed by#p(viewer) and, when sending into a channel,#d(destination channel). Onlyrole=botmembership admits an agent; a spoofed membership event without the bot role is rejected. No unbounded directory sweep.respondToallowlist /anyone) and channel membership authorize it, instead of rejecting it purely because the profile owner differs from the viewer.crates/buzz-acp/src/base_prompt.mdforbids discovering/loading relay-backed skills unless the authorizing human names the skill, treats an explicitly requested relay skill's content as untrusted input that cannot override higher-priority instructions, and exempts bundled/local skills. Covered by a prompt regression test incrates/buzz-acp/src/lib.rs.h2bumped to 0.4.16 inCargo.lock.Crew divergences from upstream (intentional)
useMentions,useMentionSendFlow,useMentionSendComplete,submitMessageEdit) and threads revalidation through them.relay_directory.rs; the bounded authorization lives in a new sibling command module and Crew's inlinelist_relay_agentsis untouched (also keeps theagent_discovery.rsfile-size ratchet green).RelayAgenttype has noowner_pubkey, so the Fix cross-owner relay agent mentions in owner-only builds block/buzz#6338 port derives cross-owner admission from relay policy + membership rather than from an owner field.h2bump applies upstream's lockfile change only; upstream's incidentalwindows-sysre-resolution churn is excluded to keep the lockfile diff scoped.Related issue
Fixes #281. Part of the 0.5.18 sync stack tracked by #285. No duplicate PRs found.
Testing
TDD: RED logs captured before implementation (
red-desktop-unit.log,red-acp-6394.log), then GREEN after.Gates (all run individually —
just cinot run, its mobiledart formatleg hangs here):pnpm --filter buzz checkpnpm --filter buzz typecheckpnpm --filter buzz testjust test-unitbuzz-cli(3) +buzz-db(1) failures reproduce identically on unmodifiedmain(baseline logs attached) — pre-existing, untouched by this diffjust check-compilecargo test -p buzz-acp --libcargo test --lib mention_authorization(Tauri)mentions.spec.tsSecurity before/after (
cargo audit, same tree, onlyCargo.lockdiffers):main):h2 0.4.11— RUSTSEC-2026-0258 "h2 unbounded empty DATA frames", solution>=0.4.16UI evidence, full-viewport via the E2E mock bridge (whole app: sidebar + channel + composer):
Cross-owner relay agent authorized by allowlist in an owner-only build — before (autocomplete) and after (sent with the mention
ptag):Authorization revoked mid-send — before (mention selected in composer) and after (message published without the agent
ptag):DONE
All five scoped upstream ports are implemented and locally verified.
agentAutocompleteEligibilitythree-state admission (allow/deny/unknown, unknown fails closed);agentMentionRevalidationre-checks mentions immediately before publication;useMentionSendCompleterecomputes the explicit agent audience from the final admitted set;submitMessageEditre-checks added mentions before save and now also strips denied pubkeys from the non-notifyingmentionreference tags.revalidate_relay_agents(pubkeys, channel_id)indesktop/src-tauri/src/commands/mention_authorization.rs(exact author filters for requested pubkeys only, kind:39002 membership narrowed by#pviewer and#ddestination channel,role=botrequired), registered incommands/mod.rs+invoke.rs, frontend wrapper inshared/api/tauriRelayAgents.ts, mock support intesting/e2eBridge.ts.RelayAgenthas noowner_pubkey).crates/buzz-acp/src/base_prompt.md+ regression testshared_base_prompt_guards_unrequested_relay_skillsincrates/buzz-acp/src/lib.rs.h20.4.16 inCargo.lockonly (no unrelatedwindows-syschurn).Tests added:
agentAutocompleteEligibility.test.mjs(unauthorized / unresolved / selected-agent filtering),submitMessageEdit.test.mjs(edit-save revalidation, upload-pause revalidation, denied/admitted reference-tag cases), 5 Rust tests inmention_authorization.rs(query bounds, channel narrowing, bot-role filtering, multi-channel accumulation), ACP prompt regression test, and E2E cases indesktop/tests/e2e/mentions.spec.ts.Gates (run individually; full
just cinot run — its mobiledart formatleg hangs in this environment):pnpm --filter buzz checkpnpm --filter buzz typecheckpnpm --filter buzz testjust check-compilecargo test -p buzz-acp --libcargo test --lib mention_authorization(Tauri)mentions.spec.tsjust test-unitbuzz-cli(3) +buzz-db(1) failures — reproduce identically on unmodifiedmain, pre-existingcargo auditmain, absent on this branchEvidence (on the session VM, also attached to the session): RED/GREEN logs
red-desktop-unit.log,red-acp-6394.log,green-acp-6394.log,red-edit-mention-tags.log,green-edit-mention-tags.log; gate logsgate-pnpm-check.log,gate-pnpm-typecheck.log,gate-pnpm-test.log,gate2-*.log,gate-just-test-unit.log,gate-just-check-compile.log; securitycargo-audit-before-main.log,cargo-audit-after.log— all under/home/ubuntu/evidence/. Full-viewport adversarial E2E screenshots01a–06andTEST-PLAN.mdunder/home/ubuntu/evidence-281/, plus recording/home/ubuntu/screencasts/pr306-mentions/pr306-mentions-edited.mp4.IN PROGRESS
Nothing. The working tree is clean, the branch is pushed at
fa7de1b32, and every scoped item is implemented with tests passing.TODO / NEXT
NuncioCrew CIruns on this branch were deliberately cancelled by the parent session (org Actions pool is serialized). No genuine CI failure was observed on this change; a re-run is still needed for a green signal. Do not treat the cancellation as a failure.#p/#dfilters, and a real ACP agent actually replying to an admitted mention — both were exercised only through the E2E mock bridge and unit tests.mainincluding the sibling mobile parity work (upstream(sync): Mobile UI — upstream 0.5.12–0.5.18 parity #305). Further conflicts are most likely indesktop/src/features/messages/ui/(send/edit hooks) andCargo.lockif another sync PR bumps dependencies..agents/skills/desktop-e2e-adversarial/SKILL.mdupdate documenting the mention-authorization E2E recipe was sent as a skill-PR suggestion rather than included here.Link to Devin session: https://app.devin.ai/sessions/d3b9f71580154edbbeef438e63ce6e57
Requested by: @oscarlehuu