/gsd forensics
What It Does
Section titled “What It Does”/gsd forensics is the deep investigation tool for when auto-mode fails in ways that aren’t obvious from the surface. It programmatically scans activity logs, the metrics ledger, crash locks, and doctor diagnostics to build a structured forensic report. It then detects anomalies — stuck loops, cost spikes, timeouts, missing artifacts, error traces — and hands the whole package to the LLM for interactive investigation.
Unlike /gsd doctor which checks structural integrity, forensics focuses on behavioral anomalies: did a unit run too many times? Did costs spike unexpectedly? Did something time out? Did a completed unit leave missing artifacts?
Forensics cannot run while auto-mode is active — it needs to inspect the state without interference.
/gsd forensicsThe command prompts you to describe what went wrong. This problem description helps the LLM focus its investigation. If you provide the description as an argument, it skips the prompt:
/gsd forensics auto-mode got stuck on task T03 and kept retryingHow It Works
Section titled “How It Works”Duplicate Detection Opt-in
Section titled “Duplicate Detection Opt-in”The first time you run forensics (when forensics_dedup is not set in your global preferences), GSD shows an interactive choice:
- Enable duplicate detection — Before filing a GitHub issue, the LLM will search closed issues, open PRs, and merged PRs to avoid creating duplicates. Uses additional AI tokens for the search.
- Skip for now — File without checking for duplicates.
If you enable it, the preference is saved to your global GSD preferences file (~/.gsd/agent/preferences.md) as forensics_dedup: true. You can also set it manually.
Data Sources
Section titled “Data Sources”The forensic report builder collects data from five sources:
- Activity logs (
.gsd/activity/*.jsonl) — Scanned from both the active auto-worktree and the project root. All matching JSONL files from each directory are sorted alphabetically (the filename encodes a sequence number, unit type, and unit ID) and the five most recent from each directory are read. Results are then merged and sorted by modification time, keeping the five most recent overall. Each log records tool calls, reasoning traces, errors, and files written during a unit’s execution. Worktree logs take priority over root logs when both exist. - Metrics ledger (
.gsd/metrics.json) — Cost, token count, timing, and model data for every completed unit. Used to compute per-type averages and detect cost spikes. The ten most recent units are included in the report. - Crash lock (
.gsd/auto.lock) — Written at auto-mode startup with PID, unit type, unit ID, and session file path. If the PID is dead, it’s a crash indicator. - Doctor checks — The full doctor scan runs internally. Error-severity issues become forensic anomalies.
- Completed keys (
.gsd/completed-units.json) — List of units marked as done. Cross-referenced against expected artifacts in both the project root and the active worktree to detect stale completions.
Anomaly Types
Section titled “Anomaly Types”| Type | Severity | What It Detects | Trigger |
|---|---|---|---|
stuck-loop | warning/error | Same unit dispatched multiple times | Count ≥ 2 (warning), ≥ 3 (error) |
cost-spike | warning | Unit cost exceeds 3× the average for its type | Per-unit cost / type average > 3.0 |
timeout | warning | Timeout patterns in activity logs | gsd-auto-timeout-recovery in tool calls, or idle/hard/timeout-recovery keywords in last reasoning |
missing-artifact | error | Completed unit but expected artifact missing or invalid | verifyExpectedArtifact() returns false at both root and worktree |
crash | error | Crash lock with dead PID | Lock exists and isLockProcessAlive() returns false |
doctor-issue | error | Error-severity structural issue from doctor | Doctor scan finds error-level issues |
error-trace | warning | Errors recorded in activity log traces | trace.errors.length > 0 |
Report Persistence
Section titled “Report Persistence”Every forensic report is saved as a timestamped markdown file in .gsd/forensics/ (e.g., report-2026-03-17-14-30-22.md). This creates an audit trail of investigations. The report includes all anomalies, recent unit history, activity log traces, doctor issues, and crash lock state.
Before writing, the report is redacted: absolute paths are replaced with relative equivalents, home directories are replaced with ~, and API keys, Bearer tokens, and environment variable values are scrubbed.
LLM Dispatch
Section titled “LLM Dispatch”The report is formatted into a structured prompt (capped at 30KB) and dispatched to the LLM with triggerTurn: true. The LLM receives the problem description, all anomalies, a table of the ten most recent units from the metrics ledger, the top three activity log traces (tool calls, files written, errors, last reasoning), doctor issues, crash lock state, metrics summary, and the path to the GSD extension source code with a comprehensive domain-organized source map.
The source map organizes GSD’s source files by domain so the LLM can navigate directly to relevant code:
| Domain | Coverage |
|---|---|
| Auto-mode engine | Dispatch loop, stuck detection, timeout recovery, artifact verification, worktree sync, budget |
| State & persistence | State derivation, file paths, JSON persistence, atomic writes |
| Forensics & recovery | Trace extraction, crash lock lifecycle, session lock |
| Metrics & telemetry | Cost/token ledger, skill telemetry, token counting |
| Health & diagnostics | Doctor checks, environment checks, issue formatting |
| Prompts & context | Prompt loading, prompt cache optimization, context budget |
| Git & worktrees | Git service, worktree manager, self-healing |
| Commands | Command dispatcher, inspect commands, maintenance commands |
The LLM follows a structured investigation sequence:
- Analyze anomalies and trace data — treat automated findings as leads, not conclusions
- Read source code — navigate to the candidate files to confirm or deny hypotheses; do not guess what code does
- Trace the code path — follow function calls from entry point through to the failure
- Clarify — may ask up to 2 questions if the report is genuinely ambiguous (skipped if data is sufficient)
- Explain — what happened, why it happened (with
file:linereferences), the problematic code snippet, and how to recover
Then the LLM offers GitHub issue creation at gsd-build/gsd-2 with labels bug, auto-generated. The issue is created via gh issue create --repo gsd-build/gsd-2 using the bash tool (not the github_issues tool, which can’t target a specific repo). The issue template includes GSD version, model, the failing unit, reproduction context, forensic findings, and a concrete fix suggestion — automatically redacted of any user-specific data.
When duplicate detection is enabled, the LLM first searches closed issues, open PRs, and merged PRs using keywords from its diagnosis. It presents any matches and lets you choose to skip issue creation (already fixed), add a comment to an existing issue, or create a new one anyway.
What Files It Touches
Section titled “What Files It Touches”Creates
Section titled “Creates”| File | Purpose |
|---|---|
.gsd/forensics/report-*.md | Timestamped, redacted forensic report |
~/.gsd/agent/preferences.md | Updated when user enables duplicate detection for the first time |
| File | Purpose |
|---|---|
.gsd/activity/*.jsonl | Activity logs from project root (last 5 by sequence, merged by mtime) |
.gsd/worktrees/<MID>/.gsd/activity/*.jsonl | Activity logs from active auto-worktree (merged with root, top 5 overall) |
.gsd/metrics.json | Cost and timing metrics for anomaly detection |
.gsd/auto.lock | Crash detection (PID, unit type, unit ID, session file) |
.gsd/completed-units.json | Stale completion detection |
.gsd/STATE.md | Current project state (active milestone and slice) |
.gsd/milestones/*/ | Doctor scan (run internally) |
~/.gsd/agent/preferences.md | Global preferences (reads forensics_dedup setting) |
Examples
Section titled “Examples”Investigating a stuck auto-mode session:
> /gsd forensics● Describe what went wrong: auto-mode kept retrying T03 and never moved forward
● Duplicate detection available Before filing a GitHub issue, forensics can search existing issues and PRs to avoid duplicates. This uses additional AI tokens for analysis. > Enable duplicate detection (recommended) Skip for now
● Building forensic report... Forensic report saved: .gsd/forensics/report-2026-03-17-14-30-22.md
● Analyzing report...
Found 3 anomalies:
[ERROR] stuck-loop: Unit execute-task/M001/S02/T03 was dispatched 4 times Repeated dispatch suggests the unit completed but its artifacts weren't verified, or the state machine kept returning it.
[WARNING] cost-spike: $2.41 vs $0.38 average for execute-task Unit execute-task/M001/S02/T03 cost 6.3x the average. May indicate excessive retries or large context.
[WARNING] error-trace: 7 error(s) in execute-task/M001/S02/T03 Error: ENOENT: no such file or directory, open 'dist/api/users.js' Error: Test suite failed: 3 failing Error: ENOENT: no such file or directory...
Investigating T03 activity log...
Would you like me to create a GitHub issue for this on gsd-build/gsd-2?Passing the problem description directly to skip the prompt:
> /gsd forensics crash lock is stale after terminal was killed
● Building forensic report... Forensic report saved: .gsd/forensics/report-2026-03-19-09-12-44.mdPrompts Used
Section titled “Prompts Used”forensics— Deep diagnostic investigation prompt
Related Commands
Section titled “Related Commands”/gsd doctor— Structural health checks (forensics runs doctor internally)/gsd status— View current project state/gsd cleanup— Clean up after resolving forensic issues/gsd stop— Stop auto-mode before running forensics