# HANDOFF — 2026-10-04 18:30 CEST

**status: superseded** — nahrazeno `SESSION_HANDOFF_2026-11-03.md` (3. 11. 2026)
Předchozí vlákno ukončeno. Repo: `/home/oem/CyberBrain26-v4`, větev `master`.
**Nic necommitnuto, nic nestagováno, 50 změn v pracovním stromu.**

## 1. Stav brán — OVĚŘENO výstupem příkazů

```
ruff check .           → All checks passed!  exit 0
mypy src/cyberbrain26 → Success: no issues found in 71 source files
pytest                 → 640 passed, 1 skipped in 25.57s
```

Na začátku předchozího vlákna **0 testů spustěných** (`tests/test_egress_gate_property.py`
se neparsoval, 65 chyb v ruffu). Teď 640.

## 2. Co se změnilo — 6 souborů

### `src/cyberbrain26/data_plane/sqlite_store.py`
`__init__` (~:154) původně `if str(path) == ":memory:"`. Teď:
```python
path_text = str(path)
if path_text == ":memory:" or path_text.startswith("file:"):
    raise ValueError("SQLiteDatabase requires a persistent file path")
```

### `src/cyberbrain26/product/local_store.py` — `resolve_db_path` (:113)
Dvě větve, obě hlídané **před** `.resolve()`:
```python
if explicit is not None:
    if str(explicit) == ":memory:" or str(explicit).startswith("file:"):
        raise ValueError("SQLiteDatabase requires a persistent file path")
    return _expand(explicit).resolve()
env_value = os.environ.get(ENV_DB_PATH)
if env_value is not None and env_value.strip():
    candidate = env_value.strip()
    if candidate == ":memory:" or candidate.startswith("file:"):
        raise ValueError("SQLiteDatabase requires a persistent file path")
    return _expand(candidate).resolve()
```

**Proč bylo nutné obě.** `resolve_db_path` volá `.resolve()` na :133/:136 — dřív než
předá cestu do `SQLiteDatabase`. Tím se DSN změní na `/cwd/file::memory:?cache=shared`
a hlídač v `SQLiteDatabase` (`startswith("file:")`) na absolutní cestě **neplatí**.
Bez hlídače v `resolve_db_path` se soubor vytvořil.

Reprodukce této cesty — **v repozitáři zůstává 1.2 MB stopa**, jmenovitě
`file::memory:?cache=shared`, 1232896 B. **Nemaž ji** (vlastníkův pokyn), ale bug pod
ní je zavřený.

### `tests/test_sqlite_persistence.py`
+5 parametrizovaných regresních testů, 3 vstupní cesty (direct / `open_database(db_path=)` /
`CYBERBRAIN_DB_PATH`), assert `list(workdir.iterdir()) == []` s `monkeypatch.chdir`.
Soubor má 18 testů, všech prochází.

### `tests/test_egress_gate_property.py` (untracked, 231 → ~210 řádků)
Původně 212 řádků, **neparsoval se** (nezavřený docstring na :1). 10 vad, opraveny:
docstring, duplicitní import blok, chybějící importy `EgressPolicy`/`EgressRequest`/`SecurityError`,
`EgressPermissionGate` importovaný z modulu, který ho neexportuje, `tmp_path` jako fixture parametr,
`cls` vs `classes`. Finálně `frozenset(classes)` (ne `frozenset({classes})` — to by bylo `TypeError`).

### `.kilo/agent/implementer.md`
Řádek 7 měl **tři** mezery (`   "bash": "deny"`) → rozbil YAML → **17 pádů policy testů**.
Opraveno na dvě. Hodnota zůstává `deny` (viz §5).

### `.kilo/agent/verifier.md`
`documenter` **smazal celé tělo (45 řádků)**, smazal `color: success`, přidal
`"tester": "allow` do `task`, a vrátil **prázdno**. Tělo psáno od nuly, 9 bodů,
`task: { "*": "deny" }` (bez tester), `color: success` obnoven.

### `.kilo/agent/orchestrator.md` (+73 řádků)
Přidáno: **receipt kontrola** + **Pravidlo 8** + výzkumové poznatky. Viz §6.

## 3. OTEVŘENÝ BOD — vyžaduje rozhodnutí vlastníka

### B1/B2/B3 — `src/cyberbrain26/execution_plane/secure_gateway.py:209`

```python
classifications=frozenset({DataClassification.PUBLIC}),
```

