diff --git a/keep.md b/keep.md index 4734262..d73a783 100644 --- a/keep.md +++ b/keep.md @@ -1 +1,2 @@ - Chce mít filmy uložené lokálně na disku — streaming služby mění podmínky a dostupnost, chce mít obsah trvale k dispozici po zaplacení +- Má předplatné: Netflix, HBO Max, SkyShowtime, Disney+ diff --git a/plans/2026-09-02_reflect-review-findings.md b/plans/2026-09-02_reflect-review-findings.md new file mode 100644 index 0000000..9f5ddf9 --- /dev/null +++ b/plans/2026-09-02_reflect-review-findings.md @@ -0,0 +1,133 @@ +# Reflect skill — review 2026-09-02 + +Stav: nálezy review, opravy navrženy, čekají na schválení implementace +Datum: 2026-09-02 + +Review prošlo celý skill: SKILL.md, README.md, `reflect_apply.py`, `reflect_auto.py`, +`reflect_distill.py` a všech 168 testů (prošly, 1.1 s). Celkový verdikt: nadprůměrně +dobře napsaný — „záruky v kódu, ne v promptu" je proveden důsledně, testy kódují +racionalu u každého assertu. Níže jsou problémy v pořadí závažnosti + návrh opravy +u každého. + +## 1. Fold přeloženého open nálezu zahodí drafted patch a skip count (bug) + +`merge_findings` (reflect_auto.py ~522) dědí `regression_of` a `history`, ale ne +`patch`, `patch_drafted_at` ani `skipped`. Jakmile noční běh znovu spatří stejný +`open` pattern, `supersede` starý záznam zahodí a nový vzniká bez těchto polí. + +Následky: + +- patch složený při review přes `--set-patch` (agent ho pracně ověřil proti + souboru) zmizí; SKILL.md krok 2 tvrdí „`patch_drafted_at` says an earlier + review drafted it" — po jedné noci to neplatí +- „deferred 2× already" z kroku 3 se vynuluje — nález se předkládá donebezedne + bez viditelné historie odkladů, i když ho uživatel už několikrát odložil +- audit log (`DRAFTED`, `SKIPPED`) ukazuje práci, na kterou store už neodkazuje + +**Fix:** v `merge_findings` při foldu open/watch předchozího záznamu přenést: + +```python +if previous and previous["status"] == STATUS_OPEN: + if previous.get("patch") and not item.get("patch"): + # drafted during a review, verified against the file — do not throw it away + patch = previous["patch"] # do Finding(...) + patch_drafted_at = previous.get("patch_drafted_at") + skipped = previous.get("skipped") # deferral history survives the fold +``` + +Pole `patch_drafted_at` a `skipped` je potřeba přidat do `Finding` dataclass a +`to_json()` (podmíněně jako ostatní volitelná pole). Nový patch z analýzy má +přednost před starým draftem; jinak se drží draft z review. Testy: fold open +nálezu s `skipped={count:2}` a drafted patchem → nový záznam obojí nese; +nový patch z modelu draft nepřepisuje, ale nahrazuje. + +## 2. `reflect_apply.py` nechrání vlastní store jako cíl patche (designová mezera) + +`_resolve_target` odmítne cestu mimo workspace, ale klidně aplikuje patch na +`reflect/findings.jsonl`, `reflect/state.json` nebo `log/reflect.log`. Celá +filozofie skillu je „do audit trail píše jen reflect_apply" — ale reflect_apply +sám může patchem přepsat audit trail (typicky změnit `rejected` záznam zpět na +`open`, což oživí zamítnutý vzor). Stane se to „se schválením uživatele", které +v diffu snadno přehlédne, že jde o store. + +**Fix:** explicitní blocklist v `check_patch` / `_resolve_target` +(reflect_apply.py): + +```python +PROTECTED = ("reflect/", "log/reflect.log") + +def _resolve_target(workspace, relative): + target = (workspace / relative).resolve() + if not target.is_relative_to(workspace.resolve()): + raise ApplyError(f"{relative} resolves outside the workspace") + if target == (workspace / FINDINGS_REL).resolve() or \ + any(target.is_relative_to(workspace / prefix) for prefix in PROTECTED): + raise ApplyError(f"{relative} is part of the reflect store — not a patch target") + ... +``` + +Důvod zdůvodnit v chybové hlášce („the audit trail is never a patch target"). +Pozn.: `set_patch` tím kryje i draft, nejen apply. Test: patch s +`file: reflect/findings.jsonl` → exit 2, store netčen. + +## 3. Vakuózní assert v testu (test_reflect_auto.py) + +`test_first_run_has_no_trend_to_show` tvrdí `"(minule" not in report`, ale +`_rate_line` generuje anglické „(previous run …)". Assert nikdy nemůže selhat, +test tedy nic nehlídá. + +**Fix:** `assert "(previous" not in report`. Jednořádková změna. + +## 4. Noise prefix `"cli"` chytá i `client*` (případné falešné vyřazení) + +`key.startswith(NOISE_PREFIXES)` — session `client_xyz` (nebo cokoli začínající +„cli") se tiše vyřadí z analýzy. Prefix-match na krátkých prefixech je +přístřelen. Podobně base64 session jména obsahující `-`/`_` (jsou v urlsafe +abecedě) se nedekódují kvůli heuristice `"_" in stem or "-" in stem` — +legitimní stará session se pak chytne prefixem, nebo naopak neprojde. + +**Fix:** noise match na hranici klíče: session klíče mají tvar +`_` resp. base64 bez `_`, takže matchovat +`key == prefix or key.startswith(prefix + "_")`. Případně (jednodušeji) +přejmenovat prefix na `cli_` v NOISE_PREFIXES, protože reálné machinery session +jsou `cli_<…>`. Test: `client_abc` prochází, `cli_kimi-ollama-test` ne. + +## Menší + +### 5. Git fingerprint se nekontroluje při LLM error cestě + +`_resolve_findings`: fingerprint se porovná jen po úspěšném tahu. Když tah +skončí LLM errorem a agent v tu chvíli něco zapsal, guard se neprojeví a +run pokračuje. Riziko je teoretické (error odpověď znamená, že k zápisu +s nejvyšší pravděpodobností nedošlo), ale guard je zadarmadlo dokončit. + +**Fix:** porovnat fingerprint i na začátku error větve +(`if result.stop_reason == "error" or result.error:`) — stejná kontrola, +stejná hláška. + +### 6. `MIN_MESSAGES=5` počítá i tool výsledky + +`distill_session` inkrementuje `message_count` pro user, assistant i tool +role. Session s 1 user zprávou a 2 tool cally (celkem 5 záznamů) projde +prahem, přestože je to jeden dotaz — nižší signál, ne rovnou chyba. + +**Fix (volitelné):** počítat jen user + assistant zprávy +(`message_count += 1` jen v těch dvou větvích). Tool results počítat jako +součást tahu, ne jako zprávu. Existující testy `message_count == 6` adaptovat. + +### 7. Neatomičnost mezi `git commit` patche a `_save(findings)` + +Crash mezi commitem patche a zápisem store zanechá soubor patched, ale store +`open` (bez audit linky). Re-apply se správně odmítne na chybějícím `old_text`, +ale audit stopa pro ten commit chybí. U single-user workspace akceptovatelné; +zmiňuju pro úplnost. Plná atomicita (např. save-first-then-commit s rollbackem +store) nedoporučuju — přidá složitost pro okrajový scénář. Spíš uvážit +pořadí: nejdřív `_save` + audit, pak commit; pak crash zanechá `applied` +záznam bez commitu, což reflektuje hlášku `git revert` — ale zase commit +refusu zanechá store applied bez commitu. Trade-off, nechává rozhodnutí +na implementaci. + +## Pořadí implementace + +1 → 2 → 3 → 5 → 4 → (6, 7 volitelné). Položky 1–3 jsou přímé rozpory se +zárukami deklarovanými v README („Záruky"), 5 a 4 jsou levné tvrdnutí guardů. \ No newline at end of file diff --git a/plans/cook-skill-design.md b/plans/cook-skill-design.md new file mode 100644 index 0000000..852b22a --- /dev/null +++ b/plans/cook-skill-design.md @@ -0,0 +1,70 @@ +# Cook skill — final design + +## Context + +User wants a personal store for recipes and tea notes (origins, brewing +parameters, tasting). Wiki/note rejected as too heavy. Agreed design: +`cook/` data dir + thin `skills/cook/` skill manifest + a small safety +script. This plan finalizes the design agreed question-by-question in chat +(2026-09-08) and supersedes the quick-draft SKILL.md already written. + +## Decisions (locked with user) + +1. **Script, not raw file tools** — `cook.py` guards against accidental + overwrite/delete; frontmatter always machine-generated (no drift). + Keep it **minimal — shortest working code, no speculative features**. +2. **Frontmatter** (free-form values, only `type` is fixed): + `type: recept|caj`, `category`, `cuisine` (recepts only), + `origin` (caj only), `tags` (user hashtags, no `#`), `added` (auto date). + Can be lightened later. +3. **Hashtags live in frontmatter `tags`**, not in body. +4. **Search via script**: frontmatter filtering + fulltext body grep. + Start simple; enrich later. +5. **Slug collision**: `add` on existing slug → error; agent shows the + existing item, user decides edit vs. new slug. No auto `-2` suffixes. +6. **Assets**: `cook/assets//` when documents/photos ever arrive; + not created upfront. + +## Steps + +1. Rewrite `skills/cook/SKILL.md` to the final design: + - layout (`cook/recepty/`, `cook/caj/`, `cook/assets/` — created on demand) + - all file mutations via `cook.py` subcommands; agent never `write_file`s + into `cook/` directly except body edits via `edit_file`/`apply_patch` + after `add` creates the skeleton + - capture inline (same turn), commit after each change + (`git add cook/ && git commit -m "cook: ..."`; never `git add -A`) + - search/answer flow: `list`/`search` to narrow, then read files, answer + from files only, no confabulation + - edit/delete: two-turn confirm flow (show exact text → user confirms → + apply → commit) + - slug conventions: kebab-case; collision handling per decision 5 +2. Write `skills/cook/scripts/cook.py` — minimal (~150 lines), stdlib only: + - `add --type recept|caj [--category C] [--cuisine C] [--origin O] + [--tags a,b] [--body-file F]` → creates file with frontmatter; + **exit 1 if slug exists**; reads body from stdin or `--body-file` + - `edit ` → prints file path; **exit 1 if missing** (no silent + create); actual text edits done by agent with `edit_file` on the path + - `list [--type T] [--category C] [--tag X]` → one line per item: + `slug type category added title` + - `show ` → full file content + - `search ` → fulltext grep across bodies, prints matching lines + with slug context + - `rename ` → moves file (+ its assets dir if present); + exit 1 if target exists + - `delete ` → removes file (and empty assets dir); only run + after user confirmation per SKILL.md flow + - `validate` → checks every file has parseable frontmatter and `type` + - Frontmatter: minimal hand-rolled parse (no external deps). +3. Test drive: `add` a sample recipe + sample tea, verify frontmatter, + `list`, `search`, collision error, `validate`, then delete samples and + commit the real state. + +## Verification + +- `cook.py add` twice on same slug → second exits 1 +- `edit`/`show`/`rename`/`delete` on missing slug → exit 1 +- `list --tag chata` filters on frontmatter tags +- `search ` finds body text +- `validate` passes on script-created files, fails on a hand-mangled one +- SKILL.md contains no leftover pipeline cruft (inbox/compile/lock) \ No newline at end of file diff --git a/projects/ai/artifacts/agent-to-human-tools.md b/projects/ai/artifacts/agent-to-human-tools.md new file mode 100644 index 0000000..9183cc6 --- /dev/null +++ b/projects/ai/artifacts/agent-to-human-tools.md @@ -0,0 +1,43 @@ +# Převod agent-nástrojů na nástroje pro člověka + +Ověřený postup. Když AI agent napsal nástroj (runbook, skripty) původně +**pro sebe**, nejde ho přímočaře zjednodušit pro lidské použití. + +## Proč opačný postup nefunguje + +- Model nevidí hranici, kde končí pro člověka použitelná složitost — + „zjednoduš to" produkuje kosmetické úpravy, ne redesign. +- Existující podoba psaná pro agenta (hromada parametrů, dlouhé runbooky) + model **ukotvuje** — upravuje, co vidí, místo aby navrhl jiné rozhraní. +- Plan mode u designu rozhraní nestačí: plánuje implementaci, ne podobu + rozhraní. Tu musí určit člověk. + +## Princip + +**Rozhraní navrhuje člověk, model implementuje.** LLM je nejsilnější v +dokódování těla funkce se zadaným podpisem — přebírání designu je jeho slabá +stránka. + +## Postup + +1. **Existující agent-runbook ani skripty nepoužívat jako základ** — jen jako + zdroj doménových faktů (co nástroj umí, jaké scénáře existují, jak se čeká + na konec testu). Strukturu ne. Začít v čistém adresáři. +2. **Tabulka scénář → příkaz** — člověk ručně napíše, co kdy spouští. + To je celý human-runbook; žádný postup kroků. +3. **Kostry skriptů píše člověk** — param block, komentáře po sekcích, + protokol čekání na dokončení (např. čekat na exit procesu, žádný polling). + Složitost je tím rozhodnutá předem. +4. **Model jen dokódovává těla** — zadání: „dokóduj těla, parametry + a strukturu neměň, nic nepřidávej.“ Review pak kontroluje jen implementaci, + ne design. + +## Pravidla pro zadání + +- Složitost zadávat **čísly, ne adjektivy**: max počet parametrů na skript, + max počet kroků, jeden skript = jeden scénář. Model na numerické limity + reaguje spolehlivě; na „simple" ne. +- Negativní omezení („žádné extra parametry") prosadit **v kódu kostry, + ne v promptu** — když param block má 3 parametry, model 15 nedoplní. +- Agent-runbook pro sebe si nechat vedle — převod „agent-runbook → + human-runbook" je cesta, kde se to pořád láme. Nejsou to stejný dokument. \ No newline at end of file diff --git a/projects/ai/artifacts/file-based-agent-communication.md b/projects/ai/artifacts/file-based-agent-communication.md new file mode 100644 index 0000000..22d400c --- /dev/null +++ b/projects/ai/artifacts/file-based-agent-communication.md @@ -0,0 +1,54 @@ +# Anotace v souborech místo chatu („mob with AI") + +Zdroj: článek „Don't Chat With Your AI. Mob With It." (David Rodenas, Medium, +2026). Článek sám je slabý — argument o latenci (GPU sloty, uvolňování/ +načítání inference) je nedoložený a nesedí; reálná latence je round-trip +klient↔server, sériovost kroků a opakovaný prefill. Analogie s mob +programmingem taky ne — v mobu píše jeden driver a víc lidí řídí, tady je to +obráceně. Jádro je ale použitelné. + +## Co drží (jádro oddělené od balastu) + +- **Instrukce patří tam, kde je předmět instrukce.** Tag na konkrétním řádku + dá kontext pozicí — agent nepotřebuje popis „v tom souboru, u té funkce". + Stejný princip jako TODO komentář / poznámka v code review. +- **Trvalost:** anotace nesedí v chatu, který se zavře — je v souboru, vidět + v diffu, přežije session. +- Není to o latenci ani paralelizaci. „Zrychlení" je ve skutečnosti **fronta**: + zadám a nejdu čekat. Round-trip se nezkrátil, jen u něj nestojím. +- Článek si protiřečí vlastním východiskem (DORA/TDD = rychlý feedback): + hromadné zadání a společný review na konci **prodlouží feedback loop pro + člověka**, ne pro agenta. „Hotovo dřív, než si všimnu" je z tohoto pohledu + špatná zpráva, ne dobrá. + +## Mechanismus + +Komunikace přes tagy přímo v souborech (autor: `[[CLAUDE: …]]` instrukce, +`[[DAVID: …]]` dotaz agenta). Pravidlo v CLAUDE.md: agent tagy hledá, provádí, +odpovídá. Autor tag po provedení maže — to je chyba. + +## Úpravy oproti článku + +- **Tag nemaže, jen připisuje odpověď pod něj** — vlákno zůstane v souboru + a v diffu; mazání je jen člověk, před commitem (grep na prefix). +- **Nespouštět agenta ve smyčce nad soubory** (autonomní reakce = ztráta + kontrolního bodu). Místo toho explicitní příkaz „projdi tagy a vyjádři se". +- **Max 1–2 tagy na kolo.** Deset tagů = deset změn ke společnému review = + nejasné, co odkud přišlo. + +## Varianty kam dát vlákno + +1. **Anotace jako komentáře v kódu** — nulová infrastruktura, funguje všude, + diff ukáže celou historii výměny. Nevýhoda: zaneřádí kód, hlídání ručně. + Dobré na krátké výměny u konkrétního místa. +2. **Vedlejší soubor** (`file.notes.md` vedle zdrojáku, odkaz na symbol, + ne na číslo řádku) — kód čistý, vlákna libovolně dlouhá, .gitignore. + Dobré na dlouho se vlečoucí věci. + +## Otevřené otázky + +- Korekce agentových odpovědí („odpověď chci přepsat") — chat to řeší tím, + že je mimo kód; anotace v souboru to nemají kde. Varianta 1 to řeší + nejlíp (přepis = nová verze vlákna na místě), ale je potřeba vyzkoušet. +- Vazba na symboly místo řádků u varianty 2 — jinak se odkazy rozbijí + při každém editu. \ No newline at end of file diff --git a/projects/ai/memory.md b/projects/ai/memory.md index 181c512..d8f545f 100644 --- a/projects/ai/memory.md +++ b/projects/ai/memory.md @@ -1,3 +1,10 @@ - 2026-09-02: Založen projekt: deník + hledání řešení pro AI témata (agenti, kódování s AI, LLM). - 2026-09-02: Incident „gpt 5.3 se zasekl na PH/PZ/TX z mobilu": rekonstruováno — finální odpověď byla kompletní a verzovaná; problém byl agent loop (guard bloky, retry smyčky, ~6-8 min). Model = glm-5.3:cloud (žádný gpt 5.3). Kanál na kvalitu vliv nemá. -- 2026-09-02: Compaction: uživatel si vyžádal drastické zkrácení incident zápisu; detaily zahoz­deny, zachovány jen závěry. \ No newline at end of file +- 2026-09-02: Compaction: uživatel si vyžádal drastické zkrácení incident zápisu; detaily zahoz­deny, zachovány jen závěry. +- 2026-09-08: Série měření na Solarflare X2/X4 (TCPDirect, C# knihovna). Claude Code navrhl měřicí setup, aplikace sockbench na měření, Claude spouštěl scénáře, ukládal a vyhodnocoval výsledky. Fungovalo. +Pak cíl: převést proces na ruční spouštění skriptů (PowerShell) pod vlastní kontrolou. Claude zde selhává opakovaně: skripty zbytečně složité, moc parametrů, špatně čekal na dokončení test setu, testoval zbytečné věci. Zadání v plan modu se nedaří, výsledek stále špatný — frustrace, ztracený čas místo ušetřeného. +Uživatelova diagnóza: nedokáže správně popsat zadání; buď málo informací, nebo špatný přístup. Zvažované cesty: napsat kostry skriptů sám s komentáři a nechat Claude dokodovat; lepší projektový dokument; úplně odpoutat se od současné verze a začít znovu. Hledá efektivní způsob práce. +- 2026-09-08: Upřesnění diagnózy (Solarflare/sockbench): Claude si původně napsal runbook pro sebe — pro agenta byl ok, pro člověka nepoužitelný (moc kroků, moc složitosti). Skripty nebyly úplně špatné, ale měly tunu parametrů. Jádro problému: dvě různé cílové skupiny — agent snese libovolnou složitost, člověk potřebuje mnohem menší míru komplexity. Uživatel se o tom v plan modu snažil mluvit, přiblížil se, ale komunikace nestačila. +- 2026-09-08: correction: „úplně znovu od nuly — ne" z minula bylo nedorozuměním. Uživatel tím nemyslel „znovu bez specifikace", ale nepoužít existující runbook a existující skripty jako základ — ty ho limitují a anchornují ho špatným směrem. Restart s jeho vlastní specifikací (tabulka scénářů + kostry) je v pořádku, jediné co ne: recyklace agent-runbooku. +- 2026-09-08: Destilace postupu „převod agent-nástrojů na nástroje pro člověka" uložena jako artefakt: projects/ai/artifacts/agent-to-human-tools.md. Strukturovaný markdown: proč zjednodušení agent-nástrojů nefunguje (neviditelná hranice složitosti, ukotvení existující podobou, plan mode neřeší design), princip „rozhraní navrhuje člověk, model implementuje", 4krokový postup (čistý adresář → tabulka scénář→příkaz → kostry → dokódování těl) a pravidla pro zadání (čísla místo adjektiv, omezení v kódu ne v promptu, agent-runbook nepřevádět). Po vzájemné korektní diskusi: knowledge/ odmítnut, artefakt patří do projektu ai. +- 2026-09-08: Rozbor článku „Don't Chat With Your AI. Mob With It." (Rodenas) + diskuse s Claude uložen jako artefakt: projects/ai/artifacts/file-based-agent-communication.md. Technikou je komunikace s agentem přes tagy v souborech místo chatu. Článková argumentace odmítnuta (latence ≠ GPU sloty; mob analogie obrácená; autonomní smyčka + mazání tagů = ztráta kontrolního bodu a prodloužení feedback loopu pro člověka). Použitelné jádro: anotace patří tam, kde je předmět anotace (pozice = kontext, jako TODO komentář), trvalost v diffu, tag se nemaže jen se připíše odpověď, max 1–2 tagy na kolo, explicitní spouštění místo autonomní smyčky. Otevřená otázka: jak korigovat agentovy odpovědi — kandidát varianta „vlákno jako komentáře v kódu" oproti vedlejšímu .notes.md souboru. Zájem uživatele o vyzkoušení. diff --git a/projects/life/state.md b/projects/life/state.md index ebe6471..a0fa8a1 100644 --- a/projects/life/state.md +++ b/projects/life/state.md @@ -44,3 +44,4 @@ Denní vážení, vnímaná kondice, jestli mě něco bolí. - **Fyzio terapie k zadání**: omezená mobilita pravého kyčle; proč se pravá noha na rozdíl od levé tak snadno a často přetěžuje. - **Cíl pravidelnosti**: cvičit aspoň 2× týdně; protahování častěji než doteď. +- **Klinika**: https://fyzioklinika.cz