# SIMD-CHAT: evidence-grounded update plan for Pulse

Research and source review: **13 October 2026, UTC**. Deliverable: an implementation plan with executable offline examples, not an implemented app upgrade.

**Recommendation:** retain the current React/TypeScript interface and optional Python service. First make signal timing, source history, and position state reproducible. Then add a small causal adaptive indicator experiment and chronological evaluation. Improve risk sizing and introduce a paper account before pursuing automated execution. More indicators, faster data, and sentiment models are candidate improvements; none has demonstrated a predictive advantage in this review.

## 1. Evidence, scope, and an important repository mismatch

The requested app is [launch-1280-simd-chat-build-custom-web, pinned at `8220e881d0f5809b46132c04d31d72b793a2fcfc`](https://github.com/identity-md-launches/launch-1280-simd-chat-build-custom-web/tree/8220e881d0f5809b46132c04d31d72b793a2fcfc). I retrieved and inspected its frontend, service, tests, and execution template through GitHub API and commit-pinned raw files. The assignment workspace initially contained no app source. App files were reviewed in disposable storage; this assignment delivers a report and examples rather than copying or changing the app.

The [supplied research job](https://explorer.imd.fun/jobs/fa11c7a3-8fa7-4526-8546-c5a6397156ef) links to a [50,981-byte Markdown report](https://api.imd.fun/artifacts/bbe25e3363b389d11377db186ab876ae62be43039494ebab94170dd26f296df3). Its SHA-256 matches the artifact identifier. The report reviews **launch-1418-simd-chat-analyze-existing-intraday-swin at `c4d55d24255bf75a693339dc697195e93c040ca5`**, not launch-1280. Its descriptions of existing WebSockets, adaptive analytics, a research worker, and a nine-candidate parameter search must not be attributed to the requested app. Its reported 48 upstream tests are also not launch-1280's test results. The explorer's structural acceptance establishes file integrity, not scientific validity.

Throughout this report:

- **Fact / observed:** inspected source behavior, a local synthetic reproduction, or a cited primary document.
- **Inference:** a consequence of those observations, not a measured trading result.
- **Proposal:** a new feature, code boundary, parameter choice, or evaluation gate.
- **Uncertainty / unanswered:** missing empirical evidence or a choice requiring future owner configuration.

The supplied research is the basis for the design directions. Exchange and statistical claims were checked against primary documentation or original research. No real trading account, owner credentials, paid sentiment integration, representative market dataset, deployed browser session, or profitability experiment was used. All example balances and prices are explicitly synthetic test fixtures, not assumed owner values.

## 2. What the requested app actually does

| Area | Observed launch-1280 behavior and evidence | Inference and necessary change |
|---|---|---|
| Market delivery | Foreground browser polling every 30 seconds; Python snapshot waits for market and sentiment together, with an 18-second outer timeout. Each market call creates a CCXT Kraken client. [App refresh][A1], [snapshot endpoint][A2], [market adapter][A3] | Sentiment can delay delivery of the market snapshot. There is no independent streaming feed to preserve. Add one and separate refresh cycles. |
| Signals | `evaluate` uses weighted sentiment and fixed Wilder RSI(14). MACD(12,26,9) and UTC-day typical-price VWAP are chart calculations, not entry requirements. Missing enabled sources block the decision. [Engine][A4] | A chart overlay is not confirmation in the strategy. Add explicit strategy modes and position-aware decisions, keeping the existing rules as baseline. |
| Timeframe and adaptation | Chart aggregation changes with 5m/15m/1h/4h selection, while signal RSI uses the underlying candles. Aggregation does not enforce a complete bucket. No adaptive indicator engine is present. [Chart][A5], [aggregation][A6] | Swing charts do not create a swing strategy. Add a strategy timeframe and complete-bar feature pipeline; introduce adaptation as new work. |
| Research execution | `Backtest.run` calls `backtest` synchronously. No worker or automated calibration/search appears in the retrieved tree. [Backtest view][A7], [repository tree][A0] | New sweep and walk-forward work needs a worker or CLI. There is nothing to rename as an existing calibration feature. |
| Backtest mechanics | One long position, prior-bar sentiment/RSI, next-open entries, fees and adverse slippage both sides, gap-aware stops, stop-first when both levels touch, final liquidation. Entry sizing includes fee cash capacity, but risk budget uses price-stop distance only. [Simulator][A8] | Preserve these useful protections; share strategy and risk functions, add costs to loss sizing, and expose remaining execution uncertainty. |
| Historical sentiment | SQLite stores one composite using 45/35/20 when every source is ready. History export attaches the latest observed composite available by the five-minute close, with a 900-second age limit. [Store][A9] | Existing export has a useful as-of rule but cannot replay different weights or a strategy enabling fewer sources. Persist components and availability versions. |
| Risk and paper state | Calculator caps quantity by nominal capital and stop distance; costs are excluded. Stop suggestion is an arithmetic mean of 14 true ranges. Paper submission records arbitrary positive quantity at displayed price in a browser journal. [Sizing and stop][A10], [paper form][A11] | The journal does not enforce calculator risk, reserve cash, or monitor exits. Introduce an account ledger and shared sizing. There is no second Wilder ATR implementation in this app to reconcile today. |
| Sentiment quality | Keywords use token membership; social sample combines recent and high-engagement posts. Optional Jev scoring falls back to keywords, documented in a detail string. RSS uses a 24-hour headline window. [Preprocessing][A12], [providers][A13] | Diversity statistics alone do not cap author influence. Refresh time alone does not establish freshness of the underlying stories. Add versioned methods, text-quality evaluation, and age/diversity controls. |
| Execution | Python template requires `dry_run=true`, rejects non-USD quote markets, and never submits real orders. [Template][A14] | Faster execution is a future integration objective, not a current measured capability. Retain the dry-run boundary for this plan. |

### Reproduced baseline examples

These are source-semantic tests with fabricated data, not market-performance observations. Exact outputs are retained in `evidence/baseline-probes.json` and `evidence/service-probes.json`.

1. Two consecutive five-minute candles are emitted by `aggregateCandles(..., 15)` as one fifteen-minute candle. The timestamp implies a full interval although the function does not track completeness.
2. A chronological 35-bar CSV with one five-minute interval removed is accepted as 34 bars. Ordering validation does not detect the gap. This does **not** prove every missing interval is a feed outage.
3. Social=80, news=20, on-chain=50 yields stored composite **53** at fixed weights. A 75/25/0 strategy would require **65**, and 25/75/0 would require **35**; neither can be reconstructed from 53.
4. With synthetic capital $10,000, configured risk 1%, stop 2%, and fees/slippage each 0.1% per side, a stop-touch fixture loses **$114.7951**, exceeding the nominal $100 risk allocation. The simulator accounts for these costs in P&L but not in loss-based entry quantity.
5. `score_text("not bullish")` returns **100**, demonstrating a negation failure in this keyword baseline.
6. A source timestamp exactly 60 seconds after snapshot time can still produce a Buy in the demo fixture. The current code intentionally allows clock tolerance; that tolerance should not serve as a historical availability rule.

## 3. Translate the supplied research into this app

The following links all refer to the [supplied report artifact][R]. The section names identify the research argument, while the app evidence above identifies the actual starting point.

| Research recommendation | Application to launch-1280 | Acceptance evidence |
|---|---|---|
| “A modular architecture” and “Use the same rules in replay and runtime” | Extract pure TypeScript contracts, indicators, decisions, risk, and replay from `engine.ts`; import them from React, a new worker, and a local CLI. | Identical decisions on identical normalized events, deterministic clock, and config. |
| “Low-latency real-time integration” | Implement market streaming rather than modifying a nonexistent `KrakenMarketStream`; decouple sentiment refresh from prices. | Reconnect/gap/finality tests and measured receipt-to-decision/UI timing. |
| “Adaptive and calibrated technical indicators” | Add causal adaptation with fixed RSI/EMA baselines. Add parameter selection and probability calibration as separate new features. | Prefix invariance, training-only parameter selection, untouched out-of-sample evaluation. |
| “Robust local backtesting” | Extend existing next-open simulator with component history, data provenance, walk-forward evaluation, execution sensitivities, and worker cancellation. | Reproducible manifests, deliberate leakage probes, identical cost assumptions across baselines. |
| “Simplified but effective risk management” | Replace paper journal semantics with a ledger and cost-inclusive sizing; keep a separate manual calculator. | Cash/risk reservation, restart, partial-fill and loss-limit invariants. |
| “Lightweight sentiment” | Improve RSS/keyword quality first; record optional Jev model/rubric and fallback explicitly, then run ablations. | Labeled-text results and trading utility evaluated separately; unavailable data cannot silently change strategy mode. |

These are transfers of research recommendations, not evidence that the newer repository's implementation is production-ready or that its features improve returns.

## 4. Proposed contracts and integration layout

Retain the static demo. Add optional persistent collection for live research and future overnight paper positions. Keep arithmetic and trade policy in pure TypeScript; Python handles market/source adapters and observation persistence. Avoid a second trading policy implemented independently in Python.

Proposed additions: `src/core/{contracts,bars,indicators,strategy,risk}.ts`, `src/research/{replay,folds,metrics}.ts`, `src/research/replay.worker.ts`, `scripts/replay.ts`, `src/lib/market-stream.ts`, `service/collector.py`, `service/migrations/002_observations.sql`, and `service/paper_store.py`. All are **new paths**. Existing UI and service call sites are changed as described below.

```typescript
// Design sketch, not installed app code; times are UTC Unix seconds.
type BarVersion = {
  venue: string; instrument: string; intervalSeconds: number;
  openTime: number; availableAt: number; revision: number;
  open: number; high: number; low: number; close: number; volume: number;
  final: boolean; origin: 'observed' | 'verified-no-trade';
};
type Observation = {
  asset: string; source: string; status: 'ready' | 'unavailable';
  score: number | null; firstSeenAt: number; evaluatedAt: number;
  availableAt: number; expiresAt: number; methodVersion: string;
  publicationRange: [number, number] | null; modelId: string | null;
};
type Decision = {
  action: 'ENTER_LONG' | 'EXIT_LONG' | 'HOLD'; reasons: string[];
  decisionTime: number; barVersionIds: string[]; observationIds: string[];
  configHash: string; featureVersion: string;
};
```

Availability means **usable after receipt, validation, and any scoring completion**. Publication time and exchange interval start have different meanings. Persist immutable observation/bar versions rather than replacing originally seen history with later revisions. Legacy CSV has no availability proof: label it `assumed-close-availability`, preserve its composite unchanged, and disallow source-weight experiments on it.

Use a `StrategyV2` with explicit timeframe, strategy mode, indicator configuration, source requirements, and exit policy. Migrate `pulse.strategy.v1` to a named legacy five-minute fixed-RSI profile; keep its numerical decision behavior as the baseline. Do not reinterpret old journal rows as executed account positions. Offer an explicit paper-account initialization; keep legacy journal readable/exportable. Persist schema/config versions and invalidate backtest results whenever any relevant config or dataset changes.

## 5. Signal accuracy: reduce ambiguity and measure incremental value

### 5.1 Closed-bar, position-aware strategies

Change `evaluate` into a wrapper around `core/strategy.decide(context, state, config)`. Run the same function in replay. Separate entry readiness from protective exits: missing social data may block a sentiment-required **entry**, but must not prevent closing an existing position on a stop, loss-limit policy, or valid exit rule. “Sell” on a flat spot account becomes HOLD, not an implicit short. Prevent repeat entries from repeated polls of the same bar using persisted decision IDs.

Add two initially experimental modes:

- `legacy-sentiment`: current thresholds plus fixed RSI ceiling, for fair comparisons.
- `technical-trend`: complete-bar EMA trend and RSI momentum, with optional sentiment veto configured as a distinct variant.

For example, test an intraday rule requiring close above EMA(26), positive EMA slope normalized by ATR, and RSI in a training-selected band. A swing variant can require the latest **completed** four-hour trend bar at a one-hour decision time. Do not multiply MACD, EMA, RSI, and VWAP conditions indiscriminately: correlated filters can reduce trade count without adding independent information. Add one feature at a time and measure its incremental effect. This is a proposed experiment motivated by the supplied report's small-feature-set recommendation [R], not an established profitable rule.

`pages/Signals.tsx` should display strategy timeframe, source coverage, warmup, feature values, reason codes, and last decision time. `Chart.tsx` may show partial candles with a visual/text label, while strategy features exclude them. Chart zoom must not mutate strategy config. Preserve the existing UTC-day VWAP as a labeled approximation; for swing tests initially omit it rather than silently changing its anchor.

### 5.2 Source history and quality

Change `service/store.py` to store source-specific observations even if another source is unavailable. Index by `(asset, source, available_at)`; retain status, score, method/model/rubric versions, coverage, publication range, and observation identifiers. Export candles plus source records and a manifest, not only a composite CSV. Compute configured weights during replay using the latest known eligible observation for each enabled source.

Change `service/providers.py` and `stats.py` to canonicalize news URLs, deduplicate normalized headline hashes, cap per-author contribution, and report source concentration. Add explicit age decay with half-life selected on training data, separately for intraday and swing. Preserve empty samples as unavailable. Cache unchanged batches; recomputing a 24-hour sample must not reset its underlying evidence age.

Keep the keyword method as a named baseline. For optional Jev, store the actual returned model, rubric hash, distribution, usage, and method enum (`keyword`, `jev`, `fallback-keyword`). Apply a model/rubric allowlist per frozen experiment; hold or use an explicitly configured fallback variant when it changes. TypeSafe's current API documents typed questions, Choice distributions, and model/usage fields; distribution confidence concerns the answer, not the probability of trade profit. [TypeSafe API][D5] Its published limitations recommend code for numerical and date comparisons. [Jev limitations][D6] This review did not verify the installed SDK's model-selection interface or call the paid API.

### 5.3 What “accuracy” will mean

Predeclare an outcome before tuning. Example experimental label: a next-eligible-price long has positive **net** P&L after twelve strategy bars, using a fixed fee/fill policy. If evaluating stop/target trading, label the actual stop/target outcome instead; a fixed-horizon predictor need not calibrate the deployed exit policy.

Report precision among accepted entries, acceptance rate, missed profitable opportunities, net expectancy, turnover, exposure, and drawdown. Predicting “no trade” almost everywhere can produce misleading headline accuracy. Compare technical-only, technical plus keyword/RSS, and technical plus Jev under equal data coverage and costs, also reporting provider-outage periods. Improvements in text classification and trading utility are separate questions.

## 6. Adaptive indicator tuning: a bounded causal experiment

**Observed:** launch-1280 has fixed RSI/MACD periods and a mean-true-range stop suggestion. It has no adaptive EMA/RSI or learned calibration [indicator engine][A4], [stop calculation][A10]. Therefore, implement a shared Wilder ATR first, keeping the old mean-TR stop as a separately versioned baseline. State the seed convention: skip the first bar's unknown previous close, seed at the mean of the first 14 subsequent true ranges, then recur `(13 × priorATR + currentTR) / 14`.

**Proposal:** add one adaptive EMA pair before attempting adaptive RSI. For each closed bar `t`:

```text
normalizedATR[t] = ATR14[t] / close[t]
baseline[t] = median(previous 20 valid normalizedATR values, excluding t)
ratio[t] = clamp(normalizedATR[t] / baseline[t], 0.5, 2.0)
smoothedRatio[t] = 0.8 × smoothedRatio[t-1] + 0.2 × ratio[t]
acceptedRatio changes only if |smoothedRatio - acceptedRatio| >= 0.15
period[t] = clamp(round(basePeriod × acceptedRatio), minimum, maximum)
EMA[t] = EMA[t-1] + 2/(period[t]+1) × (close[t]-EMA[t-1])
```

These constants are proposed engineering fixtures, not optimized trading settings. `examples/update-core.mjs` implements this causally with period 12 bounded to 8–24. It requires a complete prior baseline for readiness. Zero baseline leaves adaptation unready. Production should add minimum regime dwell and a configurable readiness policy. For a slow EMA, use separate bounds and enforce fast period below slow period. Do not recompute the entire historical series with today's chosen period, which would alter past decisions.

An adaptive RSI needs its own definition: varying Wilder smoothing while retaining gain/loss state differs from selecting the terminal value of a fixed-period RSI. Keep RSI(14) until this choice has reference fixtures. Validate any new definition in `core/indicators.ts` and version it in exports.

Compare three frozen experiments: fixed indicators; higher-volatility/longer-period adaptation above; and a faster-response variant. High volatility can require responsiveness rather than smoothing; no preferred direction is established. Inspect lag, whipsaws, missed breakouts, costs, and trade counts by regime. Regime thresholds, source weights, and grids are learned on training data only. Start with three variants rather than the Cartesian product of many thresholds.

Probability calibration is a later, distinct feature. If a probability model is justified, fit a small regularized predictor on training data and a sigmoid calibrator on a later disjoint segment. Evaluate reliability bins with counts, Brier score, and log loss; these losses also reflect discrimination, so a lower Brier score alone does not establish calibration. Isotonic fitting can overfit small samples. [scikit-learn calibration guide][D7] Display “insufficient evidence” rather than a win probability until held-out validation supports it. Do not derive risk allocation from unvalidated probabilities.

## 7. Backtesting rigor: deterministic research before parameter promotion

### 7.1 Historical depth and data audit

The live adapter requests 720 five-minute OHLC entries [A3]. Kraken documents a maximum of 720 recent entries, including an unfinished interval; an older `since` cannot retrieve unlimited history. [Kraken REST OHLC][D1] At five minutes this is roughly 60 hours, not swing-research depth. The app's 25,000-row import cap is about 86.8 days of uninterrupted five-minute bars [A8]. Raising the cap or changing the UI range cannot create absent history.

Add immutable dataset manifests: venue, market type, base/quote, interval, source URL, retrieval timestamp, file SHA-256, row count, time range, known gaps, revision policy, sentiment method, and availability assumptions. Import intended-venue archives or partitioned files through a CLI; the browser can retain a smaller preview. Kraken offers historical OHLCVT archives and explicitly describes absent archive candles as intervals with no trades. [Kraken archive documentation][D2] No archive was downloaded here, and its pair-specific coverage remains unverified.

Classify gaps as `verified-no-trade`, `unknown-loss`, or `revision-pending`. An unknown gap blocks new entries and feature readiness until recovery/warmup. If continuity needs a carry-forward zero-volume bar for a verified no-trade interval, mark it as derived; do not simulate a fill on nonexistent liquidity. The delivered complete-bucket example conservatively omits any incomplete bucket; verified-no-trade policy belongs in the importer.

### 7.2 Replay, costs, and execution policy

Extract `research/replay.ts` from `backtest` and replace its duplicated entry/sell logic with `core/strategy`. Inject clock and event availability, carry indicator prehistory into scored ranges, and store a decision trace with input IDs. A bar close at 10:15 received at 10:15:02 cannot trigger a fill at 10:15:00. With quote/tick data, fill at the first eligible executable event; with OHLC only, expose a conservative next-eligible-open delay approximation rather than claiming intrabar precision.

Preserve existing next-open, fee, slippage, gap-stop, and stop-first fixtures. Add separate policy names for market-on-trigger versus target limit fills; OHLC touch does not establish queue priority or partial-fill volume. Initial sensitivity scenarios should use configured fees, 2× fees, 0/5/20 basis-point adverse slippage, and zero/one-bar delay, labeled hypothetical until recorded spreads/fills replace them. Keep a pessimistic stop-gap scenario. Use the same cost model for legacy, new strategy, and buy-and-hold; current benchmark is gross while strategy return is net [A8].

Add optional volume participation and missed-fill rules only as explicit scenarios. Candle volume is not proof of executable liquidity. Continue long-only spot first. Shorting or perpetuals would require funding, borrow, margin, and liquidation models, not just a new side flag.

### 7.3 Chronological selection and uncertainty

Create `research/folds.ts` and `metrics.ts`. Each rolling fold contains training → calibration (only if predicting probabilities) → test. Training selects the small predeclared candidate set; freeze parameters before test. Purge labels whose outcome ends reach the next segment. Do not randomly shuffle candles. `TimeSeriesSplit` provides chronological splits and an index gap, but a fixed index gap alone is not event-label purging. [TimeSeriesSplit documentation][D8]

Conditional window examples: intraday 180 training days / 30 calibration days / 30 test days, rolling monthly; swing 24 / 6 / 6 months, rolling six-monthly. These follow the supplied research's illustrative windows [R]; they are not available-data claims or waiting requirements for this assignment. Use shorter windows only with explicit uncertainty and sample counts. Warmup may use earlier available prices, but those bars' returns must not enter test performance.

Keep a final untouched period, record every candidate and failed run, and avoid iterating design on that holdout. Original backtest-overfitting research explains why selection among many trials and hiding trials undermines apparent out-of-sample evidence. [Bailey et al., *The Probability of Backtest Overfitting*][D9] A final holdout alone does not solve repeated selection. A future larger sweep can add selection-bias diagnostics; do not describe a small fold report as a formal PBO estimate.

Report fold/instrument/regime trade counts, net expectancy, net return, drawdown, time underwater, exposure, costs, rejected entries, and out-of-sample degradation. Use date-block bootstrap intervals with a declared seed and sensitivity to block length; overlapping trade labels and correlated assets are not independent observations. Keep zero-trade folds visible as uninformative. No universal number of trades proves an edge.

Move long runs to a new worker, with request IDs, cancellation, progress, and stale-result rejection in `pages/Backtest.tsx`. Add a CLI importing the same engine for partitioned datasets. Every run exports code/config/dataset hashes, candidates, folds, random seed, fill policy, and metrics; offline replay must not query Jev or a data provider.

## 8. Risk management: enforce the estimate through a paper ledger

### 8.1 Cost-inclusive sizing

Replace price-distance-only allocation with a shared unlevered spot-long function used by calculator, replay, and paper submission:

```text
room = min(per_trade_budget, remaining_portfolio_open_risk,
           remaining_daily_loss_room_after_existing_exposure)
estimatedStopFill = stop × (1 - adverseExitSlippage)
lossPerUnit = entry - estimatedStopFill + fee × (entry + estimatedStopFill)
rawQty = min(room / lossPerUnit, freeCash / (entry × (1 + fee)),
             maxPositionNotional / entry)
quantity = floor(rawQty / venueQuantityStep) × venueQuantityStep
```

Entry is an executable ask plus modeled entry slippage; avoid double-counting spread if already using bid/ask. Production must use actual fee tier, quantity/price increments, and order minimums. Use decimal or fixed-point cash accounting. The delivered JavaScript example is illustrative binary floating point with conservative flooring and safe-lot checks; it is not a venue-ready accounting library.

Synthetic example: entry $100, stop $95, fee 0.1%, exit slippage 0.1%, $100 remaining risk gives loss/unit **$5.289905**. At quantity step 0.01, quantity is **18.90**, with modeled loss **$99.9792045**. Current fee-free sizing gives 20 units and nominal loss $100. Cash, notional, and minimum-size constraints may reduce or reject the proposed order. Stop gaps can exceed modeled loss; never label this a guaranteed maximum.

### 8.2 Account state and breach policy

Add a paper ledger with cash, reserved cash/risk, positions, pending intents, realized P&L, marked equity, peak equity, and UTC-day opening equity. In `App.tsx/PaperTrade`, request a sized intent rather than accepting quantity without account checks. Reserve cash and risk atomically with intent creation, using a ledger version to reject stale proposals. Use a persistent single-writer service transaction for the optional multi-tab/durable account; an in-memory UI mutex is insufficient across tabs.

Expose three primary owner-settable controls: per-trade loss budget, total open-risk budget, and daily loss limit. Add account drawdown limit and aggregate notional cap in advanced settings. Compute remaining daily room after marked losses and reserved/open modeled risk; document treatment of open profit, deposits, withdrawals, and missing marks. Use marked equity for loss limits, not realized P&L alone. Require owner inputs for any real account rather than repurposing demo capital.

Breach behavior: latch entry prohibition, cancel pending entry intents, continue protecting positions, and show reason/reset state. Daily reset requires a known mark and UTC boundary; drawdown breach stays latched until explicit reset and state reconciliation. Stops update risk reservations; do not free risk solely because an unconfirmed local stop was tightened. Partial fills transfer reservation into position risk; cancellation releases only the unfilled amount. Duplicate events and unknown outcomes must not release protection or duplicate exposure.

For swing paper positions, collect and evaluate protection independently of browser visibility. On restart, reconcile persisted positions/intents before allowing entries. Without the service running, label overnight monitoring unavailable. Exchange-native protective orders and real-order reconciliation are a later execution project; this plan does not enable live orders or promise stop reliability.

## 9. Market integration that supports these experiments

Add `src/lib/market-stream.ts` for foreground research and an optional `service/collector.py` for durable collection. Implement one venue first. Kraken's ticker supports BBO-triggered updates and best bid/ask quantities [D3]; OHLC updates are trade-driven and identify interval start, not a candle-finality flag [D4]. Normalize these formats and track quote freshness separately from last-trade freshness. A heartbeat does not make an old price executable.

Use explicit readiness states: disconnected → synchronizing → warming → ready; stale quotes, unresolved gaps, or venue suspension hold entries. Reconnect with bounded backoff/jitter, resubscribe, hydrate REST history, merge buffered events by instrument/interval/revision, and suppress obsolete connection callbacks. A closure watermark/grace policy must be versioned and replayed. Do not invent sequence numbers for channels lacking them.

Change `service/main.py` to return independent market and source states. Reuse clients under lifespan management; refresh sources in bounded background tasks rather than awaiting a full social/news/on-chain cycle per price request. Persist true completion availability, enforce timeouts, and never substitute demo data into live mode. Keep credentials and Jev calls on the service, outside deterministic strategy arithmetic.

Proposed performance measurements, not achieved SLAs: on documented test hardware with four liquid instruments, p95 validated closed-bar receipt→decision under 25 ms; p95 receipt→foreground UI under 350 ms with approximately 250 ms rendering batching. Measure separately the closure grace, collector lag, source scoring latency, and any future order acknowledgment/fill time. Entry quote-age and spread limits are per-profile owner settings validated in shadow tests. Streaming improves timeliness; it does not itself establish better signal accuracy.

## 10. Examples and tests to integrate

Delivered offline code: `examples/update-core.mjs`; execute **`node --test checks/update-core.test.mjs`** on Node 22+. It demonstrates complete-bar availability, component sentiment replay, seeded Wilder ATR, causal adaptive EMA, constrained spot sizing, and label-end purging. It has no runtime packages or network dependency.

For example, `completeBars([bar0, bar1], 300, 900, decisionTime)` emits no fifteen-minute strategy bar. If all three bars exist but the last is available at second 902, the bucket remains unavailable at second 900 and becomes eligible at 902. Likewise, the same Social/News observations replay to 65 or 35 under the two weight profiles above; an observation first available after the decision is excluded. These behaviors are asserted by the delivered tests.

| Integration test location (proposed) | Fixture and required assertion |
|---|---|
| `tests/core-bars.test.ts` | Partial/gapped/late buckets never become signal bars; malformed or duplicate timestamps reject; verified-no-trade bars cannot supply fills. |
| `tests/core-indicators.test.ts` | Known ATR seed/shock values; fixed RSI legacy parity; append or perturb future prices without changing earlier features; adaptive periods bounded, zero volatility and warmup handled. |
| `tests/core-strategy.test.ts` | Chart zoom leaves decisions unchanged; a completed four-hour bar gates hourly swing context; flat Sell cannot short; repeated bar cannot duplicate an entry; missing sentiment blocks entry but not protective exit. |
| `tests/test_observations.py` | Separate source weights replay; latest unavailable status does not resurrect an older success; revised bar/score not available retroactively; legacy composite cannot be reweighted. |
| `tests/replay.test.ts` | Existing stop/gap/cost tests retained; delayed decision cannot fill earlier; target limit touch not guaranteed fill; net benchmark parity; warmup excluded; exact ledger reconciliation. |
| `tests/folds.test.ts` | Outcome ending at next segment boundary purged; parameters/calibrator fit only designated rows; future-data sentinel cannot influence training; zero-trade fold not treated as evidence. |
| `tests/test_paper_store.py` | Two concurrent intents cannot overspend cash/risk; duplicate fills idempotent; partial fill/cancel preserves reservations; restart/unknown outcome holds entries; loss latch and reset tested. |
| `tests/market-stream.test.ts` | Disconnect, stale quote, duplicate/out-of-order revisions, obsolete callbacks, suspension, quiet market, and failed backfill cannot create false readiness. |
| `tests/sentiment-quality.*` | “not bullish”, asset ambiguity, repeated author, syndication, irrelevant and adversarial text; model/rubric switch, timeout, malformed result, empty sample, and fallback recorded explicitly. |
| `tests/research-browser.mjs` | Long run cancellation; stale worker result discarded; strategy migration; per-asset research preserved; changed dataset/config clears results; account controls remain keyboard accessible. |

These integration tests are future acceptance requirements. Only the delivered example tests and the baseline checks below were executed in this assignment.

## 11. Update sequence and promotion decisions

| Phase | Specific changes | Completion gate |
|---|---|---|
| P0: semantics | `types.ts`, `engine.ts`, new `core/contracts,bars,strategy`; strategy-v2 migration; reason/timeframe UI; freeze legacy fixtures. | No future input dependency; complete-bar gates; legacy decision parity; entry/exit readiness separation. |
| P1: data | `service/store.py/providers.py/main.py`, versioned observation migration, collector, market stream, dataset importer/manifests. | Source-weight replay; outage/revision recovery; genuine availability persisted; provenance and measured latency. |
| P2: risk | `core/risk`, `pages/Risk.tsx`, `App.tsx/PaperTrade`, durable paper ledger. | Cost-inclusive risk/cash invariants; concurrent intents; marked loss/drawdown limits; restart and protective exits. |
| P3: research | Shared replay, worker/CLI, folds, metrics, net benchmarks, cost/delay scenarios, export manifest. | Offline reproducibility; purge/leak tests; browser/CLI parity; complete candidate/fold report. |
| P4: adaptation and sentiment | Shared ATR and bounded adaptive EMA; fixed-RSI comparison; labeled sentiment and optional pinned Jev experiments. | Predeclared held-out evaluation, source-outage analysis, uncertainty and sample counts; no automatic default change. |
| P5: optional probabilities | Separate outcome model/calibrator and reliability UI. | Calibrator disjoint from predictor training/test; reliability and utility evidence; insufficient-sample state. |

Phases identify dependency order, not a promise of calendar completion. P1 data collection and P2/P3 implementation can overlap; assessment of P4/P5 depends on historical or forward evidence. Real execution remains a separately scoped future project.

Before promotion, predeclare acceptable utility and drawdown constraints with the owner. Suggested research gate: no causality/account-invariant failures; compare net expectancy against legacy under equal costs across multiple held-out folds; report paired block-bootstrap uncertainty and worst-fold drawdown; assess cost/delay sensitivity and missed opportunities. If intervals remain wide or results depend on one asset/regime, leave the experiment off and report inconclusive evidence. Successful deterministic tests establish mechanics, not predictive edge.

## 12. Checks performed and their limits

- Retrieved the pinned app source and research artifact; verified the research artifact SHA-256 and retained Git blob IDs/URLs in `evidence/source-manifest.json`.
- **16 launch-1280 upstream numerical/strategy/import/validation tests passed.** Used Node 24.21.0 built-in TypeScript stripping in a disposable copy, changing relative import extensions to `.ts`. This was not an npm build, full typecheck, browser test, or complete Python/service suite.
- Ran six targeted baseline probes described in section 2, including standard-library SQLite/keyword checks. Results concern synthetic source behavior only.
- **18 delivered example tests passed**, including the 16-case cash/risk-bound grid, availability/finality, prefix invariance, ATR shock, source outage handling, and purge boundary tests.
- Ran report structure/local-reference checks and JavaScript syntax checks. Results are recorded in `evidence/check-results.json`. These are author self-checks with no independent review authority.

No production UI, authenticated APIs, streaming exchange session, historical-strategy outcome, full account ledger, real order, or statistical promotion gate was tested. The proposed upgrade has not been implemented in the upstream app. The online sources can change; citations pin app code and identify documentation checked on this date.

## 13. Unanswered questions and uncertainty

| Question | Effect on implementation | Treatment until answered |
|---|---|---|
| Which execution venue, symbols, quote currency, and instrument type? | Fees, source coverage, precision, and execution policy differ. | Begin research with the existing Kraken spot/USD adapter; validate actual supported pairs. Do not infer owner's account eligibility. |
| Which decision and holding horizons constitute intraday/swing? | Warmup, sampling, outcome labels, and source decay differ. | Expose separate experimental 5m/15m and 1h/4h profiles; do not claim chart selection settles this. |
| Is the goal decision support, a paper account, or unattended trading? | Determines persistence and overnight protection. | Deliver research/paper improvements first; real execution separately scoped. |
| What historical price/sentiment data and retention rights exist? | Availability-aware evaluation may lack enough observations. | Import provenance manifests and collect forward; never synthesize missing historical sentiment as empirical evidence. |
| What account limits, fee tier, and venue order rules apply? | Determines feasible sizing. | Owner-settable runtime settings; synthetic examples are tests only. |
| What cost-adjusted utility/drawdown tradeoff should select the strategy? | Higher precision can coexist with worse net performance. | Predeclare before test/holdout use; no universal threshold supplied. |
| Does adaptive smoothing or Jev actually improve signal accuracy? | Determines whether optional complexity is worthwhile. | Unanswered until held-out/forward ablations; current evidence establishes mechanics, not edge. |

None of these questions prevents the requested plan. They must be resolved or represented by explicit settings before production integration.

## Sources

The source index below resolves the citations throughout the report. App evidence is pinned to the [reviewed launch-1280 tree][A0]; the supplied research is the [job's Markdown artifact][R]. External technical support comes from Kraken's [REST OHLC][D1], [historical archive][D2], [ticker][D3], and [OHLC stream][D4] documentation; TypeSafe's [API][D5] and [model limitations][D6]; scikit-learn's [calibration][D7] and [chronological split][D8] documentation; and the authors' [backtest-overfitting paper][D9]. Module-specific app links appear beside the findings and resolve below.

[A0]: https://github.com/identity-md-launches/launch-1280-simd-chat-build-custom-web/tree/8220e881d0f5809b46132c04d31d72b793a2fcfc
[A1]: https://github.com/identity-md-launches/launch-1280-simd-chat-build-custom-web/blob/8220e881d0f5809b46132c04d31d72b793a2fcfc/src/App.tsx#L40-L57
[A2]: https://github.com/identity-md-launches/launch-1280-simd-chat-build-custom-web/blob/8220e881d0f5809b46132c04d31d72b793a2fcfc/service/main.py#L40-L63
[A3]: https://github.com/identity-md-launches/launch-1280-simd-chat-build-custom-web/blob/8220e881d0f5809b46132c04d31d72b793a2fcfc/service/providers.py#L22-L41
[A4]: https://github.com/identity-md-launches/launch-1280-simd-chat-build-custom-web/blob/8220e881d0f5809b46132c04d31d72b793a2fcfc/src/lib/engine.ts#L10-L63
[A5]: https://github.com/identity-md-launches/launch-1280-simd-chat-build-custom-web/blob/8220e881d0f5809b46132c04d31d72b793a2fcfc/src/Chart.tsx#L13-L31
[A6]: https://github.com/identity-md-launches/launch-1280-simd-chat-build-custom-web/blob/8220e881d0f5809b46132c04d31d72b793a2fcfc/src/lib/engine.ts#L37-L46
[A7]: https://github.com/identity-md-launches/launch-1280-simd-chat-build-custom-web/blob/8220e881d0f5809b46132c04d31d72b793a2fcfc/src/pages/Backtest.tsx#L9-L25
[A8]: https://github.com/identity-md-launches/launch-1280-simd-chat-build-custom-web/blob/8220e881d0f5809b46132c04d31d72b793a2fcfc/src/lib/engine.ts#L89-L140
[A9]: https://github.com/identity-md-launches/launch-1280-simd-chat-build-custom-web/blob/8220e881d0f5809b46132c04d31d72b793a2fcfc/service/store.py#L32-L61
[A10]: https://github.com/identity-md-launches/launch-1280-simd-chat-build-custom-web/blob/8220e881d0f5809b46132c04d31d72b793a2fcfc/src/lib/engine.ts#L74-L87
[A11]: https://github.com/identity-md-launches/launch-1280-simd-chat-build-custom-web/blob/8220e881d0f5809b46132c04d31d72b793a2fcfc/src/App.tsx#L95-L103
[A12]: https://github.com/identity-md-launches/launch-1280-simd-chat-build-custom-web/blob/8220e881d0f5809b46132c04d31d72b793a2fcfc/service/stats.py#L7-L30
[A13]: https://github.com/identity-md-launches/launch-1280-simd-chat-build-custom-web/blob/8220e881d0f5809b46132c04d31d72b793a2fcfc/service/providers.py#L44-L126
[A14]: https://github.com/identity-md-launches/launch-1280-simd-chat-build-custom-web/blob/8220e881d0f5809b46132c04d31d72b793a2fcfc/templates/execution.py#L10-L63
[R]: https://api.imd.fun/artifacts/bbe25e3363b389d11377db186ab876ae62be43039494ebab94170dd26f296df3
[D1]: https://docs.kraken.com/api-reference/market-data/get-ohlc-data
[D2]: https://support.kraken.com/articles/360047124832-downloadable-historical-ohlcvt-open-high-low-close-volume-trades-data
[D3]: https://docs.kraken.com/exchange/api-reference/spot-websocket-v2/ticker
[D4]: https://docs.kraken.com/exchange/api-reference/spot-websocket-v2/ohlc
[D5]: https://docs.typesafe.ai/api
[D6]: https://docs.typesafe.ai/model-jaggedness/jev-1.13
[D7]: https://scikit-learn.org/stable/modules/calibration.html
[D8]: https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.TimeSeriesSplit.html
[D9]: https://www.davidhbailey.com/dhbpapers/backtest-prob.pdf