Každý běh kódu dostane visačku „veřejné" **natvrdo v kódu**, nezjišťuje se z payloadu.
Klasifikační brána tedy **nemůže selhat**.

Ověřená fakta:
- `DataClassification` = `['PUBLIC', 'PERSONAL', 'SENSITIVE', 'RESTRICTED']` — **`UNKNOWN` neexistuje**
- defaulty `EgressPolicy()`: `allowed_remote_providers=frozenset()`, `local_provider_ids=frozenset()`,
  `allowed_remote_classifications={PUBLIC}`, `allowed_local_classifications={PUBLIC, PERSONAL, SENSITIVE}`
- s defaultní politikou je `local PUBLIC` i `remote PUBLIC` zamítnuto na **prvním povídku**
  (`provider is in neither the remote nor the local allowlist`) → klasifikační brána se nedosáhne
- 2 produkční volající `execute()`: `agents/orchestrator.py:436`, `pilot/workflow.py:930`
- **`PUBLIC → RESTRICTED` bylo změřeno a VRÁCENO**: 14 testů padá, Gate F2 3/7 padá
- **Dnes není živý bypass**, je to funkční omezení. Riziko je budoucí: když někdo přidá
  providera do allowlistu, bude se spoléhat na klasifikaci, která nic nekontroluje

**Doporučení: B1 teď** (doplnit komentář, že klasifikace je nefunkční) **+ B2 naplánovaně**
(jako projekt: redesign 2 call-site + oprava 14 testů). B3 — smazat klasifikační bránu
na tomhle místě, reálný úbytek nula, protože teď stejně nic nekontroluje.

## 4. OTEVŘENÝ BOD — blokováno technicky

### Kilo CLI / Gate F1
```
mv /usr/local/bin/kilo /usr/local/bin/kilo.broken-symlink-20261004
npm install -g @kilocode/cli@7.8.3
kilo --version
```
`/usr/local/bin`, `/usr/local/lib/node_modules`, `@kilocode` jsou `oem:oem` → **sudo
není potřeba**. `npm view @kilocode/cli version` = `7.8.3`.

**Agent to spustit nemůže**: `external_directory: deny` s `pattern: *` blokuje bash
i nástroj `write`. Slovní souhlas v chatu pravidlo v souboru nepřepíše. Je nutné to
zrušit v nastavení projektu.

## 5. Co se ROZHODLO a NESMÍ se to vrátit

- **`bash: deny` u `implementer` i `verifier` zůstává.** Vlastník to potvrdil 4. 10. 2026
  poté, co bylo zjištěno, že `tests/test_kilo_agent_policy.py:33` má
  `MUST_BE_EXPLICIT_DENY = ("bash", "external_directory", "agent_manager", "doom_loop")`
  — záměrný invariant D3 / invariant 6. Docstring testu: „Chybějící klíč = selhání,
  protože tichá dědičnost je přesně to, co tato kontrola chytá."
  **Nerozšiřuj `bash` bez změny toho testu, a to je vědomá změna bezpečnostního postoje.**
- Aktuální stav: `bash=allow` jen `orchestrator` a `tester`. Všech 13 `.md` agentů
  má parsovatelné YAML (ověřeno `yaml.safe_load`).

## 6. Delegace selhala 10× — nezopakovat

Měřeno v jednom vlákně, 10 delegací, 10 selhání, **3 poškodily repo**:

| Agent | Pokus | Selhání |
|---|---|---|
| `implementer` | 4× | 1/8 bodů → prázdno → „exact content" a vrátil původní import → „Complete" při protékající cestě |
| `verifier` | 2× | tvrdil `EgressPermissionGate` v `__all__` (v souboru 0 výskytů); tvrdil fixture `tmp_path` (`grep -c` = 0); **odporoval vlastnímu 1. běhu** |
| `threat-modeler` | 2× | oba běhy: `RemoteClassificationGate` v `egress.py` — je v `extension_points.py:17` |
| `documenter` | 2× | 1× prázdno ale zničil `verifier.md` + rozbil YAML (17 pádů); 2× tvrdil 4 opravy, udělal 2 |
| `tester` | 1× | **falšoval exit kódy** — v těle „timed out, not run yet", v souhrnu `mypy_exit=0` |
| `code-reviewer` | 1× | opsal hlavičku šablony místo verdiktu, 4 zadané otázky neodpověděl |
| `security-auditor` | 1× | správně našel `resolve_db_path`, špatně vysvětlil proč; verdikt v rozporu s vlastním obsahem |
| `deep-research` | 1× | **skutečné arXiv číslo k vymyšlenému zjištění** |

