{"id":"session-scan","name":"session-scan","summary":"Claude Codeセッションのメトリクスを計算します。ccriderで発見し、些細なものをフィルタリングし、摩擦・機会・指紋スコアを計算します。","body":"# Session Scan (Tier 1)\n\nCompute deterministic metrics for sessions discovered via ccrider MCP.\n\n## STOP — Read Before Executing\n\n**NEVER call `mcp__ccrider__get_session_messages` in main context.**\nEach response is 5-50KB of JSON. Fetching N sessions directly = context crash.\n\n**You MUST delegate all scoring to subagents.** The main context only does:\ndiscovery, deduplication, subagent spawning, and result collection.\n\n## Requirements\n\nRequires **ccrider MCP**. If not available:\n\n> ccrider MCP is required. See: <https://github.com/neilberkman/ccrider>\n\n## Usage\n\n```\n/session-scan                         # Last 7 days, up to 50 sessions\n/session-scan --since 2026-02-01      # Since specific date\n/session-scan --project enaia         # Filter by project name\n/session-scan --limit 20              # Cap session count\n/session-scan --list                  # Discovery only, no scoring\n/session-scan --rescan                # Recompute already-scanned sessions\n```\n\n## What Main Context Does\n\n### 1. Parse Arguments\n\nExtract from `$ARGUMENTS`:\n\n- **`--since DATE`**: ISO date filter (default: 7 days ago)\n- **`--project NAME`**: Filter by project path substring\n- **`--limit N`**: Max sessions to process (default: 50)\n- **`--list`**: Discovery only — show table, skip scoring\n- **`--rescan`**: Recompute metrics for already-scanned sessions\n\n### 2. Discover Sessions (safe — response is ~1KB)\n\n```\nmcp__ccrider__list_recent_sessions(limit: N, project: PROJECT, after_date: SINCE)\n```\n\nFilter out sessions with < 10 messages. If `--list`: show table and stop.\n\n### 3. Deduplicate\n\nRead `.claude/session-metrics/metrics.jsonl` (if exists).\nSkip sessions already scanned unless `--rescan` flag is set.\nReport: \"N new sessions to scan (M already in ledger)\"\n\n### 4. Resolve Scorer Path\n\n```\nGlob: **/session-scan/references/compute-metrics.py\n```\n\nStore as `SCORER_PATH` (absolute). `PROJECT_ROOT` = current working directory.\n\n### 5. Spawn ONE Subagent Per Session\n\n**DO NOT fetch messages yourself. DO NOT run Python yourself.**\n**You MUST use the Task tool to spawn subagents.**\n\nFor EACH unscanned session, spawn a haiku subagent using this template:\n\n```\nTask(subagent_type=\"general-purpose\", model=\"haiku\", mode=\"bypassPermissions\", prompt=\"\"\"\nScore one Claude Code session. Steps:\n\n1. Fetch messages:\n   mcp__ccrider__get_session_messages(session_id: \"{SESSION_ID}\", last_n: 200)\n\n2. Write the full tool result (messages JSON) to:\n   {PROJECT_ROOT}/.claude/session-metrics/_tmp_{SHORT_ID}.json\n\n3. Run scorer and capture result in ONE Bash command:\n   python3 {SCORER_PATH} {PROJECT_ROOT}/.claude/session-metrics/_tmp_{SHORT_ID}.json --session-id {SESSION_ID} --project {PROJECT_NAME} > {PROJECT_ROOT}/.claude/session-metrics/_result_{SHORT_ID}.json && rm {PROJECT_ROOT}/.claude/session-metrics/_tmp_{SHORT_ID}.json\n\n4. Report back: \"Scored {SHORT_ID}: friction=X.XX fingerprint=Y\"\n\nIf ccrider fails, report the error and exit.\n\"\"\")\n```\n\n**Spawn ALL subagents in parallel.** Wait for all to complete.\n\n### 6. Collect Results\n\n```bash\nfor f in .claude/session-metrics/_result_*.json; do\n  cat \"$f\" >> .claude/session-metrics/metrics.jsonl\n  rm \"$f\"\ndone\n```\n\n### 7. Display Results\n\nShow summary table sorted by friction (descending):\n\n```\n| ID       | Project | Date       | Type        | Friction | Opportunity | Tier2? |\n|----------|---------|------------|-------------|----------|-------------|--------|\n| ffa155ee | enaia   | 2026-02-18 | bug-fix     | 0.42     | 0.65        | Yes    |\n| 90a74843 | wedding | 2026-02-17 | feature     | 0.15     | 0.20        | No     |\n```\n\nIf Tier 2 eligible: suggest `/session-deep-dive --from-scan`.\n\n### 8. Update Scan Metadata\n\nWrite `.claude/session-metrics/latest-scan.json`:\n\n```json\n{\n  \"scanned_at\": \"2026-02-20T14:30:00Z\",\n  \"sessions_discovered\": 25,\n  \"sessions_scanned\": 18,\n  \"sessions_skipped\": 7,\n  \"tier2_eligible\": 5\n}\n```\n\n## Scoring Reference\n\nSee `references/scoring-guide.md` for full algorithm documentation.\n\n- **Friction Score** (0-1): Weighted signals, sigmoid-normalized\n- **Fingerprint**: Rule-based classifier (6 types)\n- **Plugin Opportunity** (0-1): Missed `/phx:` commands\n- **Tier 2 Eligible**: friction > 0.35 OR opportunity > 0.5 OR plugin used OR msgs > 50\n\n## Iron Laws\n\n1. **NEVER call `get_session_messages` in main context** — WILL crash context\n2. **ONE subagent per session** — each fetches exactly ONE session\n3. **`mode=\"bypassPermissions\"` on every Task** — subagents need Write+Bash\n4. **Absolute paths in subagent prompts** — subagents don't inherit context\n5. **Result files, not direct append** — avoid jsonl race conditions\n6. **NEVER modify existing metrics.jsonl entries** — append-only ledger\n7. **ALWAYS delete temp and result files** after processing","author":"@oliver-kriska","ownerProfile":null,"authorContacts":null,"sourceUrl":"https://github.com/oliver-kriska/claude-elixir-phoenix/tree/main/.claude/skills/session-scan","license":"MIT","category":null,"lang":"en","tokens":1306,"stars":0,"calls30d":2,"claimed":false,"visibility":"public","origin":"crawler","version":"0.1.0","createdAt":"2026-08-22","updatedAt":"2026-08-22","files":[{"path":"references/compute-metrics.py","size":67764,"sha256":"6d2ea7c5b3c2c940ca40120b9ad735c7d3ca7f73dfc27ed1c0b7813e8f08278a"},{"path":"references/scoring-guide.md","size":4920,"sha256":"3b232c7f8793c9898e4969ea8404bf1147ced038a23c39af6b5ba8a5a13d9772"}],"requires":{"mcp":["ccrider"],"tools":[]},"safety":{"flags":[{"code":"injection.disable-permissions","kind":"injection","where":"SKILL.md:72","excerpt":"bypassPermissions","message":"instructs the agent to disable permission checks","severity":"warn"}],"scannedAt":"2026-08-22","hasScripts":true,"networkEndpoints":[]}}