You are a senior code reviewer preparing to review code changes.

## Code Changes

```diff
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 0000000..7c06a91
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,26 @@
+# CLAUDE.md
+
+## Project
+
+`ftl-project-expert` — CLI tool that builds expert knowledge bases from project management data (GitHub, GitLab, Jira). Uses LLMs to scan issues, explore topics, extract beliefs, and derive new insights.
+
+## Dev Setup
+
+```bash
+uv sync
+```
+
+## Issue Fix Process
+
+When fixing a GitHub issue, follow this workflow:
+
+1. **Read the issue** — `gh issue view <number> --repo benthomasson/ftl-project-expert --comments`
+2. **Checkout main and pull latest** — `git checkout main && git pull`
+3. **Fix on a dedicated branch from main** — branch name should reflect the fix (e.g. `fix-export-json-corruption`)
+4. **Commit and push**, then open a PR referencing the issue (`Fixes #N`)
+5. **Run code review with comment** — `code-review review-loop --pr <url> --github-issue <issue-url> --comment`
+6. **Address review concerns** — commit and push follow-up fixes
+7. **Re-review** until concerns are resolved or acknowledged as out-of-scope
+8. **Squash-merge** — `gh pr merge <number> --squash --delete-branch`
+9. **Checkout main and pull latest** — `git checkout main && git pull`
+10. **Reinstall uv tool** — `uv tool install --reinstall -e .`
diff --git a/ftl_project_expert/cli.py b/ftl_project_expert/cli.py
index 9387992..2d2243a 100644
--- a/ftl_project_expert/cli.py
+++ b/ftl_project_expert/cli.py
@@ -2031,17 +2031,34 @@ def summary(ctx):
         sys.exit(1)
 
     # Read beliefs from reasons or beliefs.md
+    max_beliefs = 500
     beliefs_text = ""
     belief_count = 0
+    total_count = 0
+    sorted_by_impact = False
 
     if _has_reasons() and Path("reasons.db").exists():
-        result = subprocess.run(["reasons", "list"], capture_output=True, text=True)
+        result = subprocess.run(
+            ["reasons", "list", "--status", "IN", "--by-impact"],
+            capture_output=True, text=True,
+        )
         if result.returncode == 0 and result.stdout.strip():
-            beliefs_text = result.stdout
-            belief_count = len([l for l in result.stdout.splitlines() if l.strip()])
+            lines = [l for l in result.stdout.splitlines() if l.strip()]
+            total_count = len(lines)
+            if total_count > max_beliefs:
+                lines = lines[:max_beliefs]
+            beliefs_text = "\n".join(lines)
+            belief_count = len(lines)
+            sorted_by_impact = True
     elif Path("beliefs.md").exists():
-        beliefs_text = Path("beliefs.md").read_text()
-        belief_count = len(re.findall(r"^### \S+", beliefs_text, re.MULTILINE))
+        full_text = Path("beliefs.md").read_text()
+        sections = re.split(r"(?=^### \S+)", full_text, flags=re.MULTILINE)
+        sections = [s for s in sections if s.strip().startswith("###")]
+        total_count = len(sections)
+        if total_count > max_beliefs:
+            sections = sections[:max_beliefs]
+        beliefs_text = "\n".join(sections)
+        belief_count = len(sections)
 
     if not beliefs_text or belief_count == 0:
         click.echo("No beliefs found. Run the pipeline first:")
@@ -2050,7 +2067,14 @@ def summary(ctx):
         click.echo("  project-expert accept-beliefs")
         sys.exit(1)
 
-    click.echo(f"Summarizing {belief_count} beliefs with {model}...", err=True)
+    if total_count > max_beliefs:
+        order = "by impact" if sorted_by_impact else "by file order"
+        click.echo(
+            f"Summarizing top {belief_count} of {total_count} beliefs ({order}) with {model}...",
+            err=True,
+        )
+    else:
+        click.echo(f"Summarizing {belief_count} beliefs with {model}...", err=True)
 
     project_name = config.get("repo", config.get("project", "unknown"))
 
@@ -2058,12 +2082,18 @@ def summary(ctx):
         beliefs_text=beliefs_text,
         project_name=project_name,
         belief_count=belief_count,
+        total_count=total_count,
+        sorted_by_impact=sorted_by_impact,
     )
 
+    prompt_size_kb = len(prompt.encode()) / 1024
     try:
         result = asyncio.run(invoke(prompt, model, timeout=timeout))
     except Exception as e:
-        click.echo(f"Error: {e}", err=True)
+        click.echo(
+            f"Error: Model {model} failed (prompt size: {prompt_size_kb:.0f} KB): {e}",
+            err=True,
+        )
         sys.exit(1)
 
     short_name = project_name.split("//")[-1] if "//" in project_name else project_name
diff --git a/ftl_project_expert/prompts/summary.py b/ftl_project_expert/prompts/summary.py
index 8885135..4db4758 100644
--- a/ftl_project_expert/prompts/summary.py
+++ b/ftl_project_expert/prompts/summary.py
@@ -5,12 +5,19 @@ def build_summary_prompt(
     beliefs_text: str,
     project_name: str,
     belief_count: int,
+    total_count: int = 0,
+    sorted_by_impact: bool = False,
 ) -> str:
     """Build a prompt for summarizing project state from beliefs."""
