upravy projektu a skillu
This commit is contained in:
164
skills/reflect/README.md
Normal file
164
skills/reflect/README.md
Normal file
@@ -0,0 +1,164 @@
|
||||
# reflect — jak to funguje
|
||||
|
||||
Skill hledá v mých vlastních session logách **opakující se chyby**, pojmenuje je a navrhne
|
||||
opravu. Nálezy pak procházíš ty, jeden po druhém, a rozhoduješ, co se použije.
|
||||
**Sám od sebe nikdy nic nezmění.**
|
||||
|
||||
## Dva režimy
|
||||
|
||||
```text
|
||||
ANALÝZA — denně 03:30, bez tebe REVIEW — jen když napíšeš /reflect
|
||||
cron → reflect_auto.py ├─ vezme 1 otevřený nález
|
||||
├─ destiluje session z okna ├─ ukáže diagnózu, důkazy, návrh, diff
|
||||
├─ LLM tah → nálezy ├─ čeká na tvoje rozhodnutí
|
||||
├─ zapíše do findings.jsonl ├─ aplikuje → git commit → audit
|
||||
└─ Telegram (jen když je co) └─ další nález
|
||||
NEEDITUJE NIC edituje jen to, co schválíš
|
||||
```
|
||||
|
||||
## Nálezy jsou o nedávném chování, ne o celé historii
|
||||
|
||||
Běh se dívá jen na **posledních 21 dní** (`--window-days`). Není to úspora — je to
|
||||
podmínka, aby nález něco znamenal: korpus má 3,5 měsíce a jedna dávka 200 kB, takže
|
||||
dohánění celé historie po jedné dávce za noc znamenalo, že cursor tři noci stál na
|
||||
konci května a nálezy z něj se předkládaly jako aktuální.
|
||||
|
||||
Dvě hranice, každá jinak:
|
||||
|
||||
| | Co dělá |
|
||||
|---|---|
|
||||
| **cursor** | podlaha — co se jednou analyzovalo, se neanalyzuje znovu (jinak by se zdvojily počty) |
|
||||
| **okno** | strop — co je starší než 21 dní, se přeskočí a cursor to mine natrvalo |
|
||||
|
||||
Kdybys někdy potřeboval archeologii, vrať `cursor` ve `state.json` a spusť
|
||||
`--window-days 0`.
|
||||
|
||||
## Proč tě to neotravuje každý den
|
||||
|
||||
Denně přibude jen pár session — v nich se vzor nepozná, jedna chyba je náhoda. Proto:
|
||||
|
||||
| Kdy | Status | Telegram |
|
||||
|---|---|---|
|
||||
| vzor poprvé, 1 výskyt | `watch` | ne, jen se počítá |
|
||||
| vzor podruhé (≥2× a ve ≥2 session) | `open` | ano |
|
||||
| vzor už jednou opravený se vrátí **po** opravě | `open` + **regrese** | ano |
|
||||
| vzor už jednou opravený, ale důkazy jsou starší než oprava | `watch` | ne |
|
||||
| vzor jsi zamítl | `watch` napořád | ne, už nikdy |
|
||||
|
||||
Zamítnutí je rozhodnutí, ne odklad — zamítnutý vzor se znovu neotevře.
|
||||
|
||||
## Co ti /reflect nabídne
|
||||
|
||||
| Napíšeš | Stane se |
|
||||
|---|---|
|
||||
| `ok` / `aplikuj` | patch se použije a commitne |
|
||||
| `uprav: <text>` | přepíšeš návrh vlastními slovy, ukáže se nový diff |
|
||||
| `přeskoč` | nález zůstane otevřený na příště |
|
||||
| `zamítni` | nález se zavře natrvalo |
|
||||
| `konec` | konec review |
|
||||
|
||||
Nález, který od analýzy patch nedostal (většina), si ho složí až při review: agent napíše
|
||||
návrh do JSON a nechá ho ověřit (`--set-patch`). Skript ho **nejdřív ověří proti souboru
|
||||
a teprve pak uloží**, takže nepoužitelný pokus ve `findings.jsonl` nezůstane — a agent do
|
||||
store nesahá vůbec. Pak ti ukáže diff a čeká na `ok` jako u každého jiného patche.
|
||||
|
||||
Vždy jen **jeden** nález najednou. Nálezy se číslují `1..N` podle pořadí, ne podle
|
||||
interního id.
|
||||
|
||||
## Kde co leží
|
||||
|
||||
| Cesta | Co |
|
||||
|---|---|
|
||||
| `reflect/findings.jsonl` | všechny nálezy, jeden JSON na řádek |
|
||||
| `reflect/state.json` | kam se došlo (cursor), použité okno + statistiky běhů |
|
||||
| `results/<datum>_reflect.md` | plný report jednoho běhu + okno, které pokryl, a kolik výskytů na 100 session mají už známé vzory |
|
||||
| `log/reflect.log` | audit — každé rozhodnutí, i zamítnutí a přeskočení |
|
||||
|
||||
**„Naposledy" u nálezu je nejnovější datum v důkazech**, ne datum, kdy se záznam
|
||||
naposledy přepsal. Když je starší než okno posledního běhu, je nález **zastaralý**:
|
||||
analýza tam už nedohlédne, takže se sám nikdy neobnoví — spíš než patch si zaslouží
|
||||
zamítnutí. `/reflect` ti to u něj řekne.
|
||||
|
||||
**Počty v nálezu (`7× ve 4 session`) jsou kumulativní součet napříč běhy** — sečtené
|
||||
z toho, co model napočítal v jednotlivých oknech, ne měření nad celým korpusem. Skript
|
||||
u nich hlídá jen to, co hlídat umí: vzor nemůže zasáhnout víc session, než kolikrát
|
||||
nastal, ani víc, než kolik jich v dávce vůbec bylo.
|
||||
|
||||
## Co se o tvém rozhodnutí zapíše
|
||||
|
||||
| Rozhodnutí | Do `findings.jsonl` | Do `log/reflect.log` |
|
||||
|---|---|---|
|
||||
| složení patche | `patch` + `patch_drafted_at` (= složeno při review, ne modelem) | `DRAFTED <id> [vzor] <soubor>` |
|
||||
| `ok` | `applied: {at, sha, file}`, `patch` = návrh modelu | `APPLIED <id> [vzor] <soubor> — <sha>` |
|
||||
| `uprav:` | navíc `applied.new_text` = tvoje verze (návrh modelu zůstává v `patch`) | `APPLIED-EDITED …` |
|
||||
| `zamítni` | `rejected: {at, reason}` — **důvod je povinný** | `REJECTED <id> [vzor] — <důvod>` |
|
||||
| `přeskoč` | `skipped: {count, last}`, status zůstává `open` | `SKIPPED <id> [vzor] ×N` |
|
||||
|
||||
Povinný důvod u zamítnutí není otravování: je to jediná zpětná vazba na kvalitu analýzy.
|
||||
Z prvních osmi nálezů jsi čtyři zamítl — bez důvodů se z toho čísla nedá poznat, co
|
||||
v analytickém promptu změnit.
|
||||
|
||||
Na dotaz „co jsem už rozhodl" ti to `/reflect` vypíše z logu včetně revert příkazu.
|
||||
|
||||
## Jak vrátit změnu zpět
|
||||
|
||||
Workspace je git, takže každá aplikovaná oprava je samostatný commit:
|
||||
|
||||
```bash
|
||||
git revert <sha>
|
||||
```
|
||||
|
||||
SHA najdeš v `log/reflect.log` nebo u nálezu ve `findings.jsonl` (`applied.sha`).
|
||||
|
||||
Změna žije **jen na serveru** — do trackovacího repa (`src/nanobot`) se musí dotáhnout
|
||||
zvlášť, jinak ji příští `rsync` skillu přepíše zpátky.
|
||||
|
||||
## Ruční spuštění
|
||||
|
||||
```bash
|
||||
cd ~/.nanobot/workspace
|
||||
|
||||
# normální běh (to dělá cron)
|
||||
~/.local/bin/uv run --script skills/reflect/scripts/reflect_auto.py
|
||||
|
||||
# jiné okno než výchozích 21 dní
|
||||
~/.local/bin/uv run --script skills/reflect/scripts/reflect_auto.py --window-days 7
|
||||
|
||||
# jen prompty do tmp/, nevolat model; s --all přes celý korpus
|
||||
~/.local/bin/uv run --script skills/reflect/scripts/reflect_auto.py --dry-run --all
|
||||
|
||||
# jak velký je korpus a na kolik dávek vyjde (nevolá model)
|
||||
~/.local/bin/uv run --script skills/reflect/scripts/reflect_distill.py --stats > /dev/null
|
||||
```
|
||||
|
||||
`--all` ignoruje cursor, takže by znovu přečetl už spočítané session a **nafoukl jim
|
||||
počty**. V ostrém běhu ho skript odmítne — je jen na `--dry-run`.
|
||||
|
||||
**Přerušený běh o hotovou práci nepřijde.** Nálezy i cursor se zapisují po každé dávce
|
||||
a nová dávka nezačne po 20 minutách (`--deadline-minutes`). S 21denním oknem to vyjde
|
||||
zpravidla na jednu dávku, takže se tenhle strop ani neuplatní; kdyby zbyla nezpracovaná
|
||||
dávka, Telegram to řekne i když nálezy nejsou žádné.
|
||||
|
||||
Plná cesta k `uv` je tu proto, že v neinteraktivním SSH není v `PATH`. Crontab si
|
||||
`PATH` nastavuje sám, takže tam stačí `uv run …`.
|
||||
|
||||
## Záruky
|
||||
|
||||
Nejsou to sliby v promptu, ale kód:
|
||||
|
||||
- **Analýza (`reflect_auto.py`) nemá v sobě žádnou cestu k zápisu do cizího souboru.**
|
||||
Navíc se před a po tahu porovná `git status` celého workspace — kdyby agent přesto něco
|
||||
zapsal, nálezy se zahodí.
|
||||
- **Editaci dělá výhradně `reflect_apply.py`, vždy jeden nález.** Agent soubor needituje
|
||||
sám. Skript odmítne patch, jehož původní text v souboru není nebo je tam vícekrát —
|
||||
nehádá, kam patřil. Odmítne i nález, který není `open` (tj. nebyl ti předložen).
|
||||
- **Do `findings.jsonl` píše taky jen `reflect_apply.py`.** I patch složený při review jde
|
||||
přes něj (`--set-patch`) a projde stejnou kontrolou; agent auditní stopu needituje.
|
||||
- **Commituje se jen ten jeden dotčený soubor** (`git add -- <file>`), nikdy `git add -A`.
|
||||
Rozdělaná práce Dreamu a jiných skillů se do commitu nedostane; když je rozdělaný přímo
|
||||
ten soubor, udělá se nejdřív checkpoint commit, aby byl revert přesný.
|
||||
- Skill vynechává vlastní session, takže neanalyzuje sám sebe.
|
||||
- **Každé rozhodnutí nechá záznam**, i to, které nic nezmění: zamítnutí s důvodem,
|
||||
přeskočení s počítadlem, `uprav:` odděleně od původního návrhu modelu.
|
||||
|
||||
Ověřeno testy v `tests/` — včetně toho, že `git revert` vrátí soubor do původního stavu.
|
||||
Reference in New Issue
Block a user