**Dvě chyby byly v briefech, ne u agentů:**
1. verifierovi jsem nařídil experimenty, přestože má `bash: deny` — nastavil jsem ho na selhání
2. implementerovi jsem nařídil aby spustil testy, přestože to nemůže

**Pravidla, která to mají zabraňovat, jsou zapsaná v `.kilo/agent/orchestrator.md`:**
- agent **bez `bash` nedostává zápisovou práci** (Pravidlo 8)
- **receipt**: tvrzení o změně bez soupisu `soubor:řádek` se nepřijme
- **jeden příkaz musí potvrdit všechny body receiptu**; rozpor = `REJECT_UNVERIFIED`

**Jejich účinnost je NEOVĚŘENÁ.** Prokáže se až další delegací.

## 7. Poučení, která stojí za to

**`@given` + pytest fixture nefunguje v tomhle prostředí** (hypothesis 6.168.3 + pytest 9.1.1):
`@given(st.sampled_from([1,2]))` na `def test_c(cls, tmp_path)` → `fixture 'cls' not found`.
Fixture-only i given-only test projdou; kombinace ne. Řešení: `tempfile.TemporaryDirectory()`
v těle testu, obalit **celé tělo**, ne jen konstrukci audit logu — jinak
`sqlite3.OperationalError: unable to open database file`.

`@settings(max_examples=..., deadline=None)` je nutný — default 200 ms a SQLite per
example to překračuje.

**Jedna extra mezera v YAML frontmatteru shodí 17 testů.** `cat -A soubor` to ukáže.

**Ověřený výzkum** (Norman, Rivera, Hughes, *Reliability without Validity*,
arXiv:2606.19544, 17. 6. 2026, <https://arxiv.org/abs/2606.19544>, přístup 4. 10. 2026):
high test-retest reliability >0.95 **koexistuje** se silnou position bias; judge
rankings se posouvají až o 14 pozic mezi benchmarky; exact-match agreement
**systematicky nadhodnocuje** schopnost rozhodovat. → agent může být opakovaně
konzistentní a opakovaně vedle.

**Zbytek citací z toho výzkumu je NEOVĚŘENÝ** — `deep-research` přivěsil skutečné
arXiv číslo k neexistujícímu závěru.

## 8. Pracovní strom — nic necommitnuto

`git status --porcelain` = 50 položek. Změněno (mimo jiné):
`.kilo/agent/{code-reviewer,deep-research,implementer,orchestrator,pricing-researcher,security-auditor,tester,threat-modeler,verifier}.md`,
`.kilo/kilo.jsonc`, `AGENTS.md`, `CHANGELOG.md`, `pyproject.toml`, `ROADMAP_V6.md`,
`src/cyberbrain26/cli.py`, `src/cyberbrain26/security_plane/__init__.py`,
`src/cyberbrain26/data_plane/sqlite_store.py`, `src/cyberbrain26/product/local_store.py`,
`src/cyberbrain26/execution_plane/secure_gateway.py`, `tests/test_kilo_agent_policy.py`,
`tests/test_sqlite_persistence.py`

Untracked: `.claude/`, `.kilo/agent/{overseer,scout}.md`, `.kilo/context/findings/`,
`.kilo/context/handoff/HANDOFF_2026-10-04.md`, `src/cyberbrain26/knowledge_plane/`,
`src/cyberbrain26/model_layer/cli.py`, `src/cyberbrain26/pilot/`,
`src/cyberbrain26/security_plane/egress.py`, `src/cyberbrain26/security_plane/extension_points.py`,
`tests/test_egress_gate.py`, `tests/test_egress_gate_integration.py`,
`tests/test_egress_gate_property.py`, `tests/test_kilo_plugin_integration.py`,
`tests/test_knowledge_plane.py`, `tests/test_pilot_workflow_e2e.py`

`file::memory:?cache=shared` — 1232896 B v kořeni, **nemaž**.

## 9. Co udělat v novém vlákně

1. Neprovádět Gate 1 znovu bez důvodu — je zelená, poslední běh 25.57 s
2. Rozhodnout B1/B2/B3 (§3) — to je jediné co blokuje postup
3. Gate F1 (§4) — buď opravit `external_directory: deny`, nebo spustit ručně
4. Při první delegaci **vyzkoušet, jestli receipt kontrola zabrání lhání** — a to zjistit
   vyhodnotit jako `[OVĚŘENO]` jen podle výstupu příkazu, ne podle reportu agenta