# Observer infrastructure Passive evidence-loop for the Лидерра «brain» per ADR-011. ## Files - `episodes-YYYY-MM.jsonl` — append-only JSONL, one line per Stop-event. Schema **v2** (`schema_version: 2`): the 5 mandatory fields + `decision_provenance` (who chose the node), `environment` (economy_level / model / post_compaction / session_turn / parallel_session), `task_size`, `task_ref`, `prompt_signal`, and an `outcome` that is `unknown` at write time (refined by `/brain-retro`). On an internal hook failure a minimal `observer_error` marker line is written instead of a silent skip. Written by `tools/observer-stop-hook.mjs` via `tools/observer-transcript-parser.mjs`. - `notes/YYYY-MM-DD-.md` — optional MD notes for sessions with qualitative history. - `STATUS.md` — auto-generated dashboard. Regenerated per-commit by `tools/status-md-generator.mjs`. - `.read-counter.json` — C3 observer-of-observer counter. Updated on Read of observer files. - `dashboard.html` + `dashboard.js` + `dashboard-core.js` — Brain Dashboard: visualises the episode log over the automation-graph topology (4 views — Карта / Разбор / Лента / Агрегат). Run `npm run brain:dashboard`, open the printed localhost URL. `dashboard-core.js` is pure logic, unit-tested in `tools/brain-dashboard-core.test.mjs`. ## Lifecycle 1. **Write**: every Stop-event appends one JSONL line, parsed from the session transcript (Stop-hook). 2. **Aggregate**: `/brain-retro` skill reads JSONL each sprint, proposes regulatory candidates. 3. **Surface**: `STATUS.md` shows controllers + monthly stats. 4. **Self-prune**: C3 warns if 54 weeks pass without any read of observer files. ## Routing-tag discipline When the user dictates a specific method/node (e.g. «запусти discovery-interview»), Claude must emit one line in its response: ``` ``` The Stop-hook routing-gate (`tools/observer-routing-detector.mjs` + `routingGateDecision`) detects a dictated method; if the tag is missing it returns `decision: block`, so the turn cannot end without the tag. The gate fires at most once per turn (`stop_hook_active` guard). This makes `decision_provenance` reliable — factor analysis can separate a router error from a user-dictated one. ## Privacy PII filter (phone numbers, emails, tokens) is applied **before** every write — see `tools/observer-pii-filter.mjs`. gitleaks pre-push also scans observer files as part of full-history sweep. ## Don't - Don't edit `episodes-*.jsonl` manually — it's append-only. - Don't write outside `docs/observer/notes/` for hand-curated notes. - Don't change `.read-counter.json` manually — it's maintained by hooks. ## HK1 pre-check (Pravila ADR-010) — verified 2026-05-19 Before registering `tools/observer-stop-hook.mjs` on Stop event (Task B5), verified collision against 6-component economy/skill-discipline architecture: - **User-level** `~/.claude/settings.json` already has Stop hook: **agent-type** Sonnet-4.6 economy compliance verifier (analyzes transcript for claim-without-evidence violations). - **Project-level** `.claude/settings.json` — Stop slot empty. **Result**: no overwrite. observer-stop-hook will be added as **command-type entry in project-level Stop array**. Project + user scopes are independent slots in Claude Code 2.x — both run on the same Stop event without conflict. The agent verifier (user scope) and the JSONL appender (project scope) have non-overlapping responsibilities.