@@ -4,6 +4,8 @@ OTTO watches your WhatsApp messages.
44When you make a commitment ("I'll send that Monday"), OTTO remembers.
55When you haven't followed through, OTTO asks — without judgment.
66
7+ ** "Manage the noise without falling into it."**
8+
79## Quick Start
810
911``` bash
@@ -23,29 +25,107 @@ otto done <id> Mark commitment as done
2325otto park <id> Park a commitment (guilt-free)
2426otto nudge Run follow-up check now
2527otto stats Counts and follow-through stats
28+ otto metrics Mode learning + plasticity visibility
2629otto watch Start WhatsApp webhook server
2730otto nuke Delete ALL data. Fresh start.
2831```
2932
30- ## How It Works
33+ ## Architecture
34+
35+ ### Core loop
36+
37+ ``` mermaid
38+ flowchart LR
39+ M[Message In<br/>WhatsApp]:::light --> D[Detect<br/>Opus 4.7]:::dark
40+ D --> S[Store<br/>SQLite WAL]:::light
41+ S --> SC[Schedule<br/>background thread]:::dark
42+ SC --> N[Nudge<br/>SHA256 template]:::light
43+ N --> CG{{Constitutional<br/>Gate}}:::dark
44+ CG -->|allow| O[Output<br/>CLI / WhatsApp]:::light
45+ CG -.->|suppress| Q[silence]:::light
46+
47+ classDef dark fill:#1e293b,stroke:#1e293b,color:#fde68a
48+ classDef light fill:#fde68a,stroke:#1e293b,color:#1e293b
49+ ```
50+
51+ The ** constitutional layer sits above all output.** Any nudge or action can be suppressed based on cognitive state — that is the product differentiator. OTTO can decide * not* to remind you.
52+
53+ ### Mode routing (NEXUS, 5-phase deterministic)
54+
55+ ``` mermaid
56+ flowchart TB
57+ SIG[PRISM Signals<br/>14 types, 9 pattern banks]:::dark --> R{{NEXUS Router<br/>ACTIVATE -> WEIGHT -> BOUND -> SELECT -> EXECUTE}}:::light
58+ R --> EX[Executor<br/>commitment tracking]:::dark
59+ R --> PR[Protector<br/>10% safety floor]:::dark
60+ R --> RS[Restorer<br/>5% floor — rest/explore]:::dark
61+ R --> DC[Decomposer<br/>5% floor — breakdown]:::dark
62+ EX --> OUT[Mode Output]:::light
63+ PR --> OUT
64+ RS --> OUT
65+ DC --> OUT
66+ OUT --> CGM{{Constitutional Gate}}:::dark
67+ CGM --> USR[User]:::light
68+ USR -.->|outcome trail| LRN[UCB1 Learner<br/>+ plasticity]:::dark
69+ LRN -.->|adjust weights| R
70+
71+ classDef dark fill:#1e293b,stroke:#1e293b,color:#fde68a
72+ classDef light fill:#fde68a,stroke:#1e293b,color:#1e293b
73+ ```
3174
75+ Same signals + same state = same routing. No randomness in control flow. UCB1 learning is contextual but ** deterministic given the trail history** — application-level determinism per Patent P1.
76+
77+ ### LLM integration (Tier 1 — Opus 4.7 upgrade)
78+
79+ ``` mermaid
80+ flowchart LR
81+ CFG[src/otto/model_config.py<br/>env-overridable<br/>TEMPERATURE = 0.0]:::dark
82+
83+ CFG --> OP[Opus 4.7<br/>DETECTOR_MODEL]:::light
84+ CFG --> SN[Sonnet 4.6<br/>AGENT_MODEL]:::light
85+ CFG --> HK[Haiku 4.5<br/>RESPONSE_GEN_MODEL]:::light
86+
87+ OP --> DET[detector.py<br/>commitment extraction<br/>prompt-cached system]:::dark
88+ SN --> AG[otto_agent loop<br/>tool-use orchestration<br/>prompt-cached system + tools]:::dark
89+ HK --> RG[response_gen.py<br/>optional rephrase<br/>gated by OTTO_LLM_RESPONSES]:::dark
90+
91+ classDef dark fill:#1e293b,stroke:#1e293b,color:#fde68a
92+ classDef light fill:#fde68a,stroke:#1e293b,color:#1e293b
3293```
33- MESSAGE IN --> DETECT --> STORE --> WAIT --> FOLLOW UP --> UPDATE
34- (WhatsApp) (Claude) (SQLite) (cron) (template) (count++)
94+
95+ Every model surface is one env var away from rollback:
96+
97+ ``` powershell
98+ $env:OTTO_DETECTOR_MODEL = "claude-sonnet-4-5-20250929" # rollback example
3599```
36100
37- - ** Input:** WhatsApp Cloud API webhooks via FastAPI
38- - ** Detection:** Claude Sonnet extracts commitments from messages
39- - ** Storage:** SQLite (` ~/.otto/commitments.db ` ), no ORM
40- - ** Follow-up:** Template-based nudges, zero LLM cost, 24h cooldown
41- - ** Interface:** Click CLI
101+ ## How It Works
102+
103+ - ** Input:** WhatsApp Cloud API webhooks via FastAPI (` watcher.py ` )
104+ - ** Detection:** Claude Opus 4.7 extracts commitments — nuance on "I'll try" vs "I will" drives confidence and nudge timing
105+ - ** Storage:** SQLite WAL (` ~/.otto/commitments.db ` ), shared connection pool (` db.py ` ), Fernet-encrypted sensitive fields (` crypto.py ` )
106+ - ** Follow-up:** Deterministic SHA256 template selection, 24h cooldown, zero LLM cost on the hot path
107+ - ** Routing:** PRISM signals (regex banks) -> NEXUS 5-phase router -> 4 modes -> Constitutional Gate
108+ - ** Learning:** UCB1 mode-weight learning with plasticity amplification during crisis (` learner.py ` )
109+ - ** Agent:** Same logic, different surface — tool-use loop with 10 MCP tools, pre-tool-use constitutional hooks
110+ - ** Interface:** Click CLI + optional WhatsApp Cloud API outbound
111+
112+ ## Constitutional Principles (Immutable)
113+
114+ 1 . ** Safety First** — Protector has a 10% floor and can suppress any output
115+ 2 . ** Don't Become Noise** — backs off when nudges aren't leading to completions
116+ 3 . ** User Knows Best** — "Park it" is a first-class action, not failure
117+ 4 . ** Rest Is Productive** — can grant permission to stop
118+ 5 . ** One At A Time** — when overwhelmed, reduce to ONE choice
119+ 6 . ** Dignity Always** — no clinical labels, no "ADHD mode"
120+ 7 . ** Privacy Is Sovereignty** — all data local, no cloud sync
42121
43122## Tests
44123
45124``` bash
46125cd otto_v4
47- python -m pytest tests/ -v -m " not integration" # 92 tests
48- python -m pytest tests/ -v # includes real API tests
126+ python -m pytest tests/ -v -m " not integration" # 589 core tests
127+ python -m pytest otto_agent/tests/ -v # 56 agent tests
128+ python -m pytest tests/ otto_agent/tests/ -v # 645 total (needs ANTHROPIC_API_KEY for integration)
49129```
50130
51131## License
0 commit comments