# AlphaBot V2 native execution engine — 1.0.0-rc2

This package contains complete executable source, not a server envelope. Keep all runtime modules together: `gauntlet_v2.py`, `host_strategy.py`,
`auth_gate.py`, `audit_ledger.py`, `audit_viewer.py`, `audit_dashboard.py`, and
`web/`, plus `requirements.txt`. Python 3.11+ is required. The live/check/rearm
commands require an interactive macOS terminal; init, verify, observe and
synthetic tests also run on Linux (`fcntl` locks).
The installed 0.3.1 plugin is unchanged; this native runner is a separate build.

## Restored administrator login

The original administrator gate is mandatory for `check`, `run` and `rearm`.
There is no command-line switch or offline password fallback that disables it.
The gate remains separate from broker API authentication and dashboard access.

1. Require macOS (`Darwin`), an interactive TTY and the main thread. Disable core
   dumps and read the password with the hidden `AlphaBot gateway password: ` prompt.
2. Send exactly `{"gate_challenge":"<SHA256 of UTF-8 password>"}` to
   `POST /api/v1/auth/gate` at the pinned HTTPS gateway origin. Require status
   exactly `AUTHENTICATED` and integer `session_token_expires_sec` exactly 3600.
3. Require a usable Secure, HttpOnly, hostname-bound cookie at `/`. A JSON status
   alone does not create an authenticated session. Reject redirects, mismatched
   origins, HTTP, URL credentials, paths, queries and fragments. Inherited HTTP
   proxies are disabled. A gate failure is attempted once and fails closed as
   `AUTHENTICATION_FAILED`.
4. Bind the broker/account separately at cookie-authenticated `/v1/broker-session`
   using `{broker, account_id, api_key, secret_key}`; require `bound:true` and the
   same account ID. Credentials never go into the password challenge payload.
5. Use a monotonic 3600-second deadline from challenge dispatch. A background
   watchdog revokes authorization at expiry; protected native requests and each
   strategy invocation recheck authorization. Expiry forces a fresh main-thread
   hidden prompt before strategy execution. Failed renewal leaves a durable halt.

Set `LIVE_AUTH_GATEWAY_URL` in the launcher environment to the owned gateway
origin. `init` creates separate `security.json` with the previously established
owner gateway hostname `qzotic-gateway.sotality.com`, port 443 and an account
reference field. Review those nonsecret settings against the actual AlphaBot
service before use. An existing rc1 project without `security.json` uses that
same pinned hostname (or its existing `config.json.gateway_hostname`), preserving
its existing trading-configuration fingerprint and all risk state. Configure a
Kraken account reference in `security.json.account_id`; Alpaca's account ID is
read from its authenticated account endpoint. Neither source defaults nor TLS
prove that the external gateway is currently deployed or configured correctly.

If the gateway uses Cloudflare Access service credentials, provide both
`CF_ACCESS_CLIENT_ID` and `CF_ACCESS_CLIENT_SECRET` in the environment. They are
sent only to the pinned gateway, not to broker endpoints. The actual Cloudflare
Tunnel/Access deployment, origin token checks, session identity/account binding
and server-side expiry remain external requirements. No public tunnel is
created by this package. The gateway must restore the same account binding on
session renewal without requiring the CLI to persist broker secrets on disk.

Broker environment entries are removed after successful bootstrap. Native
broker signing still requires in-memory key/secret references in the broker
clients and risk worker; the old gateway-only client's disposal of all local
references cannot be claimed for this native architecture. Immutable Python
strings, parent-process environments, swap or crash tooling may retain copies;
secure memory wiping is not guaranteed. Passwords, challenges and session cookies
are never written to the ledger, diagnostics or logs.

An expired login blocks emergency routing too; emergency code cannot bypass the
administrator gate. A prompt can block the main loop while the risk thread
continues independently, but authorization expiry may prevent its broker calls.
A failed/expired authorization that prevents flattening remains visibly
`LIQUIDATION_UNCONFIRMED`. Independent gateway/broker-side protection is still
required; this build does not claim uninterrupted protection during host or
login failure.

## Implemented execution paths

* Alpaca: authenticated real-time equity bar WebSocket, authenticated order-update
  WebSocket, native REST account/position reads and market-order submission.
  Alpaca's streaming order channel is an update channel; submission uses REST.
* Kraken: public WebSocket v2 OHLC updates, authenticated balances/executions
  channels, authenticated WebSocket v2 `add_order`, signed REST token acquisition,
  account checks, cancellation and terminal-order reconciliation. Monetary JSON
  numbers retain Decimal precision. Durable, serialized nonces survive restarts.
