Skip to content

Commit 70def7c

Browse files
authored
feat(risk): add --exclude flag, .riskignore support, and get_change_r… (#867)
* feat(risk): add --exclude flag, .riskignore support, and get_change_risk MCP tool * Add context to mcp output for agents to better understand the risk priority (percentile over raw corpus risk). * Update docs & website tool counts. * fixed benign ruff lint check
1 parent 09234ee commit 70def7c

25 files changed

Lines changed: 664 additions & 127 deletions

File tree

docs/CHANGE_RISK.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,23 @@ repowise risk # score HEAD
1111
repowise risk abc123 # score a single commit
1212
repowise risk main..HEAD # score a branch / PR range as one change
1313
repowise risk main..HEAD --ext .py # count only .py files
14+
repowise risk main..HEAD -x 'tests/' -x '*.spec.ts' # omit matching paths
1415
repowise risk --format json # machine-readable
1516
```
1617

1718
It runs in-process: pure `git` + learned constants. **No LLM, no network, and no
1819
blame at runtime**: SZZ labelling lives entirely in the offline calibration.
1920

21+
## Excluding paths
22+
23+
Use repeatable `--exclude` / `-x` flags with gitignore-style patterns to omit
24+
files from a score. The same filters apply to the requested change and the
25+
recent commits sampled for its percentile, so the comparison remains like for
26+
like. Put project-wide, risk-only rules in a repository-root `.riskignore`;
27+
those patterns apply automatically and are combined with any command-line
28+
flags. For example, `tests/` excludes that directory recursively, while
29+
`test_*.py` excludes matching test filenames anywhere in the repository.
30+
2031
## What it measures
2132

2233
The model uses Kamei-style *change* metrics (Kamei et al., "A large-scale
@@ -81,6 +92,9 @@ live in `packages/core/src/repowise/core/analysis/change_risk/model.py`.
8192

8293
## Cross-repo change risk (workspace mode)
8394

95+
> **Note:** This section describes `get_risk` in PR mode (`changed_files`). `get_change_risk` is
96+
> pure diff-shape scoring and does not access the workspace graph — it produces no cross-repo fields.
97+
8498
In a workspace, a change rarely stops at the repo boundary. When `get_risk` is
8599
called in PR mode (`changed_files`), its `directive` block gains two cross-repo
86100
fields derived from the [system graph](WORKSPACES.md#system-graph):

docs/CLI_REFERENCE.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,13 +386,15 @@ to the model's baseline commit, not this repo.
386386
|------|-------------|
387387
| `--path` | Path to the git repository (default: current directory) |
388388
| `--ext` | Comma-separated file suffixes to count (e.g. `.py` or `.ts,.tsx`) |
389+
| `--exclude` / `-x` | Gitignore-style path pattern to omit. Repeatable; filters both the change and baseline. Root `.riskignore` patterns also apply. |
389390
| `--baseline` | Recent commits to sample for the repo-relative percentile (default 200; `0` shows only the absolute calibrated band) |
390391
| `--format` | Output format: `table` (default) or `json` |
391392

392393
```bash
393394
repowise risk # score HEAD
394395
repowise risk main..HEAD # score a branch / PR range as one change
395396
repowise risk --ext .ts,.tsx # restrict to specific suffixes
397+
repowise risk main..HEAD -x 'tests/' -x '*.spec.ts' # omit tests from scoring
396398
```
397399

398400
See [`docs/CHANGE_RISK.md`](./CHANGE_RISK.md) for the scoring model.
@@ -844,7 +846,7 @@ If `PATH` is omitted, `repowise mcp` first walks upward from the current directo
844846
|------|-------------|
845847
| `--transport` | `stdio` (default, for editors), `streamable-http` (for HTTP clients), or `sse` (legacy) |
846848
| `--port` | Port for HTTP/SSE transports (default: 7338) |
847-
| `--tools` | Override which tools are exposed. A comma-separated list is an explicit allowlist; prefix names with `+`/`-` to adjust the default set (e.g. `+get_dependency_path,-get_dead_code`); `lean` selects the five-tool agent-lean profile. Overrides the `mcp.tools` config block. |
849+
| `--tools` | Override which tools are exposed. A comma-separated list is an explicit allowlist; prefix names with `+`/`-` to adjust the default set (e.g. `+get_dependency_path,-get_dead_code`); `lean` selects the six-tool agent-lean profile. Overrides the `mcp.tools` config block. |
848850
| `--all` | Expose every available tool, including opt-in and workspace tools |
849851

850852
```bash

docs/CONFIG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ distill:
150150
### The `mcp:` block
151151

152152
Controls which tools the MCP server advertises. The default surface is curated
153-
(10 tools in single-repo mode, plus 2 workspace-only tools in workspace mode);
153+
(11 tools in single-repo mode, plus 2 workspace-only tools in workspace mode);
154154
this block lets you opt extra tools in or trim the set down. The `repowise mcp
155155
--tools` / `--all` flags override it for a single launch.
156156

@@ -165,7 +165,7 @@ mcp:
165165
- `+name` / `-name` entries add to or remove from the default set; an
166166
unprefixed list is treated as an explicit allowlist.
167167
- `lean` selects the agent-lean profile: `get_answer`, `get_context`,
168-
`get_symbol`, `search_codebase`, `get_risk` (plus `list_repos` in workspace
168+
`get_symbol`, `search_codebase`, `get_risk`, `get_why` (plus `list_repos` in workspace
169169
mode), small enough that Claude Code can keep every schema always loaded.
170170
- Opt-in tools are `get_dependency_path`, `get_execution_flows`,
171171
`generate_refactoring_code`, and `get_conformance` (the last only usable in

docs/MCP_TOOLS.md

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
repowise exposes a curated set of tools via the [Model Context Protocol](https://modelcontextprotocol.io) (MCP). These tools give AI coding assistants (Claude Code, Codex, Cursor, Cline, Windsurf) structured access to your codebase intelligence: dependency graph, git history, documentation, and architectural decisions.
44

5-
16 tools are registered in total. A single-repo server advertises 10 by default: the nine flagship tools below plus `list_repos`. Workspace mode adds 2 more automatically (`get_architecture`, `get_blast_radius`), for 12. Four further tools are off by default everywhere and must be opted in. The surface is configurable; see [Configuring the tool surface](#configuring-the-tool-surface).
5+
17 tools are registered in total. A single-repo server advertises 11 by default: the ten flagship tools below plus `list_repos`. Workspace mode adds 2 more automatically (`get_architecture`, `get_blast_radius`), for 13. Four further tools are off by default everywhere and must be opted in. The surface is configurable; see [Configuring the tool surface](#configuring-the-tool-surface).
66

77
**Start the MCP server:**
88

@@ -16,7 +16,7 @@ repowise mcp --transport sse --port 7338 # legacy SSE transport
1616

1717
---
1818

19-
## The nine flagship tools
19+
## The ten flagship tools
2020

2121
| Tool | Purpose | Typical use |
2222
|------|---------|-------------|
@@ -26,6 +26,7 @@ repowise mcp --transport sse --port 7338 # legacy SSE transport
2626
| `get_symbol` | Raw source bytes for one symbol | When you need one function/class body |
2727
| `search_codebase` | Hybrid symbol / path / concept search | Finding a symbol or file, or discovering code by topic |
2828
| `get_risk` | Modification risk | Before changing hotspot files |
29+
| `get_change_risk` | Live commit or range risk | Before merging a commit or PR range |
2930
| `get_why` | Architectural decisions | Before structural changes |
3031
| `get_dead_code` | Unreachable code | Cleanup tasks |
3132
| `get_health` | Code-health marker scores | Before refactoring, find the worst files |
@@ -38,8 +39,8 @@ Also always on by default: `list_repos` (repo aliases). See [Supplementary tools
3839

3940
The default surface is deliberately small: fewer, richer tools mean fewer round-trips and less schema overhead per task. What a server advertises is resolved from three things: each tool's `default`/`requires_workspace` metadata, whether the server is in workspace mode, and an optional override.
4041

41-
- **Default (single-repo):** 10 tools, the nine flagship tools plus `list_repos`.
42-
- **Default (workspace):** those 10 plus `get_architecture` and `get_blast_radius`, added automatically when the server starts inside a workspace. They are never advertised outside one.
42+
- **Default (single-repo):** 11 tools, the ten flagship tools plus `list_repos`.
43+
- **Default (workspace):** those 11 plus `get_architecture` and `get_blast_radius`, added automatically when the server starts inside a workspace. They are never advertised outside one.
4344
- **Opt-in tools:** `get_dependency_path`, `get_execution_flows`, `generate_refactoring_code`, and `get_conformance` are registered but off by default. Turn them on per repo; `get_conformance` only does useful work in workspace mode (name it there).
4445

4546
**Configure it in `.repowise/config.yaml`** under an `mcp.tools` key. Four shapes are supported:
@@ -332,6 +333,41 @@ get_risk(changed_files=["src/api/routes.ts", "src/middleware/cors.ts"])
332333

333334
---
334335

336+
## `get_change_risk`
337+
338+
Live risk scoring for one commit or a `base..head` range. Unlike `get_risk`,
339+
which evaluates indexed files and can report blast radius, this scores the
340+
shape of the live diff and needs no index refresh.
341+
342+
**Parameters:**
343+
344+
| Parameter | Type | Required | Description |
345+
|-----------|------|----------|-------------|
346+
| `revspec` | string | No | Commit or `base..head` range to score (default `"HEAD"`) |
347+
| `repo` | string | No | *(workspace only)* Target repo alias |
348+
| `extensions` | list[string] | No | File suffixes to count, such as `[".py", ".ts"]` |
349+
| `exclude_patterns` | list[string] | No | Gitignore-style paths to omit; combined with root `.riskignore` rules |
350+
| `baseline` | int | No | Recent commits to sample for percentile ranking (default `200`; `0` disables percentile ranking) |
351+
352+
**Returns:** The corpus-calibrated `score`, `probability`, and `level`, plus a
353+
repo-relative `risk_percentile`, `review_priority`, and `classification`.
354+
`baseline_sample_size` reports how many filtered commits informed the percentile;
355+
`features`, `drivers`, and combined `exclude_patterns` make the result auditable.
356+
Use the percentile and review priority for triage; the raw score is secondary
357+
context when no repository baseline is available.
358+
359+
**When to use:** Before merging a commit or PR range, especially when you need
360+
to assess the diff itself rather than the risk of an already-indexed file.
361+
362+
**Example calls:**
363+
364+
```
365+
get_change_risk()
366+
get_change_risk(revspec="main..HEAD", extensions=[".py"], exclude_patterns=["tests/"])
367+
```
368+
369+
---
370+
335371
## `get_why`
336372

337373
Architectural decision intelligence. Falls back to git archaeology when no decision records exist for a path, and further to a rationale comment mined live from the source when neither decisions nor git history explain the "why".

docs/QUICKSTART.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ REPOWISE_API_URL=http://localhost:7337 npm run dev --workspace packages/web
228228

229229
- **[User Guide](USER_GUIDE.md)** — full CLI reference, web UI features, MCP setup, common workflows, and troubleshooting
230230
- **[CLI Reference](CLI_REFERENCE.md)** — every command with every flag
231-
- **[MCP Tools](MCP_TOOLS.md)**all 9 MCP tools with parameters and examples
231+
- **[MCP Tools](MCP_TOOLS.md)**full tool reference, configuration, parameters, and examples
232232
- **[Workspaces](WORKSPACES.md)** — multi-repo workspace setup and cross-repo intelligence
233233
- **[Auto-Sync](AUTO_SYNC.md)** — hooks, file watcher, webhooks, polling
234234
- **[Architecture](architecture/ARCHITECTURE.md)** — how repowise is built internally

docs/USER_GUIDE.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ This is how you connect repowise to Claude Code, Cursor, Cline, Windsurf, and ot
377377
| `--transport` | Protocol: `stdio` (default, for editors), `streamable-http` (for HTTP clients), or `sse` (legacy) |
378378
| `--port` | Port for HTTP/SSE transports (default: 7338) |
379379

380-
**MCP tools exposed (9 tools):**
380+
**Default single-repo MCP tools (11 tools):**
381381

382382
| Tool | What it does |
383383
|------|-------------|
@@ -387,9 +387,11 @@ This is how you connect repowise to Claude Code, Cursor, Cline, Windsurf, and ot
387387
| `get_symbol` | Raw source bytes for one indexed symbol with exact line bounds (cheaper/safer than `Read` + offset math) |
388388
| `search_codebase` | Semantic search over wiki with git freshness boosting. In workspace mode, searches across all repos. |
389389
| `get_risk` | Modification risk assessment, hotspot score, dependents, co-change partners, bus factor, blast radius, test gaps, 0–10 risk score |
390+
| `get_change_risk` | Live commit or range risk score, ranked against recent commits in the same repository |
390391
| `get_why` | Why code is structured the way it is, architectural decisions, git archaeology. Three modes: NL search, path-based, health dashboard. |
391392
| `get_dead_code` | Tiered dead code report grouped by confidence with cleanup impact estimates |
392393
| `get_health` | 25-marker code-health scores, dashboard KPIs + lowest-scoring files, or per-file findings; `include` for refactoring suggestions and trend alerts |
394+
| `list_repos` | Repository aliases served by this MCP server |
393395

394396
In workspace mode, tools are workspace-aware, pass `repo="backend"` to target a specific repo or `repo="all"` to query across the entire workspace. The default repo is used when `repo` is omitted.
395397

packages/cli/src/repowise/cli/commands/mcp_cmd.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ def _print_network_startup(
9191
"Override which tools are exposed. A comma-separated list is an "
9292
"explicit allowlist; prefix names with + or - to adjust the default "
9393
"set (e.g. '+get_dependency_path,-get_dead_code'); 'lean' selects "
94-
"the five-tool agent-lean profile. Overrides the mcp.tools config "
94+
"the six-tool agent-lean profile. Overrides the mcp.tools config "
9595
"block."
9696
),
9797
)
@@ -112,9 +112,9 @@ def mcp_command(
112112
"""Start the MCP server for editor integration.
113113
114114
Exposes a curated set of tools for querying the repowise wiki via the MCP
115-
protocol: ten in single-repo mode, plus three workspace-only tools in
116-
workspace mode. Two more (get_dependency_path, get_execution_flows) are
117-
opt-in via ``--tools`` or the ``mcp.tools`` config block. Supports stdio
115+
protocol: eleven by default in single-repo mode, plus two more by default
116+
in workspace mode. Four more are opt-in via ``--tools`` or the
117+
``mcp.tools`` config block. Supports stdio
118118
(for Claude Code, Codex, Cursor, Cline), streamable HTTP, and legacy SSE
119119
transports.
120120
@@ -127,7 +127,7 @@ def mcp_command(
127127
repowise mcp # stdio, current directory
128128
repowise mcp /path/to/repo # stdio, specific repo
129129
repowise mcp --tools +get_execution_flows # default set plus one
130-
repowise mcp --tools lean # five-tool agent-lean profile
130+
repowise mcp --tools lean # six-tool agent-lean profile
131131
repowise mcp --all # every available tool
132132
repowise mcp --transport streamable-http # HTTP on port 7338
133133
"""

0 commit comments

Comments
 (0)