New components
host_replay_adapter.py bridges gauntlet.run_year to the recovered FinBot
v0.5.2 execution engine. The vendor copy is byte-for-byte from the earlier
archive. A historical clock is scoped to each replay worker, restoring its
original clock and environment afterwards. It uses an in-memory account and
writes replay ledger JSON under runs/replay_ledgers. It does not open your live
database, contact Alpaca, or alter the installed gateway/trading process.

Existing engine controls are retained: long-only BTC/USD and ETH/USD; one lot
per symbol; no leverage; 25% combined crypto exposure; 1% planned-risk sizing;
modeled 0.25% entry and exit fees and sizing slippage allowance; 3% daily and
10% peak drawdown latches; tagged optional trailing stops. These are inherited
from the recovered source, not newly added host production restrictions.
The existing engine does not implement an autonomous Polymath decision brain.
It checks supplied research/entry instructions and simulates their execution.
The new adapter therefore calls your actual strategy through the interface
below rather than inventing PASS research or replacing your strategy with SMA.

Actual downloaded inputs
- 38 original ALFRED vintage CSV tables; 58,244 nonmissing factor observations.
- Factors: INDPRO, CPIAUCSL, UNRATE, FEDFUNDS, GS10, PAYEMS, GDPC1, T10Y3M.
- Snapshot dates: 2000-01-01, 2009-01-01, 2020-01-01, 2025-01-01,
  2025-12-31. These are FIVE snapshots, not daily vintage coverage for 100 years.
- ALFRED returned HTTP404 for T10Y3M at the first two snapshot dates. The
  missing records are documented; none were filled with guessed values.
- Each downloaded ALFRED header was checked against its requested series and
  vintage. Source URL, hash, observation count/date range and retrieval time
  are in data/download_manifest.json. data/macro_observations.jsonl is the
  normalized table, retaining source and vintage provenance.
- Snapshot values are withheld until two UTC days after the snapshot date.
  Their availability is never backdated to the economic observation month.
  An INDPRO value for 1926 found in a 2020 snapshot is NOT 1926 vintage data.
- FRED CBBTCUSD and CBETHUSD CSVs: daily historical reference prices, NOT
  intraday execution quotes and not independently point-in-time verified.
- Shiller's unchanged ie_data.xls from the publisher's site, with provenance.
  shiller_1926_2025_monthly.csv extracts all 1,200 months, January1926 through
  December2025, preserving index price, dividends, earnings, CPI, date fraction
  and long interest rate. These are retrospective monthly research references.
  Price observations are monthly averages; dividend/earnings figures include
  interpolation, as documented by the publisher. They are NOT tradable tick
  prices or unrevised release-time fundamentals. Do not pass them as BTC quotes.

What is still missing for the exact century replay
1. Actual host strategy module and capital-ratchet function. Neither is
   available in the recovered public execution-engine source. Naming an
   adapter is no longer the blocker; strategy/data coverage remains substantive.
2. Full-year intraday historical quotes for the chosen instruments. The
   recovered BTC/ETH engine has no authentic 1926 cryptocurrency history.
   Its supported universe cannot be made century-complete by renaming indices.
3. Point-in-time external research context for earlier decades. The downloaded
   ALFRED snapshots do not provide what was known on every date since1926.
These are input coverage gaps, not extra authentication requirements. A full
century run remains incomplete. No Mac deployment or weekend activation is
claimed. Local installation/running is handled by your existing host setup.

Host strategy interface (configure privately on the host)
Set replay_config.json strategy_module to the importable local module name.
No credentials or proprietary source need be sent to this chat.

def decide(context):
    # context: at, quotes, macro, account, lesson_history, mode
    # Maintain your own decision history/state as appropriate for the strategy.
    # Return an array of HOLD/BUY/SELL decisions.
    ...

def capital_floor(context):
    # context: equity, peak_equity, locked_floor, starting_capital_usd, at
    # Return the floor as a nonnegative exact decimal STRING. It cannot decrease
    # or exceed peak equity. The adapter does not invent your ratchet formula.
    ...

A BUY includes symbol, stop (decimal string), optional quantity and trailing_pct,
and research matching the recovered engine's six-channel evidence structure:
  decision=RESEARCH_PASSED, analyzed_at=timezone-aware date/time;
  geopolitical, macroeconomic, behavioral, accounting, tax, quantitative each
  have status=PASS, summary, sources[{url,observed_at,available_at}].
The source available_at and observed_at must not follow the historical decision.
No synthetic research PASS markers are generated by this adapter.
A SELL includes action and symbol. HOLD does not enter a position.
Rejected trade instructions are stored in the yearly replay ledger. The
supervisor separately records income-target deviations and proposed lessons.
Lessons are documentation; strategy changes/model training are not automatic.

Replay-bar input format
One JSON object per line, strictly increasing timestamp:
{
  "at": "2015-01-01T00:00:00Z",
  "available_at": "2015-01-01T00:00:00Z",
  "data_origin": "HISTORICAL_INTRADAY_QUOTES",
  "bar_interval_seconds": 60,
  "quotes": {"BTC/USD": "ACTUAL_DECIMAL_PRICE"},
  "source_url": "https://YOUR_REAL_SOURCE/..."
}
This is a FORMAT EXAMPLE, not a fabricated historical observation.
Quotes must include every open position. To evaluate intraday controls with
this adapter, bars must be at most60seconds apart, with no gaps exceeding the
declared interval. Each full year must cover its opening minute through
December31 23:59UTC. Quote provenance is host-supplied, not independently
vendor-authenticated. 60second observations cannot establish what happened
between observations. Gap moves may breach a floor despite protective exits.

The recovered 3% breaker runs at each supplied observation. The host's floor
callback is invoked, validated as monotonic, and crossings trigger simulated
exits and a halt. It does not promise an absolute loss ceiling. Annual income
is reconciled to realized net dispositions and ending cash, after modeled fees.
Remaining inventory closes at the final supplied year-end marks. No borrowed
capital or external inflows are counted as income. Targets are not passed to
strategy.decide as if they were market evidence.

Validation and runtime
20 tests passed, including original supervisor tests plus historical clock
restoration, macro lookahead exclusion, actual recovered-engine buy/sell/fee
reconciliation, incomplete-year rejection and synthetic-data origin rejection.
Small-window fixtures are explicitly PARTIAL_REPLAY_NOT_CENTURY and cannot
pass as complete century years. See evidence/updated_tests.txt.
Actual adapter preflight loaded the module and then logged:
  REPLAY_ADAPTER_ERROR:MARKET_REPLAY_BARS_NOT_INSTALLED
See evidence/adapter_preflight_stdout.jsonl. No income result was manufactured.
The full historical replay, host strategy and phone rendering remain unverified.

Refresh original data without credentials (public chart CSVs)
  python3 download_data.py --with-reference-prices
Other explicit snapshots can be requested with --vintages YYYY-MM-DD ...
Unavailable dates are recorded, never silently replaced by current values.
The refresh regenerates the download manifest and normalized macro table.
It does not refresh the Shiller workbook; its original URL/hash is recorded.
The official FRED API is an alternative and requires the user's own API key;
this package uses public chart downloads and includes no API key.

After host strategy and real replay bars are installed:
  python3 gauntlet.py --adapter host_replay_adapter --continuous --serve
The process must remain running on the host. No persistent chat-side execution
is promised. Sunday-night deadline and threshold remain unchanged. Monitor
locally at http://127.0.0.1:8890/; use your existing authenticated gateway to
make it available on your phone. Never expose the local monitor without that
existing access protection. Configurable port and loopback do not bind you to
a fixed external laptop IP address.
