DOX sistem
This commit is contained in:
108
AGENTS.md
108
AGENTS.md
@@ -1,90 +1,54 @@
|
|||||||
# ATM — Automated Trading Monitor
|
# 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
|
## Quick Reference
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install -e ".[windows]" # Windows: live capture
|
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)
|
cp .env.example .env # secretele Discord/Telegram (vezi README §Secrets)
|
||||||
atm calibrate # Tk wizard
|
atm calibrate # Tk wizard
|
||||||
atm debug --delay 5 # one-shot capture + detect
|
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 --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
|
atm run --tz America/New_York --oh-start 09:30 --oh-stop 16:00 # NYSE window
|
||||||
pytest -q # 230+ tests (core + 8 scenarii regresie + env loader)
|
pytest -q # 230+ teste
|
||||||
pytest tests/test_scenarios_regression.py -v # FSM pe imagini reale
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Codex sandbox/tooling notes
|
## DOX Protocol
|
||||||
|
|
||||||
On this Windows checkout, do not assume `rg` or the global `python` has project deps.
|
- **Citire** — traversează root → path-ul țintă, citind fiecare `AGENTS.md`. Dacă
|
||||||
Use the repo venv for diagnostics that need Pillow/OpenCV:
|
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
|
## Durable Rules (repo-wide)
|
||||||
.\.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
|
|
||||||
```
|
|
||||||
|
|
||||||
If `rg` is missing, use PowerShell fallbacks:
|
- **Pure-logic fără cv2/numpy** în `state_machine.py` și `config.py` (testele rulează
|
||||||
`Get-ChildItem -Recurse -File src,tests,scripts | Select-String -Pattern "needle"`.
|
headless). cv2/I/O greu mereu în `asyncio.to_thread`.
|
||||||
If a command fails due to sandbox permissions and is required for the task, rerun it
|
- **Secretele doar din env** (`.env`), niciodată în TOML sau cod.
|
||||||
with an escalation request instead of stopping the investigation without a verdict.
|
- **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:
|
## Child DOX Index
|
||||||
- `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`.
|
- **`src/atm/`** → `src/atm/AGENTS.md` — motorul: capture/detect/FSM/scheduler/
|
||||||
|
vision/canary/config. (copil: `notifier/`)
|
||||||
## Telegram commands (live)
|
- **`tests/`** → `tests/AGENTS.md` — suita de teste + regresie FSM.
|
||||||
|
- **`calibration/`** → `calibration/AGENTS.md` — corpus culori + scenarii + palette gotcha.
|
||||||
`/ss` `/status` `/pause` `/resume` `/rebase` `/3` (interval min) `/stop`
|
- **`configs/`** → `configs/AGENTS.md` — schema TOML (operating_hours, alerts, canary).
|
||||||
|
- **`scripts/`** → `scripts/AGENTS.md` — diagnostic + note sandbox Windows/venv.
|
||||||
- `/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
|
|
||||||
|
|||||||
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
|
Documentația operațională trăiește în arborele de `AGENTS.md` (format DOX), **nu**
|
||||||
pip install -e ".[windows]" # Windows: live capture
|
aici. Înainte să editezi un path, coboară din rădăcină citind fiecare `AGENTS.md`
|
||||||
pip install -e ".[dev]" # Linux/macOS: dev + tests (WSL: create venv first)
|
întâlnit; după o schimbare semnificativă, fă un DOX pass (actualizează doc-ul care
|
||||||
cp .env.example .env # secretele Discord/Telegram (vezi README §Secrets)
|
deține zona + indexul părintelui).
|
||||||
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
|
|
||||||
```
|
|
||||||
|
|
||||||
## Calibration corpus
|
Start: [`AGENTS.md`](AGENTS.md) (root — Quick Reference, reguli globale, index copii).
|
||||||
|
Copii: `src/atm/` · `src/atm/notifier/` · `tests/` · `calibration/` · `configs/` · `scripts/`.
|
||||||
`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`.
|
|
||||||
|
|
||||||
## Skill routing
|
## Skill routing
|
||||||
|
|
||||||
When the user's request matches an available skill, ALWAYS invoke it using the Skill
|
Când cererea userului se potrivește cu un skill disponibil, invocă-l cu tool-ul
|
||||||
tool as your FIRST action. Do NOT answer directly, do NOT use other tools first.
|
Skill ca PRIMĂ acțiune. NU răspunde direct, NU folosi alte tool-uri întâi.
|
||||||
The skill has specialized workflows that produce better results than ad-hoc answers.
|
Skill-ul are workflow-uri specializate care produc rezultate mai bune.
|
||||||
|
|
||||||
Key routing rules:
|
- Idei de produs, „merită construit", brainstorming → `office-hours`
|
||||||
- Product ideas, "is this worth building", brainstorming → invoke office-hours
|
- Bug-uri, erori, „de ce e stricat", 500 → `investigate`
|
||||||
- Bugs, errors, "why is this broken", 500 errors → invoke investigate
|
- Ship, deploy, push, PR → `ship`
|
||||||
- Ship, deploy, push, create PR → invoke ship
|
- QA, testează site-ul, găsește bug-uri → `qa`
|
||||||
- QA, test the site, find bugs → invoke qa
|
- Code review, verifică diff-ul → `review`
|
||||||
- Code review, check my diff → invoke review
|
- Update docs după ship → `document-release`
|
||||||
- Update docs after shipping → invoke document-release
|
- Retro săptămânal → `retro`
|
||||||
- Weekly retro → invoke retro
|
- Design system, brand → `design-consultation`
|
||||||
- Design system, brand → invoke design-consultation
|
- Audit vizual, design polish → `design-review`
|
||||||
- Visual audit, design polish → invoke design-review
|
- Architecture review → `plan-eng-review`
|
||||||
- Architecture review → invoke plan-eng-review
|
- Save progress, checkpoint, resume → `checkpoint`
|
||||||
- Save progress, checkpoint, resume → invoke checkpoint
|
- Code quality, health check → `health`
|
||||||
- Code quality, health check → invoke 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