Files
worldmonitor/todos/010-pending-p1-inferentityclassfromname-force-overmatch.md
Elie Habib 092efd4fe9 fix(panels): always fire background RPC refresh after bootstrap render (#2208)
* fix(panels): always fire background RPC refresh after bootstrap render

Bootstrap hydration (getHydratedData) is one-shot — once rendered from
it, panels never refresh and can show stale or partial data indefinitely.

Affected panels: MacroSignals, ETFFlows, Stablecoins, FuelPrices,
GulfEconomies, GroceryBasket, BigMac.

Pattern: render from bootstrap immediately for fast first paint, then
fire a background RPC call that silently updates the panel with live
data. Errors during background refresh are suppressed when bootstrap
data is already visible (no error flash over valid data).

* fix(panels): guard background RPC refresh against empty response overwriting bootstrap

Empty RPC responses (200 + empty array) no longer overwrite valid bootstrap
data with error/unavailable state across all 7 affected panels:

- ETFFlowsPanel, StablecoinPanel: wrap this.data assignment in
  `if (fresh.xxx?.length || !this.data)` guard
- FuelPricesPanel, GulfEconomiesPanel, GroceryBasketPanel, BigMacPanel:
  add `!data.xxx?.length` check in background .then() before calling render
- MacroSignalsPanel: return false early when error suppressed to skip
  redundant renderPanel() call

* fix(hormuz): fix noUncheckedIndexedAccess TypeScript errors

* fix(todos): add blank lines around headings (markdownlint MD022)

* fix(hormuz): add missing hormuz-tracker service + fix implicit any in HormuzPanel

* revert: remove HormuzPanel.ts from this branch (belongs in PR #2210)
2026-03-24 20:23:40 +04:00

2.3 KiB

status, priority, issue_id, tags
status priority issue_id tags
pending p1 010
code-review
deep-forecast
simulation-package
correctness

inferEntityClassFromName|force| overmatch misclassifies commercial entities as military_or_security_actor

Problem Statement

inferEntityClassFromName contains |force| as a standalone regex alternative. This matches any entity name containing "force" as a substring — including commercial names like "Salesforce", "Workforce Solutions", "Task Force [commodity]". Such entities are silently classified as military_or_security_actor and this misclassification is written verbatim into the simulation-package.json R2 artifact, which is consumed by downstream LLMs.

Findings

  • scripts/seed-forecasts.mjsinferEntityClassFromName, first regex branch:
    if (/military|army|navy|air force|guard|force|houthi|irgc|revolutionary|armed/.test(s)) return 'military_or_security_actor';
    
  • |force| without word boundaries matches "Salesforce", "Workforce", "Task Force Oil Logistics", etc.
  • air force (with space) already works correctly — the space is a literal match. The standalone |force| is redundant and dangerous.
  • Misclassified entity class propagates into exported simulation-package.json with no log or warning.

Proposed Solutions

if (/\b(military|army|navy|air\s+force|national\s+guard|houthi|irgc|revolutionary\s+guard|armed\s+forces?)\b/.test(s)) return 'military_or_security_actor';

Effort: Tiny | Risk: Low

Option B: Remove force entirely, rely on other terms

Remove |force| and |guard| (too broad) and add the specific IRGC/Houthi terms already present. Effort: Tiny | Risk: Low

Acceptance Criteria

  • inferEntityClassFromName('Salesforce Inc') returns 'exporter_or_importer' or 'market_participant', NOT 'military_or_security_actor'
  • inferEntityClassFromName('US Air Force') still returns 'military_or_security_actor'
  • inferEntityClassFromName('Houthi armed forces') still returns 'military_or_security_actor'
  • New unit tests for all three cases

Technical Details

  • File: scripts/seed-forecasts.mjsinferEntityClassFromName function

Work Log

  • 2026-03-24: Found by compound-engineering:review:kieran-typescript-reviewer in PR #2204 review