Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# Changelog

## [0.9.2] — 08-12-2026

### Fixed

- **The dropped-rule-set warning no longer cries wolf.** 0.9.1 measured every
rule set in `.diffmind/rules/` against the budget, so a `react.md` scoped to
`**/*.tsx` was reported as dropped from a diff containing no `.tsx` at all.
The check now runs per changed file, against only the rule sets that actually
govern it, and names the file:

```
! 2 rule set(s) do not fit the prompt budget (4851 bytes) and were dropped:
aaa-style (on app/dashboard/page.tsx), mmm-quality (on app/dashboard/page.tsx)
```

A warning that fires when nothing is wrong is one people learn to scroll past,
which costs more than having no warning at all.

## [0.9.1] — 08-12-2026

Config is not code, and reviewing it as though it were produced confident
Expand Down
2 changes: 1 addition & 1 deletion apps/tui-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "diffmind"
version = "0.9.1"
version = "0.9.2"
edition = "2024"
description = "Local-first AI code review agent — powered by on-device inference"

Expand Down
48 changes: 39 additions & 9 deletions apps/tui-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -579,14 +579,26 @@ impl ProjectRules {
}
}

/// Say so when the prompt budget cannot fit every rule set.
/// Say so when the prompt budget cannot fit every rule set that applies.
///
/// The alternative is what shipped before: a rule set stops applying and
/// nothing anywhere says it did. The check is deliberately at the *widest*
/// budget — depth 0, before any retry shrinks it — so this warns about the
/// rule sets that can never apply, not about a transient squeeze on one
/// oversized unit.
fn warn_on_dropped_rulebooks(backend: &dyn ReviewBackend, settings: &Settings, books: &[Rulebook]) {
/// nothing anywhere says it did.
///
/// Checked **per changed file**, against the sets that actually govern it.
/// Measuring the whole `.diffmind/rules/` directory instead was the obvious
/// implementation and it cried wolf: a `react.md` scoped to `**/*.tsx` was
/// reported as dropped from a diff containing no `.tsx` at all. A warning that
/// fires when nothing is wrong is one people learn to scroll past, which costs
/// more than having no warning.
///
/// The budget is taken at depth 0 — the widest — so this reports rule sets that
/// can never fit, not a transient squeeze on one oversized unit.
fn warn_on_dropped_rulebooks(
backend: &dyn ReviewBackend,
settings: &Settings,
books: &[Rulebook],
diff: &str,
) {
if books.is_empty() {
return;
}
Expand All @@ -595,16 +607,34 @@ fn warn_on_dropped_rulebooks(backend: &dyn ReviewBackend, settings: &Settings, b
settings.max_tokens as usize,
0,
);
let dropped = core_engine::rulebooks_dropped(books, budget);

// Worst affected file per rule set: the same set may fit beside one file's
// neighbours and not another's, and the reviewer only needs to be told once.
let mut dropped: std::collections::BTreeMap<String, String> = Default::default();
for file in core_engine::parse_diff(diff) {
let applicable: Vec<Rulebook> = books
.iter()
.filter(|b| b.applies_to(&file.path))
.cloned()
.collect();
for id in core_engine::rulebooks_dropped(&applicable, budget) {
dropped.entry(id).or_insert_with(|| file.path.clone());
}
}

if dropped.is_empty() {
return;
}

let named: Vec<String> = dropped
.iter()
.map(|(id, path)| format!("{id} (on {path})"))
.collect();
eprintln!(
" ! {} rule set(s) do not fit the prompt budget ({budget} bytes) and were \
dropped: {}",
dropped.len(),
dropped.join(", ")
named.join(", ")
);
eprintln!(
" Lowest severity is dropped first. Narrow their `scope`, shorten them, \
Expand All @@ -620,7 +650,7 @@ pub fn build_analyzer(
ticket: Option<String>,
project: ProjectRules,
) -> ReviewAnalyzer {
warn_on_dropped_rulebooks(&*backend, settings, &project.books);
warn_on_dropped_rulebooks(&*backend, settings, &project.books, diff);

let mut analyzer = ReviewAnalyzer::new(backend)
.with_unit_grouper(unit_grouper(project_root))
Expand Down
12 changes: 6 additions & 6 deletions npm/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@diffmind/cli",
"version": "0.9.1",
"version": "0.9.2",
"description": "Local-first AI code review for your git diffs \u2014 on-device inference, no cloud, no API keys",
"author": "Thinkgrid Labs <dennis@thinkgrid.dev>",
"license": "MIT",
Expand Down Expand Up @@ -39,10 +39,10 @@
"node": ">=18.0.0"
},
"optionalDependencies": {
"@diffmind/cli-darwin-arm64": "0.9.1",
"@diffmind/cli-darwin-x64": "0.9.1",
"@diffmind/cli-linux-arm64": "0.9.1",
"@diffmind/cli-linux-x64": "0.9.1",
"@diffmind/cli-win32-x64": "0.9.1"
"@diffmind/cli-darwin-arm64": "0.9.2",
"@diffmind/cli-darwin-x64": "0.9.2",
"@diffmind/cli-linux-arm64": "0.9.2",
"@diffmind/cli-linux-x64": "0.9.2",
"@diffmind/cli-win32-x64": "0.9.2"
}
}
2 changes: 1 addition & 1 deletion npm/platform/darwin-arm64/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@diffmind/cli-darwin-arm64",
"version": "0.9.1",
"version": "0.9.2",
"description": "diffmind prebuilt binary for darwin-arm64 (aarch64-apple-darwin)",
"author": "Thinkgrid Labs <dennis@thinkgrid.dev>",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion npm/platform/darwin-x64/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@diffmind/cli-darwin-x64",
"version": "0.9.1",
"version": "0.9.2",
"description": "diffmind prebuilt binary for darwin-x64 (x86_64-apple-darwin)",
"author": "Thinkgrid Labs <dennis@thinkgrid.dev>",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion npm/platform/linux-arm64/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@diffmind/cli-linux-arm64",
"version": "0.9.1",
"version": "0.9.2",
"description": "diffmind prebuilt binary for linux-arm64 (aarch64-unknown-linux-gnu)",
"author": "Thinkgrid Labs <dennis@thinkgrid.dev>",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion npm/platform/linux-x64/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@diffmind/cli-linux-x64",
"version": "0.9.1",
"version": "0.9.2",
"description": "diffmind prebuilt binary for linux-x64 (x86_64-unknown-linux-gnu)",
"author": "Thinkgrid Labs <dennis@thinkgrid.dev>",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion npm/platform/win32-x64/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@diffmind/cli-win32-x64",
"version": "0.9.1",
"version": "0.9.2",
"description": "diffmind prebuilt binary for win32-x64 (x86_64-pc-windows-msvc)",
"author": "Thinkgrid Labs <dennis@thinkgrid.dev>",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion packages/core-engine/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "core-engine"
version = "0.9.1"
version = "0.9.2"
edition = "2024"
description = "Diffmind shared AI engine core"

Expand Down
Loading