# F4: bod obnovy, úzký bash grant, Gate 3

**Datum:** 5. 10. 2026
**Autoritativní plán:** `.kilo/plans/CyberBrain26cil-031026-v2.md` (beze změny)
**Navazuje na:** `.kilo/context/handoff/HANDOFF_2026-10-05-0145.md`
**Rozsah:** commit F4 práce → úzce omezený `bash` pro `security-auditor` → Gate 3 pro F4.

---

## 1. Skutečný stav (ověřeno v tomto vlákně, ne převzato)

| Tvrzení | Zdroj | Stav |
|---|---|---|
| `HEAD` = `1f80b29`, větev `master` | `.git/logs/HEAD:9`, `.git/HEAD` | OVĚŘENO |
| Žádný commit od handoffu 01:45 | `.git/logs/HEAD` | OVĚŘENO |
| `free_only` filtr v routeru | `router.py:157-167, 277, 312-313, 343-344` | OVĚŘENO |
| Egress autorizace v živé cestě | `model_gateway/__init__.py:265` před `:268`; fallback autorizuje každý provider zvlášť `:411` | OVĚŘENO |
| `ModelEgressGate` volá skutečný gate | `model_egress.py:74` | OVĚŘENO |
| `destination=""` | `model_egress.py:72` | OVĚŘENO — nález otevřený |
| `RoleAssignmentStore` / `KiloConfigBuilder` nezapojené | grep v `src/`+`tests/` → jen vlastní soubory a F4 test | OVĚŘENO |
| `bash: allow` jen `orchestrator` + `tester` | `.kilo/agent/*.md`, `.kilo/kilo.jsonc:79` | OVĚŘENO |

**Rozpor, který je nutné zaznamenat:** handoff §4.4 uvádí **10 mutací, 10/10 padá**.
Soubor `mutation_check_f4.py` obsahuje **24 mutací (M1–M24)** plus `STRUCTURAL_NOTE`,
která přiznává, že **M23 a M24 (odstranění zámků) jednovláknovou suitou detekovat nelze**.
Handoff je v tomto bodě zastaralý a jeho tabulka podhodnocuje rozsah i vyznámou mezeru.
Nepoužívat §4.4 jako zdroj pro Gate 3.

**Brány z handoffu NOT v tomto vlákně přespánány** (nemám `bash`): 691 passed, ruff, mypy 74 souborů.
Před commitem je `tester` musí přeměřit — čísla jsou z 01:45.

---

## 2. Rozhodnutí vlastníka (5. 10. 2026)

| # | Rozhodnutí |
|---|---|
| 1 | Nejdřív commit bod obnovy, pak Gate 3. |
| 2 | `security-auditor` dostane `bash` — **vědomá změna bezpečnostního postoje**, částečně ruší D3. |
| 3 | Grant je **úzký**: `{"pytest": "allow", "*": "deny"}`. Ne plné `bash: allow`. |

Co se tím **nemění**: `.kilo/kilo.jsonc:79` globální `bash: deny` zůstává (D3 / Gate 0 podlaha),
`MUST_BE_EXPLICIT_DENY` zůstává v testu, `edit: deny` u auditora zůstává.
Grant je pouze na úrovni agent frontmatter.

---

## 3. Úkoly v pořadí

### K1 — Commit bod obnovy F4
1. `tester` změří Gate 1: `pytest -q`, `ruff check .`, `mypy src/cyberbrain26`.
   Zapsat skutečná čísla do záznamu. Pokud nesouhlasí s handoffem, zapsat nesoulad, ne přebrat.
2. `git status --porcelain` — potvrdit, že je stále 9 položek.
3. Jeden checkpoint commit, zahrnout všechny 9 položek:
   `.kilo/kilo.jsonc` (schváleno vlastníkem 5. 10.), `model_gateway/__init__.py`,
   `router.py`, `role_assignment.py`, `kilo_config.py`, `model_egress.py`,
   `tests/test_f4_model_intelligence.py`, `mutation_check_f4.py`, `.kilo/context/rollback/`.
