Round 7 adversarial audit (через superpowers:brainstorming skill) выявил 13 классов которые 9 предыдущих раундов не покрывали: - 2 FATAL: F5 Read-leak parent_random_id через Glob+Read (R-NEW-4 обнулён), F6 subagent tool_result.content exfil - 4 CRITICAL: C12 system DNS/config (/etc/hosts/~/.ssh/registry) вне §3.1, C13 || true exit-code spoof (per-token vs per-chain), C14 subagent state exfil, C15 §5.2 multi-language gap (PHP/Ruby/Go test runners) - 5 SERIOUS: S22 Skill(claude-md-management) exemption backdoor, S23 Workflow args parameter payload, S24 path-equivalence (Unicode NFC/NFD + Windows 8.3 + hardlinks), S25 MCP filesystem/redis write tools classification, S26 stop-keywords morphology gaps - 2 EDGE: E31 gate-error reason disclosure (probing pattern), E32 LLM-judge cache cross-session persistence 18 spec edits: header bump + TL;DR + Changes v3.8→v3.9 table + §3.1 system paths + parent-sentinel→restricted + §3.4 PostToolUse Task scanner + §3.6.2 normative-content second-layer gate + §4.5 stop-keywords expanded + §4.7 cache per-session + §5 MCP classification + §5.1 chain ANY-mutating + PostToolUse rev-parse verify + §5.1.2 PowerShell mirror + §5.2 multi-language scan + §6.3 redacted reason mode + §9 13 closures + §10.2 gate-config v3.9 fields + §11 v3.9 history entry. Spec: 2554 → 2964 строк (+410 lines). Budget: 45-60h (v3.8) → 53-72h (v3.9). Закрыто 118 holes total через 10 раундов adversarial audit. cspell-words.txt +18 терминов (exfiltration/exfil/NFD/RCE/syscall/Inodes/PROGRA/ resolv/nsswitch/ics/HKCU/HKLM/fsutil/unstar/mvn/popen/брэйншторм/стопаем). Generalisable formula R7 (новая): для каждого следующего audit задавать 3 вопроса до enumeration — какие safe tools/paths/chains дают visibility/leverage; какие границы scope подразумеваются но не enforce'ятся; где per-token vs per-chain formulation gap есть в композиции. §0 cross-refs не меняются — spec-only, не tooling-канон / не ADR / не off-phase подкатегория. Methodology: superpowers:brainstorming skill + AskUserQuestion scope choice (user выбрал «Полное v3.9 closure всех 13»). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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 anoutcomethat isunknownat write time (refined by/brain-retro). On an internal hook failure a minimalobserver_errormarker line is written instead of a silent skip. Written bytools/observer-stop-hook.mjsviatools/observer-transcript-parser.mjs.notes/YYYY-MM-DD-<slug>.md— optional MD notes for sessions with qualitative history.STATUS.md— auto-generated dashboard. Regenerated per-commit bytools/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 — Карта / Разбор / Лента / Агрегат). Runnpm run brain:dashboard, open the printed localhost URL.dashboard-core.jsis pure logic, unit-tested intools/brain-dashboard-core.test.mjs.
Lifecycle
- Write: every Stop-event appends one JSONL line, parsed from the session transcript (Stop-hook).
- Aggregate:
/brain-retroskill reads JSONL each sprint, proposes regulatory candidates. - Surface:
STATUS.mdshows controllers + monthly stats. - 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:
<!-- routing: provenance=user_directed_method node=<chosen> counterfactual=<node Claude would have chosen autonomously> -->
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-*.jsonlmanually — it's append-only. - Don't write outside
docs/observer/notes/for hand-curated notes. - Don't change
.read-counter.jsonmanually — 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.jsonalready 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.