Phase 2: persistence + safety controls
Aggiunge la persistenza SQLite, l'audit log a hash chain, il kill switch coordinato e i CLI di gestione documentati in docs/05-data-model.md e docs/07-risk-controls.md. 197 test pass, 1 skipped (sqlite3 CLI mancante), copertura totale 97%. State (`state/`): - 0001_init.sql con positions, instructions, decisions, dvol_history, manual_actions, system_state. - db.py: connect con WAL + foreign_keys + transaction ctx, runner forward-only basato su PRAGMA user_version. - models.py: record Pydantic, Decimal preservato come TEXT. - repository.py: CRUD typed con singola connessione passata, cache aware, posizioni concorrenti. Safety (`safety/`): - audit_log.py: AuditLog append-only con SHA-256 chain e fsync, verify_chain riconosce ogni manomissione (payload, prev_hash, hash, JSON, separatori). - kill_switch.py: arm/disarm transazionali, idempotenti, accoppiati all'audit chain. Config (`config/loader.py` + `strategy.yaml`): - Loader YAML con deep-merge di strategy.local.yaml. - Verifica config_hash SHA-256 (riga config_hash esclusa). - File golden strategy.yaml + esempio override. Scripts: - dead_man.sh: watchdog shell indipendente da Python. - backup.py: VACUUM INTO orario con retention 30 giorni. CLI: - audit verify (exit 2 su tampering). - kill-switch arm/disarm/status su SQLite reale. - state inspect con tabella posizioni aperte. - config hash, config validate. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
-- 0001_init.sql — initial schema for Cerbero Bite (docs/05-data-model.md)
|
||||
--
|
||||
-- Forward-only. Run by state/migrations.py once user_version == 0.
|
||||
-- Bumps user_version to 1 at the end.
|
||||
|
||||
PRAGMA foreign_keys = ON;
|
||||
|
||||
CREATE TABLE positions (
|
||||
proposal_id TEXT PRIMARY KEY,
|
||||
spread_type TEXT NOT NULL,
|
||||
asset TEXT NOT NULL DEFAULT 'ETH',
|
||||
expiry TEXT NOT NULL,
|
||||
short_strike NUMERIC NOT NULL,
|
||||
long_strike NUMERIC NOT NULL,
|
||||
short_instrument TEXT NOT NULL,
|
||||
long_instrument TEXT NOT NULL,
|
||||
n_contracts INTEGER NOT NULL,
|
||||
spread_width_usd NUMERIC NOT NULL,
|
||||
spread_width_pct NUMERIC NOT NULL,
|
||||
credit_eth NUMERIC NOT NULL,
|
||||
credit_usd NUMERIC NOT NULL,
|
||||
max_loss_usd NUMERIC NOT NULL,
|
||||
spot_at_entry NUMERIC NOT NULL,
|
||||
dvol_at_entry NUMERIC NOT NULL,
|
||||
delta_at_entry NUMERIC NOT NULL,
|
||||
eth_price_at_entry NUMERIC NOT NULL,
|
||||
proposed_at TEXT NOT NULL,
|
||||
opened_at TEXT,
|
||||
closed_at TEXT,
|
||||
close_reason TEXT,
|
||||
debit_paid_eth NUMERIC,
|
||||
pnl_eth NUMERIC,
|
||||
pnl_usd NUMERIC,
|
||||
status TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_positions_status ON positions(status);
|
||||
CREATE INDEX idx_positions_closed_at ON positions(closed_at);
|
||||
|
||||
CREATE TABLE instructions (
|
||||
instruction_id TEXT PRIMARY KEY,
|
||||
proposal_id TEXT NOT NULL REFERENCES positions(proposal_id),
|
||||
kind TEXT NOT NULL,
|
||||
payload_json TEXT NOT NULL,
|
||||
sent_at TEXT NOT NULL,
|
||||
acknowledged_at TEXT,
|
||||
filled_at TEXT,
|
||||
cancelled_at TEXT,
|
||||
actual_fill_eth NUMERIC,
|
||||
actual_fees_eth NUMERIC
|
||||
);
|
||||
|
||||
CREATE INDEX idx_instructions_proposal ON instructions(proposal_id);
|
||||
|
||||
CREATE TABLE decisions (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
decision_type TEXT NOT NULL,
|
||||
proposal_id TEXT,
|
||||
timestamp TEXT NOT NULL,
|
||||
inputs_json TEXT NOT NULL,
|
||||
outputs_json TEXT NOT NULL,
|
||||
action_taken TEXT,
|
||||
notes TEXT
|
||||
);
|
||||
|
||||
CREATE INDEX idx_decisions_timestamp ON decisions(timestamp);
|
||||
CREATE INDEX idx_decisions_proposal ON decisions(proposal_id);
|
||||
|
||||
CREATE TABLE dvol_history (
|
||||
timestamp TEXT PRIMARY KEY,
|
||||
dvol NUMERIC NOT NULL,
|
||||
eth_spot NUMERIC NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE manual_actions (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
kind TEXT NOT NULL,
|
||||
proposal_id TEXT,
|
||||
payload_json TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
consumed_at TEXT,
|
||||
consumed_by TEXT,
|
||||
result TEXT
|
||||
);
|
||||
|
||||
CREATE INDEX idx_manual_actions_unconsumed ON manual_actions(consumed_at);
|
||||
|
||||
CREATE TABLE system_state (
|
||||
id INTEGER PRIMARY KEY CHECK (id = 1),
|
||||
kill_switch INTEGER NOT NULL DEFAULT 0,
|
||||
kill_reason TEXT,
|
||||
kill_at TEXT,
|
||||
last_health_check TEXT NOT NULL,
|
||||
last_kelly_calib TEXT,
|
||||
config_version TEXT NOT NULL,
|
||||
started_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
PRAGMA user_version = 1;
|
||||
@@ -0,0 +1 @@
|
||||
"""Forward-only SQL migrations for the Cerbero Bite state database."""
|
||||
Reference in New Issue
Block a user