DOX sistem
This commit is contained in:
106
AGENTS.md
106
AGENTS.md
@@ -1,90 +1,54 @@
|
||||
# ATM — Automated Trading Monitor
|
||||
|
||||
Personal Faza-1 tool for the M2D strategy. Python 3.11+.
|
||||
Personal Faza-1 tool pentru strategia M2D. Python 3.11+.
|
||||
|
||||
> Acest repo folosește **DOX**: arborele de `AGENTS.md` de mai jos sunt contracte
|
||||
> de lucru pentru subarborii lor. Înainte să editezi un path, coboară din rădăcină
|
||||
> citind fiecare `AGENTS.md` întâlnit. După o schimbare semnificativă, fă un **DOX
|
||||
> pass**: actualizează `AGENTS.md`-ul cel mai apropiat care „deține" zona + indexul
|
||||
> părintelui, șterge ce devine învechit.
|
||||
|
||||
## Quick Reference
|
||||
|
||||
```bash
|
||||
pip install -e ".[windows]" # Windows: live capture
|
||||
pip install -e ".[dev]" # Linux/macOS: dev + tests (WSL: create venv first)
|
||||
pip install -e ".[dev]" # Linux/macOS: dev + tests (WSL: venv întâi)
|
||||
cp .env.example .env # secretele Discord/Telegram (vezi README §Secrets)
|
||||
atm calibrate # Tk wizard
|
||||
atm debug --delay 5 # one-shot capture + detect
|
||||
atm validate-calibration calibration/calibration_labels.json # offline color gate
|
||||
atm validate-calibration calibration/calibration_labels.json # color gate offline
|
||||
atm run --start-at 16:30 --stop-at 23:00 # live session
|
||||
atm run --tz America/New_York --oh-start 09:30 --oh-stop 16:00 # NYSE window override
|
||||
pytest -q # 230+ tests (core + 8 scenarii regresie + env loader)
|
||||
pytest tests/test_scenarios_regression.py -v # FSM pe imagini reale
|
||||
atm run --tz America/New_York --oh-start 09:30 --oh-stop 16:00 # NYSE window
|
||||
pytest -q # 230+ teste
|
||||
```
|
||||
|
||||
## Codex sandbox/tooling notes
|
||||
## DOX Protocol
|
||||
|
||||
On this Windows checkout, do not assume `rg` or the global `python` has project deps.
|
||||
Use the repo venv for diagnostics that need Pillow/OpenCV:
|
||||
- **Citire** — traversează root → path-ul țintă, citind fiecare `AGENTS.md`. Dacă
|
||||
un părinte indexează un copil al cărui scope conține path-ul, citește copilul și
|
||||
continuă de acolo.
|
||||
- **Editare** — `AGENTS.md`-ul cel mai apropiat = contract local; părinții = reguli
|
||||
globale. Un copil nu poate slăbi o constrângere impusă de un părinte.
|
||||
- **Update (closeout)** — re-verifică path-urile schimbate față de lanțul DOX;
|
||||
actualizează doc-urile care le dețin + indexurile afectate; șterge textul învechit;
|
||||
rulează verificarea relevantă.
|
||||
|
||||
```powershell
|
||||
.\.venv\Scripts\python.exe scripts\inspect_image_pixels.py 6033117943853423831.jpg
|
||||
.\.venv\Scripts\python.exe scripts\inspect_image_pixels.py 6033117943853423831.jpg --point 1780 725
|
||||
```
|
||||
## Durable Rules (repo-wide)
|
||||
|
||||
If `rg` is missing, use PowerShell fallbacks:
|
||||
`Get-ChildItem -Recurse -File src,tests,scripts | Select-String -Pattern "needle"`.
|
||||
If a command fails due to sandbox permissions and is required for the task, rerun it
|
||||
with an escalation request instead of stopping the investigation without a verdict.
|
||||
- **Pure-logic fără cv2/numpy** în `state_machine.py` și `config.py` (testele rulează
|
||||
headless). cv2/I/O greu mereu în `asyncio.to_thread`.
|
||||
- **Secretele doar din env** (`.env`), niciodată în TOML sau cod.
|
||||
- **Mereu** `atm validate-calibration` după recalibrare (palette gotcha — vezi
|
||||
`calibration/AGENTS.md`).
|
||||
- Modul nou în `src/atm/` ⇒ `test_<modul>.py` corespondent.
|
||||
|
||||
## Calibration corpus
|
||||
> Skill routing (Claude Code) trăiește în [`CLAUDE.md`](CLAUDE.md) — sursa canonică.
|
||||
|
||||
`calibration/` — persistent, auto-suficient. Conține:
|
||||
- `frames/` — PNG-uri raw `{ts}_{color}.png` scrise **automat** de live loop la fiecare schimbare de culoare (filename = culoarea detectată, poate fi greșită)
|
||||
- `calibration_labels.json` — ground truth **manual** (gate offline pentru `atm validate-calibration`)
|
||||
- `scenarios.json` — secvențe FSM pentru `tests/test_scenarios_regression.py`
|
||||
## Child DOX Index
|
||||
|
||||
Workflow după sesiune: review frame-urile noi din `frames/`, adaugi entry-uri în `calibration_labels.json` cu culoarea pe care ai văzut-o TU pe chart (nu neapărat cea din filename), rulezi `atm validate-calibration`.
|
||||
|
||||
## Telegram commands (live)
|
||||
|
||||
`/ss` `/status` `/pause` `/resume` `/rebase` `/3` (interval min) `/stop`
|
||||
|
||||
- `/rebase` — propune un `baseline_phash` nou pentru canary: capturează frame, crop pe `canary.roi`, phash → trimite screenshot adnotat (cerc roșu pe ROI) cu old/new hash + distance. `/rebase confirm` în ≤180s aplică: rescrie `baseline_phash` în TOML-ul activ (păstrează comentariile), mirror în `cfg` la runtime, clear `user_paused` + `drift_paused`. Fără confirm, nimic nu se modifică. Folosește-l când layout-ul TS s-a schimbat intenționat și vrei să re-ancorezi canary-ul fără `atm calibrate` full.
|
||||
|
||||
- `/ss` — verify multi-bulină: adnotează top-3 buline din `dot_roi` (cerc roșu gros pe pick-ul FSM, cercuri colorate subțiri pe vecini) + caption cu clasificarea fiecăreia (nume, RGB, distanță, confidence) + `config: {version}`. Cercul colorat folosește `cfg.colors[name].rgb` la runtime — DRY cu paleta activă.
|
||||
- `/resume` clears BOTH user pause and canary drift-pause in one shot (`/resume force` still accepted as legacy alias). Trimite un singur Alert cu screenshot adnotat inline (capture rulează **înainte** de clearing state → zero race cu FSM tick-uri). Dacă capture eșuează, title conține `⚠️ captură eșuată` și resume-ul se execută oricum.
|
||||
- Drift-pause emits a single Telegram alert on transition. While paused, `/set_interval` is refused and `/ss` captions warn that detection is off.
|
||||
- Heartbeat shows `⚠️ pauzat (drift)` instead of `activ` while canary is paused.
|
||||
|
||||
## Operating-hours config
|
||||
|
||||
`[options.operating_hours]` in TOML: `enabled`, `timezone` (NYSE local, e.g. `America/New_York`), `weekdays`, `start_hhmm`, `stop_hhmm`. Timezone validated at load; `_tz_cache` reused per tick. Boundary crossings log `market_open` / `market_closed` and notify once. Startup in-window is silent.
|
||||
|
||||
## Phase-skip backstop
|
||||
|
||||
`[options.alerts] fire_on_phase_skip = true` (default) — ARMED→light_* direct (dark_* missed) still emits a `⚠️ PHASE SKIP` alert using FSM lockout to suppress spam.
|
||||
|
||||
## Palette gotcha (2026-04-21 recalibration)
|
||||
|
||||
TradeStation M2D indicators paint the four bright colors at near-pure saturation:
|
||||
turquoise `(0,253,253)`, yellow `(253,253,0)`, light_green `(0,255,0)`, light_red `(255,0,0)`.
|
||||
If Tk-wizard calibration samples a slightly desaturated pixel, classifier returns `UNKNOWN`
|
||||
(distance > tolerance=60) → FSM never sees trigger → stuck in PRIMED → scheduler polls
|
||||
forever. Always run `atm validate-calibration calibration/calibration_labels.json` after
|
||||
recalibrating. Current active config: `configs/2026-04-21-recalib.toml`.
|
||||
|
||||
## Skill routing
|
||||
|
||||
When the user's request matches an available skill, ALWAYS invoke it using the Skill
|
||||
tool as your FIRST action. Do NOT answer directly, do NOT use other tools first.
|
||||
The skill has specialized workflows that produce better results than ad-hoc answers.
|
||||
|
||||
Key routing rules:
|
||||
- Product ideas, "is this worth building", brainstorming → invoke office-hours
|
||||
- Bugs, errors, "why is this broken", 500 errors → invoke investigate
|
||||
- Ship, deploy, push, create PR → invoke ship
|
||||
- QA, test the site, find bugs → invoke qa
|
||||
- Code review, check my diff → invoke review
|
||||
- Update docs after shipping → invoke document-release
|
||||
- Weekly retro → invoke retro
|
||||
- Design system, brand → invoke design-consultation
|
||||
- Visual audit, design polish → invoke design-review
|
||||
- Architecture review → invoke plan-eng-review
|
||||
- Save progress, checkpoint, resume → invoke checkpoint
|
||||
- Code quality, health check → invoke health
|
||||
- **`src/atm/`** → `src/atm/AGENTS.md` — motorul: capture/detect/FSM/scheduler/
|
||||
vision/canary/config. (copil: `notifier/`)
|
||||
- **`tests/`** → `tests/AGENTS.md` — suita de teste + regresie FSM.
|
||||
- **`calibration/`** → `calibration/AGENTS.md` — corpus culori + scenarii + palette gotcha.
|
||||
- **`configs/`** → `configs/AGENTS.md` — schema TOML (operating_hours, alerts, canary).
|
||||
- **`scripts/`** → `scripts/AGENTS.md` — diagnostic + note sandbox Windows/venv.
|
||||
|
||||
91
CLAUDE.md
91
CLAUDE.md
@@ -1,75 +1,32 @@
|
||||
# ATM — Automated Trading Monitor
|
||||
# ATM — Automated Trading Monitor (Claude Code)
|
||||
|
||||
Personal Faza-1 tool for the M2D strategy. Python 3.11+.
|
||||
Personal Faza-1 tool pentru strategia M2D. Python 3.11+.
|
||||
|
||||
## Quick Reference
|
||||
## Sursa de adevăr: arborele DOX
|
||||
|
||||
```bash
|
||||
pip install -e ".[windows]" # Windows: live capture
|
||||
pip install -e ".[dev]" # Linux/macOS: dev + tests (WSL: create venv first)
|
||||
cp .env.example .env # secretele Discord/Telegram (vezi README §Secrets)
|
||||
atm calibrate # Tk wizard
|
||||
atm debug --delay 5 # one-shot capture + detect
|
||||
atm validate-calibration calibration/calibration_labels.json # offline color gate
|
||||
atm run --start-at 16:30 --stop-at 23:00 # live session
|
||||
atm run --tz America/New_York --oh-start 09:30 --oh-stop 16:00 # NYSE window override
|
||||
pytest -q # 230+ tests (core + 8 scenarii regresie + env loader)
|
||||
pytest tests/test_scenarios_regression.py -v # FSM pe imagini reale
|
||||
```
|
||||
Documentația operațională trăiește în arborele de `AGENTS.md` (format DOX), **nu**
|
||||
aici. Înainte să editezi un path, coboară din rădăcină citind fiecare `AGENTS.md`
|
||||
întâlnit; după o schimbare semnificativă, fă un DOX pass (actualizează doc-ul care
|
||||
deține zona + indexul părintelui).
|
||||
|
||||
## Calibration corpus
|
||||
|
||||
`calibration/` — persistent, auto-suficient. Conține:
|
||||
- `frames/` — PNG-uri raw `{ts}_{color}.png` scrise **automat** de live loop la fiecare schimbare de culoare (filename = culoarea detectată, poate fi greșită)
|
||||
- `calibration_labels.json` — ground truth **manual** (gate offline pentru `atm validate-calibration`)
|
||||
- `scenarios.json` — secvențe FSM pentru `tests/test_scenarios_regression.py`
|
||||
|
||||
Workflow după sesiune: review frame-urile noi din `frames/`, adaugi entry-uri în `calibration_labels.json` cu culoarea pe care ai văzut-o TU pe chart (nu neapărat cea din filename), rulezi `atm validate-calibration`.
|
||||
|
||||
## Telegram commands (live)
|
||||
|
||||
`/ss` `/status` `/pause` `/resume` `/rebase` `/3` (interval min) `/stop`
|
||||
|
||||
- `/rebase` — propune un `baseline_phash` nou pentru canary: capturează frame, crop pe `canary.roi`, phash → trimite screenshot adnotat (cerc roșu pe ROI) cu old/new hash + distance. `/rebase confirm` în ≤180s aplică: rescrie `baseline_phash` în TOML-ul activ (păstrează comentariile), mirror în `cfg` la runtime, clear `user_paused` + `drift_paused`. Fără confirm, nimic nu se modifică. Folosește-l când layout-ul TS s-a schimbat intenționat și vrei să re-ancorezi canary-ul fără `atm calibrate` full.
|
||||
|
||||
- `/ss` — verify multi-bulină: adnotează top-3 buline din `dot_roi` (cerc roșu gros pe pick-ul FSM, cercuri colorate subțiri pe vecini) + caption cu clasificarea fiecăreia (nume, RGB, distanță, confidence) + `config: {version}`. Cercul colorat folosește `cfg.colors[name].rgb` la runtime — DRY cu paleta activă.
|
||||
- `/resume` clears BOTH user pause and canary drift-pause in one shot (`/resume force` still accepted as legacy alias). Trimite un singur Alert cu screenshot adnotat inline (capture rulează **înainte** de clearing state → zero race cu FSM tick-uri). Dacă capture eșuează, title conține `⚠️ captură eșuată` și resume-ul se execută oricum.
|
||||
- Drift-pause emits a single Telegram alert on transition. While paused, `/set_interval` is refused and `/ss` captions warn that detection is off.
|
||||
- Heartbeat shows `⚠️ pauzat (drift)` instead of `activ` while canary is paused.
|
||||
|
||||
## Operating-hours config
|
||||
|
||||
`[options.operating_hours]` in TOML: `enabled`, `timezone` (NYSE local, e.g. `America/New_York`), `weekdays`, `start_hhmm`, `stop_hhmm`. Timezone validated at load; `_tz_cache` reused per tick. Boundary crossings log `market_open` / `market_closed` and notify once. Startup in-window is silent.
|
||||
|
||||
## Phase-skip backstop
|
||||
|
||||
`[options.alerts] fire_on_phase_skip = true` (default) — ARMED→light_* direct (dark_* missed) still emits a `⚠️ PHASE SKIP` alert using FSM lockout to suppress spam.
|
||||
|
||||
## Palette gotcha (2026-04-21 recalibration)
|
||||
|
||||
TradeStation M2D indicators paint the four bright colors at near-pure saturation:
|
||||
turquoise `(0,253,253)`, yellow `(253,253,0)`, light_green `(0,255,0)`, light_red `(255,0,0)`.
|
||||
If Tk-wizard calibration samples a slightly desaturated pixel, classifier returns `UNKNOWN`
|
||||
(distance > tolerance=60) → FSM never sees trigger → stuck in PRIMED → scheduler polls
|
||||
forever. Always run `atm validate-calibration calibration/calibration_labels.json` after
|
||||
recalibrating. Current active config: `configs/2026-04-21-recalib.toml`.
|
||||
Start: [`AGENTS.md`](AGENTS.md) (root — Quick Reference, reguli globale, index copii).
|
||||
Copii: `src/atm/` · `src/atm/notifier/` · `tests/` · `calibration/` · `configs/` · `scripts/`.
|
||||
|
||||
## Skill routing
|
||||
|
||||
When the user's request matches an available skill, ALWAYS invoke it using the Skill
|
||||
tool as your FIRST action. Do NOT answer directly, do NOT use other tools first.
|
||||
The skill has specialized workflows that produce better results than ad-hoc answers.
|
||||
Când cererea userului se potrivește cu un skill disponibil, invocă-l cu tool-ul
|
||||
Skill ca PRIMĂ acțiune. NU răspunde direct, NU folosi alte tool-uri întâi.
|
||||
Skill-ul are workflow-uri specializate care produc rezultate mai bune.
|
||||
|
||||
Key routing rules:
|
||||
- Product ideas, "is this worth building", brainstorming → invoke office-hours
|
||||
- Bugs, errors, "why is this broken", 500 errors → invoke investigate
|
||||
- Ship, deploy, push, create PR → invoke ship
|
||||
- QA, test the site, find bugs → invoke qa
|
||||
- Code review, check my diff → invoke review
|
||||
- Update docs after shipping → invoke document-release
|
||||
- Weekly retro → invoke retro
|
||||
- Design system, brand → invoke design-consultation
|
||||
- Visual audit, design polish → invoke design-review
|
||||
- Architecture review → invoke plan-eng-review
|
||||
- Save progress, checkpoint, resume → invoke checkpoint
|
||||
- Code quality, health check → invoke health
|
||||
- Idei de produs, „merită construit", brainstorming → `office-hours`
|
||||
- Bug-uri, erori, „de ce e stricat", 500 → `investigate`
|
||||
- Ship, deploy, push, PR → `ship`
|
||||
- QA, testează site-ul, găsește bug-uri → `qa`
|
||||
- Code review, verifică diff-ul → `review`
|
||||
- Update docs după ship → `document-release`
|
||||
- Retro săptămânal → `retro`
|
||||
- Design system, brand → `design-consultation`
|
||||
- Audit vizual, design polish → `design-review`
|
||||
- Architecture review → `plan-eng-review`
|
||||
- Save progress, checkpoint, resume → `checkpoint`
|
||||
- Code quality, health check → `health`
|
||||
|
||||
45
calibration/AGENTS.md
Normal file
45
calibration/AGENTS.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# calibration — Calibration Corpus
|
||||
|
||||
## Purpose
|
||||
|
||||
Corpus persistent, auto-suficient pentru clasificarea culorilor și regresia FSM.
|
||||
Sursa de adevăr pentru ce „vede" detectorul.
|
||||
|
||||
## Ownership
|
||||
|
||||
`frames/`, `calibration_labels.json`, `scenarios.json`.
|
||||
|
||||
## Local Contracts
|
||||
|
||||
- **`frames/`** — PNG raw `{ts}_{color}.png` scrise **automat** de live loop la
|
||||
fiecare schimbare de culoare. Filename = culoarea detectată, **poate fi greșită**.
|
||||
Nu trata filename-ul ca ground truth.
|
||||
- **`calibration_labels.json`** — ground truth **manual**. Gate offline pentru
|
||||
`atm validate-calibration`. Pui culoarea pe care ai văzut-o TU pe chart, nu cea
|
||||
din filename.
|
||||
- **`scenarios.json`** — secvențe FSM pentru `tests/test_scenarios_regression.py`.
|
||||
|
||||
## Work Guidance
|
||||
|
||||
**Workflow după sesiune:** review frame-urile noi din `frames/` → adaugi entry-uri
|
||||
în `calibration_labels.json` cu culoarea reală → rulezi validate-calibration.
|
||||
|
||||
### Palette gotcha (recalibrare 2026-04-21)
|
||||
|
||||
Indicatorii M2D pictează cele patru culori bright la saturație near-pure:
|
||||
turquoise `(0,253,253)`, yellow `(253,253,0)`, light_green `(0,255,0)`,
|
||||
light_red `(255,0,0)`. Dacă Tk-wizard eșantionează un pixel ușor desaturat,
|
||||
clasificatorul întoarce `UNKNOWN` (distanță > tolerance=60) → FSM nu vede trigger
|
||||
→ stuck în PRIMED → scheduler polls la infinit. **Mereu** rulează
|
||||
validate-calibration după recalibrare. Config activ: vezi `configs/current.txt`.
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
atm validate-calibration calibration/calibration_labels.json # color gate offline
|
||||
pytest tests/test_scenarios_regression.py -v
|
||||
```
|
||||
|
||||
## Child DOX Index
|
||||
|
||||
(none — leaf)
|
||||
53
configs/AGENTS.md
Normal file
53
configs/AGENTS.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# configs — TOML Configs
|
||||
|
||||
## Purpose
|
||||
|
||||
Configurațiile de rulare (ROI-uri, paletă, canary baseline, operating-hours,
|
||||
alerts). Schema e definită și validată în `src/atm/config.py` (fail fast la load).
|
||||
|
||||
## Ownership
|
||||
|
||||
`*.toml` + `current.txt` (pointer la config-ul activ) + `example.toml` (template).
|
||||
|
||||
## Local Contracts
|
||||
|
||||
- **`current.txt`** — o singură linie: numele fișierului TOML activ. `atm run`
|
||||
fără `--config` îl folosește pe acesta.
|
||||
- Secretele **NU** stau în TOML — vin din env (`.env`). Vezi `notifier/AGENTS.md`.
|
||||
- Schema (dataclass-uri în `config.py`): `dot_roi`, `colors{name→{rgb,tolerance}}`,
|
||||
`canary{roi, baseline_phash}`, y-axis calib, `[options.operating_hours]`,
|
||||
`[options.alerts]`. Modifici schema în `config.py` ⇒ actualizezi `example.toml`
|
||||
+ acest doc în același commit.
|
||||
|
||||
### `[options.operating_hours]`
|
||||
|
||||
`enabled`, `timezone` (NYSE local, ex. `America/New_York`), `weekdays`,
|
||||
`start_hhmm`, `stop_hhmm`. Timezone validat la load; `_tz_cache` reutilizat per
|
||||
tick. Boundary crossings logează `market_open`/`market_closed` și notifică o dată.
|
||||
Startup in-window e silent.
|
||||
|
||||
### `[options.alerts]`
|
||||
|
||||
`fire_on_phase_skip = true` (default) — tranziția ARMED→light_* directă (dark_*
|
||||
ratat) emite totuși un `⚠️ PHASE SKIP`, cu FSM lockout ca să suprime spam-ul.
|
||||
|
||||
### `canary.baseline_phash`
|
||||
|
||||
Re-anchor prin comanda `/rebase confirm` (rescrie automat aici, păstrând
|
||||
comentariile). Nu edita manual decât dacă știi exact ce faci.
|
||||
|
||||
## Work Guidance
|
||||
|
||||
- Config nou = copiezi `example.toml`, numești `{data}-{tag}.toml`, pui numele în
|
||||
`current.txt`. Nu șterge config-urile vechi (audit trail al recalibrărilor).
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
atm validate-calibration calibration/calibration_labels.json
|
||||
atm debug --delay 5 # confirmă că config-ul activ încarcă & detectează
|
||||
```
|
||||
|
||||
## Child DOX Index
|
||||
|
||||
(none — leaf)
|
||||
42
scripts/AGENTS.md
Normal file
42
scripts/AGENTS.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# scripts — Diagnostic Scripts
|
||||
|
||||
## Purpose
|
||||
|
||||
Scripturi ad-hoc de diagnostic/repro rulate manual. Nu fac parte din suita de
|
||||
teste și nu sunt importate de aplicație.
|
||||
|
||||
## Ownership
|
||||
|
||||
`diag_strip_detection.py`, `diag_strip_fixes.py`, `inspect_image_pixels.py`,
|
||||
`repro_ss_resume.py`.
|
||||
|
||||
## Local Contracts
|
||||
|
||||
- **`inspect_image_pixels.py`** — citește RGB la coordonate dintr-o imagine.
|
||||
Util pentru a verifica saturația pixelilor (vezi palette gotcha în
|
||||
`calibration/AGENTS.md`).
|
||||
- **`repro_ss_resume.py`** — repro pentru fluxul `/ss` + `/resume`.
|
||||
|
||||
## Work Guidance — Sandbox/tooling (Windows checkout)
|
||||
|
||||
Nu presupune că `rg` sau `python`-ul global au dependențele proiectului.
|
||||
Pentru diagnostic care cere Pillow/OpenCV folosește venv-ul repo:
|
||||
|
||||
```powershell
|
||||
.\.venv\Scripts\python.exe scripts\inspect_image_pixels.py 6033117943853423831.jpg
|
||||
.\.venv\Scripts\python.exe scripts\inspect_image_pixels.py 6033117943853423831.jpg --point 1780 725
|
||||
```
|
||||
|
||||
Dacă `rg` lipsește, fallback PowerShell:
|
||||
`Get-ChildItem -Recurse -File src,tests,scripts | Select-String -Pattern "needle"`.
|
||||
Dacă o comandă pică din permisiuni sandbox și e necesară, rerulează cu escalare
|
||||
în loc să oprești investigația fără verdict.
|
||||
|
||||
## Verification
|
||||
|
||||
Rulează scriptul vizat manual și inspectează output-ul; nu există teste automate
|
||||
pentru `scripts/`.
|
||||
|
||||
## Child DOX Index
|
||||
|
||||
(none — leaf)
|
||||
55
src/atm/AGENTS.md
Normal file
55
src/atm/AGENTS.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# src/atm — Core Engine
|
||||
|
||||
## Purpose
|
||||
|
||||
Capture → detect → decide → notify. The motor M2D: ia frame-uri de pe chart-ul
|
||||
TradeStation, clasifică bulina/strip-ul de culoare, rulează FSM-ul de trading și
|
||||
emite alerte. Pure-logic modules (FSM, config) nu importă cv2/numpy; vision &
|
||||
capture stau izolate.
|
||||
|
||||
## Ownership
|
||||
|
||||
Tot codul Python al aplicației sub `src/atm/`, cu excepția `notifier/` (vezi
|
||||
child index). CLI-ul (`main.py`) orchestrează modulele; e sursa de adevăr pentru
|
||||
flag-urile `atm run/debug/calibrate`.
|
||||
|
||||
## Local Contracts
|
||||
|
||||
- **`state_machine.py`** — FSM pur stdlib, **fără cv2/numpy**. Stările M2D
|
||||
(PRIMED → ARMED → light_*). Orice schimbare aici cere test în
|
||||
`tests/test_state_machine.py` + scenariu în `calibration/scenarios.json`.
|
||||
- **`config.py`** — dataclass-uri frozen, validare la load (fail fast). Schema
|
||||
TOML e definită aici; modific schema ⇒ actualizez `configs/AGENTS.md`.
|
||||
- **`detector.py`** — debounce + rolling window peste clasificarea per-ciclu.
|
||||
- **`scheduler.py`** — asyncio task; capture + cv2 rulează în `to_thread`
|
||||
(nu bloca event-loop-ul). Decizia 13: scheduler cheamă `capture()` direct,
|
||||
NU prin `Detector`.
|
||||
- **`vision.py`** — primitive partajate: crop ROI, perceptual hash, interpolare
|
||||
pixel↔preț, Hough. Singurul loc unde trăiesc primitivele cv2 reutilizabile.
|
||||
- **`canary.py`** — drift de layout via phash vs `baseline_phash`. Re-anchor prin
|
||||
`/rebase` (vezi `notifier/AGENTS.md`), nu hardcoda hash-uri aici.
|
||||
- **`calibrate.py`** / **`labeler.py`** — Tk wizard; safe la import headless
|
||||
(Tk se importă lazy). Vezi gotcha de saturație în `calibration/AGENTS.md`.
|
||||
- **`levels.py`** — Phase-B: detectează linii SL (roșu) / TP (verde).
|
||||
- **`journal.py`** / **`report.py`** — store JSONL append-only + raport săptămânal.
|
||||
|
||||
## Work Guidance
|
||||
|
||||
- Nu introduce import cv2/numpy în `state_machine.py` sau `config.py` — testele
|
||||
rulează headless pe Linux/WSL și pică altfel.
|
||||
- Heavy I/O & cv2 mereu în `asyncio.to_thread` din scheduler/main.
|
||||
- Culorile vivid sunt near-pure saturation (vezi gotcha). Clasificatorul întoarce
|
||||
`UNKNOWN` peste `tolerance` — nu crește tolerance fără validate-calibration.
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
pytest -q # toată suita
|
||||
pytest tests/test_state_machine.py -v # FSM
|
||||
atm debug --delay 5 # one-shot capture + detect live
|
||||
```
|
||||
|
||||
## Child DOX Index
|
||||
|
||||
- **`notifier/`** → `src/atm/notifier/AGENTS.md` — Discord/Telegram/fanout +
|
||||
comenzile live (`/ss`, `/rebase`, `/resume`, …).
|
||||
55
src/atm/notifier/AGENTS.md
Normal file
55
src/atm/notifier/AGENTS.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# src/atm/notifier — Alerting & Live Commands
|
||||
|
||||
## Purpose
|
||||
|
||||
Tot ce iese din proces către exterior: alerte Discord/Telegram + poller-ul de
|
||||
comenzi live Telegram. Fan-out trimite același eveniment pe mai multe canale.
|
||||
|
||||
## Ownership
|
||||
|
||||
`discord.py`, `telegram.py`, `fanout.py` și poller-ul de comenzi
|
||||
(`../commands.py` definește dataclass-ul `Command` + long-poll `getUpdates`).
|
||||
|
||||
## Local Contracts
|
||||
|
||||
- **Secretele** vin DOAR din env (`ATM_DISCORD_URL`, `ATM_TG_TOKEN`,
|
||||
`ATM_TG_CHAT`), încărcate din `.env` de `config.py`. Nu hardcoda token-uri.
|
||||
- **`commands.py`** e singurul consumator de **httpx** (async long-poll).
|
||||
`TelegramNotifier` (sync) rămâne pe **requests**. Nu amesteca cele două.
|
||||
- **Comenzi live:** `/ss` `/status` `/pause` `/resume` `/rebase` `/3` (interval
|
||||
min) `/stop`.
|
||||
|
||||
### Contracte pe comenzi (nu le slăbi fără update aici)
|
||||
|
||||
- **`/rebase`** — propune `baseline_phash` nou: capture → crop pe `canary.roi`
|
||||
→ phash → screenshot adnotat (cerc roșu pe ROI) cu old/new hash + distance.
|
||||
`/rebase confirm` în ≤180s rescrie `baseline_phash` în TOML-ul activ (păstrează
|
||||
comentariile), mirror în `cfg` la runtime, clear `user_paused` + `drift_paused`.
|
||||
Fără confirm, nimic nu se schimbă.
|
||||
- **`/ss`** — top-3 buline din `dot_roi`: cerc roșu gros pe pick-ul FSM, cercuri
|
||||
colorate subțiri pe vecini; caption cu nume/RGB/distanță/confidence +
|
||||
`config: {version}`. Culoarea cercului = `cfg.colors[name].rgb` (DRY cu paleta).
|
||||
- **`/resume`** — clear ȘI user-pause ȘI drift-pause într-un shot (`/resume force`
|
||||
= alias legacy). Capture rulează **înainte** de clear (zero race cu FSM tick).
|
||||
Dacă capture pică, title conține `⚠️ captură eșuată` și resume se execută oricum.
|
||||
- **Drift-pause** — un singur alert Telegram pe tranziție. Cât e pauzat,
|
||||
`/set_interval` e refuzat, caption-ul `/ss` avertizează că detecția e oprită,
|
||||
heartbeat arată `⚠️ pauzat (drift)` în loc de `activ`.
|
||||
|
||||
## Work Guidance
|
||||
|
||||
- Orice mesaj nou de alertă → trece prin `fanout.py`, nu chema notifier-ele direct
|
||||
din `main.py`.
|
||||
- Schimbi semantica unei comenzi → actualizează contractul de mai sus în ACELAȘI
|
||||
commit (DOX pass).
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
pytest tests/test_notifier.py tests/test_commands.py -v
|
||||
.\.venv\Scripts\python.exe scripts\repro_ss_resume.py # repro /ss + /resume
|
||||
```
|
||||
|
||||
## Child DOX Index
|
||||
|
||||
(none — leaf)
|
||||
37
tests/AGENTS.md
Normal file
37
tests/AGENTS.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# tests — Test Suite
|
||||
|
||||
## Purpose
|
||||
|
||||
230+ teste: unit pe fiecare modul + 8 scenarii de regresie FSM pe imagini reale +
|
||||
env loader. Rulează headless pe Linux/WSL (de aceea FSM & config nu importă cv2).
|
||||
|
||||
## Ownership
|
||||
|
||||
Tot `tests/`. Fiecare `test_<modul>.py` oglindește un modul din `src/atm/`.
|
||||
|
||||
## Local Contracts
|
||||
|
||||
- Un modul nou în `src/atm/` ⇒ un `test_<modul>.py` corespondent.
|
||||
- **`test_scenarios_regression.py`** rulează FSM-ul peste secvențele din
|
||||
`calibration/scenarios.json` pe frame-uri reale. Schimbi FSM ⇒ adaugă/actualizează
|
||||
scenariu acolo (vezi `calibration/AGENTS.md`).
|
||||
- **`test_env_loader.py`** monkeypatchează env-ul; păstrează regula „shell wins"
|
||||
din `config._ensure_env_loaded`.
|
||||
- Testele nu trebuie să atingă rețeaua reală (Telegram/Discord) — mock-uiește.
|
||||
|
||||
## Work Guidance
|
||||
|
||||
- Rulează suita completă înainte de orice commit care atinge `src/atm/`.
|
||||
- Dacă un test cere Pillow/OpenCV pe checkout-ul Windows, folosește venv-ul repo
|
||||
(vezi `scripts/AGENTS.md`).
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
pytest -q # toată suita
|
||||
pytest tests/test_scenarios_regression.py -v # FSM pe imagini reale
|
||||
```
|
||||
|
||||
## Child DOX Index
|
||||
|
||||
(none — leaf)
|
||||
Reference in New Issue
Block a user