- routes/sessions.ts: createSessionsAnalysisRouter com GET /patterns (filtros
week/severity/key/days, paginado, Zod) e GET /stats (agregados: sessões
totais e por dia, by_source, by_outcome, tool_top, skill_top,
patterns_by_type, gate_blocks, avg_duration_sec, last_indexed_at,
latest_pattern_week); montado em /api/sessions (C4) e /api (alias F4.1)
- services/sessions/db.ts: listPatterns/countPatterns/getStats +
rowToPattern/buildPatternsWhere; gate_blocks devolve null enquanto a
tabela gate_events não existir (F1 arco C3-gates)
- tests/sessions-analysis-route.test.ts: 15 testes (filtros, paginação,
validação, gate_blocks condicional, não-colisão com /:id)
- inclui camada session_events pendente de v2.7.3 (db.ts/indexer.ts —
storeSessionEvents no indexAll; rota /:id lê da BD) já em execução, para
a árvore commitada compilar coerente
Validado contra BD real (11459 sessões, 160 padrões): curl 200 com JSON
não-vazio em /api/patterns, /api/stats, /api/sessions/patterns?week=2026-W26,
/api/sessions/stats?days=7.
Sessões com outcome=interrupted e ≥10 eventos são redirects naturais
do utilizador, não falhas da skill. O detector contava todas as
interrupções como falhas, gerando falsos positivos para skills
conversacionais como superpowers:brainstorming.
Fix: só contar como falha erros reais (outcome=error) ou interrupções
precoces (<10 eventos).
Resolve ticket #10407.
Co-Authored-By: Claude Sonnet 4.6 <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>
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>