Skip to content

Commit cf065e9

Browse files
authored
Merge pull request #10 from SolidKeyAB/feat/format-adapters
Docs: guided triage spec (symptom-first root-cause recipes)
2 parents 4b55f00 + 49932d6 commit cf065e9

1 file changed

Lines changed: 113 additions & 0 deletions

File tree

docs/TRIAGE_GUIDE.md

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Guided Triage — Root-Cause Finding in LOGAN
2+
3+
## Goal
4+
5+
Give a user who is *not* a log expert a fast path from **symptom** to **root cause**.
6+
Instead of staring at a raw file, they answer a few templated questions and LOGAN runs
7+
a *recipe* — a fixed combination of the primitives it already has (search, filter,
8+
highlight, time-gaps, trends, baseline, pin-as-finding) — and pins clickable findings.
9+
10+
## Design principle: symptom-first, domain second
11+
12+
Users reliably know the **symptom** ("it crashed", "it's slow"). They do *not* always
13+
know the **domain** (Android vs. embedded vs. backend). So:
14+
15+
- **Symptom is the front door** — a small menu of universal failure modes.
16+
- **Domain is a *pack*** that sits underneath and only swaps the keyword/field
17+
dictionaries each recipe uses (e.g. what "crash" looks like in logcat vs. serial).
18+
- Domain is **auto-detected** from log content, with a manual override.
19+
20+
```
21+
User → [Symptom menu] → recipe runs → findings pinned → [drill-down: 3 next moves]
22+
23+
[Domain pack] supplies the keywords/fields the recipe searches for
24+
```
25+
26+
This beats a pure domain menu because symptoms generalize and domains don't, and it
27+
beats a flat search box because the user doesn't have to know *what* to search for.
28+
29+
---
30+
31+
## The symptom menu (8 recipes)
32+
33+
Each recipe is a one-tap action. "Primitives" lists the existing LOGAN/MCP tools it
34+
chains. Every recipe ends by pinning results via `logan_report_finding` so they are
35+
clickable in the viewer.
36+
37+
| # | Symptom (button) | What the recipe does | Primitives used |
38+
|---|-------------------------|--------------------------------------------------------------------------------------|-----------------|
39+
| 1 | **It crashed / died** | Find fatal/exception/stack-trace markers; jump to the **last line before death**; pin the 50 lines before it as context. | `logan_investigate_crashes`, `logan_search`, `logan_get_lines`, `logan_report_finding` |
40+
| 2 | **It froze / hung** | Rank **time gaps**; surface the last log line before the silence; flag stuck/repeating loops. | `logan_time_gaps`, `logan_get_lines`, `logan_search` |
41+
| 3 | **It's slow** | Trend duration/latency fields over time; list slowest operations; flag timeout/GC spikes. | `logan_trend_fields`, `logan_trend_series`, `logan_search` |
42+
| 4 | **Error storm** | Plot error-rate over time and find the **spike**; show the **first occurrence** of each unique error; group by component. | `logan_analyze`, `logan_trend_series`, `logan_search` |
43+
| 5 | **Won't start** | Walk the startup sequence; surface config / port-bind / permission / missing-dependency errors. | `logan_search`, `logan_get_lines`, `logan_analyze` |
44+
| 6 | **Connection drops** | Find disconnect/reconnect/retry/timeout events; correlate by endpoint/peer. | `logan_search`, `logan_trend_correlate`, `logan_trend_transitions` |
45+
| 7 | **Intermittent / flaky**| Detect what **flipped** (`transitions`); correlate event-presence vs. a state field. | `logan_trend_transitions`, `logan_trend_correlate` |
46+
| 8 | **Wrong / odd value** | Trend the suspect field; find **where it changed**; correlate with surrounding events. | `logan_trend_series`, `logan_trend_transitions`, `logan_trend_correlate` |
47+
48+
---
49+
50+
## Templated guiding questions (narrowing)
51+
52+
After a symptom is picked, LOGAN asks at most 2–3 of these to narrow the recipe.
53+
All are optional — an unanswered question falls back to an auto-detect default.
54+
55+
| Question | Options / input | Effect on the recipe |
56+
|-----------------------------------|---------------------------------------|--------------------------------------------------------------|
57+
| **When did you first notice it?** | timestamp · "around line N" · *don't know* | Sets the focus window. *Don't know* → auto-jump to first error. |
58+
| **Which component / module?** | dropdown auto-filled from discovered components | Filters every search to that component. |
59+
| **Got a known-good run?** | pick a saved baseline · no | Switches the recipe to a **baseline compare** (diff vs. good). |
60+
| **One-off or repeating?** | once · keeps happening | Repeating → prefer `transitions`/`correlate` over single-hit search. |
61+
62+
---
63+
64+
## The drill-down (5-Whys)
65+
66+
After the first finding, *always* offer the same three next moves. This is what turns a
67+
single hit into a root cause:
68+
69+
1. **What happened right BEFORE this?** → pin the preceding N lines / last state change.
70+
2. **What else fired at the SAME time?** → correlate events in the same time bucket.
71+
3. **Has this happened before in the file?** → all earlier occurrences + first one.
72+
73+
Each move re-pins findings and pushes a breadcrumb so the user can step back.
74+
75+
---
76+
77+
## Domain packs
78+
79+
A pack is just a dictionary swapped in behind the recipes — same recipes, different
80+
vocabulary. Detected from log content; user-overridable.
81+
82+
| Pack | "Crash" markers (ex.) | Latency field (ex.) | Notes |
83+
|-----------------|----------------------------------------|---------------------|-------|
84+
| **Generic** | `FATAL`, `exception`, `panic`, `core dumped`, stack frames | `duration`, `elapsed`, `ms` | default fallback |
85+
| **Android/logcat** | `FATAL EXCEPTION`, `ANR`, `signal 11`, `tombstone` | `Displayed`, `Choreographer` skipped frames | level column, tags |
86+
| **Embedded/serial** | `HardFault`, `assert`, `watchdog`, `reset` | tick counters | no timestamps common → use line order |
87+
| **Web/backend** | `5xx`, `traceback`, `OOMKilled`, `segfault` | `latency_ms`, `rt`, `took` | request-id correlation |
88+
| **Automotive/MF4** | signal threshold breaches | numeric signal channels | routes through the Trends/signal engine |
89+
90+
---
91+
92+
## UX surface
93+
94+
- **Entry point:** an "Investigate / Guide me" panel in the activity bar (or extend the
95+
existing `logan_triage` flow).
96+
- **Breadcrumb:** the investigation path with a **Back** button.
97+
- **Findings:** every recipe step pins a clickable annotation (existing finding system).
98+
- **Free-text box:** a plain-English question that the AI agent maps onto a recipe — the
99+
escape hatch for anything the 8 buttons don't cover.
100+
101+
---
102+
103+
## Build order (recommended)
104+
105+
1. **This spec** — symptom → recipe table (done).
106+
2. Recipe engine: a small map of `symptom → ordered list of primitive calls`, reusing
107+
the existing MCP tools; output always pinned as findings.
108+
3. The panel UI (symptom buttons + guiding questions + breadcrumb).
109+
4. Domain-pack dictionaries + auto-detection.
110+
5. NL→recipe box on top of the agent.
111+
112+
Recipes are pure composition of primitives that already exist, so step 2 needs no new
113+
analysis engine — only wiring + a keyword/field dictionary per pack.

0 commit comments

Comments
 (0)