4. Zapsat `1f80b29` jako rodiče do zprávy commitu, aby byla regresní cesta dohledatelná.
5. **Žádný push, žádný stash, žádný reset.** Žádný remote v repu není.

### K2 — Úzký bash grant pro security-auditor
Soubory: `.kilo/agent/security-auditor.md`, `tests/test_kilo_agent_policy.py`.

1. `security-auditor.md:7` — nahradit `"bash": deny` hodnotou
   `{"pytest": "allow", "*": "deny"}`.
   Ostatní klíče frontmatteru (`edit`, `task`, `external_directory`, `agent_manager`,
   `doom_loop`, `cyberbrain26_*`) **beze změny**.
2. `tests/test_kilo_agent_policy.py` — do `PRIMARY_TOOL_ALLOW_EXCEPTIONS` přidat
   `("security-auditor", "bash")` s komentářem odkazujícím na rozhodnutí vlastníka 5. 10.
   Tím projdou `test_every_agent_bash_explicitly_denied` (`:446`) a
   `test_agent_permission_is_subset_of_global` (`:490`).
3. `test_bash_dict_form_contains_star_deny` (`:465`) projde bez zásahu — dict má `"*": "deny"`.
   **Ověřit, že tomu tak skutečně je**, a že výjimka je pouze dvouřádková.
4. Meta-test `test_detector_rejects_bash_allow` (`:1017`) **musí zůstat zelený a nesmí být
   upraven**. Je to pojistka, že kontrolní logika stále odmítná `bash: allow` bez výjimky.
   Pokud by jeho úprava byla nutná, zastavit a jít zpět k vlastníkovi.
5. `security-auditor.md:26`, `:103` — text agenta tvrdí „nemáš bash". **Přepsat** na
   „smíš spustit `pytest`, ostatní příkazy jsou deny". Charta nesmí lhát o vlastních
   oprávněních — to je přesně vzorec, který v minulých vláknech zničil důvěryhodnost reportů.
6. `security-auditor.md:95` a Gate 3 podmínka 3 (`:117`) — místo „brány které neproběhly,
   ať je spustí tester" nyní může uvést vlastní běh pytest s výstupem.
7. Kontrola po zásahu: spustit celou `tests/test_kilo_agent_policy.py`, ne jen jeden test.
   Změna se dotýká bezpečnostní podlahy — Gate 0 nesmí přijít o pojištění.

### K3 — Gate 3 pro F4
Zadání pro `security-auditor` (má úzký pytest):

1. **Rozsah:** `router.py`, `model_gateway/__init__.py`, `model_egress.py`,
   `kilo_config.py`, `role_assignment.py`. Hranice mimo audit: `security_plane/`,
   `execution_plane/`, `pilot/`.
2. **Očekávané vlastnosti k ověření `file:line`:** free-only routing bez tichého
   přesměrování; egress autorizace před každým providerem; fail-closed bez gate;
   digest místo obsahu v auditu; atomicita zápisu Kilo configu; záloha před zápisem.
3. **Každé tvrzení musí být `[OVĚŘENO]` s `file:line` a vlastním během, nebo `[NEOVĚŘENO]`.**
   Změna oproti minulému pokusu: dvě položky nesmějí zůstat `[UNVERIFIED]` s vysvětlením.
4. **Nález k ověření, ne k přijetí:** handoff §6 tvrdí, že `router.py:469`
   (`_route_round_robin`) a `router.py:418` (`_route_local_first`) nemají `free_only`.
   Čtením kódu je to **vyvráceno** — `route()` filtruje kandidáty před výběrem strategie
   (`router.py:192`). Oba agentovy nálezy byly chybné. Auditor to musí umět vyvrátit,
   ne přijmout.
5. **Mutace jako podklad, ne jako zadání:** výstup 24 mutací z `mutation_check_f4.py`
   uložit do `.kilo/context/state/` jako artefakt. `STRUKTURAL_NOTE` patří do
   verdiktu: **M23/M24 detekovatelné nejsou** — to je výsledek, ne chyba.
