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.
This branch is already included in the target branch. There is nothing to merge.
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