| 1 | # Business exposure and news intelligence V2 |
| 2 | |
| 3 | ## Acquisition and scoring boundaries |
| 4 | |
| 5 | `ResearchRepository.refresh_news_intelligence(globalInstrumentId)` is an explicit |
| 6 | worker operation used by the existing CURRENT_NEWS ensure capability. It uses |
| 7 | the existing search adapters, safe document fetcher, persistence connection and |
| 8 | request-spacing setting. Scanner/ranker/readiness reads do not acquire evidence. |
| 9 | No new GET endpoint or background all-universe refresh is introduced. |
| 10 | |
| 11 | The worker serializes requests per repository, bounds providers to three, |
| 12 | queries to twenty (the existing configured budget defaults to six), and fetched |
| 13 | documents to twenty (the existing configured document budget applies). Query |
| 14 | selection interleaves company, company-event, exposure and sector tiers. The |
| 15 | default profile query plan is limited to 3/4/3/4 queries and three sufficiently |
| 16 | confident MEDIUM/HIGH exposures. An empty response describes the configured |
| 17 | search scope, never the whole internet. Search snippets are discovery only. |
| 18 | |
| 19 | Explicit fresh Yahoo MCP acquisition observations are supplemental company-news |
| 20 | checks. They never replace web/exposure queries. No Yahoo call is made to reuse |
| 21 | these observations. An empty general-purpose quote snapshot is not evidence of |
| 22 | a successful news search. Other search adapters can be injected into the same |
| 23 | bounded worker. Disabled search is a failure; Searxng unresponsive engines make |
| 24 | coverage partial. Fetch failure or document-budget truncation also prevents a |
| 25 | complete/no-events result. Exceptions become bounded failure codes. |
| 26 | |
| 27 | ## Evidence-derived profiles |
| 28 | |
| 29 | `CompanyBusinessExposureProfile` uses canonical instrument identity and immutable |
| 30 | versioned snapshots (`BUSINESS_EXPOSURE_V1`). Official persisted report/company |
| 31 | text has priority over verified Yahoo/NSE/BSE `businessSummary` facts. Canonical |
| 32 | or structured industry metadata can supply query context; it does not establish |
| 33 | a raw-material relationship. No company-to-commodity lookup is present. |
| 34 | |
| 35 | The extractor requires an explicit uses/consumes/raw-material/produces/sells |
| 36 | relationship in source text. Unsupported or negated relationships are excluded. |
| 37 | Equal-confidence contradictory input/producer relationships have no assumed |
| 38 | price direction. Importance is HIGH only with explicit importance wording. |
| 39 | Each exposure retains source references and source-capped confidence. Explicit |
| 40 | labelled lists populate products, segments, drivers, geography, customers, |
| 41 | competitors and risks; unavailable fields remain empty. |
| 42 | |
| 43 | Exposures share a typed list (`exposure_type` distinguishes raw material, |
| 44 | commodity, energy, currency, interest rate, demand, regulation, geography, |
| 45 | competition and supply chain). `app/config/exposure_ontology_v1.json` defines |
| 46 | normalized keys and aliases. Adding ontology entries does not require rewriting |
| 47 | the extractor. `source_reliability_v1.json` versions classification confidence |
| 48 | and optional domain overrides. Publisher reliability is separate from relevance; |
| 49 | OTHER sources can supply lower-confidence candidate impacts. |
| 50 | |
| 51 | ## Events, impact and revisions |
| 52 | |
| 53 | `NEWS_IMPACT_V2` features retain source-document/event identifiers and |
| 54 | the exact profile snapshot ID. Direct-company actions require a company mention |
| 55 | in the action sentence; another company's action elsewhere is not attributed. |
| 56 | Verified exposure matches can establish SECTOR_EXPOSURE relevance without a |
| 57 | company headline mention. They do not assert that the article named the company. |
| 58 | |
| 59 | Impact is `100 × direction × magnitude × company relevance × source confidence |
| 60 | × event confidence × freshness decay`, bounded to -100..100. The initial |
| 61 | conservative magnitude is 0.5, not an estimated earnings effect. Direct-event |
| 62 | confidence is 0.9; exposure-event confidence is 0.75, with relevance capped at |
| 63 | 0.8. Linear decay uses each event's public date and validity boundary. Multiple |
| 64 | events combine by the deterministic mean of active latest-known revisions, so |
| 65 | mitigation does not overwrite an earlier adverse event. |
| 66 | |
| 67 | Input costs and supply disruption use 21-day windows; demand/orders/competition |
| 68 | use 30 days; guidance/capacity use 90 days. Short, medium and long horizon flags |
| 69 | are stored separately. Validated direct severe official/regulatory/company |
| 70 | events can remain unresolved with no expiry. A correction must append a new |
| 71 | revision of its logical event; only the latest revision known at evaluation is |
| 72 | used, including for severe overrides. There is no automatic fuzzy linking of |
| 73 | unrelated resolution articles to a severe event. |
| 74 | |
| 75 | Publication, public availability, discovery and computation timestamps are |
| 76 | distinct. Missing publication time uses discovery conservatively. Feature public |
| 77 | availability cannot precede profile evidence availability. Historical reads |
| 78 | require computation, discovery and public availability at/before the requested |
| 79 | cutoff; later revisions cannot leak into earlier output. Training consumers must |
| 80 | retain these availability cutoffs, not use a backfill's database insertion date |
| 81 | as the original publication date. No prediction model is implemented. |
| 82 | |
| 83 | ## Readiness and scoring |
| 84 | |
| 85 | Search freshness is one day, independent of event validity: |
| 86 | |
| 87 | | Search state | Meaning | |
| 88 | | --- | --- | |
| 89 | | READY_WITH_EVENTS | Complete fresh search with qualifying events | |
| 90 | | READY_NO_EVENTS | Complete fresh search, no qualifying events | |
| 91 | | PARTIAL_SEARCH | Incomplete provider/document coverage | |
| 92 | | FAILED_SEARCH | No usable completed provider coverage | |
| 93 | | STALE_SEARCH | Search completeness must be refreshed | |
| 94 | |
| 95 | Fresh complete no-event evidence satisfies CURRENT_NEWS and produces impact 0 |
| 96 | (news metric 50/100), unless independently active events still exist. Failed |
| 97 | search never fabricates a neutral metric. CURRENT_NEWS is optional for full V1 |
| 98 | analysis; missing/failed coverage reduces confidence. Active event impact can |
| 99 | remain PARTIAL/scorable while search freshness degrades. Only severe validated |
| 100 | events enter the existing critical risk-override boundary. Ordinary commodity |
| 101 | cost pressure does not suppress ranking. |
| 102 | |
| 103 | V1's seven-percent news weight and all ranker weights are unchanged. Technical |
| 104 | and sector scoring are unchanged. V1 retains its version; its input fingerprint |
| 105 | contract advances to `STOCK_RULE_ENGINE_V1_INPUT_2_NEWS` and includes news evidence, |
| 106 | search coverage and evaluation instant (continuous decay), invalidating obsolete |
| 107 | cached results. This can reduce cache hits for news-bearing evaluations. |
| 108 | |
| 109 | ## Valuation and TMCV freshness |
| 110 | |
| 111 | Persisted fresh price can materialize PE from a valid trailing-EPS basis and PB |
| 112 | from book value. Instrument and currency must agree; conflicting simultaneous |
| 113 | prices are rejected. Quarterly EPS is not annualized into trailing EPS. Bases |
| 114 | use a 120-day reporting window; price-derived ratios retain the price timestamp |
| 115 | and market-session validity. Refreshing price does not reset the basis age. |
| 116 | Existing annual fundamental valuation evidence retains its 400-day policy. |
| 117 | |
| 118 | The local TMCV audit found June 30 income/finance-cost support alongside March 31 |
| 119 | mandatory debt/equity. Readiness selected the newer supporting date for display, |
| 120 | although stale mandatory inputs caused READY_STALE. The diagnostic now reports |
| 121 | the selected stale mandatory dates and `FRESHNESS_POLICY_EXPIRED:DEBT,EQUITY`. |
| 122 | It does not relabel stale March facts as fresh. June 30 mandatory facts evaluated |
| 123 | September 14 are fresh under the unchanged 120-day policy. No verified issuer |
| 124 | release calendar was present: period end remains the fallback anchor, with an |
| 125 | explicit valid-until honored when supplied. No release date or longer TTL is |
| 126 | invented. |
| 127 | |
| 128 | ## Persistence and validation |
| 129 | |
| 130 | Java research-service remains Flyway owner. Approved additive V12 creates only: |
| 131 | |
| 132 | - `company_business_exposure_profiles`: versioned evidence snapshots. |
| 133 | - `research_news_search_runs`: immutable provider coverage and outcome history. |
| 134 | - `research_event_impact_features`: immutable event-impact revisions. |
| 135 | |
| 136 | Core identity, impact, confidence, horizon and temporal fields use typed indexed |
| 137 | columns; extensible details use JSONB. Database triggers reject UPDATE/DELETE. |
| 138 | The Python adapter uses INSERT and deterministic revision identities; repeat |
| 139 | identical records reuse the existing row. PostgreSQL startup requires V12. |
| 140 | SQLite mirrors the append-only repository boundary for tests. No migration-time |
| 141 | provider call, data rewrite or backfill occurs. |
| 142 | |
| 143 | The migration was executed in a separate PostgreSQL schema inside a transaction; |
| 144 | all three tables and mutation guards validated, followed by ROLLBACK. It was not |
| 145 | applied to the deployed research schema. The generic cable/COPPER fixture |
| 146 | discovers and scores adverse exposure impact without a company headline mention, |
| 147 | retains multi-day relevance, and creates no severe override. Focused tests cover |
| 148 | provider failure/empty aggregation, immutability, timestamps, scoring, valuation |
| 149 | and the reproduced balance-sheet dates. Tests require no live news provider. |
| 150 | |
| 151 | Remaining operational work: deployment of V12 before this Python version, |
| 152 | scheduled bounded profile/news refresh policy, expanded issuer-document coverage, |
| 153 | authoritative release calendars and explicit resolution-event linking. Optional |
| 154 | read-only ranking smoke was not run because this slice requires a migration. |
| 155 | No frontend, prediction, broad refresh or recommendation redesign is included. |