+    if total_count > belief_count:
+        order = "top by impact" if sorted_by_impact else "first"
+        count_line = f"## Beliefs analyzed: {belief_count} ({order} out of {total_count} total)"
+    else:
+        count_line = f"## Beliefs analyzed: {belief_count}"
     return f"""You are a senior project manager synthesizing a comprehensive project summary from verified beliefs about a project.
 
 ## Project: {project_name}
-## Beliefs analyzed: {belief_count}
+{count_line}
 
 ## Beliefs
 

```

## Your Task

Analyze the diff and identify what additional information you need to render confident verdicts.
Do NOT render verdicts yet. Only request observations.

## Available Observation Tools

| Tool | Purpose | When to use |
|------|---------|-------------|
| `exception_hierarchy` | Show exception MRO and subclasses | Retry logic, exception handling |
| `raises_analysis` | What exceptions a function raises | New function calls, error paths |
| `call_graph` | What a function calls | Impact analysis |
| `find_usages` | Where a symbol is used (with prod/test split) | Quick integration lookup |
| `find_callers` | Caller analysis with prod/test split and calling context | Method signature changes, return type changes, constructor modifications, integration verification |
| `test_coverage` | Find tests for a file (uses coverage-map if available) | Test coverage claims |
| `coverage_map_tests` | Find tests covering a file (from coverage-map.json) | Precise test coverage from actual execution |
| `coverage_map_files` | Find files covered by tests matching a pattern | Impact analysis for test changes |
| `function_body` | Full source of a function/method | Need complete function context beyond diff hunks |
| `file_imports` | Extract imports from a file | Verify import changes, check dependencies |
| `project_dependencies` | Get pyproject.toml/requirements.txt | Verify new imports have dependencies |
| `related_test_files` | Find test files for a source file | Discover tests by naming, imports, and coverage map |
| `class_hierarchy` | Show base classes and their `__init__` signatures | Class changes its parent, modifies `__init__`, or uses `super()` |
| `symbol_migration` | Check if a rename is complete across the repo | Symbol renamed in diff — verify old name is fully removed |
| `generator_info` | Report whether a function uses `yield` | Function might be a generator — affects return value semantics |

## What to Look For

1. **Exception handling**: Any `retry_if_exception_type`, `except`, or exception class references
2. **New dependencies**: Calls to external libraries where you don't know the error behavior
3. **Behavioral changes**: Modified logic where you need to verify callers/callees
4. **Test claims**: References to tests you can't see in the diff
5. **Inheritance changes**: Class definition changes, new base classes, `super()` calls
6. **Renames**: Symbols that appear to have been renamed in the diff
7. **Factory methods**: Calls to `@classmethod` / `@staticmethod` constructors (e.g. `Result.error(...)`) — request `function_body` to see their implementation

## Output Format

Output a JSON array of observation requests:

```json
[
  {"name": "descriptive_name", "tool": "tool_name", "params": {"param": "value"}},
  ...
]
```

If you don't need any observations (simple changes, all context is in the diff), output:

```json
[]
```

## Examples

For a diff containing `retry_if_exception_type((OSError, httpx.TransportError))`:
```json
[
  {"name": "oserror_subclasses", "tool": "exception_hierarchy", "params": {"class_name": "builtins.OSError"}},
  {"name": "transport_errors", "tool": "exception_hierarchy", "params": {"class_name": "httpx.TransportError"}}
]
```

For a diff adding a new function that calls `oauth_client.get_access_token()`:
```json
[
  {"name": "oauth_exceptions", "tool": "raises_analysis", "params": {"file_path": "src/auth/oauth.py", "function_name": "get_access_token"}}
]
```

For a diff modifying a method but you need the full function to verify:
```json
[
  {"name": "full_getattr", "tool": "function_body", "params": {"file_path": "src/proxy.py", "function_name": "__getattr__"}}
]
```

For a diff changing a method signature or return type (verify all callers):
```json
[
  {"name": "handle_request_callers", "tool": "find_callers", "params": {"symbol": "handle_request"}}
]
```

For a diff adding new imports (e.g., `import httpx`):
```json
[
  {"name": "file_imports", "tool": "file_imports", "params": {"file_path": "src/client.py"}},
  {"name": "project_deps", "tool": "project_dependencies", "params": {}}
]
```

For a diff calling a factory method like `ModuleResult.error_result(msg)`:
```json
[
  {"name": "error_result_body", "tool": "function_body", "params": {"file_path": "src/models.py", "function_name": "error_result"}}
]
```

For a diff where a class changes its parent class:
```json
[
  {"name": "client_hierarchy", "tool": "class_hierarchy", "params": {"class_name": "MyClient", "file_path": "src/client.py"}}
]
```

For a diff that renames a symbol (e.g., `OldClient` to `NewClient`):
```json
[
  {"name": "client_rename", "tool": "symbol_migration", "params": {"old_name": "OldClient", "new_name": "NewClient"}}
]
```

For a diff modifying a function that might be a generator:
```json
[
  {"name": "process_gen", "tool": "generator_info", "params": {"file_path": "src/pipeline.py", "function_name": "process_items"}}
]
```

Now analyze the diff above and output your observation requests as JSON:
