Skip to content
Back to skills

Summarize

ASecurity

Summarize a /swe benchmark run for a given repo/problem/model triple. Reports artifact completion status (github-issue.md, lld.md, review.md, testing.md), error signals captured during the run, and a token-and-themes summary derived from the matching session JSONL files under ~/.claude/projects/. Output is a single markdown report saved next to the artifacts.

  • 14 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 6, 2026
ai-agentspythongobashawstestinggit

Works with

  • claude code
  • mcp

Security analysis

A100/100

Scanned October 6, 2026

npx -y skills add aws-samples/sample-agentic-coding-harness-benchmarks --skill summarize --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Summarize?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Summarize
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/aws-samples-summarize/badge)](https://www.skillsdirectory.com/skills/aws-samples-summarize)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: summarize
description: "Summarize a /swe benchmark run for a given repo/problem/model triple. Reports artifact completion status (github-issue.md, lld.md, review.md, testing.md), error signals captured during the run, and a token-and-themes summary derived from the matching session JSONL files under ~/.claude/projects/. Output is a single markdown report saved next to the artifacts."
license: Apache-2.0
metadata:
  author: Amit Arora
  version: "1.1"
---

# Summarize Skill

Use this skill **after** a `/swe` benchmark run to evaluate how that run went. It performs two passes:

1. **Artifact pass** - check the `benchmarks/swe-benchmark-data/{repo-name}/{problem-name}/{model-name}/` folder and report which of the four expected files exist, are non-empty, and are well-formed; surface any error/diagnostic content found in those files.
2. **Session pass** - read the JSONL files from `~/.claude/projects/<encoded-cwd>/` for the session(s) that produced the artifacts, and summarize token usage (per model, broken down by input / output / cache-create / cache-read), tool-call mix, error events, and recurring themes from user prompts and assistant turns.

The result is written as a single markdown report next to the artifacts and printed back to the user.

**This skill stops at reporting. It does not modify the artifacts, re-run `/swe`, or open issues.**

## Workflow

1. **Gather Inputs** - Capture `--repo`, `--problem`, and `--model` (never guess them); optionally `--session-id` to narrow the JSONL pass
2. **Locate Artifacts Folder** - Resolve `benchmarks/swe-benchmark-data/{repo}/{problem}/{model}/`
3. **Artifact Pass** - Check existence, size, and quality of `github-issue.md`, `lld.md`, `review.md`, `testing.md`
4. **Locate Session JSONL Files** - Resolve `~/.claude/projects/<encoded-cwd>/*.jsonl` and filter by session/time
5. **Session Pass** - Aggregate token usage, tool calls, errors, and themes
6. **Write Report** - Save `summary.md` next to the artifacts and print it
7. **Present Summary & Seek Guidance**

---

## Step 1: Gather Inputs

**NEVER guess `--repo`, `--problem`, or `--model`.** Either the user passes them as command-line parameters or you ask explicitly. Do not infer them from the current working directory, recent files, or memory.

### 1.1 Required Inputs

1. **`--repo`** (kebab-case, e.g. `mcp-gateway-registry`) - matches the `{repo-name}` folder under `benchmarks/swe-benchmark-data/`.
2. **`--problem`** (kebab-case, e.g. `remove-faiss`) - matches the `{problem-name}` folder.
3. **`--model`** (kebab-case, e.g. `claude-opus-4-7`) - matches the `{model-name}` folder.

If any are missing, ask explicitly:

> The `/summarize` skill requires three inputs that I will not guess. Please provide:
> 1. `--repo <repo-name>`
> 2. `--problem <problem-name>`
> 3. `--model <model-name>`

### 1.2 Optional Inputs

- **`--session-id <uuid>`** - limit the session pass to a specific JSONL file. If not given, the skill picks every JSONL whose `cwd` matches this repository and whose `gitBranch` / time window overlaps with the artifact mtimes.
- **`--since <ISO timestamp>`** / **`--until <ISO timestamp>`** - further narrow the session pass.
- **`--out <path>`** - override the default report path (`summary.md` inside the artifacts folder).

## Step 2: Locate the Artifacts Folder

Resolve the artifact folder using the repo root - never hardcode `/home/ubuntu/...`:

```bash
REPO_ROOT="$(git rev-parse --show-toplevel)"
ART_DIR="$REPO_ROOT/benchmarks/swe-benchmark-data/{repo}/{problem}/{model}"
```

If `$ART_DIR` does not exist, stop and report it as a hard failure: there is nothing to summarize.

## Step 3: Artifact Pass

For each of the four expected artifacts, record:

| Field | How to Compute |
|-------|----------------|
| Exists | `test -f "$ART_DIR/<file>"` |
| Size (bytes) | `stat -c %s "$ART_DIR/<file>"` |
| Lines | `wc -l < "$ART_DIR/<file>"` |
| Last modified | `stat -c %y "$ART_DIR/<file>"` |
| Looks well-formed | Heuristic checks below |

### Expected Files and Heuristics

| File | Heuristic for "looks well-formed" |
|------|-----------------------------------|
| `github-issue.md` | Contains `## Title`, `## Description`, and at least one `### Acceptance Criteria` checkbox |
| `lld.md` | Contains `# Low-Level Design`, a `Table of Contents`, and at least the `Architecture`, `Data Models`, and `File changes` headings |
| `review.md` | Contains all five reviewers (`Pixel`, `Byte`, `Circuit`, `Cipher`, `Sage`) and a `Verdict:` line for each |
| `testing.md` | Contains `# Testing Plan`, `## 1. Functional Tests`, and a `## 6. Test Execution Checklist` |

### Error Signals to Capture

While scanning each artifact, also surface lines that suggest the run was incomplete:

- Lines containing `TODO`, `TBD`, `FIXME`, `{...}` placeholder fences left in by the model
- Lines starting with `Error:`, `Traceback`, or `# Aborted`
- Headings present in the template but with empty bodies (e.g. a `### Strengths` immediately followed by another heading)

Record up to 10 such hits per file with line numbers.

### Output of the Artifact Pass

Build an in-memory dict shaped like:

```json
{
  "artifacts": {
    "github-issue.md": {"exists": true, "bytes": 1840, "lines": 56, "well_formed": true, "issues": []},
    "lld.md":         {"exists": true, "bytes": 12930, "lines": 410, "well_formed": true, "issues": [{"line": 312, "snippet": "TODO: pick algorithm"}]},
    "review.md":      {"exists": true, "bytes": 4220, "lines": 130, "well_formed": false, "issues": [{"line": 88, "snippet": "Verdict: NEEDS REVISION"}]},
    "testing.md":     {"exists": false}
  }
}
```

## Step 4: Locate Session JSONL Files

Claude Code stores per-project session transcripts under `~/.claude/projects/<encoded-cwd>/*.jsonl`. The encoded directory is the absolute project path with `/` replaced by `-` and a leading `-` (e.g. `/home/ubuntu/repos/sample-claude-code-multi-model` becomes `-home-ubuntu-repos-sample-claude-code-multi-model`).

The encoded path is derived from `git rev-parse --show-toplevel`, not necessarily from the current working directory. This means if you run from a subdirectory (e.g. `repo/bedrock`), the encoded path will still be for the repo root.

### Session File Selection Algorithm

1. **Get the repo root and encoded path:**
   ```bash
   REPO_ROOT="$(git rev-parse --show-toplevel)"
   ENCODED="$(echo "$REPO_ROOT" | sed 's|/|-|g')"
   SESSIONS_DIR="$HOME/.claude/projects/$ENCODED"
   ```

2. **Check for subdirectory sessions:** Also check for sessions in directories that start with `$ENCODED-` (these represent runs from subdirectories):
   ```bash
   # For REPO_ROOT=/home/ubuntu/repos/sample-claude-code-multi-model
   # ENCODED=-home-ubuntu-repos-sample-claude-code-multi-model
   # Also check: -home-ubuntu-repos-sample-claude-code-multi-model-bedrock
   SHADOW_DIRS=$(ls -d ${SESSIONS_DIR}-* 2>/dev/null || true)
   ```

3. **Build list of session directories:**
   - Primary: `$SESSIONS_DIR`
   - Shadow (subdirectory runs): Any `${SESSIONS_DIR}-*` directories

4. **Find matching sessions:**
   - If `--session-id <uuid>` is provided, use only that session
   - Otherwise, list all `*.jsonl` files in all session directories
   - Filter to sessions whose timestamps overlap with artifact mtimes (1-hour grace window)

5. **Verify session by cwd (if needed):**
   - Check the `cwd` field in user events to ensure it matches the repo path
   - If multiple sessions overlap in time, use the one with matching `cwd`

If no JSONL file matches, mark the session pass as `Not Available` in the report and continue - the artifact pass alone is still useful.

## Step 5: Session Pass

Each line in a session JSONL is a JSON object. The relevant types are:

| `type` | What it carries | What we extract |
|--------|-----------------|-----------------|
| `assistant` | `message.usage`, `message.model`, `message.content` (text + tool_use blocks) | Tokens (input / output / cache-create / cache-read), model id, tool calls |
| `user` | `message.content` (text or tool_result) | User prompt text; tool_result error strings |
| `system` | System reminders, hook output | Error / warning lines |
| `attachment` | File attachments | Filenames referenced |

Pseudocode for the aggregation:

```python
import json
from collections import Counter, defaultdict
import re

totals = defaultdict(lambda: {
    "input_tokens": 0,
    "output_tokens": 0,
    "cache_creation_input_tokens": 0,
    "cache_read_input_tokens": 0,
    "messages": 0,
})
tool_calls = Counter()
errors = []
user_prompts = []

for path in selected_jsonl_files:
    with open(path) as f:
        for line in f:
            obj = json.loads(line)
            t = obj.get("type")
            msg = obj.get("message") or {}
            if t == "assistant" and isinstance(msg, dict):
                model = msg.get("model", "unknown")
                u = msg.get("usage") or {}
                bucket = totals[model]
                bucket["input_tokens"] += u.get("input_tokens", 0) or 0
                bucket["output_tokens"] += u.get("output_tokens", 0) or 0
                bucket["cache_creation_input_tokens"] += (
                    u.get("cache_creation_input_tokens", 0) or 0
                )
                bucket["cache_read_input_tokens"] += (
                    u.get("cache_read_input_tokens", 0) or 0
                )
                bucket["messages"] += 1
                for block in msg.get("content", []) or []:
                    if isinstance(block, dict) and block.get("type") == "tool_use":
                        tool_calls[block.get("name", "?")] += 1
            elif t == "user" and isinstance(msg, dict):
                content = msg.get("content")
                if isinstance(content, str):
                    user_prompts.append(content)
                elif isinstance(content, list):
                    for block in content:
                        if isinstance(block, dict):
                            if block.get("type") == "text":
                                user_prompts.append(block.get("text", ""))
                            elif block.get("type") == "tool_result" and block.get("is_error"):
                                errors.append(str(block.get("content", ""))[:500])
            elif t == "system":
                text = obj.get("content") or obj.get("text") or ""
                if any(s in text for s in ("Error", "error", "failed", "Traceback")):
                    errors.append(text[:500])
```

### Themes

Extract recurring topics from `user_prompts`:

1. Lowercase, strip punctuation, drop stopwords.
2. Take the top 15 most frequent 1-3 word phrases. (Use a simple counter; no NLP libs required.)
3. Cluster verbs ("update", "remove", "add", "review", "ask") to label intent.

Themes go in the report as a short bullet list, e.g.:

```
- folder structure / repo layout (12 mentions)
- gitignore / submodule discussion (5 mentions)
- "do not guess" inputs (4 mentions)
- skill rewrite (testing, lld, review) (4 mentions)
```

## Step 6: Write the Report

Save `summary.md` next to the artifacts (or to `--out` if provided):

```markdown
# Summary: {repo} / {problem} / {model}

*Created: {iso-timestamp}*
*Artifacts: `benchmarks/swe-benchmark-data/{repo}/{problem}/{model}/`*

## Run Status

| Artifact | Exists | Bytes | Lines | Well-formed | Issues |
|----------|--------|-------|-------|-------------|--------|
| github-issue.md | yes | 1840 | 56 | yes | 0 |
| lld.md          | yes | 12930 | 410 | yes | 1 |
| review.md       | yes | 4220 | 130 | no  | 3 |
| testing.md      | no  | -    | -   | -   | -   |

**Overall:** {GREEN / YELLOW / RED} - {one-line headline}

### Issues Captured in Artifacts

- `lld.md:312` `TODO: pick algorithm`
- `review.md:88` `Verdict: NEEDS REVISION`
- ...

## Session Token Usage

| Model | Messages | Input | Output | Cache Create | Cache Read | Total |
|-------|----------|-------|--------|--------------|------------|-------|
| claude-opus-4-7 | 97 | 12,403 | 28,192 | 145,200 | 312,800 | 498,595 |
| claude-haiku-4-5 | 8 | 432 | 980 | 0 | 0 | 1,412 |
| **All models** | 105 | 12,835 | 29,172 | 145,200 | 312,800 | 500,007 |

*Cache hit ratio:* `cache_read / (cache_read + input)` = 96.2%

## Tool Call Mix

| Tool | Count |
|------|-------|
| Bash | 41 |
| Read | 33 |
| Edit | 14 |
| Agent | 5 |
| Write | 4 |
| Grep | 3 |

## Errors and Warnings

- `tool_result is_error: ENOENT: no such file ...` (truncated)
- `system: Error: pre-commit hook failed - ruff check exited 1`
- ...

## Themes from User Prompts

- folder structure / repo layout (12 mentions)
- "do not guess" inputs (4 mentions)
- skill rewrite (4 mentions)
- ...

## Sessions Included

| Session | First event | Last event | Lines |
|---------|-------------|------------|-------|
| 9afad8af-a121-4047-b07b-fb8b8556eb55 | 2026-06-05T15:43Z | 2026-06-05T17:10Z | 257 |
| 6e8e145a-b043-4722-af15-68841a6853cb | 2026-06-05T17:11Z | 2026-06-05T17:55Z | 88 |

## Next Steps

- {Auto-generated: e.g. "Re-run /swe to regenerate testing.md (missing)."}
- {e.g. "Resolve the NEEDS REVISION verdict in review.md before implementing."}
```

### Overall Status Rule

Pick `GREEN`, `YELLOW`, or `RED` using these thresholds:

| Status | Rule |
|--------|------|
| GREEN | All four artifacts exist, all four well-formed, no errors in session pass |
| YELLOW | All four artifacts exist but at least one has issues, OR session pass shows non-fatal errors |
| RED | One or more artifacts missing, OR a fatal error stopped the run |

## Step 7: Present Summary & Seek Guidance

After writing `summary.md`, print the report (or a tightened version) back to the user and ask:

1. Should I open the relevant artifact(s) so you can inspect the issues yourself?
2. Should I diff this run against another `{model-name}` run for the same problem? (e.g. `claude-opus-4-7` vs `claude-sonnet-4-6`)
3. Anything else you want me to dig into from the session JSONL files (e.g. specific tool errors, specific time window)?

Do not modify any artifact, re-run `/swe`, open issues, or commit anything unless the user explicitly authorizes it as a separate request.

---

## Important Guidelines

### Read-Only Posture
- This skill is **strictly read-only** with respect to the artifact folder and the session JSONL files. Never edit them.
- The only file the skill writes is `summary.md` in the artifacts folder (or the `--out` override).

### Hard Stops
1. **Do not guess inputs.** If `--repo`, `--problem`, or `--model` are missing, ask.
2. **Do not hardcode `/home/ubuntu/...`.** Use `git rev-parse --show-toplevel` and `$HOME`.
3. **Do not modify the artifact files.** Reading them is the whole point.
4. **Do not implement code, run tests, or open PRs.** Out of scope.

### Session JSONL Caveats
- Token counts come from `message.usage`. Only `assistant` events carry it. User events do not.
- A single session may span multiple models if `/model` was used mid-run; group totals by `message.model`.
- `cache_creation_input_tokens` and `cache_read_input_tokens` are real billable tokens; include them in the totals.
- The `web_search_requests` / `web_fetch_requests` under `usage.server_tool_use` are billable separately - call them out if non-zero.
- **Important:** When the session was run from a subdirectory, the session directory may be encoded differently (e.g. `-home-ubuntu-repos-sample-claude-code-multi-model-bedrock` instead of `-home-ubuntu-repos-sample-claude-code-multi-model`). Always check shadow directories.

### Heuristics, Not Verdicts
The "well-formed" checks are heuristics. If a heuristic fails, report the failure transparently rather than declaring the artifact bad. The user is the final judge.

## Example Usage

User: "/summarize --repo mcp-gateway-registry --problem remove-faiss --model claude-opus-4-7"

1. Resolve `$ART_DIR=benchmarks/swe-benchmark-data/mcp-gateway-registry/remove-faiss/claude-opus-4-7/`
2. Confirm `$ART_DIR` exists
3. Artifact pass: stat each of the four expected files; record sizes, line counts, well-formed checks, and any TODO/error snippets
4. Resolve `$SESSIONS_DIR=$HOME/.claude/projects/-home-ubuntu-repos-sample-claude-code-multi-model/`
5. If no matching sessions found, also check `$HOME/.claude/projects/-home-ubuntu-repos-sample-claude-code-multi-model-*/`
6. Session pass: walk every `*.jsonl` whose timestamps overlap the artifact mtimes; aggregate tokens by model, count tool calls, capture errors, extract themes
7. Write `$ART_DIR/summary.md`
8. Print the report and ask whether to diff against another model

---

## Constraints

- **Read-only over artifacts and JSONL** - the only output write is `summary.md`.
- **No execution** of the cloned `repo/` tree.
- **No emojis, clever code, or em-dashes** in any output.
- **Naming**: always "Amazon Bedrock" (never "AWS Bedrock").

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.