Delete single-send P2P crypto trade asks Laya keeps under the gate (#142) #48

Merged
backmeupplz merged 13 commits from feat/142-crypto-trade-rule into main 2026-10-19 17:35:51 +00:00
backmeupplz commented 2026-10-19 14:23:18 +00:00 (Migrated from github.com)

Closes agentboard #142.

What

Adds a third structural ad rule, crypto_trade_ask, next to the #124 and #126 rules. It targets unsolicited P2P crypto buy/sell asks that Laya keeps under the 0.80 gate. The incident was "Всем привет, есть кто продаёт усдт? Напишите, договоримся." (0.7404, sent once, so the repeat boost never applied).

The rule matches a shape, not wording. It needs three parts on the existing promoText normalization (lookalikes, case, emoji):

  1. A trade intent: a counterparty sought ("есть кто продаёт", "кто может продать", "у кого купить", "anyone selling", "who can exchange") or the author's own trade ("куплю/продам/обменяю", "WTB", "will buy", line-start "Обмен …"). Venue questions ("где/как купить", "where can I buy"), negated trades and hedged market talk ("куплю биток, если упадёт") don't count.
  2. A crypto asset as the traded object, next to the verb: USDT with its spellings (усдт/юсдт/юстд, lookalikes), tether/тезер, крипта, BTC/битки, ETH, TON, etc. Goods paid in crypto ("Продам iPhone, оплата в USDT") are excluded.
  3. A deal cue: a DM call, a bare "напишите/пишите", "договоримся", rate terms ("по адекватному курсу"), a volume, cash or in-person, or a contact handle or t.me link. Web links and bare price levels don't count.

It plugs into promoPattern, so it gets the existing 0.30 floor, the promo_pattern_detected log with pattern: "crypto_trade_ask", the audit and stats path, and the cleanup of earlier repeat copies. Reports, warnings, quoted text, attributed reposts, addressed messages, doubts and replies to another member's crypto/trade question all stay kept. The prompt, the model and the 0.80 gate are unchanged, with no retraining.

Replay (prod capture, latest request per message)

window matches model ≥0.80 new deletions 0.30–0.80 under floor FP in new
119,836 texts, 12.8 days (Oct 6–19) 52 45 5 2 0
last 8.7 days 46 42 4 0 0

The 5 new deletions are 35320, the #124 asks 34977 and 34979, an earlier copy 34781, and an English "Who can exchange my 2.4k$ in bank to crypto, DM me" ask. The side-gig and testimonial match sets are identical to main, and the crypto match set has been identical across review rounds 4–10.

Tests

  • promo-patterns.test.ts: the incident, the #124 asks and "will buy usdt, any amount" match standalone, as channel comments and forwarded. Held-out paraphrases match, crypto controls never match, requested answers are tested, and adversarial 4096-char inputs stay linear.
  • A pinned review corpus (src/fixtures/crypto-trade-corpus.ts: 815 ads and 846 conversations from eleven independent review rounds and the fe81e3b and e7df6ab reviews) keeps its exact outcome, with known residuals listed (80 ads left to the model, 53 conversations that still match). Tokens that are also common words (TON, TRX, эфир, Solana) count only in trade context, crypto-themed goods ("BTC майнер", "crypto wallet Ledger") are goods with or without a hyphen, and rule reminders that quote a trade ad ("…здесь запрещены", "…— бан", "not allowed") stay kept.
  • bot.test.ts: single sends at 0.7404 and 0.6407 and an edit into an ask are pattern-deleted, with logs, audit and stats checked. Controls at 0.79 and requested answers stay kept, and an ask under the floor only logs.
  • bun run check: typecheck clean, 661 pass / 0 fail.
Closes agentboard #142. ## What Adds a third structural ad rule, `crypto_trade_ask`, next to the #124 and #126 rules. It targets unsolicited P2P crypto buy/sell asks that Laya keeps under the 0.80 gate. The incident was "Всем привет, есть кто продаёт усдт? Напишите, договоримся." (0.7404, sent once, so the repeat boost never applied). The rule matches a shape, not wording. It needs three parts on the existing `promoText` normalization (lookalikes, case, emoji): 1. A trade intent: a counterparty sought ("есть кто продаёт", "кто может продать", "у кого купить", "anyone selling", "who can exchange") or the author's own trade ("куплю/продам/обменяю", "WTB", "will buy", line-start "Обмен …"). Venue questions ("где/как купить", "where can I buy"), negated trades and hedged market talk ("куплю биток, если упадёт") don't count. 2. A crypto asset as the traded object, next to the verb: USDT with its spellings (усдт/юсдт/юстд, lookalikes), tether/тезер, крипта, BTC/битки, ETH, TON, etc. Goods paid in crypto ("Продам iPhone, оплата в USDT") are excluded. 3. A deal cue: a DM call, a bare "напишите/пишите", "договоримся", rate terms ("по адекватному курсу"), a volume, cash or in-person, or a contact handle or t.me link. Web links and bare price levels don't count. It plugs into `promoPattern`, so it gets the existing 0.30 floor, the `promo_pattern_detected` log with `pattern: "crypto_trade_ask"`, the audit and stats path, and the cleanup of earlier repeat copies. Reports, warnings, quoted text, attributed reposts, addressed messages, doubts and replies to another member's crypto/trade question all stay kept. The prompt, the model and the 0.80 gate are unchanged, with no retraining. ## Replay (prod capture, latest request per message) | window | matches | model ≥0.80 | new deletions 0.30–0.80 | under floor | FP in new | |---|---:|---:|---:|---:|---:| | 119,836 texts, 12.8 days (Oct 6–19) | 52 | 45 | 5 | 2 | 0 | | last 8.7 days | 46 | 42 | 4 | 0 | 0 | The 5 new deletions are 35320, the #124 asks 34977 and 34979, an earlier copy 34781, and an English "Who can exchange my 2.4k$ in bank to crypto, DM me" ask. The side-gig and testimonial match sets are identical to `main`, and the crypto match set has been identical across review rounds 4–10. ## Tests - `promo-patterns.test.ts`: the incident, the #124 asks and "will buy usdt, any amount" match standalone, as channel comments and forwarded. Held-out paraphrases match, crypto controls never match, requested answers are tested, and adversarial 4096-char inputs stay linear. - A pinned review corpus (`src/fixtures/crypto-trade-corpus.ts`: 815 ads and 846 conversations from eleven independent review rounds and the fe81e3b and e7df6ab reviews) keeps its exact outcome, with known residuals listed (80 ads left to the model, 53 conversations that still match). Tokens that are also common words (TON, TRX, эфир, Solana) count only in trade context, crypto-themed goods ("BTC майнер", "crypto wallet Ledger") are goods with or without a hyphen, and rule reminders that quote a trade ad ("…здесь запрещены", "…— бан", "not allowed") stay kept. - `bot.test.ts`: single sends at 0.7404 and 0.6407 and an edit into an ask are pattern-deleted, with logs, audit and stats checked. Controls at 0.79 and requested answers stay kept, and an ask under the floor only logs. - `bun run check`: typecheck clean, 661 pass / 0 fail.
Sign in to join this conversation.
No description provided.