feat(crew): evidence on the thread log — prompt rule, --evidence tag, desktop cards, owner accept/reject (#121) - #128
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:
|
Author
This was referenced Aug 10, 2026
Merged
devin-ai-integration
Bot
force-pushed
the
devin/1786360062-evidence-thread-log
branch
from
August 11, 2026 09:29
df2a999 to
2aa2d6e
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> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.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> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.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> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.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> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.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> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.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> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com>
oscarlehuu
force-pushed
the
devin/1786360062-evidence-thread-log
branch
from
August 11, 2026 11:02
64d5bf9 to
9942078
Compare
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
Ships the #121 slice: an agent that reports "done" attaches the artifact it already produced, the desktop renders it as a card in the timeline, and the owner accepts or rejects it with a standard NIP-25 reaction the agent can read back. Evidence is a byproduct of work done properly — no computer-use anywhere in the flow, no new event kinds, no relay changes.
Wire contract (
D-036, see numbering note below):on the existing message kind. First occurrence wins; the CLI validates the enum value only (it cannot and does not verify that evidence exists); the renderer does not trust it — an unrecognized value falls back to the ordinary message body. Images ride the existing Blossom upload + NIP-92
imetapath.Design choices worth knowing before reading the diff:
EvidenceKind::append_tagtakes the already-builtEventBuilderand appends before signing (precedentcrates/buzz-cli/src/client.rs:590), sobuzz-sdkandbuzz-corekeep zero additional Crew delta.MessageRow.tsxwas at 980/1000 lines against the file-size ratchet. D-022 forbids raisingMAX_LINES, so the change there is +7 lines of prop pass-through only; the dispatch and all card logic live in Crew-ownedMessageRowDefaultBody.tsx/EvidenceCard.tsx/lib/evidenceTag.ts. Final: 987/1000,MAX_LINESuntouched.crates/buzz-acp/src/lib.rs), because the base prompt is paid on every turn of every agent — a fat section would violate the issue's own token-frugality principle. Actual: 13 lines.handleReactionSelect), souseReactionHandler.tsandMessageReactions.tsxare unchanged. Reject sends ❌ and opens the reply composer, because a bare ❌ leaves the agent nothing to act on. Controls are owner-only, reusing the receipt card's owner resolution rather than inventing a second owner concept.Known limit, documented in
DECISIONS.mdrather than only in the issue: evidence is self-reported and can be fabricated. This raises the cost of lying and the odds of getting caught (fabricated numbers diverge from CI, fabricated screenshots diverge from the app); it does not cryptographically verify work. Independent verification stays where it lives today: CI + PR review. Related non-claim: the ≤30-line evidence bound is a prompt rule and a probe check, never a runtime guard.Definition of Done → change
crates/buzz-acp/src/base_prompt.md(new self-contained## Evidence on completion, placed after Communication Patterns, before Engineering Discipline) · new "Upstream files Crew edits" table indocs/crew/UPSTREAM-SYNC.md(the list the issue referenced did not exist yet) ·docs/crew/upstream-proposals/evidence-on-completion.md— Crew-owned draft of the generic, Crew-free half. No PR, branch, or push againstblock/buzz(D-020, rootAGENTS.md); per the correction on the issue, the upstream contribution is a separate founder decision and is not a blocking DoD item.buzz messages send --evidence <kind>emits the validated tagcrates/buzz-cli/src/commands/evidence.rs(enum + exact-match parse, no aliases/case folding) ·--evidenceonMessagesCmd::Send·SendMessageParams.evidencethreaded throughcmd_send_messageEvidenceCard.tsx(metrics → compact number table; test-run → red→green blocks; diff-stat → summary + PR link reusingAgentReceiptCard's href resolver; before-after-visual → side-by-sideimetaimages degrading to captions + links) ·lib/evidenceTag.tstolerant parseEvidenceCardcontrols → existing kind-7 reaction handler; verdict derived from the owner's own reaction (nothing new persisted); agent-readable half needs no new CLI —buzz reactions get --event <id>already shipsdocs/crew/DECISIONS.mdD-036 ·docs/crew/STATE.md(anti-drift rule, #117)docs/crew/verification/0010-evidence-on-thread-log-probes.md· live probes + per-kind rendered card screenshots posted as a PR commentDecision numbering
Took D-036, the slot the orchestrator allocated to issue #121 (D-028/029/030 → PR #120, D-031/032 → PR #124, D-033 → PR #127, D-034 → PR #129, D-035 → issue #119) — the plan's assumed D-031 was long gone. Spike id 0021 and verification record 0010 for the same reason: parallel sessions are consuming the lower ids (#120 took spikes 0015-0017).
Related issue
Closes #121. Plan of record:
plans/20260810-evidence-thread-log/on PR #123 (9 phases, all executed except phase 09's live probes, which run against this PR).Testing
Spike first (
docs/crew/spikes/0021-evidence-tag-roundtrip.md, verdict PASS) — the whole wire design depended on an unknown Crew-invented tag surviving the kind-9 path, which was unproven: an unknown tag on kind 9 round-tripped publish → relay ingest → Postgres →/querybyte-identically,formatTimelineMessageskept it onTimelineMessage.tags,applyEditTagOverlaypreserved it across an edit, and a normal reply in the same thread kept correctthread_metadatacounters. Mobile/web ignore-safety is source-level evidence, not a running-client test.Then contract tests RED before implementation, per the repo workflow. Observed RED reasons (each a genuine absence, on a built e2e bundle):
GREEN after implementation:
Also green:
pnpm --filter buzz check,pnpm --filter buzz typecheck,cargo fmt --check,cargo clippy --all-targets -- -D warnings,just test-unit,just check-compile,desktop/ pnpm check:px-text,node scripts/check-file-sizes.mjs.just ci's mobile leg (dart format) hangs in this environment, so the Rust/desktop gates were run individually.Beyond the four card contracts, the non-regression contracts are pinned too: a message with no
crew-evidencetag renders exactly as today; an unrecognized kind value renders the ordinary body rather than a broken card; aKIND_AGENT_RECEIPT(46043) message carrying the tag keeps its receipt card and does not grow a second evidence card; a non-owner sees the card without Accept/Reject controls; a third party's ❌ does not display the card as rejected.CI: 9 passed / 2 failed / 1 skipped. The two red lanes are smoke shards whose failures all reproduce on clean
origin/mainrun 31362178966 —channel-activity-popover.spec.ts:459,channels.spec.ts:500(#110),inbox-edit.spec.ts:175/325,inbox-reactions.spec.ts:36,messaging.spec.ts:1819;Desktop Smoke E2E (4)is the known 30-minute cancellation lane (#109).channel-activity-popover.spec.tswas additionally reproduced locally on a cleanorigin/mainworktree at35af74019(toHaveCount(2) → Received: 1). No evidence-related check is red. One earlierDesktop Rustfailure (Text file busy (os error 26)spawning the provider binary) went green on the next head — recorded as transient in verification record 0010.Phase 09 live probes ran against a real local relay plus the headless Playwright harness — results, per-kind rendered card screenshots and the
buzz reactions getagent read-back are in this comment, recorded indocs/crew/verification/0010-evidence-on-thread-log-probes.md. One limit stated there rather than glossed: the e2e bridge'sadd_reactionis mock-only (e2eBridge.ts:9528-9571), so probe 1 is two halves — the desktop half proves the emitted kind-7's target event id and the card's accepted/rejected states, the relay half proves a kind-7 lands on a real relay and is agent-readable viabuzz reactions get. No single run exercises click → relay end to end, since a real Tauri run would need computer-use, which this issue bans. Tracked as a harness gap in #133, not worked around here.Link to Devin session: https://app.devin.ai/sessions/dc642c6db0de4d11b8f47f98a3f1e6fc
Requested by: @oscarlehuu