feat(observabilidade): Espelho — MVP Session Replay #1

Open
ealmeida wants to merge 0 commits from feat/observabilidade-espelho into main
Owner

Observabilidade (Espelho) — MVP Session Replay

Primeiro sistema Descomplicar® que observa empiricamente o comportamento do Claude Code sessão a sessão. Fecha o ciclo PDCA para automações sérias.

Desk task: #2059 · Desk project: #65 · Hub: 05-Projectos/Observabilidade/

O que entrega

  • Painel /sessions no DashDescomplicar com lista filtrável (período, projecto, tool, skill, search) + timeline colapsável por sessão (user/assistant/tool_use/tool_result/system/attachment)
  • Indexer Node.js (api/scripts/sessions-indexer.ts) com modos --full (batch) e --watch (chokidar incremental)
  • SQLite local em ~/.claude-work/sessions.db (WAL + synchronous=NORMAL, upsertMany transaccional)
  • Rotas GET /api/sessions e GET /api/sessions/:id com validação Zod
  • systemd user service observabilidade-indexer.service para watcher permanente

Resultados empíricos

Fase Gate Resultado
Indexer+SQLite Full scan 1596 ficheiros 1603 indexados, 0 falhas, 8s
API Express /api/sessions?days=7 559 resultados, detalhe com 37 events
UI Lista Build + HTTP 200 0 TS errors, Vite dev OK
UI Timeline Detalhe funcional 4 filtros, anchors #evt-N
Watcher+systemd Service active + restart clean active (running), 1608 sessões via watcher

Qualidade

  • 14 testes (parser: 6, db: 5, routes: 3) — todos verdes
  • Two-stage review por task (spec compliance + code quality) via subagentes isolados
  • 4 bugs corrigidos em review: NaN em duration, outcome logic max_tokens, ENOENT→410 Gone, exit codes CLI
  • 2 melhorias não-planeadas: upsertMany transaccional (bulk), SIGTERM handler watcher

Princípios respeitados (SPEC §3)

  • Empírico antes de teórico (gate funcional obrigatório por fase)
  • Ver antes de medir (UI timeline é o artefacto central; sem classificação/alertas)
  • Read-only aos JSONL originais
  • Privacidade: tudo local, sem envio externo

Follow-ups documentados

Lista completa em Hub/05-Projectos/Observabilidade/research/padroes-observados.md:

  • UI: debounce search, row clickable inteira, endpoint /api/sessions/facets para filtros globais
  • Parser: parseSessionMeta lightweight variant para indexer
  • Watcher: substituir npx tsx por node --import tsx/esm (propagação SIGTERM)

Critério global pendente (semana 1 de uso)

  • Abrir 3 sessões diferentes em <10s cada
  • Registar 3 padrões concretos em padroes-observados.md
  • Escrever 1 automação informada pelos padrões

Só avançar para Fase 6+ (classificador, alertas, Langfuse) depois dos 3 padrões identificados.

Commits (15)

