# okstra-inspect facet — logs

Loaded lazily by the dispatch table in `SKILL.md` (core). Shared rules — Step 0 preflight, the standard task-key resolution rule (0/1/N), the no-task fallback, and Output Rules — live in the core file and still apply here.

## logs

Trigger phrases: "okstra logs", "log status", "log files", "log size", "log cleanup".

Read-only inventory of the worker log files written next to each prompt history file (`<prompt>.log`). Reports sizes, ages, totals, and suggests cleanup commands. **Does not delete** — the user runs whichever `find … -delete` line they like.

**Background:** every CLI-worker dispatch writes a sidecar log next to its prompt history file. All five providers go through the same shared runner (`~/.okstra/lib/python/okstra_ctl/worker_runner.py`), so the file is there whichever provider ran:

```
.okstra/tasks/<task-group>/<task-id>/runs/<phase>/prompts/
  <worker>-worker-prompt-<phase>-<seq>.md    <-- prompt (git-tracked)
  <worker>-worker-prompt-<phase>-<seq>.log   <-- the run's archive of what the worker did
```

The log is rewritten from scratch at each dispatch — only the latest run for a given seq is preserved. Different seqs keep separate files. It holds one row per tool call and per tool result plus the worker's closing text, and drops thinking; a provider that emits plain text instead of an event stream has its progress copy capped at 5000 lines per run, with `[okstra log-cap] N progress line(s) elided` marking what was dropped. Long-running implementation dispatches can still produce multi-MB logs; analysis-phase dispatches are typically smaller.

### logs.1 — Inventory

```bash
okstra log-report --project-root <projectRoot> --text
```

Scans `<projectRoot>/.okstra/tasks/**/runs/*/prompts/*.log` and returns fixed labeled text (sizes are **raw bytes**, mtimes **epoch seconds**):
- `topLargest[]` — `{path, sizeBytes, mtimeEpoch, taskKey, taskGroup, taskId, phase, worker, seq}`, size desc (widen with `--top <N>`)
- `perTask[]` — `{taskKey, fileCount, totalBytes, oldestEpoch, newestEpoch}`, total-size desc
- `totals` — `{fileCount, totalBytes, taskCount}`

If `totals.fileCount` is 0, report `No worker log files found under <projectRoot>` and stop.

### logs.2 — Summary tables

Render from the CLI output (format bytes → KB/MB; epoch → `Nd`/`Nh` relative to now):

**Table A — Top largest logs** (from `topLargest`): `| # | Task | Phase | Worker | Seq | Size | Age | Path |`.

**Table B — Per-task totals** (from `perTask`): `| Task Key | Files | Total Size | Oldest | Newest |`.

**Footer:** `Total: <fileCount> files, <totalBytes→MB> across <taskCount> tasks under <PROJECT_ROOT>`.

### logs.3 — Suggested cleanup commands

Emit a fenced bash block the user can copy-paste. Do NOT execute. Each block pairs a dry-run preview (`-print`) with the destructive (`-delete`) command:

```markdown
## Cleanup options (manual)

# Delete only logs older than 7 days
find <PROJECT_ROOT>/.okstra/tasks \
  -type f -path '*/runs/*/prompts/*.log' -mtime +7 -print    # dry-run
find <PROJECT_ROOT>/.okstra/tasks \
  -type f -path '*/runs/*/prompts/*.log' -mtime +7 -delete

# Delete only logs older than 30 days
find <PROJECT_ROOT>/.okstra/tasks \
  -type f -path '*/runs/*/prompts/*.log' -mtime +30 -print   # dry-run
find <PROJECT_ROOT>/.okstra/tasks \
  -type f -path '*/runs/*/prompts/*.log' -mtime +30 -delete

# Delete all logs for a specific task-group (e.g. dev-9388)
find <PROJECT_ROOT>/.okstra/tasks/dev-9388 \
  -type f -name '*.log' -print    # dry-run
find <PROJECT_ROOT>/.okstra/tasks/dev-9388 \
  -type f -name '*.log' -delete

# Delete all logs for a specific task-id (e.g. dev-9428)
find <PROJECT_ROOT>/.okstra/tasks/*/dev-9428 \
  -type f -name '*.log' -print    # dry-run
find <PROJECT_ROOT>/.okstra/tasks/*/dev-9428 \
  -type f -name '*.log' -delete

# Delete everything (caution)
find <PROJECT_ROOT>/.okstra/tasks \
  -type f -path '*/runs/*/prompts/*.log' -print    # dry-run
find <PROJECT_ROOT>/.okstra/tasks \
  -type f -path '*/runs/*/prompts/*.log' -delete
```

Substitute the literal `<PROJECT_ROOT>` with the resolved absolute path so the commands are directly copy-pasteable.

### logs.4 — Notes for the user

- Logs are truncated on each re-dispatch of the same `seq`, so deleting an in-flight run's log will cause the wrapper to recreate an empty file on the next dispatch — no data loss beyond the current trace.
- **If a dispatch is currently running, check task status first (load `facets/status.md`)** and avoid deleting logs for tasks in `in-progress` state — you will lose the live trace for the active run.
- Prompt history files (`.md`) are separate and are NOT touched by these commands — only `.log` sidecars.
- This sub-command **does not modify any external files itself**, including `.gitignore`. If the project commits `.okstra/`, the user may want to add `.okstra/tasks/**/runs/**/prompts/*.log` to `.gitignore` manually to keep large logs out of git.