* Independent OS risk thread with its own event loop, broker session and, for
  Kraken, its own authenticated socket. One-second target sampling reads Alpaca
  account equity or Kraken authenticated balances valued at a fresh public bid.
  It cancels outstanding orders immediately upon halt, before waiting for the
  strategy's submission lock, then reconciles and liquidates observed inventory.
* Permanent peak and milestone ratchets: $250 baseline; $500/$1,000/$2,000 at
  $1,000/$2,000/$4,000 peaks, continuing by doubling. The owner's additional
  starting-capital-minus-acquisition-cost protection is retained. Acquisition
  cost includes actual fees or an explicitly labeled conservative fee reserve.
* FULL-sync SQLite WAL ledger with fixed-point TEXT amounts, hash-chained market
  observations, risk samples, order intents, order acknowledgments, terminal
  execution receipts, decisions and LESSON records. This is an internal
  management ledger; it is not represented as a GAAP/IFRS or tax-reporting book.
* At a fill/target deviation **at least 0.0001%**, a LESSON records the exact
  order/fill failure path, target, fill, deviation, cumulative count and penalty.
  Subsequent strategy budgets apply `lesson_risk_decay ** cumulative_count`.
* Intent persistence precedes submission. Ambiguous requests are never blindly
  resubmitted. Read-only client-ID lookup recovers acknowledged or filled orders
  after response loss. An unresolved sell blocks another liquidation submission.
* Durable halts survive restart. Explicit operator rearm requires a reconciled,
  flat account above the preserved floor. It preserves peaks, floors, lessons,
  receipts, history and the consumed monthly-entry marker.

## Install and initialize

```bash
python3 -m venv .venv
. .venv/bin/activate
python3 -m pip install -r requirements.txt
python3 gauntlet_v2.py init --project "$PWD/alpaca-project" --broker alpaca --symbol SPY
```

For Kraken use a separate project and account scope:

```bash
python3 gauntlet_v2.py init --project "$PWD/kraken-project" --broker kraken --symbol BTC/USD
```

`init` creates `config.json`, `security.json` and empty macro/event input files. It
refuses to overwrite an existing project. Defaults are $500 starting capital,
$100 maximum modeled order budget, 0.5% fee reserve, 1% slippage reserve and
0.95 lesson decay. Set configuration to the intended dedicated account **before
first check/run**, because the durable database binds the configuration and key
fingerprint. No credential belongs in configuration, source, logs or chat.

A first live start requires a flat dedicated account, no open orders and cash
matching configured starting capital within $0.01. Alpaca requires a USD cash
account with multiplier 1 and a tradable fractional equity. Kraken requires USD
plus the selected BASE/USD spot asset; margin, other assets and earn wallets
are rejected. The scopes are separate; this is not a consolidated cross-broker
portfolio. Do not use a shared account with unrelated holdings.

## Credentials and preflight

Set `LIVE_BROKER_API_KEY` and `LIVE_BROKER_SECRET_KEY` in the launcher's environment
using your existing secret manager. The code reads exactly those environment
variables at runtime. For Kraken, the secret is the broker-provided Base64 secret.
Use a key scoped to this account with balance/order-history/WebSocket/trading/
cancellation permissions and no withdrawals. Both threads use the same key,
with serialized persistent nonce handling. Keep any other process off that key.

```bash
python3 gauntlet_v2.py check --project "$PWD/alpaca-project"
```

`check` performs real broker reads, validates account/instrument access, writes a
local preflight observation and never sends an order or cancellation. It does
not prove market-data entitlement or full execution acceptance. `verify` checks
local database integrity, physical double-entry rows, receipt/LESSON rows,
LESSON ancestry, trial balances and durable risk/book state against event hashes
without credentials or network:

```bash
python3 gauntlet_v2.py verify --project "$PWD/alpaca-project"
```

## Strategy inputs

The retained strategy buys 20% of cash, reduced by cumulative LESSON decay and
capped by `max_order_usd`, when the latest visible INDPRO month exceeds the mean
of the previous three consecutive months. It consumes at most one entry per
observation month. Geopolitical tone strictly below -5 triggers a risk override.
Every market update and every risk sample refreshes the local signal context.

`macro.jsonl` schema (one JSON object per line; numbers are decimal strings):

```json
{"series":"INDPRO","observation_date":"2026-09-01","available_at":"2026-10-16T13:15:00+00:00","value":"100.5"}
```