d2452d4 docs(observabilidade): v2.7.0 — Espelho MVP entregue
c590431 feat(observabilidade): systemd user service para watcher
80a5f3b feat(observabilidade): watcher chokidar incremental
8ca6b7e feat(observabilidade): UI timeline por sessão com filtros
eb781a8 feat(observabilidade): UI lista de sessões com filtros
b933b4c fix(observabilidade): close DB no SIGTERM e distinguir ENOENT/parse errors
e101577 feat(observabilidade): rota /api/sessions com validação Zod
7a13d21 fix(observabilidade): stub watcher sai limpo com exit 0 para Task 9 systemd
cdadc89 fix(observabilidade): indexer CLI sai com código 1 se failed>0
296819d feat(observabilidade): indexer full scan + CLI + stub watcher
3bfec24 perf(observabilidade): synchronous=NORMAL e upsertMany transaccional
a2ce1fa feat(observabilidade): wrapper SQLite com schema, upsert e filtros
bd954f4 fix(observabilidade): stream cleanup, outcome logic e NaN guard no parser
26b631b feat(observabilidade): parser JSONL com detecção de tool_calls e skills
17e5736 feat(observabilidade): setup dependências e tipos SessionMeta/SessionEvent
## Observabilidade (Espelho) — MVP Session Replay Primeiro sistema Descomplicar® que observa empiricamente o comportamento do Claude Code sessão a sessão. Fecha o ciclo PDCA para automações sérias. **Desk task:** #2059 · **Desk project:** #65 · **Hub:** `05-Projectos/Observabilidade/` ### O que entrega - Painel `/sessions` no DashDescomplicar com lista filtrável (período, projecto, tool, skill, search) + timeline colapsável por sessão (user/assistant/tool_use/tool_result/system/attachment) - Indexer Node.js (`api/scripts/sessions-indexer.ts`) com modos `--full` (batch) e `--watch` (chokidar incremental) - SQLite local em `~/.claude-work/sessions.db` (WAL + synchronous=NORMAL, upsertMany transaccional) - Rotas `GET /api/sessions` e `GET /api/sessions/:id` com validação Zod - systemd user service `observabilidade-indexer.service` para watcher permanente ### Resultados empíricos | Fase | Gate | Resultado | |---|---|---| | Indexer+SQLite | Full scan 1596 ficheiros | **1603 indexados, 0 falhas, 8s** | | API Express | `/api/sessions?days=7` | **559 resultados**, detalhe com 37 events | | UI Lista | Build + HTTP 200 | **0 TS errors**, Vite dev OK | | UI Timeline | Detalhe funcional | 4 filtros, anchors `#evt-N` | | Watcher+systemd | Service active + restart clean | **active (running)**, 1608 sessões via watcher | ### Qualidade - **14 testes** (parser: 6, db: 5, routes: 3) — todos verdes - **Two-stage review por task** (spec compliance + code quality) via subagentes isolados - **4 bugs corrigidos em review**: NaN em duration, outcome logic max_tokens, ENOENT→410 Gone, exit codes CLI - **2 melhorias não-planeadas**: `upsertMany` transaccional (bulk), SIGTERM handler watcher ### Princípios respeitados (SPEC §3) - ✅ Empírico antes de teórico (gate funcional obrigatório por fase) - ✅ Ver antes de medir (UI timeline é o artefacto central; sem classificação/alertas) - ✅ Read-only aos JSONL originais - ✅ Privacidade: tudo local, sem envio externo ### Follow-ups documentados Lista completa em `Hub/05-Projectos/Observabilidade/research/padroes-observados.md`: - UI: debounce search, row clickable inteira, endpoint `/api/sessions/facets` para filtros globais - Parser: `parseSessionMeta` lightweight variant para indexer - Watcher: substituir `npx tsx` por `node --import tsx/esm` (propagação SIGTERM) ### Critério global pendente (semana 1 de uso) - [ ] Abrir 3 sessões diferentes em <10s cada - [ ] Registar 3 padrões concretos em `padroes-observados.md` - [ ] Escrever 1 automação informada pelos padrões Só avançar para Fase 6+ (classificador, alertas, Langfuse) depois dos 3 padrões identificados. ### Commits (15) ``` d2452d4 docs(observabilidade): v2.7.0 — Espelho MVP entregue c590431 feat(observabilidade): systemd user service para watcher 80a5f3b feat(observabilidade): watcher chokidar incremental 8ca6b7e feat(observabilidade): UI timeline por sessão com filtros eb781a8 feat(observabilidade): UI lista de sessões com filtros b933b4c fix(observabilidade): close DB no SIGTERM e distinguir ENOENT/parse errors e101577 feat(observabilidade): rota /api/sessions com validação Zod 7a13d21 fix(observabilidade): stub watcher sai limpo com exit 0 para Task 9 systemd cdadc89 fix(observabilidade): indexer CLI sai com código 1 se failed>0 296819d feat(observabilidade): indexer full scan + CLI + stub watcher 3bfec24 perf(observabilidade): synchronous=NORMAL e upsertMany transaccional a2ce1fa feat(observabilidade): wrapper SQLite com schema, upsert e filtros bd954f4 fix(observabilidade): stream cleanup, outcome logic e NaN guard no parser 26b631b feat(observabilidade): parser JSONL com detecção de tool_calls e skills 17e5736 feat(observabilidade): setup dependências e tipos SessionMeta/SessionEvent ```
ealmeida added 15 commits 2026-04-23 02:00:18 +01:00
- Instala better-sqlite3 + chokidar + @types/better-sqlite3
- Upgrade googleapis 144 → 171 (resolve 4 vulns moderate em uuid/gaxios)
- Cria api/types/session.ts (SessionMeta, SessionEvent, ParseResult, SessionOutcome)
- Cria SPEC.md raiz com marker APPROVED a referenciar SPEC autoritativo no Hub
- Task 1 de 10 do plano Observabilidade (Espelho)
- Desk #2059, Projecto #65

