$npx -y skills add Borda/AI-Rig --skill debrief-codingRead local codemap telemetry logs and produce a diagnostic/usage report. Supports date filtering, session filtering, and optional anonymization before sharing. TRIGGER when: analyse recent codemap usage, debug query patterns, investigate errors, or prepare a shareable anonymized
| 1 | <objective> |
| 2 | |
| 3 | Reads `.cache/codemap/logs/` JSONL telemetry, analyses usage patterns, writes diagnostic report. |
| 4 | |
| 5 | NOT for: validating codemap installation health/integration (use `/codemap:integration check`); building/querying structural index (use `/codemap:scan-codebase` or `/codemap:query-code`). |
| 6 | |
| 7 | </objective> |
| 8 | |
| 9 | <workflow> |
| 10 | |
| 11 | ## Flags |
| 12 | |
| 13 | - `--since <YYYY-MM-DD>` — filter to records on or after this date (default: all) |
| 14 | - `--session <id>` — filter to a single session UUID |
| 15 | - `--anonymize` — run `anonymize.py` on both log files before reading; replaces qualified names with stable pseudonyms; keeps salt in `.cache/codemap/logs/.salt` (never included in output) |
| 16 | - `--output <path>` — write report to this path (default: `.reports/codemap/debrief-<YYYY-MM-DD>.md`) |
| 17 | |
| 18 | ## Step 0: Verify logs exist |
| 19 | |
| 20 | ```bash |
| 21 | ls .cache/codemap/logs/*.jsonl 2>/dev/null # timeout: 5000 |
| 22 | ``` |
| 23 | |
| 24 | No files → stop: "No codemap telemetry found. Run any `/codemap:*` skill or `scan-query` command to start collecting logs." |
| 25 | |
| 26 | Telemetry **sharded per session** (`_telemetry.py` + `log-skill-start.js` + `log-tool-use.js`): CLI records in `cli_<session>.jsonl`, skill records in `skills_<session>.jsonl`, Grep/Read/Glob records in `tools_<session>.jsonl`; runs with no seeded session id fall back to unsuffixed `cli.jsonl` / `skills.jsonl` / `tools.jsonl`. Collect **all** matching files, not just legacy names: |
| 27 | |
| 28 | ```bash |
| 29 | CLI_LOGS=$(ls .cache/codemap/logs/cli_*.jsonl .cache/codemap/logs/cli.jsonl 2>/dev/null) # timeout: 5000 |
| 30 | SKILLS_LOGS=$(ls .cache/codemap/logs/skills_*.jsonl .cache/codemap/logs/skills.jsonl 2>/dev/null) # timeout: 5000 |
| 31 | TOOLS_LOGS=$(ls .cache/codemap/logs/tools_*.jsonl .cache/codemap/logs/tools.jsonl 2>/dev/null) # timeout: 5000 |
| 32 | ``` |
| 33 | |
| 34 | ## Step 1: Optionally anonymize |
| 35 | |
| 36 | If `--anonymize` flag given: |
| 37 | |
| 38 | **Guard**: anonymize every present shard — never assume legacy `cli.jsonl` / `skills.jsonl` exist (per-session sharding means they usually don't). Loop over `$CLI_LOGS` / `$SKILLS_LOGS` sets from Step 0; anonymized copies land in `.cache/codemap/export/` (anonymize.py refuses to write next to `.salt` — never target logs dir); don't mix anonymized and original data in Step 2. |
| 39 | |
| 40 | ```bash |
| 41 | for f in .cache/codemap/logs/cli_*.jsonl .cache/codemap/logs/cli.jsonl \ |
| 42 | .cache/codemap/logs/skills_*.jsonl .cache/codemap/logs/skills.jsonl \ |
| 43 | .cache/codemap/logs/tools_*.jsonl .cache/codemap/logs/tools.jsonl; do |
| 44 | [ -f "$f" ] || continue |
| 45 | python "${CLAUDE_PLUGIN_ROOT:-plugins/codemap}/bin/anonymize.py" \ |
| 46 | --input "$f" # default --out-dir .cache/codemap/export/ — separated from .salt; timeout: 15000 |
| 47 | done |
| 48 | ``` |
| 49 | |
| 50 | If neither set has any file: print `⚠ --anonymize: no CLI or skill logs found — cannot produce anonymized report.` and stop. If only one layer present, anonymize it and note gap. |
| 51 | |
| 52 | Use `-anon` variants under `.cache/codemap/export/` as source in Step 2. anonymize.py not found → warn, proceed with originals. |
| 53 | |
| 54 | ## Step 2: Read log files |
| 55 | |
| 56 | Read **every** CLI shard (`cli_*.jsonl` plus legacy `cli.jsonl`), **every** skill shard (`skills_*.jsonl` plus legacy `skills.jsonl`), **every** tool shard (`tools_*.jsonl` plus legacy `tools.jsonl`) with Read tool — use `$CLI_LOGS` / `$SKILLS_LOGS` / `$TOOLS_LOGS` lists from Step 0 (or `-anon` siblings when anonymized). Concatenate records before analysing; single-file read misses per-session shards, reports near-empty dataset. |
| 57 | |
| 58 | Each line is one JSON record. Filter by `--since` (compare `ts` field) and `--session` if given. |
| 59 | |
| 60 | **`--session` guard**: when `--session <id>` given, session UUID may be absent from one or both log files (e.g., skills.jsonl records only skill events, not all CLI events). Filtering absent session ID returns empty set for that file — expected, not error. Report "session not found in <file>" rather than treating empty result as data loss. |
| 61 | |
| 62 | CLI record fields: `ts`, `layer`, `session`, `cmd`, `argv`, `result` (nested: `count`, `exhaustive`, `stale`, `method`, `not_covered`, `error`), `timing_ms`, `stderr` (optional), `exit_code` (optional). |
| 63 | |
| 64 | Skill record fields: `ts`, `layer`, `session`, `skill`, `event`, `intent`, `hook_session`. |
| 65 | |
| 66 | Tool record fields (`layer: "tool"`, from `log-tool-use.js`): `ts`, `layer`, `session`, `v` (plugin version, 0.23+), `tool` (`Grep`|`Read`|`Glob`|`Bash`), `target` (Grep/Glob pattern or search path, Read file_path, Bash search command truncated to 200 chars — 0.23+ logs search-shaped Bash since harness configs without native Grep/Glob route all searching through Bash). Count raw grep/read volume per session — the signal codemap's con |