Claude Code Plugins

Community-maintained marketplace

Feedback

session-chronicle

@terrylica/cc-skills
4
0

Excavate session logs for provenance tracking. TRIGGERS - who created, document finding, trace origin, session archaeology, provenance, ADR reference.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name session-chronicle
description Excavate session logs for provenance tracking. TRIGGERS - who created, document finding, trace origin, session archaeology, provenance, ADR reference.
allowed-tools Read, Grep, Glob, Bash

Session Chronicle

Excavate Claude Code session logs to capture complete provenance for research findings, ADR decisions, and code contributions. Traces UUID chains across multiple auto-compacted sessions.

S3 Artifact Sharing: Artifacts can be uploaded to S3 for team access. See S3 Sharing ADR.

When to Use This Skill

  • User asks "who created this?" or "where did this come from?"
  • User says "document this finding" with full session context
  • ADR or research finding needs provenance tracking
  • Git commit needs session UUID references
  • Tracing edits across auto-compacted sessions

Preflight Check

Step 1: Verify Session Storage Location

/usr/bin/env bash << 'PREFLIGHT_EOF'
# Check Claude session storage
PROJECT_DIR="$HOME/.claude/projects"
if [[ ! -d "$PROJECT_DIR" ]]; then
  echo "ERROR: Session storage not found at $PROJECT_DIR"
  exit 1
fi

# Count project folders
PROJECT_COUNT=$(ls -1d "$PROJECT_DIR"/*/ 2>/dev/null | wc -l)
echo "Found $PROJECT_COUNT project folders in $PROJECT_DIR"
echo "Ready for session archaeology"
PREFLIGHT_EOF

Step 2: Find Current Project Sessions

/usr/bin/env bash << 'FIND_SESSIONS_EOF'
# Encode current working directory path
CWD=$(pwd)
ENCODED_PATH=$(echo "$CWD" | tr '/' '-')
PROJECT_SESSIONS="$HOME/.claude/projects/$ENCODED_PATH"

if [[ -d "$PROJECT_SESSIONS" ]]; then
  SESSION_COUNT=$(ls -1 "$PROJECT_SESSIONS"/*.jsonl 2>/dev/null | wc -l)
  echo "Found $SESSION_COUNT session files for current project"
  echo "Location: $PROJECT_SESSIONS"

  # Show largest sessions (likely most relevant)
  echo -e "\nLargest sessions (by line count):"
  wc -l "$PROJECT_SESSIONS"/*.jsonl 2>/dev/null | sort -rn | head -5
else
  echo "No sessions found for current project at: $PROJECT_SESSIONS"
  echo "Checking all project folders..."
  ls -la "$HOME/.claude/projects/" | head -10
fi
FIND_SESSIONS_EOF

Step 3: Verify Required Tools

/usr/bin/env bash << 'TOOLS_EOF'
# Check for jq (required for JSONL parsing)
command -v jq &>/dev/null || { echo "WARNING: jq not installed (brew install jq)"; }

# Check for brotli (required for compression)
command -v brotli &>/dev/null || { echo "ERROR: brotli not found (brew install brotli)"; exit 1; }

# Check for aws and op (required for S3 upload)
command -v aws &>/dev/null || { echo "WARNING: aws CLI not installed (brew install awscli)"; }
command -v op &>/dev/null || { echo "WARNING: 1Password CLI not installed (brew install 1password-cli)"; }

echo "Required tools available"
TOOLS_EOF

Part 1: AskUserQuestion Flows

Flow A: Identify Target for Provenance

When the skill is triggered, first identify what the user wants to trace:

AskUserQuestion:
  question: "What do you want to trace provenance for?"
  header: "Target"
  multiSelect: false
  options:
    - label: "Specific code/feature"
      description: "Trace who created a specific function, feature, or code block"
    - label: "Research finding"
      description: "Document a finding with full session context for reproducibility"
    - label: "Configuration/decision"
      description: "Trace when and why a configuration or architectural decision was made"
    - label: "Custom search"
      description: "Search session logs for specific keywords or patterns"

Flow B: Specify Search Parameters

Based on target type, gather search parameters:

AskUserQuestion:
  question: "What keywords or identifiers should we search for?"
  header: "Search"
  multiSelect: true
  options:
    - label: "File path pattern"
      description: "Search for edits to specific files (e.g., **/minimal_3*)"
    - label: "Function/variable name"
      description: "Search for creation of specific identifiers"
    - label: "Session UUID"
      description: "Start from a known session UUID"
    - label: "Date range"
      description: "Limit search to sessions from specific dates"