The line above illustrates the schema only; it is not supplied as market data.
Provide actual licensed observations in the initialized input file. No synthetic
signal is inserted by the runtime. Missing four-month history produces an
explicit HOLD while streaming and risk monitoring continue. Supplied publication
metadata controls post-2000 visibility; absent metadata assumes observation-date
visibility. The retained pre-2000 policy uses observation dates even when release
metadata exists, which permits historical look-ahead. No historical strategy
performance claim follows from this build.

`geopolitical.jsonl` accepts `at` (timezone-aware ISO) and `tone` (decimal string).
An empty file explicitly represents no supplied events and neutral tone 0. A
month containing only future events has unknown tone and blocks entries. This
local schema is not a native GDELT ingestion implementation. The runtime does
not fetch macroeconomic or geopolitical data from an external provider.

## Audit dashboard and entry diagnostics

`run` starts its correct-database observer on `http://127.0.0.1:8080` by default
(use `--port` to choose another local port). Open that page after completing the
hidden login. A connected, heartbeating WebSocket observer is required before
`decide()` and new entries. Until the observer connects, entry is blocked and
the risk thread continues monitoring; opening the browser does not itself start
trading or authorize an order. A lost observer blocks subsequent entries while
risk handling remains independent. Observer connections are read-only, use
separate SQLite query-only connections, have Host/Origin and CSP checks, bounded
requests/clients/messages, and reconnect through committed-event replay cursors.

The dashboard includes Overview, Transaction ledger, Lesson memory repeat matrix,
and Positions & context. It includes a historical event slider, date/time lookup,
first milestone-crossing lookup, and recorded equity versus protected-floor plot.
Displayed windows are explicitly bounded (256 events, 200 lessons, 1,000
observations). Amounts are displayed from fixed-point strings; browser numeric
chart drawing is presentation-only. The dashboard performs no external tracking,
loads no external assets and has no order/start/login endpoints.

Before strategy invocation and again after an order preflight, the runner invokes
an independent read-only verifier and exclusively creates a local
`live_diagnostics_<event>_<suffix>.html` report. Failure blocks entry. Emergency
liquidation remains separate from observer readiness; it still requires valid
administrator authorization. Observer-only mode and independent export do not
need broker credentials or a trading login:

```bash
python3 gauntlet_v2.py observe --project "$PWD/alpaca-project" --port 8080
python3 audit_viewer.py --project "$PWD/alpaca-project" --verify
python3 audit_viewer.py --project "$PWD/alpaca-project" --date 2026-10-28 --format html --output snapshot.html
python3 audit_viewer.py --project "$PWD/alpaca-project" --milestone 1000
```

Date-only exports include the full UTC day. The dashboard's date/time input is
interpreted in the browser's local timezone and sent as UTC. Historical snapshots
show the halt state as of the selected event rather than substituting today's
state. No missing historical observation is fabricated. Full independent
verification is O(history); instant reports on an unbounded ledger are not
promised. This build does not include a browser binary; responsive rendering and
keyboard/zoom behavior remain unverified where no browser runtime is installed.

## Double-entry and upgrade behavior

Every newly instrumented observation has balanced Decimal postings for cash,
fee-inclusive inventory, valuation adjustments and opening/unrealized equity.
Terminal receipts post acquisitions/disposals and realized results. Actual fees
are capitalized on entry; an explicitly labeled reserve is used when actual fees
are unknown. Fee-estimate reconciliation is disclosed separately. Unexplained
cash/cost changes post to `Equity:UnclassifiedSuspense`, create a LESSON and latch
a durable halt; rearm refuses unresolved accounting. In-flight fills are marked
as deferred reconciliation until authoritative receipts arrive.

Audit events, receipt rows, LESSON rows and journal lines have append-only SQL
triggers. Each event hash covers its postings and accounting metadata. Independent
verification checks physical rows, balanced debits/credits, trial balances, LESSON
ancestry and durable book/peak/ratchet state. This is tamper evidence, not a defense
against an administrator rewriting the full chain or deleting a tail without an
external anchor. There is no external tracking or anchoring service.

An existing rc1 database is upgraded additively: the new journal-line table,
indexes and immutable triggers are installed. Existing events, lessons, pending
intents, receipts, peaks, floors and monthly-entry state are preserved. Earlier
rc1 events did not contain double-entry postings; the upgrade explicitly starts
accounting at the first newly instrumented snapshot and does not reconstruct or
certify missing prior accounting. Existing pending outcomes still halt and require
reconciliation, and the upgrade never clears a halt.

## Start an actual live session

These commands can submit real-money orders; they are instructions, not actions
that were performed while building this package:

```bash
python3 gauntlet_v2.py run --project "$PWD/alpaca-project" --live
```

Use the Kraken project instead to run Kraken. Run each broker as a separate
process with its own environment and dedicated account. A timed session is
available with `--duration 300` (seconds). Ctrl-C, SIGTERM, duration expiry,
stream failure or a risk fault stop admission, cancel/reconcile, attempt full
liquidation of the managed scope and leave a durable halt. Exit code 2 indicates
halt/fault, including an intentional session shutdown; it is not a normal
automatic-restart signal. Exit code 0 applies to successful init/check/verify/rearm.

Review the ledger and broker state after any halt. Rearm only after resolving
the cause; the command makes no trade and refuses unresolved intents, positions,
open orders, cash/holdings mismatches or equity below the preserved floor:

```bash
python3 gauntlet_v2.py rearm --project "$PWD/alpaca-project" --acknowledge-halt --reason "Reviewed halt and verified broker account is reconciled and flat"
```

Do not delete state to bypass a halt or reset a ratchet. Different configuration
or key fingerprints require deliberate migration/review; there is no automatic
risk-state reset. Unknown outcomes that cannot be recovered by broker client-ID
lookup remain unresolved rather than being declared absent. Manual broker-side
resolution may be required.

## Operational limits and release status

Status is **implementation candidate**, not live-broker acceptance certification.
The tests exercise real local HTTPS login and HTTP/WebSocket broker transport against clearly labeled
synthetic broker-protocol servers and compute account changes dynamically. They
do not contact the production gateway, Alpaca or Kraken, use real credentials or trade real funds.

A one-second sampling target is not a hard real-time guarantee. API latency,
rate limits, venue outages, market closures, unsellable dust, unknown submissions,
process termination and operating-system scheduling can prevent timely sampling
or liquidation. Kraken risk samples use authenticated streamed balances plus a
fresh bid, not a fresh private REST balance request every second. A missed
sampling deadline, stale stream or transport failure latches halt and attempts
liquidation; it never reports confirmed flatness without a terminal reconciliation
and a subsequent zero-position/no-open-orders check. Independent broker-side
protection is still needed when the host is down.

All buys/sells are market orders. Order budgets and net liquidation equity are
conservative estimates, not guaranteed debit or fill-price caps. Alpaca order
responses do not supply comprehensive actual fee accounting here: `fee=null`
explicitly marks unknown actual fees, and acquisition cost uses a disclosed
configured reserve. Kraken terminal receipts include the authoritative reported
aggregate fee in quote currency. Unexpected cash/holdings movements outside
those known/estimated bounds halt the engine instead of inventing explanations.

The native SQLite schema remains distinct from the old 0.3.1 database. Use this
package's restored native dashboard/viewer, not the old plugin dashboard. The
old plugin is unchanged. `AUDIT_FINDINGS.md` identifies restored omissions and
remaining acceptance gaps, including actual Alpaca fees, venue-level individual
fill/fee completeness, external gateway deployment and broker-side protection.

## Reproduce local validation

```bash
python3 -m unittest discover -s tests -v
python3 -m compileall -q .
```

`TEST_RESULTS.txt`, `QA_REPORT.json`, `QA_GATE.json` and `SHA256SUMS` record the
executed checks, source identity and unresolved external acceptance checks.
The production release evidence gate remains blocked until live-broker and
host-environment acceptance are completed. This does not prevent review and
local execution of the complete candidate source.

## Primary protocol references checked 2026-10-28

* https://docs.alpaca.markets/us/docs/streaming-market-data
* https://docs.alpaca.markets/us/docs/websocket-streaming
* https://docs.alpaca.markets/us/reference/postorder
* https://docs.alpaca.markets/us/reference/getorderbyclientorderid
* https://docs.kraken.com/api/docs/websocket-v2/add_order/
* https://docs.kraken.com/api/docs/websocket-v2/balances/
* https://docs.kraken.com/api/docs/websocket-v2/executions/
* https://docs.kraken.com/api/docs/websocket-v2/ohlc/
* https://docs.kraken.com/api/docs/guides/spot-rest-auth/
* https://docs.kraken.com/api/docs/rest-api/get-websockets-token/
* https://docs.kraken.com/api/docs/rest-api/get-closed-orders/

Synthetic HTTPS authentication tests also require the `openssl` executable to generate an ephemeral localhost certificate. Test-only gate fixtures are confined to `tests/`; there is no runtime test-mode authentication switch.
