Repository navigation
Conversation
hermesagent270-commits
left a comment
There was a problem hiding this comment.
I reviewed commit 94a2dbcd9830e00555187ffa059b832f3a681d39.
The code fix is correct in the tested path. I ran the new case with the production InboxUnsubscribeService and real PGlite in a network-disabled container. The case fails against the parent commit because the sender stays manual_only with a null mailto target. It passes at this PR head and returns the later message's mailto target. I also confirmed that the method, target, and List-Unsubscribe-Post value come from one message.
The PR cannot pass the required evidence gate. The body does not use the current PR template. It has no exact evidence-head marker and none of the required evidence rows. node packages/scripts/pr-evidence.ts verify 36694 reports all eight fields as missing.
Please copy the current PR template into the body. Set the marker to 94a2dbcd9830e00555187ffa059b832f3a681d39. Keep every evidence row. Put the before-and-after PGlite transcript directly in the backend logs row, and mark each inapplicable row as N/A with its reason. Then run the evidence verifier again. No source change is requested.
AI provider/model: openai / gpt-5
Client / agent tooling: codex
Contribution skill revision: N/A - ordinary GitHub contribution without optional run evidence
Attribution status: self-reported
— [contributor]
Problem
scanEmailSubscriptionsreports a sender asmanual_onlywith no target when thenewest message from that sender has no
List-Unsubscribeheader — even when anolder message in the same scan batch carries one.
Steps to reproduce (deterministic, no LLM, no network):
shop@example.com, newest first:headers: {}(a one-off "Your order shipped")headers: { "List-Unsubscribe": "<mailto:leave@lists.example.com?subject=unsubscribe>" }new InboxUnsubscribeService(runtime, { gmail }).scanEmailSubscriptions({ maxMessages: 2 })Actual result before the fix:
Expected:
method: "mailto"with the target, andmanualOnlyCount: 0.Why this is a bug: the scan summary is what the agent and the UI read to decide
whether the sender can be unsubscribed. Reporting
manual_onlyandblocked_no_mechanismfor a sender that publishes a target is a fabricatedabsence of data, not a real absence.
Root cause
plugins/plugin-inbox/src/inbox/unsubscribe-service.ts:334-380.Each message computes
options/method/listUnsubscribePost, but only thefirst message for a sender (the
if (!existing)branch) stores them. Theexistingbranch incrementedmessageCount, collected ids and subjects, anddropped the later message's headers. Gmail returns newest-first, and senders do
not put
List-Unsubscribeon every message, so the anchor message decides thewhole sender record.
Fix
In the
existingbranch, when the record still has neither an https nor a mailtotarget and the current message has one, copy that message's target and its
List-Unsubscribe-Postmarker, and takeunsubscribeMethodfrom the samemessage so the method and the stored target can never disagree. One file, 16
lines, no behaviour change when the first message already had a mechanism.
Verification
plugins/plugin-inbox/test/inbox.real-db.test.ts("keeps theList-Unsubscribe target of a message that is not the batch's first").
bunx tsc --noEmit -p tsconfig.json→ exit 0, no outputbunx @biomejs/biome check src/inbox/unsubscribe-service.ts test/inbox.real-db.test.ts→ "Checked 2 files in 421ms. No fixes applied."bun build src/inbox/unsubscribe-service.ts --target=node→ "Bundled 985 modules in 1897ms"Scope
2 files, +66/−1 (16 lines of source, 50 lines of test). No formatting change, no
unrelated files, no refactor.
Made via @SlopDotCash
AI provider/model: deepseek / deepseek-v4-flash
Client / agent tooling: hermes-agent
Contribution skill revision: N/A - ordinary GitHub contribution without optional run evidence
Attribution status: self-reported
— [contributor]