AntFleet

Anatomy · f5ac807a-0

Sharp-move dedup window violates idempotency under same-minute reruns

mediumbugclosed in 4b9b492
repo 6f7fc663·PR #23·reviewed 1 week ago·closed 1 week ago

The vulnerable code

skills/price-threshold-alert/SKILL.md:156-162

156```
157*$TOKEN — New ATH — ${today}*
158
159$TOKEN just printed a new all-time high at $X.XXXXe-N.
160Previous ATH: $Y.YYYYe-N (set ${prior_ath_age} ago).
16124h move: ±Z.Z% · 1h move: ±W.W%
162

The reasoning

Opus

Sharp-move dedup window violates idempotency under same-minute reruns

mediumbughigh
  • skills/price-threshold-alert/SKILL.md:156-162
  • skills/price-threshold-alert/SKILL.md:270-271
The constraint promises idempotency under same-minute reruns, but the sharp-move step writes `last_alerts.sharp_move = NOW` every time it fires. If the run is re-executed within the same minute with the same price input, the first run sets last_alerts.sharp_move to T0; the second run sees that timestamp within 4h and dedups. That is consistent. However, the ATH gate (Step 4) only updates `state.ath.announced_at` for the baseline case; for a real ATH it updates `observed_at` but does not specify updating `announced_at`/`last_alerts.ath`. The spec says "Notify only if the last ath alert was >4h ago" but never tells the implementer to set `last_alerts.ath = NOW` on a real ATH notification. Consequently, a re-run with the same higher price would: (a) see CURRENT_PRICE not strictly greater than the just-updated `ath.price_usd`, so `new_ath=false` — actually safe. But the missing `last_alerts.ath = NOW` write means if a later run sees an even higher price within 4h, the dedup check has stale data and the alert fires again, which is fine — but the documented dedup clock is never advanced for ATH alerts in the spec text, making the 4h dedup unreachable in practice. This is a spec/contract gap.

Recommendation

In Step 4, explicitly require setting `state.last_alerts.ath = NOW` when an ATH notification is sent (and `state.ath.announced_at = NOW`). This mirrors Step 5's explicit `last_alerts.sharp_move = NOW` write.

GPT-5

Output unavailable for this row.

The agreement

Both frontier models flagged this within the same line range. AntFleet's unanimous gate fired — the finding posted on the PR. Closed in 4b9b492.

The fix

156```
157*$TOKEN — New ATH — ${today}*
158
159$TOKEN just printed a new all-time high at $X.XXXXe-N.
160Previous ATH: $Y.YYYYe-N (set ${prior_ath_age} ago).
16124h move: ±Z.Z% · 1h move: ±W.W%
162

Closure

Closed 1 week ago

SHA: 4b9b49251c8c9808bf147d55aa2930352af2e8c0

View closure receipt on GitHub →

Tweet thread template

tweet 1 of 8152 / 280

Two frontier models reviewed PR #23 on 6f7fc663. Both found this bug: medium bug: Sharp-move dedup window violates idempotency under same-minute reruns

tweet 2 of 8131 / 280

The vulnerable code (skills/price-threshold-alert/SKILL.md:156-162): (full snippet at https://www.antfleet.dev/anatomy/f5ac807a-0)

tweet 3 of 8280 / 280

What Opus saw: "The constraint promises idempotency under same-minute reruns, but the sharp-move step writes `last_alerts.sharp_move = NOW` every time it fires. If the run is re-executed within the same minute with the same price input, the first run sets last_alerts.sharp_move…

tweet 4 of 837 / 280

What GPT-5 saw: "Output unavailable"

tweet 5 of 897 / 280

Both flagged the same line range. AntFleet's unanimous gate fired — the finding posted on the PR.

tweet 6 of 893 / 280

The fix landed in commit 4b9b492: (view diff at https://www.antfleet.dev/anatomy/f5ac807a-0)

tweet 7 of 881 / 280

AntFleet reviews every PR with two frontier models. Only unanimous findings post.

tweet 8 of 877 / 280

Full anatomy + reasoning + diffs: https://www.antfleet.dev/anatomy/f5ac807a-0

Paste into X composer one tweet at a time. X has no multi-tweet intent API.