6. **Slovník verdiktu:** `PASS` / `FAIL` / `REJECT_UNVERIFIED`. `REJECT_UNVERIFIED`
   platí, pokud auditor neprovede kontrolu, která je k dispozici, nebo prohlásí věc
   neověřenou místo ověření.
7. Verdikt zapsat do `.kilo/context/handoff/` a do nového handoffu pro další vlákno.

### K4 — `mutation_check_f4.py` (rozhodnutí bez dotazu)
**Doporučení: přesunout do `scripts/f4-mutation-check.py`, nechat jako nástroj.**
Argument: `pytest` ho nesbírá, takže jako pytest test by 10–24× prodloužil build
a Gate 3 by potřeboval flag. Ale po Gate 3 ho mazat nelze — pravidlo „test, který umí
umřít, je jediný důkaz, že test něco chrání" platí dál. Krok K1 commituje nástroj
v kořeni; přesun je samostatný, malý a lze ho udělat po Gate 3.

---

## 4. Co zůstává otevřené — mimo tento plán

| Bod | Proč mimo | Kam patří |
|---|---|---|
| `destination=""` (`model_egress.py:72`) | Bezpečnostní nález v `execution_plane`, mimo F4 scope | F3 — zapsat do plánu, ne opravovat tady |
| `RoleAssignmentStore` / `KiloConfigBuilder` nezapojené | Knihovní třídy bez volajícího, ne mrtvý kód; zapojení = nová aplikační cesta | F4 doplnění, samostatný krok |
| Tiché přesměrování `route(model_id="paid-b", free_only=True) → free-a` | Fail-closed, ale volající neví | F4 — zvážit zda má být výjimka místo fallbacku |
| Registrace pluginu v `.kilo/kilo.jsonc` | Zápis vyžaduje výslovný souhlas vlastníka | Připravit diff, neaplikovat |
| `pyproject.toml:8` liché od `README` | `pyproject.toml` je v chráněném seznamu | Vyžaduje souhlas |
| Zákaznická discovery (0 rozhovorů) | Vyžaduje vlastníkův outreach | F5 Gate, nejvyšší obchodní blokáda |

---

## 5. Rizika

| Riziko | Způsob odezvy |
|---|---|
| Gate 1 nesouhlasí s handoffem (691/74) | Zapsat skutečné čísla, handoff neopravovat mlčky |
| Zásah do policy testů oslabí Gate 0 | `test_detector_rejects_bash_allow` se nesmí měnit; celá policy suite, ne jeden test |
| Agent si doplní oprávnění do charty | K2.5 mění text agenta, ne jen hodnotu |
| Mutace M23/M24 vyjdou jako „pokryto" | `STRUCTURAL_NOTE` je součástí verdiktu |
| Gate 3 skončí jako minule | Slovník `REJECT_UNVERIFIED` + zákaz `[UNVERIFIED]` místo ověření |
| Po změně `bash` přestane být kdo bezpečný | Globální `deny` zůstává; výjimka je úzká a evidovaná |

---

## 6. Validace po každém kroku

```bash
cd /home/oem/CyberBrain26-v4
PYTHONPATH=src python3 -m pytest -q                    # po K1 i po K2
python3 -m ruff check .
PYTHONPATH=src python3 -m mypy src/cyberbrain26
python3 -m pytest tests/test_kilo_agent_policy.py -q   # po K2 povinně celý soubor
python3 -m pytest tests/test_f4_model_intelligence.py -q
```

Gate 1 z handoffu je zelená — **nezahajovat ji znovu bez důvodu**. V tomto plánu je důvodem
každý krok, který mění kód nebo policy.

---

## 7. Podmínka návratu

Nic z §4 se neřeší, dokud Gate 3 pro F4 nemá verdikt.
Gate 3 je v tomto repu provedeno poprvé za existenci projektu — a to je věc, kterou je
nutné v handoffu napsat nahlas, ne zmínit v poznámce.