Security Audit (Regra #47):
- npm audit --audit-level=moderate: 0 vulnerabilities
- Calendar API continua operacional (google.calendar v3 inalterada)
Task 5 do MVP Espelho: endpoint Express com factory createSessionsRouter(db)
que expõe GET / (lista filtrável por days/project/tool/skill/q + limit/offset
validados via Zod) e GET /:id (meta + eventos via parseSessionFile). Integrado
em server.ts com DB aberta a partir de OBSERVABILIDADE_DB ?? DEFAULT_DB_PATH.

Validação empírica: total=559 sessões (últimos 7d), detalhe com 37 eventos.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Cria unit file para correr sessions-indexer em --watch permanente.
Inclui KillMode=mixed + TimeoutStopSec=10s + Restart=on-failure
para graceful shutdown do watcher+DB.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ealmeida added 1 commit 2026-04-23 02:02:00 +01:00
ealmeida added 4 commits 2026-04-23 02:17:53 +01:00
Adiciona tabela 'patterns' à BD sessions (UNIQUE por week_iso+pattern_key)
e helpers upsertPattern/getPatternsByWeek/getConsecutiveWeeks no SessionsDb.

Módulo patterns.ts implementa 6 detectores heurísticos para deteccão semanal:
  1. skills_with_high_error_rate (ratio > 0.2, severity warning|action)
  2. tools_low_efficiency (tool_calls/event_count médio > 0.5)
  3. skill_tool_pairs (top 5 co-ocorrências)
  4. duration_outliers (sessões > p95 com outcome != completed)
  5. abandoned_sessions (event_count<3 AND outcome=unknown, >=5)
  6. growing_complexity (avg tool_calls actual > anterior*1.3)

5 testes cobrem detector de erro, abandonadas, consecutive_weeks,
idempotência do upsert e toPatternRecord.

Refs Fase 6A · Desk #2059 · Project #65

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Script CLI api/scripts/sessions-patterns.ts com args --week, --publish, --force.
Default: semana actual, dry-run (render HTML stderr + JSON summary stdout).

Com --publish:
  - POST html comentário para /api/v1/discussions/32/comments (Desk)
  - Para padrões com consecutive_weeks>=3 e severity warning|action: auto-abre
    TICKET via /api/v1/tickets (priority 3|4 conforme severity)

Pipeline interno: detectPatterns -> upsertPattern placeholder -> computar
consecutive_weeks -> upsert final. Escape HTML defensivo; 5 sample ids por padrão.

Auth via DESK_API_TOKEN (env file), NUNCA hardcoded.

Refs Fase 6A

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Units user:
  observabilidade-patterns.service (Type=oneshot, executa --publish)
  observabilidade-patterns.timer (OnCalendar=Sun 23:00, Persistent=true)

EnvironmentFile aponta para ~/.claude-work/observabilidade-patterns.env
(ficheiro privado, não commitado). Exemplo fornecido em .env.example.

Activação utilizador:
  cp systemd/observabilidade-patterns.{service,timer} ~/.config/systemd/user/
  cp systemd/observabilidade-patterns.env.example ~/.claude-work/observabilidade-patterns.env
  $EDITOR ~/.claude-work/observabilidade-patterns.env  # colocar DESK_API_TOKEN
  systemctl --user daemon-reload
  systemctl --user enable --now observabilidade-patterns.timer

Refs Fase 6A

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ealmeida added 1 commit 2026-04-23 02:20:55 +01:00
Antes: skills_invoked vazio em 1608/1608 sessões porque detectSkillInvoked
apenas era aplicado ao text extraído de content[type=text]. A string
'Launching skill: X' vive dentro de tool_result.content (string ou array
de text blocks), que era ignorada.

Fix: adicionar helper extractResultText(r) que trata ambos os casos e
aplicar detectSkillInvoked + detectHook também ao tool_result. Após
re-indexação full, 526/1616 sessões têm agora skills detectadas e o
detector de padrões devolve 6 padrões (vs 2 baseline), incluindo
skills_with_high_error_rate reais.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ealmeida added 1 commit 2026-04-23 02:27:25 +01:00
Substitui chamadas HTTP directas à API Desk (/api/v1/discussions, /api/v1/tickets)
por JSON-RPC 2.0 ao gateway MCP (desk-crm). Helper callMcpTool lida com respostas
JSON ou SSE. Substitui DESK_API_TOKEN/DESK_BASE_URL por MCP_GATEWAY_TOKEN/URL.

- add_discussion_comment: discussion_id=32, staff_id=25 (Observabilidade)
- create_ticket: subject/message/priority(1-4)/department=1

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ealmeida added 1 commit 2026-04-23 02:34:24 +01:00
Itera semanas ISO desde a primeira sessão até (excluindo) a semana corrente,
detectando padrões e fazendo upsert com consecutive_weeks acumulado. Nunca
publica comentários nem abre tickets — apenas povoa a tabela patterns com
histórico. Output JSON por semana e sumário final.

Permite popular retroactivamente a tabela patterns após nova instalação ou
reset, dando base imediata ao detector de padrões persistentes.
ealmeida added 5 commits 2026-04-23 03:07:44 +01:00
- Schema worklog_comments (id, discussion, parent, datas, staff, campos parseados em JSON)
- Parser HTML tolerante (h2/h3/h4) extrai title, task_ref, duration, work_items,
  files_modified, problems, patterns_text, actions
- Módulo worklog-import com paginação MCP get_discussion_comments
- Helper mcp-client.ts partilhado (gateway MCP JSON-RPC + SSE)
- Dep runtime: node-html-parser

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Script CLI com args --discussion 31|32|33|all, --since-days N, --force
- Paginação via MCP gateway (limit 100, tree_view false)
- Output JSON-line progressivo + summary final
- Testes: parseWorklogHtml tolerante (h2/h3/h4), idempotência upsert

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- #7 actions_never_executed: acções P1/P2 em disc #33 há ≥14 dias pendentes
- #8 skill_narrative_vs_data: skill reportada problemática em worklogs
  mas com outcome=completed nas sessões (≥3 matches)
- #9 worklog_pattern_frequency: tokens recorrentes (≥3 worklogs) em patterns_text
- Integrados em detectPatterns() como secção opcional quando worklogs > 0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Service oneshot invoca sessions-worklog-import.ts --discussion all --since-days 7
- Timer OnCalendar=*-*-* 03:00:00 com Persistent=true (catch-up)
- EnvironmentFile reutiliza observabilidade-patterns.env (MCP_GATEWAY_TOKEN)
- Logs append em ~/.claude-work/observabilidade-worklog-import.log

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ealmeida added 1 commit 2026-04-23 03:45:56 +01:00
Quando um padrão atinge ≥3 semanas consecutivas com severity warning/action,
além de abrir ticket no Desk, propõe também como staging entry no
/media/ealmeida/Dados/.carl/carl.json para revisão e eventual promoção a
regra. Idempotente por pattern_key. Dry-run log-only.

Fecha o feedback loop Observabilidade → CARL identificado na análise do
sistema: padrões detectados empiricamente viram propostas de regras.
Checking for merge conflicts…
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin feat/observabilidade-espelho:feat/observabilidade-espelho
git checkout feat/observabilidade-espelho
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: ealmeida/DashDescomplicar#1