Repository navigation
Description
Problem
amountFromBody in pm-stack/aggregator/scripts/produce-charge-candidates.ts:169-186 treats future and negated charge wording as paid evidence. The verb-evidence tier added today in PR #3193 (commit d6dfa4c1, the Codex-P2 follow-up to #3120) is:
/\b(?:charged|paid)[:\s]*\$([\d,]+\.\d{2})/i // line 175It matches the verb wherever it appears, with no check on what precedes it, and it runs before #3120's due-language veto (lines 178-182). So a body that says the money has not moved — or has not moved yet — yields an amount, and gmailCandidates (line 235: amount ??= amountFromBody(text)) turns it into a charge candidate for the message's date.
Evidence (verified this run, 2026-10-31)
Laptop probe ~/git/fleet/probe-2026-10-31-laneA-chargeverb/ (on the laptop): the real produce-charge-candidates.ts from origin/main, sha256 999f2dd904924bc718aa278f209441656e85da05db75aa33c6a95e6d8b0eefe3 — identical on the sandbox and laptop clones — imported under bun test. Control passes; all five target cases return an amount today and should return undefined:
| Body | Today | Expected |
|---|---|---|
Receipt\nYou were charged $20.00 for OpenAI\nBalance due $0.00 (control, PR #3193's own test) |
"20.00" |
"20.00" |
Your subscription renews Nov 5\nYou will be charged $20.00 on Nov 5 |
"20.00" |
undefined |
Reminder: your card will be charged $42.50 tomorrow |
"42.50" |
undefined |
Invoice\nAmount to be paid $20.00 by Nov 15\nAmount due $20.00 |
"20.00" |
undefined |
The attempt failed. You were not charged $20.00 |
"20.00" |
undefined |
Good news: your card was never charged $20.00 for this order |
"20.00" |
undefined |
Result: 1 pass / 5 fail (probe.txt in the probe dir).
Why it matters
This is exactly the class #3120 closed today — money that is merely due, scheduled, or explicitly not charged becoming a charge candidate — re-entering through the fix's own new tier:
- A renewal/reminder mail ("will be charged … tomorrow") becomes a candidate dated the reminder's day, then the real charge arrives later and the pipeline carries both (or dedupes against the wrong date).
- An invoice body's "to be paid $X" defeats the due veto that is the whole point of lines 178-182: the veto only runs when the paid tiers found nothing.
- A failure/declined body that reassures "you were not charged $X" produces the candidate fix(aggregator): charges producer turns declined purchase alerts and outstanding invoices into charge candidates (PR #2149) #3120's subject gate was built to stop, whenever the subject itself doesn't carry a gated word (the Gmail body read at line 235 is reached for receipt/invoice subjects whose subject carried no amount).
Acceptance criteria
amountFromBodyreturnsundefinedfor future forms:will be charged $X,will be charged $X tomorrow/on <date>, andto be paid $X.amountFromBodyreturnsundefinedfor negated forms:not charged $X,never charged $X,was not charged $X,will not be charged $X.- Genuine past-tense evidence still wins exactly as PR fix(aggregator): charges producer — reject declined alerts and amount-due-only invoices (#3120) #3193 requires:
You were charged $20.00(including with a trailingBalance due $0.00line),Paid $20.00,Amount paid $21.60,Total charged $21.60all return their amounts. - The fix(aggregator): charges producer turns declined purchase alerts and outstanding invoices into charge candidates (PR #2149) #3120 due-only cases still return
undefined(Amount due $20.00,Balance due: $42.50). - New tests in
pm-stack/aggregator/test/produce-charge-candidates.test.tspin the future and negated cases above; the existing fix(aggregator): charges producer turns declined purchase alerts and outstanding invoices into charge candidates (PR #2149) #3120/fix(aggregator): charges producer body fallback matches 'total' inside 'Subtotal', recording the subtotal as the charge (PR #2149) #3121 tests still pass.
Related: #3120 (closed by PR #3193 — this is a residual in that fix, not a reopen: the subject gate and due veto themselves work as designed), #3121 (the sibling body-fallback issue), #3161 (the charges evidence contract design).
Activity
dezren39 commentedon Oct 31, 2026
🤖 Agent note · filed
dezren39 commentedon Oct 31, 2026
Intake review
Related: PR #3193 (the verb-evidence tier this is a residual of) and #3120 (the due-language veto it bypasses).
Notes: Verified by the filer's laptop probe against the real
produce-charge-candidates.ts(origin/main, sha256 recorded in the body): 1 control pass / 5 target fails — future ("will be charged"), scheduled ("to be paid") and negated ("not charged", "never charged") wording all return amounts today. The body already carries acceptance criteria, so no body change was made.Risks: Money-path sensitivity: a fabricated "paid" candidate misstates charges in the aggregator. The negation/future guard must not over-veto genuine receipts (the PR #3193 control case must keep passing).
Suggested approach: Add a pre-tier guard in
amountFromBody— reject verb matches preceded by future/negation markers (will be,to be,not,never) within a small window — and promote the body's six-row probe table to a pinning test.— fleet monitor intake, 2026-10-31 fleet-monitor run (17:12 CDT)
5 remaining items
dezren39 commentedon Nov 2, 2026
agent-note:v1 — picked up
Agent: repo-worker-code (OpenChamber scheduled lane)
Task: repo-health-code-pilot task 5677 (small_fix)
At: 2026-11-02T10:53:33Z
State: picked-up
Found via: atomic queue claim; no saved progress.
Next: Fresh metadata confirms #3224 OPEN with no open matching PR. I will reproduce the false-positive cases on current main, implement the narrow verb-tier guard, run targeted tests, and open a PR or park before the run budget expires.
Links: #3224 · task 5677
dezren39 commentedon Nov 2, 2026
agent-note:v1 — handed-off
Agent: repo-worker-code (OpenChamber scheduled lane)
Task: repo-health-code-pilot task 5677 (small_fix)
At: 2026-11-02T11:00:36Z
State: handed-off
Outcome: PR #4333 opened at fd87ced to fix #3224. Targeted parser tests pass; CI is pending.
Links: #3224 · #4333 · task 5677
dezren39 commentedon Nov 2, 2026
agent-note:v1 — done
Agent: repo-worker-code (OpenChamber scheduled lane)
Task: repo-health-code-pilot task 5677 (small_fix)
At: 2026-11-02T11:00:47Z
State: done
Outcome: PR #4333 OPEN, issue #3224 OPEN pending merge. CI checks were pending at completion. Task labels cleared; no sandbox backlog or sweep-log changes made.
Links: #3224 · #4333 · task 5677