Analyze Session
Use the smallest authoritative evidence path that answers the question. For the
active session, start with a summary introspect overview (hint for a quick
check). Use reflect with a concrete causal question only when persisted
evidence is needed; its summary overview is the default. Reuse observations
already obtained within the relevant scope. Expand depth or facets only for a
specific evidence gap or an explicitly requested deep audit; discover the full
tool contract before using fields absent from the resident schema.
Use astra journal digest for a named past/offline session, exact aggregate
metrics, durable-event ordering, or a concrete gap reported by structured
observation. Raw JSONL parsing is a fallback only when the digest is unavailable
or missing a required field. Never estimate missing metrics or describe session
memory, assistant prose, or a prior answer as live runtime evidence.
Task
$ARGUMENTS
Phase 1: Choose The Evidence Boundary
For an ordinary retrospective of the active session, use the single composite
introspect and optional single composite reflect calls above. Stop observing
when they answer the user's question; repeated observation adds latency and can
create contradictory evidence.
Resolve and run a journal digest only if the user names a past session, requests exact persisted metrics/event order, or structured observation reports a concrete coverage gap:
command -v astra
astra journal digest last --format json
astra journal digest <SESSION_ID> --format json
astra journal digest <SESSION_ID> --focus summary --format json
If astra is not on PATH, check for one known local binary and invoke it
directly, rather than issuing repeated discovery and retry calls. Prefer
./target/debug/astra in a development checkout, then ./target/release/astra.
Record executable provenance only when comparing recorded behavior with current source. Do this in the same shell call as the digest when possible:
readlink -f ./target/debug/astra
stat ./target/debug/astra
git log -1 --format='%H %cI'
A journal proves what the executed binary did, not what the current checkout would do. If the binary predates a relevant commit or its provenance is unknown, label current-code conclusions separately and rebuild before claiming the session reproduces on HEAD.
For /tmp/debug-*.json input, skip digest metrics and use the debug dump only for
the message/tool/prompt snapshot it contains.
Phase 2: Trust The Selected Evidence
For structured observation, distinguish live introspect facts from persisted
reflect evidence and cite that boundary in the answer. Do not turn the user's
request for a retrospective into an exhaustive telemetry inventory.
Snapshots exclude later calls, and completed-turn aggregates can exclude the ongoing turn. State the observed scope; a zero in that scope does not prove absence elsewhere. Account separately for diagnostic calls made afterward.
When a digest is required, trust its stable schema:
Stable schema: schema_version = "astra-journal-digest-v2" from
crates/astra-cli/src/cli/journal_digest.rs.
Use these fields directly. Do not invent numbers.
| Field | Use |
|---|---|
aggregates |
Turn count, tokens, duration, tool counts, failures, stalls, compactions |
turns[] |
Per-turn tokens, latency, TTFT, context time, visible/used/activated tools, selected skills, budget pressure |
subruns[] |
Child-run identities and their own LLM/tool rounds; never merge these into root turns by numeric turn id |
failed_tool_calls[] |
Failed call category, tool name, args preview, error preview |
compaction_events[] |
When context was compacted and what signal triggered it |
stalls[] |
Stall/circuit-breaker evidence |
turn_errors[], other_errors[] |
Error cascade and failure boundaries |
journal_lines_malformed |
Whether digest skipped corrupted journal lines |
If schema_version differs, report the mismatch and still use fields that exist.
Phase 3: Diagnose By Focus
Context/tokens:
- Compare
tokens_in,tokens_out,budget_pressure,visible_tools_count, and compaction timing. - A high input-token turn with low tool progress usually points to history, tool result, or skill injection bloat.
- Repeated high
budget_pressureafter compaction points to prompt assembly or tool-result retention.
Tools:
- Start with
failed_tool_calls[], grouped bytoolanderror_category. - Compare
visible_tools_count,tools_used_count, andactivated_tools_count. - A visible-but-unused tool is not automatically bad; repeated activation without successful use is the signal.
Stalls/looping:
- Use
stalls[]and consecutive turns with similaruser_input_preview, failed tools, or no new successful tools. - Check whether the agent changed approach after a nudge or repeated the same call pattern.
Errors:
- Anchor every root cause to the first failed turn or failed tool call that made later work invalid.
- Separate permission/safety guard blocks from tool implementation failures.
Flow:
- Reconstruct the session as
user intent -> turn sequence -> tool outcomes -> compaction/stall/errors -> final state. - Prefer the smallest explanation that accounts for the observed sequence.
Async work and delegation:
- Treat the producer-owned work unit (for example one fixed-size fanout group), not each transport event or child, as the lifecycle unit.
- A child
turn_complete, a mailbox event, a progress row,not_found, or an empty shell-task list is not evidence that the parent work unit completed. - Verify every completion claim against a canonical terminal observation or aggregate whose terminal count equals its target count. Quote the exact contradictory tool result when the model claims more than the producer did.
- Reconstruct event order: group creation -> accepted identities -> child transitions -> canonical group settlement -> parent synthesis. Report extra parent LLM boundaries between child transitions as a wake/coalescing defect, even if the eventual answer is correct.
- Separate model epistemic failure from enforcement failure. If the runtime supplied non-terminal truth but still allowed an impossible completion claim, both layers contributed; a stronger prompt alone is not a system fix.
- Check CLI-only, CLI+Server, and Edge+Server ownership separately. Equivalent status words do not prove they share the same producer or wake contract.
Phase 4: Optional Deep Evidence
Use only when the digest does not answer the question.
| Evidence | Path |
|---|---|
| Heavy prompt checkpoint | ~/.astra/sessions/<id>/step_checkpoints/*-heavy.json |
| Debug full turn dump | /tmp/debug-*-turn*-full.json |
| Local journal | ~/.astra/sessions/<id>.jsonl |
| Session journal implementation | crates/services/src/session_journal.rs |
| Stall/guard implementation | crates/runtime/src/turn/ |
| Tool surface implementation | crates/runtime/src/tool_registry/, crates/runtime/src/capabilities.rs |
Output Contract
For routine checks, give a brief conclusion, supporting observation, and any remaining uncertainty. Use the detailed format below only for a substantive incident; include digest metrics and executable provenance only when relevant and actually obtained. Do not acquire extra evidence just to fill a template.
Findings:
- <highest-impact diagnosis with digest evidence>
Evidence:
- session=<id>, schema=<schema>, turns=<n>, failed_tools=<n>, stalls=<n>, compactions=<n>
- executable=<resolved path>, built=<timestamp>, source_head=<sha>, provenance=<matched|predates|unknown>
- <turn/tool/error citations>
Root cause:
- <one concrete mechanism>
Recommended fix:
- <code owner or workflow fix>
Unknowns:
- <only if evidence is missing>
{
"schema_version": 2,
"skill": "analyze_session",
"cause": "session_stalls",
"headline": "agent stalled on repeated tool calls with no new progress",
"findings": ["turn 4-7 repeated identical grep with no new matches"],
"recommended_action": "narrow scope to src/ or switch to rg",
"success_criteria": [
{
"metric": "session_stalls_delta",
"operator": "lte",
"threshold": 0.0,
"window_turns": 3,
"description": "session stalls stop increasing"
}
],
"source": "real_skill"
}