Flow C: Confirm Discovered Sessions

After scanning, confirm with user:

AskUserQuestion:
  question: "Found N related sessions. Which should we include?"
  header: "Sessions"
  multiSelect: true
  options:
    - label: "Full session chain (Recommended)"
      description: "Archive ALL sessions in UUID chain - complete provenance across auto-compacts"
    - label: "Add earlier sessions"
      description: "Include sessions BEFORE the chain starts (for deeper context)"
    - label: "Manual selection"
      description: "I'll specify which sessions to include"
    - label: "Provide more context"
      description: "The search didn't find what I need, let me clarify"

IMPORTANT: Always default to archiving the FULL session chain. Auto-compacting creates arbitrary boundaries - a finding's true origin often spans multiple sessions.

Flow D: Choose Output Format

AskUserQuestion:
  question: "What outputs should be generated?"
  header: "Outputs"
  multiSelect: true
  options:
    - label: "Full session chain archive (.jsonl.br per session)"
      description: "Compress EACH session with Brotli (best compression)"
    - label: "provenance.jsonl (append-only log)"
      description: "NDJSON record with UUIDs, timestamps, contributors"
    - label: "Markdown finding document"
      description: "findings/<name>.md with embedded provenance table"
    - label: "Git commit with provenance"
      description: "Structured commit message with session references"
    - label: "Upload to S3 for team sharing"
      description: "Upload artifacts to S3 with retrieval command in commit"

Flow E: Link to Existing ADR (for S3 upload)

When S3 upload is selected:

AskUserQuestion:
  question: "Link this finding to an existing ADR?"
  header: "ADR Link"
  multiSelect: false
  options:
    - label: "No ADR link"
      description: "This finding is standalone"
    - label: "Specify ADR slug"
      description: "Link to an existing ADR (e.g., 2025-12-15-feature-name)"

Part 2: Session Archaeology Process

Step 1: Full Project Scan

Scan all session files in the project folder to build a session index:

/usr/bin/env bash << 'SCAN_EOF'
PROJECT_SESSIONS="$HOME/.claude/projects/$ENCODED_PATH"

