v2.10.0
career-ops-hq/career-opsv2.10.0Sep 8, 2026by github-actions[bot]
AI Summary
This major release focuses on resilience monitoring, international language support, and data ingestion enhancements. It introduces new features for company monitoring, military intelligence, and resilience tracking with USDA food stocks and education dimensions.
Key Highlights
- Added Traditional Chinese (zh-TW) and Swahili language support
- Enhanced company monitoring with sealed offline prediction custody
- New resilience features including USDA food stocks and education dimension
- Military defense industrial intelligence added
- Improved resilience tracking with acceptance outcomes comparison
New Features
- i18n: Add Traditional Chinese (zh-TW) locale
- i18n: Add Swahili language support
- webmcp: Expose safe live dashboard controls
- resilience: Ingest USDA food stocks and expose stocks-to-use
- resilience: Activate the education dimension
- resilience: Add flag-dark education dimension to the Country Resilience Index
- company-monitoring: Seal offline prediction custody
- data: Mineral production & processing shares (USGS MCS / BGS)
- preflight: Preflight system dependencies instead of failing mid-build
- military: Add defense industrial intelligence
- markets: Correlate news volume with market returns
- company-monitoring: Classify and admit material impacts
- company-monitoring: Ingest verified X posts
- company-monitoring: Add bounded Exa cohort discovery
- mcp: Expose story corroboration to agents
Full Release Notes
## What's Changed - chore(release): automate desktop release train (#6586) - docs(sources): reconcile provider and host counts (#6582) - docs: publish panel implementation count (#6584) - fix(license): put AGPL title first for detection (#6576) (#6583) - fix(docs): point Mintlify OpenAPI download at real bundle (#6578) - fix(license): expose AGPL text to scanners (#6576) (#6579) - docs(about): update GitHub star count (#6580) - fix(panels): deliver boot data to panels that mount after the pass (#6567) - fix(resilience): fail closed on malformed blend inputs (#6570) - fix(resilience): make whole-index pair gaps CI-visible (#6572) - fix(resilience): activate financial system exposure safely (#6568) - fix(resilience): compare acceptance outcomes, not gate config (#6566) - fix(seeders): seed-bundle-resilience defers every section forever — #6531's budget is below every section's timeout+grace (#6564) - fix(sentry): admit every app-serving host to the allowUrls ingest gate (#6565) - fix(csp-filter): suppress the Google Fonts /l/font subsetting endpoint (TR round 7) (#6560) - fix(sentry): the anonymous trampoline hop is '?' at runtime, not '' (#6554) - fix(railway): stop recovery approval emails and retry failures (#6551) - feat(i18n): add Traditional Chinese (zh-TW) locale (#6546) - feat(i18n): Add Swahili language support (#5406) - feat(webmcp): expose safe live dashboard controls (#6516) - fix(sentry-triage): convex OCC conflict herds + Y4 trampoline gate hole (#6547) - ci: let the acceptance-artifact validator run on the PR that commits one (#6544) - refactor(markets): one stablecoin classifier instead of three copies (#6541) - docs(resilience): commit the education post-flip acceptance artifact (#6460) (#6542) - feat(resilience): ingest USDA food stocks and expose stocks-to-use (#6531) - fix(resilience): condition the fin-sys integration premium on parent diversity (#6529) - feat(company-monitoring): seal offline prediction custody (#6534) - feat(data): mineral production & processing shares (USGS MCS / BGS) (#6527) - feat: preflight system dependencies instead of failing mid-build (#6387) - fix(railway): bound reconcile fanout and evidence reads (#6539) - fix(compose): wire relay shared secret (#6540) - feat(military): add defense industrial intelligence (#6536) - feat(markets): correlate news volume with market returns (#6530) - fix(ops): publish Railway drift as an independent check (#6533) - fix(resilience): unblock education acceptance capture (#6532) - fix(auth): restore readable input text in Clerk modal (#6535) - fix(ops): make the Railway deploy-drift alarm carry signal (#6141) (#6522) - fix(resilience): activate non-DRS debt imputation (#6526) - fix(ci): invalidate stale deploy gate statuses (#6525) - fix(railway): keep protected recovery reachable (#6524) - fix(docs): repair the Mintlify deploy break and the lint that missed it (#6521) - fix(sources): require explicit provider retirement (#6514) - docs(platform): add customer evaluation guide (#6518) - fix(resilience): stop absence from scoring as strength (#6515) - fix(ingestion): publish Military-Bases seed metadata (#6471) - fix(resilience): rebuild healthy education cohort (#6517) - fix(sources): show readable provider names (#6512) - fix(ci): recover deploy gate from API failures (#6513) - fix(sources): publish complete provider catalog (#6509) - fix(resilience): stop a transient seed-meta read failure from faking a dead producer (#6503) - ci(e2e): upload Playwright traces when variant-smoke-full fails (#6496) (#6497) - fix(welcome): stop internal CTAs minting affiliate codes, and guard every path to checkout (#6493) (#6504) - chore(gitignore): ignore public/sources/ and tie the rule to the build (#6498) (#6506) - docs(solutions): capture the self-comparing gate failure shape (#6487) (#6502) - fix(sources): let the attribution drift gate see reference drift (#6487) (#6499) - docs(openapi): document billing-verification 503 + ForbiddenError.code on gated ops (#5496) - fix(sentry): filter the round-6 TR package-CDN webfonts (unpkg, jsDelivr) (#6495) - docs(company-monitoring): remove provider approval claims (#6494) - test(company-monitoring): add sealed evidence curation gate (#6488) - docs(usage-errors): make Retry-After authoritative over the backoff schedule (#6485) - feat(resilience): activate the education dimension (#6460) (#6473) - docs(sources): domain-segmented data-sources catalog + /sources marketing page (#6491) (#6492) - fix(energy): let the IEA country keys re-export seededAt, and give the guard test a fixture that can fail (#6489) (#6490) - fix(feeds): point Tuoi Tre at its canonical host so Feed Validation stops blocking the news-health publish (#6484) (#6486) - fix(premium): honor the retryable billing-verification 503 on premium RPCs (#6482) - ops(webmcp): enroll dashboard origins and enforce security gates (#6465) - fix(ci): let the post-merge monitor survive a blip and name the real cause (#6479) (#6481) - fix(railway): let the watchdog go red, retry the read path, and stop the gate walk early (#6474) (#6478) - fix(markets): order the gap-fetch timers so our own cutoff is never the provider's fault (#6468) (#6476) - fix(convex): rename admission-snapshot so the production push is legal (#6480) - feat(company-monitoring): classify and admit material impacts (#6470) - docs(railway): correct three claims that shipped with the pagination fix (#6477) - docs(resilience): record education probe acceptance and its two read traps (#6472) - fix(railway): watchdog never paginates — GitHub rewrites next links to the repository-ID path (#6378) (#6469) - fix(health): register the educationAttainment probe + education pre-flip gates (#6452, #6460) (#6467) - ops(resilience): register the educationAttainment health probe (#6452) (#6464) - fix(resilience): financialSystemExposure inverts the ranking — executable calibration gates, then the retune (#6459) (#6463) - feat(company-monitoring): normalize scoped evidence candidates (#6457) - fix(sentry): group limiter degradation by failure mode, not by route (#6454) (#6458) - fix(sidecar): pin IPv6-only RSS fetches (#6456) - fix(rate-limit): confirm CF edge-proof covers /api/* and warn when it stops (#6435) - fix(rate-limit): meter the gateway reverse-geocode RPC at 60/min (#6451) - fix(feeds): drop the dead YC Blog publisher-family label (#6455) - feat(resilience): add flag-dark education dimension to the Country Resilience Index (#6450) - fix(feeds): restore server-only sources to dashboard (#6444) - fix(brief): corroboration gates count publisher families, not feed labels (#6443) - fix(ui): harden panel font scaling (#6453) - feat(company-monitoring): ingest verified X posts (#6424) - fix: require expiring health probe cutovers (#6392) - feat(ui): add global and per-panel font scaling (#6445) - fix(ingestion): rebuild GB consumer-price roster around scrapeable retailers (#6358) (#6442) - feat(mcp): expose story corroboration to agents (#4925 item 3) (#6421) - feat(company-monitoring): add bounded Exa cohort discovery (#6404) - fix(alerts): give keyword-spike alerts the sources, headlines and links they already held (#6414) (#6433) - chore(ci): ignore generated sidecar bundles in edge checks (#5926) - ops(ci): alarm on failed post-merge production deploys (#6376) (#6406) - fix(api): rate-limit the three unguarded public proxies (#6234) (#6412) - fix(session): stop one dropped mint request blacking out anonymous browsing (#6413) - fix(settings): keep plan verification pending through auth retries (#6423) - fix(sentry): split Cloudflare edge 5xx from origin 5xx by fingerprint (#6370) (#6409) - fix(analytics): make the Umami retention tick commit, and size it for the volume (#6375) (#6407) - fix(sentry): repair the alicdn font rule and filter the round-5 TR injectors (#6408) - fix(markets): harden Hyperliquid and FRED live data (#6339) - fix(rate-limit): stop the test-context abort racing the decision (#6236) (#6405) - fix(gdelt-intel): share one timestamp validator between the fetch-ordering and health paths (#5858) (#6044) - ops(railway): mark company-monitoring-worker planned so the post-#6397 apply can run (#6402) (#6403) - fix(ingestion): harden theater posture publication (#6401) - fix(energy): stop one absent country from withholding the JODI dataset (#6395) (#6400) - fix(ingestion): reject empty theater posture publishes (#6393) - fix(settings): apply source toggles to the live dashboard on close (#6380) (#6399) - fix(analytics): judge collector health against its own baseline instead of a fixed 0.5 (#6026) (#6041) - fix(railway): align deploy closures with build inputs (#6397) - fix(ingestion): tolerate bounded consumer-price retailer loss (#6394) - feat(company-monitoring): add durable scan orchestration (#6386) - fix(ci): paginate the deploy gate's check-runs read (root cause of #6389) (#6391) - fix(intel): stop feed newlines forging rows in the three sibling prompt blocks (#5881) (#5897) - test(e2e): wait for degraded digest retry (#5899) - fix(ci): keep the deploy gate posting a status when the required list is long (#6389) (#6390) - fix: silence floating promise in playback snapshot-exit path (#5968) - fix(correlation): harden seeder input reads (#6385) - ops(monitor): acknowledge the eight consumer-price coverage partials against owner issues (#6363) - fix(analytics): keep Umami storage warnings non-fatal (#6384) - fix(monitor): monitor the newest gated main revision instead of failing on an undecided head (#6374) - fix(dashboard): apply panel settings without a reload (#6379) (#6382) - feat(markets): authorize Finnhub+AV quote provider chain (#6304) (#6350) - fix(convex): stop a one-dot test helper from failing every convex deploy (#6232 follow-up) (#6373) - fix(railway): fence reconciliation cutover with leases (#6326) (#6326) - feat(company-monitoring): add bounded portfolio onboarding (#6232) - test(company-monitoring): add progressive blind evaluation scorer (#6219) - fix(railway): add reconciliation recovery control plane (#6325) - feat(mcp): expose WTO trade flows to agents, name coverage-collapse causes (#6323) (#6353) - fix(sentry): filter the two extension webfonts still dominating TR (follow-up to #6371) (#6372) - fix(analytics): unblock Umami storage monitor (#6354) - feat(markets): add the RUB quote table as a third FX panel tab (#6231) (#6352) - fix(trade): serve every supported tariff-trend window and name what is uncovered (#6316) (#6349) - fix(sentry): narrow the CSP rules to observed signatures and repair a vacuous guard (follow-up to #6369) (#6371) - test: replace implementation checks with behavior coverage (#6368) - fix(sentry): filter the CSP injectors that dominate TR/J0, and close two format gaps (#6369) - fix(payments): send the welcome email to the account's current login address (#6335) (#6364) - fix: unblock checkout on the API host and revive two dead iOS filters (#6365) - fix(observability): stop two non-errors paging at Sentry error level (#6351) - fix(entitlements): repair the free-tier ownership model shipped in #6345 (#6346) - fix(insights): name which editorial gate rejected the world brief (#5947) (#6342) - fix(entitlements): restore all free-tier-owned preferences (#6345) - fix(china): recover Japan MOD releases from unterminated anchors (#6344) - fix(consumer-prices): evidence-gated extraction recovery for the eight partial markets (#6182) (#6343) - fix(api): classify truncated Convex response bodies as transient (#6340) - feat: add visual stock/market watchlist customization (#1881) - test(ci): eliminate observed timing and fixture flakes (#6327) - fix(panels): transfer gate ownership on every user toggle (review P1) (#6338) - fix(panels): stop the free-tier count cap being a one-way door (#6337) - chore(trade): remove the v1 trade-flow cutover bridge (#6315) (#6329) - fix(payments): send lifecycle emails to the account login email, not the checkout alias (#6330) (#6336) - fix(sentry): name world-brief rejection gates, drop mutated-CSP noise (#6333) - fix(china): stop scroll re-priming from flickering the corridor and nowcast panels (#6328) - fix(markets): restore parameterized crypto quote requests (#6320) - fix(markets): deliver quotes for custom watchlist symbols (#6318) - fix(trade): serve every supported trade-flow window and name what is uncovered (#6309) (#6322) - fix(rss): preserve stale feeds through upstream failures (#6312) - fix(markets): honor stablecoin coin filters and restore custom IDs (#6317) - perf(tests): cut idle waits and redundant parsing in unit + smoke CI (#6324) - fix(markets): restore parameterized commodity quote requests (#6307) (#6314) - fix(maritime): stop the AIS relay sustaining its own upstream IP block (#6313) - fix(news): prioritize China feeds before digest deadline (#6311) - fix(consumer-prices): attribute coverage loss to a bounded failure reason (#6301) - docs(health): pin the published /api/health key count to the registry (#6300) (#6303) - fix(china): retry Japan MOD empty index through proxy (#6302) - fix(railway): classify unprovisioned seeders as planned (#6278) - test(build-guards): make dist-gated skip explicit via WM_EXPECT_BUILT_OUTPUT (#6284) - fix(health): stop a producer fault from masking a vanished data key (#6263) (#6299) - chore(deps): bump postgres from 17-alpine to 18-alpine (#6293) - feat(i18n): give the translator prompt the product's domain glossary (#6295) - fix(webmcp): migrate tools to document.modelContext (#6292) - fix(analytics): preserve collector timeout fallback (#6088) - i18n(de): fix mistranslated domain terms and complete the German locale (#6294) - fix(markets): bound market-implications LLM misses instead of alarming on each (#6259) (#6266) - fix(security): patch js-yaml and stop upstream advisories blocking PRs (#6298) - fix(consumer-prices): repair dead extraction fallback and prompt-fabricated prices (#6270) - fix(markets): recover sector ETF valuations by rotating the proxy exit (#6290) - refactor(china): retire the Vercel edge egress hop from the SZSE disclosure seeder (#6274) - fix(weather): harden the US-only disclosure guards from the #6269 review (#6276) - fix(weather): rank NWS alerts by severity before the 50-cap (#6277) - fix(military): seed stale-snapshot flight fixtures through the normalizing field (#6291) - fix(mcp): attach both source failure reasons to get_airspace error (#6085) (#6283) - fix(military): bound stale flight recovery cache (#6287) - feat(aviation): keyless ADS-B redundancy — adsb.lol primary, blind-spot gap-fill, ODbL attribution (#6273) - fix(seeders): recover rejected Redis publications (#6286) - fix(aviation): skip degenerate bbox block for icao24-only requests (#6275) - fix(military): reject Upstash command errors (#6258) - fix(military): deliver global flight coverage to dashboard (#6261) - fix(china): retry transient NBS fetches so one socket blip can't stale the release calendar (#6264) - fix(maritime): bound AIS reconnects and report degraded health (#6268) - fix(worktree): self-heal hooks path at push time (#6285) - fix(rate-limit): fail closed paid-provider market routes (#6260) - fix(procurement): keep SAM seeding on reachable IPv4 (#6265) - chore(worktree): verify dependency installation (#6131) - ci: add generated-file drift gate for bootstrap-tier-keys (#6282) - ops(railway): prune the recovered umami drift suppression and stop an empty baseline expiring (#6064) (#6281) - fix: disclose US-only weather alert coverage (#6269) - test(military): close three assertion gaps in the OpenSky cooldown suite (#6241) (#6255) - fix(military): persist the OpenSky 429 cooldown so the seeder stops re-firing (#6241) (#6252) - feat(markets): opt-in FX panel over the orphaned fx:yoy seed (#6199) (#6226) - fix(docs): use MDX comments for the generated attribution markers (#6251) - fix(architecture): close the four gold-standard deviations (#6235) (#6239) - fix(military): one global OpenSky query per run — 86% → 43% of the daily credit quota (#6222) (#6244) - feat(markets): show the CBR key rate in the Central Banks tab (#6202) - docs(sources): audit upstream attribution inventory (#6250) - perf(inp): cut /dashboard interaction-time work and fix the readout (#6221) - fix(seed): preserve shared FX fallback provenance (#6233) - feat(railway): give all 41 registry services an exact watch-path closure (#6204) (#6218) - fix(railway): reconcile on Deploy Gate completion and alarm on a silent fleet (#6203) (#6216) - fix(seo): make category explainer answer-first (#6217) - fix(seed-utils): stop retrying a Retry-After the run cannot wait out (#6110) (#6215) - fix(brief-gates): stop flagging a sentence-initial common noun the source already contains (#6109) (#6201) - fix(seo): complete Dataset structured data (#6207) - fix(railway): fail closed on partial fleet history (#6206) - feat(china): seed Stock Connect northbound turnover + margin balance from SSE/SZSE (#6190) - feat(company-monitoring): define dark service contract (#6188) - test(company-monitoring): freeze viability and evaluation contract (#6186) - fix(markets): keep replayed sector valuations safe, honest, and refreshable (#6197) - fix(mcp): publish activationUnknown on the cache envelope (#6198) - docs(correlation): record #5991 RRF decision (#6079) - fix(consumer-prices): recover partial retailer extraction (#6185) - feat(markets): add Bank of Russia RUB rates + CBR key rate seeder (#6154) (#6187) - fix(aviation): preserve OpenSky credit budget (#6196) - ops(railway): trigger seeder deploys from CI and judge drift against the service closure (#6142) (#6151) - fix(health): bound content freshness activation grace (#6152) - fix(markets): stabilize sector valuation coverage (#6183) - fix(portwatch): retry transient ArcGIS rate limits (#6184) - fix(client): keep map overlays on a faked WebGL context + name push 400s (#6194) - fix(payments): capture unattributable Dodo events instead of retry-storming (#6191) - test(prediction-markets): pin fixture expiry clock (#6195) - ops(analytics): activate the Umami 90-day retention runner (#6148) (#6189) - ci(proto): enforce breaking changes in workflow (#6147) - feat(desktop): acknowledge checkout in returning browser (#6136) - fix(review): restore the desktop handoff outcome guards dropped in the rebase (#5911, #6120) (#6145) - fix(seeders): make every Railway entry point announce that it finished (#6144) - feat(ops): detect when a Railway service is not running the merged commit (#6143) - fix(desktop): migrate remaining links to shared opener (#6137) - fix(desktop): commit the release train to one switching binary (#5908) (#6124) - fix(mcp): ground world brief in seeded insights (#6134) - fix(insights): don't split the brief lead at an acronym that carries its citation (#5947) (#6119) - chore(supply-chain): promote FlowEstimate.source to a closed enum (#6101) (#6122) - fix(health): widen PortWatch content freshness budget (#6135) - fix(selfhost): allow Docker LLM origins through sidecar SSRF guard (#6130) - fix(health): surface mid-publish military starvation (#6132) - harden(health): treat an unreadable activation marker as unknown, not confirmed-absent (#6095) (#6117) - fix(sentry-triage): five live issues across payments, analytics, session copy and crash filters (#6129) - fix(security): clear production dependency audit failures (#6140) - fix(military): stop seed-military-flights crashing on every run (#6128) - fix(security): bump brace-expansion past GHSA-rgw5-rvv9-x895 (#6118) (#6123) - fix(military): cap Wingbits aircraft detail batches (#6099) - fix(quota): separate dashboard AI limits from MCP (#6105) - fix(panels): hydrate late-mounted hub activity panels (#6100) - fix(mcp): age the #6080 fixture guard on the content clock, not the legacy fallback (#6080) (#6096) - fix(navigation): keep variant links on dashboard (#6098) - fix(china-nowcast): publish an observed China energy-demand change (#6067) (#6081) - ops(relay): attribute theater-posture publications to their actual source (#5945) (#6092) - fix(mcp): align the freshness envelope with health's PortWatch content-freshness dimension (#6080) (#6094) - fix(ops): reconcile Railway config drift (#6091) - fix(markets): restore ETF valuation identity for Yahoo summaries (#6090) - fix(china-nowcast): persist comparable corridor history (#6083) - fix(china-nowcast): name each CCFI exclusion honestly and fail closed on undated observations (#6066) (#6077) - fix(china): separate PortWatch content freshness and healthy-quiet groups in decision coverage (#6060) (#6073) - chore(supply-chain): declare the CCFI period-change fields on ShippingIndex (#6078) (#6084) - fix(china): accept same-publisher corridor corroboration (#6076) - feat(search): build intelligence command deck (#5971) - fix(china-nowcast): publish a directional CCFI period change (#6066) (#6074) - fix(health): bound the consumer-price coverage rollout window (#6059) (#6075) - fix(feeds): enforce complete geographic classifications (#6072) - fix(health): retire expired on-demand softenings (#6071) - fix(hydration): handle dashboard container scrolls (#5894) - fix(news): refresh expired persistent RSS responses (#6069) - fix(webcams): fit 2x2 wall to short viewports (#6065) - fix(economic): accept full macro-stress FRED batch (#6062) - fix(ui): normalize China dashboard panel styling (#6063) - fix(insights): make world brief readable (#6061) - fix(analytics): bound the umami pool's acquisition wait so overload fails fast (#6057) - feat(feeds): P3 — Canada + Arctic/Nordic security source pack (#5960) (#6054) - fix(map): gate CMD+K locked premium layers for free users (#6045) (#6049) - fix(map): use hasPremiumAccess for GlobeMap premium gating (#6050) - fix(seo): rotate Bing-rejected www IndexNow key (#6055) (#6056) - feat(i18n): add Ukrainian (uk) locale + lang boost for UA feeds (#6052) - fix(review): address code review findings for theater presets (#6023) - fix(analytics): restore umami session_data writes and gate the image on a runtime write probe (#6051) - fix(ingestion): bound provider retries and expose coverage (#6022) - fix(digest): tie the replay read-snapshot's lifecycle down and prove it (#6039) - fix(map): hide sunset iranAttacks toggle from SVG/mobile picker (#6048) - fix(feeds): reconcile regional rollout contracts (#6031) - docs: align public copy with code-derived counts — CII 31 Tier-1, 55 free layers, 41 MCP tools (#5488) - feat(bootstrap): cut the slow public tier over to KV serving (stage 1, #5338) (#6035) - fix(digest): page replay-log reads and re-anchor the caps to Upstash's real limit (#6033) - fix(analytics): eliminate Umami session-data write race (#6034) - fix(payments): absorb Dodo checkout 429s with a bounded jittered retry, pin SDK retries off (#6027) (#6032) - fix(insights): let a lead cite every story a merged claim draws from (#6030) - fix(review): harden geo coverage gate against silent-pass failures (#6029) - fix(china): restore Japan MOD via the Japanese Joint Staff homepage (#5904) (#6013) - fix(news): deduplicate before limiting summary headlines (#5969) - fix(bootstrap): survive sandboxed iframes, match aliased fetch wrappers (#6028) - test(feeds): geographic coverage health audit vs geography keyCountries (#5957) (#5999) - feat(feeds): add strategic default weights separate from locale boost (#5958) (#6000) - feat(correlation): add staged runtime correlation modes (#6020) - fix(insights): restore world brief synthesis by reserving a corroborated lead slot (#5947) (#6019) - fix(markets): restore complete sector valuation coverage (#5997) - fix(analytics): aggregate collector health across users (#5998) - feat(feeds): P1 — Africa depth beyond Nigeria (Horn, DRC, West Africa) (#5980) - fix(analytics): harden Umami collector write-path acceptance (#5996) - fix(analytics): gate receiptless-200 collector alerts on aggregate floors (#5978) (#5979) - feat(feeds): P1 — Eastern flank neighbors pack (Romania, Baltics, Turkey Black Sea) (#5952) (#5975) - feat(feeds): P1 — Indo-Pacific gaps (Taiwan mainstream, Pakistan, SE Asia security) (#5954) (#5977) - feat(feeds): P1 — Caucasus, Central Asia, Belarus/Moldova theater packs (#5953) (#5976) - fix(widgets): preserve custom panels across auth and cloud refresh (#5924) - feat(feeds): P1 — Ukraine depth pack (local institutions + daily frontline assessment) (#5951) (#5972) - fix(analytics): alert only on actionable collector write failures (#5974) - ops(ingestion): bound aviation/RSS throttling and expose consumer-price partial coverage (#5970) - feat(feeds): document and enforce UA/RU EN default balance (#5950) (#5966) - feat(feeds): default-enable Ukraine/Poland frontline sources for EN (#5949) (#5963) - fix(analytics): validate concurrent collector writes (#5964) - fix(markets): restore sector valuation enrichment after Yahoo 401s (#5962) - fix(insights): preserve freshness on synthesis rejection (#5947) (#5965) - feat(growth): measure content-to-product handoffs (#5944) - fix(ops): sync seed-conflict-intel Railway watch paths with GDELT bulk contract registry (#5961) - Merge commit from fork - feat(growth): operationalize AI visibility evidence loop (#5940) - Merge commit from fork - fix(seo): enforce complete meta descriptions (#5943) - feat(mobile): add feed-first primary navigation (#5244) - fix(auth): compensate Clerk token cache for client clock skew (#5938) - test(auth): harden Clerk expiry regression (#5937) (#5942) - fix(seo): add and validate Dataset descriptions (#5941) - fix(auth): reject stale Clerk fallback after session switch (#5937) - fix(ci): replace invalid Actions pin with the commit SHA it resolves to (#5925) - fix(desktop-build): pass the client VITE_ env to Tauri builds and gate its completeness (#5905) (#5919) - fix(pro): expose H1 in static page HTML (#5939) - fix(mcp): expose commodities news to agents (#5914) - test(china): pin Japan MOD Cloudflare fallback contract (#5917) - fix(markets): restore sector valuation enrichment (#5918) - fix(security): bump tauri to 2.11.5 and gate the advisory floor (#5518) (#5934) - fix(seo): close sitemap and IndexNow coverage gaps (#5936) - fix(seed): recover OFAC sanctions freshness (#5927) - fix(markets): alarm on empty prediction pools (#5916) - fix(auth): keep the Clerk token when its forced refresh fails (#5933) - docs: document recent intelligence and billing features (#5913) - epic(desktop): establish parity baseline and drift gates (#5902) (#5915) - docs(mcp): document prediction market categories (#5898) - Surface account and billing in one user menu (#5901) - i18n: translate 88 new strings across all 23 remaining locales (#5882) - fix(sentry): suppress SnapTube WebView bridge JSON.parse noise (#5900) - fix(cross-source-signals): unwrap seed envelopes and align extractors with their writers (#5870) (#5896) - fix(premium): observe entitlement desyncs (#5879) - refactor(gating): split panel-gating.ts by gate (#5813) (#5893) - fix(news): rotate a custom category's capped feed window and surface its source coverage (#5873) (#5887) - fix(china): distinguish decision group unavailability (#5891) - fix(intel): stop feed newlines forging rows in every analyst prompt block (#5857) (#5884) - fix(entitlements): enforce declared export formats (#5880) - fix(news): stop a degraded 200 digest from poisoning the last-good cache (#5877) (#5883) - fix(news): validate cached classification values (#5553) - fix(finance): derive the news/data panel-key collision so commodities-news is created (#5871) (#5888) - fix(ops): prune the recovered gdeltIntel freshness suppression (#5770) (#5867) - fix(markets): classify each prediction market into exactly one pool (#5733) (#5872) - fix(wildfire): cap the canonical fires payload under the 5MB publish limit (#5866) (#5869) - fix(news): stop 19 uncapped rss-proxy fetches and the doubled news load (#5376) (#5878) - ci: attach provenance and SBOM attestations to the published image (#5788) - fix(widgets): block beforeunload in custom widget sandbox (#5760) - fix(gdelt): move consumers to one bulk materializer (#5863) - fix(ml): stop caching a rejected model-load promise for the whole session (#5678) - test(mcp-grant): add Playwright E2E spec for /mcp-grant consent page (#5658) - refactor(tech-events): remove the dead narrowing from the cache-fill path (#5834) - fix(self-hosting): support optional AIS and Windows seeders (#5799) - fix(gdelt): rotate seed-gdelt-intel topics on last-attempt so one scarce DOC success stops monopolizing (#5848) (#5859) - fix(checkout): preserve provider 429 responses end to end (#5862) - docs(china): document complete data coverage (#5860) - fix(intel): read materialized GDELT topics from Redis in chat-analyst (#5850) (#5856) - fix(llm-health): quarantine models the provider rejects instead of retrying them on every call (#4949) (#5458) - fix(security): bump sharp >=0.35.0 in blog-site (GHSA-f88m-g3jw-g9cj, HIGH) (#5477) - fix(conflict): make the GDELT bulk export primary and demote the DOC country sweep to fallback (#5849) (#5855) - fix(pro): fail closed on entitlement reload guard (#5853) - docs(agents): clarify pull request authority (#5854) - fix(china): close the SZSE proxy retry and edge diagnostic gaps (#5839) - fix(auth): tolerate small Clerk JWT clock skew (#5832) - fix(consumer-prices): gate implausible movers as parse artifacts (#5445) (#5461) - fix(pro): prevent post-checkout entitlement reload loops (#5846) - feat(pricing): 3 months free on every annual plan + API Business Annual SKU (#5845) - fix(proxy): match the Decodo curl-endpoint rewrite case-insensitively (#5847) - ci(gate): give each changes job a distinct check-run name (#5822) (#5842) - fix(ci): restore deterministic main test runs (#5840) - feat(market): blend fundamentals into the analyze-stock rating (#5598) - fix(review): normalize Decodo host before sticky-port detection (#5837) - fix(pro): stop upgrade banner flickering for Pro users (#5836) - fix(correlation): suppress isolated slow-run warnings (#5835) - fix(china): diversify SZSE proxy exits (#5833) - fix(tech-events): cache the widest payload on cold-start fallback (#5427) (#5603) - fix(gdelt): reduce rate-limited ingestion fanout (#5830) - ci(gate): require every gated-workflow job, not just test.yml's (#5402) (#5825) - test(mcp): reject extra intel-history requests (#5831) - fix(hooks): repair the shared absolute core.hooksPath instead of warning (#5810) (#5824) - docs(api): publish versioning and deprecation policy (#5827) - test(mcp): pin intel history POST body privacy (#5821) - fix(ci): preserve gate status API order (#5828) - fix(ci): paginate gate status lookup (#5826) - i18n(hi): translate 90 recently added strings across dashboard features (#5778) - fix(ci): validate Railway project token context (#5816) - fix(health): retire shipping rates recovery exception (#5784) - fix: merge GED Candidate release onto annual UCDP base instead of probing annual-only (#5796) - fix(ops): fail closed on ingestion acceptance drift (#5802) - fix(sentry): attribute events to deployed builds (#5815) - fix(premium): stop rendering a failed lookup and a signed-out caller as "free plan" (#5619) (#5779) - fix(hooks): stop the green-tree cache attesting a tree the gates never ran (#5800) (#5809) - fix(dashboard): gate playback on entitlements, not a dead Clerk field (#5812) - fix(mcp): preserve conflict events within output budget (#5807) - fix(conflict): fall back to official HAPI snapshots (#5806) - test(docs): gate the /api/bootstrap Cache-Control values the docs publish (#5794) (#5808) - fix(portwatch): make port-activity recovery converge (#5804) - fix(china): require sustained SZSE recovery (#5803) - fix(gdelt): bound ingestion recovery (#5805) - feat(market): surface an LLM news-sentiment sub-score on stock analysis (#5656) - feat(market): add per-stock risk analytics to stock analysis (#5649) - fix(notifications): guide denied push users to browser settings (#5764) - fix(hooks): route tests/dom/ to vitest instead of the node:test runner (#5795) (#5801) - fix(china): add bounded SZSE edge fallback (#5786) - test(checkout): close #5380 coverage gaps — false-passing idempotency test, webhook rollback, boundaries (#5606) - fix(bootstrap): stop the edge answering an invalid key from a warm weather cache (#5386) (#5791) - fix(security): harden contact and local-secret validation (#5787) - fix(intel): give history ingestion a durable health signal (#5736) (#5792) - fix(session): recover when cookies cannot persist (#5798) - fix(ops): retire recovered China coverage exception (#5785) - sec(intel): decide the untrusted-text posture and add a retraction path (#5743) (#5781) - fix(seed): reject ACLED events without stable ids (#5783) - fix(china): classify the Japan MOD proxy target block (#5776) - fix(api-keys): tolerate transient auth races (#5780) - fix(scripts): recognise keyword-preceded regex in stripJsComments (#5763) - fix: decode HTML entities exactly once, repo-wide (#5436) (#5754) - fix(auth): bound Clerk token cache by the token's own expiry (#5753) - fix(checkout): handle a create-checkout 200 whose body will not parse (#5761) - sec(seed): stop seeder imports from loading production credentials (#5767) (#5775) - fix(ops): enforce ingestion operational acceptance (#5756) - feat(mcp): expose client-side analysis composites as MCP tools (#5696) (#5739) - fix(test): stop the China macro fixture rotting on a calendar date (#5762) (#5765) - feat(intel): corporate intelligence — SEC EDGAR filings, 8-K material events, earnings surprises, real company enrichment (#5695) (#5738) - fix(boot): handle the variant stylesheet preload rejection (#5758) - feat(intel): historical intelligence memory — semantic search, timelines, and precedent matching (#5737) - fix(prefs): serialize cloud preference writes (#5755) - feat(mcp): on-demand NLP intelligence utilities — classify, extract entities, news clusters, keyword spikes (#5734) - feat(forecast): geopolitical bet family — long-horizon market slice (#5735) - fix(pro): stop Upgrade banner flashing for entitled users (#5728) (#5751) - fix(research): reject incomplete daily coverage (#5746) - fix(docs): align API meta descriptions with runtime (#5750) - fix(analytics): verify collector writes and retry identity (#5748) - fix(seo): submit apex MCP URL via IndexNow (#5749) - fix(seo): expand crawlable meta descriptions (#5747) - fix: gitignore docker-compose.override.yml and secrets/ (#5725) - fix(auth): avoid negative-caching transient user-key failures (#5599) - fix(seed): restore GDELT timeline recovery (#5719) - feat(research): Strait of Hormuz transit report — source-backed research pilot (#5668) (#5721) - fix(china): retry transient SZSE proxy failures (#5722) - fix(health): bound degraded source markers (#5717) - fix(test): isolate shallow Git fixture (#5732) - fix(china): classify Japan MOD proxy failures (#5718) - fix(conflict): recover HAPI from egress bot blocks (#5720) - docs(legal): clarify optional World Monitor attribution (#5716) - fix(seo): generate truthful sitemap freshness (#5711) - feat(growth): establish SEO and AI-citation scorecard (#5709) - fix(rate-limit): isolate paid callers from shared IP buckets (#5708) - test(china): lock quiet disclosure health semantics (#5710) - docs(legal): clarify subscription license tiers (#5702) - chore(mcp): fold MCP-edge and gateway Pro-MCP gates into server/_shared/pro-mcp-gate.ts (#5659) - feat(pricing): reduce Pro Business to $49.99/mo and $499/yr (#5688) - fix(session): tell a dropped cookie apart from a rejected one (#5687) - perf(globe): bound HTML marker count and instrument the field (#5368) (#5371) - fix(e2e): retry once in CI so a Playwright protocol glitch stops reddening gates (#5686) - fix(bootstrap): stop non-on-demand keys taking the credential-less public path (#5683) - fix(session): scope wm-session blackouts to the failing route (#5674) (#5677) - fix(session): tag dead-session route and stop premium 401s killing it (#5674) (#5680) - fix(entitlements): honor Clerk Pro role in JSON gates (#5650) - fix(entitlements): finish the billing-verification sweep (#5661) - feat(welcome): add blog navigation and Palantir FAQ (#5681) - test(gates): DOM-behavioral coverage for ExportGateControl, the PDF click cycle, resolveGateAction and PanelTabBar's locked notice (#5660) - chore(i18n): refresh all 24 /pro locales for the pricing restructure + stop English copy silently rotting translations (#5655) - feat(onboarding): surface command search in Pro setup - test(seo): align pricing assertions with visible surfaces - fix(csp): re-sync script-src hashes with the regenerated inline JSON-LD - fix(ci): drop stale crawler-copy stats claim - Address PR review feedback (#5676) - fix(seo): replace crawler-only prerender content - fix(comtrade): enforce CI and quota contracts - fix(china): recover Japan MOD through proxy fallback (#5657) - fix(i18n): stop advertising query locale alternates - fix(china): proxy SZSE disclosures after direct failure (#5651) - chore(china): give the decision-parity audit teeth (#5643) (#5648) - fix(seo): generate canonical public product facts (#5672) - chore(china): dedupe provenance OpenAPI schemas (#5647) - docs(comtrade): record the verified Railway cron instead of assuming it - fix(a11y): add focus-visible indicators for settings controls (#5059) (#5522) - fix(comtrade): compose the period strategies, bound quota and coverage - fix(hooks): use PR base ref for pre-push commits-ahead guard (#5670) - fix(blog): track canonical-host conversions (#5662) - fix(blog): attribute product conversion clicks - fix(comtrade): fall back to prior period per-reporter, cap request quota - fix(review): correct JSDoc target and give the Comtrade budget test teeth - fix(docs): recompute stats on second main merge (178 components, 209 services) - feat(pricing): seed real Dodo product IDs for Pro Business - feat(china): compose decision-parity signals (#5639) - fix(data): recover humanitarian, China, and PortWatch coverage (#5640) - fix(comtrade): restore bilateral HS4 ingestion continuity - fix(activation): harden day-0 outcome ownership (#5638) - fix(entitlements): stop fresh Pro purchases getting 15 min of broken Pro (#5600) (#5623) - feat(activation): record day-0 activation outcomes server-side (#5621) (#5626) - feat(market): join upcoming earnings into stock analysis (#5636) - feat(china): add opacity-resistant activity nowcast (#5631) - docs(solutions): capture the npm registry outage that silently redded the security gate (#5637) - docs(concepts): correct Plan Family entry — tier gates are thresholds - docs(solutions): compound the credential-class vs plan-family quota lesson - fix(docs): recompute stats on the merged tree (176 components, 207 services) - fix(review): close API-tier OAuth quota leak + probe retry + popover staleness - refactor(gates): consolidate cross-unit duplication from the simplify pass - fix(export): widen print-host contentWindow slice with the document fallback member - test(docs): update license-key guidance pin for the Pro Business wording - docs(pricing): reconcile every surface with the new tier ladder and export gating - feat(pro): pricing page restructure — Personal/Commercial axis header, Enterprise band, five-column grid; rebuild public/pro - feat(pricing): Pro Business goes public — catalog copy, both mirrors, v3 cache key (7 sites), license-chip parity guard, pricing docs - feat(dashboard): per-plan tab cap with visible locked add-control — Free 3 / Pro 10 / Pro Business 25, creation-only, billing-aware - feat(export): entitlement-gated export with visible locked state, billing-aware CTAs, and PDF data report - feat(activation): make the denial cohort readable, not just recorded (#5617) (#5630) - feat(billing): Pro Business lifecycle — shared pro checkout family with upgrade carve-out, guided 409 copy, welcome email, day-0 activation - fix(mcp): Settings quota widget reports plan-resolved limit — 250 for Pro Business, unlimited for Enterprise, client normalizer no longer coerces null/0 to 50 - feat(activation): record a browser-blocked step in its own durable bucket (#5617) (#5629) - fix(summarization): stop logging 'All providers failed' for declined-by-design chains (#5377) (#5605) - fix(military): harden cross-Strait activity publication (#5627) - fix(ci): stop an npm registry outage from silently redding the security gate (#5628) - feat(mcp): plan-driven daily quota for pro-family callers — 250/day Pro Business, null=unlimited, user_key stays 50 - feat(billing): Pro Business catalog foundation — dataExport entitlement field, dual PLAN_PRECEDENCE entries, resolvePlanKey catalog fallback - feat(china): compose regional logistics corridor control towers (#5593) - docs(activation): capture the denied-permission dead-end learning (#5609) (#5624) - fix(settings): clamp unavailable MCP tab (#5625) - fix(premium): stop rendering a 403 as "Pro required — upgrade" when the client says Pro (#5608) (#5618) - fix(activation): route a denied push permission to the blocked state (#5609) (#5615) - fix(pro): point activation step 3 at MCP Clients, not the API upsell (#5607) (#5613) - fix(military): stop cross-Strait seeder crashing on every publish (#5616) - feat(china): add official exchange disclosure signals (#5594) - fix(china): harden policy ingestion (#5610) - feat(china): add official macro-financial pulse (#5597) - feat(china): ingest official policy enforcement events (#5595) - feat(military): add cross-strait activity baseline (#5596) - docs: add Japanese README (#5410) - feat(markets): expandable terminal price chart + fix(dev): OpenSky proxy path (#5459) - fix(sidecar): release upstream fetch semaphore on stalled/truncated responses (#5489) - feat(provenance): add decision-signal contract (#5592) - fix(activation): land outcome tracking on main (#5590) - fix(observability): detect silent catch blocks in Sentry coverage audit (#5586) - fix: register missing Breaking Defense intel source (#5405) - feat(business-seats): add domain-gated Pro seat invites for API Business (#5563) - feat(activation): onboard unactivated first-cycle Pro users (#5564) - fix(seo): preflight crawlable live sessions (#5589) - feat(market): add structured fundamentals + panel to stock analysis (#5467) - perf(market): serve the live price tape from the 'live' cache tier (#5465) - fix(rss-proxy): preserve original error/response when relay fallback throws (#5464) - fix(provenance): require explicit feed classifications (#5571) - test: guard Pro JSON-LD pricing against catalog drift (#5451) - fix(security): baseline unreachable brace expansion advisory (#5572) - fix(conflict): fix humanitarian pipeline — HAPI per-identifier throttle, not IP (#5554) (#5568) - feat(monitoring): probe the Umami analytics collector every 15 minutes (#5565) (#5567) - docs: correct CII country coverage (#5511) - refactor(forecast): extract market settlement loader (#5566) - docs(architecture): align alert docs with wired producers (#5513) - fix(header): keep Sign In visible on medium-width desktops (#5557) - feat(forecast): Phase 2 — LLM ensemble + prediction-market/FRED calibration slices (#5525) (#5526) - fix(news): fail-closed source provenance defaults (#5390) (#5556) - fix(deps): bump postcss to 8.5.18+ to clear GHSA-r28c-9q8g-f849 (#5562) - perf(gates): fix stale-hook delivery + batch esbuild check + incremental tsc (push timeouts) (#5558) - feat(seo): close crawlable-corpus audit gaps — social meta, name aliases, trust links, partial risk rendering (#5555) - feat(pricing): API Starter rename + commercial-license split + 5 Pro seats on Business ($299.99) (#5552) - feat(seo): add crawlable live intelligence tools (#5546) - fix(_crypto): fail closed on malformed auth inputs (#5550) - fix(renewable): replace hardcoded fallback with last-known-good data (#5551) - feat(activation): day-0 pro activation onboarding interstitial (#5534) - fix(seo): prevent raw-text crawlers from extracting "WWorld Monitor" Move the decorative "W" brand mark from inline text to a CSS ::after pseudo-element. Raw textContent extraction now yields "World Monitor" instead of "WWorld Monitor". The visual appearance, accessible name, and first-paint footprint are unchanged — the ::after inherits the same font-size and color from .skeleton-brand-mark. Adds focused regression tests in deploy-config.test.mjs asserting: - Raw text does not contain "WWorld" - The brand mark span has no text content - The "W" is rendered via CSS content Fixes #5541 (#5549) - fix(docker): preserve caller auth for local MCP requests (#5537) - fix(docker): preserve caller auth for local MCP requests (#5492) - feat(i18n): Hoàn thiện bản dịch tiếng Việt (vi.json) (#5539) - fix(routing): redirect pricing to canonical section (#5548) - fix(payments): dead-letter authenticated malformed webhooks instead of 401 (#5547) - fix(giving): disclose published benchmark provenance (#5540) - fix(payments): persist failed Dodo webhook incidents (#5533) - Merge commit from fork - test(bootstrap): cover DebugBear sampling boundaries (#5545) - fix(seo): remove unsupported schemamap robots directive (#5544) - chore(bootstrap): wind down the R2-origin experiment (DebugBear sampling + KTD7 no-go) (#5536) - fix(payments): restore lapsed subscriber reactivation path (#5532) - fix(security): bump find-my-way to 9.7.0 — GHSA-c96f-x56v-gq3h (HTTP/2 DDoS) (#5527) - feat(api): enforce the sold daily cap + informative at-cap 429 (#4635) (#4684) - fix(forecast): extend EIA settlement grace (#5524) - fix(global-tenders): spread SAM.gov request budget, stop retrying 429s (#5444) (#5457) - fix(auth): close the #5379 adversarial sweep — resource exhaustion, state corruption, MCP entitlement gaps, and the inert live suite (#5385) - fix(auth): keep Pro brief denials out of session recovery (#5516) - fix(python-sdk): avoid secret-scan literals (#5486) - fix(mcp): route sibling fetches through canonical API (#5517) - fix(notification-channels): bound convexRelay() with a 15s timeout (#5485) - docs(solutions): compound #4771 learnings — coverage-semantics bug + i18n shell convention (#5495) - ux(payments): billing-aware renewal/lapsed states instead of generic Upgrade CTA (#4771) (#5494) - feat(homepage): link Palantir positioning article (#5491) - fix(auth): honor current API access during renewal checks (#5490) - fix(seed-gdelt-intel): degrade bookkeeping failures instead of crashing; brownout-scale timeline TTL; content-age opt-in (#5478) (#5481) - ci(deploy-gate): retry the check-runs poll before posting a terminal 'pending' (#5479) (#5482) - fix(payments): distinguish transient entitlement-lookup failure from confirmed denial (#5483) - feat(blog): strengthen SEO and AI discoverability (#5475) - fix(payments): re-check Dodo before stale-subscription denial (#5447) - docs(blog): clarify WorldMonitor and Palantir positioning (#5480) - feat(agent-readiness): advertise SDKs in the agent view + homepage rel=alternate pointer (orank round 2) (#5476) - feat(agent-readiness): sandbox, docs-MCP JSON-RPC errors, schemamap, modular llms.txt (orank round) (#5469) - fix(content): replace blog title cards with product imagery (#5452) - feat(blog): pinned-post support; pin the Palantir post to the top of the index (#5446) - docs(solutions): three-layer cache eviction runbook for the live product catalog (#5422) - feat(content): receipts round — rewrite Palantir post, print the real scorecard, live radiation + tender records (#5443) - Update blog post to 6 dashboards, fix variants count, and add Energy … (#5408) - fix(seed-utils): retry transient Redis blips on the read path + skip-path meta ops (#5437) (#5438) - fix(feed-digest): decode & last so RSS entities aren't decoded twice (#5432) - fix(deps): clear sharp + fast-xml-parser high advisories redding audit-lockfile on all PRs (#5423) (#5424) - fix(rss-proxy): remove dead rsshub.app from allowlists (#5414) - fix(pricing): call out 'License / API key included' on the API Starter tier (#5419) - feat(content): 13 blog posts — undocumented features (tenders, sanctions, aviation, radiation, energy dashboard…) + 'not Palantir' positioning (#5403) - fix(deps): clear fresh high advisories redding audit-lockfile on all PRs (#5417) (#5418) - fix(seed-research): isolate arXiv categories + retry + TTL so a single blip can't empty prod (#5409) (#5413) - test(pro): critical-path budget guard for the committed /pro build (#5396) (#5397) - test(rss-proxy): wire test file into CI, lock the SSRF/auth/rate-limit guards, fix relay www-tolerance (#5378) (#5399) - chore(lint): appease biome 2.4.9's promoted rules across scripts/ (unblocks all PRs) (#5400) - fix(analytics): swallow Umami beacon rejection leaking to Sentry (#5393) - fix(deps): clear high-severity DoS advisories failing the security-audit gate (#5395) - fix(mcp): make GET /mcp crawler-readable and fix the discovery cache key (#5382) - docs(solutions): capture two reusable learnings from the KV cutover (#5338) (#5383) - fix(auth): follow-up to #5369 — fix Infinity-exp test and reset leaked timeout (#5370) - fix(checkout): retry transient create-checkout failures once with an Idempotency-Key (WORLDMONITOR-Q4) (#5374) - fix(auth): adversarial sweep — resource exhaustion, boundary validation, test double contract (#5369) - fix(sentry): suppress zero-frame 'Unexpected token' SyntaxErrors from injected scripts (#5367) - fix(notifications): enforce Country Scope uniformly across all alert categories (#5359) (#5366) - docs(solutions): seeder auxiliary Redis writes crash on Upstash timeout (#5365) - fix(seed-utils): retry transient Redis failures in writeExtraKey / extendExistingTtl (#5364) - docs(bootstrap): finalize U-K3 evidence with clean-24h confirmation (#5338) (#5363) - docs(solutions): Sentry noise filtering with stack gating and signature matching (#5361) - fix(sentry): suppress Clerk UI load failure and extension fetch-wrapper noise (#5360) - feat(bootstrap): serve public tier from KV via the Worker (U-K4, #5338) (#5357) - docs(solutions): desktop-CLS victim-vs-mover learning + panel-mount vocabulary (#5332) (#5356) - i18n(it): complete Italian translation — translate remaining untransl… (#5349) - test(dom): cover sanitizer and construction contracts (#5348) - fix(seo): scope the Mintlify docs proxy to www + redirect prefix-less /api-reference/* (#5345) (#5347) - feat(bootstrap): turn on the KV shadow measurement (U-K3 gate, #5338) (#5342) - perf(cls): reserve grid slots for immediate-tier panels — shell the top-8 mounts (#5332) (#5344) - feat(bootstrap): Workers KV serving path — publisher write + shadow measurement (U-K1, U-K2, #5338) (#5341) - fix(brief): catch duration-led historical explainers (#5340) - perf(bootstrap): record incumbent Redis latency (#5339) - feat(cls): shift-time mover attribution — name what grew, not what moved (#5332) (#5336) - fix(comtrade): restore HS preview classifier (#5337) - fix(brief): exclude historical explainers (#5335) - perf(cls): pin always-full panels to deterministic row heights (#5332) (#5333) - fix(forecast): retire legacy infrastructure cascade forecasts (#5334) - fix(bootstrap): preserve R2 RUM CORS headers at edge (#5331) - docs(solutions): compound the #5300 lever-test learning + seed CONCEPTS.md (#5329) - fix(bootstrap): preserve R2 origin RUM on Vercel (#5328) - fix(forecast): present() observes 0 (not NaN) on absence — VOID-rate regression (#5327) - fix(bootstrap): schedule R2 shadow work on Vercel (#5326) - perf(bootstrap): prepare measured R2 origin rollout (#5325) - fix(china): seed country index from ais relay (#5324) - fix(news): audit China source coverage by locale (#5323) - fix(health): detect vanished compact projections (#5322) - perf(seeders): stop seeding float64 conversion noise into the market sparklines (#5300) (#5319) - test(seeders): audit extraKey TTLs — and fix the wildfire projection it found (#5320) - fix(china): keep country-index audit cache Railway-backed (#5318) - test(seeders): ratchet the TTL-outlives-staleness invariant across the fleet (#5317) - fix(forecasts): dashboard key shipped the 11.5MB seeder trace, not a projection (#5311) (#5315) - fix(china): harden coverage audit contracts (#5314) - feat(mcp): add procurement opportunities tool (#5312) - perf(forecasts): serve the dashboard the forecast LIST, not the dossiers (#5300) (#5311) - fix(china): complete coverage audit contract (#5313) - perf(bootstrap): serve UCDP as a dashboard projection, not 2,000 raw events (#5300) (#5305) - perf(bootstrap): stop shipping 17 tier keys no client reads (#5300) (#5308) - fix(seeders): absorb a transient tender-source blip instead of raising a health warn (#5310) - perf(bootstrap): serve thermal escalation as a dashboard-sized view, not the full watch (#5300) (#5303) - perf(bootstrap): make cyberThreats an on-demand key instead of slow-tier freight (#5300) (#5302) - fix(seeders): give the ACLED conflict key a TTL that outlives its staleness gate (#5309) - perf(health): serve ?compact=1 from a compact verdict snapshot (#5300) (#5307) - fix(forecast): give DeepSeek-Flash the routing its timeout always assumed (#5304) - feat(china): add dedicated country summary (#5297) - fix(natural): correct HKO health and cyclone wind fallback (#5298) - docs(solutions): capture three verified learnings from the 2026-07-14 seeder/health session (#5306) - feat(procurement): technology-relevance filtering and documented AusTender blocker (#5286) (#5299) - fix(health): stop grading an unconfigured optional source as SEED_ERROR (#5295) - feat(natural): add Pacific cyclone attribution (#5296) - feat(china): add current macro and release calendar coverage (#5294) - fix(sentry): close two beforeSend gaps re-surfacing known third-party noise (#5293) - fix(railway): prevent skipped seeder deployments (#5292) - fix(seeders): restore defense patents via USPTO ODP (#5284) - fix(feeds): bypass Nature redirect loop (#5291) - fix(seeders): stop seed-conflict-intel crash-looping when it has no usable source (#5256) (#5290) - feat(china): add coverage health foundation (#5283) - feat(china): deepen strategic trade and energy coverage (#5282) - feat(china): deepen markets and server news coverage (#5281) - feat(china): expand aviation and safe PLA identification (#5280) - fix(seeders): declare papaparse + fast-xml-parser in scripts/package.json (#5266 regression) (#5289) - fix(api): strip router-injected ?rpc= so public RPC URLs are CDN-shielded (#5285) (#5287) - feat(procurement): add global tender intelligence (#5266) - fix(e2e): tolerate detached smoke responses (#5267) - fix(wildfire): package compactor with Railway seeder (#5270) - fix(conflict): restore keyless GDELT fallback (#5269) - fix(security): consolidate runtime hardening residuals (#5260) - fix(seeders): fail retry when last-good keys are gone (#5258) - perf(llm): cut DeepSeek Flash stall tail (#5257) - perf(redis): shield residual dashboard read egress (#5263) - perf(health): memoize Redis verdict sweep (#5262) - docs: add Chinese README (#5265) - fix(globe): guard OrbitControls against mixed mouse+touch pointer crashes (#5252) - fix(health): measure list-typed data keys with LLEN, not STRLEN (#5254) - fix(session): distinguish dead recovery reasons (#5253) - perf(bootstrap): restore CDN cache shield for tier reads (#5249) (#5250) - docs: fix inconsistent em dashes and real-time hyphenation (#5248) - fix(sentry): skip client-synthesized session-degraded 503s (#5245) (#5247) - feat(forecast): fast-resolving commodity price bets — Gate-1 accelerator (#5233) (#5243) - fix(security): harden Turnstile client IP identity (#5241) - fix(security): harden client-ip proof comparison (#5242) - fix(seeders): extract dependency-free client-ip.ts so usage.ts stops pulling @upstash into seeder containers (#5231) (#5236) - feat(forecast): bet-template engine + energy pilot (Phase 1, #5233) (#5238) - feat(forecast): honesty bridges — real-skill Brier + funnel guardrail (Phase 0, #5233) (#5237) - fix(telemetry): attribute usage to verified clients (#5229) - fix(seo): advertise localized docs sitemap (#5226) - fix(intelligence): cap deduct-situation LLM budget under edge ceiling (#5225) - docs(i18n): expand Chinese SEO descriptions (#5223) - fix(auth): suppress dead anonymous session retry storms (#5219) - fix(security): harden webhook registration boundaries (#5218) - docs(i18n): re-sync 87 zh-Hans pages to current English (#5215) (#5222) - perf(mobile): split post-hydration long-task wave (#5220) - fix(sentry): suppress h5player userscript frame-src CSP noise (#5221) - docs: improve SEO titles and descriptions for zh translation (#5217) - fix: repair broken links in zh translation (#5216) - fix(rate-limit): isolate paid summarize callers (#5212) - fix(boot): tolerate blocked browser storage (#5211) - feat(docs): add Chinese (zh-Hans) translation at full parity (#5214) - fix(convex): enforce Pro gate on notification channels (#5210) - fix(cls): create #mapSection already collapsed for the collapsed-map cohort (#5159) (#5205) - fix(build): co-locate ResilienceWidget into panels-intel chunk (#5203) (#5204) - perf(map): gate overlay counter-scale var writes on real zoom change (#5080 slice 2) (#5202) - docs: improve SEO titles for MCP apps and overview pages (#5200) - feat(mcp-apps): expand interactive widget fleet 5 → 10 (#4956) (#5199) - fix(risk): make canonical CII the only product source (#5197) - fix(forecast): resolve judged entries from deadline evidence (#5196) - fix(brief): reject truncated why-matters prose (#5184) - docs: improve SEO title for license page (#5182) - fix(brief): vary analyst why-matters prose (#5175) - fix(docs): explain how to find and replace API keys (#5181) - docs(legal): set UAE governing law, clarify refunds, ground operator in Dubai (#5180) - docs: tighten SEO metadata on About, Privacy, and Terms pages (#5179) - fix(homepage): point WIRED citation to the global wired.com edition (#5178) - feat(docs): add About, Privacy, and Terms trust pages (#5177) - fix: clarify IMF real GDP local-currency units (#4072) - docs: fix typo and escape pipe in pipelines table (#5176) - fix(welcome): drop dead Wikidata QID from homepage sameAs (#5174) - perf(search): defer mobile sheet population past first paint (#5167) - fix(a11y): restore Intel Feed tag contrast (#5172) - perf(mobile): profile panel work and trim font precache (#5173) - fix(cls): preserve collapsed map boot footprint (#5161) - fix(welcome): support legacy root clearing (#5164) - Fix Windows / CRLF compatibility and test suite bugs (#4358) - feat(airlines): Add automated ICAO-IATA code generator script (#4309) - ci(consumer-prices): run vitest suite (#5154) - fix(convex): guard JSON object request bodies (#5156) - fix(edge): allow longer enterprise wm_ keys through bot gate (#5155) - docs: unescape HTML entities inside inline code spans (#5152) - docs: tighten indicators & signals description under 160 chars (#5151) - fix(docs): prevent internal plan publication drift (#5149) - fix(matcher): don't treat missing category as an exact category match (#5139) - fix(observability): filter Floot automation + DebugBear-wrapped fetch Sentry noise (#5143) - fix(forecast): reclassify unrest count specs to judged (#5091) (#5142) - fix: correct verb form "time out" in desktop-app doc (#5146) - fix: repair broken links flagged by mint broken-links (#5144) - docs: tighten SEO descriptions across 71 pages to 130-160 chars (#5145) - chore(deps): bump actions/github-script from 7.0.1 to 9.0.0 (#5122) - chore(deps): bump actions/setup-go from 5.6.0 to 6.5.0 (#5118) - fix(seed): time-box seed-conflict-intel GDELT fallback sweep to fit the fetch deadline (#5140) (#5141) - chore(deps): bump actions/checkout from 4.3.1 to 6.0.3 (#5121) - chore(deps): bump docker/build-push-action from 7.0.0 to 7.2.0 (#5120) - chore(deps): bump node in /consumer-prices-core (#5117) - perf(cls): take cached-mode banner out of flow to stop column shove (#4580) (#5137) - fix(forecast): reclassify conflict/ucdp_zone count specs to judged (#5136) (#5138) - fix(forecast): fall back to GDELT for conflict events when ACLED creds absent (#5099) (#5134) - perf(cls): pin mobile boot skeleton to the real map footprint (#4580) (#5133) - perf(observability): sample field web-vital telemetry to cut Sentry volume ~80% (#5132) - perf(lcp): paint cached World Brief at panel construction (#4890) (#5130) - fix(dashboard): stabilize CLS-prone deep-dive motion (#5124) - fix(lcp): tag field LCP element selector (#5123) - fix(forecast): harden simulation keyword matching (#5128) - test(forecast): lock ACLED health visibility (#5127) - chore(perf-tooling): harden render-axis interaction traces (#5125) - fix(seed): don't crash seed-conflict-intel when ACLED creds are absent (#5126) - fix(pro): collect DebugBear RUM on marketing pages (#5116) - fix(forecast): calibrate detector probabilities (#5107) - test(forecast): tighten simulation selection assertions (#5112) - fix(forecast): surface silent forecast input feed gaps (#5109) - fix(dashboard): reduce mobile map tap presentation work (#5111) - fix(forecast): guard market calibration anchors (#5105) - fix(forecast): fail ACLED seed when primary feed is unavailable (#5106) - fix(forecast): harden theater simulation gating (#5108) - fix(sentry): suppress Firefox host-suffixed NetworkError for DebugBear RUM beacon (#5110) - fix(forecast): enforce hard resolution publish coverage (#5096) - fix(forecast): restore FRED macro signals (#5104) - fix(frontend): harden dashboard lazy loading and metadata (#5089) - feat(api): IETF RateLimit headers + verifiable signed webhook sample (orank Usability) (#5095) - perf(dashboard): add mobile tap render-axis tracing (#5088) - fix(rum): wire lcp web-vitals reporting (#5090) - fix(forecast): resolve judged forecast outcomes (#5087) - fix(forecast): use ACLED resolution feeds for hard counts (#5085) - perf(edge): cache apex→www 301 + point published human links at www (#5081) (#5086) - fix(api): cool down Finnhub symbol-search 429s (#5082) - perf(wildfire): cap dashboard fire payload (#5083) - fix(relay): stop double-TLS wrapping OpenSky proxy fetches (#5074) (#5084) - Fix forecast hard resolution coverage (#5072) - fix(seeders): don't crash a bundle when a member fails gracefully (#5077) (#5078) - perf(forecast): prune archived terminal entries from the resolution ledger (#5067) (#5073) - Fix SPA lifecycle recovery (#5064) - Fix seeder health metadata drift (#5071) - fix(aviation): avoid caching unavailable flight data (#5070) - Fix RPC no-store cache contract (#5068) - Harden Convex entitlement lifecycle races (#5065) - test(news): stabilize completeness selection attribution fixture (#5069) - Fix container healthchecks: IPv6/localhost + auth-gated probe path (#5051) - fix(forecast): avoid stale UCDP count resolutions (#5063) - fix(docker): keyless healthcheck + wire UCDP_ACCESS_TOKEN into ais-relay env (#5052) - perf(map): cut INP input-delay — guard rebuild loops, throttle hover query, yield-schedule heavy commit (#5042) (#5045) - perf(dashboard/INP): route flashLocation through the base-map geometry cache (#5049) (#5050) - fix(checkout): quiet active subscription blocks (#5048) - feat(corpus): make chokepoint/country pages useful + deep-link into the live map (#5044) - feat(billing): self-serve Starter→Business API upgrade (#4634) (#4672) - feat(api): add plan limit notification lifecycle (#4648) - fix(news): keep digest cold builds under edge timeout (#5047) - perf(onboarding): defer mission-preset auto-open to idle after paint (#5046) - feat(content): add crawlable static corpus (#5041) - fix(digest): prefix story-track reads in previews (#5040) - docs(mcp): document endpoint exposure workflow (#5039) - feat(agent-skills): expand catalog with tranche 4 recipes (#5033) - feat(mcp-apps): interactive dashboard fleet — 4 new ui:// widgets (#4959) (#5035) - perf(map): skip zoom-hidden SVG marker DOM (#5036) - fix(seed-economy): bound FRED fetch concurrency under the 240s deadline (#5037) (#5038) - Harden watchlist notification follow-ups (#5034) - fix(payments): pace dunning Resend sends under the 10 req/s limit (#5032) - feat(markets): ticker tagging at ingest, market-hours awareness, watchlist story alerts (#4922) (#5031) - perf(pro): keep signal bars animation off layout (#5028) - fix(pipeline): harden AIS relay Upstash detection, mask Redis creds, add EVALSHA-free rate-limit fallback (#5025) - feat(forecast): add resolution ledger and scorecard (#5024) - fix(notifications): fail open on dedup SETNX errors (#5026) - fix(forecast): harden simulation outcome writes (#5027) - perf(pro): split @sentry into its own cacheable chunk (#5019) (#5020) - perf(map): route boot-path container geometry through the resize cache (#5017) (#5022) - chore(aeo): brand-named developer-resource discoverability pages (#5023) - chore(perf): remove stale protomaps.github.io dns-prefetch (#5016) (#5021) - perf(pages): immutable /pro asset caching, lazy preview + on-demand Turnstile, WebP blog covers (#5013) (#5015) - feat(agents): Web Bot Auth key directory + /agent/auth WWW-Authenticate challenge (orank) (#5009) - fix(forecast): resolution-spec emission amendment — horizon-commensurable count + resolvable supply/gps windows (#5010) (#5012) - fix(health): no-store on the compact status response so uptime monitors never read a stale verdict (#5008) - feat(forecast): resolvability contract — machine-checkable resolution spec per forecast (#4976) (#5004) - fix(forecast): reserve run-budget for the full provider chain so market_implications' groq fallback isn't stranded (#4978 follow-up) (#5003) - feat(content): free-vs-paid comparison post + fix never-firing FAQPage JSON-LD (#4998, #5001) (#5002) - fix(seo): self-canonicalize variant subdomain dashboards + canonical Link headers for sitemap .md pages (#4996, #4999) (#5000) - fix(seo): restore WIRED/2M+ meta description — sync VARIANT_META.full with hand-tuned index.html + drift guard (#5005) (#5006) - fix(seed-bigmac): parallelize 50-country EXA loop to stop 240s-deadline crashes (#4994) (#4995) - feat(llm): never serve OpenRouter inference from China-hosted providers (#4993) - fix(payments): reconcile missed Dodo renewals (#4794) - fix(portwatch): prioritize never-cached countries in the cold-fetch cap so coverage reaches 174 (health COVERAGE_PARTIAL) (#4992) - perf(brief): route whyMatters to deepseek-v4-flash, decouple from the reasoning tier (#4983 follow-up) (#4991) - feat(payments): reconcile stuck pending payments (#4795) - fix(fred): pipeline batch seed reads (#4989) - fix(notifications): coalesce repeated alert events (#4985) - fix(gpsjam): restore the free gpsjam.org source, retire the Wingbits quota dependency (#4987) - feat(iran-events): flag-gate the whole Iran-events domain, default OFF (war-ended sunset) (#4982) - fix(middleware): stop bot-gating /favico/* — public brand assets must be world-readable (#4988) - fix(llm): reasoning-off for short brief stages — v4-pro empty-content 80% (#4983) (#4984) - fix(forecast): stop false SEED_ERROR when market_implications is starved of the shared LLM run budget (#4978) (#4980) - fix(widget): persist Pro widget HTML across reloads (#4981) - docs(mcp): mcp-remote bridge setup + Cloudflare apex-redirect exemption contract (#4951) - fix(llm): pin regions on the two unpinned LLM edge routes + log provider error bodies (#4944 U7) (#4966) - feat(llm): core chain to OpenRouter DeepSeek V4 Flash + output-shape hardening (#4944 U1+U2) (#4950) - feat(llm): seeder narrative tiers to DeepSeek V4 Flash; pin probability-coupled critical_signals (#4944 U6) (#4977) - feat(telemetry): llm_call events for the telemetry-dark seeder transports (#4944 U5) (#4954) - fix(pricing): remove the phantom "XLSX exports" claim from API Business (#4974) (#4975) - fix(forecast): stable semantic-slot ids for military and state-derived forecasts (#4933) (#4973) - feat(pricing): publish the API Business tier — visible, priced, self-serve (#4945) (#4946) - feat(analytics): restore Umami on canonical www host + end-to-end checkout funnel events (#4931) (#4934) - feat(billing): dunning + winback email lifecycle for failed payments and cancellations (#4932) (#4935) - fix(forecast): non-finite probability guards — NaN can no longer enter or anchor the probability spine (#4933) (#4969) - fix(feeds): allowlist war.gov + thenationalnews.com + trumpstruth.org — unblock feed-health activation (#4970) (#4971) - feat(ux): persistent read-state — NEW tags survive reload (#4923, slice a) (#4926) - feat(markets): macro-print actuals, earnings in the daily brief, finance-demotion seam (#4922) (#4929) - feat(brief): the brief contract — top-8 synthesis, verified citations, enforce-mode gate, shared grounding spine (#4921) (#4928) - feat(news): completeness measurement — feed health w/ silent zeros, coverage ledger + provenance, GDELT recall benchmark (#4920) (#4927) - feat(news): unified story-identity service — one similarity definition for clustering, dedup, corroboration (#4919) (#4924) - fix(forecast): word-boundary term matching — stop substring country false positives corrupting probabilities (#4933) (#4939) - feat(content): global-intelligence glossary — 20 crawlable DefinedTerm pages (#4960) (#4968) - feat(agent-readiness): advertise the live docs MCP server + real /agent.txt (#4958) (#4964) - feat(agent-readiness): three-tier AI-crawler policy in robots.txt + real /agents.md (#4952) (#4955) - fix(sentry): CSP noise filters — Doubao KaTeX fonts, injected Google Fonts CSS, content-filter frame vendors (#4942) (#4943) - feat(ci): live MCP smoke — 6-hourly anonymous strict-client walk of prod (apex+www) — #4937/#4938 regression net (#4941) - fix(mcp): serve ping + prompts/* + logging/setLevel anonymously — gated 401 hangs Claude Desktop via mcp-remote (#4937) (#4940) - chore(digest): reuse prior envelope prose on non-due compose ticks (#4917) (#4918) - chore(llm): cache-identity churn batch 2 — summary pair-dedup v7, market-brief context quantization, forecast prompt-hash cache, whyMatters v8 cross-read (#4914) (#4916) - fix(summarization): entitlement-gate the summarize provider chain — stop the anon 401 flood + 3x fan-out (#4913) (#4915) - chore(llm): regional hygiene — narrative prompt-hash cache + brief retry-budget cap (#4911) - fix(health-freshness): revalidate every poll — CF browser-TTL rewrite would oscillate synthesized-OK sources to stale (#4910) (#4912) - chore(digest): flip BRIEF_WHY_MATTERS_SHADOW to opt-in — default-on doubled gemini spend (#4909) - perf(health): collapse health polling cost — CDN-cache compact health, 5-min cadence, idle-deferred first hydration (#4907) (#4908) - feat(observability): emit llm_call events from callForecastLLM — the seeder path #4901 missed (#4906) - fix(health-freshness): read the keyless compact health endpoint — stop the anon 401-per-minute flood (#4902) (#4905) - fix(intelligence): stop ISO stopword-codes (IN/US/AT/NO) over-matching shared brief grounding (#4904) - perf(CLS): attribute field shift classes — hiddenAtLoad/scrollY/viewport env on CLS reports (#4580) (#4903) - feat(observability): emit llm_call usage events from every server-side LLM path (#4901) - perf(forecasts): input-hash cache guard for the market_implications LLM stage (#4900) - perf(pwa): keep blog OG covers out of the dashboard SW precache (#4891) (#4899) - fix(intelligence): share the anon country-brief cache per country+lang — stop hashing caller context into the key (#4898) - perf(map): time-box marker pulse animations — settle to static after 6s (#4669) (#4897) **Full Changelog**: https://github.com/koala73/worldmonitor/compare/sdk/go/v0.1.1...v2.10.0