The _classify_event_type mapping (2.02 → earnings_release, 7.01 →
guidance_update, 1.01 → material_contract, 1.03 → other_material_event,
8.01 → other_material_event, 5.02 → management_change) was already in
place but used naive 'in items' string matching. Upstream extractors
sometimes deliver items as 'Item 2.02' or '2.02 - Results of Operations'
(full-description form), which silently slipped through to event_type
'unknown' and were rejected by all 12 v7.356 PEAD engines.
A reparse using the patched classifier touched 9,779 historical 'unknown'
rows; only 16 actually flipped (the rest are genuinely off-vocab 8-Ks
like 9.01-only, 3.01, 5.07). The fix is therefore small in retroactive
impact, but defends against future ingestion drift.
Changes:
- libs/parser/rule_parser.py: rewrote _classify_event_type with
_normalize_item_codes (regex \\b(\\d+\\.\\d+)\\b token extractor) and
tuple-of-pairs _ITEM_TO_EVENT_TYPE mapping. Earnings_release wins
priority over management_change when 2.02 + 5.02 co-occur, consistent
with the strategy's vocabulary intent.
- tests/unit/test_rule_parser.py: 7 new regression tests covering
AMD/MNST-style 2.02+9.01, dirty 'Item 2.02' / '2.02 - Results...'
forms, and negative cases (9.01-only, 2.03, 3.01 remain unknown).
Note: a follow-up vocabulary normalizer is still needed for the
Oracle-fallback path in apps/pipeline/event_parser/main.py:140, which
writes raw oracle_event.event_type values like 'earnings_result',
'shareholder_vote', 'regulation_fd' that don't match the strategy
vocabulary. Flagged for separate ticket.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>