# Build session index
echo "Scanning sessions..."
for session in "$PROJECT_SESSIONS"/*.jsonl; do
  SESSION_ID=$(basename "$session" .jsonl)
  LINE_COUNT=$(wc -l < "$session")
  FIRST_TS=$(head -1 "$session" | jq -r '.timestamp // empty')
  LAST_TS=$(tail -1 "$session" | jq -r '.timestamp // empty')

  echo "$SESSION_ID|$LINE_COUNT|$FIRST_TS|$LAST_TS"
done > /tmp/session_index.txt

echo "Indexed $(wc -l < /tmp/session_index.txt) sessions"
SCAN_EOF

Step 2: Search for Target

Search across all sessions for the target:

/usr/bin/env bash << 'SEARCH_EOF'
# Search for keyword in all sessions
grep -l "SEARCH_TERM" "$PROJECT_SESSIONS"/*.jsonl

# Extract entries with tool_use containing the target
jq -c 'select(.message.content[]?.type == "tool_use") |
       select(.message.content[].input | tostring | contains("SEARCH_TERM"))' \
  "$PROJECT_SESSIONS"/*.jsonl
SEARCH_EOF

Step 3: Trace UUID Chain

Trace parentUuid chain backwards to find origin:

/usr/bin/env bash << 'TRACE_EOF'
trace_uuid_chain() {
  local uuid="$1"
  local session_file="$2"
  local depth=0
  local max_depth=100

  echo "Tracing UUID chain from: $uuid"

  while [[ -n "$uuid" && $depth -lt $max_depth ]]; do
    # Find entry with this UUID
    entry=$(jq -c "select(.uuid == \"$uuid\")" "$session_file" 2>/dev/null)

    if [[ -n "$entry" ]]; then
      parent=$(echo "$entry" | jq -r '.parentUuid // empty')
      timestamp=$(echo "$entry" | jq -r '.timestamp // empty')
      type=$(echo "$entry" | jq -r '.type // empty')

      echo "  [$depth] $uuid ($type) @ $timestamp"
      echo "       -> parent: $parent"

      uuid="$parent"
      ((depth++))
    else
      # UUID not in this session - search other sessions
      echo "  UUID $uuid not in current session, searching others..."
      found=false
      for session in "$PROJECT_SESSIONS"/*.jsonl; do
        if grep -q "\"uuid\":\"$uuid\"" "$session" 2>/dev/null; then
          session_file="$session"
          echo "  Found in $(basename "$session")"
          found=true
          break
        fi
      done
      [[ "$found" == "false" ]] && break
    fi
  done

  echo "Chain depth: $depth"
}
TRACE_EOF

Step 4: Extract Edit Context

Extract the exact tool_use that created/modified the target:

/usr/bin/env bash << 'EXTRACT_EOF'
# Extract tool_use block with context (5 entries before and after)
jq -c 'select(.message.content[]?.type == "tool_use") |
       select(.message.content[].name == "Edit" or .message.content[].name == "Write")' \
  "$SESSION_FILE" | head -20
EXTRACT_EOF

Part 3: Output Generation

NDJSON Provenance Record Schema

Each provenance record in provenance.jsonl:

{
  "id": "uuid-v4",
  "type": "finding|decision|contribution",
  "target": {
    "file": "path/to/file.py",
    "identifier": "minimal_3",
    "description": "3-feature baseline model"
  },
  "origin": {
    "session_id": "7380c12f-9c92-426f-9fe8-2c08705c81aa",
    "edit_uuid": "055fa4fe-b85d-4ff1-b337-f15b99d98eac",
    "parent_uuid": "da0ffa7d-7374-414f-8197-7b8bb3d10e52",
    "timestamp": "2026-01-01T01:48:27.634Z",
    "model": "claude-opus-4-5-20251101",
    "contributor": "claude"
  },
  "chain": {
    "sessions_traced": 3,
    "total_entries": 22456,
    "chain_depth": 15
  },
  "artifacts": {
    "session_context": "findings/provenance/session_context_<id>.jsonl.gz",
    "finding_doc": "findings/<name>.md"
  },
  "created_at": "2026-01-01T12:00:00Z"
}

Compressed Session Context

CRITICAL: Extract the FULL chain across ALL related sessions, not just a fixed window.

The provenance chain typically spans multiple auto-compacted sessions. Each session file represents a context window - the finding may have origins several sessions back.

/usr/bin/env bash << 'COMPRESS_EOF'
# Extract FULL session chain - not limited to fixed entries
# Each session in the chain gets its own compressed file

OUTPUT_DIR="findings/provenance/session_chain_${TARGET_ID}"
mkdir -p "$OUTPUT_DIR"

# 1. Get the UUID chain (traced by uuid_tracer.sh)
CHAIN_FILE="$OUTPUT_DIR/uuid_chain.jsonl"

# 2. For EACH session in the chain, extract and compress the FULL session
for session_id in $(cat "$CHAIN_FILE" | jq -r '.session_id' | sort -u); do
  SESSION_PATH="$PROJECT_SESSIONS/${session_id}.jsonl"
  if [[ -f "$SESSION_PATH" ]]; then
    # Compress entire session (not just a window)
    gzip -c "$SESSION_PATH" > "$OUTPUT_DIR/${session_id}.jsonl.gz"
    echo "Archived: ${session_id} ($(wc -l < "$SESSION_PATH") entries)"
  fi
done

# 3. Create manifest of all archived sessions
cat "$CHAIN_FILE" | jq -s '{
  target_id: $TARGET_ID,
  sessions_archived: (map(.session_id) | unique),
  total_sessions: (map(.session_id) | unique | length),
  chain_depth: length,
  created_at: now | todate
}' > "$OUTPUT_DIR/manifest.json"

echo "Full session chain archived to: $OUTPUT_DIR"
COMPRESS_EOF

Why full sessions?

  • Auto-compacting creates session boundaries at arbitrary points
  • A single finding's context may span 3-5+ sessions
  • Partial extraction loses critical context about HOW the finding evolved
  • Full sessions enable complete reproduction and audit

Markdown Finding Document Template

# Finding: <title>

**Date**: YYYY-MM-DD
**Status**: VALIDATED
**ADR**: [link if applicable]

---

## Summary

<1-2 paragraph description of the finding>

---

## Provenance

| Field       | Value           |
| ----------- | --------------- |
| Session ID  | `<session_id>`  |
| Timestamp   | `<timestamp>`   |
| Model       | `<model>`       |
| Edit UUID   | `<edit_uuid>`   |
| Parent UUID | `<parent_uuid>` |

### Session Chain

| Session     | Lines   | Date Range      |
| ----------- | ------- | --------------- |
| <session_1> | <lines> | <start> - <end> |
| <session_2> | <lines> | <start> - <end> |

### Context

<Original Claude message before the edit>

---

## Artifacts

| File                                       | Description                |
| ------------------------------------------ | -------------------------- |
| `provenance/session_context_<id>.jsonl.gz` | Compressed session excerpt |
| `provenance/<name>_edit_context.json`      | Exact tool_use block       |

---

## Reproduction

```bash
# Commands to reproduce or verify the finding
```

Generated by session-chronicle skill


### Git Commit Message Template

feat(finding):

Session-Chronicle Provenance: session_id: edit_uuid: parent_uuid: timestamp: model: sessions_traced: chain_depth:

Artifacts:

  • findings/.md
  • findings/provenance/sessioncontext.jsonl.gz
  • findings/provenance/_edit_context.json

Co-authored-by: Claude noreply@anthropic.com


---

## Part 4: Iterative Fallback

If initial search fails or is insufficient:

### Fallback A: Expand Search Scope

AskUserQuestion: question: "Search didn't find clear matches. How should we proceed?" header: "Fallback" multiSelect: false options: - label: "Expand to all sessions" description: "Search entire project history (may be slow)" - label: "Different search terms" description: "Let me provide alternative keywords" - label: "Specific session file" description: "I know which session file contains it" - label: "Date range narrowing" description: "I can narrow down when this was created"


### Fallback B: Manual Context

AskUserQuestion: question: "Please provide additional context for the search" header: "Context" multiSelect: true options: - label: "Approximate date" description: "When was this approximately created?" - label: "Related files" description: "What other files were involved?" - label: "Conversation topic" description: "What were we discussing when this was created?" - label: "Session UUID if known" description: "I have a specific session UUID to start from"


---

## Part 5: Workflow Summary
  1. PREFLIGHT ├── Verify session storage location ├── Find current project sessions └── Check required tools (jq, brotli, aws, op)

  2. IDENTIFY TARGET └── AskUserQuestion: What to trace?

  3. FULL PROJECT SCAN ├── Index all session files ├── Search for target across sessions └── Build session timeline

  4. TRACE UUID CHAIN ├── Find target entry ├── Trace parentUuid backwards └── Cross-reference multiple sessions if needed

  5. CONFIRM WITH USER ├── AskUserQuestion: Which sessions to include? └── AskUserQuestion: Link to existing ADR?

  6. GENERATE OUTPUTS ├── Append to provenance.jsonl ├── Create Brotli-compressed session context (.jsonl.br) ├── Generate markdown finding document └── Prepare git commit message

  7. S3 UPLOAD (optional) ├── Upload artifacts to S3 via scripts/s3_upload.sh ├── Uses 1Password for credential injection └── Updates manifest with S3 location

  8. GIT COMMIT ├── Embed S3 URIs in commit message ├── Include retrieval command for coworkers └── Add Session-Chronicle-S3: trailer

  9. FALLBACK (if needed) └── AskUserQuestion: Provide more context


### S3 Upload Scripts

| Script | Purpose |
| ------ | ------- |
| `scripts/s3_upload.sh` | Upload artifacts to S3 with 1Password credentials |
| `scripts/retrieve_artifact.sh` | Download and decompress artifacts for coworkers |
| `scripts/generate_commit_message.sh` | Generate commit message with S3 links |

---

## References

- [S3 Sharing ADR](/docs/adr/2026-01-02-session-chronicle-s3-sharing.md)
- [S3 Retrieval Guide](./references/s3-retrieval-guide.md)
- [Session Storage](/plugins/devops-tools/skills/session-recovery/SKILL.md)
- [NDJSON Specification](https://github.com/ndjson/ndjson-spec)
- [jq Manual](https://jqlang.github.io/jq/manual/)
- [Brotli Compression](https://github.com/google/brotli)

---

## Success Criteria

1. **Complete chain traced** - All UUID links followed to origin
2. **Cross-session tracking** - Auto-compacted sessions handled
3. **Machine-readable output** - NDJSON provenance record created
4. **Human-readable output** - Markdown finding document generated
5. **Git-ready** - Commit message with full provenance prepared
6. **Reproducible** - Compressed context allows verification
7. **Team-accessible** - Artifacts uploaded to S3 with retrieval command